@parv0888/scheme-engine 0.1.0
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/calculators/discount-application.d.ts +44 -0
- package/dist/calculators/discount-application.d.ts.map +1 -0
- package/dist/calculators/discount-application.js +174 -0
- package/dist/calculators/discount-application.js.map +1 -0
- package/dist/calculators/index.d.ts +65 -0
- package/dist/calculators/index.d.ts.map +1 -0
- package/dist/calculators/index.js +196 -0
- package/dist/calculators/index.js.map +1 -0
- package/dist/calculators/payout-types/article.d.ts +23 -0
- package/dist/calculators/payout-types/article.d.ts.map +1 -0
- package/dist/calculators/payout-types/article.js +73 -0
- package/dist/calculators/payout-types/article.js.map +1 -0
- package/dist/calculators/payout-types/basket.d.ts +49 -0
- package/dist/calculators/payout-types/basket.d.ts.map +1 -0
- package/dist/calculators/payout-types/basket.js +108 -0
- package/dist/calculators/payout-types/basket.js.map +1 -0
- package/dist/calculators/payout-types/coupon.d.ts +23 -0
- package/dist/calculators/payout-types/coupon.d.ts.map +1 -0
- package/dist/calculators/payout-types/coupon.js +74 -0
- package/dist/calculators/payout-types/coupon.js.map +1 -0
- package/dist/calculators/payout-types/discount.d.ts +21 -0
- package/dist/calculators/payout-types/discount.d.ts.map +1 -0
- package/dist/calculators/payout-types/discount.js +110 -0
- package/dist/calculators/payout-types/discount.js.map +1 -0
- package/dist/calculators/payout-types/fixed-discount.d.ts +31 -0
- package/dist/calculators/payout-types/fixed-discount.d.ts.map +1 -0
- package/dist/calculators/payout-types/fixed-discount.js +65 -0
- package/dist/calculators/payout-types/fixed-discount.js.map +1 -0
- package/dist/calculators/payout-types/foc.d.ts +30 -0
- package/dist/calculators/payout-types/foc.d.ts.map +1 -0
- package/dist/calculators/payout-types/foc.js +130 -0
- package/dist/calculators/payout-types/foc.js.map +1 -0
- package/dist/calculators/payout-types/mrp-percentage.d.ts +34 -0
- package/dist/calculators/payout-types/mrp-percentage.d.ts.map +1 -0
- package/dist/calculators/payout-types/mrp-percentage.js +77 -0
- package/dist/calculators/payout-types/mrp-percentage.js.map +1 -0
- package/dist/calculators/payout-types/nlp.d.ts +22 -0
- package/dist/calculators/payout-types/nlp.d.ts.map +1 -0
- package/dist/calculators/payout-types/nlp.js +59 -0
- package/dist/calculators/payout-types/nlp.js.map +1 -0
- package/dist/calculators/payout-types/per-unit.d.ts +32 -0
- package/dist/calculators/payout-types/per-unit.d.ts.map +1 -0
- package/dist/calculators/payout-types/per-unit.js +94 -0
- package/dist/calculators/payout-types/per-unit.js.map +1 -0
- package/dist/calculators/payout-types/product-new.d.ts +27 -0
- package/dist/calculators/payout-types/product-new.d.ts.map +1 -0
- package/dist/calculators/payout-types/product-new.js +85 -0
- package/dist/calculators/payout-types/product-new.js.map +1 -0
- package/dist/calculators/payout-types/product.d.ts +31 -0
- package/dist/calculators/payout-types/product.d.ts.map +1 -0
- package/dist/calculators/payout-types/product.js +73 -0
- package/dist/calculators/payout-types/product.js.map +1 -0
- package/dist/calculators/payout-types/topup.d.ts +19 -0
- package/dist/calculators/payout-types/topup.d.ts.map +1 -0
- package/dist/calculators/payout-types/topup.js +46 -0
- package/dist/calculators/payout-types/topup.js.map +1 -0
- package/dist/calculators/slab-matcher.d.ts +41 -0
- package/dist/calculators/slab-matcher.d.ts.map +1 -0
- package/dist/calculators/slab-matcher.js +68 -0
- package/dist/calculators/slab-matcher.js.map +1 -0
- package/dist/esm/calculators/discount-application.js +170 -0
- package/dist/esm/calculators/discount-application.js.map +1 -0
- package/dist/esm/calculators/index.js +176 -0
- package/dist/esm/calculators/index.js.map +1 -0
- package/dist/esm/calculators/payout-types/article.js +70 -0
- package/dist/esm/calculators/payout-types/article.js.map +1 -0
- package/dist/esm/calculators/payout-types/basket.js +105 -0
- package/dist/esm/calculators/payout-types/basket.js.map +1 -0
- package/dist/esm/calculators/payout-types/coupon.js +71 -0
- package/dist/esm/calculators/payout-types/coupon.js.map +1 -0
- package/dist/esm/calculators/payout-types/discount.js +107 -0
- package/dist/esm/calculators/payout-types/discount.js.map +1 -0
- package/dist/esm/calculators/payout-types/fixed-discount.js +62 -0
- package/dist/esm/calculators/payout-types/fixed-discount.js.map +1 -0
- package/dist/esm/calculators/payout-types/foc.js +127 -0
- package/dist/esm/calculators/payout-types/foc.js.map +1 -0
- package/dist/esm/calculators/payout-types/mrp-percentage.js +74 -0
- package/dist/esm/calculators/payout-types/mrp-percentage.js.map +1 -0
- package/dist/esm/calculators/payout-types/nlp.js +56 -0
- package/dist/esm/calculators/payout-types/nlp.js.map +1 -0
- package/dist/esm/calculators/payout-types/per-unit.js +91 -0
- package/dist/esm/calculators/payout-types/per-unit.js.map +1 -0
- package/dist/esm/calculators/payout-types/product-new.js +82 -0
- package/dist/esm/calculators/payout-types/product-new.js.map +1 -0
- package/dist/esm/calculators/payout-types/product.js +70 -0
- package/dist/esm/calculators/payout-types/product.js.map +1 -0
- package/dist/esm/calculators/payout-types/topup.js +43 -0
- package/dist/esm/calculators/payout-types/topup.js.map +1 -0
- package/dist/esm/calculators/slab-matcher.js +64 -0
- package/dist/esm/calculators/slab-matcher.js.map +1 -0
- package/dist/esm/helpers/calc-type-checks.js +30 -0
- package/dist/esm/helpers/calc-type-checks.js.map +1 -0
- package/dist/esm/helpers/compare-value.js +109 -0
- package/dist/esm/helpers/compare-value.js.map +1 -0
- package/dist/esm/helpers/constraint-checks.js +67 -0
- package/dist/esm/helpers/constraint-checks.js.map +1 -0
- package/dist/esm/helpers/index.js +8 -0
- package/dist/esm/helpers/index.js.map +1 -0
- package/dist/esm/helpers/math.js +84 -0
- package/dist/esm/helpers/math.js.map +1 -0
- package/dist/esm/helpers/payout-type-checks.js +29 -0
- package/dist/esm/helpers/payout-type-checks.js.map +1 -0
- package/dist/esm/helpers/qualifier-checks.js +188 -0
- package/dist/esm/helpers/qualifier-checks.js.map +1 -0
- package/dist/esm/helpers/scheme-applicability.js +93 -0
- package/dist/esm/helpers/scheme-applicability.js.map +1 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/types/applied-scheme.js +19 -0
- package/dist/esm/types/applied-scheme.js.map +1 -0
- package/dist/esm/types/enums.js +115 -0
- package/dist/esm/types/enums.js.map +1 -0
- package/dist/esm/types/index.js +5 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/item-props.js +2 -0
- package/dist/esm/types/item-props.js.map +1 -0
- package/dist/esm/types/scheme.js +2 -0
- package/dist/esm/types/scheme.js.map +1 -0
- package/dist/helpers/calc-type-checks.d.ts +21 -0
- package/dist/helpers/calc-type-checks.d.ts.map +1 -0
- package/dist/helpers/calc-type-checks.js +36 -0
- package/dist/helpers/calc-type-checks.js.map +1 -0
- package/dist/helpers/compare-value.d.ts +40 -0
- package/dist/helpers/compare-value.d.ts.map +1 -0
- package/dist/helpers/compare-value.js +120 -0
- package/dist/helpers/compare-value.js.map +1 -0
- package/dist/helpers/constraint-checks.d.ts +30 -0
- package/dist/helpers/constraint-checks.d.ts.map +1 -0
- package/dist/helpers/constraint-checks.js +73 -0
- package/dist/helpers/constraint-checks.js.map +1 -0
- package/dist/helpers/index.d.ts +8 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +24 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/math.d.ts +50 -0
- package/dist/helpers/math.d.ts.map +1 -0
- package/dist/helpers/math.js +96 -0
- package/dist/helpers/math.js.map +1 -0
- package/dist/helpers/payout-type-checks.d.ts +17 -0
- package/dist/helpers/payout-type-checks.d.ts.map +1 -0
- package/dist/helpers/payout-type-checks.js +34 -0
- package/dist/helpers/payout-type-checks.js.map +1 -0
- package/dist/helpers/qualifier-checks.d.ts +62 -0
- package/dist/helpers/qualifier-checks.d.ts.map +1 -0
- package/dist/helpers/qualifier-checks.js +194 -0
- package/dist/helpers/qualifier-checks.js.map +1 -0
- package/dist/helpers/scheme-applicability.d.ts +40 -0
- package/dist/helpers/scheme-applicability.d.ts.map +1 -0
- package/dist/helpers/scheme-applicability.js +99 -0
- package/dist/helpers/scheme-applicability.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/types/applied-scheme.d.ts +157 -0
- package/dist/types/applied-scheme.d.ts.map +1 -0
- package/dist/types/applied-scheme.js +22 -0
- package/dist/types/applied-scheme.js.map +1 -0
- package/dist/types/enums.d.ts +91 -0
- package/dist/types/enums.d.ts.map +1 -0
- package/dist/types/enums.js +118 -0
- package/dist/types/enums.js.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +21 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/item-props.d.ts +103 -0
- package/dist/types/item-props.d.ts.map +1 -0
- package/dist/types/item-props.js +3 -0
- package/dist/types/item-props.js.map +1 -0
- package/dist/types/scheme.d.ts +172 -0
- package/dist/types/scheme.d.ts.map +1 -0
- package/dist/types/scheme.js +3 -0
- package/dist/types/scheme.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Scheme } from "../../types/scheme";
|
|
2
|
+
import type { SchemeSlabResult } from "../../types/applied-scheme";
|
|
3
|
+
import type { QualifierItem } from "../../helpers/qualifier-checks";
|
|
4
|
+
export interface ProductCalculatorInput {
|
|
5
|
+
/** Full scheme configuration. */
|
|
6
|
+
scheme: Scheme;
|
|
7
|
+
/** Precomputed compare value used for slab matching (usually quantity/units). */
|
|
8
|
+
compareValue: number;
|
|
9
|
+
/** Total amount of the qualifying set (used when distributing unitary scheme value as discount). */
|
|
10
|
+
totalAmount: number;
|
|
11
|
+
/** Items contributing to qualification for this scheme. */
|
|
12
|
+
applicableProducts: QualifierItem[];
|
|
13
|
+
/** Whether to use MRP billing payout (slab.mrpPayout) where applicable. */
|
|
14
|
+
isMrpBilling: boolean;
|
|
15
|
+
/** Price of the payout FOC product (for unitary scheme) */
|
|
16
|
+
focProductPrice?: number;
|
|
17
|
+
/** Company rule: treat PRODUCT payout as unitary (distribute free product value as discount). */
|
|
18
|
+
companyUsesUnitaryProductScheme?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Calculate payout for PRODUCT payout type.
|
|
22
|
+
*
|
|
23
|
+
* factor = Math.floor(compareValue / slab.constraint)
|
|
24
|
+
* payoutQty = payout × factor
|
|
25
|
+
* Calls addProduct to add free product.
|
|
26
|
+
*
|
|
27
|
+
* If companyUsesUnitaryProductScheme, also distributes focProduct price
|
|
28
|
+
* as a discount across applicable products.
|
|
29
|
+
*/
|
|
30
|
+
export declare function calculateProductPayout(input: ProductCalculatorInput): SchemeSlabResult;
|
|
31
|
+
//# sourceMappingURL=product.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../../../src/calculators/payout-types/product.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAKnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAEpE,MAAM,WAAW,sBAAsB;IACrC,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,YAAY,EAAE,MAAM,CAAC;IACrB,oGAAoG;IACpG,WAAW,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,kBAAkB,EAAE,aAAa,EAAE,CAAC;IACpC,2EAA2E;IAC3E,YAAY,EAAE,OAAO,CAAC;IACtB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iGAAiG;IACjG,+BAA+B,CAAC,EAAE,OAAO,CAAC;CAC3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,sBAAsB,GAAG,gBAAgB,CAyEtF"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateProductPayout = calculateProductPayout;
|
|
4
|
+
const enums_1 = require("../../types/enums");
|
|
5
|
+
const applied_scheme_1 = require("../../types/applied-scheme");
|
|
6
|
+
const constraint_checks_1 = require("../../helpers/constraint-checks");
|
|
7
|
+
const slab_matcher_1 = require("../slab-matcher");
|
|
8
|
+
/**
|
|
9
|
+
* Calculate payout for PRODUCT payout type.
|
|
10
|
+
*
|
|
11
|
+
* factor = Math.floor(compareValue / slab.constraint)
|
|
12
|
+
* payoutQty = payout × factor
|
|
13
|
+
* Calls addProduct to add free product.
|
|
14
|
+
*
|
|
15
|
+
* If companyUsesUnitaryProductScheme, also distributes focProduct price
|
|
16
|
+
* as a discount across applicable products.
|
|
17
|
+
*/
|
|
18
|
+
function calculateProductPayout(input) {
|
|
19
|
+
const { scheme, compareValue, totalAmount, applicableProducts, isMrpBilling, focProductPrice = 0, companyUsesUnitaryProductScheme = false, } = input;
|
|
20
|
+
const result = (0, applied_scheme_1.createEmptySlabResult)(enums_1.SchemePayoutType.PRODUCT);
|
|
21
|
+
result.targetMethod = "addProduct";
|
|
22
|
+
if (!(0, constraint_checks_1.isValidConstraintType)(scheme.constraintType)) {
|
|
23
|
+
result.warnings.push(`Invalid constraint type: ${scheme.constraintType}`);
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
if (!scheme.payoutCalculationType) {
|
|
27
|
+
result.warnings.push(`No matching calculation type found: ${scheme.payoutCalculationType}`);
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
const slabs = [...scheme.slabs].sort((a, b) => (a.constraint < b.constraint ? 1 : -1));
|
|
31
|
+
if (slabs.length === 0) {
|
|
32
|
+
result.warnings.push("Slab list is empty");
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
const matcherParams = {
|
|
36
|
+
slabs,
|
|
37
|
+
compareValue,
|
|
38
|
+
applicableProducts,
|
|
39
|
+
payoutType: enums_1.SchemePayoutType.PRODUCT,
|
|
40
|
+
discountOn: scheme.discountOn ?? null,
|
|
41
|
+
};
|
|
42
|
+
const match = (0, slab_matcher_1.findMatchingSlab)(matcherParams);
|
|
43
|
+
if (!match)
|
|
44
|
+
return result;
|
|
45
|
+
const { slab } = match;
|
|
46
|
+
const payoutProductId = slab.productId;
|
|
47
|
+
const payoutProductMasterBatchId = slab.masterBatchId?.[0] || null;
|
|
48
|
+
// Budget-cap the factor
|
|
49
|
+
const employeeWiseRemainingBudget = scheme.employeeWiseRemainingBudget;
|
|
50
|
+
let factor;
|
|
51
|
+
if ((employeeWiseRemainingBudget || employeeWiseRemainingBudget === 0) &&
|
|
52
|
+
compareValue > employeeWiseRemainingBudget) {
|
|
53
|
+
factor = Math.floor(employeeWiseRemainingBudget / slab.constraint);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
factor = Math.floor(compareValue / slab.constraint);
|
|
57
|
+
}
|
|
58
|
+
const payoutQty = (isMrpBilling ? slab.mrpPayout : slab.payout) * factor;
|
|
59
|
+
result.matched = true;
|
|
60
|
+
result.matchedSlabId = slab.id;
|
|
61
|
+
result.freeQty = payoutQty;
|
|
62
|
+
result.productToAdd = { productId: payoutProductId, quantity: payoutQty, masterBatchId: payoutProductMasterBatchId };
|
|
63
|
+
// If unitary product scheme, also calculate distributed discount
|
|
64
|
+
if (companyUsesUnitaryProductScheme && focProductPrice > 0) {
|
|
65
|
+
const discountAmountTotal = focProductPrice * payoutQty;
|
|
66
|
+
const itemDiscountPercent = ((discountAmountTotal || 0) * 100) / (totalAmount || 1);
|
|
67
|
+
result.discountPercent = itemDiscountPercent;
|
|
68
|
+
result.discountValue = discountAmountTotal;
|
|
69
|
+
result.targetMethod = "setDiscountAndValueScheme";
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=product.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product.js","sourceRoot":"","sources":["../../../src/calculators/payout-types/product.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Scheme } from "../../types/scheme";
|
|
2
|
+
import type { SchemeSlabResult } from "../../types/applied-scheme";
|
|
3
|
+
import type { QualifierItem } from "../../helpers/qualifier-checks";
|
|
4
|
+
export interface TopupCalculatorInput {
|
|
5
|
+
/** Full scheme configuration. */
|
|
6
|
+
scheme: Scheme;
|
|
7
|
+
/** Precomputed compare value used for slab matching. */
|
|
8
|
+
compareValue: number;
|
|
9
|
+
/** Items contributing to qualification for this scheme. */
|
|
10
|
+
applicableProducts: QualifierItem[];
|
|
11
|
+
/** Whether to use MRP billing payout (slab.mrpPayout). */
|
|
12
|
+
isMrpBilling: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Calculate payout for TOPUP (TopUpDiscount) payout type.
|
|
16
|
+
* Simple: itemDiscountPercent = slab.payout directly.
|
|
17
|
+
*/
|
|
18
|
+
export declare function calculateTopupPayout(input: TopupCalculatorInput): SchemeSlabResult;
|
|
19
|
+
//# sourceMappingURL=topup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topup.d.ts","sourceRoot":"","sources":["../../../src/calculators/payout-types/topup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAKnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAEpE,MAAM,WAAW,oBAAoB;IACnC,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,kBAAkB,EAAE,aAAa,EAAE,CAAC;IACpC,0DAA0D;IAC1D,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,oBAAoB,GAAG,gBAAgB,CAwClF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateTopupPayout = calculateTopupPayout;
|
|
4
|
+
const enums_1 = require("../../types/enums");
|
|
5
|
+
const applied_scheme_1 = require("../../types/applied-scheme");
|
|
6
|
+
const constraint_checks_1 = require("../../helpers/constraint-checks");
|
|
7
|
+
const slab_matcher_1 = require("../slab-matcher");
|
|
8
|
+
/**
|
|
9
|
+
* Calculate payout for TOPUP (TopUpDiscount) payout type.
|
|
10
|
+
* Simple: itemDiscountPercent = slab.payout directly.
|
|
11
|
+
*/
|
|
12
|
+
function calculateTopupPayout(input) {
|
|
13
|
+
const { scheme, compareValue, applicableProducts, isMrpBilling } = input;
|
|
14
|
+
const result = (0, applied_scheme_1.createEmptySlabResult)(enums_1.SchemePayoutType.TOPUP);
|
|
15
|
+
if (!(0, constraint_checks_1.isValidConstraintType)(scheme.constraintType)) {
|
|
16
|
+
result.warnings.push(`Invalid constraint type: ${scheme.constraintType}`);
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
if (!scheme.payoutCalculationType) {
|
|
20
|
+
result.warnings.push(`No matching calculation type found: ${scheme.payoutCalculationType}`);
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
const slabs = [...scheme.slabs].sort((a, b) => (a.constraint < b.constraint ? 1 : -1));
|
|
24
|
+
if (slabs.length === 0) {
|
|
25
|
+
result.warnings.push("Slab list is empty");
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
const matcherParams = {
|
|
29
|
+
slabs,
|
|
30
|
+
compareValue,
|
|
31
|
+
applicableProducts,
|
|
32
|
+
payoutType: enums_1.SchemePayoutType.TOPUP,
|
|
33
|
+
discountOn: scheme.discountOn ?? null,
|
|
34
|
+
};
|
|
35
|
+
const match = (0, slab_matcher_1.findMatchingSlab)(matcherParams);
|
|
36
|
+
if (!match)
|
|
37
|
+
return result;
|
|
38
|
+
const { slab } = match;
|
|
39
|
+
const itemDiscountPercent = isMrpBilling ? slab.mrpPayout : slab.payout;
|
|
40
|
+
result.matched = true;
|
|
41
|
+
result.matchedSlabId = slab.id;
|
|
42
|
+
result.discountPercent = itemDiscountPercent;
|
|
43
|
+
result.targetMethod = "setDiscountScheme";
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=topup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topup.js","sourceRoot":"","sources":["../../../src/calculators/payout-types/topup.ts"],"names":[],"mappings":";;AAuBA,oDAwCC;AA7DD,6CAAqD;AACrD,+DAAmE;AACnE,uEAAwE;AACxE,kDAA2E;AAc3E;;;GAGG;AACH,SAAgB,oBAAoB,CAAC,KAA2B;IAC9D,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;IACzE,MAAM,MAAM,GAAG,IAAA,sCAAqB,EAAC,wBAAgB,CAAC,KAAK,CAAC,CAAC;IAE7D,IAAI,CAAC,IAAA,yCAAqB,EAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC;QAClD,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,4BAA4B,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;QAC1E,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;QAClC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,uCAAuC,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC;QAC5F,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC3C,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,aAAa,GAAsB;QACvC,KAAK;QACL,YAAY;QACZ,kBAAkB;QAClB,UAAU,EAAE,wBAAgB,CAAC,KAAK;QAClC,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,IAAI;KACtC,CAAC;IAEF,MAAM,KAAK,GAAG,IAAA,+BAAgB,EAAC,aAAa,CAAC,CAAC;IAC9C,IAAI,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IACvB,MAAM,mBAAmB,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;IAExE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC,EAAE,CAAC;IAC/B,MAAM,CAAC,eAAe,GAAG,mBAAmB,CAAC;IAC7C,MAAM,CAAC,YAAY,GAAG,mBAAmB,CAAC;IAE1C,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Slab } from "../types/scheme";
|
|
2
|
+
import type { QualifierItem } from "../helpers/qualifier-checks";
|
|
3
|
+
import { SchemePayoutType } from "../types/enums";
|
|
4
|
+
export interface SlabMatcherParams {
|
|
5
|
+
/** Slab list for the scheme (typically pre-sorted by caller). */
|
|
6
|
+
slabs: Slab[];
|
|
7
|
+
/** The metric used to evaluate slab constraints (qty/amount/units depending on scheme.constraintType). */
|
|
8
|
+
compareValue: number;
|
|
9
|
+
/** Items contributing to qualification (used for qualifier checks). */
|
|
10
|
+
applicableProducts: QualifierItem[];
|
|
11
|
+
/** Payout type context (qualifier logic can vary by payout type). */
|
|
12
|
+
payoutType: SchemePayoutType | string;
|
|
13
|
+
/** Discount-on mode (e.g. group scheme) that alters qualifier checks. */
|
|
14
|
+
discountOn: number | null;
|
|
15
|
+
}
|
|
16
|
+
export interface MatchedSlab {
|
|
17
|
+
/** The slab that qualified and matched. */
|
|
18
|
+
slab: Slab;
|
|
19
|
+
/** Index of the matched slab in the `slabs` array. */
|
|
20
|
+
index: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Finds the first matching slab from a list sorted desc by constraint.
|
|
24
|
+
* Applies:
|
|
25
|
+
* 1. Secondary category / qualifier filter
|
|
26
|
+
* 2. Payout-type-aware constraint check (with maxConstraint handling)
|
|
27
|
+
*
|
|
28
|
+
* Returns the matched slab or null if none matched.
|
|
29
|
+
*/
|
|
30
|
+
export declare function findMatchingSlab(params: SlabMatcherParams): MatchedSlab | null;
|
|
31
|
+
/**
|
|
32
|
+
* Finds two adjacent slabs for step/continuous interpolation.
|
|
33
|
+
* Returns the lower and upper slab. If compare value exceeds the highest slab,
|
|
34
|
+
* uses that slab for both lower and upper.
|
|
35
|
+
*/
|
|
36
|
+
export declare function findInterpolationSlabs(params: SlabMatcherParams): {
|
|
37
|
+
lower: Slab;
|
|
38
|
+
upper: Slab;
|
|
39
|
+
lowerIndex: number;
|
|
40
|
+
} | null;
|
|
41
|
+
//# sourceMappingURL=slab-matcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slab-matcher.d.ts","sourceRoot":"","sources":["../../src/calculators/slab-matcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIlD,MAAM,WAAW,iBAAiB;IAChC,iEAAiE;IACjE,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,0GAA0G;IAC1G,YAAY,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,kBAAkB,EAAE,aAAa,EAAE,CAAC;IACpC,qEAAqE;IACrE,UAAU,EAAE,gBAAgB,GAAG,MAAM,CAAC;IACtC,yEAAyE;IACzE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,IAAI,EAAE,IAAI,CAAC;IACX,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,GAAG,IAAI,CA4B9E;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,iBAAiB,GACxB;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4BzD"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findMatchingSlab = findMatchingSlab;
|
|
4
|
+
exports.findInterpolationSlabs = findInterpolationSlabs;
|
|
5
|
+
const constraint_checks_1 = require("../helpers/constraint-checks");
|
|
6
|
+
const qualifier_checks_1 = require("../helpers/qualifier-checks");
|
|
7
|
+
/**
|
|
8
|
+
* Finds the first matching slab from a list sorted desc by constraint.
|
|
9
|
+
* Applies:
|
|
10
|
+
* 1. Secondary category / qualifier filter
|
|
11
|
+
* 2. Payout-type-aware constraint check (with maxConstraint handling)
|
|
12
|
+
*
|
|
13
|
+
* Returns the matched slab or null if none matched.
|
|
14
|
+
*/
|
|
15
|
+
function findMatchingSlab(params) {
|
|
16
|
+
const { slabs, compareValue, applicableProducts, payoutType, discountOn } = params;
|
|
17
|
+
for (let i = 0; i < slabs.length; i++) {
|
|
18
|
+
const slab = slabs[i];
|
|
19
|
+
// Check secondary category / first qualifier / third qualifier
|
|
20
|
+
const qualifierParams = {
|
|
21
|
+
secondQualifier: slab.secondQualifier,
|
|
22
|
+
secondQualifierType: slab.secondQualifierType,
|
|
23
|
+
discountOn,
|
|
24
|
+
firstQualifier: slab.firstQualifier,
|
|
25
|
+
thirdQualifier: slab.thirdQualifier,
|
|
26
|
+
thirdQualifierType: slab.thirdQualifierType,
|
|
27
|
+
schemePayoutType: payoutType,
|
|
28
|
+
slabConstraint: slab.constraint,
|
|
29
|
+
};
|
|
30
|
+
if (!(0, qualifier_checks_1.checkIfSecondaryCategoryFilterPassed)(qualifierParams, applicableProducts)) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if ((0, constraint_checks_1.checkSlabConstraint)(compareValue, slab, payoutType)) {
|
|
34
|
+
return { slab, index: i };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Finds two adjacent slabs for step/continuous interpolation.
|
|
41
|
+
* Returns the lower and upper slab. If compare value exceeds the highest slab,
|
|
42
|
+
* uses that slab for both lower and upper.
|
|
43
|
+
*/
|
|
44
|
+
function findInterpolationSlabs(params) {
|
|
45
|
+
const { slabs, compareValue, applicableProducts, payoutType, discountOn } = params;
|
|
46
|
+
for (let i = 0; i < slabs.length; i++) {
|
|
47
|
+
const lowerSlab = slabs[i];
|
|
48
|
+
const qualifierParams = {
|
|
49
|
+
secondQualifier: lowerSlab.secondQualifier,
|
|
50
|
+
secondQualifierType: lowerSlab.secondQualifierType,
|
|
51
|
+
discountOn,
|
|
52
|
+
firstQualifier: lowerSlab.firstQualifier,
|
|
53
|
+
thirdQualifier: lowerSlab.thirdQualifier,
|
|
54
|
+
thirdQualifierType: lowerSlab.thirdQualifierType,
|
|
55
|
+
schemePayoutType: payoutType,
|
|
56
|
+
slabConstraint: lowerSlab.constraint,
|
|
57
|
+
};
|
|
58
|
+
if (!(0, qualifier_checks_1.checkIfSecondaryCategoryFilterPassed)(qualifierParams, applicableProducts)) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if ((0, constraint_checks_1.checkSlabConstraint)(compareValue, lowerSlab, payoutType)) {
|
|
62
|
+
const upperSlab = i === slabs.length - 1 ? lowerSlab : slabs[i + 1];
|
|
63
|
+
return { lower: lowerSlab, upper: upperSlab, lowerIndex: i };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=slab-matcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slab-matcher.js","sourceRoot":"","sources":["../../src/calculators/slab-matcher.ts"],"names":[],"mappings":";;AAkCA,4CA4BC;AAOD,wDA8BC;AAhGD,oEAAmE;AACnE,kEAA8G;AAsB9G;;;;;;;GAOG;AACH,SAAgB,gBAAgB,CAAC,MAAyB;IACxD,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAEnF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAEtB,+DAA+D;QAC/D,MAAM,eAAe,GAAyB;YAC5C,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;YAC7C,UAAU;YACV,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;YAC3C,gBAAgB,EAAE,UAAU;YAC5B,cAAc,EAAE,IAAI,CAAC,UAAU;SAChC,CAAC;QAEF,IAAI,CAAC,IAAA,uDAAoC,EAAC,eAAe,EAAE,kBAAkB,CAAC,EAAE,CAAC;YAC/E,SAAS;QACX,CAAC;QAED,IAAI,IAAA,uCAAmB,EAAC,YAAY,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC;YACxD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,SAAgB,sBAAsB,CACpC,MAAyB;IAEzB,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAEnF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAE3B,MAAM,eAAe,GAAyB;YAC5C,eAAe,EAAE,SAAS,CAAC,eAAe;YAC1C,mBAAmB,EAAE,SAAS,CAAC,mBAAmB;YAClD,UAAU;YACV,cAAc,EAAE,SAAS,CAAC,cAAc;YACxC,cAAc,EAAE,SAAS,CAAC,cAAc;YACxC,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;YAChD,gBAAgB,EAAE,UAAU;YAC5B,cAAc,EAAE,SAAS,CAAC,UAAU;SACrC,CAAC;QAEF,IAAI,CAAC,IAAA,uDAAoC,EAAC,eAAe,EAAE,kBAAkB,CAAC,EAAE,CAAC;YAC/E,SAAS;QACX,CAAC;QAED,IAAI,IAAA,uCAAmB,EAAC,YAAY,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC;YAC7D,MAAM,SAAS,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACpE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { SchemeCategory, SchemePayoutType, AdditionalCalculationLogic } from "../types/enums";
|
|
2
|
+
import { calculateDiscount, calculateMarkupDiscount, clampNonNegative, formatPrice } from "../helpers/math";
|
|
3
|
+
import { isFocTypePayoutScheme, isPercentDiscountOnMRPTypePayoutScheme } from "../helpers/payout-type-checks";
|
|
4
|
+
/**
|
|
5
|
+
* Calculate the total primary or secondary discount value from applied schemes.
|
|
6
|
+
* Pure function — returns results without mutating the input.
|
|
7
|
+
*
|
|
8
|
+
* Bug 7 fix: Clamps negative discount values to 0.
|
|
9
|
+
* Bug 5 fix: Returns warning when MRP < price causes zero-out.
|
|
10
|
+
*/
|
|
11
|
+
export function calculateAppliedDiscountValues(input) {
|
|
12
|
+
const { appliedSchemes, baseValue, quantity, freeQty, mrp, price, schemeCategory, useGrossTotalForSuccessiveDiscounts, companyUsesUnitaryProductScheme = false, companyUsesPricingBatchNumberInDms = false, enableBottlerCompanyFlows = false, } = input;
|
|
13
|
+
const isPrimary = schemeCategory === SchemeCategory.PRIMARY;
|
|
14
|
+
const discountKey = isPrimary ? "primaryDiscountValue" : "secondaryDiscountValue";
|
|
15
|
+
const percentKey = isPrimary ? "primaryDiscountPercent" : "secondaryDiscountPercent";
|
|
16
|
+
let tempBaseValue = baseValue;
|
|
17
|
+
let totalDiscount = 0;
|
|
18
|
+
const warnings = [];
|
|
19
|
+
const filtered = appliedSchemes.filter((s) => s.schemeType === schemeCategory);
|
|
20
|
+
for (const scheme of filtered) {
|
|
21
|
+
// Pricing-batch companies may split the same SKU into multiple batches,
|
|
22
|
+
// each with its own discount percent. In those cases we must compute
|
|
23
|
+
// discount values on the batch quantity instead of applying each entry
|
|
24
|
+
// on the full item quantity/baseValue (which would double-count).
|
|
25
|
+
const batchQtyRaw = companyUsesPricingBatchNumberInDms
|
|
26
|
+
? (typeof scheme.remainingQuantity === "number" ? scheme.remainingQuantity : scheme.cases)
|
|
27
|
+
: undefined;
|
|
28
|
+
const batchQty = typeof batchQtyRaw === "number" && batchQtyRaw > 0 ? batchQtyRaw : null;
|
|
29
|
+
const effectiveQty = batchQty ?? quantity;
|
|
30
|
+
const effectivePrice = typeof scheme.price === "number" && scheme.price > 0 ? scheme.price : price;
|
|
31
|
+
const effectiveBaseValue = batchQty ? effectivePrice * effectiveQty : baseValue;
|
|
32
|
+
// Recalculate PerUnit percentages if recalculation data present
|
|
33
|
+
if (scheme.recalculateSchemeData) {
|
|
34
|
+
const recalced = recalculateSchemePercentage(scheme, tempBaseValue);
|
|
35
|
+
if (isPrimary) {
|
|
36
|
+
scheme.primaryDiscountPercent = recalced.discountPercent;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
scheme.secondaryDiscountPercent = recalced.discountPercent;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const currentPercent = scheme[percentKey] || 0;
|
|
43
|
+
let currentValue = 0;
|
|
44
|
+
// Skip: FIXED_DISCOUNT already has value set
|
|
45
|
+
if (scheme.schemePayoutType === SchemePayoutType.FIXED_DISCOUNT) {
|
|
46
|
+
currentValue = scheme[discountKey] || 0;
|
|
47
|
+
}
|
|
48
|
+
// Skip: PRODUCT + unitary scheme
|
|
49
|
+
else if (scheme.schemePayoutType === SchemePayoutType.PRODUCT &&
|
|
50
|
+
companyUsesUnitaryProductScheme) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
// FOC-type schemes
|
|
54
|
+
else if (isFocTypePayoutScheme(scheme.schemePayoutType)) {
|
|
55
|
+
const totalQty = quantity + freeQty;
|
|
56
|
+
if (totalQty > 0) {
|
|
57
|
+
currentValue = (scheme.freeQty * tempBaseValue) / totalQty;
|
|
58
|
+
}
|
|
59
|
+
// Zero out for pricing batch companies
|
|
60
|
+
if ((scheme.schemePayoutType === SchemePayoutType.PRODUCT ||
|
|
61
|
+
scheme.schemePayoutType === SchemePayoutType.FOC ||
|
|
62
|
+
scheme.schemePayoutType === SchemePayoutType.FOC_SLAB) &&
|
|
63
|
+
companyUsesPricingBatchNumberInDms) {
|
|
64
|
+
currentValue = 0;
|
|
65
|
+
if (isPrimary) {
|
|
66
|
+
scheme.primaryDiscountPercent = 0;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
scheme.secondaryDiscountPercent = 0;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// MRP percentage discount
|
|
74
|
+
else if (isPercentDiscountOnMRPTypePayoutScheme(scheme.schemePayoutType) &&
|
|
75
|
+
!enableBottlerCompanyFlows) {
|
|
76
|
+
const discountedPrice = mrp - (mrp * currentPercent) / 100;
|
|
77
|
+
if (discountedPrice < effectivePrice) {
|
|
78
|
+
const rawValue = effectiveBaseValue - discountedPrice * effectiveQty;
|
|
79
|
+
currentValue = clampNonNegative(Number(formatPrice(rawValue)));
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// Bug 5: MRP discount silently zeroes out when MRP < price
|
|
83
|
+
if (isPrimary) {
|
|
84
|
+
scheme.primaryDiscountPercent = 0;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
scheme.secondaryDiscountPercent = 0;
|
|
88
|
+
}
|
|
89
|
+
warnings.push(`MRP discount zeroed out: discountedPrice (${discountedPrice}) >= price (${effectivePrice}) for scheme ${scheme.schemeId}`);
|
|
90
|
+
currentValue = 0;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Markup discount
|
|
94
|
+
else if (scheme.isMarkup) {
|
|
95
|
+
currentValue = calculateMarkupDiscount(tempBaseValue, currentPercent);
|
|
96
|
+
}
|
|
97
|
+
// Default: percentage-based discount
|
|
98
|
+
else {
|
|
99
|
+
currentValue = calculateDiscount(tempBaseValue, currentPercent);
|
|
100
|
+
}
|
|
101
|
+
// Bug 7 fix: Clamp to non-negative
|
|
102
|
+
currentValue = clampNonNegative(currentValue);
|
|
103
|
+
if (isPrimary) {
|
|
104
|
+
scheme.primaryDiscountValue = currentValue;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
scheme.secondaryDiscountValue = currentValue;
|
|
108
|
+
}
|
|
109
|
+
totalDiscount += currentValue;
|
|
110
|
+
if (useGrossTotalForSuccessiveDiscounts) {
|
|
111
|
+
tempBaseValue -= currentValue;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Calculate effective percent
|
|
115
|
+
const effectivePercent = filtered.length === 1
|
|
116
|
+
? filtered[0][percentKey]
|
|
117
|
+
: baseValue > 0
|
|
118
|
+
? (totalDiscount / baseValue) * 100
|
|
119
|
+
: 0;
|
|
120
|
+
return {
|
|
121
|
+
discountValue: totalDiscount,
|
|
122
|
+
discountPercent: effectivePercent || 0,
|
|
123
|
+
clampedToZero: false,
|
|
124
|
+
warnings,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Recalculates perUnit discount percentage based on updated net prices.
|
|
129
|
+
* Pure function – returns new percent, caller decides where to assign.
|
|
130
|
+
*/
|
|
131
|
+
export function recalculateSchemePercentage(scheme, tempBaseValue) {
|
|
132
|
+
if (scheme.schemePayoutType !== SchemePayoutType.PERUNIT || !scheme.recalculateSchemeData) {
|
|
133
|
+
const isPrimary = scheme.schemeType === SchemeCategory.PRIMARY;
|
|
134
|
+
return {
|
|
135
|
+
discountPercent: isPrimary
|
|
136
|
+
? scheme.primaryDiscountPercent
|
|
137
|
+
: scheme.secondaryDiscountPercent,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
const data = scheme.recalculateSchemeData;
|
|
141
|
+
const { discountAmountOfPerUnit, totalTaxPercentage, usesStdUnit, usesSuperUnit, usesAdditionalUnit, compareValue, calculationOnCompleteNumber, additionalCalculationLogic, } = data;
|
|
142
|
+
// Approximate net prices proportional to tempBaseValue
|
|
143
|
+
// The caller should provide more precise values via the recalculateSchemeData
|
|
144
|
+
// For now, derive from the available data
|
|
145
|
+
const quantity = scheme.productId ? 1 : 1; // quantity is per-item
|
|
146
|
+
const netPrice = tempBaseValue ? tempBaseValue / (quantity || 1) : 0;
|
|
147
|
+
// These are rough approximations — the real recalculation happens
|
|
148
|
+
// when the caller sets up properly via RecalculateSchemeData
|
|
149
|
+
let finalNetPrice = netPrice;
|
|
150
|
+
if (usesStdUnit) {
|
|
151
|
+
// The calling code should compute actual stdUnitNetPrice * factor
|
|
152
|
+
finalNetPrice = netPrice;
|
|
153
|
+
}
|
|
154
|
+
else if (usesSuperUnit) {
|
|
155
|
+
finalNetPrice = netPrice;
|
|
156
|
+
}
|
|
157
|
+
else if (usesAdditionalUnit) {
|
|
158
|
+
finalNetPrice = netPrice;
|
|
159
|
+
}
|
|
160
|
+
const discountAmountPreTax = discountAmountOfPerUnit / (1 + totalTaxPercentage / 100);
|
|
161
|
+
let itemDiscountPercent;
|
|
162
|
+
if (additionalCalculationLogic === AdditionalCalculationLogic.DISCOUNT_VALUE_SUBTRACTED_FROM_PRICE) {
|
|
163
|
+
itemDiscountPercent = ((discountAmountPreTax || 0) * 100) / (finalNetPrice || 1);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
itemDiscountPercent = ((discountAmountOfPerUnit ?? 0) / (finalNetPrice || 1)) * 100;
|
|
167
|
+
}
|
|
168
|
+
return { discountPercent: itemDiscountPercent };
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=discount-application.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discount-application.js","sourceRoot":"","sources":["../../../src/calculators/discount-application.ts"],"names":[],"mappings":"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"}
|