-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Fix IOU Options bug #8839
Fix IOU Options bug #8839
Conversation
Show Request and Send Money options when there are two participants, Splitbill option when there are more than two participants and no option if there is only one participant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you check out this #8357 (comment)
I've asked to move the logic to a new method!
Done. @iwiznia @Santhosh-Sellavel I have found another existing bug. While splitting bill, the logged in user(Chaudary Dai in this case) is counted twice. I think changing
to
in IOUModal.js solves the issue. Should I go through whole process of reporting? Or will I be compensated if I solved it here? |
/** | ||
* Returns the list of report compose actions | ||
* | ||
* @param {Boolean} showSplitBill | ||
* @param {Boolean} showSendRequestMoney | ||
* @param {Boolean} hasExcludedIOUEmails | ||
* @param {Function} openPicker | ||
* @param {Function} displayFileInModal | ||
* @returns {Array<object>} | ||
*/ | ||
getReportComposeActions(showSplitBill, showSendRequestMoney, hasExcludedIOUEmails, openPicker, displayFileInModal) { | ||
return [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need to compute and pass everything to this function it does not make any sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved.
...(!hasExcludedIOUEmails | ||
&& Permissions.canUseIOU(this.props.betas) | ||
&& showSplitBill ? [ | ||
{ | ||
icon: Expensicons.Receipt, | ||
text: this.props.translate('iou.splitBill'), | ||
onSelected: () => { | ||
Navigation.navigate( | ||
ROUTES.getIouSplitRoute( | ||
this.props.reportID, | ||
), | ||
); | ||
}, | ||
}, | ||
] : []), | ||
...(!hasExcludedIOUEmails | ||
&& Permissions.canUseIOU(this.props.betas) | ||
&& showSendRequestMoney ? [ | ||
{ | ||
icon: Expensicons.MoneyCircle, | ||
text: this.props.translate('iou.requestMoney'), | ||
onSelected: () => { | ||
Navigation.navigate( | ||
ROUTES.getIouRequestRoute( | ||
this.props.reportID, | ||
), | ||
); | ||
}, | ||
}, | ||
] : []), | ||
...(!hasExcludedIOUEmails && Permissions.canUseIOUSend(this.props.betas) && showSendRequestMoney ? [ | ||
{ | ||
icon: Expensicons.Send, | ||
text: this.props.translate('iou.sendMoney'), | ||
onSelected: () => { | ||
Navigation.navigate( | ||
ROUTES.getIOUSendRoute( | ||
this.props.reportID, | ||
), | ||
); | ||
}, | ||
}, | ||
] : []), | ||
{ | ||
icon: Expensicons.Paperclip, | ||
text: this.props.translate('reportActionCompose.addAttachment'), | ||
onSelected: () => { | ||
openPicker({ | ||
onPicked: (file) => { | ||
displayFileInModal({file}); | ||
}, | ||
}); | ||
}, | ||
}, | ||
]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code is not DRY, we have redundant checks here. Can you refactor this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactoring this might result into nested ternary operators. I was discouraged to use nested ternary operators in previous PRs. Any suggestion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could use simple if/else no need for ternary here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will look something like this. Any suggestion?
const actions = [];
if (!hasExcludedIOUEmails) {
if (Permissions.canUseIOU(this.props.betas)) {
if (showSplitBill) {
actions.push(
{
icon: Expensicons.Receipt,
text: this.props.translate('iou.splitBill'),
onSelected: () => {
Navigation.navigate(
ROUTES.getIouSplitRoute(
this.props.reportID,
),
);
},
},
);
}
if (showSendRequestMoney) {
actions.push({
icon: Expensicons.MoneyCircle,
text: this.props.translate('iou.requestMoney'),
onSelected: () => {
Navigation.navigate(
ROUTES.getIouRequestRoute(
this.props.reportID,
),
);
},
});
}
}
if (Permissions.canUseIOUSend(this.props.betas) && showSendRequestMoney) {
actions.push({
icon: Expensicons.Send,
text: this.props.translate('iou.sendMoney'),
onSelected: () => {
Navigation.navigate(
ROUTES.getIOUSendRoute(
this.props.reportID,
),
);
},
});
}
}
actions.push({
icon: Expensicons.Paperclip,
text: this.props.translate('reportActionCompose.addAttachment'),
onSelected: () => {
openPicker({
onPicked: (file) => {
displayFileInModal({file});
},
});
},
});
return actions;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's just move IOU options computation alone to a new method, leave Add Attachment untouched thanks!
getIOUOptions(reportParticipants) {
const iouOptions = [];
const participants = _.filter(reportParticipants, email => this.props.myPersonalDetails.login !== email).length > 1;
const hasExcludedIOUEmails = lodashIntersection(reportParticipants, CONST.EXPENSIFY_EMAILS).length > 0;
const hasMultipleParticipants = participants.length > 1;
if (hasExcludedIOUEmails || participants.length === 0 || Permissions.canUseIOU(this.props.betas)) {
return iouOptions;
}
if (hasMultipleParticipants) {
// append split
}
else {
if (Permissions.canUseIOUSend(this.props.betas)) {
// append send
}
// append request
}
return iouOptions;
}
cc: @iwiznia
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/pages/iou/IOUModal.js
Outdated
participants={this.props.hasMultipleParticipants | ||
? this.state.participants | ||
: _.filter(this.state.participants, email => this.props.myPersonalDetails.login !== email.login)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be done here, I think it could be moved along the lines here
Lines 110 to 111 in 4c64bec
const participants = lodashGet(props, 'report.participants', []); | |
const participantsWithDetails = _.map(OptionsListUtils.getPersonalDetailsForLogins(participants, props.personalDetails), personalDetails => ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Participants are updated during IOUParicipantsPage step. So, it cannot be moved here. We need to make use of updated participants list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IOUParicipantsPage
will not be used for Room or group flow. So no issues there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check and let me know!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's a good idea. It adds more complication.
@sobitneupane I believe this is well within the scope of this issue. cc @iwiznia |
I have already solved the issue mentioned in this comment while solving this issue as it is part of this issue. It would have been an issue introduced while solving this issue. But while testing I found that the issue I mentioned also occurs. If it is believed to be part of this issue I will solve it here. It was an existing issue. |
Thanks, I would let @iwiznia take the final call! |
Solved this issue as well. I am okay either way. |
I think it's basically the same issue or very closely related, so original amount should apply. If you disagree, please let me know and we can discuss. |
onSelected: () => { | ||
Navigation.navigate( | ||
ROUTES.getIOUSendRoute( | ||
this.props.reportID, | ||
), | ||
); | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given it's only one param per method and line is not too long, I think this is more readable
onSelected: () => { | |
Navigation.navigate( | |
ROUTES.getIOUSendRoute( | |
this.props.reportID, | |
), | |
); | |
}, | |
onSelected: () => Navigation.navigate(ROUTES.getIOUSendRoute(this.props.reportID)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
made the requested change
* @returns {Array<object>} | ||
*/ | ||
getIOUOptions(reportParticipants) { | ||
const iouOptions = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this (see other comments)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
made the requested change
const hasMultipleParticipants = participants.length > 1; | ||
|
||
if (hasExcludedIOUEmails || participants.length === 0 || !Permissions.canUseIOU(this.props.betas)) { | ||
return iouOptions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return iouOptions; | |
return []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
made the requested change
iouOptions.push( | ||
{ | ||
icon: Expensicons.Receipt, | ||
text: this.props.translate('iou.splitBill'), | ||
onSelected: () => { | ||
Navigation.navigate( | ||
ROUTES.getIouSplitRoute( | ||
this.props.reportID, | ||
), | ||
); | ||
}, | ||
}, | ||
); | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Early return here
iouOptions.push( | |
{ | |
icon: Expensicons.Receipt, | |
text: this.props.translate('iou.splitBill'), | |
onSelected: () => { | |
Navigation.navigate( | |
ROUTES.getIouSplitRoute( | |
this.props.reportID, | |
), | |
); | |
}, | |
}, | |
); | |
} else { | |
return [{ | |
icon: Expensicons.Receipt, | |
text: this.props.translate('iou.splitBill'), | |
onSelected: () => Navigation.navigate(ROUTES.getIouSplitRoute(this.props.reportID)), | |
}]; | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
made the requested change
}, | ||
); | ||
} else { | ||
iouOptions.push({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iouOptions.push({ | |
const iouOptions = []; | |
iouOptions.push({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
else statement is removed as it is no longer needed and variable is declared at the top of the function.
onSelected: () => { | ||
Navigation.navigate( | ||
ROUTES.getIouRequestRoute( | ||
this.props.reportID, | ||
), | ||
); | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onSelected: () => { | |
Navigation.navigate( | |
ROUTES.getIouRequestRoute( | |
this.props.reportID, | |
), | |
); | |
}, | |
onSelected: () => Navigation.navigate(ROUTES.getIOUSendRoute(this.props.reportID)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
made the requested change
@Santhosh-Sellavel if everything looks good, please approve the PR. |
myPersonalDetails: { | ||
key: ONYXKEYS.MY_PERSONAL_DETAILS, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prop type is defined for myPersonalDetails
can you add that, thanks!
PR Reviewer Checklist
|
@sobitneupane Example: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Waiting till the comment above is addressed before merging |
Added. |
@iwiznia We are good to go here! |
🚀 Cherry-picked to staging by @sketchydroide in version: 1.1.57-8 🚀
@Expensify/applauseleads please QA this PR and check it off on the deploy checklist if it passes. |
🚀 Deployed to production by @chiragsalian in version: 1.1.57-17 🚀
|
Show Request and Send Money options when there are two participants, Splitbill option when there are more than two participants and no option if there is only one participant
Details
Fixed Issues
$ #8357
Tests
PR Review Checklist
Contributor (PR Author) Checklist
### Fixed Issues
section aboveTests
sectionQA steps
sectiontoggleReport
and notonIconClick
)src/languages/*
filesSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)/** comment above it */
displayName
propertythis
properly so there are no scoping issues (i.e. foronClick={this.submit}
the methodthis.submit
should be bound tothis
in the constructor)this
are necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);
ifthis.submit
is never passed to a component event handler likeonClick
)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)PR Reviewer Checklist
### Fixed Issues
section aboveTests
sectionQA steps
sectiontoggleReport
and notonIconClick
).src/languages/*
filesSTYLE.md
) were followed/** comment above it */
displayName
propertythis
properly so there are no scoping issues (i.e. foronClick={this.submit}
the methodthis.submit
should be bound tothis
in the constructor)this
are necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);
ifthis.submit
is never passed to a component event handler likeonClick
)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)QA Steps
Screenshots
Web
Mobile Web
Desktop
iOS
Android