Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
1b4218d
remove old API call and create skeleton of new one
Gonals Sep 5, 2022
a5912bf
add fake data
Gonals Sep 5, 2022
8de1ab4
Merge branch 'main' into alberto-requestMoney
Gonals Sep 5, 2022
da2704b
error message
Gonals Sep 5, 2022
8490938
use existing chat when available
Gonals Sep 5, 2022
ccd0e51
remove unneeded code
Gonals Sep 6, 2022
cfd5408
add missing params
Gonals Sep 6, 2022
5e489a2
style
Gonals Sep 6, 2022
76115dc
resolve conflicts
Gonals Sep 7, 2022
4da1f9d
move to actual params
Gonals Sep 7, 2022
41f975d
pass parameters
Gonals Sep 8, 2022
86ff05b
remove extra function
Gonals Sep 8, 2022
417226a
Merge branch 'main' into alberto-requestMoney
Gonals Sep 8, 2022
4b0979c
Use existing IOU report when available
Gonals Sep 12, 2022
706ab51
load ious early
Gonals Sep 12, 2022
d1d0464
build better optimistic action
Gonals Sep 13, 2022
9373c1d
handle total IOU owed
Gonals Sep 13, 2022
567595d
Do not disable button when offline
Gonals Sep 13, 2022
1adea53
update comments
Gonals Sep 13, 2022
464f429
add translation
Gonals Sep 13, 2022
e253231
add JSDOc
Gonals Sep 14, 2022
0ad2e78
remove isLoading
Gonals Sep 14, 2022
ca21371
remove withNetwork
Gonals Sep 14, 2022
0382be8
Merge branch 'main' into alberto-requestMoney
Gonals Sep 15, 2022
175e8b9
address a few comments
Gonals Sep 15, 2022
4dd7412
missed a couple
Gonals Sep 15, 2022
a4073ac
Merge branch 'main' into alberto-requestMoney
Gonals Sep 20, 2022
b1e1fa7
do not show offline message
Gonals Sep 20, 2022
39bfe27
rename reportID param
Gonals Sep 20, 2022
2576245
correctly prevent preview transparency when not needed
Gonals Sep 21, 2022
4b110f7
remove unneeded import
Gonals Sep 21, 2022
01b91cd
Merge branch 'main' into alberto-requestMoney
Gonals Sep 21, 2022
95161b5
Hide from main menu when offline
Gonals Sep 21, 2022
73979e8
pass clientID
Gonals Sep 23, 2022
676b269
conflicts
Gonals Sep 23, 2022
f1d20ff
correctly build the optimistic action now that the function changed
Gonals Sep 29, 2022
7c67a45
several changes to fit new code after merge main
Gonals Sep 29, 2022
35f4b67
style
Gonals Sep 29, 2022
b7c3593
merge main
Gonals Oct 6, 2022
1c25dcd
make report defaults strings
Gonals Oct 6, 2022
76b03bb
Merge branch 'main' into alberto-requestMoney
Gonals Oct 10, 2022
69a992a
use function to retrieve mas sequence number
Gonals Oct 10, 2022
77c9202
use random number instead
Gonals Oct 10, 2022
26eaef0
remove unneeded export
Gonals Oct 10, 2022
d2653d2
Merge branch 'main' into alberto-requestMoney
Gonals Oct 11, 2022
7760296
add comments to optimistic action
Gonals Oct 11, 2022
caac0f7
try best guess for sequence number
Gonals Oct 11, 2022
f3144af
update maxSequenceNumber optimistically
Gonals Oct 11, 2022
e0941eb
Merge branch 'main' into alberto-requestMoney
Gonals Oct 11, 2022
4804261
change parameter to string
Gonals Oct 11, 2022
ded0bae
improve header
Gonals Oct 11, 2022
beaf969
correct default
Gonals Oct 13, 2022
897d93b
spacing
Gonals Oct 13, 2022
48fe19a
Fix not displaying actions correctly
Gonals Oct 13, 2022
180ce4a
change type
Gonals Oct 13, 2022
3f143ea
Merge branch 'main' into alberto-requestMoney
Gonals Oct 14, 2022
49d3ccf
Compare numbers
Gonals Oct 17, 2022
7be5f73
add locale and other minor improvements
Gonals Oct 18, 2022
7a91acf
improvements to optimistic data generation
Gonals Oct 18, 2022
fd44b8a
more comments addressed
Gonals Oct 18, 2022
a6cda47
Merge branch 'main' into alberto-requestMoney
Gonals Oct 18, 2022
c70f141
fix long line
Gonals Oct 18, 2022
adc05a3
Merge branch 'main' into alberto-requestMoney
Gonals Oct 18, 2022
997d0de
Add chatReport functions
Gonals Oct 19, 2022
6f1d212
move function to Utils and use it:
Gonals Oct 19, 2022
304fc88
do not use that function anymore
Gonals Oct 19, 2022
180172a
better create data for chat reports and whatnot
Gonals Oct 19, 2022
10b2413
enable money requests from the main menu
Gonals Oct 19, 2022
29c8e4b
correctly get char report
Gonals Oct 19, 2022
8839c38
cleanup
Gonals Oct 19, 2022
2e70114
cleanup
Gonals Oct 19, 2022
aacd54e
Merge branch 'main' into alberto-requestMoney
Gonals Oct 21, 2022
8ae152a
Better handle create action cleanup
Gonals Oct 21, 2022
c3e0058
reorganize data build
Gonals Oct 21, 2022
6e725b2
dateutils import
Gonals Oct 21, 2022
d63f492
use consts
Gonals Oct 21, 2022
2c4028e
Merge branch 'main' into alberto-requestMoney
Gonals Oct 25, 2022
ef58ba7
Add new function to handle existing IOUs
Gonals Oct 25, 2022
edfd163
do not update total twice
Gonals Oct 25, 2022
4986dea
copy full file to reduce conflicts
Gonals Oct 25, 2022
b542650
store iou in chat report correctly
Gonals Oct 25, 2022
08d6217
correctly handle /bin/zsh IOUs
Gonals Oct 26, 2022
9c17752
Merge branch 'main' into alberto-requestMoney
Gonals Oct 26, 2022
587575a
Merge branch 'main' into alberto-requestMoney
Gonals Oct 26, 2022
1031f7a
update lastMessage
Gonals Oct 26, 2022
d1183ad
treat message as an array
Gonals Oct 26, 2022
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
1 change: 1 addition & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,7 @@ const CONST = {
},
REPORT_ACTION_TYPE: {
PAY: 'pay',
CREATE: 'create',
},
AMOUNT_MAX_LENGTH: 10,
},
Expand Down
4 changes: 2 additions & 2 deletions src/components/IOUBadge.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ const propTypes = {

const defaultProps = {
iouReport: {
reportID: 0,
chatReportID: 0,
reportID: '',
chatReportID: '',
Comment thread
mountiny marked this conversation as resolved.
total: 0,
ownerEmail: null,
currency: CONST.CURRENCY.USD,
Expand Down
11 changes: 1 addition & 10 deletions src/components/IOUConfirmationList.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import ButtonWithMenu from './ButtonWithMenu';
import Log from '../libs/Log';
import SettlementButton from './SettlementButton';
import ROUTES from '../ROUTES';
import networkPropTypes from './networkPropTypes';
import {withNetwork} from './OnyxProvider';
Comment thread
Gonals marked this conversation as resolved.
import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from './withCurrentUserPersonalDetails';

const propTypes = {
Expand Down Expand Up @@ -79,9 +77,6 @@ const propTypes = {
selectedCurrencyCode: PropTypes.string,
}),

/** Information about the network */
network: networkPropTypes.isRequired,

/** Current user session */
session: PropTypes.shape({
email: PropTypes.string.isRequired,
Expand Down Expand Up @@ -330,8 +325,7 @@ class IOUConfirmationList extends Component {
render() {
const selectedParticipants = this.getSelectedParticipants();
const shouldShowSettlementButton = this.props.iouType === CONST.IOU.IOU_TYPE.SEND;
const shouldDisableButton = selectedParticipants.length === 0 || this.props.network.isOffline;
const isLoading = this.props.iou.loading && !this.props.network.isOffline;
const shouldDisableButton = selectedParticipants.length === 0;
const recipient = this.state.participants[0];
const canModifyParticipants = this.props.isIOUAttachedToExistingChatReport && this.props.hasMultipleParticipants;
return (
Expand All @@ -357,7 +351,6 @@ class IOUConfirmationList extends Component {
? (
<SettlementButton
isDisabled={shouldDisableButton}
isLoading={isLoading}
onPress={this.confirm}
shouldShowPaypal={Boolean(recipient.payPalMeAddress)}
enablePaymentsRoute={ROUTES.IOU_SEND_ENABLE_PAYMENTS}
Expand All @@ -368,7 +361,6 @@ class IOUConfirmationList extends Component {
) : (
<ButtonWithMenu
isDisabled={shouldDisableButton}
isLoading={isLoading}
onPress={(_event, value) => this.confirm(value)}
options={this.splitOrRequestOptions}
/>
Expand All @@ -384,7 +376,6 @@ IOUConfirmationList.defaultProps = defaultProps;
export default compose(
withLocalize,
withWindowDimensions,
withNetwork(),
withCurrentUserPersonalDetails,
withOnyx({
iou: {key: ONYXKEYS.IOU},
Expand Down
2 changes: 2 additions & 0 deletions src/components/ReportActionItem/IOUAction.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import {withOnyx} from 'react-native-onyx';
import lodashGet from 'lodash/get';
import ONYXKEYS from '../../ONYXKEYS';
import IOUQuote from './IOUQuote';
import reportActionPropTypes from '../../pages/home/report/reportActionPropTypes';
Expand Down Expand Up @@ -47,6 +48,7 @@ const IOUAction = (props) => {
{((props.isMostRecentIOUReportAction && Boolean(props.action.originalMessage.IOUReportID))
|| (props.action.originalMessage.type === 'pay')) && (
<IOUPreview
pendingAction={lodashGet(props.action, 'pendingAction', null)}
iouReportID={props.action.originalMessage.IOUReportID.toString()}
chatReportID={props.chatReportID}
onPayButtonPressed={launchDetailsModal}
Expand Down
6 changes: 5 additions & 1 deletion src/components/ReportActionItem/IOUPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ const propTypes = {
/** Information about the user accepting the terms for payments */
walletTerms: walletTermsPropTypes,

/** Pending action, if any */
pendingAction: PropTypes.oneOf(_.values(CONST.RED_BRICK_ROAD_PENDING_ACTION)),

...withLocalizePropTypes,
};

Expand All @@ -91,6 +94,7 @@ const defaultProps = {
onPreviewPressed: () => {},
containerStyles: [],
walletTerms: {},
pendingAction: null,
};

const IOUPreview = (props) => {
Expand Down Expand Up @@ -132,7 +136,7 @@ const IOUPreview = (props) => {
? <ActivityIndicator style={styles.iouPreviewBoxLoading} color={themeColors.text} />
: (
<OfflineWithFeedback
pendingAction={CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}
pendingAction={props.pendingAction}
errors={props.walletTerms.errors}
onClose={() => {
PaymentMethods.clearWalletTermsError();
Expand Down
4 changes: 2 additions & 2 deletions src/components/ReportTransaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ import Button from './Button';
const propTypes = {
/** The chatReport which the transaction is associated with */
/* eslint-disable-next-line react/no-unused-prop-types */
chatReportID: PropTypes.number.isRequired,
chatReportID: PropTypes.string.isRequired,

/** ID for the IOU report */
/* eslint-disable-next-line react/no-unused-prop-types */
iouReportID: PropTypes.number.isRequired,
iouReportID: PropTypes.string.isRequired,

/** The report action which we are displaying */
action: PropTypes.shape(reportActionPropTypes).isRequired,
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ export default {
error: {
invalidSplit: 'Split amounts do not equal total amount',
other: 'Unexpected error, please try again later',
genericCreateFailureMessage: 'Unexpected error requesting money, please try again later',
Comment thread
Gonals marked this conversation as resolved.
Comment thread
Gonals marked this conversation as resolved.
},
},
notificationPreferences: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ export default {
error: {
invalidSplit: 'La suma de las partes no equivale al monto total',
other: 'Error inesperado, por favor inténtalo más tarde',
genericCreateFailureMessage: 'Error inesperado solicitando dinero, por favor inténtalo más tarde',
Comment thread
luacmartins marked this conversation as resolved.
},
},
notificationPreferences: {
Expand Down
64 changes: 64 additions & 0 deletions src/libs/IOUUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
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} total - IOU total amount
* @param {Boolean} isDefaultUser - Whether we are calculating the amount for the current user
* @returns {Number}
*/
function calculateAmount(participants, total, isDefaultUser = false) {
// Convert to cents before working with iouAmount to avoid
// javascript subtraction with decimal problem -- when dealing with decimals,
// because they are encoded as IEEE 754 floating point numbers, some of the decimal
// numbers cannot be represented with perfect accuracy.
// Cents is temporary and there must be support for other currencies in the future
const iouAmount = Math.round(parseFloat(total * 100));
const totalParticipants = participants.length + 1;
const amountPerPerson = Math.round(iouAmount / totalParticipants);

if (!isDefaultUser) {
return amountPerPerson;
}

const sumAmount = amountPerPerson * totalParticipants;
const difference = iouAmount - sumAmount;

return iouAmount !== sumAmount ? (amountPerPerson + difference) : amountPerPerson;
}
Comment on lines +10 to +28

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add unit tests for this file?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are quite good shouts, I think such issues could be external, what do you think @Julesssss @luacmartins @Gonals


/**
* The owner of the IOU report is the account who is owed money and the manager is the one who owes money!
* In case the owner/manager swap, we need to update the owner of the IOU report and the report total, since it is always positive.
* For example: if user1 owes user2 $10, then we have: {ownerEmail: user2, managerEmail: user1, total: $10 (a positive amount, owed to user2)}
* If user1 requests $17 from user2, then we have: {ownerEmail: user1, managerEmail: user2, total: $7 (still a positive amount, but now owed to user1)}
*
* @param {Object} iouReport
* @param {String} actorEmail
* @param {Number} amount
* @param {String} type
* @returns {Object}
*/
function updateIOUOwnerAndTotal(iouReport, actorEmail, amount, type = CONST.IOU.REPORT_ACTION_TYPE.CREATE) {
const iouReportUpdate = {...iouReport};

if (actorEmail === iouReport.ownerEmail) {
iouReportUpdate.total += type === CONST.IOU.REPORT_ACTION_TYPE.CANCEL ? -amount : amount;
} else {
iouReportUpdate.total += type === CONST.IOU.REPORT_ACTION_TYPE.CANCEL ? amount : -amount;
}

if (iouReportUpdate.total < 0) {
// The total sign has changed and hence we need to flip the manager and owner of the report.
iouReportUpdate.ownerEmail = iouReport.managerEmail;
iouReportUpdate.managerEmail = iouReport.ownerEmail;
iouReportUpdate.total = -iouReportUpdate.total;
}

return iouReportUpdate;
}

export {
calculateAmount,
updateIOUOwnerAndTotal,
};
41 changes: 32 additions & 9 deletions src/libs/ReportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -645,10 +645,19 @@ function buildOptimisticReportAction(sequenceNumber, text, file) {
};
}

/*
/**
* Builds an optimistic IOU report with a randomly generated reportID
*
* @param {String} ownerEmail - Email of the person generating the IOU.
* @param {String} userEmail - Email of the other person participating in the IOU.
* @param {Number} total - IOU amount in cents.
* @param {String} chatReportID - Report ID of the chat where the IOU is.
Comment thread
mountiny marked this conversation as resolved.
* @param {String} currency - IOU currency.
* @param {String} locale - Locale where the IOU is created
*
* @returns {Object}
*/
function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportID, currency, locale) {
function buildOptimisticIOUReport(ownerEmail, userEmail, total, chatReportID, currency, locale) {
const formattedTotal = NumberFormatUtils.format(locale,
total, {
style: 'currency',
Expand All @@ -659,7 +668,7 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI
chatReportID,
currency,
hasOutstandingIOU: true,
managerEmail: recipientEmail,
managerEmail: userEmail,
ownerEmail,
reportID: generateReportID(),
state: CONST.REPORT.STATE.SUBMITTED,
Expand All @@ -674,17 +683,19 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI
* @param {Number} sequenceNumber - Caller is responsible for providing a best guess at what the next sequenceNumber will be.
* @param {String} type - IOUReportAction type. Can be oneOf(create, decline, cancel, pay).
* @param {Number} amount - IOU amount in cents.
* @param {String} currency - IOU currency.
* @param {String} comment - User comment for the IOU.
* @param {String} paymentType - Only required if the IOUReportAction type is 'pay'. Can be oneOf(elsewhere, payPal, Expensify).
* @param {String} existingIOUTransactionID - Only required if the IOUReportAction type is oneOf(cancel, decline). Generates a randomID as default.
* @param {Number} existingIOUReportID - Only required if the IOUReportActions type is oneOf(decline, cancel, pay). Generates a randomID as default.
* @param {String} iouTransactionID - Only required if the IOUReportAction type is oneOf(cancel, decline). Generates a randomID as default.
* @param {String} iouReportID - Only required if the IOUReportActions type is oneOf(decline, cancel, pay). Generates a randomID as default.
* @param {String} debtorEmail - Email of the user that has to pay
* @param {String} locale - Locale of the user
*
* @returns {Object}
*/
function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, paymentType = '', existingIOUTransactionID = '', existingIOUReportID = 0) {
const currency = lodashGet(currentUserPersonalDetails, 'localCurrencyCode');
const IOUTransactionID = existingIOUTransactionID || NumberUtils.rand64();
const IOUReportID = existingIOUReportID || generateReportID();
function buildOptimisticIOUReportAction(sequenceNumber, type, amount, currency, comment, paymentType = '', iouTransactionID = '', iouReportID = '', debtorEmail = '', locale = 'en') {
const IOUTransactionID = iouTransactionID || NumberUtils.rand64();
Comment on lines +696 to +697

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why unit tests for this missed out.

const IOUReportID = iouReportID || generateReportID();
const originalMessage = {
amount,
comment,
Expand All @@ -693,6 +704,17 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, p
IOUReportID,
type,
};
const formattedTotal = NumberFormatUtils.format(locale,
amount / 100, {
style: 'currency',
currency,
});
const message = [{
type: CONST.REPORT.MESSAGE.TYPE.COMMENT,
isEdited: false,
html: comment ? `Requested ${formattedTotal} from ${debtorEmail} for ${comment}` : `Requested ${formattedTotal} from ${debtorEmail}`,
text: comment ? `Requested ${formattedTotal} from ${debtorEmail} for ${comment}` : `Requested ${formattedTotal} from ${debtorEmail}`,
}];

// We store amount, comment, currency in IOUDetails when type = pay
if (type === CONST.IOU.REPORT_ACTION_TYPE.PAY) {
Expand All @@ -711,6 +733,7 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, p
avatar: lodashGet(currentUserPersonalDetails, 'avatar', getDefaultAvatar(currentUserEmail)),
clientID: NumberUtils.generateReportActionClientID(),
isAttachment: false,
message,
originalMessage,
person: [{
style: 'strong',
Expand Down
Loading