Skip to content

Commit

Permalink
Merge pull request #40388 from nkdengineer/fix/40379
Browse files Browse the repository at this point in the history
Allow selecting a payer from the splits page
  • Loading branch information
rafecolton authored Apr 30, 2024
2 parents cad52d9 + 3fa6b72 commit a462d58
Show file tree
Hide file tree
Showing 13 changed files with 274 additions and 75 deletions.
5 changes: 5 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,11 @@ const ROUTES = {
getRoute: (iouType: IOUType, transactionID: string, reportID: string, backTo = '', action: IOUAction = 'create') =>
getUrlWithBackToParam(`${action as string}/${iouType as string}/participants/${transactionID}/${reportID}`, backTo),
},
MONEY_REQUEST_STEP_SPLIT_PAYER: {
route: ':action/:iouType/confirmation/:transactionID/:reportID/payer',
getRoute: (action: ValueOf<typeof CONST.IOU.ACTION>, iouType: ValueOf<typeof CONST.IOU.TYPE>, transactionID: string, reportID: string, backTo = '') =>
getUrlWithBackToParam(`${action}/${iouType}/confirmation/${transactionID}/${reportID}/payer`, backTo),
},
MONEY_REQUEST_STEP_SCAN: {
route: ':action/:iouType/scan/:transactionID/:reportID',
getRoute: (action: IOUAction, iouType: IOUType, transactionID: string, reportID: string, backTo = '') =>
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ const SCREENS = {
STEP_WAYPOINT: 'Money_Request_Step_Waypoint',
STEP_TAX_AMOUNT: 'Money_Request_Step_Tax_Amount',
STEP_TAX_RATE: 'Money_Request_Step_Tax_Rate',
STEP_SPLIT_PAYER: 'Money_Request_Step_Split_Payer',
STEP_SEND_FROM: 'Money_Request_Step_Send_From',
CURRENCY: 'Money_Request_Currency',
WAYPOINT: 'Money_Request_Waypoint',
Expand Down
180 changes: 108 additions & 72 deletions src/components/MoneyRequestConfirmationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {getDefaultWorkspaceAvatar} from '@libs/ReportUtils';
import playSound, {SOUNDS} from '@libs/Sound';
import * as TransactionUtils from '@libs/TransactionUtils';
import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot';
import * as UserUtils from '@libs/UserUtils';
import * as IOU from '@userActions/IOU';
import type {IOUAction, IOUType} from '@src/CONST';
import CONST from '@src/CONST';
Expand All @@ -45,6 +46,7 @@ import ConfirmModal from './ConfirmModal';
import FormHelpMessage from './FormHelpMessage';
import MenuItem from './MenuItem';
import MenuItemWithTopDescription from './MenuItemWithTopDescription';
import {usePersonalDetails} from './OnyxProvider';
import OptionsSelector from './OptionsSelector';
import PDFThumbnail from './PDFThumbnail';
import ReceiptEmptyState from './ReceiptEmptyState';
Expand Down Expand Up @@ -229,6 +231,7 @@ function MoneyRequestConfirmationList({
const styles = useThemeStyles();
const {translate, toLocaleDigit} = useLocalize();
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
const personalDetails = usePersonalDetails();
const {canUseP2PDistanceRequests, canUseViolations} = usePermissions(iouType);
const {isOffline} = useNetwork();

Expand Down Expand Up @@ -415,6 +418,18 @@ function MoneyRequestConfirmationList({

const selectedParticipants = useMemo(() => selectedParticipantsProp.filter((participant) => participant.selected), [selectedParticipantsProp]);
const payeePersonalDetails = useMemo(() => payeePersonalDetailsProp ?? currentUserPersonalDetails, [payeePersonalDetailsProp, currentUserPersonalDetails]);
const payeeTooltipDetails = useMemo(
() => ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs([payeePersonalDetails.accountID], personalDetails), false),
[payeePersonalDetails.accountID, personalDetails],
);
const payeeIcons = [
{
source: UserUtils.getAvatar(payeePersonalDetails.avatar, payeePersonalDetails.accountID) ?? '',
name: payeePersonalDetails.login ?? '',
type: CONST.ICON_TYPE_AVATAR,
id: payeePersonalDetails.accountID,
},
];
const canModifyParticipants = !isReadOnly && canModifyParticipantsProp && hasMultipleParticipants;
const shouldDisablePaidBySection = canModifyParticipants;
const optionSelectorSections = useMemo(() => {
Expand All @@ -432,6 +447,7 @@ function MoneyRequestConfirmationList({
}

const myIOUAmount = IOUUtils.calculateAmount(selectedParticipants.length, iouAmount, iouCurrencyCode ?? '', true);

const formattedPayeeOption = OptionsListUtils.getIOUConfirmationOptionsFromPayeePersonalDetail(
payeePersonalDetails,
iouAmount > 0 ? CurrencyUtils.convertToDisplayString(myIOUAmount, iouCurrencyCode) : '',
Expand Down Expand Up @@ -976,84 +992,104 @@ function MoneyRequestConfirmationList({
);

return (
// @ts-expect-error This component is deprecated and will not be migrated to TypeScript (context: https://expensify.slack.com/archives/C01GTK53T8Q/p1709232289899589?thread_ts=1709156803.359359&cid=C01GTK53T8Q)
<OptionsSelector
sections={optionSelectorSections}
onSelectRow={canModifyParticipants ? selectParticipant : navigateToReportOrUserDetail}
onAddToSelection={selectParticipant}
onConfirmSelection={confirm}
selectedOptions={selectedOptions}
canSelectMultipleOptions={canModifyParticipants}
disableArrowKeysActions={!canModifyParticipants}
boldStyle
showTitleTooltip
shouldTextInputAppearBelowOptions
shouldShowTextInput={false}
shouldUseStyleForChildren={false}
optionHoveredStyle={canModifyParticipants ? styles.hoveredComponentBG : {}}
footerContent={footerContent}
listStyles={listStyles}
shouldAllowScrollingChildren
>
{isDistanceRequest && (
<View style={styles.confirmationListMapItem}>
<ConfirmedRoute transaction={transaction ?? ({} as OnyxTypes.Transaction)} />
</View>
)}
{isTypeInvoice && (
<>
{/** Hide it temporarily, it will back when https://github.com/Expensify/App/pull/40386 is merged */}
{isTypeSplit && action === CONST.IOU.ACTION.CREATE && false && (
<MenuItem
key={translate('workspace.invoices.sendFrom')}
shouldShowRightIcon={!isReadOnly && canUpdateSenderWorkspace}
title={senderWorkspace?.name}
icon={senderWorkspace?.avatar ? senderWorkspace?.avatar : getDefaultWorkspaceAvatar(senderWorkspace?.name)}
iconType={CONST.ICON_TYPE_WORKSPACE}
description={translate('workspace.common.workspace')}
label={translate('workspace.invoices.sendFrom')}
isLabelHoverable={false}
interactive={!isReadOnly && canUpdateSenderWorkspace}
key={translate('moneyRequestConfirmationList.paidBy')}
label={translate('moneyRequestConfirmationList.paidBy')}
interactive={!isPolicyExpenseChat && !isReadOnly}
description={payeePersonalDetails.login ?? ReportUtils.getDisplayNameForParticipant(payeePersonalDetails.accountID)}
title={payeePersonalDetails.displayName ?? ReportUtils.getDisplayNameForParticipant(payeePersonalDetails.accountID)}
icon={payeeIcons}
onPress={() => {
Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_SEND_FROM.getRoute(iouType, transaction?.transactionID ?? '', reportID, Navigation.getActiveRouteWithoutParams()));
Navigation.navigate(
ROUTES.MONEY_REQUEST_STEP_SPLIT_PAYER.getRoute(action, iouType, transaction?.transactionID ?? '', reportID, Navigation.getActiveRouteWithoutParams()),
);
}}
style={styles.moneyRequestMenuItem}
labelStyle={styles.mt2}
titleStyle={styles.flex1}
disabled={didConfirm || !canUpdateSenderWorkspace}
shouldShowRightIcon={!isPolicyExpenseChat && !isReadOnly}
titleWithTooltips={payeePersonalDetails?.isOptimisticPersonalDetail ? undefined : payeeTooltipDetails}
/>
)}
{!isDistanceRequest &&
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
(receiptImage || receiptThumbnail
? receiptThumbnailContent
: // The empty receipt component should only show for IOU Requests of a paid policy ("Team" or "Corporate")
PolicyUtils.isPaidGroupPolicy(policy) &&
!isDistanceRequest &&
iouType === CONST.IOU.TYPE.SUBMIT && (
<ReceiptEmptyState
onPress={() =>
Navigation.navigate(
ROUTES.MONEY_REQUEST_STEP_SCAN.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID, Navigation.getActiveRouteWithoutParams()),
)
}
/>
))}
{primaryFields}
{!shouldShowAllFields && (
<ShowMoreButton
containerStyle={[styles.mt1, styles.mb2]}
onPress={toggleShouldExpandFields}
{/** @ts-expect-error This component is deprecated and will not be migrated to TypeScript (context: https://expensify.slack.com/archives/C01GTK53T8Q/p1709232289899589?thread_ts=1709156803.359359&cid=C01GTK53T8Q) */}
<OptionsSelector
sections={optionSelectorSections}
onSelectRow={canModifyParticipants ? selectParticipant : navigateToReportOrUserDetail}
onAddToSelection={selectParticipant}
onConfirmSelection={confirm}
selectedOptions={selectedOptions}
canSelectMultipleOptions={canModifyParticipants}
disableArrowKeysActions={!canModifyParticipants}
boldStyle
showTitleTooltip
shouldTextInputAppearBelowOptions
shouldShowTextInput={false}
shouldUseStyleForChildren={false}
optionHoveredStyle={canModifyParticipants ? styles.hoveredComponentBG : {}}
footerContent={footerContent}
listStyles={listStyles}
shouldAllowScrollingChildren
>
{isDistanceRequest && (
<View style={styles.confirmationListMapItem}>
<ConfirmedRoute transaction={transaction ?? ({} as OnyxTypes.Transaction)} />
</View>
)}
{isTypeInvoice && (
<MenuItem
key={translate('workspace.invoices.sendFrom')}
shouldShowRightIcon={!isReadOnly && canUpdateSenderWorkspace}
title={senderWorkspace?.name}
icon={senderWorkspace?.avatar ? senderWorkspace?.avatar : getDefaultWorkspaceAvatar(senderWorkspace?.name)}
iconType={CONST.ICON_TYPE_WORKSPACE}
description={translate('workspace.common.workspace')}
label={translate('workspace.invoices.sendFrom')}
isLabelHoverable={false}
interactive={!isReadOnly && canUpdateSenderWorkspace}
onPress={() => {
Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_SEND_FROM.getRoute(iouType, transaction?.transactionID ?? '', reportID, Navigation.getActiveRouteWithoutParams()));
}}
style={styles.moneyRequestMenuItem}
labelStyle={styles.mt2}
titleStyle={styles.flex1}
disabled={didConfirm || !canUpdateSenderWorkspace}
/>
)}
{!isDistanceRequest &&
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
(receiptImage || receiptThumbnail
? receiptThumbnailContent
: // The empty receipt component should only show for IOU Requests of a paid policy ("Team" or "Corporate")
PolicyUtils.isPaidGroupPolicy(policy) &&
!isDistanceRequest &&
iouType === CONST.IOU.TYPE.SUBMIT && (
<ReceiptEmptyState
onPress={() =>
Navigation.navigate(
ROUTES.MONEY_REQUEST_STEP_SCAN.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID, Navigation.getActiveRouteWithoutParams()),
)
}
/>
))}
{primaryFields}
{!shouldShowAllFields && (
<ShowMoreButton
containerStyle={[styles.mt1, styles.mb2]}
onPress={toggleShouldExpandFields}
/>
)}
{shouldShowAllFields && supplementaryFields}
<ConfirmModal
title={translate('attachmentPicker.wrongFileType')}
onConfirm={navigateBack}
onCancel={navigateBack}
isVisible={isAttachmentInvalid}
prompt={translate('attachmentPicker.protectedPDFNotSupported')}
confirmText={translate('common.close')}
shouldShowCancelButton={false}
/>
)}
{shouldShowAllFields && supplementaryFields}
<ConfirmModal
title={translate('attachmentPicker.wrongFileType')}
onConfirm={navigateBack}
onCancel={navigateBack}
isVisible={isAttachmentInvalid}
prompt={translate('attachmentPicker.protectedPDFNotSupported')}
confirmText={translate('common.close')}
shouldShowCancelButton={false}
/>
</OptionsSelector>
</OptionsSelector>
</>
);
}

Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ export default {
moneyRequestConfirmationList: {
paidBy: 'Paid by',
splitWith: 'Split with',
splitAmounts: 'Split amounts',
whatsItFor: "What's it for?",
},
optionsSelector: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ export default {
moneyRequestConfirmationList: {
paidBy: 'Pagado por',
splitWith: 'Dividir con',
splitAmounts: 'Importes a dividir',
whatsItFor: '¿Para qué es?',
},
optionsSelector: {
Expand Down
1 change: 1 addition & 0 deletions src/libs/API/parameters/SplitBillParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type SplitBillParams = {
createdReportActionID?: string;
policyID: string | undefined;
chatType: string | undefined;
splitPayerAccountIDs: number[];
};

export default SplitBillParams;
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator<MoneyRequestNa
[SCREENS.MONEY_REQUEST.STEP_SCAN]: () => require('../../../../pages/iou/request/step/IOURequestStepScan').default as React.ComponentType,
[SCREENS.MONEY_REQUEST.STEP_TAG]: () => require('../../../../pages/iou/request/step/IOURequestStepTag').default as React.ComponentType,
[SCREENS.MONEY_REQUEST.STEP_WAYPOINT]: () => require('../../../../pages/iou/request/step/IOURequestStepWaypoint').default as React.ComponentType,
[SCREENS.MONEY_REQUEST.STEP_SPLIT_PAYER]: () => require('../../../../pages/iou/request/step/IOURequestStepSplitPayer').default as React.ComponentType,
[SCREENS.MONEY_REQUEST.STEP_SEND_FROM]: () => require('../../../../pages/iou/request/step/IOURequestStepSendFrom').default as React.ComponentType,
[SCREENS.MONEY_REQUEST.HOLD]: () => require('../../../../pages/iou/HoldReasonPage').default as React.ComponentType,
[SCREENS.IOU_SEND.ADD_BANK_ACCOUNT]: () => require('../../../../pages/AddPersonalBankAccountPage').default as React.ComponentType,
Expand Down
1 change: 1 addition & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
[SCREENS.MONEY_REQUEST.STEP_TAX_AMOUNT]: ROUTES.MONEY_REQUEST_STEP_TAX_AMOUNT.route,
[SCREENS.MONEY_REQUEST.STEP_TAX_RATE]: ROUTES.MONEY_REQUEST_STEP_TAX_RATE.route,
[SCREENS.MONEY_REQUEST.STATE_SELECTOR]: {path: ROUTES.MONEY_REQUEST_STATE_SELECTOR.route, exact: true},
[SCREENS.MONEY_REQUEST.STEP_SPLIT_PAYER]: ROUTES.MONEY_REQUEST_STEP_SPLIT_PAYER.route,
[SCREENS.IOU_SEND.ENABLE_PAYMENTS]: ROUTES.IOU_SEND_ENABLE_PAYMENTS,
[SCREENS.IOU_SEND.ADD_BANK_ACCOUNT]: ROUTES.IOU_SEND_ADD_BANK_ACCOUNT,
[SCREENS.IOU_SEND.ADD_DEBIT_CARD]: ROUTES.IOU_SEND_ADD_DEBIT_CARD,
Expand Down
7 changes: 7 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,13 @@ type MoneyRequestNavigatorParamList = {
reportID: string;
backTo: Routes;
};
[SCREENS.MONEY_REQUEST.STEP_SPLIT_PAYER]: {
action: ValueOf<typeof CONST.IOU.ACTION>;
iouType: ValueOf<typeof CONST.IOU.TYPE>;
transactionID: string;
reportID: string;
backTo: Routes;
};
[SCREENS.IOU_SEND.ENABLE_PAYMENTS]: undefined;
[SCREENS.IOU_SEND.ADD_BANK_ACCOUNT]: undefined;
[SCREENS.IOU_SEND.ADD_DEBIT_CARD]: undefined;
Expand Down
Loading

0 comments on commit a462d58

Please sign in to comment.