Fix spend rule currency deploy blockers#94207
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
🦜 Polyglot Parrot! 🦜Squawk! Looks like you added some shiny new English strings. Allow me to parrot them back to you in other tongues: View the translation diffdiff --git a/src/languages/de.ts b/src/languages/de.ts
index faeb5761de6..4d0fdf95471 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -8274,7 +8274,12 @@ Fügen Sie weitere Ausgabelimits hinzu, um den Cashflow Ihres Unternehmens zu sc
bodyRemovedFromCards: ({cards}: {cards: string}) => `Ausgaberegel von ${cards}`,
composeOnCards: ({content, cards}: {content: string; cards: string}) => `${content} auf ${cards}`,
composeFromCards: ({content, cards}: {content: string; cards: string}) => `${content} von ${cards}`,
+ bodyCurrency: ({adjective, value}: {adjective: string; value: string}) => (adjective !== '' ? `${adjective} Währung „${value}“` : `Währung „${value}“`),
+ bodyCurrencyChange: ({adjective, oldValue, newValue}: {adjective: string; oldValue: string; newValue: string}) =>
+ adjective !== '' ? `${adjective} Währung von „${oldValue}“ zu „${newValue}“` : `Währung von „${oldValue}“ in „${newValue}“`,
},
+ allowedCurrencyFilters: ({currencies}: {currencies: string}) => `Währungen ${currencies}`,
+ blockedCurrencyFilters: ({currencies}: {currencies: string}) => `Währungen, die nicht in ${currencies} sind`,
},
updatedCategoryTaxRate: ({categoryName, oldTax, newTax}: {categoryName: string; oldTax: string; newTax: string}) =>
`hat den Standardsteuersatz der Kategorie „${categoryName}“ auf „${newTax}“ geändert (zuvor „${oldTax}“)`,
@@ -9821,7 +9826,6 @@ Hier ist ein *Testbeleg*, um dir zu zeigen, wie es funktioniert:`,
pdfFailedBody: 'Your file could not be generated. Try again, or reach out to Concierge for help.',
readyPartialBody: ({count, total}: {count: number; total: number}) =>
`${count} of ${total} reports exported. If it didn't automatically download, use the button below. See which reports failed in <concierge-link>Concierge</concierge-link>.`,
-
close: 'Close',
},
domain: {
diff --git a/src/languages/es.ts b/src/languages/es.ts
index f687e08d44f..5bf9059ced9 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -7745,7 +7745,12 @@ ${amount} para ${merchant} - ${date}`,
bodyRemovedFromCards: ({cards}: {cards: string}) => `regla de gasto de ${cards}`,
composeOnCards: ({content, cards}: {content: string; cards: string}) => `${content} en ${cards}`,
composeFromCards: ({content, cards}: {content: string; cards: string}) => `${content} de ${cards}`,
+ bodyCurrency: ({adjective, value}: {adjective: string; value: string}) => (adjective !== '' ? `moneda ${adjective} «${value}»` : `moneda «${value}»`),
+ bodyCurrencyChange: ({adjective, oldValue, newValue}: {adjective: string; oldValue: string; newValue: string}) =>
+ adjective !== '' ? `Moneda ${adjective} de «${oldValue}» a «${newValue}»` : `moneda de '${oldValue}' a '${newValue}'`,
},
+ allowedCurrencyFilters: ({currencies}: {currencies: string}) => `monedas ${currencies}`,
+ blockedCurrencyFilters: ({currencies}: {currencies: string}) => `monedas que no estén en ${currencies}`,
},
preventSelfApproval: (oldValue, newValue) =>
`actualizó "Evitar la autoaprobación" a "${newValue === 'true' ? 'Habilitada' : 'Deshabilitada'}" (previamente "${oldValue === 'true' ? 'Habilitada' : 'Deshabilitada'}")`,
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 2c3e1398bd7..2c1de6401d8 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -8308,7 +8308,12 @@ Ajoutez davantage de règles de dépenses pour protéger la trésorerie de l’e
bodyRemovedFromCards: ({cards}: {cards: string}) => `règle de dépense provenant de ${cards}`,
composeOnCards: ({content, cards}: {content: string; cards: string}) => `${content} sur ${cards}`,
composeFromCards: ({content, cards}: {content: string; cards: string}) => `${content} de ${cards}`,
+ bodyCurrency: ({adjective, value}: {adjective: string; value: string}) => (adjective !== '' ? `Devise ${adjective} « ${value} »` : `devise « ${value} »`),
+ bodyCurrencyChange: ({adjective, oldValue, newValue}: {adjective: string; oldValue: string; newValue: string}) =>
+ adjective !== '' ? `Devise ${adjective} de « ${oldValue} » à « ${newValue} »` : `devise de « ${oldValue} » à « ${newValue} »`,
},
+ allowedCurrencyFilters: ({currencies}: {currencies: string}) => `devises ${currencies}`,
+ blockedCurrencyFilters: ({currencies}: {currencies: string}) => `devises ne figurant pas dans ${currencies}`,
},
updatedCategoryTaxRate: ({categoryName, oldTax, newTax}: {categoryName: string; oldTax: string; newTax: string}) =>
`a modifié le taux de taxe par défaut de la catégorie « ${categoryName} » en « ${newTax} » (auparavant « ${oldTax} »)`,
@@ -9853,7 +9858,6 @@ Voici un *reçu test* pour vous montrer comment ça fonctionne :`,
pdfFailedBody: 'Your file could not be generated. Try again, or reach out to Concierge for help.',
readyPartialBody: ({count, total}: {count: number; total: number}) =>
`${count} of ${total} reports exported. If it didn't automatically download, use the button below. See which reports failed in <concierge-link>Concierge</concierge-link>.`,
-
close: 'Close',
},
domain: {
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 653eb26f6ff..43228d57dca 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -8264,7 +8264,12 @@ Aggiungi altre regole di spesa per proteggere il flusso di cassa aziendale.`,
bodyRemovedFromCards: ({cards}: {cards: string}) => `regola di spesa da ${cards}`,
composeOnCards: ({content, cards}: {content: string; cards: string}) => `${content} su ${cards}`,
composeFromCards: ({content, cards}: {content: string; cards: string}) => `${content} da ${cards}`,
+ bodyCurrency: ({adjective, value}: {adjective: string; value: string}) => (adjective !== '' ? `Valuta ${adjective} "${value}"` : `valuta '${value}'`),
+ bodyCurrencyChange: ({adjective, oldValue, newValue}: {adjective: string; oldValue: string; newValue: string}) =>
+ adjective !== '' ? `valuta ${adjective} da '${oldValue}' a '${newValue}'` : `valuta da '${oldValue}' a '${newValue}'`,
},
+ allowedCurrencyFilters: ({currencies}: {currencies: string}) => `valute ${currencies}`,
+ blockedCurrencyFilters: ({currencies}: {currencies: string}) => `valute non in ${currencies}`,
},
updatedCategoryTaxRate: ({categoryName, oldTax, newTax}: {categoryName: string; oldTax: string; newTax: string}) =>
`ha cambiato l’aliquota fiscale predefinita della categoria "${categoryName}" in "${newTax}" (in precedenza "${oldTax}")`,
@@ -9809,7 +9814,6 @@ Ecco una *ricevuta di prova* per mostrarti come funziona:`,
pdfFailedBody: 'Your file could not be generated. Try again, or reach out to Concierge for help.',
readyPartialBody: ({count, total}: {count: number; total: number}) =>
`${count} of ${total} reports exported. If it didn't automatically download, use the button below. See which reports failed in <concierge-link>Concierge</concierge-link>.`,
-
close: 'Close',
},
domain: {
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 7ccdb1c30d5..8a9b86dae4a 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -8165,7 +8165,12 @@ ${reportName}`,
bodyRemovedFromCards: ({cards}: {cards: string}) => `${cards} からの支出ルール`,
composeOnCards: ({content, cards}: {content: string; cards: string}) => `${cards} 上の ${content}`,
composeFromCards: ({content, cards}: {content: string; cards: string}) => `${cards} からの ${content}`,
+ bodyCurrency: ({adjective, value}: {adjective: string; value: string}) => (adjective !== '' ? `${adjective} 通貨「${value}」` : `通貨「${value}」`),
+ bodyCurrencyChange: ({adjective, oldValue, newValue}: {adjective: string; oldValue: string; newValue: string}) =>
+ adjective !== '' ? `${adjective}通貨を「${oldValue}」から「${newValue}」に変更しました` : `通貨を「${oldValue}」から「${newValue}」に変更しました`,
},
+ allowedCurrencyFilters: ({currencies}: {currencies: string}) => `通貨 ${currencies}`,
+ blockedCurrencyFilters: ({currencies}: {currencies: string}) => `${currencies} に含まれない通貨`,
},
updatedCategoryTaxRate: ({categoryName, oldTax, newTax}: {categoryName: string; oldTax: string; newTax: string}) =>
`「${categoryName}」カテゴリのデフォルト税率を「${newTax}」に変更しました(以前は「${oldTax}」)`,
@@ -9686,7 +9691,6 @@ ${reportName}`,
pdfFailedBody: 'Your file could not be generated. Try again, or reach out to Concierge for help.',
readyPartialBody: ({count, total}: {count: number; total: number}) =>
`${count} of ${total} reports exported. If it didn't automatically download, use the button below. See which reports failed in <concierge-link>Concierge</concierge-link>.`,
-
close: 'Close',
},
domain: {
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 5711bfed6be..01d8c7010a8 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -8231,7 +8231,12 @@ er bestedingsregels toe om de kasstroom van het bedrijf te beschermen.`,
bodyRemovedFromCards: ({cards}: {cards: string}) => `bestedingsregel van ${cards}`,
composeOnCards: ({content, cards}: {content: string; cards: string}) => `${content} op ${cards}`,
composeFromCards: ({content, cards}: {content: string; cards: string}) => `${content} van ${cards}`,
+ bodyCurrency: ({adjective, value}: {adjective: string; value: string}) => (adjective !== '' ? `${adjective} valuta '${value}'` : `valuta '${value}'`),
+ bodyCurrencyChange: ({adjective, oldValue, newValue}: {adjective: string; oldValue: string; newValue: string}) =>
+ adjective !== '' ? `${adjective} valuta gewijzigd van '${oldValue}' naar '${newValue}'` : `valuta van '${oldValue}' naar '${newValue}'`,
},
+ allowedCurrencyFilters: ({currencies}: {currencies: string}) => `valuta’s ${currencies}`,
+ blockedCurrencyFilters: ({currencies}: {currencies: string}) => `valuta die niet in ${currencies} staan`,
},
updatedCategoryTaxRate: ({categoryName, oldTax, newTax}: {categoryName: string; oldTax: string; newTax: string}) =>
`heeft het standaardbelastingtarief van de categorie "${categoryName}" gewijzigd naar "${newTax}" (voorheen "${oldTax}")`,
@@ -9775,7 +9780,6 @@ Hier is een *proefbon* om je te laten zien hoe het werkt:`,
pdfFailedBody: 'Your file could not be generated. Try again, or reach out to Concierge for help.',
readyPartialBody: ({count, total}: {count: number; total: number}) =>
`${count} of ${total} reports exported. If it didn't automatically download, use the button below. See which reports failed in <concierge-link>Concierge</concierge-link>.`,
-
close: 'Close',
},
domain: {
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index a87bec01ff4..90a2649c3d6 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -8223,7 +8223,12 @@ Dodaj więcej zasad wydatków, żeby chronić płynność finansową firmy.`,
bodyRemovedFromCards: ({cards}: {cards: string}) => `zasada wydatków z ${cards}`,
composeOnCards: ({content, cards}: {content: string; cards: string}) => `${content} na ${cards}`,
composeFromCards: ({content, cards}: {content: string; cards: string}) => `${content} z ${cards}`,
+ bodyCurrency: ({adjective, value}: {adjective: string; value: string}) => (adjective !== '' ? `${adjective} waluta „${value}”` : `waluta „${value}”`),
+ bodyCurrencyChange: ({adjective, oldValue, newValue}: {adjective: string; oldValue: string; newValue: string}) =>
+ adjective !== '' ? `zmieniono walutę ${adjective} z „${oldValue}” na „${newValue}”` : `walutę z „${oldValue}” na „${newValue}”`,
},
+ allowedCurrencyFilters: ({currencies}: {currencies: string}) => `waluty ${currencies}`,
+ blockedCurrencyFilters: ({currencies}: {currencies: string}) => `waluty inne niż ${currencies}`,
},
updatedCategoryTaxRate: ({categoryName, oldTax, newTax}: {categoryName: string; oldTax: string; newTax: string}) =>
`zmienił(a) domyślną stawkę podatku dla kategorii „${categoryName}” na „${newTax}” (wcześniej „${oldTax}”)`,
@@ -9760,7 +9765,6 @@ Oto *paragon testowy*, żeby pokazać Ci, jak to działa:`,
pdfFailedBody: 'Your file could not be generated. Try again, or reach out to Concierge for help.',
readyPartialBody: ({count, total}: {count: number; total: number}) =>
`${count} of ${total} reports exported. If it didn't automatically download, use the button below. See which reports failed in <concierge-link>Concierge</concierge-link>.`,
-
close: 'Close',
},
domain: {
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 4417c9f2a38..ec441f53972 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -8221,7 +8221,12 @@ Adicione mais regras de gasto para proteger o fluxo de caixa da empresa.`,
bodyRemovedFromCards: ({cards}: {cards: string}) => `regra de gasto de ${cards}`,
composeOnCards: ({content, cards}: {content: string; cards: string}) => `${content} em ${cards}`,
composeFromCards: ({content, cards}: {content: string; cards: string}) => `${content} de ${cards}`,
+ bodyCurrency: ({adjective, value}: {adjective: string; value: string}) => (adjective !== '' ? `Moeda ${adjective} '${value}'` : `moeda '${value}'`),
+ bodyCurrencyChange: ({adjective, oldValue, newValue}: {adjective: string; oldValue: string; newValue: string}) =>
+ adjective !== '' ? `${adjective} moeda de '${oldValue}' para '${newValue}'` : `moeda de '${oldValue}' para '${newValue}'`,
},
+ allowedCurrencyFilters: ({currencies}: {currencies: string}) => `moedas ${currencies}`,
+ blockedCurrencyFilters: ({currencies}: {currencies: string}) => `moedas que não estão em ${currencies}`,
},
updatedCategoryTaxRate: ({categoryName, oldTax, newTax}: {categoryName: string; oldTax: string; newTax: string}) =>
`alterou a alíquota de imposto padrão da categoria "${categoryName}" para "${newTax}" (antes "${oldTax}")`,
@@ -9764,7 +9769,6 @@ Aqui está um *comprovante de teste* para mostrar como funciona:`,
pdfFailedBody: 'Your file could not be generated. Try again, or reach out to Concierge for help.',
readyPartialBody: ({count, total}: {count: number; total: number}) =>
`${count} of ${total} reports exported. If it didn't automatically download, use the button below. See which reports failed in <concierge-link>Concierge</concierge-link>.`,
-
close: 'Close',
},
domain: {
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 8bae9ab9db1..1d4a7ae9cc2 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -8004,7 +8004,12 @@ ${reportName}`,
bodyRemovedFromCards: ({cards}: {cards: string}) => `来自 ${cards} 的消费规则`,
composeOnCards: ({content, cards}: {content: string; cards: string}) => `${cards} 上的 ${content}`,
composeFromCards: ({content, cards}: {content: string; cards: string}) => `来自 ${cards} 的 ${content}`,
+ bodyCurrency: ({adjective, value}: {adjective: string; value: string}) => (adjective !== '' ? `${adjective} 货币“${value}”` : `货币“${value}”`),
+ bodyCurrencyChange: ({adjective, oldValue, newValue}: {adjective: string; oldValue: string; newValue: string}) =>
+ adjective !== '' ? `将 ${adjective} 货币从“${oldValue}”更改为“${newValue}”` : `货币从“${oldValue}”更改为“${newValue}”`,
},
+ allowedCurrencyFilters: ({currencies}: {currencies: string}) => `货币 ${currencies}`,
+ blockedCurrencyFilters: ({currencies}: {currencies: string}) => `不在 ${currencies} 中的货币`,
},
updatedCategoryTaxRate: ({categoryName, oldTax, newTax}: {categoryName: string; oldTax: string; newTax: string}) =>
`将“${categoryName}”类别的默认税率更改为“${newTax}”(之前为“${oldTax}”)`,
@@ -9502,7 +9507,6 @@ ${reportName}`,
pdfFailedBody: 'Your file could not be generated. Try again, or reach out to Concierge for help.',
readyPartialBody: ({count, total}: {count: number; total: number}) =>
`${count} of ${total} reports exported. If it didn't automatically download, use the button below. See which reports failed in <concierge-link>Concierge</concierge-link>.`,
-
close: 'Close',
},
domain: {
Note You can apply these changes to your branch by copying the patch to your clipboard, then running |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 26e1a0826c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Codecov Report❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.
|
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.1405-04-03.at.11.47.55.PM.movScreen.Recording.1405-04-03.at.11.48.34.PM.movScreen.Recording.1405-04-03.at.11.49.30.PM.movAndroid: mWeb ChromeScreen.Recording.1405-04-03.at.11.54.14.PM.movScreen.Recording.1405-04-03.at.11.54.46.PM.movScreen.Recording.1405-04-03.at.11.55.43.PM.moviOS: HybridAppiOS: mWeb SafariScreen.Recording.1405-04-03.at.11.59.24.PM.movScreen.Recording.1405-04-03.at.11.59.55.PM.movScreen.Recording.1405-04-04.at.12.00.33.AM.mov |
Explanation of Change
Fixes deploy blockers for currencies in spend rules
Fixed Issues
$ #94116
$ #94078
$ #94091
Offline tests
Validate the linked issues
QA Steps
Validate the linked issues
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps./** comment above it */thisproperly so there are no scoping issues (i.e. foronClick={this.submit}the methodthis.submitshould be bound tothisin the constructor)thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)Screenshots/Videos
Screen.Recording.2026-06-23.at.1.14.29.PM.mov