From fde446ec2b25e62116495af12c27193d3baa6c52 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 2 Jun 2025 20:10:41 +0530 Subject: [PATCH 1/2] Implemented over trip limit violation --- src/CONST.ts | 1 + src/hooks/useViolations.ts | 1 + src/languages/en.ts | 1 + src/languages/es.ts | 1 + src/libs/Violations/ViolationsUtils.ts | 18 ++++++++++++++++++ 5 files changed, 22 insertions(+) diff --git a/src/CONST.ts b/src/CONST.ts index 8eac62a893da..9755c67fee1e 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -5396,6 +5396,7 @@ const CONST = { TAX_REQUIRED: 'taxRequired', HOLD: 'hold', RECEIPT_GENERATED_WITH_AI: 'receiptGeneratedWithAI', + OVER_TRIP_LIMIT: 'overTripLimit', }, RTER_VIOLATION_TYPES: { BROKEN_CARD_CONNECTION: 'brokenCardConnection', diff --git a/src/hooks/useViolations.ts b/src/hooks/useViolations.ts index 8e9638afc0dc..e8c40432c669 100644 --- a/src/hooks/useViolations.ts +++ b/src/hooks/useViolations.ts @@ -35,6 +35,7 @@ const violationNameToField: Record 'amount', overCategoryLimit: () => 'amount', overLimit: () => 'amount', + overTripLimit: () => 'amount', overLimitAttendee: () => 'amount', perDayLimit: () => 'amount', prohibitedExpense: () => 'receipt', diff --git a/src/languages/en.ts b/src/languages/en.ts index ef7a7c83c42c..ee586e0f3ee4 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -5799,6 +5799,7 @@ const translations = { overAutoApprovalLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Expense exceeds auto-approval limit of ${formattedLimit}`, overCategoryLimit: ({formattedLimit}: ViolationsOverCategoryLimitParams) => `Amount over ${formattedLimit}/person category limit`, overLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Amount over ${formattedLimit}/person limit`, + overTripLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Amount over ${formattedLimit}/trip limit`, overLimitAttendee: ({formattedLimit}: ViolationsOverLimitParams) => `Amount over ${formattedLimit}/person limit`, perDayLimit: ({formattedLimit}: ViolationsPerDayLimitParams) => `Amount over daily ${formattedLimit}/person category limit`, receiptNotSmartScanned: diff --git a/src/languages/es.ts b/src/languages/es.ts index 735e63e74721..8ccd3dbe8776 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -6319,6 +6319,7 @@ const translations = { `Importe supera el límite de aprobación automática${formattedLimit ? ` de ${formattedLimit}` : ''}`, overCategoryLimit: ({formattedLimit}: ViolationsOverCategoryLimitParams) => `Importe supera el límite para la categoría${formattedLimit ? ` de ${formattedLimit}/persona` : ''}`, overLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Importe supera el límite${formattedLimit ? ` de ${formattedLimit}/persona` : ''}`, + overTripLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Importe supera el límite${formattedLimit ? ` de ${formattedLimit}/viaje` : ''}`, overLimitAttendee: ({formattedLimit}: ViolationsOverLimitParams) => `Importe supera el límite${formattedLimit ? ` de ${formattedLimit}/persona` : ''}`, perDayLimit: ({formattedLimit}: ViolationsPerDayLimitParams) => `Importe supera el límite diario de la categoría${formattedLimit ? ` de ${formattedLimit}/persona` : ''}`, receiptNotSmartScanned: diff --git a/src/libs/Violations/ViolationsUtils.ts b/src/libs/Violations/ViolationsUtils.ts index e203568e58ca..080b9e9a63ae 100644 --- a/src/libs/Violations/ViolationsUtils.ts +++ b/src/libs/Violations/ViolationsUtils.ts @@ -231,6 +231,7 @@ const ViolationsUtils = { const hasReceiptRequiredViolation = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.RECEIPT_REQUIRED && violation.data); const hasCategoryReceiptRequiredViolation = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.RECEIPT_REQUIRED && !violation.data); const hasOverLimitViolation = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.OVER_LIMIT); + const hasOverTripLimitViolation = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.OVER_TRIP_LIMIT); const hasCategoryOverLimitViolation = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.OVER_CATEGORY_LIMIT); const hasMissingCommentViolation = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.MISSING_COMMENT); // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing @@ -326,6 +327,21 @@ const ViolationsUtils = { }); } + if (canCalculateAmountViolations && !hasOverTripLimitViolation && Math.abs(updatedTransaction.amount) < Math.abs(amount) && TransactionUtils.hasReservationList(updatedTransaction)) { + newTransactionViolations.push({ + name: CONST.VIOLATIONS.OVER_TRIP_LIMIT, + data: { + formattedLimit: CurrencyUtils.convertAmountToDisplayString(updatedTransaction.amount, updatedTransaction.currency), + }, + type: CONST.VIOLATION_TYPES.VIOLATION, + showInReview: true, + }); + } + + if (canCalculateAmountViolations && hasOverTripLimitViolation && Math.abs(updatedTransaction.amount) >= Math.abs(amount) && TransactionUtils.hasReservationList(updatedTransaction)) { + newTransactionViolations = reject(newTransactionViolations, {name: CONST.VIOLATIONS.OVER_TRIP_LIMIT}); + } + if (!hasMissingCommentViolation && shouldShowMissingComment) { newTransactionViolations.push({ name: CONST.VIOLATIONS.MISSING_COMMENT, @@ -419,6 +435,8 @@ const ViolationsUtils = { return translate('violations.overCategoryLimit', {formattedLimit}); case 'overLimit': return translate('violations.overLimit', {formattedLimit}); + case 'overTripLimit': + return translate('violations.overTripLimit', {formattedLimit}); case 'overLimitAttendee': return translate('violations.overLimitAttendee', {formattedLimit}); case 'perDayLimit': From 918909d7a8a4afb5bb71f68b1abf52c57fdb3873 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Fri, 25 Jul 2025 09:51:40 +0530 Subject: [PATCH 2/2] Added translations and commented future logic --- src/languages/de.ts | 1 + src/languages/fr.ts | 1 + src/languages/it.ts | 1 + src/languages/ja.ts | 1 + src/languages/nl.ts | 1 + src/languages/pl.ts | 1 + src/languages/pt-BR.ts | 1 + src/languages/zh-hans.ts | 1 + src/libs/Violations/ViolationsUtils.ts | 32 ++++++++++++++------------ 9 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/languages/de.ts b/src/languages/de.ts index df45fdbab385..cf3b1dc1c6cf 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -6461,6 +6461,7 @@ const translations = { overAutoApprovalLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Ausgabe überschreitet die automatische Genehmigungsgrenze von ${formattedLimit}`, overCategoryLimit: ({formattedLimit}: ViolationsOverCategoryLimitParams) => `Betrag über dem ${formattedLimit}/Personen-Kategorielimit`, overLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Betrag über dem Limit von ${formattedLimit}/Person`, + overTripLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Betrag über ${formattedLimit}/Fahrtgrenze`, overLimitAttendee: ({formattedLimit}: ViolationsOverLimitParams) => `Betrag über dem Limit von ${formattedLimit}/Person`, perDayLimit: ({formattedLimit}: ViolationsPerDayLimitParams) => `Betrag über dem täglichen ${formattedLimit}/Personen-Kategorielimit`, receiptNotSmartScanned: diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 289a93296386..e03889272fe0 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -6472,6 +6472,7 @@ const translations = { overAutoApprovalLimit: ({formattedLimit}: ViolationsOverLimitParams) => `La dépense dépasse la limite d'approbation automatique de ${formattedLimit}`, overCategoryLimit: ({formattedLimit}: ViolationsOverCategoryLimitParams) => `Montant supérieur à ${formattedLimit}/limite de catégorie par personne`, overLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Montant au-delà de la limite de ${formattedLimit}/personne`, + overTripLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Montant supérieur à la limite de ${formattedLimit}/voyage`, overLimitAttendee: ({formattedLimit}: ViolationsOverLimitParams) => `Montant au-delà de la limite de ${formattedLimit}/personne`, perDayLimit: ({formattedLimit}: ViolationsPerDayLimitParams) => `Montant dépassant la limite quotidienne de ${formattedLimit}/personne pour la catégorie`, receiptNotSmartScanned: diff --git a/src/languages/it.ts b/src/languages/it.ts index 62f790fe5548..41a27c4fdda1 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -6475,6 +6475,7 @@ const translations = { overAutoApprovalLimit: ({formattedLimit}: ViolationsOverLimitParams) => `La spesa supera il limite di approvazione automatica di ${formattedLimit}`, overCategoryLimit: ({formattedLimit}: ViolationsOverCategoryLimitParams) => `Importo superiore al limite di categoria di ${formattedLimit}/persona`, overLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Importo oltre il limite di ${formattedLimit}/persona`, + overTripLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Importo superiore al limite di ${formattedLimit}/viaggio`, overLimitAttendee: ({formattedLimit}: ViolationsOverLimitParams) => `Importo oltre il limite di ${formattedLimit}/persona`, perDayLimit: ({formattedLimit}: ViolationsPerDayLimitParams) => `Importo oltre il limite giornaliero ${formattedLimit}/persona per categoria`, receiptNotSmartScanned: diff --git a/src/languages/ja.ts b/src/languages/ja.ts index cf9c0f9cfc89..f3347ed1d8b2 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -6432,6 +6432,7 @@ const translations = { overAutoApprovalLimit: ({formattedLimit}: ViolationsOverLimitParams) => `経費が自動承認限度額の${formattedLimit}を超えています。`, overCategoryLimit: ({formattedLimit}: ViolationsOverCategoryLimitParams) => `${formattedLimit}/人のカテゴリ制限を超える金額`, overLimit: ({formattedLimit}: ViolationsOverLimitParams) => `${formattedLimit}/人の制限を超えた金額`, + overTripLimit: ({formattedLimit}: ViolationsOverLimitParams) => `${formattedLimit}/回を超える金額`, overLimitAttendee: ({formattedLimit}: ViolationsOverLimitParams) => `${formattedLimit}/人の制限を超えた金額`, perDayLimit: ({formattedLimit}: ViolationsPerDayLimitParams) => `1日あたりのカテゴリ制限${formattedLimit}/人を超える金額`, receiptNotSmartScanned: '領収書と経費の詳細を手動で追加しました。詳細を学ぶ。', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 3052c8b19c6a..a18bc0cde0c9 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -6468,6 +6468,7 @@ const translations = { overAutoApprovalLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Uitgave overschrijdt de automatische goedkeuringslimiet van ${formattedLimit}`, overCategoryLimit: ({formattedLimit}: ViolationsOverCategoryLimitParams) => `Bedrag boven ${formattedLimit}/persoon categorielimiet`, overLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Bedrag boven ${formattedLimit}/persoon limiet`, + overTripLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Bedrag boven ${formattedLimit}/ritlimiet`, overLimitAttendee: ({formattedLimit}: ViolationsOverLimitParams) => `Bedrag boven ${formattedLimit}/persoon limiet`, perDayLimit: ({formattedLimit}: ViolationsPerDayLimitParams) => `Bedrag boven de dagelijkse ${formattedLimit}/persoon categoriegrens`, receiptNotSmartScanned: diff --git a/src/languages/pl.ts b/src/languages/pl.ts index 180cb81c2c69..29dad0a67817 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -6452,6 +6452,7 @@ const translations = { overAutoApprovalLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Wydatek przekracza limit automatycznej akceptacji wynoszący ${formattedLimit}`, overCategoryLimit: ({formattedLimit}: ViolationsOverCategoryLimitParams) => `Kwota przekracza limit ${formattedLimit} na osobę w kategorii`, overLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Kwota przekracza limit ${formattedLimit}/osobę`, + overTripLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Kwota przekraczająca limit ${formattedLimit}/przejazd`, overLimitAttendee: ({formattedLimit}: ViolationsOverLimitParams) => `Kwota przekracza limit ${formattedLimit}/osobę`, perDayLimit: ({formattedLimit}: ViolationsPerDayLimitParams) => `Kwota przekracza dzienny limit ${formattedLimit}/osoba dla kategorii`, receiptNotSmartScanned: diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 6893735d977a..a94f43fb18b0 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -6465,6 +6465,7 @@ const translations = { overAutoApprovalLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Despesa excede o limite de aprovação automática de ${formattedLimit}`, overCategoryLimit: ({formattedLimit}: ViolationsOverCategoryLimitParams) => `Quantia acima do limite de ${formattedLimit}/pessoa da categoria`, overLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Quantia acima do limite de ${formattedLimit}/pessoa`, + overTripLimit: ({formattedLimit}: ViolationsOverLimitParams) => `Valor acima do limite de ${formattedLimit}/viagem`, overLimitAttendee: ({formattedLimit}: ViolationsOverLimitParams) => `Quantia acima do limite de ${formattedLimit}/pessoa`, perDayLimit: ({formattedLimit}: ViolationsPerDayLimitParams) => `Quantia acima do limite diário de ${formattedLimit}/pessoa para a categoria`, receiptNotSmartScanned: diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 887a9425559a..0dfc68ad10fb 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -6351,6 +6351,7 @@ const translations = { overAutoApprovalLimit: ({formattedLimit}: ViolationsOverLimitParams) => `费用超出了自动批准限额 ${formattedLimit}`, overCategoryLimit: ({formattedLimit}: ViolationsOverCategoryLimitParams) => `金额超过 ${formattedLimit}/人类别限制`, overLimit: ({formattedLimit}: ViolationsOverLimitParams) => `金额超过${formattedLimit}/人限制`, + overTripLimit: ({formattedLimit}: ViolationsOverLimitParams) => `超过 ${formattedLimit}/次限额的金额`, overLimitAttendee: ({formattedLimit}: ViolationsOverLimitParams) => `金额超过${formattedLimit}/人限制`, perDayLimit: ({formattedLimit}: ViolationsPerDayLimitParams) => `金额超过每日 ${formattedLimit}/人类别限制`, receiptNotSmartScanned: '收据和费用详情手动添加。了解更多。', diff --git a/src/libs/Violations/ViolationsUtils.ts b/src/libs/Violations/ViolationsUtils.ts index e2bc8fbec5ec..0bc0290480e6 100644 --- a/src/libs/Violations/ViolationsUtils.ts +++ b/src/libs/Violations/ViolationsUtils.ts @@ -284,7 +284,8 @@ const ViolationsUtils = { const hasReceiptRequiredViolation = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.RECEIPT_REQUIRED && violation.data); const hasCategoryReceiptRequiredViolation = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.RECEIPT_REQUIRED && !violation.data); const hasOverLimitViolation = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.OVER_LIMIT); - const hasOverTripLimitViolation = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.OVER_TRIP_LIMIT); + // TODO: Uncomment when the OVER_TRIP_LIMIT violation is implemented + // const hasOverTripLimitViolation = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.OVER_TRIP_LIMIT); const hasCategoryOverLimitViolation = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.OVER_CATEGORY_LIMIT); const hasMissingCommentViolation = transactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.MISSING_COMMENT); // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing @@ -380,20 +381,21 @@ const ViolationsUtils = { }); } - if (canCalculateAmountViolations && !hasOverTripLimitViolation && Math.abs(updatedTransaction.amount) < Math.abs(amount) && TransactionUtils.hasReservationList(updatedTransaction)) { - newTransactionViolations.push({ - name: CONST.VIOLATIONS.OVER_TRIP_LIMIT, - data: { - formattedLimit: CurrencyUtils.convertAmountToDisplayString(updatedTransaction.amount, updatedTransaction.currency), - }, - type: CONST.VIOLATION_TYPES.VIOLATION, - showInReview: true, - }); - } - - if (canCalculateAmountViolations && hasOverTripLimitViolation && Math.abs(updatedTransaction.amount) >= Math.abs(amount) && TransactionUtils.hasReservationList(updatedTransaction)) { - newTransactionViolations = reject(newTransactionViolations, {name: CONST.VIOLATIONS.OVER_TRIP_LIMIT}); - } + // TODO: Uncomment when the OVER_TRIP_LIMIT violation is implemented + // if (canCalculateAmountViolations && !hasOverTripLimitViolation && Math.abs(updatedTransaction.amount) < Math.abs(amount) && TransactionUtils.hasReservationList(updatedTransaction)) { + // newTransactionViolations.push({ + // name: CONST.VIOLATIONS.OVER_TRIP_LIMIT, + // data: { + // formattedLimit: CurrencyUtils.convertAmountToDisplayString(updatedTransaction.amount, updatedTransaction.currency), + // }, + // type: CONST.VIOLATION_TYPES.VIOLATION, + // showInReview: true, + // }); + // } + + // if (canCalculateAmountViolations && hasOverTripLimitViolation && Math.abs(updatedTransaction.amount) >= Math.abs(amount) && TransactionUtils.hasReservationList(updatedTransaction)) { + // newTransactionViolations = reject(newTransactionViolations, {name: CONST.VIOLATIONS.OVER_TRIP_LIMIT}); + // } if (!hasMissingCommentViolation && shouldShowMissingComment) { newTransactionViolations.push({