shareneus 1.7.338 → 1.7.340
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.
|
@@ -71,6 +71,7 @@ function getReverseTaxBreakdown(taxes, qty) {
|
|
|
71
71
|
var _a, _b, _c;
|
|
72
72
|
const calcMethod = normalizeCalcMethod((_a = row === null || row === void 0 ? void 0 : row.CalcMethod) !== null && _a !== void 0 ? _a : row === null || row === void 0 ? void 0 : row.calcMethod);
|
|
73
73
|
const rate = toNum((_b = row === null || row === void 0 ? void 0 : row.Rate) !== null && _b !== void 0 ? _b : row === null || row === void 0 ? void 0 : row.rate);
|
|
74
|
+
console.log('Reverse tax row', { row, calcMethod, rate, qty });
|
|
74
75
|
switch (calcMethod) {
|
|
75
76
|
case 'PerUnit':
|
|
76
77
|
summary.fixedTaxAmount = (0, math_operations_1.Add)(summary.fixedTaxAmount, getPerUnitTaxAmount(row, qty));
|
|
@@ -169,6 +170,7 @@ class TransactionCalculationEngine {
|
|
|
169
170
|
return total;
|
|
170
171
|
}
|
|
171
172
|
const taxBreakdown = getReverseTaxBreakdown(input.taxRows, toNum(input.qty) || 1);
|
|
173
|
+
console.log('Reverse tax breakdown', taxBreakdown);
|
|
172
174
|
const totalAfterFixedTax = (0, math_operations_1.Subtract)(total, taxBreakdown.fixedTaxAmount);
|
|
173
175
|
if (taxBreakdown.percentTaxRate) {
|
|
174
176
|
const divisor = (0, math_operations_1.Add)(1, (0, math_operations_1.Divide)(taxBreakdown.percentTaxRate, 100));
|
|
@@ -184,12 +186,15 @@ class TransactionCalculationEngine {
|
|
|
184
186
|
includeTaxInTotal: input.includeTaxInTotal,
|
|
185
187
|
qty,
|
|
186
188
|
});
|
|
189
|
+
console.log('Subtotal from total using taxes', subtotal);
|
|
187
190
|
const disc = toNum(input.disc);
|
|
188
191
|
const recDisc = toNum(input.recDisc);
|
|
192
|
+
console.log('Discounts', { disc, recDisc });
|
|
189
193
|
const amount = input.noDisc
|
|
190
194
|
? subtotal
|
|
191
195
|
: (0, math_operations_1.Add)(subtotal, (0, math_operations_1.Add)(disc, recDisc));
|
|
192
196
|
const unitPrice = (0, math_operations_1.Divide)(amount, qty);
|
|
197
|
+
console.log('Reverse calculated amount and unit price', { amount, unitPrice });
|
|
193
198
|
return { amount, unitPrice };
|
|
194
199
|
}
|
|
195
200
|
// Shared reverse-calculation formula. Components only need to supply their own field mapping.
|
package/package.json
CHANGED
|
@@ -65,88 +65,88 @@ function sumTaxAmountFromTaxes(taxes: any): number {
|
|
|
65
65
|
);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
function sumTaxRateFromTaxes(taxes: any): number {
|
|
69
|
-
const rows = getTaxesArray(taxes);
|
|
70
|
-
return rows.reduce(
|
|
71
|
-
(sum, row) => Add(sum, toNum(row?.Rate ?? row?.rate)),
|
|
72
|
-
0,
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function normalizeCalcMethod(calcMethod: any): string {
|
|
77
|
-
return calcMethod === 'Percentage' || isNullOrEmpty(calcMethod)
|
|
78
|
-
? 'Percent'
|
|
79
|
-
: String(calcMethod);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function getTaxRowQty(row: any, fallbackQty: number): number {
|
|
83
|
-
return toNum(row?.Qty ?? row?.qty ?? row?.Quantity ?? row?.quantity) || fallbackQty;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function getPerUnitTaxAmount(
|
|
87
|
-
row: any,
|
|
88
|
-
fallbackQty: number,
|
|
89
|
-
fallbackToAmt = true,
|
|
90
|
-
): number {
|
|
91
|
-
const perUnitAmt = toNum(row?.PerUnitAmt ?? row?.perUnitAmt);
|
|
92
|
-
const qty = getTaxRowQty(row, fallbackQty);
|
|
93
|
-
|
|
94
|
-
if (perUnitAmt !== 0 && qty !== 0) {
|
|
95
|
-
return Multiply(perUnitAmt, qty);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return fallbackToAmt ? toNum(row?.Amt ?? row?.amt) : 0;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function getReverseTaxBreakdown(taxes: any, qty: number): {
|
|
102
|
-
fixedTaxAmount: number;
|
|
103
|
-
percentTaxRate: number;
|
|
104
|
-
} {
|
|
105
|
-
return getTaxesArray(taxes).reduce(
|
|
106
|
-
(summary, row) => {
|
|
107
|
-
const calcMethod = normalizeCalcMethod(row?.CalcMethod ?? row?.calcMethod);
|
|
108
|
-
const rate = toNum(row?.Rate ?? row?.rate);
|
|
109
|
-
|
|
110
|
-
switch (calcMethod) {
|
|
111
|
-
case 'PerUnit':
|
|
112
|
-
summary.fixedTaxAmount = Add(
|
|
113
|
-
summary.fixedTaxAmount,
|
|
114
|
-
getPerUnitTaxAmount(row, qty),
|
|
115
|
-
);
|
|
116
|
-
break;
|
|
117
|
-
|
|
118
|
-
case 'PerUnitPlusPercent':
|
|
119
|
-
summary.fixedTaxAmount = Add(
|
|
120
|
-
summary.fixedTaxAmount,
|
|
121
|
-
getPerUnitTaxAmount(row, qty, false),
|
|
122
|
-
);
|
|
123
|
-
summary.percentTaxRate = Add(summary.percentTaxRate, rate);
|
|
124
|
-
break;
|
|
125
|
-
|
|
126
|
-
case 'MaxOfPercentOrPerUnit': {
|
|
127
|
-
const amt = toNum(row?.Amt ?? row?.amt);
|
|
128
|
-
const perUnitAmt = getPerUnitTaxAmount(row, qty);
|
|
129
|
-
if (amt !== 0) {
|
|
130
|
-
summary.fixedTaxAmount = Add(summary.fixedTaxAmount, amt);
|
|
131
|
-
} else if (perUnitAmt !== 0) {
|
|
132
|
-
summary.fixedTaxAmount = Add(summary.fixedTaxAmount, perUnitAmt);
|
|
133
|
-
} else {
|
|
134
|
-
summary.percentTaxRate = Add(summary.percentTaxRate, rate);
|
|
135
|
-
}
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
case 'Percent':
|
|
140
|
-
default:
|
|
141
|
-
summary.percentTaxRate = Add(summary.percentTaxRate, rate);
|
|
142
|
-
break;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return summary;
|
|
146
|
-
},
|
|
147
|
-
{ fixedTaxAmount: 0, percentTaxRate: 0 },
|
|
148
|
-
);
|
|
149
|
-
}
|
|
68
|
+
function sumTaxRateFromTaxes(taxes: any): number {
|
|
69
|
+
const rows = getTaxesArray(taxes);
|
|
70
|
+
return rows.reduce(
|
|
71
|
+
(sum, row) => Add(sum, toNum(row?.Rate ?? row?.rate)),
|
|
72
|
+
0,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function normalizeCalcMethod(calcMethod: any): string {
|
|
77
|
+
return calcMethod === 'Percentage' || isNullOrEmpty(calcMethod)
|
|
78
|
+
? 'Percent'
|
|
79
|
+
: String(calcMethod);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function getTaxRowQty(row: any, fallbackQty: number): number {
|
|
83
|
+
return toNum(row?.Qty ?? row?.qty ?? row?.Quantity ?? row?.quantity) || fallbackQty;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function getPerUnitTaxAmount(
|
|
87
|
+
row: any,
|
|
88
|
+
fallbackQty: number,
|
|
89
|
+
fallbackToAmt = true,
|
|
90
|
+
): number {
|
|
91
|
+
const perUnitAmt = toNum(row?.PerUnitAmt ?? row?.perUnitAmt);
|
|
92
|
+
const qty = getTaxRowQty(row, fallbackQty);
|
|
93
|
+
|
|
94
|
+
if (perUnitAmt !== 0 && qty !== 0) {
|
|
95
|
+
return Multiply(perUnitAmt, qty);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return fallbackToAmt ? toNum(row?.Amt ?? row?.amt) : 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function getReverseTaxBreakdown(taxes: any, qty: number): {
|
|
102
|
+
fixedTaxAmount: number;
|
|
103
|
+
percentTaxRate: number;
|
|
104
|
+
} {
|
|
105
|
+
return getTaxesArray(taxes).reduce(
|
|
106
|
+
(summary, row) => {
|
|
107
|
+
const calcMethod = normalizeCalcMethod(row?.CalcMethod ?? row?.calcMethod);
|
|
108
|
+
const rate = toNum(row?.Rate ?? row?.rate);
|
|
109
|
+
console.log('Reverse tax row', { row, calcMethod, rate, qty });
|
|
110
|
+
switch (calcMethod) {
|
|
111
|
+
case 'PerUnit':
|
|
112
|
+
summary.fixedTaxAmount = Add(
|
|
113
|
+
summary.fixedTaxAmount,
|
|
114
|
+
getPerUnitTaxAmount(row, qty),
|
|
115
|
+
);
|
|
116
|
+
break;
|
|
117
|
+
|
|
118
|
+
case 'PerUnitPlusPercent':
|
|
119
|
+
summary.fixedTaxAmount = Add(
|
|
120
|
+
summary.fixedTaxAmount,
|
|
121
|
+
getPerUnitTaxAmount(row, qty, false),
|
|
122
|
+
);
|
|
123
|
+
summary.percentTaxRate = Add(summary.percentTaxRate, rate);
|
|
124
|
+
break;
|
|
125
|
+
|
|
126
|
+
case 'MaxOfPercentOrPerUnit': {
|
|
127
|
+
const amt = toNum(row?.Amt ?? row?.amt);
|
|
128
|
+
const perUnitAmt = getPerUnitTaxAmount(row, qty);
|
|
129
|
+
if (amt !== 0) {
|
|
130
|
+
summary.fixedTaxAmount = Add(summary.fixedTaxAmount, amt);
|
|
131
|
+
} else if (perUnitAmt !== 0) {
|
|
132
|
+
summary.fixedTaxAmount = Add(summary.fixedTaxAmount, perUnitAmt);
|
|
133
|
+
} else {
|
|
134
|
+
summary.percentTaxRate = Add(summary.percentTaxRate, rate);
|
|
135
|
+
}
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
case 'Percent':
|
|
140
|
+
default:
|
|
141
|
+
summary.percentTaxRate = Add(summary.percentTaxRate, rate);
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return summary;
|
|
146
|
+
},
|
|
147
|
+
{ fixedTaxAmount: 0, percentTaxRate: 0 },
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
150
|
|
|
151
151
|
/**
|
|
152
152
|
* Distribute a flat discount amount across a set of rows proportionally
|
|
@@ -228,30 +228,31 @@ export class TransactionCalculationEngine {
|
|
|
228
228
|
: baseAmount;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
static calculateSubtotalFromTotalUsingTaxes(input: {
|
|
232
|
-
total: number;
|
|
233
|
-
taxRows: unknown;
|
|
234
|
-
includeTaxInTotal: boolean;
|
|
235
|
-
qty?: number;
|
|
236
|
-
}): number {
|
|
237
|
-
const total = toNum(input.total);
|
|
238
|
-
if (!input.includeTaxInTotal) {
|
|
239
|
-
return total;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const taxBreakdown = getReverseTaxBreakdown(
|
|
243
|
-
input.taxRows,
|
|
244
|
-
toNum(input.qty) || 1,
|
|
245
|
-
);
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
231
|
+
static calculateSubtotalFromTotalUsingTaxes(input: {
|
|
232
|
+
total: number;
|
|
233
|
+
taxRows: unknown;
|
|
234
|
+
includeTaxInTotal: boolean;
|
|
235
|
+
qty?: number;
|
|
236
|
+
}): number {
|
|
237
|
+
const total = toNum(input.total);
|
|
238
|
+
if (!input.includeTaxInTotal) {
|
|
239
|
+
return total;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const taxBreakdown = getReverseTaxBreakdown(
|
|
243
|
+
input.taxRows,
|
|
244
|
+
toNum(input.qty) || 1,
|
|
245
|
+
);
|
|
246
|
+
console.log('Reverse tax breakdown', taxBreakdown);
|
|
247
|
+
const totalAfterFixedTax = Subtract(total, taxBreakdown.fixedTaxAmount);
|
|
248
|
+
|
|
249
|
+
if (taxBreakdown.percentTaxRate) {
|
|
250
|
+
const divisor = Add(1, Divide(taxBreakdown.percentTaxRate, 100));
|
|
251
|
+
return divisor === 0 ? totalAfterFixedTax : Divide(totalAfterFixedTax, divisor);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return totalAfterFixedTax;
|
|
255
|
+
}
|
|
255
256
|
|
|
256
257
|
static reverseCalculateAmountAndUnitPriceFromTotal(input: {
|
|
257
258
|
qty: number;
|
|
@@ -264,20 +265,21 @@ export class TransactionCalculationEngine {
|
|
|
264
265
|
}): { amount: number; unitPrice: number } {
|
|
265
266
|
const qty = toNum(input.qty) || 1;
|
|
266
267
|
const subtotal =
|
|
267
|
-
TransactionCalculationEngine.calculateSubtotalFromTotalUsingTaxes({
|
|
268
|
-
total: input.total,
|
|
269
|
-
taxRows: input.taxRows,
|
|
270
|
-
includeTaxInTotal: input.includeTaxInTotal,
|
|
271
|
-
qty,
|
|
272
|
-
});
|
|
273
|
-
|
|
268
|
+
TransactionCalculationEngine.calculateSubtotalFromTotalUsingTaxes({
|
|
269
|
+
total: input.total,
|
|
270
|
+
taxRows: input.taxRows,
|
|
271
|
+
includeTaxInTotal: input.includeTaxInTotal,
|
|
272
|
+
qty,
|
|
273
|
+
});
|
|
274
|
+
console.log('Subtotal from total using taxes', subtotal);
|
|
274
275
|
const disc = toNum(input.disc);
|
|
275
276
|
const recDisc = toNum(input.recDisc);
|
|
277
|
+
console.log('Discounts', { disc, recDisc });
|
|
276
278
|
const amount = input.noDisc
|
|
277
279
|
? subtotal
|
|
278
280
|
: Add(subtotal, Add(disc, recDisc));
|
|
279
281
|
const unitPrice = Divide(amount, qty);
|
|
280
|
-
|
|
282
|
+
console.log('Reverse calculated amount and unit price', { amount, unitPrice });
|
|
281
283
|
return { amount, unitPrice };
|
|
282
284
|
}
|
|
283
285
|
|
|
@@ -313,7 +315,7 @@ export class TransactionCalculationEngine {
|
|
|
313
315
|
? taxCode.Components
|
|
314
316
|
: [];
|
|
315
317
|
|
|
316
|
-
return components.reduce((sum:number, comp: any) => Add(sum, toNum(comp?.Rate)), 0);
|
|
318
|
+
return components.reduce((sum: number, comp: any) => Add(sum, toNum(comp?.Rate)), 0);
|
|
317
319
|
}
|
|
318
320
|
|
|
319
321
|
// -------------------------------------------------------------------------
|
|
@@ -554,15 +556,15 @@ export class TransactionCalculationEngine {
|
|
|
554
556
|
return { ...item };
|
|
555
557
|
}
|
|
556
558
|
|
|
557
|
-
// If total doesn't include tax, treat it as "already stripped".
|
|
558
|
-
const subtotal = includeTaxInTotal
|
|
559
|
-
? TransactionCalculationEngine.calculateSubtotalFromTotalUsingTaxes({
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
: total;
|
|
559
|
+
// If total doesn't include tax, treat it as "already stripped".
|
|
560
|
+
const subtotal = includeTaxInTotal
|
|
561
|
+
? TransactionCalculationEngine.calculateSubtotalFromTotalUsingTaxes({
|
|
562
|
+
total,
|
|
563
|
+
taxRows: item?.Taxes ?? item?.taxes,
|
|
564
|
+
includeTaxInTotal,
|
|
565
|
+
qty,
|
|
566
|
+
})
|
|
567
|
+
: total;
|
|
566
568
|
|
|
567
569
|
if (item.NoDisc) {
|
|
568
570
|
const unpr = Divide(subtotal, qty);
|