Skip to content

Commit

Permalink
Merge pull request #54603 from daledah/fix/54510
Browse files Browse the repository at this point in the history
fix: add missing violation data
  • Loading branch information
carlosmiceli authored Feb 8, 2025
2 parents b0b7709 + 23e7448 commit 631006e
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 45 deletions.
10 changes: 10 additions & 0 deletions src/libs/DateUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,15 @@ const getDayValidationErrorKey = (inputDate: Date): string => {
return '';
};

/**
* Checks if the input time is after the reference date
* param {Date} inputDate - The date to validate.
* returns {boolean} - Returns true if the input date is after the reference date, otherwise false.
*/
const isFutureDay = (inputDate: Date): boolean => {
return isAfter(startOfDay(inputDate), startOfDay(new Date()));
};

/**
* Checks if the input time is at least one minute in the future compared to the reference time.
* param {Date} inputTime - The time to validate.
Expand Down Expand Up @@ -957,6 +966,7 @@ const DateUtils = {
isValidDateString,
getFormattedDurationBetweenDates,
getFormattedDuration,
isFutureDay,
getFormattedDateRangeForPerDiem,
};

Expand Down
59 changes: 58 additions & 1 deletion src/libs/Violations/ViolationsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import reject from 'lodash/reject';
import Onyx from 'react-native-onyx';
import type {OnyxUpdate} from 'react-native-onyx';
import type {LocaleContextProps} from '@components/LocaleContextProvider';
import * as CurrencyUtils from '@libs/CurrencyUtils';
import DateUtils from '@libs/DateUtils';
import {getDistanceRateCustomUnitRate, getSortedTagKeys} from '@libs/PolicyUtils';
import * as TransactionUtils from '@libs/TransactionUtils';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -168,6 +170,7 @@ const ViolationsUtils = {
policyTagList: PolicyTagLists,
policyCategories: PolicyCategories,
hasDependentTags: boolean,
isInvoiceTransaction: boolean,
): OnyxUpdate {
const isPartialTransaction = TransactionUtils.isPartialMerchant(TransactionUtils.getMerchant(updatedTransaction)) && TransactionUtils.isAmountMissing(updatedTransaction);
if (isPartialTransaction) {
Expand Down Expand Up @@ -205,7 +208,7 @@ const ViolationsUtils = {

// Add 'missingCategory' violation if category is required and not set
if (!hasMissingCategoryViolation && policyRequiresCategories && !categoryKey) {
newTransactionViolations.push({name: 'missingCategory', type: CONST.VIOLATION_TYPES.VIOLATION});
newTransactionViolations.push({name: 'missingCategory', type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true});
}
}

Expand All @@ -222,6 +225,60 @@ const ViolationsUtils = {
newTransactionViolations = reject(newTransactionViolations, {name: CONST.VIOLATIONS.CUSTOM_UNIT_OUT_OF_POLICY});
}

const isControlPolicy = policy.type === CONST.POLICY.TYPE.CORPORATE;
const inputDate = new Date(updatedTransaction.modifiedCreated ?? updatedTransaction.created);
const shouldDisplayFutureDateViolation = !isInvoiceTransaction && DateUtils.isFutureDay(inputDate) && isControlPolicy;
const hasReceiptRequiredViolation = transactionViolations.some((violation) => violation.name === 'receiptRequired');
const hasOverLimitViolation = transactionViolations.some((violation) => violation.name === 'overLimit');
const amount = updatedTransaction.modifiedAmount ?? updatedTransaction.amount;
const shouldShowReceiptRequiredViolation =
!isInvoiceTransaction &&
policy.maxExpenseAmountNoReceipt &&
Math.abs(amount) > policy.maxExpenseAmountNoReceipt &&
!TransactionUtils.hasReceipt(updatedTransaction) &&
isControlPolicy;
const shouldShowOverLimitViolation = !isInvoiceTransaction && policy.maxExpenseAmount && Math.abs(amount) > policy.maxExpenseAmount && isControlPolicy;
const hasFutureDateViolation = transactionViolations.some((violation) => violation.name === 'futureDate');
// Add 'futureDate' violation if transaction date is in the future and policy type is corporate
if (!hasFutureDateViolation && shouldDisplayFutureDateViolation) {
newTransactionViolations.push({name: CONST.VIOLATIONS.FUTURE_DATE, type: CONST.VIOLATION_TYPES.VIOLATION, showInReview: true});
}

// Remove 'futureDate' violation if transaction date is not in the future
if (hasFutureDateViolation && !shouldDisplayFutureDateViolation) {
newTransactionViolations = reject(newTransactionViolations, {name: CONST.VIOLATIONS.FUTURE_DATE});
}

if (!hasReceiptRequiredViolation && shouldShowReceiptRequiredViolation) {
newTransactionViolations.push({
name: CONST.VIOLATIONS.RECEIPT_REQUIRED,
data: {
formattedLimit: CurrencyUtils.convertAmountToDisplayString(policy.maxExpenseAmountNoReceipt, policy.outputCurrency),
},
type: CONST.VIOLATION_TYPES.VIOLATION,
showInReview: true,
});
}

if (hasReceiptRequiredViolation && !shouldShowReceiptRequiredViolation) {
newTransactionViolations = reject(newTransactionViolations, {name: CONST.VIOLATIONS.RECEIPT_REQUIRED});
}

if (!hasOverLimitViolation && shouldShowOverLimitViolation) {
newTransactionViolations.push({
name: CONST.VIOLATIONS.OVER_LIMIT,
data: {
formattedLimit: CurrencyUtils.convertAmountToDisplayString(policy.maxExpenseAmount, policy.outputCurrency),
},
type: CONST.VIOLATION_TYPES.VIOLATION,
showInReview: true,
});
}

if (hasOverLimitViolation && !shouldShowOverLimitViolation) {
newTransactionViolations = reject(newTransactionViolations, {name: CONST.VIOLATIONS.OVER_LIMIT});
}

return {
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${updatedTransaction.transactionID}`,
Expand Down
35 changes: 31 additions & 4 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1414,7 +1414,15 @@ function buildOnyxDataForMoneyRequest(moneyRequestParams: BuildOnyxDataForMoneyR
return [optimisticData, successData, failureData];
}

const violationsOnyxData = ViolationsUtils.getViolationsOnyxData(transaction, [], policy, policyTagList ?? {}, policyCategories ?? {}, hasDependentTags(policy, policyTagList ?? {}));
const violationsOnyxData = ViolationsUtils.getViolationsOnyxData(
transaction,
[],
policy,
policyTagList ?? {},
policyCategories ?? {},
hasDependentTags(policy, policyTagList ?? {}),
false,
);

if (violationsOnyxData) {
optimisticData.push(violationsOnyxData);
Expand Down Expand Up @@ -1804,7 +1812,15 @@ function buildOnyxDataForInvoice(
return [optimisticData, successData, failureData];
}

const violationsOnyxData = ViolationsUtils.getViolationsOnyxData(transaction, [], policy, policyTagList ?? {}, policyCategories ?? {}, hasDependentTags(policy, policyTagList ?? {}));
const violationsOnyxData = ViolationsUtils.getViolationsOnyxData(
transaction,
[],
policy,
policyTagList ?? {},
policyCategories ?? {},
hasDependentTags(policy, policyTagList ?? {}),
true,
);

if (violationsOnyxData) {
optimisticData.push(violationsOnyxData);
Expand Down Expand Up @@ -2177,7 +2193,15 @@ function buildOnyxDataForTrackExpense(
return [optimisticData, successData, failureData];
}

const violationsOnyxData = ViolationsUtils.getViolationsOnyxData(transaction, [], policy, policyTagList ?? {}, policyCategories ?? {}, hasDependentTags(policy, policyTagList ?? {}));
const violationsOnyxData = ViolationsUtils.getViolationsOnyxData(
transaction,
[],
policy,
policyTagList ?? {},
policyCategories ?? {},
hasDependentTags(policy, policyTagList ?? {}),
false,
);

if (violationsOnyxData) {
optimisticData.push(violationsOnyxData);
Expand Down Expand Up @@ -3334,6 +3358,8 @@ function getUpdateMoneyRequestParams(

const hasPendingWaypoints = 'waypoints' in transactionChanges;
const hasModifiedDistanceRate = 'customUnitRateID' in transactionChanges;
const hasModifiedCreated = 'created' in transactionChanges;
const hasModifiedAmount = 'amount' in transactionChanges;
if (transaction && updatedTransaction && (hasPendingWaypoints || hasModifiedDistanceRate)) {
// Delete the draft transaction when editing waypoints when the server responds successfully and there are no errors
successData.push({
Expand Down Expand Up @@ -3593,7 +3619,7 @@ function getUpdateMoneyRequestParams(
});
}

if (policy && isPaidGroupPolicy(policy) && updatedTransaction && (hasModifiedTag || hasModifiedCategory || hasModifiedDistanceRate)) {
if (policy && isPaidGroupPolicy(policy) && updatedTransaction && (hasModifiedTag || hasModifiedCategory || hasModifiedDistanceRate || hasModifiedAmount || hasModifiedCreated)) {
const currentTransactionViolations = allTransactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`] ?? [];
const violationsOnyxdata = ViolationsUtils.getViolationsOnyxData(
updatedTransaction,
Expand All @@ -3602,6 +3628,7 @@ function getUpdateMoneyRequestParams(
policyTagList ?? {},
policyCategories ?? {},
hasDependentTags(policy, policyTagList ?? {}),
isInvoiceReportReportUtils(iouReport),
);
optimisticData.push(violationsOnyxdata);
failureData.push({
Expand Down
3 changes: 2 additions & 1 deletion src/pages/iou/request/step/IOURequestStepAmount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ function IOURequestStepAmount({

const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID}`);
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`);
const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`);
const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST);
const [draftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`);
const [splitDraftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`);
Expand Down Expand Up @@ -284,7 +285,7 @@ function IOURequestStepAmount({
return;
}

updateMoneyRequestAmountAndCurrency({transactionID, transactionThreadReportID: reportID, currency, amount: newAmount, taxAmount, policy, taxCode});
updateMoneyRequestAmountAndCurrency({transactionID, transactionThreadReportID: reportID, currency, amount: newAmount, taxAmount, policy, taxCode, policyCategories});
navigateBack();
};

Expand Down
Loading

0 comments on commit 631006e

Please sign in to comment.