diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 082cea49d7718..bd77749b17164 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -348,9 +348,9 @@ const ROUTES = { getUrlWithBackToParam(`create/${iouType}/distance/${transactionID}/${reportID}`, backTo), }, MONEY_REQUEST_STEP_MERCHANT: { - route: 'create/:iouType/merchant/:transactionID/:reportID', - getRoute: (iouType: ValueOf, transactionID: string, reportID: string, backTo = '') => - getUrlWithBackToParam(`create/${iouType}/merchant/${transactionID}/${reportID}`, backTo), + route: ':action/:iouType/merchant/:transactionID/:reportID', + getRoute: (action: ValueOf, iouType: ValueOf, transactionID: string, reportID: string, backTo = '') => + getUrlWithBackToParam(`${action}/${iouType}/merchant/${transactionID}/${reportID}`, backTo), }, MONEY_REQUEST_STEP_PARTICIPANTS: { route: 'create/:iouType/participants/:transactionID/:reportID', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 1626fdbd1898d..768e60339a953 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -147,7 +147,6 @@ const SCREENS = { CONFIRMATION: 'Money_Request_Confirmation', CURRENCY: 'Money_Request_Currency', CATEGORY: 'Money_Request_Category', - MERCHANT: 'Money_Request_Merchant', WAYPOINT: 'Money_Request_Waypoint', EDIT_WAYPOINT: 'Money_Request_Edit_Waypoint', DISTANCE: 'Money_Request_Distance', diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 7608447a213e8..dcd1de99f516f 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -435,7 +435,7 @@ function MoneyRequestConfirmationList(props) { IOU.setMoneyRequestPendingFields(props.transactionID, {waypoints: isDistanceRequestWithPendingRoute ? CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD : null}); const distanceMerchant = DistanceRequestUtils.getDistanceMerchant(hasRoute, distance, unit, rate, currency, translate, toLocaleDigit); - IOU.setMoneyRequestMerchant_temporaryForRefactor(props.transactionID, distanceMerchant); + IOU.setMoneyRequestMerchant(props.transactionID, distanceMerchant, false); }, [isDistanceRequestWithPendingRoute, hasRoute, distance, unit, rate, currency, translate, toLocaleDigit, props.isDistanceRequest, props.transactionID]); /** @@ -739,11 +739,15 @@ function MoneyRequestConfirmationList(props) { style={[styles.moneyRequestMenuItem]} titleStyle={styles.flex1} onPress={() => { - if (props.isEditingSplitBill) { - Navigation.navigate(ROUTES.EDIT_SPLIT_BILL.getRoute(props.reportID, props.reportActionID, CONST.EDIT_REQUEST_FIELD.MERCHANT)); - return; - } - Navigation.navigate(ROUTES.MONEY_REQUEST_MERCHANT.getRoute(props.iouType, props.reportID)); + Navigation.navigate( + ROUTES.MONEY_REQUEST_STEP_MERCHANT.getRoute( + CONST.IOU.ACTION.EDIT, + props.iouType, + transaction.transactionID, + props.reportID, + Navigation.getActiveRouteWithoutParams(), + ), + ); }} disabled={didConfirm} interactive={!props.isReadOnly} diff --git a/src/components/MoneyTemporaryForRefactorRequestConfirmationList.js b/src/components/MoneyTemporaryForRefactorRequestConfirmationList.js index ec4f0f9cf5f8c..720f9e27a0ebc 100755 --- a/src/components/MoneyTemporaryForRefactorRequestConfirmationList.js +++ b/src/components/MoneyTemporaryForRefactorRequestConfirmationList.js @@ -486,7 +486,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({ IOU.setMoneyRequestPendingFields(transaction.transactionID, {waypoints: isDistanceRequestWithPendingRoute ? CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD : null}); const distanceMerchant = DistanceRequestUtils.getDistanceMerchant(hasRoute, distance, unit, rate, currency, translate, toLocaleDigit); - IOU.setMoneyRequestMerchant_temporaryForRefactor(transaction.transactionID, distanceMerchant); + IOU.setMoneyRequestMerchant(transaction.transactionID, distanceMerchant, true); }, [isDistanceRequestWithPendingRoute, hasRoute, distance, unit, rate, currency, translate, toLocaleDigit, isDistanceRequest, transaction]); /** @@ -710,11 +710,9 @@ function MoneyTemporaryForRefactorRequestConfirmationList({ style={[styles.moneyRequestMenuItem]} titleStyle={styles.flex1} onPress={() => { - if (isEditingSplitBill) { - Navigation.navigate(ROUTES.EDIT_SPLIT_BILL.getRoute(reportID, reportActionID, CONST.EDIT_REQUEST_FIELD.MERCHANT)); - return; - } - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_MERCHANT.getRoute(iouType, transaction.transactionID, reportID, Navigation.getActiveRouteWithoutParams())); + Navigation.navigate( + ROUTES.MONEY_REQUEST_STEP_MERCHANT.getRoute(CONST.IOU.ACTION.CREATE, iouType, transaction.transactionID, reportID, Navigation.getActiveRouteWithoutParams()), + ); }} disabled={didConfirm} interactive={!isReadOnly} diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index 6b16f272e4c8b..20dc6b05bdd37 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -334,7 +334,11 @@ function MoneyRequestView({ interactive={canEditMerchant} shouldShowRightIcon={canEditMerchant} titleStyle={styles.flex1} - onPress={() => Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.MERCHANT))} + onPress={() => + Navigation.navigate( + ROUTES.MONEY_REQUEST_STEP_MERCHANT.getRoute(CONST.IOU.ACTION.EDIT, CONST.IOU.TYPE.REQUEST, transaction?.transactionID ?? '', report.reportID), + ) + } brickRoadIndicator={hasViolations('merchant') || (hasErrors && isEmptyMerchant && isPolicyExpenseChat) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} error={hasErrors && isPolicyExpenseChat && isEmptyMerchant ? translate('common.error.enterMerchant') : ''} /> diff --git a/src/components/transactionPropTypes.js b/src/components/transactionPropTypes.js index bdcf60bec5da2..7eb1b776358c2 100644 --- a/src/components/transactionPropTypes.js +++ b/src/components/transactionPropTypes.js @@ -67,6 +67,17 @@ export default PropTypes.shape({ }), ), + /** Selected participants */ + participants: PropTypes.arrayOf( + PropTypes.shape({ + accountID: PropTypes.number, + login: PropTypes.string, + isPolicyExpenseChat: PropTypes.bool, + isOwnPolicyExpenseChat: PropTypes.bool, + selected: PropTypes.bool, + }), + ), + /** The original currency of the transaction */ currency: PropTypes.string, diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx index 4723bbfd9b4ec..049ecb95f2292 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx @@ -100,7 +100,6 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator require('../../../pages/iou/steps/MoneyRequestConfirmPage').default as React.ComponentType, [SCREENS.MONEY_REQUEST.CURRENCY]: () => require('../../../pages/iou/IOUCurrencySelection').default as React.ComponentType, [SCREENS.MONEY_REQUEST.CATEGORY]: () => require('../../../pages/iou/MoneyRequestCategoryPage').default as React.ComponentType, - [SCREENS.MONEY_REQUEST.MERCHANT]: () => require('../../../pages/iou/MoneyRequestMerchantPage').default as React.ComponentType, [SCREENS.IOU_SEND.ADD_BANK_ACCOUNT]: () => require('../../../pages/AddPersonalBankAccountPage').default as React.ComponentType, [SCREENS.IOU_SEND.ADD_DEBIT_CARD]: () => require('../../../pages/settings/Wallet/AddDebitCardPage').default as React.ComponentType, [SCREENS.IOU_SEND.ENABLE_PAYMENTS]: () => require('../../../pages/EnablePayments/EnablePaymentsPage').default as React.ComponentType, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 52e512d32c59b..582514d9e677f 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -413,7 +413,6 @@ const config: LinkingOptions['config'] = { [SCREENS.MONEY_REQUEST.CONFIRMATION]: ROUTES.MONEY_REQUEST_CONFIRMATION.route, [SCREENS.MONEY_REQUEST.CURRENCY]: ROUTES.MONEY_REQUEST_CURRENCY.route, [SCREENS.MONEY_REQUEST.CATEGORY]: ROUTES.MONEY_REQUEST_CATEGORY.route, - [SCREENS.MONEY_REQUEST.MERCHANT]: ROUTES.MONEY_REQUEST_MERCHANT.route, [SCREENS.MONEY_REQUEST.RECEIPT]: ROUTES.MONEY_REQUEST_RECEIPT.route, [SCREENS.MONEY_REQUEST.DISTANCE]: ROUTES.MONEY_REQUEST_DISTANCE.route, [SCREENS.IOU_SEND.ENABLE_PAYMENTS]: ROUTES.IOU_SEND_ENABLE_PAYMENTS, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 71864582812fb..3a1abe8260a35 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -271,11 +271,12 @@ type MoneyRequestNavigatorParamList = { reportID: string; backTo: string; }; - [SCREENS.MONEY_REQUEST.MERCHANT]: { - iouType: string; + [SCREENS.MONEY_REQUEST.STEP_MERCHANT]: { + action: ValueOf; + iouType: ValueOf; + transactionID: string; reportID: string; - field: string; - threadReportID: string; + backTo: string; }; [SCREENS.IOU_SEND.ENABLE_PAYMENTS]: undefined; [SCREENS.IOU_SEND.ADD_BANK_ACCOUNT]: undefined; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 7fca6614f1a18..ff588ee4e0728 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -291,9 +291,8 @@ function setMoneyRequestDescription(transactionID: string, comment: string, isDr Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {comment: {comment: comment.trim()}}); } -// eslint-disable-next-line @typescript-eslint/naming-convention -function setMoneyRequestMerchant_temporaryForRefactor(transactionID: string, merchant: string) { - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {merchant: merchant.trim()}); +function setMoneyRequestMerchant(transactionID: string, merchant: string, isDraft: boolean) { + Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {merchant}); } function setMoneyRequestPendingFields(transactionID: string, pendingFields: PendingFields) { @@ -3731,10 +3730,6 @@ function setMoneyRequestCurrency(currency: string) { Onyx.merge(ONYXKEYS.IOU, {currency}); } -function setMoneyRequestMerchant(merchant: string) { - Onyx.merge(ONYXKEYS.IOU, {merchant: merchant.trim()}); -} - function setMoneyRequestCategory(category: string) { Onyx.merge(ONYXKEYS.IOU, {category}); } @@ -3873,7 +3868,6 @@ export { setMoneyRequestCurrency_temporaryForRefactor, setMoneyRequestDescription, setMoneyRequestOriginalCurrency_temporaryForRefactor, - setMoneyRequestMerchant_temporaryForRefactor, setMoneyRequestParticipants_temporaryForRefactor, setMoneyRequestPendingFields, setMoneyRequestReceipt, diff --git a/src/pages/EditRequestPage.js b/src/pages/EditRequestPage.js index aa22439dee705..69d88ca16c23d 100644 --- a/src/pages/EditRequestPage.js +++ b/src/pages/EditRequestPage.js @@ -22,7 +22,6 @@ import ROUTES from '@src/ROUTES'; import EditRequestAmountPage from './EditRequestAmountPage'; import EditRequestCategoryPage from './EditRequestCategoryPage'; import EditRequestDistancePage from './EditRequestDistancePage'; -import EditRequestMerchantPage from './EditRequestMerchantPage'; import EditRequestReceiptPage from './EditRequestReceiptPage'; import EditRequestTagPage from './EditRequestTagPage'; import reportActionPropTypes from './home/report/reportActionPropTypes'; @@ -74,13 +73,7 @@ const defaultProps = { function EditRequestPage({report, route, policy, policyCategories, policyTags, parentReportActions, transaction}) { const parentReportActionID = lodashGet(report, 'parentReportActionID', '0'); const parentReportAction = lodashGet(parentReportActions, parentReportActionID, {}); - const { - amount: transactionAmount, - currency: transactionCurrency, - merchant: transactionMerchant, - category: transactionCategory, - tag: transactionTag, - } = ReportUtils.getTransactionDetails(transaction); + const {amount: transactionAmount, currency: transactionCurrency, category: transactionCategory, tag: transactionTag} = ReportUtils.getTransactionDetails(transaction); const defaultCurrency = lodashGet(route, 'params.currency', '') || transactionCurrency; const fieldToEdit = lodashGet(route, ['params', 'field'], ''); @@ -128,31 +121,6 @@ function EditRequestPage({report, route, policy, policyCategories, policyTags, p [transaction, report, policy, policyTags, policyCategories], ); - const saveMerchant = useCallback( - ({merchant: newMerchant}) => { - const newTrimmedMerchant = newMerchant.trim(); - - // In case the merchant hasn't been changed, do not make the API request. - // In case the merchant has been set to empty string while current merchant is partial, do nothing too. - if (newTrimmedMerchant === transactionMerchant || (newTrimmedMerchant === '' && transactionMerchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT)) { - Navigation.dismissModal(); - return; - } - - // An empty newTrimmedMerchant is only possible for the P2P IOU case - IOU.updateMoneyRequestMerchant( - transaction.transactionID, - report.reportID, - newTrimmedMerchant || CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT, - policy, - policyTags, - policyCategories, - ); - Navigation.dismissModal(); - }, - [transactionMerchant, transaction, report, policy, policyTags, policyCategories], - ); - const saveTag = useCallback( ({tag: newTag}) => { let updatedTag = newTag; @@ -191,16 +159,6 @@ function EditRequestPage({report, route, policy, policyCategories, policyTags, p ); } - if (fieldToEdit === CONST.EDIT_REQUEST_FIELD.MERCHANT) { - return ( - - ); - } - if (fieldToEdit === CONST.EDIT_REQUEST_FIELD.CATEGORY && shouldShowCategories) { return ( { - setDraftSplitTransaction({merchant: transactionChanges.merchant.trim()}); - }} - /> - ); - } - if (fieldToEdit === CONST.EDIT_REQUEST_FIELD.CATEGORY) { return ( Boolean(participant.isPolicyExpenseChat)); + const isEditing = action === CONST.IOU.ACTION.EDIT; + // In the split flow, when editing we use SPLIT_TRANSACTION_DRAFT to save draft value + const isEditingSplitBill = iouType === CONST.IOU.TYPE.SPLIT && isEditing; + const {merchant} = ReportUtils.getTransactionDetails(isEditingSplitBill && !lodashIsEmpty(splitDraftTransaction) ? splitDraftTransaction : transaction); + const isEmptyMerchant = merchant === '' || merchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT; + const isMerchantRequired = _.some(transaction.participants, (participant) => Boolean(participant.isPolicyExpenseChat)); const navigateBack = () => { Navigation.goBack(backTo); }; @@ -71,7 +102,26 @@ function IOURequestStepMerchant({ * @param {String} value.moneyRequestMerchant */ const updateMerchant = (value) => { - IOU.setMoneyRequestMerchant_temporaryForRefactor(transactionID, value.moneyRequestMerchant); + const newMerchant = value.moneyRequestMerchant.trim(); + + // In the split flow, when editing we use SPLIT_TRANSACTION_DRAFT to save draft value + if (isEditingSplitBill) { + IOU.setDraftSplitTransaction(transactionID, {merchant: newMerchant}); + navigateBack(); + return; + } + + // In case the merchant hasn't been changed, do not make the API request. + // In case the merchant has been set to empty string while current merchant is partial, do nothing too. + if (newMerchant === merchant || (newMerchant === '' && merchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT)) { + navigateBack(); + return; + } + IOU.setMoneyRequestMerchant(transactionID, newMerchant, !isEditing); + if (isEditing) { + // When creating new money requests newMerchant can be blank so we fall back on PARTIAL_TRANSACTION_MERCHANT + IOU.updateMoneyRequestMerchant(transactionID, reportID, newMerchant || CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT, policy, policyTags, policyCategories); + } navigateBack(); }; @@ -99,7 +149,7 @@ function IOURequestStepMerchant({ maxLength={CONST.MERCHANT_NAME_MAX_LENGTH} label={translate('common.merchant')} accessibilityLabel={translate('common.merchant')} - role={CONST.ACCESSIBILITY_ROLE.TEXT} + role={CONST.ROLE.PRESENTATION} ref={inputCallbackRef} /> @@ -112,4 +162,24 @@ IOURequestStepMerchant.propTypes = propTypes; IOURequestStepMerchant.defaultProps = defaultProps; IOURequestStepMerchant.displayName = 'IOURequestStepMerchant'; -export default compose(withWritableReportOrNotFound, withFullTransactionOrNotFound)(IOURequestStepMerchant); +export default compose( + withWritableReportOrNotFound, + withFullTransactionOrNotFound, + withOnyx({ + splitDraftTransaction: { + key: ({route}) => { + const transactionID = lodashGet(route, 'params.transactionID', 0); + return `${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`; + }, + }, + policy: { + key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY}${report ? report.policyID : '0'}`, + }, + policyCategories: { + key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${report ? report.policyID : '0'}`, + }, + policyTags: { + key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${report ? report.policyID : '0'}`, + }, + }), +)(IOURequestStepMerchant);