-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Refactor createIOUTransaction to RequestMoney #10843
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
Changes from all commits
1b4218d
a5912bf
8de1ab4
da2704b
8490938
ccd0e51
cfd5408
5e489a2
76115dc
4da1f9d
41f975d
86ff05b
417226a
4b0979c
706ab51
d1d0464
9373c1d
567595d
1adea53
464f429
e253231
0ad2e78
ca21371
0382be8
175e8b9
4dd7412
a4073ac
b1e1fa7
39bfe27
2576245
4b110f7
01b91cd
95161b5
73979e8
676b269
f1d20ff
7c67a45
35f4b67
b7c3593
1c25dcd
76b03bb
69a992a
77c9202
26eaef0
d2653d2
7760296
caac0f7
f3144af
e0941eb
4804261
ded0bae
beaf969
897d93b
48fe19a
180ce4a
3f143ea
49d3ccf
7be5f73
7a91acf
fd44b8a
a6cda47
c70f141
adc05a3
997d0de
6f1d212
304fc88
180172a
10b2413
29c8e4b
8839c38
2e70114
aacd54e
8ae152a
c3e0058
6e725b2
d63f492
2c4028e
ef58ba7
edfd163
4986dea
b542650
08d6217
9c17752
587575a
1031f7a
d1183ad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add unit tests for this file?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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, | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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. | ||
|
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', | ||
|
|
@@ -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, | ||
|
|
@@ -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
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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, | ||
|
|
@@ -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) { | ||
|
|
@@ -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', | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.