@qrwise/pos-calculations 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +82 -36
- package/dist/index.d.cts +26 -5
- package/dist/index.d.ts +26 -5
- package/dist/index.js +75 -35
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -20,82 +20,128 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
calculateTotals: () => calculateTotals
|
|
23
|
+
calculateTotals: () => calculateTotals,
|
|
24
|
+
clamp: () => clamp,
|
|
25
|
+
format2: () => format2,
|
|
26
|
+
getDiscountBreakdown: () => getDiscountBreakdown,
|
|
27
|
+
isAddVatAfterDiscount: () => isAddVatAfterDiscount,
|
|
28
|
+
isVatExemptDiscount: () => isVatExemptDiscount,
|
|
29
|
+
toMoneyNumber: () => toMoneyNumber
|
|
24
30
|
});
|
|
25
31
|
module.exports = __toCommonJS(index_exports);
|
|
26
32
|
|
|
27
33
|
// src/calculate-totals.ts
|
|
28
|
-
|
|
29
|
-
|
|
34
|
+
var clamp = (n, min = 0, max = Number.POSITIVE_INFINITY) => Math.min(Math.max(n, min), max);
|
|
35
|
+
var toMoneyNumber = (v, fallback = 0) => {
|
|
36
|
+
const n = typeof v === "number" ? v : typeof v === "string" ? Number(v.replace(/,/g, "").trim()) : fallback;
|
|
37
|
+
if (!Number.isFinite(n)) return fallback;
|
|
38
|
+
return n;
|
|
39
|
+
};
|
|
40
|
+
function format2(value) {
|
|
41
|
+
return Number((value || 0).toFixed(2));
|
|
42
|
+
}
|
|
43
|
+
function includesAny(value, keywords) {
|
|
44
|
+
return keywords.some((keyword) => value.includes(keyword));
|
|
45
|
+
}
|
|
46
|
+
function isAddVatAfterDiscount(discountType) {
|
|
47
|
+
const value = String(discountType || "").toLowerCase();
|
|
48
|
+
return includesAny(value, ["solo", "solo parent"]) || includesAny(value, ["national", "athlete", "naac"]) || includesAny(value, ["uniformed", "uniformed personnel", "mov"]);
|
|
30
49
|
}
|
|
31
50
|
function isVatExemptDiscount(discountType) {
|
|
32
|
-
|
|
51
|
+
const value = String(discountType || "").toLowerCase();
|
|
52
|
+
return includesAny(value, ["senior", "sc"]) || includesAny(value, ["pwd", "person with disability"]);
|
|
53
|
+
}
|
|
54
|
+
function getDiscountBreakdown(discountType, discountedAmount) {
|
|
55
|
+
const value = String(discountType || "").toLowerCase();
|
|
56
|
+
return {
|
|
57
|
+
sc: includesAny(value, ["senior", "sc"]) ? discountedAmount : 0,
|
|
58
|
+
pwd: includesAny(value, ["pwd", "person with disability"]) ? discountedAmount : 0,
|
|
59
|
+
solo: includesAny(value, ["solo", "solo parent"]) ? discountedAmount : 0,
|
|
60
|
+
naac: includesAny(value, ["national", "athlete", "naac"]) ? discountedAmount : 0,
|
|
61
|
+
mov: includesAny(value, ["uniformed", "uniformed personnel", "mov"]) ? discountedAmount : 0
|
|
62
|
+
};
|
|
33
63
|
}
|
|
34
64
|
function calculateTotals(input) {
|
|
35
65
|
const {
|
|
36
|
-
discountableTotalAmount,
|
|
37
|
-
nonDiscountableTotalAmount,
|
|
38
|
-
serviceChargeableTotalAmount,
|
|
39
|
-
voucherType,
|
|
66
|
+
discountableTotalAmount = 0,
|
|
67
|
+
nonDiscountableTotalAmount = 0,
|
|
68
|
+
serviceChargeableTotalAmount = 0,
|
|
69
|
+
voucherType = null,
|
|
40
70
|
voucherRate = 0,
|
|
41
|
-
discountType,
|
|
71
|
+
discountType = null,
|
|
42
72
|
discountRate = 0,
|
|
43
|
-
vatRate,
|
|
44
|
-
serviceChargeRate,
|
|
45
|
-
togoCharge,
|
|
73
|
+
vatRate = 12,
|
|
74
|
+
serviceChargeRate = 0,
|
|
75
|
+
togoCharge = 0,
|
|
46
76
|
diningOption = "FOR_HERE"
|
|
47
77
|
} = input;
|
|
48
|
-
const grossAmount =
|
|
78
|
+
const grossAmount = format2(discountableTotalAmount + nonDiscountableTotalAmount);
|
|
49
79
|
let voucherDiscount = 0;
|
|
50
80
|
if (voucherType === "FIXED") {
|
|
51
|
-
voucherDiscount = Math.min(voucherRate, grossAmount);
|
|
81
|
+
voucherDiscount = Math.min(toMoneyNumber(voucherRate), grossAmount);
|
|
52
82
|
}
|
|
53
83
|
if (voucherType === "PERCENTAGE") {
|
|
54
|
-
voucherDiscount = grossAmount * (voucherRate / 100);
|
|
84
|
+
voucherDiscount = grossAmount * (toMoneyNumber(voucherRate) / 100);
|
|
55
85
|
}
|
|
56
|
-
voucherDiscount =
|
|
57
|
-
const subtotalAfterVoucher =
|
|
58
|
-
const vatDivisor = 1 + vatRate / 100;
|
|
59
|
-
let vatNet =
|
|
60
|
-
let vat =
|
|
86
|
+
voucherDiscount = format2(clamp(voucherDiscount, 0, grossAmount));
|
|
87
|
+
const subtotalAfterVoucher = format2(grossAmount - voucherDiscount);
|
|
88
|
+
const vatDivisor = 1 + toMoneyNumber(vatRate, 12) / 100;
|
|
89
|
+
let vatNet = format2(subtotalAfterVoucher / vatDivisor);
|
|
90
|
+
let vat = format2(subtotalAfterVoucher - vatNet);
|
|
61
91
|
let discount = 0;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
92
|
+
const hasDiscount = !!discountType && toMoneyNumber(discountRate) > 0;
|
|
93
|
+
if (hasDiscount) {
|
|
94
|
+
const discountableVatNet = format2(discountableTotalAmount / vatDivisor);
|
|
95
|
+
discount = format2(discountableVatNet * (toMoneyNumber(discountRate) / 100));
|
|
96
|
+
vatNet = format2(vatNet - discount);
|
|
66
97
|
if (isVatExemptDiscount(discountType)) {
|
|
67
98
|
vat = 0;
|
|
68
99
|
}
|
|
100
|
+
if (isAddVatAfterDiscount(discountType)) {
|
|
101
|
+
vat = format2(vatNet * (toMoneyNumber(vatRate, 12) / 100));
|
|
102
|
+
}
|
|
69
103
|
}
|
|
70
104
|
let serviceCharge = 0;
|
|
71
|
-
if (diningOption === "FOR_HERE" && serviceChargeRate > 0) {
|
|
72
|
-
|
|
105
|
+
if (diningOption === "FOR_HERE" && serviceChargeRate > 0 && serviceChargeableTotalAmount > 0) {
|
|
106
|
+
const serviceChargeVatNet = format2(serviceChargeableTotalAmount / vatDivisor);
|
|
107
|
+
serviceCharge = format2(serviceChargeVatNet * (toMoneyNumber(serviceChargeRate) / 100));
|
|
73
108
|
}
|
|
74
|
-
const finalTogoCharge = diningOption === "TO_GO" ? togoCharge : 0;
|
|
75
|
-
const totalAmount =
|
|
109
|
+
const finalTogoCharge = diningOption === "TO_GO" ? toMoneyNumber(togoCharge) : 0;
|
|
110
|
+
const totalAmount = format2(Math.max(0, vatNet + vat + serviceCharge + finalTogoCharge));
|
|
111
|
+
const signedVoucherDiscount = -voucherDiscount;
|
|
112
|
+
const signedDiscount = -discount;
|
|
76
113
|
return {
|
|
77
114
|
grossAmount,
|
|
78
|
-
voucherDiscount:
|
|
115
|
+
voucherDiscount: signedVoucherDiscount,
|
|
79
116
|
subtotalAfterVoucher,
|
|
80
117
|
vatNet,
|
|
81
118
|
vat,
|
|
82
|
-
discount:
|
|
119
|
+
discount: signedDiscount,
|
|
83
120
|
serviceCharge,
|
|
84
121
|
togoCharge: finalTogoCharge,
|
|
85
122
|
totalAmount,
|
|
86
123
|
bir: {
|
|
87
|
-
vatSales: vat > 0 ? vatNet + Math.abs(
|
|
88
|
-
vatExemptSales: vat
|
|
124
|
+
vatSales: vat > 0 ? format2(vatNet + Math.abs(signedDiscount)) : 0,
|
|
125
|
+
vatExemptSales: vat <= 0 ? format2(vatNet + Math.abs(signedDiscount)) : 0,
|
|
89
126
|
vatZeroRatedSales: 0,
|
|
90
127
|
nonTaxableSales: 0,
|
|
91
128
|
vat,
|
|
92
|
-
discount,
|
|
129
|
+
discount: signedDiscount,
|
|
93
130
|
serviceCharge,
|
|
94
|
-
|
|
95
|
-
|
|
131
|
+
togoCharge: finalTogoCharge,
|
|
132
|
+
amountPayable: totalAmount,
|
|
133
|
+
totalSales: vat > 0 ? subtotalAfterVoucher : format2(vatNet + Math.abs(signedDiscount))
|
|
134
|
+
},
|
|
135
|
+
discountBreakdown: getDiscountBreakdown(discountType, signedDiscount)
|
|
96
136
|
};
|
|
97
137
|
}
|
|
98
138
|
// Annotate the CommonJS export names for ESM import in node:
|
|
99
139
|
0 && (module.exports = {
|
|
100
|
-
calculateTotals
|
|
140
|
+
calculateTotals,
|
|
141
|
+
clamp,
|
|
142
|
+
format2,
|
|
143
|
+
getDiscountBreakdown,
|
|
144
|
+
isAddVatAfterDiscount,
|
|
145
|
+
isVatExemptDiscount,
|
|
146
|
+
toMoneyNumber
|
|
101
147
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -4,14 +4,14 @@ type DiscountType = "SENIOR" | "PWD" | "NAAC" | "SOLO" | "MOV";
|
|
|
4
4
|
interface CalculateTotalsInput {
|
|
5
5
|
discountableTotalAmount: number;
|
|
6
6
|
nonDiscountableTotalAmount: number;
|
|
7
|
-
serviceChargeableTotalAmount
|
|
7
|
+
serviceChargeableTotalAmount?: number;
|
|
8
8
|
voucherType?: VoucherType | null;
|
|
9
9
|
voucherRate?: number;
|
|
10
10
|
discountType?: DiscountType | null;
|
|
11
11
|
discountRate?: number;
|
|
12
|
-
vatRate
|
|
13
|
-
serviceChargeRate
|
|
14
|
-
togoCharge
|
|
12
|
+
vatRate?: number;
|
|
13
|
+
serviceChargeRate?: number;
|
|
14
|
+
togoCharge?: number;
|
|
15
15
|
diningOption?: DiningOption;
|
|
16
16
|
}
|
|
17
17
|
interface CalculateTotalsResult {
|
|
@@ -32,10 +32,31 @@ interface CalculateTotalsResult {
|
|
|
32
32
|
vat: number;
|
|
33
33
|
discount: number;
|
|
34
34
|
serviceCharge: number;
|
|
35
|
+
togoCharge: number;
|
|
35
36
|
amountPayable: number;
|
|
37
|
+
totalSales: number;
|
|
38
|
+
};
|
|
39
|
+
discountBreakdown: {
|
|
40
|
+
sc: number;
|
|
41
|
+
pwd: number;
|
|
42
|
+
solo: number;
|
|
43
|
+
naac: number;
|
|
44
|
+
mov: number;
|
|
36
45
|
};
|
|
37
46
|
}
|
|
38
47
|
|
|
48
|
+
declare const clamp: (n: number, min?: number, max?: number) => number;
|
|
49
|
+
declare const toMoneyNumber: (v: unknown, fallback?: number) => number;
|
|
50
|
+
declare function format2(value: number): number;
|
|
51
|
+
declare function isAddVatAfterDiscount(discountType?: string | null): boolean;
|
|
52
|
+
declare function isVatExemptDiscount(discountType?: string | null): boolean;
|
|
53
|
+
declare function getDiscountBreakdown(discountType: string | null | undefined, discountedAmount: number): {
|
|
54
|
+
sc: number;
|
|
55
|
+
pwd: number;
|
|
56
|
+
solo: number;
|
|
57
|
+
naac: number;
|
|
58
|
+
mov: number;
|
|
59
|
+
};
|
|
39
60
|
declare function calculateTotals(input: CalculateTotalsInput): CalculateTotalsResult;
|
|
40
61
|
|
|
41
|
-
export { type CalculateTotalsInput, type CalculateTotalsResult, type DiningOption, type DiscountType, type VoucherType, calculateTotals };
|
|
62
|
+
export { type CalculateTotalsInput, type CalculateTotalsResult, type DiningOption, type DiscountType, type VoucherType, calculateTotals, clamp, format2, getDiscountBreakdown, isAddVatAfterDiscount, isVatExemptDiscount, toMoneyNumber };
|
package/dist/index.d.ts
CHANGED
|
@@ -4,14 +4,14 @@ type DiscountType = "SENIOR" | "PWD" | "NAAC" | "SOLO" | "MOV";
|
|
|
4
4
|
interface CalculateTotalsInput {
|
|
5
5
|
discountableTotalAmount: number;
|
|
6
6
|
nonDiscountableTotalAmount: number;
|
|
7
|
-
serviceChargeableTotalAmount
|
|
7
|
+
serviceChargeableTotalAmount?: number;
|
|
8
8
|
voucherType?: VoucherType | null;
|
|
9
9
|
voucherRate?: number;
|
|
10
10
|
discountType?: DiscountType | null;
|
|
11
11
|
discountRate?: number;
|
|
12
|
-
vatRate
|
|
13
|
-
serviceChargeRate
|
|
14
|
-
togoCharge
|
|
12
|
+
vatRate?: number;
|
|
13
|
+
serviceChargeRate?: number;
|
|
14
|
+
togoCharge?: number;
|
|
15
15
|
diningOption?: DiningOption;
|
|
16
16
|
}
|
|
17
17
|
interface CalculateTotalsResult {
|
|
@@ -32,10 +32,31 @@ interface CalculateTotalsResult {
|
|
|
32
32
|
vat: number;
|
|
33
33
|
discount: number;
|
|
34
34
|
serviceCharge: number;
|
|
35
|
+
togoCharge: number;
|
|
35
36
|
amountPayable: number;
|
|
37
|
+
totalSales: number;
|
|
38
|
+
};
|
|
39
|
+
discountBreakdown: {
|
|
40
|
+
sc: number;
|
|
41
|
+
pwd: number;
|
|
42
|
+
solo: number;
|
|
43
|
+
naac: number;
|
|
44
|
+
mov: number;
|
|
36
45
|
};
|
|
37
46
|
}
|
|
38
47
|
|
|
48
|
+
declare const clamp: (n: number, min?: number, max?: number) => number;
|
|
49
|
+
declare const toMoneyNumber: (v: unknown, fallback?: number) => number;
|
|
50
|
+
declare function format2(value: number): number;
|
|
51
|
+
declare function isAddVatAfterDiscount(discountType?: string | null): boolean;
|
|
52
|
+
declare function isVatExemptDiscount(discountType?: string | null): boolean;
|
|
53
|
+
declare function getDiscountBreakdown(discountType: string | null | undefined, discountedAmount: number): {
|
|
54
|
+
sc: number;
|
|
55
|
+
pwd: number;
|
|
56
|
+
solo: number;
|
|
57
|
+
naac: number;
|
|
58
|
+
mov: number;
|
|
59
|
+
};
|
|
39
60
|
declare function calculateTotals(input: CalculateTotalsInput): CalculateTotalsResult;
|
|
40
61
|
|
|
41
|
-
export { type CalculateTotalsInput, type CalculateTotalsResult, type DiningOption, type DiscountType, type VoucherType, calculateTotals };
|
|
62
|
+
export { type CalculateTotalsInput, type CalculateTotalsResult, type DiningOption, type DiscountType, type VoucherType, calculateTotals, clamp, format2, getDiscountBreakdown, isAddVatAfterDiscount, isVatExemptDiscount, toMoneyNumber };
|
package/dist/index.js
CHANGED
|
@@ -1,74 +1,114 @@
|
|
|
1
1
|
// src/calculate-totals.ts
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
var clamp = (n, min = 0, max = Number.POSITIVE_INFINITY) => Math.min(Math.max(n, min), max);
|
|
3
|
+
var toMoneyNumber = (v, fallback = 0) => {
|
|
4
|
+
const n = typeof v === "number" ? v : typeof v === "string" ? Number(v.replace(/,/g, "").trim()) : fallback;
|
|
5
|
+
if (!Number.isFinite(n)) return fallback;
|
|
6
|
+
return n;
|
|
7
|
+
};
|
|
8
|
+
function format2(value) {
|
|
9
|
+
return Number((value || 0).toFixed(2));
|
|
10
|
+
}
|
|
11
|
+
function includesAny(value, keywords) {
|
|
12
|
+
return keywords.some((keyword) => value.includes(keyword));
|
|
13
|
+
}
|
|
14
|
+
function isAddVatAfterDiscount(discountType) {
|
|
15
|
+
const value = String(discountType || "").toLowerCase();
|
|
16
|
+
return includesAny(value, ["solo", "solo parent"]) || includesAny(value, ["national", "athlete", "naac"]) || includesAny(value, ["uniformed", "uniformed personnel", "mov"]);
|
|
4
17
|
}
|
|
5
18
|
function isVatExemptDiscount(discountType) {
|
|
6
|
-
|
|
19
|
+
const value = String(discountType || "").toLowerCase();
|
|
20
|
+
return includesAny(value, ["senior", "sc"]) || includesAny(value, ["pwd", "person with disability"]);
|
|
21
|
+
}
|
|
22
|
+
function getDiscountBreakdown(discountType, discountedAmount) {
|
|
23
|
+
const value = String(discountType || "").toLowerCase();
|
|
24
|
+
return {
|
|
25
|
+
sc: includesAny(value, ["senior", "sc"]) ? discountedAmount : 0,
|
|
26
|
+
pwd: includesAny(value, ["pwd", "person with disability"]) ? discountedAmount : 0,
|
|
27
|
+
solo: includesAny(value, ["solo", "solo parent"]) ? discountedAmount : 0,
|
|
28
|
+
naac: includesAny(value, ["national", "athlete", "naac"]) ? discountedAmount : 0,
|
|
29
|
+
mov: includesAny(value, ["uniformed", "uniformed personnel", "mov"]) ? discountedAmount : 0
|
|
30
|
+
};
|
|
7
31
|
}
|
|
8
32
|
function calculateTotals(input) {
|
|
9
33
|
const {
|
|
10
|
-
discountableTotalAmount,
|
|
11
|
-
nonDiscountableTotalAmount,
|
|
12
|
-
serviceChargeableTotalAmount,
|
|
13
|
-
voucherType,
|
|
34
|
+
discountableTotalAmount = 0,
|
|
35
|
+
nonDiscountableTotalAmount = 0,
|
|
36
|
+
serviceChargeableTotalAmount = 0,
|
|
37
|
+
voucherType = null,
|
|
14
38
|
voucherRate = 0,
|
|
15
|
-
discountType,
|
|
39
|
+
discountType = null,
|
|
16
40
|
discountRate = 0,
|
|
17
|
-
vatRate,
|
|
18
|
-
serviceChargeRate,
|
|
19
|
-
togoCharge,
|
|
41
|
+
vatRate = 12,
|
|
42
|
+
serviceChargeRate = 0,
|
|
43
|
+
togoCharge = 0,
|
|
20
44
|
diningOption = "FOR_HERE"
|
|
21
45
|
} = input;
|
|
22
|
-
const grossAmount =
|
|
46
|
+
const grossAmount = format2(discountableTotalAmount + nonDiscountableTotalAmount);
|
|
23
47
|
let voucherDiscount = 0;
|
|
24
48
|
if (voucherType === "FIXED") {
|
|
25
|
-
voucherDiscount = Math.min(voucherRate, grossAmount);
|
|
49
|
+
voucherDiscount = Math.min(toMoneyNumber(voucherRate), grossAmount);
|
|
26
50
|
}
|
|
27
51
|
if (voucherType === "PERCENTAGE") {
|
|
28
|
-
voucherDiscount = grossAmount * (voucherRate / 100);
|
|
52
|
+
voucherDiscount = grossAmount * (toMoneyNumber(voucherRate) / 100);
|
|
29
53
|
}
|
|
30
|
-
voucherDiscount =
|
|
31
|
-
const subtotalAfterVoucher =
|
|
32
|
-
const vatDivisor = 1 + vatRate / 100;
|
|
33
|
-
let vatNet =
|
|
34
|
-
let vat =
|
|
54
|
+
voucherDiscount = format2(clamp(voucherDiscount, 0, grossAmount));
|
|
55
|
+
const subtotalAfterVoucher = format2(grossAmount - voucherDiscount);
|
|
56
|
+
const vatDivisor = 1 + toMoneyNumber(vatRate, 12) / 100;
|
|
57
|
+
let vatNet = format2(subtotalAfterVoucher / vatDivisor);
|
|
58
|
+
let vat = format2(subtotalAfterVoucher - vatNet);
|
|
35
59
|
let discount = 0;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
60
|
+
const hasDiscount = !!discountType && toMoneyNumber(discountRate) > 0;
|
|
61
|
+
if (hasDiscount) {
|
|
62
|
+
const discountableVatNet = format2(discountableTotalAmount / vatDivisor);
|
|
63
|
+
discount = format2(discountableVatNet * (toMoneyNumber(discountRate) / 100));
|
|
64
|
+
vatNet = format2(vatNet - discount);
|
|
40
65
|
if (isVatExemptDiscount(discountType)) {
|
|
41
66
|
vat = 0;
|
|
42
67
|
}
|
|
68
|
+
if (isAddVatAfterDiscount(discountType)) {
|
|
69
|
+
vat = format2(vatNet * (toMoneyNumber(vatRate, 12) / 100));
|
|
70
|
+
}
|
|
43
71
|
}
|
|
44
72
|
let serviceCharge = 0;
|
|
45
|
-
if (diningOption === "FOR_HERE" && serviceChargeRate > 0) {
|
|
46
|
-
|
|
73
|
+
if (diningOption === "FOR_HERE" && serviceChargeRate > 0 && serviceChargeableTotalAmount > 0) {
|
|
74
|
+
const serviceChargeVatNet = format2(serviceChargeableTotalAmount / vatDivisor);
|
|
75
|
+
serviceCharge = format2(serviceChargeVatNet * (toMoneyNumber(serviceChargeRate) / 100));
|
|
47
76
|
}
|
|
48
|
-
const finalTogoCharge = diningOption === "TO_GO" ? togoCharge : 0;
|
|
49
|
-
const totalAmount =
|
|
77
|
+
const finalTogoCharge = diningOption === "TO_GO" ? toMoneyNumber(togoCharge) : 0;
|
|
78
|
+
const totalAmount = format2(Math.max(0, vatNet + vat + serviceCharge + finalTogoCharge));
|
|
79
|
+
const signedVoucherDiscount = -voucherDiscount;
|
|
80
|
+
const signedDiscount = -discount;
|
|
50
81
|
return {
|
|
51
82
|
grossAmount,
|
|
52
|
-
voucherDiscount:
|
|
83
|
+
voucherDiscount: signedVoucherDiscount,
|
|
53
84
|
subtotalAfterVoucher,
|
|
54
85
|
vatNet,
|
|
55
86
|
vat,
|
|
56
|
-
discount:
|
|
87
|
+
discount: signedDiscount,
|
|
57
88
|
serviceCharge,
|
|
58
89
|
togoCharge: finalTogoCharge,
|
|
59
90
|
totalAmount,
|
|
60
91
|
bir: {
|
|
61
|
-
vatSales: vat > 0 ? vatNet + Math.abs(
|
|
62
|
-
vatExemptSales: vat
|
|
92
|
+
vatSales: vat > 0 ? format2(vatNet + Math.abs(signedDiscount)) : 0,
|
|
93
|
+
vatExemptSales: vat <= 0 ? format2(vatNet + Math.abs(signedDiscount)) : 0,
|
|
63
94
|
vatZeroRatedSales: 0,
|
|
64
95
|
nonTaxableSales: 0,
|
|
65
96
|
vat,
|
|
66
|
-
discount,
|
|
97
|
+
discount: signedDiscount,
|
|
67
98
|
serviceCharge,
|
|
68
|
-
|
|
69
|
-
|
|
99
|
+
togoCharge: finalTogoCharge,
|
|
100
|
+
amountPayable: totalAmount,
|
|
101
|
+
totalSales: vat > 0 ? subtotalAfterVoucher : format2(vatNet + Math.abs(signedDiscount))
|
|
102
|
+
},
|
|
103
|
+
discountBreakdown: getDiscountBreakdown(discountType, signedDiscount)
|
|
70
104
|
};
|
|
71
105
|
}
|
|
72
106
|
export {
|
|
73
|
-
calculateTotals
|
|
107
|
+
calculateTotals,
|
|
108
|
+
clamp,
|
|
109
|
+
format2,
|
|
110
|
+
getDiscountBreakdown,
|
|
111
|
+
isAddVatAfterDiscount,
|
|
112
|
+
isVatExemptDiscount,
|
|
113
|
+
toMoneyNumber
|
|
74
114
|
};
|