@wtree/payload-ecommerce-coupon 3.78.5 → 3.78.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.mjs
CHANGED
|
@@ -422,12 +422,22 @@ const createReferralCodesCollection = (pluginConfig) => {
|
|
|
422
422
|
};
|
|
423
423
|
};
|
|
424
424
|
//#endregion
|
|
425
|
+
//#region src/utilities/roundTo2.ts
|
|
426
|
+
/**
|
|
427
|
+
* Rounds a number to 2 decimal places (standard for monetary values).
|
|
428
|
+
*/
|
|
429
|
+
function roundTo2(value) {
|
|
430
|
+
return Math.round(value * 100) / 100;
|
|
431
|
+
}
|
|
432
|
+
//#endregion
|
|
425
433
|
//#region src/collections/createReferralProgramsCollection.ts
|
|
426
434
|
function toNumber(value) {
|
|
427
435
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
428
436
|
}
|
|
429
|
-
function
|
|
430
|
-
|
|
437
|
+
function normalizeLegacyX100Money(value) {
|
|
438
|
+
if (value == null) return null;
|
|
439
|
+
if (Number.isInteger(value) && Math.abs(value) >= 1e3) return roundTo2(value / 100);
|
|
440
|
+
return value;
|
|
431
441
|
}
|
|
432
442
|
const createReferralProgramsCollection = (pluginConfig) => {
|
|
433
443
|
const { collections, access, adminGroups, referralConfig, integration } = pluginConfig;
|
|
@@ -453,14 +463,14 @@ const createReferralProgramsCollection = (pluginConfig) => {
|
|
|
453
463
|
},
|
|
454
464
|
hooks: { beforeChange: [({ data }) => {
|
|
455
465
|
if (!data.commissionRules || !Array.isArray(data.commissionRules) || data.commissionRules.length === 0) throw new APIError("At least one commission rule is required", 400);
|
|
456
|
-
const maxPartnerCommissionPerOrder = toNumber(data.maxPartnerCommissionPerOrder);
|
|
466
|
+
const maxPartnerCommissionPerOrder = normalizeLegacyX100Money(toNumber(data.maxPartnerCommissionPerOrder));
|
|
457
467
|
if (maxPartnerCommissionPerOrder != null && maxPartnerCommissionPerOrder < 0) throw new APIError("Maximum commission per order for partner must be a non-negative number", 400);
|
|
458
|
-
const maxCustomerDiscountPerOrder = toNumber(data.maxCustomerDiscountPerOrder);
|
|
468
|
+
const maxCustomerDiscountPerOrder = normalizeLegacyX100Money(toNumber(data.maxCustomerDiscountPerOrder));
|
|
459
469
|
if (maxCustomerDiscountPerOrder != null && maxCustomerDiscountPerOrder < 0) throw new APIError("Maximum discount for customer per order must be a non-negative number", 400);
|
|
460
|
-
const minOrderAmount = toNumber(data.minOrderAmount);
|
|
470
|
+
const minOrderAmount = normalizeLegacyX100Money(toNumber(data.minOrderAmount));
|
|
461
471
|
if (minOrderAmount != null && minOrderAmount < 0) throw new APIError("Minimum Order Amount must be a non-negative number", 400);
|
|
462
|
-
data.maxPartnerCommissionPerOrder = maxPartnerCommissionPerOrder != null ?
|
|
463
|
-
data.maxCustomerDiscountPerOrder = maxCustomerDiscountPerOrder != null ?
|
|
472
|
+
data.maxPartnerCommissionPerOrder = maxPartnerCommissionPerOrder != null ? maxPartnerCommissionPerOrder : null;
|
|
473
|
+
data.maxCustomerDiscountPerOrder = maxCustomerDiscountPerOrder != null ? maxCustomerDiscountPerOrder : null;
|
|
464
474
|
data.minOrderAmount = minOrderAmount ?? null;
|
|
465
475
|
data.commissionRules = data.commissionRules.map((rule, index) => {
|
|
466
476
|
const r = rule;
|
|
@@ -491,8 +501,8 @@ const createReferralProgramsCollection = (pluginConfig) => {
|
|
|
491
501
|
partnerSplit = partnerPctInput;
|
|
492
502
|
customerSplit = customerPctComputed;
|
|
493
503
|
} else {
|
|
494
|
-
const partnerAmountInput = toNumber(r.partnerAmount);
|
|
495
|
-
const customerAmountInput = toNumber(r.customerAmount);
|
|
504
|
+
const partnerAmountInput = normalizeLegacyX100Money(toNumber(r.partnerAmount));
|
|
505
|
+
const customerAmountInput = normalizeLegacyX100Money(toNumber(r.customerAmount));
|
|
496
506
|
const legacyPartnerSplitInput = toNumber(r.partnerSplit);
|
|
497
507
|
const legacyCustomerSplitInput = toNumber(r.customerSplit);
|
|
498
508
|
const hasNewFixedInputs = partnerAmountInput != null || customerAmountInput != null;
|
|
@@ -502,8 +512,8 @@ const createReferralProgramsCollection = (pluginConfig) => {
|
|
|
502
512
|
if (customerAmountInput == null || customerAmountInput < 0) throw new APIError(`Commission rule ${index + 1}: Customer fixed amount must be a non-negative number`, 400);
|
|
503
513
|
partnerAmount = partnerAmountInput;
|
|
504
514
|
customerAmount = customerAmountInput;
|
|
505
|
-
partnerSplit =
|
|
506
|
-
customerSplit =
|
|
515
|
+
partnerSplit = partnerAmountInput;
|
|
516
|
+
customerSplit = customerAmountInput;
|
|
507
517
|
} else if (hasLegacyFixedInputs) {
|
|
508
518
|
if (legacyPartnerSplitInput == null || legacyPartnerSplitInput < 0) throw new APIError(`Commission rule ${index + 1}: For fixed commissions, both partner and customer values must be non-negative numbers`, 400);
|
|
509
519
|
const resolvedLegacyCustomerSplit = legacyCustomerSplitInput ?? 100 - legacyPartnerSplitInput;
|
|
@@ -517,7 +527,11 @@ const createReferralProgramsCollection = (pluginConfig) => {
|
|
|
517
527
|
return {
|
|
518
528
|
...rule,
|
|
519
529
|
appliesTo: appliesTo === "categories" ? "segments" : appliesTo,
|
|
520
|
-
totalCommission: {
|
|
530
|
+
totalCommission: {
|
|
531
|
+
type,
|
|
532
|
+
...typeof r.totalCommission.value === "number" ? { value: r.totalCommission.value } : {},
|
|
533
|
+
...typeof r.totalCommission.maxAmount === "number" ? { maxAmount: r.totalCommission.maxAmount } : {}
|
|
534
|
+
},
|
|
521
535
|
partnerPercent,
|
|
522
536
|
customerPercent,
|
|
523
537
|
partnerAmount,
|
|
@@ -546,19 +560,19 @@ const createReferralProgramsCollection = (pluginConfig) => {
|
|
|
546
560
|
name: "maxPartnerCommissionPerOrder",
|
|
547
561
|
type: "number",
|
|
548
562
|
min: 0,
|
|
549
|
-
admin: { description: "Maximum commission per order for partner. Leave empty for no cap.
|
|
563
|
+
admin: { description: "Maximum commission per order for partner (normal currency value, ). Leave empty for no cap." }
|
|
550
564
|
},
|
|
551
565
|
{
|
|
552
566
|
name: "maxCustomerDiscountPerOrder",
|
|
553
567
|
type: "number",
|
|
554
568
|
min: 0,
|
|
555
|
-
admin: { description: "Maximum customer discount per order. Leave empty for no cap.
|
|
569
|
+
admin: { description: "Maximum customer discount per order (normal currency value, ). Leave empty for no cap." }
|
|
556
570
|
},
|
|
557
571
|
{
|
|
558
572
|
name: "minOrderAmount",
|
|
559
573
|
type: "number",
|
|
560
574
|
min: 0,
|
|
561
|
-
admin: { description: "Minimum cart subtotal required for this program. Leave empty for no minimum." }
|
|
575
|
+
admin: { description: "Minimum cart subtotal required for this program (normal currency value, ). Leave empty for no minimum." }
|
|
562
576
|
},
|
|
563
577
|
{
|
|
564
578
|
name: "commissionRules",
|
|
@@ -658,7 +672,7 @@ const createReferralProgramsCollection = (pluginConfig) => {
|
|
|
658
672
|
min: 0,
|
|
659
673
|
admin: {
|
|
660
674
|
condition: (_, siblingData) => siblingData?.totalCommission?.type === "fixed",
|
|
661
|
-
description: "Fixed partner commission amount per item."
|
|
675
|
+
description: "Fixed partner commission amount per item (normal currency value)."
|
|
662
676
|
}
|
|
663
677
|
},
|
|
664
678
|
{
|
|
@@ -667,7 +681,7 @@ const createReferralProgramsCollection = (pluginConfig) => {
|
|
|
667
681
|
min: 0,
|
|
668
682
|
admin: {
|
|
669
683
|
condition: (_, siblingData) => siblingData?.totalCommission?.type === "fixed",
|
|
670
|
-
description: "Fixed customer discount amount per item."
|
|
684
|
+
description: "Fixed customer discount amount per item (normal currency value)."
|
|
671
685
|
}
|
|
672
686
|
},
|
|
673
687
|
{
|
|
@@ -676,7 +690,7 @@ const createReferralProgramsCollection = (pluginConfig) => {
|
|
|
676
690
|
min: 0,
|
|
677
691
|
admin: {
|
|
678
692
|
hidden: true,
|
|
679
|
-
description: "Canonical storage field. Percentage mode: percent. Fixed mode: amount
|
|
693
|
+
description: "Canonical storage field. Percentage mode: percent. Fixed mode: amount."
|
|
680
694
|
}
|
|
681
695
|
},
|
|
682
696
|
{
|
|
@@ -685,7 +699,7 @@ const createReferralProgramsCollection = (pluginConfig) => {
|
|
|
685
699
|
min: 0,
|
|
686
700
|
admin: {
|
|
687
701
|
hidden: true,
|
|
688
|
-
description: "Canonical storage field. Percentage mode: percent. Fixed mode: amount
|
|
702
|
+
description: "Canonical storage field. Percentage mode: percent. Fixed mode: amount."
|
|
689
703
|
}
|
|
690
704
|
}
|
|
691
705
|
]
|
|
@@ -694,14 +708,6 @@ const createReferralProgramsCollection = (pluginConfig) => {
|
|
|
694
708
|
timestamps: true
|
|
695
709
|
};
|
|
696
710
|
};
|
|
697
|
-
//#endregion
|
|
698
|
-
//#region src/utilities/roundTo2.ts
|
|
699
|
-
/**
|
|
700
|
-
* Rounds a number to 2 decimal places (standard for monetary values).
|
|
701
|
-
*/
|
|
702
|
-
function roundTo2(value) {
|
|
703
|
-
return Math.round(value * 100) / 100;
|
|
704
|
-
}
|
|
705
711
|
function normalizeCurrencyCode(currencyCode) {
|
|
706
712
|
if (!currencyCode) return "AED";
|
|
707
713
|
return currencyCode.toUpperCase();
|
|
@@ -792,15 +798,52 @@ function calculateItemRewardByRule({ rule, itemTotal, quantity, allowedTotalComm
|
|
|
792
798
|
customer
|
|
793
799
|
};
|
|
794
800
|
}
|
|
795
|
-
const splits = getRuleSplits(rule);
|
|
796
|
-
if (!splits) return null;
|
|
797
801
|
let totalPot = 0;
|
|
798
|
-
if (rule.totalCommission.type === "percentage")
|
|
799
|
-
|
|
802
|
+
if (rule.totalCommission.type === "percentage") {
|
|
803
|
+
const commissionValue = typeof rule.totalCommission.value === "number" && Number.isFinite(rule.totalCommission.value) ? rule.totalCommission.value : null;
|
|
804
|
+
if (commissionValue == null) {
|
|
805
|
+
const partnerPercentInput = typeof rule.partnerPercent === "number" ? rule.partnerPercent : typeof rule.partnerSplit === "number" ? rule.partnerSplit : null;
|
|
806
|
+
if (partnerPercentInput == null || partnerPercentInput < 0 || partnerPercentInput > 100) return null;
|
|
807
|
+
const customerPercentInput = typeof rule.customerPercent === "number" ? rule.customerPercent : typeof rule.customerSplit === "number" ? rule.customerSplit : 100 - partnerPercentInput;
|
|
808
|
+
if (customerPercentInput == null || customerPercentInput < 0 || customerPercentInput > 100) return null;
|
|
809
|
+
const partner = itemTotal * partnerPercentInput / 100;
|
|
810
|
+
const customer = itemTotal * customerPercentInput / 100;
|
|
811
|
+
if (resolvedMaxAmount != null) {
|
|
812
|
+
const maxPotForLine = resolvedMaxAmount * quantity;
|
|
813
|
+
const totalForLine = partner + customer;
|
|
814
|
+
if (totalForLine > maxPotForLine && totalForLine > 0) {
|
|
815
|
+
const ratio = maxPotForLine / totalForLine;
|
|
816
|
+
return {
|
|
817
|
+
partner: Math.floor(partner * ratio),
|
|
818
|
+
customer: Math.floor(customer * ratio)
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
return {
|
|
823
|
+
partner: Math.floor(partner),
|
|
824
|
+
customer: Math.floor(customer)
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
totalPot = itemTotal * commissionValue / 100;
|
|
828
|
+
} else {
|
|
829
|
+
const splits = getRuleSplits(rule);
|
|
830
|
+
if (!splits) return null;
|
|
831
|
+
totalPot = rule.totalCommission.value * quantity;
|
|
832
|
+
if (resolvedMaxAmount != null) {
|
|
833
|
+
const maxPotForLine = resolvedMaxAmount * quantity;
|
|
834
|
+
if (totalPot > maxPotForLine) totalPot = maxPotForLine;
|
|
835
|
+
}
|
|
836
|
+
return {
|
|
837
|
+
partner: Math.floor(totalPot * splits.partnerSplit / 100),
|
|
838
|
+
customer: Math.floor(totalPot * splits.customerSplit / 100)
|
|
839
|
+
};
|
|
840
|
+
}
|
|
800
841
|
if (resolvedMaxAmount != null) {
|
|
801
842
|
const maxPotForLine = resolvedMaxAmount * quantity;
|
|
802
843
|
if (totalPot > maxPotForLine) totalPot = maxPotForLine;
|
|
803
844
|
}
|
|
845
|
+
const splits = getRuleSplits(rule);
|
|
846
|
+
if (!splits) return null;
|
|
804
847
|
return {
|
|
805
848
|
partner: Math.floor(totalPot * splits.partnerSplit / 100),
|
|
806
849
|
customer: Math.floor(totalPot * splits.customerSplit / 100)
|
|
@@ -885,10 +928,10 @@ function selectBestRuleForItem({ rules, item, itemTotal, quantity, cartTotal, mi
|
|
|
885
928
|
return best;
|
|
886
929
|
}
|
|
887
930
|
function getProgramMinimumOrderAmount({ program, allowedTotalCommissionTypes }) {
|
|
931
|
+
if (typeof program?.minOrderAmount === "number" && Number.isFinite(program.minOrderAmount)) return program.minOrderAmount;
|
|
888
932
|
const rules = Array.isArray(program?.commissionRules) ? program.commissionRules : [];
|
|
889
933
|
if (!rules.length) return null;
|
|
890
934
|
const allowedTypes = allowedCommissionTypesSet(allowedTotalCommissionTypes);
|
|
891
|
-
if (typeof program?.minOrderAmount === "number" && Number.isFinite(program.minOrderAmount)) return program.minOrderAmount;
|
|
892
935
|
const minValues = rules.filter((rule) => {
|
|
893
936
|
if (rule?.totalCommission?.type) return allowedTypes.has(rule.totalCommission.type);
|
|
894
937
|
return true;
|