Skip to content

Commit dd8ed54

Browse files
authored
Merge pull request #61852 from FitseTLT/fix-violation-data-build-currency-bug
Fix - Client side calculation of overLimit violation doesn't take forex rates into account
2 parents 9df6c13 + 5f9dc56 commit dd8ed54

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

src/libs/Violations/ViolationsUtils.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,19 @@ const ViolationsUtils = {
232232
const hasOverLimitViolation = transactionViolations.some((violation) => violation.name === 'overLimit');
233233
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
234234
const amount = updatedTransaction.modifiedAmount || updatedTransaction.amount;
235+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
236+
const currency = updatedTransaction.modifiedCurrency || updatedTransaction.currency;
237+
const canCalculateAmountViolations = policy.outputCurrency === currency;
238+
235239
const shouldShowReceiptRequiredViolation =
240+
canCalculateAmountViolations &&
236241
!isInvoiceTransaction &&
237242
policy.maxExpenseAmountNoReceipt &&
238243
Math.abs(amount) > policy.maxExpenseAmountNoReceipt &&
239244
!TransactionUtils.hasReceipt(updatedTransaction) &&
240245
isControlPolicy;
241-
const shouldShowOverLimitViolation = !isInvoiceTransaction && policy.maxExpenseAmount && Math.abs(amount) > policy.maxExpenseAmount && isControlPolicy;
246+
const shouldShowOverLimitViolation =
247+
canCalculateAmountViolations && !isInvoiceTransaction && policy.maxExpenseAmount && Math.abs(amount) > policy.maxExpenseAmount && isControlPolicy;
242248
const hasFutureDateViolation = transactionViolations.some((violation) => violation.name === 'futureDate');
243249
// Add 'futureDate' violation if transaction date is in the future and policy type is corporate
244250
if (!hasFutureDateViolation && shouldDisplayFutureDateViolation) {
@@ -250,7 +256,7 @@ const ViolationsUtils = {
250256
newTransactionViolations = reject(newTransactionViolations, {name: CONST.VIOLATIONS.FUTURE_DATE});
251257
}
252258

253-
if (!hasReceiptRequiredViolation && shouldShowReceiptRequiredViolation) {
259+
if (canCalculateAmountViolations && !hasReceiptRequiredViolation && shouldShowReceiptRequiredViolation) {
254260
newTransactionViolations.push({
255261
name: CONST.VIOLATIONS.RECEIPT_REQUIRED,
256262
data: {
@@ -261,11 +267,11 @@ const ViolationsUtils = {
261267
});
262268
}
263269

264-
if (hasReceiptRequiredViolation && !shouldShowReceiptRequiredViolation) {
270+
if (canCalculateAmountViolations && hasReceiptRequiredViolation && !shouldShowReceiptRequiredViolation) {
265271
newTransactionViolations = reject(newTransactionViolations, {name: CONST.VIOLATIONS.RECEIPT_REQUIRED});
266272
}
267273

268-
if (!hasOverLimitViolation && shouldShowOverLimitViolation) {
274+
if (canCalculateAmountViolations && !hasOverLimitViolation && shouldShowOverLimitViolation) {
269275
newTransactionViolations.push({
270276
name: CONST.VIOLATIONS.OVER_LIMIT,
271277
data: {
@@ -276,7 +282,7 @@ const ViolationsUtils = {
276282
});
277283
}
278284

279-
if (hasOverLimitViolation && !shouldShowOverLimitViolation) {
285+
if (canCalculateAmountViolations && hasOverLimitViolation && !shouldShowOverLimitViolation) {
280286
newTransactionViolations = reject(newTransactionViolations, {name: CONST.VIOLATIONS.OVER_LIMIT});
281287
}
282288

tests/unit/ViolationUtilsTest.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ describe('getViolationsOnyxData', () => {
8383
comment: {attendees: [{email: '[email protected]', displayName: 'Test User', avatarUrl: ''}]},
8484
created: '2023-07-24 13:46:20',
8585
merchant: 'United Airlines',
86-
currency: 'USD',
86+
currency: CONST.CURRENCY.USD,
8787
};
8888
transactionViolations = [];
8989
policy = {requiresTag: false, requiresCategory: false} as Policy;
@@ -155,6 +155,7 @@ describe('getViolationsOnyxData', () => {
155155
describe('controlPolicyViolations', () => {
156156
beforeEach(() => {
157157
policy.type = 'corporate';
158+
policy.outputCurrency = CONST.CURRENCY.USD;
158159
});
159160

160161
it('should not add futureDate violation if the policy is not corporate', () => {
@@ -185,12 +186,28 @@ describe('getViolationsOnyxData', () => {
185186
expect(result.value).toEqual(expect.arrayContaining([receiptRequiredViolation, ...transactionViolations]));
186187
});
187188

189+
it('should not add receiptRequired violation if the transaction has different currency than the workspace currency', () => {
190+
transaction.amount = 1000000;
191+
transaction.modifiedCurrency = CONST.CURRENCY.CAD;
192+
policy.maxExpenseAmountNoReceipt = 2500;
193+
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policy, policyTags, policyCategories, false, false);
194+
expect(result.value).toEqual([]);
195+
});
196+
188197
it('should add overLimit violation if the transaction amount is over the policy limit', () => {
189198
transaction.amount = 1000000;
190199
policy.maxExpenseAmount = 200000;
191200
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policy, policyTags, policyCategories, false, false);
192201
expect(result.value).toEqual(expect.arrayContaining([overLimitViolation, ...transactionViolations]));
193202
});
203+
204+
it('should not add overLimit violation if the transaction currency is different from the workspace currency', () => {
205+
transaction.amount = 1000000;
206+
transaction.modifiedCurrency = CONST.CURRENCY.NZD;
207+
policy.maxExpenseAmount = 200000;
208+
const result = ViolationsUtils.getViolationsOnyxData(transaction, transactionViolations, policy, policyTags, policyCategories, false, false);
209+
expect(result.value).toEqual([]);
210+
});
194211
});
195212

196213
describe('policyRequiresCategories', () => {

0 commit comments

Comments
 (0)