diff --git a/src/ROUTES.js b/src/ROUTES.js
index f7d465be96a7..7e20bb7523f0 100644
--- a/src/ROUTES.js
+++ b/src/ROUTES.js
@@ -93,6 +93,8 @@ export default {
getIouRequestCurrencyRoute: (reportID, currency, backTo) => `${IOU_REQUEST_CURRENCY}/${reportID}?currency=${currency}&backTo=${backTo}`,
getIouBillCurrencyRoute: (reportID, currency, backTo) => `${IOU_BILL_CURRENCY}/${reportID}?currency=${currency}&backTo=${backTo}`,
getIouSendCurrencyRoute: (reportID, currency, backTo) => `${IOU_SEND_CURRENCY}/${reportID}?currency=${currency}&backTo=${backTo}`,
+ SPLIT_BILL_DETAILS: `r/:reportID/split/:reportActionID`,
+ getSplitBillDetailsRoute: (reportID, reportActionID) => `r/${reportID}/split/${reportActionID}`,
getNewTaskRoute: (reportID) => `${NEW_TASK}/${reportID}`,
NEW_TASK_WITH_REPORT_ID: `${NEW_TASK}/:reportID?`,
TASK_TITLE: 'r/:reportID/title',
diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js
index 048744c9eca7..4e53f6967df0 100755
--- a/src/components/MoneyRequestConfirmationList.js
+++ b/src/components/MoneyRequestConfirmationList.js
@@ -23,10 +23,10 @@ import * as CurrencyUtils from '../libs/CurrencyUtils';
const propTypes = {
/** Callback to inform parent modal of success */
- onConfirm: PropTypes.func.isRequired,
+ onConfirm: PropTypes.func,
/** Callback to parent modal to send money */
- onSendMoney: PropTypes.func.isRequired,
+ onSendMoney: PropTypes.func,
/** Should we request a single or multiple participant selection from user */
hasMultipleParticipants: PropTypes.bool.isRequired,
@@ -40,11 +40,17 @@ const propTypes = {
/** Selected participants from MoneyRequestModal with login */
participants: PropTypes.arrayOf(optionPropTypes).isRequired,
+ /** Payee of the money request with login */
+ payeePersonalDetails: optionPropTypes,
+
/** Can the participants be modified or not */
canModifyParticipants: PropTypes.bool,
+ /** Should the list be read only, and not editable? */
+ isReadOnly: PropTypes.bool,
+
/** Depending on expense report or personal IOU report, respective bank account route */
- bankAccountRoute: PropTypes.string.isRequired,
+ bankAccountRoute: PropTypes.string,
...windowDimensionsPropTypes,
@@ -69,18 +75,24 @@ const propTypes = {
}),
/** Callback function to navigate to a provided step in the MoneyRequestModal flow */
- navigateToStep: PropTypes.func.isRequired,
+ navigateToStep: PropTypes.func,
/** The policyID of the request */
policyID: PropTypes.string,
};
const defaultProps = {
+ onConfirm: () => {},
+ onSendMoney: () => {},
+ navigateToStep: () => {},
iou: {
selectedCurrencyCode: CONST.CURRENCY.USD,
},
iouType: CONST.IOU.MONEY_REQUEST_TYPE.REQUEST,
+ payeePersonalDetails: null,
canModifyParticipants: false,
+ isReadOnly: false,
+ bankAccountRoute: '',
session: {
email: null,
},
@@ -158,6 +170,15 @@ class MoneyRequestConfirmationList extends Component {
return _.map(participants, (option) => _.omit(option, 'descriptiveText'));
}
+ /**
+ * Returns the personalDetails object for the payee. Use the payee prop if passed, else fallback to current user
+ *
+ * @returns {Object} personalDetails
+ */
+ getPayeePersonalDetails() {
+ return this.props.payeePersonalDetails || this.props.currentUserPersonalDetails;
+ }
+
/**
* Returns the sections needed for the OptionsSelector
*
@@ -174,15 +195,15 @@ class MoneyRequestConfirmationList extends Component {
const formattedParticipants = _.union(formattedSelectedParticipants, formattedUnselectedParticipants);
const myIOUAmount = IOUUtils.calculateAmount(selectedParticipants.length, this.props.iouAmount, true);
- const formattedMyPersonalDetails = OptionsListUtils.getIOUConfirmationOptionsFromMyPersonalDetail(
- this.props.currentUserPersonalDetails,
+ const formattedPayeePersonalDetails = OptionsListUtils.getIOUConfirmationOptionsFromPayeePersonalDetail(
+ this.getPayeePersonalDetails(),
CurrencyUtils.convertToDisplayString(myIOUAmount, this.props.iou.selectedCurrencyCode),
);
sections.push(
{
title: this.props.translate('moneyRequestConfirmationList.whoPaid'),
- data: [formattedMyPersonalDetails],
+ data: [formattedPayeePersonalDetails],
shouldShow: true,
indexOffset: 0,
isDisabled: true,
@@ -206,6 +227,36 @@ class MoneyRequestConfirmationList extends Component {
return sections;
}
+ getFooterContent() {
+ if (this.props.isReadOnly) {
+ return;
+ }
+
+ const selectedParticipants = this.getSelectedParticipants();
+ const shouldShowSettlementButton = this.props.iouType === CONST.IOU.MONEY_REQUEST_TYPE.SEND;
+ const shouldDisableButton = selectedParticipants.length === 0;
+ const recipient = this.state.participants[0];
+
+ return shouldShowSettlementButton ? (
+
+ ) : (
+ this.confirm(value)}
+ options={this.getSplitOrRequestOptions()}
+ />
+ );
+ }
+
/**
* Returns selected options -- there is checkmark for every row in List for split flow
* @returns {Array}
@@ -215,7 +266,7 @@ class MoneyRequestConfirmationList extends Component {
return [];
}
const selectedParticipants = this.getSelectedParticipants();
- return [...selectedParticipants, OptionsListUtils.getIOUConfirmationOptionsFromMyPersonalDetail(this.props.currentUserPersonalDetails)];
+ return [...selectedParticipants, OptionsListUtils.getIOUConfirmationOptionsFromPayeePersonalDetail(this.getPayeePersonalDetails())];
}
/**
@@ -263,11 +314,7 @@ class MoneyRequestConfirmationList extends Component {
}
render() {
- const selectedParticipants = this.getSelectedParticipants();
- const shouldShowSettlementButton = this.props.iouType === CONST.IOU.MONEY_REQUEST_TYPE.SEND;
- const shouldDisableButton = selectedParticipants.length === 0;
- const recipient = this.state.participants[0];
- const canModifyParticipants = this.props.canModifyParticipants && this.props.hasMultipleParticipants;
+ const canModifyParticipants = !this.props.isReadOnly && this.props.canModifyParticipants && this.props.hasMultipleParticipants;
const formattedAmount = CurrencyUtils.convertToDisplayString(this.props.iouAmount, this.props.iou.selectedCurrencyCode);
return (
@@ -285,43 +332,24 @@ class MoneyRequestConfirmationList extends Component {
shouldShowTextInput={false}
shouldUseStyleForChildren={false}
optionHoveredStyle={canModifyParticipants ? styles.hoveredComponentBG : {}}
- footerContent={
- shouldShowSettlementButton ? (
-
- ) : (
- this.confirm(value)}
- options={this.getSplitOrRequestOptions()}
- />
- )
- }
+ footerContent={this.getFooterContent()}
>
this.props.navigateToStep(0)}
style={[styles.moneyRequestMenuItem, styles.mt2]}
titleStyle={styles.moneyRequestConfirmationAmount}
- disabled={this.state.didConfirm}
+ disabled={this.state.didConfirm || this.props.isReadOnly}
/>
Navigation.navigate(ROUTES.MONEY_REQUEST_DESCRIPTION)}
style={[styles.moneyRequestMenuItem, styles.mb2]}
- disabled={this.state.didConfirm}
+ disabled={this.state.didConfirm || this.props.isReadOnly}
/>
);
diff --git a/src/components/OptionsSelector/BaseOptionsSelector.js b/src/components/OptionsSelector/BaseOptionsSelector.js
index f2ae4ee96718..312f5d386b61 100755
--- a/src/components/OptionsSelector/BaseOptionsSelector.js
+++ b/src/components/OptionsSelector/BaseOptionsSelector.js
@@ -275,7 +275,8 @@ class BaseOptionsSelector extends Component {
}
render() {
- const shouldShowFooter = (this.props.shouldShowConfirmButton || this.props.footerContent) && !(this.props.canSelectMultipleOptions && _.isEmpty(this.props.selectedOptions));
+ const shouldShowFooter =
+ !this.props.isReadOnly && (this.props.shouldShowConfirmButton || this.props.footerContent) && !(this.props.canSelectMultipleOptions && _.isEmpty(this.props.selectedOptions));
const defaultConfirmButtonText = _.isUndefined(this.props.confirmButtonText) ? this.props.translate('common.confirm') : this.props.confirmButtonText;
const shouldShowDefaultConfirmButton = !this.props.footerContent && defaultConfirmButtonText;
const textInput = (
diff --git a/src/components/ReportActionItem/MoneyRequestAction.js b/src/components/ReportActionItem/MoneyRequestAction.js
index 174e4c922327..1f11eeae780e 100644
--- a/src/components/ReportActionItem/MoneyRequestAction.js
+++ b/src/components/ReportActionItem/MoneyRequestAction.js
@@ -91,12 +91,12 @@ const defaultProps = {
};
const MoneyRequestAction = (props) => {
- const hasMultipleParticipants = lodashGet(props.chatReport, 'participants', []).length > 1;
const isSplitBillAction = lodashGet(props.action, 'originalMessage.type', '') === CONST.IOU.REPORT_ACTION_TYPE.SPLIT;
const onIOUPreviewPressed = () => {
- if (isSplitBillAction && hasMultipleParticipants) {
- Navigation.navigate(ROUTES.getReportParticipantsRoute(props.chatReportID));
+ if (isSplitBillAction) {
+ const reportActionID = lodashGet(props.action, 'reportActionID', '0');
+ Navigation.navigate(ROUTES.getSplitBillDetailsRoute(props.chatReportID, reportActionID));
return;
}
diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js
index 6a00bc750e9a..0e523002a939 100644
--- a/src/libs/Navigation/AppNavigator/AuthScreens.js
+++ b/src/libs/Navigation/AppNavigator/AuthScreens.js
@@ -340,6 +340,12 @@ class AuthScreens extends React.Component {
component={ModalStackNavigators.EnablePaymentsStackNavigator}
listeners={modalScreenListeners}
/>
+
{
+ const SplitBillDetailsPage = require('../../../pages/iou/SplitBillDetailsPage').default;
+ return SplitBillDetailsPage;
+ },
+ name: 'SplitDetails_Root',
+ },
+]);
+
const DetailsModalStackNavigator = createModalStackNavigator([
{
getComponent: () => {
@@ -696,6 +706,7 @@ export {
IOUBillStackNavigator,
IOURequestModalStackNavigator,
IOUSendModalStackNavigator,
+ SplitDetailsModalStackNavigator,
DetailsModalStackNavigator,
ReportDetailsModalStackNavigator,
TaskModalStackNavigator,
diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js
index ed34421d4ace..4659477c2df9 100644
--- a/src/libs/Navigation/linkingConfig.js
+++ b/src/libs/Navigation/linkingConfig.js
@@ -295,6 +295,11 @@ export default {
IOU_Send_Add_Debit_Card: ROUTES.IOU_SEND_ADD_DEBIT_CARD,
},
},
+ SplitDetails: {
+ screens: {
+ SplitDetails_Root: ROUTES.SPLIT_BILL_DETAILS,
+ },
+ },
Task_Details: {
screens: {
Task_Title: ROUTES.TASK_TITLE,
diff --git a/src/libs/OptionsListUtils.js b/src/libs/OptionsListUtils.js
index 8513ce55f13a..d2a0aa0aace4 100644
--- a/src/libs/OptionsListUtils.js
+++ b/src/libs/OptionsListUtils.js
@@ -794,25 +794,25 @@ function getSearchOptions(reports, personalDetails, searchValue = '', betas) {
}
/**
- * Build the IOUConfirmation options for showing MyPersonalDetail
+ * Build the IOUConfirmation options for showing the payee personalDetail
*
- * @param {Object} myPersonalDetail
+ * @param {Object} personalDetail
* @param {String} amountText
* @returns {Object}
*/
-function getIOUConfirmationOptionsFromMyPersonalDetail(myPersonalDetail, amountText) {
+function getIOUConfirmationOptionsFromPayeePersonalDetail(personalDetail, amountText) {
return {
- text: myPersonalDetail.displayName,
- alternateText: myPersonalDetail.login,
+ text: personalDetail.displayName ? personalDetail.displayName : personalDetail.login,
+ alternateText: personalDetail.login,
icons: [
{
- source: ReportUtils.getAvatar(myPersonalDetail.avatar, myPersonalDetail.login),
- name: myPersonalDetail.login,
+ source: ReportUtils.getAvatar(personalDetail.avatar, personalDetail.login),
+ name: personalDetail.login,
type: CONST.ICON_TYPE_AVATAR,
},
],
descriptiveText: amountText,
- login: myPersonalDetail.login,
+ login: personalDetail.login,
};
}
@@ -953,7 +953,7 @@ export {
getMemberInviteOptions,
getHeaderMessage,
getPersonalDetailsForLogins,
- getIOUConfirmationOptionsFromMyPersonalDetail,
+ getIOUConfirmationOptionsFromPayeePersonalDetail,
getIOUConfirmationOptionsFromParticipants,
getSearchText,
getAllReportErrors,
diff --git a/src/pages/iou/SplitBillDetailsPage.js b/src/pages/iou/SplitBillDetailsPage.js
new file mode 100644
index 000000000000..19178582b6ba
--- /dev/null
+++ b/src/pages/iou/SplitBillDetailsPage.js
@@ -0,0 +1,117 @@
+import React from 'react';
+import _ from 'underscore';
+import {View} from 'react-native';
+import PropTypes from 'prop-types';
+import {withOnyx} from 'react-native-onyx';
+import lodashGet from 'lodash/get';
+import styles from '../../styles/styles';
+import ONYXKEYS from '../../ONYXKEYS';
+import * as OptionsListUtils from '../../libs/OptionsListUtils';
+import ModalHeader from './ModalHeader';
+import ScreenWrapper from '../../components/ScreenWrapper';
+import MoneyRequestConfirmationList from '../../components/MoneyRequestConfirmationList';
+import personalDetailsPropType from '../personalDetailsPropType';
+import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
+import compose from '../../libs/compose';
+import reportActionPropTypes from '../home/report/reportActionPropTypes';
+import reportPropTypes from '../reportPropTypes';
+import withReportOrNotFound from '../home/report/withReportOrNotFound';
+import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView';
+import CONST from '../../CONST';
+
+const propTypes = {
+ /* Onyx Props */
+
+ /** The personal details of the person who is logged in */
+ personalDetails: personalDetailsPropType,
+
+ /** The active report */
+ report: reportPropTypes.isRequired,
+
+ /** Array of report actions for this report */
+ reportActions: PropTypes.shape(reportActionPropTypes),
+
+ /** Route params */
+ route: PropTypes.shape({
+ params: PropTypes.shape({
+ /** Report ID passed via route r/:reportID/split/details */
+ reportID: PropTypes.string,
+
+ /** ReportActionID passed via route r/split/:reportActionID */
+ reportActionID: PropTypes.string,
+ }),
+ }).isRequired,
+
+ ...withLocalizePropTypes,
+};
+
+const defaultProps = {
+ personalDetails: {},
+ reportActions: {},
+};
+
+/**
+ * Get the reportID for the associated chatReport
+ *
+ * @param {Object} route
+ * @param {Object} route.params
+ * @param {String} route.params.reportID
+ * @returns {String}
+ */
+function getReportID(route) {
+ return route.params.reportID.toString();
+}
+
+const SplitBillDetailsPage = (props) => {
+ const reportAction = props.reportActions[`${props.route.params.reportActionID.toString()}`];
+ const personalDetails = OptionsListUtils.getPersonalDetailsForLogins(reportAction.originalMessage.participants, props.personalDetails);
+ const participants = OptionsListUtils.getParticipantsOptions(reportAction.originalMessage, personalDetails);
+ const payeePersonalDetails = _.filter(participants, (participant) => participant.login === reportAction.actorEmail)[0];
+ const participantsExcludingPayee = _.filter(participants, (participant) => participant.login !== reportAction.actorEmail);
+ const splitAmount = parseInt(lodashGet(reportAction, 'originalMessage.amount', 0), 10);
+
+ return (
+
+
+
+
+ {Boolean(participants.length) && (
+
+ )}
+
+
+
+ );
+};
+
+SplitBillDetailsPage.propTypes = propTypes;
+SplitBillDetailsPage.defaultProps = defaultProps;
+SplitBillDetailsPage.displayName = 'SplitBillDetailsPage';
+
+export default compose(
+ withLocalize,
+ withReportOrNotFound,
+ withOnyx({
+ personalDetails: {
+ key: ONYXKEYS.PERSONAL_DETAILS,
+ },
+ reportActions: {
+ key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${getReportID(route)}`,
+ canEvict: false,
+ },
+ }),
+)(SplitBillDetailsPage);
diff --git a/src/pages/iou/steps/MoneyRequestConfirmPage.js b/src/pages/iou/steps/MoneyRequestConfirmPage.js
index 0ab9aea75cf3..e86edadf5223 100644
--- a/src/pages/iou/steps/MoneyRequestConfirmPage.js
+++ b/src/pages/iou/steps/MoneyRequestConfirmPage.js
@@ -57,7 +57,7 @@ const MoneyRequestConfirmPage = (props) => (
/>
);
-MoneyRequestConfirmPage.displayName = 'IOUConfirmPage';
+MoneyRequestConfirmPage.displayName = 'MoneyRequestConfirmPage';
MoneyRequestConfirmPage.propTypes = propTypes;
MoneyRequestConfirmPage.defaultProps = defaultProps;