Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

show individual split amount on Bill Split IOU Previews #18715

Merged
merged 4 commits into from
May 14, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/MoneyRequestConfirmationList.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class MoneyRequestConfirmationList extends Component {
* @returns {Array}
*/
getParticipantsWithAmount(participants) {
const iouAmount = IOUUtils.calculateAmount(participants, this.props.iouAmount);
const iouAmount = IOUUtils.calculateAmount(participants.length, this.props.iouAmount);
return OptionsListUtils.getIOUConfirmationOptionsFromParticipants(participants, CurrencyUtils.convertToDisplayString(iouAmount, this.props.iou.selectedCurrencyCode));
}

Expand Down Expand Up @@ -168,7 +168,7 @@ class MoneyRequestConfirmationList extends Component {
const formattedUnselectedParticipants = this.getParticipantsWithoutAmount(unselectedParticipants);
const formattedParticipants = _.union(formattedSelectedParticipants, formattedUnselectedParticipants);

const myIOUAmount = IOUUtils.calculateAmount(selectedParticipants, this.props.iouAmount, true);
const myIOUAmount = IOUUtils.calculateAmount(selectedParticipants.length, this.props.iouAmount, true);
const formattedMyPersonalDetails = OptionsListUtils.getIOUConfirmationOptionsFromMyPersonalDetail(
this.props.currentUserPersonalDetails,
CurrencyUtils.convertToDisplayString(myIOUAmount, this.props.iou.selectedCurrencyCode),
Expand Down
21 changes: 16 additions & 5 deletions src/components/ReportActionItem/IOUPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {showContextMenuForReport} from '../ShowContextMenuContext';
import * as OptionsListUtils from '../../libs/OptionsListUtils';
import Button from '../Button';
import * as CurrencyUtils from '../../libs/CurrencyUtils';
import * as IOUUtils from '../../libs/IOUUtils';

const propTypes = {
/** Additional logic for displaying the pay button */
Expand Down Expand Up @@ -199,11 +200,21 @@ const IOUPreview = (props) => {
</View>
</View>

{!isCurrentUserManager && props.shouldShowPendingConversionMessage && (
<Text style={[styles.textLabel, styles.colorMuted]}>{props.translate('iou.pendingConversionMessage')}</Text>
)}

<Text>{Str.htmlDecode(lodashGet(props.action, 'originalMessage.comment', ''))}</Text>
<View style={[styles.flexRow]}>
<View style={[styles.flex1]}>
{!isCurrentUserManager && props.shouldShowPendingConversionMessage && (
<Text style={[styles.textLabel, styles.colorMuted]}>{props.translate('iou.pendingConversionMessage')}</Text>
)}
<Text>{Str.htmlDecode(lodashGet(props.action, 'originalMessage.comment', ''))}</Text>
</View>
{props.isBillSplit && !_.isEmpty(participantEmails) && (
<Text style={[styles.textLabel, styles.colorMuted, styles.ml1]}>
{props.translate('iou.amountEach', {
amount: CurrencyUtils.convertToDisplayString(IOUUtils.calculateAmount(participantEmails.length - 1, requestAmount), requestCurrency),
})}
</Text>
)}
</View>

{isCurrentUserManager && !props.shouldHidePayButton && props.iouReport.stateNum === CONST.REPORT.STATE_NUM.PROCESSING && (
<Button
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ export default {
settlePaypalMe: 'Pay with PayPal.me',
requestAmount: ({amount}) => `request ${amount}`,
splitAmount: ({amount}) => `split ${amount}`,
amountEach: ({amount}) => `${amount} each`,
noReimbursableExpenses: 'This report has an invalid amount',
pendingConversionMessage: "Total will update when you're back online",
error: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ export default {
settlePaypalMe: 'Pagar con PayPal.me',
requestAmount: ({amount}) => `solicitar ${amount}`,
splitAmount: ({amount}) => `dividir ${amount}`,
amountEach: ({amount}) => `${amount} cada uno`,
noReimbursableExpenses: 'El monto de este informe es inválido',
pendingConversionMessage: 'El total se actualizará cuando estés online',
error: {
Expand Down
6 changes: 3 additions & 3 deletions src/libs/IOUUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import CONST from '../CONST';
/**
* Calculates the amount per user given a list of participants
*
* @param {Array} participants - List of logins for the participants in the chat. It should not include the current user's login.
* @param {Number} numberOfParticipants - Number of participants in the chat. It should not include the current user.
* @param {Number} total - IOU total amount in the smallest units of the currency
* @param {Boolean} isDefaultUser - Whether we are calculating the amount for the current user
* @returns {Number}
*/
function calculateAmount(participants, total, isDefaultUser = false) {
const totalParticipants = participants.length + 1;
function calculateAmount(numberOfParticipants, total, isDefaultUser = false) {
const totalParticipants = numberOfParticipants + 1;
const amountPerPerson = Math.round(total / totalParticipants);
let finalAmount = amountPerPerson;
if (isDefaultUser) {
Expand Down
4 changes: 2 additions & 2 deletions src/libs/actions/IOU.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,8 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment
}

// Loop through participants creating individual chats, iouReports and reportActionIDs as needed
const splitAmount = IOUUtils.calculateAmount(participants, amount, false);
const splits = [{email: currentUserEmail, amount: IOUUtils.calculateAmount(participants, amount, true)}];
const splitAmount = IOUUtils.calculateAmount(participants.length, amount, false);
const splits = [{email: currentUserEmail, amount: IOUUtils.calculateAmount(participants.length, amount, true)}];

const hasMultipleParticipants = participants.length > 1;
_.each(participants, (participant) => {
Expand Down
12 changes: 6 additions & 6 deletions tests/unit/IOUUtilsTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,20 +137,20 @@ describe('IOUUtils', () => {

test('103 JPY split among 3 participants including the default user should be [35, 34, 34]', () => {
const participants = ['tonystark@expensify.com', 'reedrichards@expensify.com'];
expect(IOUUtils.calculateAmount(participants, 103, true)).toBe(35);
expect(IOUUtils.calculateAmount(participants, 103)).toBe(34);
expect(IOUUtils.calculateAmount(participants.length, 103, true)).toBe(35);
expect(IOUUtils.calculateAmount(participants.length, 103)).toBe(34);
});

test('10 AFN split among 4 participants including the default user should be [1, 3, 3, 3]', () => {
const participants = ['tonystark@expensify.com', 'reedrichards@expensify.com', 'suestorm@expensify.com'];
expect(IOUUtils.calculateAmount(participants, 10, true)).toBe(1);
expect(IOUUtils.calculateAmount(participants, 10)).toBe(3);
expect(IOUUtils.calculateAmount(participants.length, 10, true)).toBe(1);
expect(IOUUtils.calculateAmount(participants.length, 10)).toBe(3);
});

test('0.02 USD split among 4 participants including the default user should be [-1, 1, 1, 1]', () => {
const participants = ['tonystark@expensify.com', 'reedrichards@expensify.com', 'suestorm@expensify.com'];
expect(IOUUtils.calculateAmount(participants, 2, true)).toBe(-1);
expect(IOUUtils.calculateAmount(participants, 2)).toBe(1);
expect(IOUUtils.calculateAmount(participants.length, 2, true)).toBe(-1);
expect(IOUUtils.calculateAmount(participants.length, 2)).toBe(1);
});
});
});