-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Use transaction distanceUnit to prevent retroactive changes #50001
Conversation
I created this issue to do the migration separately to keep this PR focused [$250] Migrate IOURequestStepDistanceRate to useOnyx |
@MarioExpensify Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
src/languages/en.ts
Outdated
@@ -1010,7 +1009,7 @@ const translations = { | |||
changed: 'changed', | |||
removed: 'removed', | |||
transactionPending: 'Transaction pending.', | |||
chooseARate: ({unit}: ReimbursementRateParams) => `Select a workspace reimbursement rate per ${unit}`, | |||
chooseARate: 'Select a workspace reimbursement rate per mile or kilometer', |
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.
This works better when the selected rate is in a different unit than the current policy distance unit. I think it works fine when the unit is all the same too.
@neil-marcellini I believe the distance value should get corrected |
const unit = DistanceRequestUtils.getDistanceUnit(transaction, mileageRate); | ||
const {rate} = mileageRate ?? {}; |
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 have two sources of truth mileageRate.unit
and unit
which could be confusing and error-prone. Can we have the returned mileageRate
already have the correct unit. i.e. write a function DistanceRequestUtils.getRate
and in that function pass both the policy and the transaction and set the unit
accordingly.
Also I think we can remove the isCustomUnitRateIDForP2P
, getRateForP2P
and getCustomUnitRateID
(not sure about this one) functions or at least not export them. The getRate
function should be enough
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.
That's a pretty good idea, thanks. I'll work on it.
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 ended up adding two new util functions for getting the rate of existing transactions and then getting the distance unit for use when updating a transaction.
I left one use of these other utils you recommended removing, because making the current code work with the new utils would require creating a temporary transaction, setting the customUnitRateID from the transaction changes into it, then using one util for the rate and another for the unit. It's just as messy as the existing code. Not to mention that I would also need to change a lot of the OnyxEntryOrInput types to work with the OnyxEntry types. So I'm going to leave that as is.
App/src/libs/TransactionUtils/index.ts
Lines 807 to 809 in 7982c26
const mileageRate = isCustomUnitRateIDForP2P(transaction) | |
? DistanceRequestUtils.getRateForP2P(policyCurrency) | |
: mileageRates?.[customUnitRateID] ?? DistanceRequestUtils.getDefaultMileageRate(policy); |
Please let me know what you think in your next review.
Oh shoot, you're totally right! I can't believe I missed that, thanks for pointing it out. When the rate changes the distance unit, the distance should be converted into the new unit. I'll put this back to a draft while I work on that backend fix. |
@carlosmiceli Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
Hey @neil-marcellini, everything looks pretty good with the PR. Waiting for all tests to wrap, just a question regarding the ESLint issues (withOnyx deprecated), should we move forward and let this to be fixed by another PR or should we fix in this PR? |
Yeah I have a separate issue for that here [$250] Migrate MoneyRequestConfirmationList to useOnyx. Merging! |
@neil-marcellini looks like this was merged without a test passing. Please add a note explaining why this was done and remove the |
See comment above |
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to staging by https://github.com/neil-marcellini in version: 9.0.51-1 🚀
|
@neil-marcellini @MarioExpensify Can we use Expensifail account for BETA enable tests and Gmail for non-Beta? |
I'm not 100% sure on that, @neil-marcellini do you know if that would be ok? |
🚀 Deployed to production by https://github.com/yuwenmemon in version: 9.0.51-4 🚀
|
🚀 Deployed to production by https://github.com/yuwenmemon in version: 9.0.51-4 🚀
|
@@ -202,14 +199,7 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals | |||
let amountDescription = `${translate('iou.amount')}`; | |||
|
|||
const hasRoute = TransactionUtils.hasRoute(transactionBackup ?? transaction, isDistanceRequest); | |||
const rateID = TransactionUtils.getRateID(transaction) ?? '-1'; | |||
|
|||
const currency = transactionCurrency ?? CONST.CURRENCY.USD; |
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.
Seems like this change re-introduced a bug we fixed in #50142.
Any objections to reverting to using this line instead of currency
from DistanceRequestUtils.getRate({transaction, policy})
?
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.
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 think we need to move that logic to DistanceRequestUtils.getRate
.
Is there any case where we don't want to use the transaction currency and instead use the rate's currency? I think there is only one case, that is if we change the rate to a rate that uses a diff currency (same with unit useTransactionDistanceUnit
)
Do you know why the currency is displayed correctly on the rate change page?
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 you know why the currency is displayed correctly on the rate change page?
We display the transaction's currency for the selected rate:
const rateForDisplay = DistanceRequestUtils.getRateForDisplay(unit, rate.rate, isSelected ? transactionCurrency : rate.currency, translate, toLocaleDigit); |
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 think we need to move that logic to
DistanceRequestUtils.getRate
Moving it into DistanceRequestUtils.getRate
will complicate the function with an extra parameter and an extra if-else check. If you think it's worth it, I'll add a useTransactionCurrency
param.
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.
Using transactionCurrency
directly is fine. Having too many sources of truth is confusing and will always lead to such bugs. We probably need to cleanup this at a later time (or at least centralize it)
@neil-marcellini should we reopen this as it caused a regression? |
@MarioExpensify Can you please link to the regression? |
const conversionFactor = existingDistanceUnit === CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES ? CONST.CUSTOM_UNITS.MILES_TO_KILOMETERS : CONST.CUSTOM_UNITS.KILOMETERS_TO_MILES; | ||
const distance = NumberUtils.roundToTwoDecimalPlaces((transaction?.comment?.customUnit?.quantity ?? 0) * conversionFactor); | ||
lodashSet(updatedTransaction, 'comment.customUnit.quantity', distance); | ||
lodashSet(updatedTransaction, 'pendingFields.waypoints', CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); |
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.
Coming from #51285 {BZ checklist}, setting pending action on waypoint caused the map preview to be blank when selecting distance rate with different unit. There more to RC see detailed Analysis in this Proposal #51285 (comment)
Details
Fixed Issues
#43588
PROPOSAL: N/A
Tests
Precondition:
Original bug:
1001Record241002081325.mov
Test without the beta:
no-beta.mov
Test updating rate updates distanceUnit and converts distance
2024-10-09_15-13-02.mp4
Note: There's an existing bug on main where the map doesn't load and the modified expense action doesn't show as the most recent one. Here's proof it fails on main too
BugOnMain2024-10-09_15-23-28.mp4
Tracked expense
Note: The rate currency not matching the amount will be fixed separately here, we only care that the unit isn't updated retroactively
2024-10-04_08-21-16.mp4
Distance split
2024-10-04_08-24-57.mp4
Optimistic distance unit
2024-10-16_11-25-35.mp4
I also updates some of the allowed write counts where I found issues during testing. I haven't added any extra writes with these PRs.
Offline tests
N/A optimistic data is tested above
QA Steps
Same a tests
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)Design
label and/or tagged@Expensify/design
so the design team can review the changes.ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
See above. I only tested on Chrome since changes should be platform independent and C+ will test all platforms.
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
MacOS: Desktop