Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"test:debug": "TZ=utc NODE_OPTIONS='--inspect-brk --experimental-vm-modules' jest --runInBand",
"perf-test": "NODE_OPTIONS=--experimental-vm-modules npx reassure",
"typecheck": "NODE_OPTIONS=--max_old_space_size=8192 tsc",
"lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=280 --cache --cache-location=node_modules/.cache/eslint",
"lint": "NODE_OPTIONS=--max_old_space_size=8192 eslint . --max-warnings=278 --cache --cache-location=node_modules/.cache/eslint",
"lint-changed": "NODE_OPTIONS=--max_old_space_size=8192 ./scripts/lintChanged.sh",
"lint-watch": "npx eslint-watch --watch --changed",
"shellcheck": "./scripts/shellCheck.sh",
Expand Down
58 changes: 19 additions & 39 deletions src/libs/actions/Policy/DistanceRate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
import * as ReportUtils from '@libs/ReportUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Policy, Report, Transaction, TransactionViolation} from '@src/types/onyx';
import type {Policy, Report, TransactionViolation} from '@src/types/onyx';
import type {ErrorFields} from '@src/types/onyx/OnyxCommon';
import type {CustomUnit, Rate} from '@src/types/onyx/Policy';
import type {OnyxData} from '@src/types/onyx/Request';

const allPolicies: OnyxCollection<Policy> = {};
Onyx.connect({

Check warning on line 27 in src/libs/actions/Policy/DistanceRate.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.POLICY,
callback: (val, key) => {
if (!key) {
Expand Down Expand Up @@ -56,29 +56,6 @@
},
});

let allTransactions: NonNullable<OnyxCollection<Transaction>> = {};
Onyx.connect({
key: ONYXKEYS.COLLECTION.TRANSACTION,
waitForCollectionCallback: true,
callback: (value) => {
if (!value) {
allTransactions = {};
return;
}

allTransactions = value;
},
});

let transactionViolations: OnyxCollection<TransactionViolation[]>;
Onyx.connect({
key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS,
waitForCollectionCallback: true,
callback: (value) => {
transactionViolations = value;
},
});

/**
* Takes array of customUnitRates and removes pendingFields and errorFields from each rate - we don't want to send those via API
*/
Expand Down Expand Up @@ -451,7 +428,13 @@
API.write(WRITE_COMMANDS.SET_POLICY_DISTANCE_RATES_ENABLED, params, {optimisticData, successData, failureData});
}

function deletePolicyDistanceRates(policyID: string, customUnit: CustomUnit, rateIDsToDelete: string[]) {
function deletePolicyDistanceRates(
policyID: string,
customUnit: CustomUnit,
rateIDsToDelete: string[],
transactionIDsAffected: string[],
transactionViolations: OnyxCollection<TransactionViolation[]>,
) {
const currentRates = customUnit.rates;
const optimisticRates: Record<string, Rate> = {};
const successRates: Record<string, Rate> = {};
Expand Down Expand Up @@ -520,22 +503,18 @@
},
];

const transactions = Object.values(allTransactions ?? {}).filter(
(transaction) =>
transaction?.comment?.customUnit?.customUnitID === customUnit.customUnitID &&
transaction?.comment?.customUnit?.customUnitRateID &&
rateIDsToDelete.includes(transaction?.comment?.customUnit?.customUnitRateID),
);
const optimisticTransactionsViolations: OnyxUpdate[] = [];
const failureTransactionsViolations: OnyxUpdate[] = [];

transactions.forEach((transaction) => {
const currentTransactionViolations = transactionViolations?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction?.transactionID}`] ?? [];
for (const transactionID of transactionIDsAffected) {
const currentTransactionViolations = transactionViolations?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`] ?? [];
if (currentTransactionViolations.some((violation) => violation.name === CONST.VIOLATIONS.CUSTOM_UNIT_OUT_OF_POLICY)) {
return;
}

optimisticTransactionsViolations.push({
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction?.transactionID}`,
key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`,
value: [
...currentTransactionViolations,
{
Expand All @@ -545,12 +524,13 @@
},
],
});
});

const failureTransactionsViolations: OnyxUpdate[] = transactions.map((transaction) => {
const currentTransactionViolations = transactionViolations?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction?.transactionID}`];
return {onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transaction?.transactionID}`, value: currentTransactionViolations};
});
failureTransactionsViolations.push({
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`,
value: currentTransactionViolations,
});
}

optimisticData.push(...optimisticTransactionsViolations);
failureData.push(...failureTransactionsViolations);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,42 @@ function PolicyDistanceRateDetailsPage({route}: PolicyDistanceRateDetailsPagePro
const policyID = route.params.policyID;
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${route.params.policyID}`, {canBeMissing: true});
const rateID = route.params.rateID;

const customUnit = getDistanceRateCustomUnit(policy);
const rate = customUnit?.rates[rateID];
const customUnitID = customUnit?.customUnitID;
const [eligibleTransactionIDs] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION, {
selector: (transactions) => {
return Object.values(transactions ?? {}).reduce((transactionIDs, transaction) => {
if (
transaction &&
customUnitID &&
transaction?.comment?.customUnit?.customUnitID === customUnitID &&
transaction?.comment?.customUnit?.customUnitRateID &&
transaction?.comment?.customUnit?.customUnitRateID === rateID
) {
transactionIDs.add(transaction?.transactionID);
}
return transactionIDs;
}, new Set<string>());
},
canBeMissing: true,
});

const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {
selector: (violations) => {
if (!eligibleTransactionIDs || eligibleTransactionIDs.size === 0) {
return undefined;
}
return Object.fromEntries(
Object.entries(violations ?? {}).filter(([key]) => {
const id = key.replace(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, '');
return eligibleTransactionIDs?.has(id);
}),
);
},
canBeMissing: true,
});

const currency = rate?.currency ?? CONST.CURRENCY.USD;
const taxClaimablePercentage = rate?.attributes?.taxClaimablePercentage;
const taxRateExternalID = rate?.attributes?.taxRateExternalID;
Expand Down Expand Up @@ -83,7 +116,7 @@ function PolicyDistanceRateDetailsPage({route}: PolicyDistanceRateDetailsPagePro

const deleteRate = () => {
Navigation.goBack();
deletePolicyDistanceRates(policyID, customUnit, [rateID]);
deletePolicyDistanceRates(policyID, customUnit, [rateID], Array.from(eligibleTransactionIDs ?? []), transactionViolations);
setIsDeleteModalVisible(false);
};

Expand Down
54 changes: 53 additions & 1 deletion src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import useFilteredSelection from '@hooks/useFilteredSelection';
import useLocalize from '@hooks/useLocalize';
import useMobileSelectionMode from '@hooks/useMobileSelectionMode';
import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
import usePolicy from '@hooks/usePolicy';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useSearchBackPress from '@hooks/useSearchBackPress';
Expand All @@ -42,6 +43,7 @@ import type {WorkspaceSplitNavigatorParamList} from '@navigation/types';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import ButtonWithDropdownMenu from '@src/components/ButtonWithDropdownMenu';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import type {Rate} from '@src/types/onyx/Policy';
Expand Down Expand Up @@ -78,6 +80,54 @@ function PolicyDistanceRatesPage({
[customUnitRates],
);

const rateIDs = new Set(Object.keys(selectableRates));

const [eligibleTransactionsData] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION, {
selector: (transactions) => {
if (!customUnit?.customUnitID || rateIDs.size === 0) {
return undefined;
}
return Object.values(transactions ?? {}).reduce(
(transactionsData, transaction) => {
if (
transaction &&
customUnit?.customUnitID &&
transaction?.comment?.customUnit?.customUnitID === customUnit.customUnitID &&
transaction?.comment?.customUnit?.customUnitRateID &&
rateIDs.has(transaction?.comment?.customUnit?.customUnitRateID)
) {
transactionsData.transactionIDs.add(transaction.transactionID);
if (!transactionsData.rateIDToTransactionIDsMap[transaction?.comment?.customUnit?.customUnitRateID]) {
// eslint-disable-next-line no-param-reassign
transactionsData.rateIDToTransactionIDsMap[transaction?.comment?.customUnit?.customUnitRateID] = [];
}
transactionsData.rateIDToTransactionIDsMap[transaction?.comment?.customUnit?.customUnitRateID]?.push(transaction?.transactionID);
}
return transactionsData;
},
{transactionIDs: new Set<string>(), rateIDToTransactionIDsMap: {} as Record<string, string[]>},
);
},
canBeMissing: true,
});

const eligibleTransactionIDs = eligibleTransactionsData?.transactionIDs;

const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {
selector: (violations) => {
if (!eligibleTransactionIDs || eligibleTransactionIDs.size === 0) {
return undefined;
}
return Object.fromEntries(
Object.entries(violations ?? {}).filter(([key]) => {
const id = key.replace(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, '');
return eligibleTransactionIDs?.has(id);
}),
);
},
canBeMissing: true,
});

const filterRateSelection = useCallback(
(rate?: Rate) => !!rate && !!customUnitRates?.[rate.customUnitRateID] && customUnitRates?.[rate.customUnitRateID]?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE,
[customUnitRates],
Expand Down Expand Up @@ -235,7 +285,9 @@ function PolicyDistanceRatesPage({
return;
}

deletePolicyDistanceRates(policyID, customUnit, selectedDistanceRates);
const transactionIDsAffected = selectedDistanceRates.flatMap((rateID) => eligibleTransactionsData?.rateIDToTransactionIDsMap?.[rateID] ?? []);

deletePolicyDistanceRates(policyID, customUnit, selectedDistanceRates, transactionIDsAffected, transactionViolations);
setIsDeleteModalVisible(false);

InteractionManager.runAfterInteractions(() => {
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/DistanceRateTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe('DistanceRate', () => {
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy);

if (policy.customUnits) {
deletePolicyDistanceRates(policy.id, policy.customUnits[customUnitID], [customUnitRateID1]);
deletePolicyDistanceRates(policy.id, policy.customUnits[customUnitID], [customUnitRateID1], [transaction1.transactionID], undefined);
}
await waitForBatchedUpdates();
const transactionViolations = await new Promise<Record<string, TransactionViolations | undefined>>((resolve) => {
Expand Down
Loading