@qrwise/pos-calculations 0.0.6 → 0.0.7

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 CHANGED
@@ -72,67 +72,76 @@ function calculateTotals(input) {
72
72
  discountRate = 0,
73
73
  vatRate = 12,
74
74
  serviceChargeRate = 0,
75
- togoCharge = 0,
76
- diningOption = "FOR_HERE"
75
+ togoCharge = 0
77
76
  } = input;
78
- const grossAmount = format2(discountableTotalAmount + nonDiscountableTotalAmount);
79
- let voucherDiscount = 0;
77
+ const totalOrderAmount = format2(discountableTotalAmount + nonDiscountableTotalAmount);
78
+ let voucherDiscounted = 0;
80
79
  if (voucherType === "FIXED") {
81
- voucherDiscount = Math.min(toMoneyNumber(voucherRate), grossAmount);
80
+ voucherDiscounted = -Math.min(toMoneyNumber(voucherRate), totalOrderAmount);
82
81
  }
83
82
  if (voucherType === "PERCENTAGE") {
84
- voucherDiscount = grossAmount * (toMoneyNumber(voucherRate) / 100);
83
+ voucherDiscounted = -(totalOrderAmount * (toMoneyNumber(voucherRate) / 100));
85
84
  }
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);
91
- let discount = 0;
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);
97
- if (isVatExemptDiscount(discountType)) {
98
- vat = 0;
99
- }
100
- if (isAddVatAfterDiscount(discountType)) {
101
- vat = format2(vatNet * (toMoneyNumber(vatRate, 12) / 100));
85
+ const subtotal = totalOrderAmount + voucherDiscounted;
86
+ const voucherVatNet = Number((totalOrderAmount / vatRate).toFixed(2));
87
+ const voucherVat = Number((voucherVatNet * 0.12).toFixed(2));
88
+ let vatNet = Number((subtotal / vatRate).toFixed(2));
89
+ let vat = Number((vatNet * 0.12).toFixed(2));
90
+ const isSpecial = discountRate > 0;
91
+ const isAddVat = isAddVatAfterDiscount(discountType);
92
+ const discounted = Number((discountRate * -vatNet).toFixed(2));
93
+ if (isSpecial) {
94
+ vatNet = Number((vatNet + discounted).toFixed(2));
95
+ if (!isAddVat) {
96
+ vat = -vat;
102
97
  }
103
98
  }
104
99
  let serviceCharge = 0;
105
- if (diningOption === "FOR_HERE" && serviceChargeRate > 0 && serviceChargeableTotalAmount > 0) {
106
- const serviceChargeVatNet = format2(serviceChargeableTotalAmount / vatDivisor);
107
- serviceCharge = format2(serviceChargeVatNet * (toMoneyNumber(serviceChargeRate) / 100));
100
+ if (serviceChargeRate > 0 && serviceChargeableTotalAmount > 0) {
101
+ const scRate = serviceChargeRate / 100;
102
+ if (isSpecial) {
103
+ serviceCharge = Number(((vatNet + Math.abs(discounted)) * scRate).toFixed(2));
104
+ } else {
105
+ serviceCharge = Number((vatNet * scRate).toFixed(2));
106
+ }
108
107
  }
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;
108
+ let totalAmount = vatNet + vat + serviceCharge + togoCharge;
109
+ if (isSpecial && !isAddVat) {
110
+ totalAmount -= vat;
111
+ }
112
+ if (totalAmount < 0) totalAmount = 0;
113
113
  return {
114
- grossAmount,
115
- voucherDiscount: signedVoucherDiscount,
116
- subtotalAfterVoucher,
117
- vatNet,
114
+ gross: subtotal + Math.abs(voucherDiscounted),
115
+ hasVoucher: voucherRate > 0,
116
+ voucher: {
117
+ discount: voucherDiscounted,
118
+ net: subtotal,
119
+ vatNet: voucherVatNet,
120
+ vat: voucherVat,
121
+ forBirDiscount: -(voucherType === "FIXED" ? voucherVatNet - Number(voucherRate.toFixed(2)) : voucherVatNet * Number(voucherRate.toFixed(2)))
122
+ },
123
+ hasDiscount: discountRate > 0,
124
+ discount: {
125
+ discount: discounted,
126
+ net: vatNet
127
+ },
128
+ netOfVat: vatNet + Math.abs(discounted),
118
129
  vat,
119
- discount: signedDiscount,
120
130
  serviceCharge,
121
- togoCharge: finalTogoCharge,
131
+ togoCharge,
122
132
  totalAmount,
123
133
  bir: {
124
- vatSales: vat > 0 ? format2(vatNet + Math.abs(signedDiscount)) : 0,
125
- vatExemptSales: vat <= 0 ? format2(vatNet + Math.abs(signedDiscount)) : 0,
134
+ vatSales: vat > 0 ? vatNet + Math.abs(discounted) : 0,
135
+ vatExemptSales: vat > 0 ? 0 : vatNet + Math.abs(discounted),
126
136
  vatZeroRatedSales: 0,
127
137
  nonTaxableSales: 0,
128
138
  vat,
129
- discount: signedDiscount,
139
+ totalSales: vat > 0 ? subtotal : vatNet + Math.abs(discounted),
140
+ discount: discounted,
130
141
  serviceCharge,
131
- togoCharge: finalTogoCharge,
132
- amountPayable: totalAmount,
133
- totalSales: vat > 0 ? subtotalAfterVoucher : format2(vatNet + Math.abs(signedDiscount))
134
- },
135
- discountBreakdown: getDiscountBreakdown(discountType, signedDiscount)
142
+ togoCharge,
143
+ amountPayable: totalAmount
144
+ }
136
145
  };
137
146
  }
138
147
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.d.cts CHANGED
@@ -12,15 +12,24 @@ interface CalculateTotalsInput {
12
12
  vatRate?: number;
13
13
  serviceChargeRate?: number;
14
14
  togoCharge?: number;
15
- diningOption?: DiningOption;
16
15
  }
17
16
  interface CalculateTotalsResult {
18
- grossAmount: number;
19
- voucherDiscount: number;
20
- subtotalAfterVoucher: number;
21
- vatNet: number;
17
+ gross: number;
18
+ hasVoucher: boolean;
19
+ voucher: {
20
+ discount: number;
21
+ net: number;
22
+ vatNet: number;
23
+ vat: number;
24
+ forBirDiscount: number;
25
+ };
26
+ hasDiscount: boolean;
27
+ discount: {
28
+ discount: number;
29
+ net: number;
30
+ };
31
+ netOfVat: number;
22
32
  vat: number;
23
- discount: number;
24
33
  serviceCharge: number;
25
34
  togoCharge: number;
26
35
  totalAmount: number;
@@ -30,18 +39,11 @@ interface CalculateTotalsResult {
30
39
  vatZeroRatedSales: number;
31
40
  nonTaxableSales: number;
32
41
  vat: number;
42
+ totalSales: number;
33
43
  discount: number;
34
44
  serviceCharge: number;
35
45
  togoCharge: number;
36
46
  amountPayable: number;
37
- totalSales: number;
38
- };
39
- discountBreakdown: {
40
- sc: number;
41
- pwd: number;
42
- solo: number;
43
- naac: number;
44
- mov: number;
45
47
  };
46
48
  }
47
49
 
package/dist/index.d.ts CHANGED
@@ -12,15 +12,24 @@ interface CalculateTotalsInput {
12
12
  vatRate?: number;
13
13
  serviceChargeRate?: number;
14
14
  togoCharge?: number;
15
- diningOption?: DiningOption;
16
15
  }
17
16
  interface CalculateTotalsResult {
18
- grossAmount: number;
19
- voucherDiscount: number;
20
- subtotalAfterVoucher: number;
21
- vatNet: number;
17
+ gross: number;
18
+ hasVoucher: boolean;
19
+ voucher: {
20
+ discount: number;
21
+ net: number;
22
+ vatNet: number;
23
+ vat: number;
24
+ forBirDiscount: number;
25
+ };
26
+ hasDiscount: boolean;
27
+ discount: {
28
+ discount: number;
29
+ net: number;
30
+ };
31
+ netOfVat: number;
22
32
  vat: number;
23
- discount: number;
24
33
  serviceCharge: number;
25
34
  togoCharge: number;
26
35
  totalAmount: number;
@@ -30,18 +39,11 @@ interface CalculateTotalsResult {
30
39
  vatZeroRatedSales: number;
31
40
  nonTaxableSales: number;
32
41
  vat: number;
42
+ totalSales: number;
33
43
  discount: number;
34
44
  serviceCharge: number;
35
45
  togoCharge: number;
36
46
  amountPayable: number;
37
- totalSales: number;
38
- };
39
- discountBreakdown: {
40
- sc: number;
41
- pwd: number;
42
- solo: number;
43
- naac: number;
44
- mov: number;
45
47
  };
46
48
  }
47
49
 
package/dist/index.js CHANGED
@@ -40,67 +40,76 @@ function calculateTotals(input) {
40
40
  discountRate = 0,
41
41
  vatRate = 12,
42
42
  serviceChargeRate = 0,
43
- togoCharge = 0,
44
- diningOption = "FOR_HERE"
43
+ togoCharge = 0
45
44
  } = input;
46
- const grossAmount = format2(discountableTotalAmount + nonDiscountableTotalAmount);
47
- let voucherDiscount = 0;
45
+ const totalOrderAmount = format2(discountableTotalAmount + nonDiscountableTotalAmount);
46
+ let voucherDiscounted = 0;
48
47
  if (voucherType === "FIXED") {
49
- voucherDiscount = Math.min(toMoneyNumber(voucherRate), grossAmount);
48
+ voucherDiscounted = -Math.min(toMoneyNumber(voucherRate), totalOrderAmount);
50
49
  }
51
50
  if (voucherType === "PERCENTAGE") {
52
- voucherDiscount = grossAmount * (toMoneyNumber(voucherRate) / 100);
51
+ voucherDiscounted = -(totalOrderAmount * (toMoneyNumber(voucherRate) / 100));
53
52
  }
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);
59
- let discount = 0;
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);
65
- if (isVatExemptDiscount(discountType)) {
66
- vat = 0;
67
- }
68
- if (isAddVatAfterDiscount(discountType)) {
69
- vat = format2(vatNet * (toMoneyNumber(vatRate, 12) / 100));
53
+ const subtotal = totalOrderAmount + voucherDiscounted;
54
+ const voucherVatNet = Number((totalOrderAmount / vatRate).toFixed(2));
55
+ const voucherVat = Number((voucherVatNet * 0.12).toFixed(2));
56
+ let vatNet = Number((subtotal / vatRate).toFixed(2));
57
+ let vat = Number((vatNet * 0.12).toFixed(2));
58
+ const isSpecial = discountRate > 0;
59
+ const isAddVat = isAddVatAfterDiscount(discountType);
60
+ const discounted = Number((discountRate * -vatNet).toFixed(2));
61
+ if (isSpecial) {
62
+ vatNet = Number((vatNet + discounted).toFixed(2));
63
+ if (!isAddVat) {
64
+ vat = -vat;
70
65
  }
71
66
  }
72
67
  let serviceCharge = 0;
73
- if (diningOption === "FOR_HERE" && serviceChargeRate > 0 && serviceChargeableTotalAmount > 0) {
74
- const serviceChargeVatNet = format2(serviceChargeableTotalAmount / vatDivisor);
75
- serviceCharge = format2(serviceChargeVatNet * (toMoneyNumber(serviceChargeRate) / 100));
68
+ if (serviceChargeRate > 0 && serviceChargeableTotalAmount > 0) {
69
+ const scRate = serviceChargeRate / 100;
70
+ if (isSpecial) {
71
+ serviceCharge = Number(((vatNet + Math.abs(discounted)) * scRate).toFixed(2));
72
+ } else {
73
+ serviceCharge = Number((vatNet * scRate).toFixed(2));
74
+ }
76
75
  }
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;
76
+ let totalAmount = vatNet + vat + serviceCharge + togoCharge;
77
+ if (isSpecial && !isAddVat) {
78
+ totalAmount -= vat;
79
+ }
80
+ if (totalAmount < 0) totalAmount = 0;
81
81
  return {
82
- grossAmount,
83
- voucherDiscount: signedVoucherDiscount,
84
- subtotalAfterVoucher,
85
- vatNet,
82
+ gross: subtotal + Math.abs(voucherDiscounted),
83
+ hasVoucher: voucherRate > 0,
84
+ voucher: {
85
+ discount: voucherDiscounted,
86
+ net: subtotal,
87
+ vatNet: voucherVatNet,
88
+ vat: voucherVat,
89
+ forBirDiscount: -(voucherType === "FIXED" ? voucherVatNet - Number(voucherRate.toFixed(2)) : voucherVatNet * Number(voucherRate.toFixed(2)))
90
+ },
91
+ hasDiscount: discountRate > 0,
92
+ discount: {
93
+ discount: discounted,
94
+ net: vatNet
95
+ },
96
+ netOfVat: vatNet + Math.abs(discounted),
86
97
  vat,
87
- discount: signedDiscount,
88
98
  serviceCharge,
89
- togoCharge: finalTogoCharge,
99
+ togoCharge,
90
100
  totalAmount,
91
101
  bir: {
92
- vatSales: vat > 0 ? format2(vatNet + Math.abs(signedDiscount)) : 0,
93
- vatExemptSales: vat <= 0 ? format2(vatNet + Math.abs(signedDiscount)) : 0,
102
+ vatSales: vat > 0 ? vatNet + Math.abs(discounted) : 0,
103
+ vatExemptSales: vat > 0 ? 0 : vatNet + Math.abs(discounted),
94
104
  vatZeroRatedSales: 0,
95
105
  nonTaxableSales: 0,
96
106
  vat,
97
- discount: signedDiscount,
107
+ totalSales: vat > 0 ? subtotal : vatNet + Math.abs(discounted),
108
+ discount: discounted,
98
109
  serviceCharge,
99
- togoCharge: finalTogoCharge,
100
- amountPayable: totalAmount,
101
- totalSales: vat > 0 ? subtotalAfterVoucher : format2(vatNet + Math.abs(signedDiscount))
102
- },
103
- discountBreakdown: getDiscountBreakdown(discountType, signedDiscount)
110
+ togoCharge,
111
+ amountPayable: totalAmount
112
+ }
104
113
  };
105
114
  }
106
115
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qrwise/pos-calculations",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "Shared POS calculations for QR Wise POS",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",