@qrwise/pos-calculations 0.0.20 → 0.0.22
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 +19 -8
- package/dist/index.d.cts +1 -3
- package/dist/index.d.ts +1 -3
- package/dist/index.js +19 -8
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -416,6 +416,17 @@ function voucherVatNet(transaction, voucher, discount) {
|
|
|
416
416
|
const eligibleGross = itemizedGross > 0 ? itemizedGross : percentageGross > 0 ? percentageGross : gross;
|
|
417
417
|
return format2(Math.min(gross, eligibleGross) / 1.12);
|
|
418
418
|
}
|
|
419
|
+
function itemizedVoucherCount(transaction) {
|
|
420
|
+
const splits = transaction.metadata?.split_discounts;
|
|
421
|
+
if (!Array.isArray(splits)) return 0;
|
|
422
|
+
return splits.reduce((count, rawSplit) => {
|
|
423
|
+
if (!rawSplit || typeof rawSplit !== "object") return count;
|
|
424
|
+
const rawVoucher = rawSplit.voucher;
|
|
425
|
+
if (!rawVoucher || typeof rawVoucher !== "object") return count;
|
|
426
|
+
const voucher = rawVoucher;
|
|
427
|
+
return Math.abs(toMoneyNumber(voucher.discount_amount)) > 0 ? count + 1 : count;
|
|
428
|
+
}, 0);
|
|
429
|
+
}
|
|
419
430
|
function buildTransactionProjection(transaction, options = {}) {
|
|
420
431
|
const status = `${transaction.status} ${transaction.payment_status}`.toLowerCase();
|
|
421
432
|
const state = status.includes("refund") || status.includes("return") ? "RETURNED" : status.includes("cancel") || status.includes("void") ? "CANCELLED" : "SUCCESS";
|
|
@@ -424,10 +435,10 @@ function buildTransactionProjection(transaction, options = {}) {
|
|
|
424
435
|
const discount = Math.abs(toMoneyNumber(transaction.discount_amount));
|
|
425
436
|
const voucher = Math.abs(toMoneyNumber(transaction.voucher_discount_amount));
|
|
426
437
|
const voucherRate = toMoneyNumber(transaction.voucher_rate);
|
|
427
|
-
const hasVoucher =
|
|
438
|
+
const hasVoucher = voucher > 0;
|
|
428
439
|
const hasVoucherAndDiscount = isSuccessful && voucher > 0 && discount > 0;
|
|
429
440
|
const scopedVoucherVatNet = voucherVatNet(transaction, voucher, discount);
|
|
430
|
-
const voucherForBirDiscount = -format2(
|
|
441
|
+
const voucherForBirDiscount = itemizedVoucherCount(transaction) > 1 ? -format2(voucher / 1.12) : -format2(
|
|
431
442
|
transaction.voucher_type?.toLowerCase() === "fixed" ? scopedVoucherVatNet - format2(voucherRate) : scopedVoucherVatNet * format2(voucherRate / 100)
|
|
432
443
|
);
|
|
433
444
|
const otherDiscount = isSuccessful && hasVoucher ? format2(voucherForBirDiscount) : 0;
|
|
@@ -437,7 +448,9 @@ function buildTransactionProjection(transaction, options = {}) {
|
|
|
437
448
|
const storedVatExemptSales = toMoneyNumber(transaction.vat_exempt_sales);
|
|
438
449
|
const storedZeroRatedSales = toMoneyNumber(transaction.zero_rated_sales);
|
|
439
450
|
const storedNonTaxableSales = toMoneyNumber(transaction.non_taxable_sales);
|
|
440
|
-
const
|
|
451
|
+
const storedNetOfVat = storedVatSales + storedVatExemptSales + storedZeroRatedSales + storedNonTaxableSales;
|
|
452
|
+
const fullyDiscountedCancellationNet = !isSuccessful && storedNetOfVat === 0 && toMoneyNumber(transaction.amount_payable) === 0 && gross > 0 && options.isVatRegistered !== void 0 ? format2(gross / (options.isVatRegistered ? 1.12 : 1)) : 0;
|
|
453
|
+
const netOfVat = storedNetOfVat || fullyDiscountedCancellationNet || Math.max(0, toMoneyNumber(transaction.amount_payable) - storedVat);
|
|
441
454
|
const returned = state === "RETURNED" ? -format2(netOfVat) : 0;
|
|
442
455
|
const cancelled = state === "CANCELLED" ? -format2(netOfVat) : 0;
|
|
443
456
|
const { counts, discountWeights, vatExemptWeights } = discountAllocation(transaction, options);
|
|
@@ -475,9 +488,10 @@ function buildTransactionProjection(transaction, options = {}) {
|
|
|
475
488
|
};
|
|
476
489
|
const regularVat = storedVat || format2(Math.abs(storedVatExemptSales * 0.12));
|
|
477
490
|
let vatAmount = format2(
|
|
478
|
-
isSuccessful ? voucher > 0 ? Math.abs(scopedVoucherVatNet * 0.12) : regularVat : netOfVat * 0.12
|
|
491
|
+
isSuccessful ? voucher > 0 ? Math.abs(scopedVoucherVatNet * 0.12) : regularVat : options.isVatRegistered === false ? 0 : netOfVat * 0.12
|
|
479
492
|
);
|
|
480
|
-
|
|
493
|
+
const hasMixedStatutoryTax = isSuccessful && discount > 0 && storedVat > 0 && storedVatSales > 0 && storedVatExemptSales > 0;
|
|
494
|
+
if (hasVoucherAndDiscount || hasMixedStatutoryTax) {
|
|
481
495
|
vatAmount = format2(
|
|
482
496
|
storedVat + Math.abs(adjustments.scDiscountAdjustment) + Math.abs(adjustments.pwdDiscountAdjustment) + Math.abs(adjustments.otherDiscountAdjustment)
|
|
483
497
|
);
|
|
@@ -491,7 +505,6 @@ function buildTransactionProjection(transaction, options = {}) {
|
|
|
491
505
|
vatableSales + vatExemptSales + zeroRatedSales + storedNonTaxableSales + deductions.scDiscount + deductions.pwdDiscount + deductions.naacDiscount + deductions.soloDiscount + deductions.movDiscount + deductions.otherDiscount
|
|
492
506
|
) : 0;
|
|
493
507
|
const serviceCharge = toMoneyNumber(transaction.service_charge_amount);
|
|
494
|
-
const takeoutCharge = toMoneyNumber(transaction.takeout_charge_amount);
|
|
495
508
|
return {
|
|
496
509
|
state,
|
|
497
510
|
receipt: {
|
|
@@ -510,7 +523,6 @@ function buildTransactionProjection(transaction, options = {}) {
|
|
|
510
523
|
storedVatSales + storedVatExemptSales + storedZeroRatedSales + storedNonTaxableSales + storedVat
|
|
511
524
|
),
|
|
512
525
|
serviceCharge,
|
|
513
|
-
takeoutCharge,
|
|
514
526
|
amountPayable: toMoneyNumber(transaction.amount_payable)
|
|
515
527
|
},
|
|
516
528
|
report: {
|
|
@@ -522,7 +534,6 @@ function buildTransactionProjection(transaction, options = {}) {
|
|
|
522
534
|
zeroRatedSales,
|
|
523
535
|
deductions,
|
|
524
536
|
serviceCharge,
|
|
525
|
-
takeoutCharge,
|
|
526
537
|
adjustments,
|
|
527
538
|
vatPayable: isSuccessful ? Math.max(0, format2(vatAmount - Math.abs(adjustments.totalAdjustments))) : 0,
|
|
528
539
|
netSales,
|
package/dist/index.d.cts
CHANGED
|
@@ -118,7 +118,6 @@ interface FinancialTransactionInput {
|
|
|
118
118
|
zero_rated_sales?: number | string | null;
|
|
119
119
|
non_taxable_sales?: number | string | null;
|
|
120
120
|
service_charge_amount?: number | string | null;
|
|
121
|
-
takeout_charge_amount?: number | string | null;
|
|
122
121
|
discount_customers?: Array<{
|
|
123
122
|
discount_id?: string | null;
|
|
124
123
|
discount_name?: string | null;
|
|
@@ -139,6 +138,7 @@ interface FinancialTransactionInput {
|
|
|
139
138
|
}
|
|
140
139
|
interface TransactionProjectionOptions {
|
|
141
140
|
discountRatesById?: Record<string, number>;
|
|
141
|
+
isVatRegistered?: boolean;
|
|
142
142
|
}
|
|
143
143
|
declare function buildTransactionProjection(transaction: FinancialTransactionInput, options?: TransactionProjectionOptions): {
|
|
144
144
|
state: string;
|
|
@@ -156,7 +156,6 @@ declare function buildTransactionProjection(transaction: FinancialTransactionInp
|
|
|
156
156
|
vatAmount: number;
|
|
157
157
|
totalSales: number;
|
|
158
158
|
serviceCharge: number;
|
|
159
|
-
takeoutCharge: number;
|
|
160
159
|
amountPayable: number;
|
|
161
160
|
};
|
|
162
161
|
report: {
|
|
@@ -178,7 +177,6 @@ declare function buildTransactionProjection(transaction: FinancialTransactionInp
|
|
|
178
177
|
totalDeductions: number;
|
|
179
178
|
};
|
|
180
179
|
serviceCharge: number;
|
|
181
|
-
takeoutCharge: number;
|
|
182
180
|
adjustments: {
|
|
183
181
|
scDiscountAdjustment: number;
|
|
184
182
|
pwdDiscountAdjustment: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -118,7 +118,6 @@ interface FinancialTransactionInput {
|
|
|
118
118
|
zero_rated_sales?: number | string | null;
|
|
119
119
|
non_taxable_sales?: number | string | null;
|
|
120
120
|
service_charge_amount?: number | string | null;
|
|
121
|
-
takeout_charge_amount?: number | string | null;
|
|
122
121
|
discount_customers?: Array<{
|
|
123
122
|
discount_id?: string | null;
|
|
124
123
|
discount_name?: string | null;
|
|
@@ -139,6 +138,7 @@ interface FinancialTransactionInput {
|
|
|
139
138
|
}
|
|
140
139
|
interface TransactionProjectionOptions {
|
|
141
140
|
discountRatesById?: Record<string, number>;
|
|
141
|
+
isVatRegistered?: boolean;
|
|
142
142
|
}
|
|
143
143
|
declare function buildTransactionProjection(transaction: FinancialTransactionInput, options?: TransactionProjectionOptions): {
|
|
144
144
|
state: string;
|
|
@@ -156,7 +156,6 @@ declare function buildTransactionProjection(transaction: FinancialTransactionInp
|
|
|
156
156
|
vatAmount: number;
|
|
157
157
|
totalSales: number;
|
|
158
158
|
serviceCharge: number;
|
|
159
|
-
takeoutCharge: number;
|
|
160
159
|
amountPayable: number;
|
|
161
160
|
};
|
|
162
161
|
report: {
|
|
@@ -178,7 +177,6 @@ declare function buildTransactionProjection(transaction: FinancialTransactionInp
|
|
|
178
177
|
totalDeductions: number;
|
|
179
178
|
};
|
|
180
179
|
serviceCharge: number;
|
|
181
|
-
takeoutCharge: number;
|
|
182
180
|
adjustments: {
|
|
183
181
|
scDiscountAdjustment: number;
|
|
184
182
|
pwdDiscountAdjustment: number;
|
package/dist/index.js
CHANGED
|
@@ -383,6 +383,17 @@ function voucherVatNet(transaction, voucher, discount) {
|
|
|
383
383
|
const eligibleGross = itemizedGross > 0 ? itemizedGross : percentageGross > 0 ? percentageGross : gross;
|
|
384
384
|
return format2(Math.min(gross, eligibleGross) / 1.12);
|
|
385
385
|
}
|
|
386
|
+
function itemizedVoucherCount(transaction) {
|
|
387
|
+
const splits = transaction.metadata?.split_discounts;
|
|
388
|
+
if (!Array.isArray(splits)) return 0;
|
|
389
|
+
return splits.reduce((count, rawSplit) => {
|
|
390
|
+
if (!rawSplit || typeof rawSplit !== "object") return count;
|
|
391
|
+
const rawVoucher = rawSplit.voucher;
|
|
392
|
+
if (!rawVoucher || typeof rawVoucher !== "object") return count;
|
|
393
|
+
const voucher = rawVoucher;
|
|
394
|
+
return Math.abs(toMoneyNumber(voucher.discount_amount)) > 0 ? count + 1 : count;
|
|
395
|
+
}, 0);
|
|
396
|
+
}
|
|
386
397
|
function buildTransactionProjection(transaction, options = {}) {
|
|
387
398
|
const status = `${transaction.status} ${transaction.payment_status}`.toLowerCase();
|
|
388
399
|
const state = status.includes("refund") || status.includes("return") ? "RETURNED" : status.includes("cancel") || status.includes("void") ? "CANCELLED" : "SUCCESS";
|
|
@@ -391,10 +402,10 @@ function buildTransactionProjection(transaction, options = {}) {
|
|
|
391
402
|
const discount = Math.abs(toMoneyNumber(transaction.discount_amount));
|
|
392
403
|
const voucher = Math.abs(toMoneyNumber(transaction.voucher_discount_amount));
|
|
393
404
|
const voucherRate = toMoneyNumber(transaction.voucher_rate);
|
|
394
|
-
const hasVoucher =
|
|
405
|
+
const hasVoucher = voucher > 0;
|
|
395
406
|
const hasVoucherAndDiscount = isSuccessful && voucher > 0 && discount > 0;
|
|
396
407
|
const scopedVoucherVatNet = voucherVatNet(transaction, voucher, discount);
|
|
397
|
-
const voucherForBirDiscount = -format2(
|
|
408
|
+
const voucherForBirDiscount = itemizedVoucherCount(transaction) > 1 ? -format2(voucher / 1.12) : -format2(
|
|
398
409
|
transaction.voucher_type?.toLowerCase() === "fixed" ? scopedVoucherVatNet - format2(voucherRate) : scopedVoucherVatNet * format2(voucherRate / 100)
|
|
399
410
|
);
|
|
400
411
|
const otherDiscount = isSuccessful && hasVoucher ? format2(voucherForBirDiscount) : 0;
|
|
@@ -404,7 +415,9 @@ function buildTransactionProjection(transaction, options = {}) {
|
|
|
404
415
|
const storedVatExemptSales = toMoneyNumber(transaction.vat_exempt_sales);
|
|
405
416
|
const storedZeroRatedSales = toMoneyNumber(transaction.zero_rated_sales);
|
|
406
417
|
const storedNonTaxableSales = toMoneyNumber(transaction.non_taxable_sales);
|
|
407
|
-
const
|
|
418
|
+
const storedNetOfVat = storedVatSales + storedVatExemptSales + storedZeroRatedSales + storedNonTaxableSales;
|
|
419
|
+
const fullyDiscountedCancellationNet = !isSuccessful && storedNetOfVat === 0 && toMoneyNumber(transaction.amount_payable) === 0 && gross > 0 && options.isVatRegistered !== void 0 ? format2(gross / (options.isVatRegistered ? 1.12 : 1)) : 0;
|
|
420
|
+
const netOfVat = storedNetOfVat || fullyDiscountedCancellationNet || Math.max(0, toMoneyNumber(transaction.amount_payable) - storedVat);
|
|
408
421
|
const returned = state === "RETURNED" ? -format2(netOfVat) : 0;
|
|
409
422
|
const cancelled = state === "CANCELLED" ? -format2(netOfVat) : 0;
|
|
410
423
|
const { counts, discountWeights, vatExemptWeights } = discountAllocation(transaction, options);
|
|
@@ -442,9 +455,10 @@ function buildTransactionProjection(transaction, options = {}) {
|
|
|
442
455
|
};
|
|
443
456
|
const regularVat = storedVat || format2(Math.abs(storedVatExemptSales * 0.12));
|
|
444
457
|
let vatAmount = format2(
|
|
445
|
-
isSuccessful ? voucher > 0 ? Math.abs(scopedVoucherVatNet * 0.12) : regularVat : netOfVat * 0.12
|
|
458
|
+
isSuccessful ? voucher > 0 ? Math.abs(scopedVoucherVatNet * 0.12) : regularVat : options.isVatRegistered === false ? 0 : netOfVat * 0.12
|
|
446
459
|
);
|
|
447
|
-
|
|
460
|
+
const hasMixedStatutoryTax = isSuccessful && discount > 0 && storedVat > 0 && storedVatSales > 0 && storedVatExemptSales > 0;
|
|
461
|
+
if (hasVoucherAndDiscount || hasMixedStatutoryTax) {
|
|
448
462
|
vatAmount = format2(
|
|
449
463
|
storedVat + Math.abs(adjustments.scDiscountAdjustment) + Math.abs(adjustments.pwdDiscountAdjustment) + Math.abs(adjustments.otherDiscountAdjustment)
|
|
450
464
|
);
|
|
@@ -458,7 +472,6 @@ function buildTransactionProjection(transaction, options = {}) {
|
|
|
458
472
|
vatableSales + vatExemptSales + zeroRatedSales + storedNonTaxableSales + deductions.scDiscount + deductions.pwdDiscount + deductions.naacDiscount + deductions.soloDiscount + deductions.movDiscount + deductions.otherDiscount
|
|
459
473
|
) : 0;
|
|
460
474
|
const serviceCharge = toMoneyNumber(transaction.service_charge_amount);
|
|
461
|
-
const takeoutCharge = toMoneyNumber(transaction.takeout_charge_amount);
|
|
462
475
|
return {
|
|
463
476
|
state,
|
|
464
477
|
receipt: {
|
|
@@ -477,7 +490,6 @@ function buildTransactionProjection(transaction, options = {}) {
|
|
|
477
490
|
storedVatSales + storedVatExemptSales + storedZeroRatedSales + storedNonTaxableSales + storedVat
|
|
478
491
|
),
|
|
479
492
|
serviceCharge,
|
|
480
|
-
takeoutCharge,
|
|
481
493
|
amountPayable: toMoneyNumber(transaction.amount_payable)
|
|
482
494
|
},
|
|
483
495
|
report: {
|
|
@@ -489,7 +501,6 @@ function buildTransactionProjection(transaction, options = {}) {
|
|
|
489
501
|
zeroRatedSales,
|
|
490
502
|
deductions,
|
|
491
503
|
serviceCharge,
|
|
492
|
-
takeoutCharge,
|
|
493
504
|
adjustments,
|
|
494
505
|
vatPayable: isSuccessful ? Math.max(0, format2(vatAmount - Math.abs(adjustments.totalAdjustments))) : 0,
|
|
495
506
|
netSales,
|