Skip to content

Commit 8382898

Browse files
committed
feat: refactor replaceReceipt, remove onyx.connect() usage and add useOnyx hooks to components/hooks calling this function
1 parent 22c81bf commit 8382898

11 files changed

Lines changed: 39 additions & 39 deletions

File tree

__mocks__/reportData/violations.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const receiptErrorsR14932: ReceiptErrors = {
3333
transactionID: RECEIPT_ERRORS_TRANSACTION_ID_R14932,
3434
source: CONST.POLICY.ID_FAKE,
3535
transactionPolicy: undefined,
36+
policyTagList: undefined,
3637
},
3738
},
3839
};

src/components/ReportActionItem/MoneyRequestReceiptView.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ function MoneyRequestReceiptView({
173173
const deviceHasHoverSupport = hasHoverSupport();
174174
const lazyIcons = useMemoizedLazyExpensifyIcons(['Expand', 'ReceiptPlus']);
175175

176+
const [policyTagList] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policy?.id}`);
177+
176178
// Browsers don't fire mouseenter when an element mounts under the cursor
177179
useEffect(() => {
178180
if (isLoading) {
@@ -441,7 +443,7 @@ function MoneyRequestReceiptView({
441443
return;
442444
}
443445
const source = URL.createObjectURL(file as Blob);
444-
replaceReceipt({transactionID: linkedTransactionID, file: file as File, source, transactionPolicy: policy, transactionPolicyCategories: policyCategories});
446+
replaceReceipt({transactionID: linkedTransactionID, file: file as File, source, transactionPolicy: policy, transactionPolicyCategories: policyCategories, policyTagList});
445447
};
446448

447449
// For empty receipt should be fullHeight

src/libs/actions/IOU/Receipt.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,7 @@ import type * as OnyxTypes from '@src/types/onyx';
2020
import type {ReceiptSource} from '@src/types/onyx/Transaction';
2121
import {isEmptyObject} from '@src/types/utils/EmptyObject';
2222
import type {ReplaceReceipt} from '.';
23-
import {getAllReports, getAllTransactions, getAllTransactionViolations, getPolicyTags, getReceiptError} from '.';
24-
25-
/**
26-
* @deprecated This function uses Onyx.connect and should be replaced with useOnyx for reactive data access.
27-
* TODO: remove `getPolicyTagsData` from this file https://github.com/Expensify/App/issues/80048
28-
*/
29-
function getPolicyTagsData(policyID: string | undefined) {
30-
const allPolicyTags = getPolicyTags();
31-
return allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] ?? {};
32-
}
23+
import {getAllReports, getAllTransactions, getAllTransactionViolations, getReceiptError} from '.';
3324

3425
function detachReceipt(
3526
transactionID: string | undefined,
@@ -169,7 +160,7 @@ function detachReceipt(
169160
);
170161
}
171162

172-
function replaceReceipt({transactionID, file, source, state, transactionPolicy, transactionPolicyCategories, isSameReceipt}: ReplaceReceipt) {
163+
function replaceReceipt({transactionID, file, source, state, transactionPolicy, transactionPolicyCategories, isSameReceipt, policyTagList}: ReplaceReceipt) {
173164
if (!file) {
174165
return;
175166
}
@@ -188,7 +179,7 @@ function replaceReceipt({transactionID, file, source, state, transactionPolicy,
188179
filename: file.name,
189180
};
190181
const newTransaction = transaction && {...transaction, receipt: receiptOptimistic};
191-
const retryParams: ReplaceReceipt = {transactionID, file: undefined, source, transactionPolicy, transactionPolicyCategories};
182+
const retryParams: ReplaceReceipt = {transactionID, file: undefined, source, transactionPolicy, transactionPolicyCategories, policyTagList};
192183
const currentSearchQueryJSON = getCurrentSearchQueryJSON();
193184

194185
const optimisticData: Array<OnyxUpdate<typeof ONYXKEYS.COLLECTION.TRANSACTION | typeof ONYXKEYS.COLLECTION.SNAPSHOT | typeof ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS>> = [
@@ -232,9 +223,6 @@ function replaceReceipt({transactionID, file, source, state, transactionPolicy,
232223
];
233224

234225
if (transactionPolicy && isPaidGroupPolicy(transactionPolicy) && newTransaction) {
235-
// TODO: Replace getPolicyTagsData (https://github.com/Expensify/App/issues/72721) and getPolicyRecentlyUsedTagsData (https://github.com/Expensify/App/issues/71491) with useOnyx hook
236-
// eslint-disable-next-line @typescript-eslint/no-deprecated
237-
const policyTagList = getPolicyTagsData(transactionPolicy.id);
238226
const currentTransactionViolations = allTransactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`] ?? [];
239227
const violationsOnyxData = ViolationsUtils.getViolationsOnyxData(
240228
newTransaction,

src/libs/actions/IOU/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ type ReplaceReceipt = {
417417
transactionPolicyCategories?: OnyxEntry<OnyxTypes.PolicyCategories>;
418418
transactionPolicy: OnyxEntry<OnyxTypes.Policy>;
419419
isSameReceipt?: boolean;
420+
policyTagList: OnyxEntry<OnyxTypes.PolicyTagLists>;
420421
};
421422

422423
type GetSearchOnyxUpdateParams = {

src/pages/inbox/report/ReportActionCompose/useAttachmentUploadValidation.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ function useAttachmentUploadValidation({
6262
const [userBillingGracePeriodEnds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END);
6363
const [draftTransactionIDs] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, {selector: validTransactionDraftIDsSelector});
6464

65+
const [policyTagList] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policy?.id}`);
66+
6567
const reportAttachmentsContext = useContext(AttachmentModalContext);
6668
const showAttachmentModalScreen = useCallback(
6769
(file: FileObject | FileObject[], dataTransferItems?: DataTransferItem[]) => {
@@ -93,7 +95,7 @@ function useAttachmentUploadValidation({
9395

9496
if (shouldAddOrReplaceReceipt && transactionID) {
9597
const source = URL.createObjectURL(files.at(0) as Blob);
96-
replaceReceipt({transactionID, file: files.at(0) as File, source, transactionPolicy: policy, transactionPolicyCategories: policyCategories});
98+
replaceReceipt({transactionID, file: files.at(0) as File, source, transactionPolicy: policy, transactionPolicyCategories: policyCategories, policyTagList});
9799
return;
98100
}
99101

src/pages/iou/request/step/IOURequestStepScan/index.native.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ function IOURequestStepScan({
127127

128128
const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${report?.policyID}`);
129129

130+
const [policyTagList] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policy?.id}`);
131+
130132
// Track camera init telemetry
131133
const cameraInitSpanStarted = useRef(false);
132134
const cameraInitialized = useRef(false);
@@ -215,9 +217,9 @@ function IOURequestStepScan({
215217
} else {
216218
navigateBack();
217219
}
218-
replaceReceipt({transactionID: initialTransactionID, file: file as File, source, transactionPolicy: policy, transactionPolicyCategories: policyCategories});
220+
replaceReceipt({transactionID: initialTransactionID, file: file as File, source, transactionPolicy: policy, transactionPolicyCategories: policyCategories, policyTagList});
219221
},
220-
[initialTransactionID, policy, policyCategories, backTo, navigateBack],
222+
[initialTransactionID, policy, policyCategories, backTo, navigateBack, policyTagList],
221223
);
222224

223225
const getSource = useCallback((file: FileObject) => file.uri ?? '', []);

src/pages/iou/request/step/IOURequestStepScan/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ function IOURequestStepScan({
4040
const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${report?.policyID}`);
4141
const [draftTransactionIDs] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, {selector: validTransactionDraftIDsSelector});
4242

43+
const [policyTagList] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policy?.id}`);
44+
4345
// End the create expense span on mount for web (no camera init tracking needed)
4446
useEffect(() => {
4547
endSpan(CONST.TELEMETRY.SPAN_OPEN_CREATE_EXPENSE);
@@ -51,10 +53,10 @@ function IOURequestStepScan({
5153

5254
const updateScanAndNavigate = useCallback(
5355
(file: FileObject, source: string) => {
54-
replaceReceipt({transactionID: initialTransactionID, file: file as File, source, transactionPolicy: policy, transactionPolicyCategories: policyCategories});
56+
replaceReceipt({transactionID: initialTransactionID, file: file as File, source, transactionPolicy: policy, transactionPolicyCategories: policyCategories, policyTagList});
5557
navigateBack();
5658
},
57-
[initialTransactionID, navigateBack, policy, policyCategories],
59+
[initialTransactionID, navigateBack, policy, policyCategories, policyTagList],
5860
);
5961

6062
const getSource = useCallback((file: FileObject) => file.uri ?? URL.createObjectURL(file as Blob), []);

src/pages/media/AttachmentModalScreen/routes/TransactionReceiptModalContent.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,13 @@ function TransactionReceiptModalContent({navigation, route}: AttachmentModalScre
300300
source: durableUri,
301301
transactionPolicyCategories: policyCategories,
302302
transactionPolicy: policy,
303+
policyTagList,
303304
...(isSameReceipt ? {state: transaction?.receipt?.state, isSameReceipt: true} : {}),
304305
});
305306
}
306307
});
307308
},
308-
[transaction, isDraftTransaction, isOdometerImage, isEditingConfirmation, imageType, fileType, policyCategories, policy],
309+
[transaction, isDraftTransaction, isOdometerImage, isEditingConfirmation, imageType, fileType, policyCategories, policy, policyTagList],
309310
);
310311

311312
const rotateReceipt = useCallback(() => {

tests/actions/IOUTest/ReceiptTest.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ describe('actions/IOU/Receipt', () => {
160160
await setupTransactionWithSnapshot(transactionID, {receipt: {source: 'original.jpg'}});
161161

162162
// When replaceReceipt is called without a file
163-
replaceReceipt({transactionID, file: undefined, source, transactionPolicy: undefined});
163+
replaceReceipt({transactionID, file: undefined, source, transactionPolicy: undefined, policyTagList: undefined});
164164
await waitForBatchedUpdates();
165165

166166
// Then the receipt source remains unchanged
@@ -173,7 +173,7 @@ describe('actions/IOU/Receipt', () => {
173173
await setupTransactionWithSnapshot(transactionID, {receipt: {source: 'test1'}});
174174

175175
// When replaceReceipt is called with a new file
176-
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined});
176+
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined, policyTagList: undefined});
177177
await waitForBatchedUpdates();
178178

179179
// Then both the transaction and its snapshot entry reflect the new receipt
@@ -191,7 +191,7 @@ describe('actions/IOU/Receipt', () => {
191191
await setupTransactionWithSnapshot(transactionID, {receipt: {source: 'test1', state: CONST.IOU.RECEIPT_STATE.SCAN_READY}});
192192

193193
// When replaceReceipt is called with the same state explicitly passed
194-
replaceReceipt({transactionID, file: createFile(), source, state: CONST.IOU.RECEIPT_STATE.SCAN_READY, transactionPolicy: undefined});
194+
replaceReceipt({transactionID, file: createFile(), source, state: CONST.IOU.RECEIPT_STATE.SCAN_READY, transactionPolicy: undefined, policyTagList: undefined});
195195
await waitForBatchedUpdates();
196196

197197
// Then the new receipt retains the provided state instead of falling back to OPEN
@@ -209,7 +209,7 @@ describe('actions/IOU/Receipt', () => {
209209
await setupTransactionWithSnapshot(transactionID);
210210

211211
// When replaceReceipt is called
212-
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined});
212+
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined, policyTagList: undefined});
213213
await waitForBatchedUpdates();
214214

215215
// Then the receipt is created with the new source on both the transaction and snapshot
@@ -229,7 +229,7 @@ describe('actions/IOU/Receipt', () => {
229229

230230
try {
231231
// When replaceReceipt is called
232-
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined});
232+
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined, policyTagList: undefined});
233233
await waitForBatchedUpdates();
234234

235235
// Then the optimisticData marks the receipt field as pending UPDATE
@@ -253,7 +253,7 @@ describe('actions/IOU/Receipt', () => {
253253

254254
try {
255255
// When replaceReceipt is called
256-
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined});
256+
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined, policyTagList: undefined});
257257
await waitForBatchedUpdates();
258258

259259
// Then API.write is invoked with the REPLACE_RECEIPT command and the correct transactionID
@@ -291,7 +291,7 @@ describe('actions/IOU/Receipt', () => {
291291
await waitForBatchedUpdates();
292292

293293
// When replaceReceipt is called with the paid group policy
294-
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: policy});
294+
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: policy, policyTagList: undefined});
295295
await waitForBatchedUpdates();
296296

297297
// Then transaction violations are computed and stored
@@ -307,7 +307,7 @@ describe('actions/IOU/Receipt', () => {
307307

308308
try {
309309
// When replaceReceipt is called
310-
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined});
310+
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined, policyTagList: undefined});
311311
await waitForBatchedUpdates();
312312

313313
// Then the failureData restores the original receipt, clears pendingFields, and attaches errors
@@ -332,7 +332,7 @@ describe('actions/IOU/Receipt', () => {
332332

333333
try {
334334
// When replaceReceipt is called
335-
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined});
335+
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined, policyTagList: undefined});
336336
await waitForBatchedUpdates();
337337

338338
// Then the failureData sets receipt to null since there was nothing to restore
@@ -356,7 +356,7 @@ describe('actions/IOU/Receipt', () => {
356356

357357
try {
358358
// When replaceReceipt is called
359-
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined});
359+
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined, policyTagList: undefined});
360360
await waitForBatchedUpdates();
361361

362362
// Then the successData clears the pending field for the receipt
@@ -378,7 +378,7 @@ describe('actions/IOU/Receipt', () => {
378378

379379
try {
380380
// When replaceReceipt is called
381-
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined});
381+
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined, policyTagList: undefined});
382382
await waitForBatchedUpdates();
383383

384384
// Then no snapshot updates are included in either optimisticData or failureData
@@ -399,7 +399,7 @@ describe('actions/IOU/Receipt', () => {
399399

400400
try {
401401
// When replaceReceipt is called
402-
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined});
402+
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: undefined, policyTagList: undefined});
403403
await waitForBatchedUpdates();
404404

405405
// Then the failureData restores the original receipt inside the snapshot entry
@@ -425,6 +425,7 @@ describe('actions/IOU/Receipt', () => {
425425
source,
426426
state: CONST.IOU.RECEIPT_STATE.SCAN_READY,
427427
transactionPolicy: undefined,
428+
policyTagList: undefined,
428429
isSameReceipt: true,
429430
});
430431
await waitForBatchedUpdates();
@@ -475,7 +476,7 @@ describe('actions/IOU/Receipt', () => {
475476
// When replaceReceipt is called with the paid group policy
476477
const writeSpy = mockApiWrite();
477478
try {
478-
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: policy});
479+
replaceReceipt({transactionID, file: createFile(), source, transactionPolicy: policy, policyTagList: undefined});
479480
await waitForBatchedUpdates();
480481

481482
// Then the failureData restores the original violations

tests/unit/SidebarUtilsTest.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ describe('SidebarUtils', () => {
737737
source: '',
738738
filename: 'download.jpeg',
739739
action: 'replaceReceipt',
740-
retryParams: {transactionID: '', source: '', transactionPolicy: undefined},
740+
retryParams: {transactionID: '', source: '', transactionPolicy: undefined, policyTagList: undefined},
741741
},
742742
},
743743
created: '2024-08-08 18:20:44.171',
@@ -835,7 +835,7 @@ describe('SidebarUtils', () => {
835835
source: '',
836836
filename: 'download.jpeg',
837837
action: 'replaceReceipt',
838-
retryParams: {transactionID: '', source: '', transactionPolicy: undefined},
838+
retryParams: {transactionID: '', source: '', transactionPolicy: undefined, policyTagList: undefined},
839839
},
840840
},
841841
created: '2024-08-08 18:20:44.171',

0 commit comments

Comments
 (0)