diff --git a/src/components/ReportActionItem/MoneyRequestPreview.js b/src/components/ReportActionItem/MoneyRequestPreview.js index 3a0741cf9bd2..2afc6240f85d 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview.js +++ b/src/components/ReportActionItem/MoneyRequestPreview.js @@ -170,7 +170,7 @@ function MoneyRequestPreview(props) { !_.isEmpty(requestMerchant) && !props.isBillSplit && requestMerchant !== CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT && requestMerchant !== CONST.TRANSACTION.DEFAULT_MERCHANT; const shouldShowDescription = !_.isEmpty(description) && !shouldShowMerchant; - const receiptImages = hasReceipt ? [ReceiptUtils.getThumbnailAndImageURIs(props.transaction.receipt.source, props.transaction.filename || props.transaction.receiptFilename || '')] : []; + const receiptImages = hasReceipt ? [ReceiptUtils.getThumbnailAndImageURIs(props.transaction.receipt.source, props.transaction.filename || '')] : []; const getSettledMessage = () => { switch (lodashGet(props.action, 'originalMessage.paymentType', '')) { diff --git a/src/components/ReportActionItem/ReportPreview.js b/src/components/ReportActionItem/ReportPreview.js index c14e40010b54..1350c62bda88 100644 --- a/src/components/ReportActionItem/ReportPreview.js +++ b/src/components/ReportActionItem/ReportPreview.js @@ -120,9 +120,7 @@ function ReportPreview(props) { const isScanning = hasReceipts && ReportUtils.areAllRequestsBeingSmartScanned(props.iouReportID, props.action); const hasErrors = hasReceipts && ReportUtils.hasMissingSmartscanFields(props.iouReportID); const lastThreeTransactionsWithReceipts = ReportUtils.getReportPreviewDisplayTransactions(props.action); - const lastThreeReceipts = _.map(lastThreeTransactionsWithReceipts, ({receipt, filename, receiptFilename}) => - ReceiptUtils.getThumbnailAndImageURIs(receipt.source, filename || receiptFilename || ''), - ); + const lastThreeReceipts = _.map(lastThreeTransactionsWithReceipts, ({receipt, filename}) => ReceiptUtils.getThumbnailAndImageURIs(receipt.source, filename || '')); const hasOnlyOneReceiptRequest = numberOfRequests === 1 && hasReceipts; const previewSubtitle = hasOnlyOneReceiptRequest diff --git a/src/libs/migrateOnyx.js b/src/libs/migrateOnyx.js index 5b4b05598165..e401cbd9db69 100644 --- a/src/libs/migrateOnyx.js +++ b/src/libs/migrateOnyx.js @@ -6,6 +6,7 @@ import MoveToIndexedDB from './migrations/MoveToIndexedDB'; import RenameExpensifyNewsStatus from './migrations/RenameExpensifyNewsStatus'; import AddLastVisibleActionCreated from './migrations/AddLastVisibleActionCreated'; import PersonalDetailsByAccountID from './migrations/PersonalDetailsByAccountID'; +import RenameReceiptFilename from './migrations/RenameReceiptFilename'; export default function () { const startTime = Date.now(); @@ -13,7 +14,15 @@ export default function () { return new Promise((resolve) => { // Add all migrations to an array so they are executed in order - const migrationPromises = [MoveToIndexedDB, RenamePriorityModeKey, AddEncryptedAuthToken, RenameExpensifyNewsStatus, AddLastVisibleActionCreated, PersonalDetailsByAccountID]; + const migrationPromises = [ + MoveToIndexedDB, + RenamePriorityModeKey, + AddEncryptedAuthToken, + RenameExpensifyNewsStatus, + AddLastVisibleActionCreated, + PersonalDetailsByAccountID, + RenameReceiptFilename, + ]; // Reduce all promises down to a single promise. All promises run in a linear fashion, waiting for the // previous promise to finish before moving onto the next one. diff --git a/src/libs/migrations/RenameReceiptFilename.js b/src/libs/migrations/RenameReceiptFilename.js new file mode 100644 index 000000000000..b8df705fd7d1 --- /dev/null +++ b/src/libs/migrations/RenameReceiptFilename.js @@ -0,0 +1,57 @@ +import Onyx from 'react-native-onyx'; +import _ from 'underscore'; +import lodashHas from 'lodash/has'; +import ONYXKEYS from '../../ONYXKEYS'; +import Log from '../Log'; + +// This migration changes the property name on a transaction from receiptFilename to filename so that it matches what is stored in the database +export default function () { + return new Promise((resolve) => { + // Connect to the TRANSACTION collection key in Onyx to get all of the stored transactions. + // Go through each transaction and change the property name + const connectionID = Onyx.connect({ + key: ONYXKEYS.COLLECTION.TRANSACTION, + waitForCollectionCallback: true, + callback: (transactions) => { + Onyx.disconnect(connectionID); + + if (!transactions || transactions.length === 0) { + Log.info('[Migrate Onyx] Skipped migration RenameReceiptFilename because there are no transactions'); + return resolve(); + } + + if (!_.compact(_.pluck(transactions, 'receiptFilename')).length) { + Log.info('[Migrate Onyx] Skipped migration RenameReceiptFilename because there were no transactions with the receiptFilename property'); + return resolve(); + } + + Log.info('[Migrate Onyx] Running RenameReceiptFilename migration'); + + const dataToSave = _.reduce( + transactions, + (result, transaction) => { + // Do nothing if there is no receiptFilename property + if (!lodashHas(transaction, 'receiptFilename')) { + return result; + } + Log.info(`[Migrate Onyx] Renaming receiptFilename ${transaction.receiptFilename} to filename`); + return { + ...result, + [`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`]: { + filename: transaction.receiptFilename, + receiptFilename: null, + }, + }; + }, + {}, + ); + + // eslint-disable-next-line rulesdir/prefer-actions-set-data + Onyx.mergeCollection(ONYXKEYS.COLLECTION.TRANSACTION, dataToSave).then(() => { + Log.info(`[Migrate Onyx] Ran migration RenameReceiptFilename and renamed ${_.size(dataToSave)} properties`); + resolve(); + }); + }, + }); + }); +} diff --git a/src/types/onyx/Transaction.ts b/src/types/onyx/Transaction.ts index de128d85e6b1..ea0b178444b5 100644 --- a/src/types/onyx/Transaction.ts +++ b/src/types/onyx/Transaction.ts @@ -19,25 +19,27 @@ type Route = { type Routes = Record; type Transaction = { - transactionID: string; amount: number; category: string; - currency: string; - reportID: string; comment: Comment; - merchant: string; created: string; - pendingAction: OnyxCommon.PendingAction; + currency: string; errors: OnyxCommon.Errors; + // The name of the file used for a receipt (formerly receiptFilename) + filename?: string; + merchant: string; modifiedAmount?: number; modifiedCreated?: string; modifiedCurrency?: string; + pendingAction: OnyxCommon.PendingAction; receipt: { receiptID?: number; source?: string; state?: ValueOf; }; + reportID: string; routes?: Routes; + transactionID: string; tag: string; };