Expensify / App

Welcome to New Expensify: a complete re-imagination of financial collaboration, centered around chat. Help us build the next generation of Expensify by sharing feedback and contributing to the code.
https://new.expensify.com
MIT License
3.56k stars 2.9k forks source link

Split Bill - Unequal split of the total amount entered on the BNP #26817

Closed lanitochka17 closed 1 year ago

lanitochka17 commented 1 year ago

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Action Performed:

  1. Launch New Expensify app
  2. Tap on FAB button
  3. Select Split Bill
  4. Tap on the currency
  5. Select MMK currency
  6. Enter an amount in the big number pad page
  7. Click on the Next button
  8. Select a couple of attendees from the list
  9. Tap the Next confirmation button

Expected Result:

In the final confirmation screen next to each attendee should be an equal split of the total amount entered on the BNP

Actual Result:

Split Bill is not shared equally when User select MMK currency

Workaround:

Unknown

Platforms:

Which of our officially supported platforms is this issue occurring on?

Version Number: 1.3.63-0

Reproducible in staging?: Y

Reproducible in production?: Y

If this was caught during regression testing, add the test name, ID and link from TestRail:

Email or phone of affected tester (no customers):

Logs: https://stackoverflow.com/c/expensify/questions/4856

Notes/Photos/Videos: Any additional supporting documentation

https://github.com/Expensify/App/assets/78819774/f808b149-5b02-410c-baaf-75030c24fe7a

Expensify/Expensify Issue URL:

Issue reported by: Applause - Internal Team

Slack conversation:

View all open jobs on GitHub

melvin-bot[bot] commented 1 year ago

Triggered auto assignment to @laurenreidexpensify (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details.

melvin-bot[bot] commented 1 year ago

Bug0 Triage Checklist (Main S/O)

alphaboss1104 commented 1 year ago

Proposal

Please re-state the problem that we are trying to solve in this issue.

Split Bill - Unequal split of the total amount entered on the BNP

What is the root cause of that problem?

If we are going to split the MMK 3 to 3 participants or split some money that currency's decimals is 0, currencyUnit is set as 1 and totalInCurrencySubunit is set as 3.

And Ideally amountPerPerson should be set as 0.75 but it is set as 1 because of Math.round().

https://github.com/Expensify/App/blob/1bdc5acc12f982b4f6e37bfadf9060ac3d2d3b3c/src/libs/IOUUtils.js#L15-L29

This is the first root cause.

And then minimumFractionDigits is the second root cause. In the code below if the currency isn't RSD, the minimumFractionDigits is set as undefined. And when minimumFractionDigits is undefined, the actual number of fraction digits used depends on the currency. So we couldn't get the correct value.

https://github.com/Expensify/App/blob/1bdc5acc12f982b4f6e37bfadf9060ac3d2d3b3c/src/libs/CurrencyUtils.js#L127C95-L119-L128

What changes do you think we should make in order to solve the problem?

We should remove the Math.round() in the code here.

      function calculateAmount(numberOfParticipants, total, currency, isDefaultUser = false) {
          const currencyUnit = Math.min(100, CurrencyUtils.getCurrencyUnit(currency));
-         const totalInCurrencySubunit = Math.round((total / 100) * currencyUnit);
+         const totalInCurrencySubunit = (total / 100) * currencyUnit;
          const totalParticipants = numberOfParticipants + 1;
-         const amountPerPerson = Math.round(totalInCurrencySubunit / totalParticipants);
+         const amountPerPerson = totalInCurrencySubunit / totalParticipants;
          let finalAmount = amountPerPerson;
          if (isDefaultUser) {
              const sumAmount = amountPerPerson * totalParticipants;
              const difference = totalInCurrencySubunit - sumAmount;
              finalAmount = totalInCurrencySubunit !== sumAmount ? amountPerPerson + difference : amountPerPerson;
          }
-         return Math.round((finalAmount * 100) / currencyUnit);
+         return (finalAmount * 100) / currencyUnit;
      }

And then also we should change the code here.

    return NumberFormatUtils.format(BaseLocaleListener.getPreferredLocale(), convertedAmount, {
        style: 'currency',
        currency,
-       minimumFractionDigits: currency === 'RSD' ? getCurrencyDecimals(currency) : undefined,
+       minimumFractionDigits: 2,
    });

What alternative solutions did you explore? (Optional)

None.

hungvu193 commented 1 year ago

Dupe of https://github.com/Expensify/App/issues/14205. It was decided to close.

laurenreidexpensify commented 1 year ago

Thanks @hungvu193 am closing