[Duplicate Expenses] Re-enable Distance Expense Support with fixes#82005
[Duplicate Expenses] Re-enable Distance Expense Support with fixes#82005JS00001 merged 21 commits intoExpensify:mainfrom
Conversation
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.
|
|
@jjcoffee hows this one going? |
|
Hey, I noticed you changed If you want to automatically generate translations for other locales, an Expensify employee will have to:
Alternatively, if you are an external contributor, you can run the translation script locally with your own OpenAI API key. To learn more, try running: npx ts-node ./scripts/generateTranslations.ts --helpTypically, you'd want to translate only what you changed by running |
|
Will add screenshots tomorrow since BE was down 😅. Please don't let that delay your review @hoangzinh 🙏 |
|
@JS00001 Could you run the generate translations workflow when you get a chance? Thanks 🙏 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a6b912fb36
ℹ️ 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".
|
Ran |
This comment has been minimized.
This comment has been minimized.
|
@JS00001 Sorry, apparently I needed to merge main first! Can you run it again? |
|
Haha no worries, ran again |
🦜 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 032bb690..e9e25d8e 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -1600,6 +1600,8 @@ const translations: TranslationDeepObject<typeof en> = {
failedToSubmitViaDEW: (reason: string) => `Der Bericht konnte nicht übermittelt werden. ${reason}`,
failedToAutoApproveViaDEW: (reason: string) => `Genehmigung über <a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">Workspace-Regeln</a> fehlgeschlagen. ${reason}`,
failedToApproveViaDEW: (reason: string) => `Genehmigung fehlgeschlagen. ${reason}`,
+ cannotDuplicateDistanceExpense:
+ 'Sie können Entfernungsausgaben nicht über mehrere Arbeitsbereiche hinweg duplizieren, da sich die Sätze zwischen den Arbeitsbereichen unterscheiden können.',
},
transactionMerge: {
listPage: {
@@ -8596,7 +8598,6 @@ Hier ist ein *Testbeleg*, um dir zu zeigen, wie es funktioniert:`,
addMember: 'Dieses Mitglied kann nicht hinzugefügt werden. Bitte versuche es erneut.',
vacationDelegate: 'Dieser Benutzer kann nicht als Urlaubsvertretung festgelegt werden. Bitte versuche es erneut.',
},
-
reportSuspiciousActivityPrompt: (email: string) =>
`Bist du sicher? Dadurch wird das Konto von <strong>${email}</strong> gesperrt. <br /><br /> Unser Team wird das Konto anschließend überprüfen und unbefugten Zugriff entfernen. Um den Zugriff wiederherzustellen, muss die Person mit Concierge zusammenarbeiten.`,
reportSuspiciousActivityConfirmationPrompt: 'Wir überprüfen das Konto, um sicherzustellen, dass es sicher entsperrt werden kann, und melden uns bei Fragen über Concierge.',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 4e3309f1..fa75cf03 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -1606,6 +1606,7 @@ const translations: TranslationDeepObject<typeof en> = {
failedToAutoApproveViaDEW: (reason: string) =>
`impossible d’approuver via les <a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">règles de l’espace de travail</a>. ${reason}`,
failedToApproveViaDEW: (reason: string) => `échec de l’approbation. ${reason}`,
+ cannotDuplicateDistanceExpense: 'Vous ne pouvez pas dupliquer des dépenses de distance entre espaces de travail, car les taux peuvent différer d’un espace de travail à l’autre.',
},
transactionMerge: {
listPage: {
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 21557b04..9e78b24f 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -1597,6 +1597,7 @@ const translations: TranslationDeepObject<typeof en> = {
failedToAutoApproveViaDEW: (reason: string) =>
`approvazione non riuscita tramite le <a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">regole dello spazio di lavoro</a>. ${reason}`,
failedToApproveViaDEW: (reason: string) => `approvazione non riuscita. ${reason}`,
+ cannotDuplicateDistanceExpense: 'Non puoi duplicare le spese chilometriche tra diversi spazi di lavoro perché le tariffe potrebbero essere diverse.',
},
transactionMerge: {
listPage: {
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 90d56d21..f7f87c71 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -1586,6 +1586,7 @@ const translations: TranslationDeepObject<typeof en> = {
failedToSubmitViaDEW: (reason: string) => `レポートの送信に失敗しました。${reason}`,
failedToAutoApproveViaDEW: (reason: string) => `<a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">ワークスペースルール</a>で承認に失敗しました。${reason}`,
failedToApproveViaDEW: (reason: string) => `承認に失敗しました。${reason}`,
+ cannotDuplicateDistanceExpense: '距離精算はワークスペースごとにレートが異なる可能性があるため、ワークスペース間で複製することはできません。',
},
transactionMerge: {
listPage: {
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 5b0bf0ee..7de585af 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -1594,6 +1594,7 @@ const translations: TranslationDeepObject<typeof en> = {
failedToSubmitViaDEW: (reason: string) => `het is niet gelukt om het rapport in te dienen. ${reason}`,
failedToAutoApproveViaDEW: (reason: string) => `goedkeuren via <a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">werkruimteregels</a> is mislukt. ${reason}`,
failedToApproveViaDEW: (reason: string) => `goedkeuren mislukt. ${reason}`,
+ cannotDuplicateDistanceExpense: 'Je kunt afstandsvergoedingen niet dupliceren tussen werkruimtes, omdat de tarieven per werkruimte kunnen verschillen.',
},
transactionMerge: {
listPage: {
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 20148b5e..af0b92ef 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -1595,6 +1595,7 @@ const translations: TranslationDeepObject<typeof en> = {
failedToAutoApproveViaDEW: (reason: string) =>
`nie udało się zatwierdzić przez <a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">zasady w przestrzeni roboczej</a>. ${reason}`,
failedToApproveViaDEW: (reason: string) => `nie udało się zaakceptować. ${reason}`,
+ cannotDuplicateDistanceExpense: 'Nie możesz duplikować wydatków za przejazdy między przestrzeniami roboczymi, ponieważ stawki mogą się różnić między poszczególnymi przestrzeniami.',
},
transactionMerge: {
listPage: {
@@ -8546,7 +8547,6 @@ Oto *paragon testowy*, żeby pokazać Ci, jak to działa:`,
vacationDelegate: 'Nie można ustawić tego użytkownika jako zastępującego na czas nieobecności. Spróbuj ponownie.',
},
cannotSetVacationDelegateForMember: (email: string) => `Nie możesz ustawić zastępstwa urlopowego dla ${email}, ponieważ jest on/ona obecnie zastępcą dla następujących członków:`,
-
reportSuspiciousActivityPrompt: (email: string) =>
`Czy na pewno? To zablokuje konto użytkownika <strong>${email}</strong>. <br /><br /> Nasz zespół następnie przejrzy konto i usunie wszelki nieautoryzowany dostęp. Aby odzyskać dostęp, będą musieli współpracować z Concierge.`,
reportSuspiciousActivityConfirmationPrompt: 'Przejrzymy konto, aby potwierdzić, że bezpiecznie je odblokować, i skontaktujemy się przez Concierge w razie pytań.',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index ba6fc695..f6b5054d 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -1591,6 +1591,7 @@ const translations: TranslationDeepObject<typeof en> = {
failedToSubmitViaDEW: (reason: string) => `falha ao enviar o relatório. ${reason}`,
failedToAutoApproveViaDEW: (reason: string) => `falha ao aprovar pelas <a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">regras do workspace</a>. ${reason}`,
failedToApproveViaDEW: (reason: string) => `falha ao aprovar. ${reason}`,
+ cannotDuplicateDistanceExpense: 'Você não pode duplicar despesas de distância entre espaços de trabalho porque as tarifas podem ser diferentes entre eles.',
},
transactionMerge: {
listPage: {
@@ -8551,7 +8552,6 @@ Aqui está um *comprovante de teste* para mostrar como funciona:`,
vacationDelegate: 'Não foi possível definir este usuário como delegado de férias. Tente novamente.',
},
cannotSetVacationDelegateForMember: (email: string) => `Você não pode definir um procurador de férias para ${email} porque esta pessoa já é procuradora dos seguintes membros:`,
-
reportSuspiciousActivityPrompt: (email: string) =>
`Tem certeza? Isso irá bloquear a conta de <strong>${email}</strong>. <br /><br /> Nossa equipe irá então analisar a conta e remover qualquer acesso não autorizado. Para recuperar o acesso, será necessário que trabalhem com a Concierge.`,
reportSuspiciousActivityConfirmationPrompt: 'Vamos revisar a conta para verificar se é seguro desbloqueá-la e entraremos em contato via Concierge caso haja dúvidas.',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 2b4d9d8d..479231cc 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -1563,6 +1563,7 @@ const translations: TranslationDeepObject<typeof en> = {
failedToSubmitViaDEW: (reason: string) => `报表提交失败。${reason}`,
failedToAutoApproveViaDEW: (reason: string) => `未能通过<a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">工作区规则</a>批准。${reason}`,
failedToApproveViaDEW: (reason: string) => `批准失败。${reason}`,
+ cannotDuplicateDistanceExpense: '你无法在不同工作区之间复制里程报销,因为各个工作区的费率可能不同。',
},
transactionMerge: {
listPage: {
Note You can apply these changes to your branch by copying the patch to your clipboard, then running |
|
Translations done! cc @hoangzinh |
JS00001
left a comment
There was a problem hiding this comment.
Nice work! Please keep an eye out for blockers
|
🚧 @JS00001 has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/JS00001 in version: 9.3.31-0 🚀
|
|
Deploy Blocker ##84194 was identified to be related to this PR. |
|
Deploy Blocker #84228 was identified to be related to this PR. |
|
🚀 Deployed to production by https://github.com/blimpich in version: 9.3.31-12 🚀
|
| policyRecentlyUsedCurrencies, | ||
| betas, | ||
| customUnitPolicyID, | ||
| shouldHandleNavigation = true, |
There was a problem hiding this comment.
@jjcoffee I'm concerned that this is becoming a bad code smell. It looks like you're passing this down to handleNavigateAfterExpenseCreate(), so it's not your fault, but I think seeing the need to pass down a boolean argument is the exact reason why it's bad.
Functions ideally shouldn't have boolean arguments that change the flow of the function (it should be two separate functions).
The most common practice for navigation is to handle it in the view components. Action files should ONLY be for making API requests which trigger changes to Onyx.
If you could find a way to clean this up, I think it would be really great and help improve code quality.
There was a problem hiding this comment.
@tgolen Thanks for bringing this up! Definitely agree that it's not best practise, though as you point out it's already a pattern being used elsewhere in the same file, e.g.
App/src/libs/actions/IOU/index.ts
Line 6844 in db3eec1
App/src/libs/actions/IOU/index.ts
Lines 7742 to 7745 in db3eec1
So I would say that it makes sense to open up an issue to the community for a broader refactor to cover all instances.
|
We had a issue where seconday action menu is not closed automatically after duplicate action #84237 |
Explanation of Change
Fixed Issues
$ #65948
$ #80420
$ #80392
$ #80399
$ #82274
PROPOSAL: N/A
Tests
Same as QA.
Offline tests
Same as QA.
QA Steps
Duplicating Per Diem (#82274)
Precondition:
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.Screenshots/Videos
Android: Native
android-app-2026-03-03_15.27.41.mp4
Android: mWeb Chrome
android-chrome-2026-03-03_15.33.39.mp4
iOS: Native
ios-app-2026-03-03_13.32.46.mp4
iOS: mWeb Safari
ios-safari-2026-03-03_14.21.12.mp4
MacOS: Chrome / Safari
desktop-chrome-2026-03-03_10.04.46.mp4