Using Half-Round-Even rounding in the bill amounts as this is what python round uses.

When the bill amounts were Odd number + .5, payment could not be received as javascript rounded it up, but python rounded it down.
We are now using the python rounding (Half Round Even / Banker's Rounding) in the bill service.
This commit is contained in:
Amritanshu Agrawal 2021-03-20 08:05:50 +05:30
parent 0775d12271
commit 669821a643
2 changed files with 21 additions and 8 deletions

View File

@ -1,7 +1,6 @@
import { SelectionModel } from '@angular/cdk/collections';
import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { round } from 'mathjs';
import { BehaviorSubject, throwError } from 'rxjs';
import { Observable } from 'rxjs/internal/Observable';
import { tap } from 'rxjs/operators';
@ -14,9 +13,9 @@ import { SaleCategory } from '../core/sale-category';
import { Table } from '../core/table';
import { ToasterService } from '../core/toaster.service';
import { ModifierCategoryService } from '../modifier-categories/modifier-category.service';
import { MathService } from '../shared/math.service';
import { Bill } from './bills/bill';
import { BillSelectionItem } from './bills/bill-selection-item';
import { Inventory } from './bills/inventory';
import { Kot } from './bills/kot';
import { VoucherType } from './bills/voucher-type';
@ -39,6 +38,7 @@ export class BillService {
constructor(
private dialog: MatDialog,
private toaster: ToasterService,
private math: MathService,
private ser: VoucherService,
private modifierCategoryService: ModifierCategoryService,
) {
@ -75,7 +75,10 @@ export class BillService {
productId: i.product.id,
isHappyHour: i.isHappyHour,
isPrinted: !!k.id,
info: `${i.product.name} @ ${i.price} - ${round(i.discount * 100, 2)}%`,
info: `${i.product.name} @ ${i.price} - ${this.math.halfRoundEven(
i.discount * 100,
2,
)}%`,
quantity: i.quantity,
modifiers: i.modifiers,
}),
@ -284,7 +287,7 @@ export class BillService {
updateAmounts() {
this.netAmount.next(
round(
this.math.halfRoundEven(
this.bill.kots.reduce(
(t, k) =>
k.inventories.reduce((a, c) => a + (c.isHappyHour ? 0 : c.price) * c.quantity, 0) + t,
@ -293,7 +296,7 @@ export class BillService {
),
);
this.discountAmount.next(
round(
this.math.halfRoundEven(
this.bill.kots.reduce(
(t, k) =>
k.inventories.reduce(
@ -305,7 +308,7 @@ export class BillService {
),
);
this.taxAmount.next(
round(
this.math.halfRoundEven(
this.bill.kots.reduce(
(t, k) =>
k.inventories.reduce(
@ -318,7 +321,7 @@ export class BillService {
),
);
this.amountBs.next(
round(
this.math.halfRoundEven(
this.bill.kots.reduce(
(t, k) =>
k.inventories.reduce(

View File

@ -5,7 +5,6 @@ import { evaluate, round } from 'mathjs';
providedIn: 'root',
})
export class MathService {
// eslint-disable-next-line class-methods-use-this
parseAmount(amount: string = '', rounding: number = 2): number {
const cleaned = `${amount}`.replace(new RegExp('(₹[s]*)|(,)|(s)', 'g'), '');
if (cleaned === '') {
@ -13,4 +12,15 @@ export class MathService {
}
return round(evaluate(cleaned), rounding);
}
halfRoundEven(x: number, n = 0): number {
const fraction = Math.round(x * Math.pow(10, n + 8)) % Math.pow(10, 8);
if (fraction > 50000000 - 1 && fraction < 50000000 + 1) {
// To compensate for floating point rounding errors
const floor = Math.floor(x * Math.pow(10, n));
return floor % 2 === 0 ? floor / Math.pow(10, n) : (floor + 1) / Math.pow(10, n);
} else {
return round(x, n);
}
}
}