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:
parent
0775d12271
commit
669821a643
@ -1,7 +1,6 @@
|
|||||||
import { SelectionModel } from '@angular/cdk/collections';
|
import { SelectionModel } from '@angular/cdk/collections';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { round } from 'mathjs';
|
|
||||||
import { BehaviorSubject, throwError } from 'rxjs';
|
import { BehaviorSubject, throwError } from 'rxjs';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { tap } from 'rxjs/operators';
|
import { tap } from 'rxjs/operators';
|
||||||
@ -14,9 +13,9 @@ import { SaleCategory } from '../core/sale-category';
|
|||||||
import { Table } from '../core/table';
|
import { Table } from '../core/table';
|
||||||
import { ToasterService } from '../core/toaster.service';
|
import { ToasterService } from '../core/toaster.service';
|
||||||
import { ModifierCategoryService } from '../modifier-categories/modifier-category.service';
|
import { ModifierCategoryService } from '../modifier-categories/modifier-category.service';
|
||||||
|
import { MathService } from '../shared/math.service';
|
||||||
|
|
||||||
import { Bill } from './bills/bill';
|
import { Bill } from './bills/bill';
|
||||||
import { BillSelectionItem } from './bills/bill-selection-item';
|
|
||||||
import { Inventory } from './bills/inventory';
|
import { Inventory } from './bills/inventory';
|
||||||
import { Kot } from './bills/kot';
|
import { Kot } from './bills/kot';
|
||||||
import { VoucherType } from './bills/voucher-type';
|
import { VoucherType } from './bills/voucher-type';
|
||||||
@ -39,6 +38,7 @@ export class BillService {
|
|||||||
constructor(
|
constructor(
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
|
private math: MathService,
|
||||||
private ser: VoucherService,
|
private ser: VoucherService,
|
||||||
private modifierCategoryService: ModifierCategoryService,
|
private modifierCategoryService: ModifierCategoryService,
|
||||||
) {
|
) {
|
||||||
@ -75,7 +75,10 @@ export class BillService {
|
|||||||
productId: i.product.id,
|
productId: i.product.id,
|
||||||
isHappyHour: i.isHappyHour,
|
isHappyHour: i.isHappyHour,
|
||||||
isPrinted: !!k.id,
|
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,
|
quantity: i.quantity,
|
||||||
modifiers: i.modifiers,
|
modifiers: i.modifiers,
|
||||||
}),
|
}),
|
||||||
@ -284,7 +287,7 @@ export class BillService {
|
|||||||
|
|
||||||
updateAmounts() {
|
updateAmounts() {
|
||||||
this.netAmount.next(
|
this.netAmount.next(
|
||||||
round(
|
this.math.halfRoundEven(
|
||||||
this.bill.kots.reduce(
|
this.bill.kots.reduce(
|
||||||
(t, k) =>
|
(t, k) =>
|
||||||
k.inventories.reduce((a, c) => a + (c.isHappyHour ? 0 : c.price) * c.quantity, 0) + t,
|
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(
|
this.discountAmount.next(
|
||||||
round(
|
this.math.halfRoundEven(
|
||||||
this.bill.kots.reduce(
|
this.bill.kots.reduce(
|
||||||
(t, k) =>
|
(t, k) =>
|
||||||
k.inventories.reduce(
|
k.inventories.reduce(
|
||||||
@ -305,7 +308,7 @@ export class BillService {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
this.taxAmount.next(
|
this.taxAmount.next(
|
||||||
round(
|
this.math.halfRoundEven(
|
||||||
this.bill.kots.reduce(
|
this.bill.kots.reduce(
|
||||||
(t, k) =>
|
(t, k) =>
|
||||||
k.inventories.reduce(
|
k.inventories.reduce(
|
||||||
@ -318,7 +321,7 @@ export class BillService {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
this.amountBs.next(
|
this.amountBs.next(
|
||||||
round(
|
this.math.halfRoundEven(
|
||||||
this.bill.kots.reduce(
|
this.bill.kots.reduce(
|
||||||
(t, k) =>
|
(t, k) =>
|
||||||
k.inventories.reduce(
|
k.inventories.reduce(
|
||||||
|
@ -5,7 +5,6 @@ import { evaluate, round } from 'mathjs';
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class MathService {
|
export class MathService {
|
||||||
// eslint-disable-next-line class-methods-use-this
|
|
||||||
parseAmount(amount: string = '', rounding: number = 2): number {
|
parseAmount(amount: string = '', rounding: number = 2): number {
|
||||||
const cleaned = `${amount}`.replace(new RegExp('(₹[s]*)|(,)|(s)', 'g'), '');
|
const cleaned = `${amount}`.replace(new RegExp('(₹[s]*)|(,)|(s)', 'g'), '');
|
||||||
if (cleaned === '') {
|
if (cleaned === '') {
|
||||||
@ -13,4 +12,15 @@ export class MathService {
|
|||||||
}
|
}
|
||||||
return round(evaluate(cleaned), rounding);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user