diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index e3329532f324..acaa83181bbf 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -114,8 +114,8 @@ const propTypes = { /** File path of the receipt */ receiptPath: PropTypes.string, - /** File source of the receipt */ - receiptSource: PropTypes.string, + /** File name of the receipt */ + receiptFilename: PropTypes.string, /** List styles for OptionsSelector */ listStyles: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]), @@ -141,6 +141,9 @@ const propTypes = { /** Whether the money request is a distance request */ isDistanceRequest: PropTypes.bool, + /** Whether the receipt associated with this report is being scanned */ + isScanning: PropTypes.bool, + /** A flag for verifying that the current report is a sub-report of a workspace chat */ isPolicyExpenseChat: PropTypes.bool, @@ -171,7 +174,7 @@ const defaultProps = { reportID: '', ...withCurrentUserPersonalDetailsDefaultProps, receiptPath: '', - receiptSource: '', + receiptFilename: '', listStyles: [], policyCategories: {}, policyTags: {}, @@ -179,6 +182,7 @@ const defaultProps = { transaction: {}, mileageRate: {unit: CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES, rate: 0, currency: 'USD'}, isDistanceRequest: false, + isScanning: false, isPolicyExpenseChat: false, }; @@ -188,9 +192,6 @@ function MoneyRequestConfirmationList(props) { const {onSendMoney, onConfirm, onSelectParticipant, transaction} = props; const {translate, toLocaleDigit} = useLocalize(); - // A flag and a toggler for showing the rest of the form fields - const [shouldExpandFields, toggleShouldExpandFields] = useReducer((state) => !state, false); - const shouldShowAllFields = props.isDistanceRequest || shouldExpandFields; const isTypeRequest = props.iouType === CONST.IOU.MONEY_REQUEST_TYPE.REQUEST; const {unit, rate, currency} = props.mileageRate; @@ -201,6 +202,14 @@ function MoneyRequestConfirmationList(props) { const shouldShowCategories = props.isPolicyExpenseChat && Permissions.canUseCategories(props.betas) && (props.iouCategory || OptionsListUtils.hasEnabledOptions(_.values(props.policyCategories))); + // A flag for showing SmartScan fields: date, merchant, and amount, only when we don't have a receiptPath (e.g. manual request) + // or in the split details page which is ReadOnly + const shouldShowSmartScanFields = (!props.receiptPath || props.isReadOnly) && !props.isScanning; + + // A flag and a toggler for showing the rest of the form fields + const [shouldExpandFields, toggleShouldExpandFields] = useReducer((state) => !state, false); + const shouldShowAllFields = props.isDistanceRequest || shouldExpandFields || !shouldShowSmartScanFields; + // Fetches the first tag list of the policy const policyTag = PolicyUtils.getTag(props.policyTags); const policyTagList = lodashGet(policyTag, 'tags', {}); @@ -245,7 +254,10 @@ function MoneyRequestConfirmationList(props) { const getParticipantsWithAmount = useCallback( (participantsList) => { const iouAmount = IOUUtils.calculateAmount(participantsList.length, props.iouAmount, props.iouCurrencyCode); - return OptionsListUtils.getIOUConfirmationOptionsFromParticipants(participantsList, CurrencyUtils.convertToDisplayString(iouAmount, props.iouCurrencyCode)); + return OptionsListUtils.getIOUConfirmationOptionsFromParticipants( + participantsList, + props.iouAmount > 0 ? CurrencyUtils.convertToDisplayString(iouAmount, props.iouCurrencyCode) : '', + ); }, [props.iouAmount, props.iouCurrencyCode], ); @@ -254,7 +266,9 @@ function MoneyRequestConfirmationList(props) { const splitOrRequestOptions = useMemo(() => { let text; - if (props.receiptPath || isDistanceRequestWithoutRoute) { + if (props.receiptPath && props.hasMultipleParticipants && props.iouAmount === 0) { + text = translate('iou.split'); + } else if (props.receiptPath || isDistanceRequestWithoutRoute) { text = translate('iou.request'); } else { const translationKey = props.hasMultipleParticipants ? 'iou.splitAmount' : 'iou.requestAmount'; @@ -266,7 +280,7 @@ function MoneyRequestConfirmationList(props) { value: props.hasMultipleParticipants ? CONST.IOU.MONEY_REQUEST_TYPE.SPLIT : CONST.IOU.MONEY_REQUEST_TYPE.REQUEST, }, ]; - }, [props.hasMultipleParticipants, props.receiptPath, translate, formattedAmount, isDistanceRequestWithoutRoute]); + }, [props.hasMultipleParticipants, props.iouAmount, props.receiptPath, translate, formattedAmount, isDistanceRequestWithoutRoute]); const selectedParticipants = useMemo(() => _.filter(props.selectedParticipants, (participant) => participant.selected), [props.selectedParticipants]); const payeePersonalDetails = useMemo(() => props.payeePersonalDetails || props.currentUserPersonalDetails, [props.payeePersonalDetails, props.currentUserPersonalDetails]); @@ -290,7 +304,7 @@ function MoneyRequestConfirmationList(props) { const myIOUAmount = IOUUtils.calculateAmount(selectedParticipants.length, props.iouAmount, props.iouCurrencyCode, true); const formattedPayeeOption = OptionsListUtils.getIOUConfirmationOptionsFromPayeePersonalDetail( payeePersonalDetails, - CurrencyUtils.convertToDisplayString(myIOUAmount, props.iouCurrencyCode), + props.iouAmount > 0 ? CurrencyUtils.convertToDisplayString(myIOUAmount, props.iouCurrencyCode) : '', ); sections.push( @@ -459,6 +473,9 @@ function MoneyRequestConfirmationList(props) { ); }, [confirm, props.bankAccountRoute, props.iouCurrencyCode, props.iouType, props.isReadOnly, props.policyID, selectedParticipants, splitOrRequestOptions, translate, formError]); + const {image: receiptImage, thumbnail: receiptThumbnail} = + props.receiptPath && props.receiptFilename ? ReceiptUtils.getThumbnailAndImageURIs(props.receiptPath, props.receiptFilename) : {}; + return ( )} - {!_.isEmpty(props.receiptPath) ? ( + {(receiptImage || receiptThumbnail) && ( - ) : ( + )} + {shouldShowSmartScanFields && ( - Navigation.navigate(ROUTES.MONEY_REQUEST_DATE.getRoute(props.iouType, props.reportID))} - disabled={didConfirm || props.isReadOnly || !isTypeRequest} - /> - {props.isDistanceRequest ? ( + {shouldShowSmartScanFields && ( + Navigation.navigate(ROUTES.MONEY_REQUEST_DATE.getRoute(props.iouType, props.reportID))} + disabled={didConfirm || props.isReadOnly} + /> + )} + {props.isDistanceRequest && ( Navigation.navigate(ROUTES.MONEY_REQUEST_DISTANCE.getRoute(props.iouType, props.reportID))} disabled={didConfirm || props.isReadOnly || !isTypeRequest} /> - ) : ( + )} + {shouldShowSmartScanFields && ( Navigation.navigate(ROUTES.MONEY_REQUEST_MERCHANT.getRoute(props.iouType, props.reportID))} - disabled={didConfirm || props.isReadOnly || !isTypeRequest} + disabled={didConfirm || props.isReadOnly} /> )} {shouldShowCategories && ( diff --git a/src/components/MoneyRequestHeaderStatusBar.js b/src/components/MoneyRequestHeaderStatusBar.js index a4f21e3d168d..499fa1433e05 100644 --- a/src/components/MoneyRequestHeaderStatusBar.js +++ b/src/components/MoneyRequestHeaderStatusBar.js @@ -8,7 +8,7 @@ function MoneyRequestHeaderStatusBar() { const {translate} = useLocalize(); return ( - + {translate('iou.receiptStatusTitle')} diff --git a/src/components/ReportActionItem/MoneyRequestPreview.js b/src/components/ReportActionItem/MoneyRequestPreview.js index 35215cadd15d..b4101d9b5721 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview.js +++ b/src/components/ReportActionItem/MoneyRequestPreview.js @@ -317,7 +317,7 @@ function MoneyRequestPreview(props) { )} {shouldShowDescription && {description}} - {props.isBillSplit && !_.isEmpty(participantAccountIDs) && ( + {props.isBillSplit && !_.isEmpty(participantAccountIDs) && requestAmount > 0 && ( {props.translate('iou.amountEach', { amount: CurrencyUtils.convertToDisplayString( diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index f2d5eb878fcd..d5676672dd33 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -24,6 +24,14 @@ import ReceiptGeneric from '../../../assets/images/receipt-generic.png'; import * as LocalePhoneNumber from '../LocalePhoneNumber'; import * as Policy from './Policy'; +let allPersonalDetails; +Onyx.connect({ + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + callback: (val) => { + allPersonalDetails = val || {}; + }, +}); + let allReports; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT, @@ -116,7 +124,7 @@ function resetMoneyRequestInfo(id = '') { tag: '', created, receiptPath: '', - receiptSource: '', + receiptFilename: '', transactionID: '', billable: null, }); @@ -1262,6 +1270,225 @@ function splitBillAndOpenReport(participants, currentUserLogin, currentUserAccou Report.notifyNewAction(splitData.chatReportID, currentUserAccountID); } +/** Used exclusively for starting a split bill request that contains a receipt, the split request will be completed once the receipt is scanned + * or user enters details manually. + * + * @param {Array} participants + * @param {String} currentUserLogin + * @param {Number} currentUserAccountID + * @param {String} comment + * @param {Object} receipt + * @param {String} existingSplitChatReportID - Either a group DM or a workspace chat + */ +function startSplitBill(participants, currentUserLogin, currentUserAccountID, comment, receipt, existingSplitChatReportID = '') { + const currentUserEmailForIOUSplit = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin); + const participantAccountIDs = _.map(participants, (participant) => Number(participant.accountID)); + const existingSplitChatReport = + existingSplitChatReportID || participants[0].reportID + ? allReports[`${ONYXKEYS.COLLECTION.REPORT}${existingSplitChatReportID || participants[0].reportID}`] + : ReportUtils.getChatByParticipants(participantAccountIDs); + const splitChatReport = existingSplitChatReport || ReportUtils.buildOptimisticChatReport(participantAccountIDs); + const isOwnPolicyExpenseChat = splitChatReport.isOwnPolicyExpenseChat || false; + + const {name: filename, source, state = CONST.IOU.RECEIPT_STATE.SCANREADY} = receipt; + const receiptObject = {state, source}; + + // ReportID is -2 (aka "deleted") on the group transaction + const splitTransaction = TransactionUtils.buildOptimisticTransaction(0, CONST.CURRENCY.USD, CONST.REPORT.SPLIT_REPORTID, comment, '', '', '', '', receiptObject, filename); + + // Note: The created action must be optimistically generated before the IOU action so there's no chance that the created action appears after the IOU action in the chat + const splitChatCreatedReportAction = ReportUtils.buildOptimisticCreatedReportAction(currentUserEmailForIOUSplit); + const splitIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( + CONST.IOU.REPORT_ACTION_TYPE.SPLIT, + 0, + CONST.CURRENCY.USD, + comment, + participants, + splitTransaction.transactionID, + '', + '', + false, + false, + receiptObject, + isOwnPolicyExpenseChat, + ); + + splitChatReport.lastReadTime = DateUtils.getDBTime(); + splitChatReport.lastMessageText = splitIOUReportAction.message[0].text; + splitChatReport.lastMessageHtml = splitIOUReportAction.message[0].html; + + // If we have an existing splitChatReport (group chat or workspace) use it's pending fields, otherwise indicate that we are adding a chat + if (!existingSplitChatReport) { + splitChatReport.pendingFields = { + createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }; + } + + const optimisticData = [ + { + // Use set for new reports because it doesn't exist yet, is faster, + // and we need the data to be available when we navigate to the chat page + onyxMethod: existingSplitChatReport ? Onyx.METHOD.MERGE : Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT}${splitChatReport.reportID}`, + value: splitChatReport, + }, + { + onyxMethod: existingSplitChatReport ? Onyx.METHOD.MERGE : Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${splitChatReport.reportID}`, + value: { + ...(existingSplitChatReport ? {} : {[splitChatCreatedReportAction.reportActionID]: splitChatCreatedReportAction}), + [splitIOUReportAction.reportActionID]: splitIOUReportAction, + }, + }, + { + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}${splitTransaction.transactionID}`, + value: splitTransaction, + }, + ]; + + const successData = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${splitChatReport.reportID}`, + value: { + ...(existingSplitChatReport ? {} : {[splitChatCreatedReportAction.reportActionID]: {pendingAction: null}}), + [splitIOUReportAction.reportActionID]: {pendingAction: null}, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}${splitTransaction.transactionID}`, + value: {pendingAction: null}, + }, + ]; + + if (!existingSplitChatReport) { + successData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${splitChatReport.reportID}`, + value: {pendingFields: {createChat: null}}, + }); + } + + const failureData = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}${splitTransaction.transactionID}`, + value: { + errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), + }, + }, + ]; + + if (existingSplitChatReport) { + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${splitChatReport.reportID}`, + value: { + [splitIOUReportAction.reportActionID]: { + errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), + }, + }, + }); + } else { + failureData.push( + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${splitChatReport.reportID}`, + value: { + errorFields: { + createChat: ErrorUtils.getMicroSecondOnyxError('report.genericCreateReportFailureMessage'), + }, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${splitChatReport.reportID}`, + value: { + [splitChatCreatedReportAction.reportActionID]: { + errors: ErrorUtils.getMicroSecondOnyxError('report.genericCreateReportFailureMessage'), + }, + [splitIOUReportAction.reportActionID]: { + errors: ErrorUtils.getMicroSecondOnyxError('report.genericCreateFailureMessage'), + }, + }, + }, + ); + } + + const splits = [{email: currentUserEmailForIOUSplit, accountID: currentUserAccountID}]; + + _.each(participants, (participant) => { + const email = participant.isOwnPolicyExpenseChat ? '' : OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login || participant.text).toLowerCase(); + const accountID = participant.isOwnPolicyExpenseChat ? 0 : Number(participant.accountID); + if (email === currentUserEmailForIOUSplit) { + return; + } + + // When splitting with a workspace chat, we only need to supply the policyID and the workspace reportID as it's needed so we can update the report preview + if (participant.isOwnPolicyExpenseChat) { + splits.push({ + policyID: participant.policyID, + chatReportID: splitChatReport.reportID, + }); + return; + } + + const participantPersonalDetails = allPersonalDetails[participant.accountID]; + if (!participantPersonalDetails) { + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + value: { + [accountID]: { + accountID, + avatar: UserUtils.getDefaultAvatarURL(accountID), + displayName: LocalePhoneNumber.formatPhoneNumber(participant.displayName || email), + login: participant.login || participant.text, + isOptimisticPersonalDetail: true, + }, + }, + }); + } + + splits.push({ + email, + accountID, + }); + }); + + // Save the new splits array into the transaction's comment in case the user calls CompleteSplitBill while offline + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}${splitTransaction.transactionID}`, + value: { + comment: { + splits, + }, + }, + }); + + API.write( + 'StartSplitBill', + { + chatReportID: splitChatReport.reportID, + reportActionID: splitIOUReportAction.reportActionID, + transactionID: splitTransaction.transactionID, + splits: JSON.stringify(splits), + receipt, + comment, + isFromGroupDM: !existingSplitChatReport, + ...(existingSplitChatReport ? {} : {createdReportActionID: splitChatCreatedReportAction.reportActionID}), + }, + {optimisticData, successData, failureData}, + ); + + resetMoneyRequestInfo(); + Navigation.dismissModal(splitChatReport.reportID); + Report.notifyNewAction(splitChatReport.chatReportID, currentUserAccountID); +} + /** * @param {String} transactionID * @param {Number} transactionThreadReportID @@ -2331,10 +2558,10 @@ function setMoneyRequestParticipants(participants) { /** * @param {String} receiptPath - * @param {String} receiptSource + * @param {String} receiptFilename */ -function setMoneyRequestReceipt(receiptPath, receiptSource) { - Onyx.merge(ONYXKEYS.IOU, {receiptPath, receiptSource, merchant: ''}); +function setMoneyRequestReceipt(receiptPath, receiptFilename) { + Onyx.merge(ONYXKEYS.IOU, {receiptPath, receiptFilename, merchant: ''}); } function createEmptyTransaction() { @@ -2410,6 +2637,7 @@ export { deleteMoneyRequest, splitBill, splitBillAndOpenReport, + startSplitBill, requestMoney, sendMoneyElsewhere, approveMoneyRequest, diff --git a/src/pages/iou/MoneyRequestSelectorPage.js b/src/pages/iou/MoneyRequestSelectorPage.js index c8e3aebaa0b3..d006e3480a4e 100644 --- a/src/pages/iou/MoneyRequestSelectorPage.js +++ b/src/pages/iou/MoneyRequestSelectorPage.js @@ -99,7 +99,7 @@ function MoneyRequestSelectorPage(props) { title={title[iouType]} onBackButtonPress={Navigation.dismissModal} /> - {iouType === CONST.IOU.MONEY_REQUEST_TYPE.REQUEST ? ( + {iouType === CONST.IOU.MONEY_REQUEST_TYPE.REQUEST || iouType === CONST.IOU.MONEY_REQUEST_TYPE.SPLIT ? ( participant.accountID !== reportAction.actorAccountID); - const {amount: splitAmount, currency: splitCurrency, comment: splitComment, category: splitCategory} = ReportUtils.getTransactionDetails(transaction); + const { + amount: splitAmount, + currency: splitCurrency, + merchant: splitMerchant, + created: splitCreated, + comment: splitComment, + category: splitCategory, + } = ReportUtils.getTransactionDetails(transaction); + const isScanning = TransactionUtils.hasReceipt(transaction) && TransactionUtils.isReceiptBeingScanned(transaction); return ( @@ -80,18 +89,24 @@ function SplitBillDetailsPage(props) { pointerEvents="box-none" style={[styles.containerWithSpaceBetween]} > + {isScanning && } {Boolean(participants.length) && ( )} diff --git a/src/pages/iou/steps/MoneyRequestConfirmPage.js b/src/pages/iou/steps/MoneyRequestConfirmPage.js index 907869c0e3a4..d007e168de79 100644 --- a/src/pages/iou/steps/MoneyRequestConfirmPage.js +++ b/src/pages/iou/steps/MoneyRequestConfirmPage.js @@ -194,6 +194,22 @@ function MoneyRequestConfirmPage(props) { (selectedParticipants) => { const trimmedComment = props.iou.comment.trim(); + // If we have a receipt let's start the split bill by creating only the action, the transaction, and the group DM if needed + if (iouType.current === CONST.IOU.MONEY_REQUEST_TYPE.SPLIT && props.iou.receiptPath) { + const existingSplitChatReportID = CONST.REGEX.NUMBER.test(reportID.current) ? reportID.current : ''; + FileUtils.readFileAsync(props.iou.receiptPath, props.iou.receiptFilename).then((receipt) => { + IOU.startSplitBill( + selectedParticipants, + props.currentUserPersonalDetails.login, + props.currentUserPersonalDetails.accountID, + trimmedComment, + receipt, + existingSplitChatReportID, + ); + }); + return; + } + // IOUs created from a group report will have a reportID param in the route. // Since the user is already viewing the report, we don't need to navigate them to the report if (iouType.current === CONST.IOU.MONEY_REQUEST_TYPE.SPLIT && CONST.REGEX.NUMBER.test(reportID.current)) { @@ -224,8 +240,8 @@ function MoneyRequestConfirmPage(props) { return; } - if (props.iou.receiptPath && props.iou.receiptSource) { - FileUtils.readFileAsync(props.iou.receiptPath, props.iou.receiptSource).then((file) => { + if (props.iou.receiptPath && props.iou.receiptFilename) { + FileUtils.readFileAsync(props.iou.receiptPath, props.iou.receiptFilename).then((file) => { const receipt = file; receipt.state = file && isManualRequestDM ? CONST.IOU.RECEIPT_STATE.OPEN : CONST.IOU.RECEIPT_STATE.SCANREADY; requestMoney(selectedParticipants, trimmedComment, receipt); @@ -248,7 +264,7 @@ function MoneyRequestConfirmPage(props) { props.iou.currency, props.iou.category, props.iou.receiptPath, - props.iou.receiptSource, + props.iou.receiptFilename, isDistanceRequest, requestMoney, createDistanceRequest, @@ -344,7 +360,7 @@ function MoneyRequestConfirmPage(props) { IOU.setMoneyRequestParticipants(newParticipants); }} receiptPath={props.iou.receiptPath} - receiptSource={props.iou.receiptSource} + receiptFilename={props.iou.receiptFilename} iouType={iouType.current} reportID={reportID.current} isPolicyExpenseChat={isPolicyExpenseChat} diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js index ac30bcf55787..e3dc7407e99b 100755 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js @@ -59,9 +59,6 @@ const propTypes = { /** Whether the money request is a distance request or not */ isDistanceRequest: PropTypes.bool, - /** Whether the money request is a scan request or not */ - isScanRequest: PropTypes.bool, - ...withLocalizePropTypes, }; @@ -73,7 +70,6 @@ const defaultProps = { reports: {}, betas: [], isDistanceRequest: false, - isScanRequest: false, }; function MoneyRequestParticipantsSelector({ @@ -89,7 +85,6 @@ function MoneyRequestParticipantsSelector({ safeAreaPaddingBottomStyle, iouType, isDistanceRequest, - isScanRequest, }) { const [searchTerm, setSearchTerm] = useState(''); const [newChatOptions, setNewChatOptions] = useState({ @@ -245,7 +240,7 @@ function MoneyRequestParticipantsSelector({ // the app from crashing on native when you try to do this, we'll going to hide the button if you have a workspace and other participants const hasPolicyExpenseChatParticipant = _.some(participants, (participant) => participant.isPolicyExpenseChat); const shouldShowConfirmButton = !(participants.length > 1 && hasPolicyExpenseChatParticipant); - const isAllowedToSplit = !isDistanceRequest && !isScanRequest; + const isAllowedToSplit = !isDistanceRequest; return ( 0 ? safeAreaPaddingBottomStyle : {}]}> diff --git a/src/types/onyx/IOU.ts b/src/types/onyx/IOU.ts index 7151bb84d1f1..a89b0d4530ef 100644 --- a/src/types/onyx/IOU.ts +++ b/src/types/onyx/IOU.ts @@ -16,7 +16,7 @@ type IOU = { merchant?: string; created?: string; receiptPath?: string; - receiptSource?: string; + receiptFilename?: string; transactionID?: string; participants?: Participant[]; tag?: string;