@wtree/payload-ecommerce-coupon 3.78.2 → 3.78.4
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/README.md +33 -6
- package/dist/client/hooks.d.ts +1 -1
- package/dist/client/hooks.d.ts.map +1 -1
- package/dist/client/index.d.ts +8 -8
- package/dist/client/index.d.ts.map +1 -1
- package/dist/collections/createCouponsCollection.d.ts +2 -2
- package/dist/collections/createCouponsCollection.d.ts.map +1 -1
- package/dist/collections/createReferralCodesCollection.d.ts +2 -2
- package/dist/collections/createReferralCodesCollection.d.ts.map +1 -1
- package/dist/collections/createReferralProgramsCollection.d.ts +2 -2
- package/dist/collections/createReferralProgramsCollection.d.ts.map +1 -1
- package/dist/components/PartnerDashboard/CommissionBreakdown.d.ts +2 -2
- package/dist/components/PartnerDashboard/CommissionBreakdown.d.ts.map +1 -1
- package/dist/components/PartnerDashboard/EarningsSummary.d.ts +2 -2
- package/dist/components/PartnerDashboard/EarningsSummary.d.ts.map +1 -1
- package/dist/components/PartnerDashboard/ProgramOverview.d.ts +3 -3
- package/dist/components/PartnerDashboard/ProgramOverview.d.ts.map +1 -1
- package/dist/components/PartnerDashboard/RecentReferrals.d.ts +3 -3
- package/dist/components/PartnerDashboard/RecentReferrals.d.ts.map +1 -1
- package/dist/components/PartnerDashboard/ReferralCodes.d.ts +3 -3
- package/dist/components/PartnerDashboard/ReferralCodes.d.ts.map +1 -1
- package/dist/components/PartnerDashboard/ReferralPerformance.d.ts +2 -2
- package/dist/components/PartnerDashboard/ReferralPerformance.d.ts.map +1 -1
- package/dist/components/PartnerDashboard/index.d.ts +1 -1
- package/dist/components/PartnerDashboard/index.d.ts.map +1 -1
- package/dist/endpoints/applyCoupon.d.ts +2 -2
- package/dist/endpoints/applyCoupon.d.ts.map +1 -1
- package/dist/endpoints/partnerStats.d.ts +2 -2
- package/dist/endpoints/partnerStats.d.ts.map +1 -1
- package/dist/endpoints/validateCoupon.d.ts +2 -2
- package/dist/endpoints/validateCoupon.d.ts.map +1 -1
- package/dist/hooks/recalculateCart.d.ts +2 -2
- package/dist/hooks/recalculateCart.d.ts.map +1 -1
- package/dist/index.d.ts +17 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +158 -54
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +122 -18
- package/dist/index.mjs.map +1 -1
- package/dist/plugin.d.ts +2 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/types.d.ts +4 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/utilities/calculateValues.d.ts +2 -2
- package/dist/utilities/calculateValues.d.ts.map +1 -1
- package/dist/utilities/getCartTotalWithDiscounts.d.ts.map +1 -1
- package/dist/utilities/migrateReferralRulesV2.d.ts.map +1 -1
- package/dist/utilities/pricing.d.ts.map +1 -1
- package/dist/utilities/pushTypeScriptProperties.d.ts +1 -1
- package/dist/utilities/pushTypeScriptProperties.d.ts.map +1 -1
- package/dist/utilities/recordCouponUsageForOrder.d.ts +2 -2
- package/dist/utilities/recordCouponUsageForOrder.d.ts.map +1 -1
- package/dist/utilities/sanitizePluginConfig.d.ts +1 -1
- package/dist/utilities/sanitizePluginConfig.d.ts.map +1 -1
- package/dist/utilities/userRoles.d.ts +3 -3
- package/dist/utilities/userRoles.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -454,11 +454,14 @@ const createReferralProgramsCollection = (pluginConfig) => {
|
|
|
454
454
|
},
|
|
455
455
|
hooks: { beforeChange: [({ data }) => {
|
|
456
456
|
if (!data.commissionRules || !Array.isArray(data.commissionRules) || data.commissionRules.length === 0) throw new payload.APIError("At least one commission rule is required", 400);
|
|
457
|
-
const
|
|
458
|
-
if (
|
|
457
|
+
const maxPartnerCommissionPerOrder = toNumber(data.maxPartnerCommissionPerOrder);
|
|
458
|
+
if (maxPartnerCommissionPerOrder != null && maxPartnerCommissionPerOrder < 0) throw new payload.APIError("Maximum commission per order for partner must be a non-negative number", 400);
|
|
459
|
+
const maxCustomerDiscountPerOrder = toNumber(data.maxCustomerDiscountPerOrder);
|
|
460
|
+
if (maxCustomerDiscountPerOrder != null && maxCustomerDiscountPerOrder < 0) throw new payload.APIError("Maximum discount for customer per order must be a non-negative number", 400);
|
|
459
461
|
const minOrderAmount = toNumber(data.minOrderAmount);
|
|
460
462
|
if (minOrderAmount != null && minOrderAmount < 0) throw new payload.APIError("Minimum Order Amount must be a non-negative number", 400);
|
|
461
|
-
data.
|
|
463
|
+
data.maxPartnerCommissionPerOrder = maxPartnerCommissionPerOrder != null ? toCents(maxPartnerCommissionPerOrder) : null;
|
|
464
|
+
data.maxCustomerDiscountPerOrder = maxCustomerDiscountPerOrder != null ? toCents(maxCustomerDiscountPerOrder) : null;
|
|
462
465
|
data.minOrderAmount = minOrderAmount ?? null;
|
|
463
466
|
data.commissionRules = data.commissionRules.map((rule, index) => {
|
|
464
467
|
const r = rule;
|
|
@@ -541,10 +544,16 @@ const createReferralProgramsCollection = (pluginConfig) => {
|
|
|
541
544
|
admin: { description: "Whether this referral program is currently active" }
|
|
542
545
|
},
|
|
543
546
|
{
|
|
544
|
-
name: "
|
|
547
|
+
name: "maxPartnerCommissionPerOrder",
|
|
545
548
|
type: "number",
|
|
546
549
|
min: 0,
|
|
547
|
-
admin: { description: "Maximum commission
|
|
550
|
+
admin: { description: "Maximum commission per order for partner. Leave empty for no cap. Enter value in currency units (will be converted to cents)." }
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
name: "maxCustomerDiscountPerOrder",
|
|
554
|
+
type: "number",
|
|
555
|
+
min: 0,
|
|
556
|
+
admin: { description: "Maximum customer discount per order. Leave empty for no cap. Enter value in currency units (will be converted to cents)." }
|
|
548
557
|
},
|
|
549
558
|
{
|
|
550
559
|
name: "minOrderAmount",
|
|
@@ -759,11 +768,11 @@ function getRuleSplits(rule) {
|
|
|
759
768
|
customerSplit: typeof rule.customerSplit === "number" ? rule.customerSplit : typeof rule.refereeSplit === "number" ? rule.refereeSplit : 100 - partnerRaw
|
|
760
769
|
};
|
|
761
770
|
}
|
|
762
|
-
function calculateItemRewardByRule({ rule, itemTotal, quantity,
|
|
771
|
+
function calculateItemRewardByRule({ rule, itemTotal, quantity, allowedTotalCommissionTypes }) {
|
|
763
772
|
const allowedTypes = allowedCommissionTypesSet(allowedTotalCommissionTypes);
|
|
764
773
|
if (rule.totalCommission) {
|
|
765
774
|
if (!allowedTypes.has(rule.totalCommission.type)) return null;
|
|
766
|
-
const resolvedMaxAmount = typeof
|
|
775
|
+
const resolvedMaxAmount = typeof rule.totalCommission.maxAmount === "number" && Number.isFinite(rule.totalCommission.maxAmount) ? rule.totalCommission.maxAmount : null;
|
|
767
776
|
if (rule.totalCommission.type === "fixed" && rule.totalCommission.value == null) {
|
|
768
777
|
const partnerAmtPerUnit = typeof rule.partnerSplit === "number" ? rule.partnerSplit : null;
|
|
769
778
|
const customerAmtPerUnit = typeof rule.customerSplit === "number" ? rule.customerSplit : null;
|
|
@@ -822,7 +831,7 @@ function getItemCategoryIds(item) {
|
|
|
822
831
|
function getItemTagIds(item) {
|
|
823
832
|
return Array.isArray(item?.product?.tags) ? normalizeIds(item.product.tags) : [];
|
|
824
833
|
}
|
|
825
|
-
function selectBestRuleForItem({ rules, item, itemTotal, quantity, cartTotal, minOrderAmount,
|
|
834
|
+
function selectBestRuleForItem({ rules, item, itemTotal, quantity, cartTotal, minOrderAmount, allowedTotalCommissionTypes }) {
|
|
826
835
|
const allowedTypes = allowedCommissionTypesSet(allowedTotalCommissionTypes);
|
|
827
836
|
const eligibleRules = rules.filter((rule) => {
|
|
828
837
|
if (!(rule?.totalCommission?.type ? allowedTypes.has(rule.totalCommission.type) : true)) return false;
|
|
@@ -852,7 +861,6 @@ function selectBestRuleForItem({ rules, item, itemTotal, quantity, cartTotal, mi
|
|
|
852
861
|
rule,
|
|
853
862
|
itemTotal,
|
|
854
863
|
quantity,
|
|
855
|
-
maxAmount,
|
|
856
864
|
allowedTotalCommissionTypes
|
|
857
865
|
});
|
|
858
866
|
if (!reward) continue;
|
|
@@ -917,13 +925,16 @@ function calculateCommissionAndDiscount({ cartItems, program, currencyCode = "AE
|
|
|
917
925
|
quantity,
|
|
918
926
|
cartTotal,
|
|
919
927
|
minOrderAmount: typeof program?.minOrderAmount === "number" && Number.isFinite(program.minOrderAmount) ? program.minOrderAmount : null,
|
|
920
|
-
maxAmount: typeof program?.maxAmount === "number" && Number.isFinite(program.maxAmount) ? program.maxAmount : null,
|
|
921
928
|
allowedTotalCommissionTypes
|
|
922
929
|
});
|
|
923
930
|
if (!bestMatch) continue;
|
|
924
931
|
totalPartnerCommission += bestMatch.reward.partner;
|
|
925
932
|
totalCustomerDiscount += bestMatch.reward.customer;
|
|
926
933
|
}
|
|
934
|
+
const maxPartnerCommissionPerOrder = typeof program?.maxPartnerCommissionPerOrder === "number" && Number.isFinite(program.maxPartnerCommissionPerOrder) ? program.maxPartnerCommissionPerOrder : null;
|
|
935
|
+
const maxCustomerDiscountPerOrder = typeof program?.maxCustomerDiscountPerOrder === "number" && Number.isFinite(program.maxCustomerDiscountPerOrder) ? program.maxCustomerDiscountPerOrder : null;
|
|
936
|
+
if (maxPartnerCommissionPerOrder != null) totalPartnerCommission = Math.min(totalPartnerCommission, maxPartnerCommissionPerOrder);
|
|
937
|
+
if (maxCustomerDiscountPerOrder != null) totalCustomerDiscount = Math.min(totalCustomerDiscount, maxCustomerDiscountPerOrder);
|
|
927
938
|
return {
|
|
928
939
|
partnerCommission: totalPartnerCommission,
|
|
929
940
|
customerDiscount: totalCustomerDiscount
|
|
@@ -947,38 +958,56 @@ function writeField$1(doc, field, value) {
|
|
|
947
958
|
function normalizeCode$1(value) {
|
|
948
959
|
return typeof value === "string" ? value.trim().toUpperCase() : "";
|
|
949
960
|
}
|
|
950
|
-
async function
|
|
951
|
-
|
|
961
|
+
async function ensureRequestData$1(req) {
|
|
962
|
+
if (req?.data && typeof req.data === "object") return req.data;
|
|
963
|
+
try {
|
|
964
|
+
await (0, payload.addDataAndFileToRequest)(req);
|
|
965
|
+
} catch {}
|
|
966
|
+
if (req?.data && typeof req.data === "object") return req.data;
|
|
967
|
+
try {
|
|
968
|
+
const parsed = await req?.json?.();
|
|
969
|
+
if (parsed && typeof parsed === "object") {
|
|
970
|
+
req.data = parsed;
|
|
971
|
+
return parsed;
|
|
972
|
+
}
|
|
973
|
+
} catch {}
|
|
974
|
+
req.data = {};
|
|
975
|
+
return req.data;
|
|
976
|
+
}
|
|
977
|
+
async function findByNormalizedCode$1({ payload: payload$5, collection, normalizedCode }) {
|
|
978
|
+
const exactQuery = await payload$5.find({
|
|
952
979
|
collection,
|
|
953
980
|
where: { normalizedCode: { equals: normalizedCode } },
|
|
954
981
|
limit: 1
|
|
955
982
|
});
|
|
956
983
|
if (exactQuery?.docs?.[0]) return exactQuery.docs[0];
|
|
957
|
-
const lowerQuery = await payload.find({
|
|
984
|
+
const lowerQuery = await payload$5.find({
|
|
958
985
|
collection,
|
|
959
986
|
where: { code: { equals: normalizedCode.toLowerCase() } },
|
|
960
987
|
limit: 1
|
|
961
988
|
});
|
|
962
989
|
if (lowerQuery?.docs?.[0]) return lowerQuery.docs[0];
|
|
963
|
-
const upperQuery = await payload.find({
|
|
990
|
+
const upperQuery = await payload$5.find({
|
|
964
991
|
collection,
|
|
965
992
|
where: { code: { equals: normalizedCode.toUpperCase() } },
|
|
966
993
|
limit: 1
|
|
967
994
|
});
|
|
968
995
|
if (upperQuery?.docs?.[0]) return upperQuery.docs[0];
|
|
969
|
-
return (await payload.find({
|
|
996
|
+
return (await payload$5.find({
|
|
970
997
|
collection,
|
|
971
998
|
where: { code: { equals: normalizedCode } },
|
|
972
999
|
limit: 1
|
|
973
1000
|
}))?.docs?.[0] ?? null;
|
|
974
1001
|
}
|
|
975
1002
|
const applyCouponHandler = ({ pluginConfig }) => async (req) => {
|
|
976
|
-
const { payload } = req;
|
|
1003
|
+
const { payload: payload$6 } = req;
|
|
977
1004
|
const fields = pluginConfig.integration.fields;
|
|
978
1005
|
const collections = pluginConfig.integration.collections;
|
|
979
|
-
const
|
|
980
|
-
const
|
|
981
|
-
const
|
|
1006
|
+
const data = await ensureRequestData$1(req);
|
|
1007
|
+
const rawCode = data?.code;
|
|
1008
|
+
const cartIDRaw = data?.cartID;
|
|
1009
|
+
const cartID = typeof cartIDRaw === "string" || typeof cartIDRaw === "number" ? cartIDRaw : null;
|
|
1010
|
+
const customerEmail = typeof data?.customerEmail === "string" ? data.customerEmail : void 0;
|
|
982
1011
|
const normalizedCode = normalizeCode$1(rawCode);
|
|
983
1012
|
if (!normalizedCode || !cartID) return Response.json({
|
|
984
1013
|
success: false,
|
|
@@ -987,19 +1016,19 @@ const applyCouponHandler = ({ pluginConfig }) => async (req) => {
|
|
|
987
1016
|
const allowCoupon = await Promise.resolve(pluginConfig.policies.canApplyCoupon({
|
|
988
1017
|
req,
|
|
989
1018
|
user: req?.user,
|
|
990
|
-
payload
|
|
1019
|
+
payload: payload$6
|
|
991
1020
|
}));
|
|
992
1021
|
const allowReferral = await Promise.resolve(pluginConfig.policies.canApplyReferral({
|
|
993
1022
|
req,
|
|
994
1023
|
user: req?.user,
|
|
995
|
-
payload
|
|
1024
|
+
payload: payload$6
|
|
996
1025
|
}));
|
|
997
1026
|
if (!allowCoupon && !(pluginConfig.enableReferrals && allowReferral)) return Response.json({
|
|
998
1027
|
success: false,
|
|
999
1028
|
error: "Forbidden"
|
|
1000
1029
|
}, { status: 403 });
|
|
1001
1030
|
try {
|
|
1002
|
-
const cart = await payload.findByID({
|
|
1031
|
+
const cart = await payload$6.findByID({
|
|
1003
1032
|
collection: collections.cartsSlug,
|
|
1004
1033
|
id: cartID,
|
|
1005
1034
|
depth: 2
|
|
@@ -1016,14 +1045,14 @@ const applyCouponHandler = ({ pluginConfig }) => async (req) => {
|
|
|
1016
1045
|
}, { status: 400 });
|
|
1017
1046
|
if (pluginConfig.enableReferrals && allowReferral) {
|
|
1018
1047
|
const referralResult = await handleReferralCode({
|
|
1019
|
-
payload,
|
|
1048
|
+
payload: payload$6,
|
|
1020
1049
|
cart,
|
|
1021
1050
|
cartID,
|
|
1022
1051
|
normalizedCode,
|
|
1023
1052
|
pluginConfig
|
|
1024
1053
|
});
|
|
1025
1054
|
if (!referralResult.ok && referralResult.status === 404 && pluginConfig.referralConfig.allowBothSystems && allowCoupon) return await handleCouponCode({
|
|
1026
|
-
payload,
|
|
1055
|
+
payload: payload$6,
|
|
1027
1056
|
cart,
|
|
1028
1057
|
cartID,
|
|
1029
1058
|
normalizedCode,
|
|
@@ -1037,7 +1066,7 @@ const applyCouponHandler = ({ pluginConfig }) => async (req) => {
|
|
|
1037
1066
|
error: "Forbidden"
|
|
1038
1067
|
}, { status: 403 });
|
|
1039
1068
|
return await handleCouponCode({
|
|
1040
|
-
payload,
|
|
1069
|
+
payload: payload$6,
|
|
1041
1070
|
cart,
|
|
1042
1071
|
cartID,
|
|
1043
1072
|
normalizedCode,
|
|
@@ -1052,11 +1081,11 @@ const applyCouponHandler = ({ pluginConfig }) => async (req) => {
|
|
|
1052
1081
|
}, { status: 500 });
|
|
1053
1082
|
}
|
|
1054
1083
|
};
|
|
1055
|
-
async function handleCouponCode({ payload, cart, cartID, normalizedCode, customerEmail, pluginConfig }) {
|
|
1084
|
+
async function handleCouponCode({ payload: payload$7, cart, cartID, normalizedCode, customerEmail, pluginConfig }) {
|
|
1056
1085
|
const fields = pluginConfig.integration.fields;
|
|
1057
1086
|
const resolvers = pluginConfig.integration.resolvers;
|
|
1058
1087
|
const coupon = await findByNormalizedCode$1({
|
|
1059
|
-
payload,
|
|
1088
|
+
payload: payload$7,
|
|
1060
1089
|
collection: pluginConfig.collections.couponsSlug,
|
|
1061
1090
|
normalizedCode
|
|
1062
1091
|
});
|
|
@@ -1085,7 +1114,7 @@ async function handleCouponCode({ payload, cart, cartID, normalizedCode, custome
|
|
|
1085
1114
|
success: false,
|
|
1086
1115
|
error: "Customer email is required for this coupon."
|
|
1087
1116
|
}, { status: 400 });
|
|
1088
|
-
if ((await payload.find({
|
|
1117
|
+
if ((await payload$7.find({
|
|
1089
1118
|
collection: pluginConfig.orderIntegration.ordersSlug,
|
|
1090
1119
|
where: { and: [
|
|
1091
1120
|
{ [fields.orderAppliedCouponField]: { equals: coupon.id } },
|
|
@@ -1121,7 +1150,7 @@ async function handleCouponCode({ payload, cart, cartID, normalizedCode, custome
|
|
|
1121
1150
|
writeField$1(data, fields.cartAppliedCouponField, coupon.id);
|
|
1122
1151
|
writeField$1(data, fields.cartDiscountAmountField, discountAmount);
|
|
1123
1152
|
writeField$1(data, fields.cartTotalField, nextTotal);
|
|
1124
|
-
await payload.update({
|
|
1153
|
+
await payload$7.update({
|
|
1125
1154
|
collection: pluginConfig.integration.collections.cartsSlug,
|
|
1126
1155
|
id: cartID,
|
|
1127
1156
|
data
|
|
@@ -1138,11 +1167,11 @@ async function handleCouponCode({ payload, cart, cartID, normalizedCode, custome
|
|
|
1138
1167
|
currency: pluginConfig.defaultCurrency
|
|
1139
1168
|
});
|
|
1140
1169
|
}
|
|
1141
|
-
async function handleReferralCode({ payload, cart, cartID, normalizedCode, pluginConfig }) {
|
|
1170
|
+
async function handleReferralCode({ payload: payload$8, cart, cartID, normalizedCode, pluginConfig }) {
|
|
1142
1171
|
const fields = pluginConfig.integration.fields;
|
|
1143
1172
|
const resolvers = pluginConfig.integration.resolvers;
|
|
1144
1173
|
const referralCode = await findByNormalizedCode$1({
|
|
1145
|
-
payload,
|
|
1174
|
+
payload: payload$8,
|
|
1146
1175
|
collection: pluginConfig.collections.referralCodesSlug,
|
|
1147
1176
|
normalizedCode
|
|
1148
1177
|
});
|
|
@@ -1163,7 +1192,7 @@ async function handleReferralCode({ payload, cart, cartID, normalizedCode, plugi
|
|
|
1163
1192
|
error: "Referral code usage limit exceeded"
|
|
1164
1193
|
}, { status: 400 });
|
|
1165
1194
|
const programId = typeof referralCode.program === "string" || typeof referralCode.program === "number" ? referralCode.program : referralCode.program?.id;
|
|
1166
|
-
const program = await payload.findByID({
|
|
1195
|
+
const program = await payload$8.findByID({
|
|
1167
1196
|
collection: pluginConfig.collections.referralProgramsSlug,
|
|
1168
1197
|
id: programId
|
|
1169
1198
|
});
|
|
@@ -1200,7 +1229,7 @@ async function handleReferralCode({ payload, cart, cartID, normalizedCode, plugi
|
|
|
1200
1229
|
writeField$1(data, fields.cartPartnerCommissionField, roundedPartnerCommission);
|
|
1201
1230
|
writeField$1(data, fields.cartCustomerDiscountField, roundedCustomerDiscount);
|
|
1202
1231
|
writeField$1(data, fields.cartTotalField, nextTotal);
|
|
1203
|
-
await payload.update({
|
|
1232
|
+
await payload$8.update({
|
|
1204
1233
|
collection: pluginConfig.integration.collections.cartsSlug,
|
|
1205
1234
|
id: cartID,
|
|
1206
1235
|
data
|
|
@@ -1407,37 +1436,55 @@ function relationId$2(value) {
|
|
|
1407
1436
|
function normalizeCode(value) {
|
|
1408
1437
|
return typeof value === "string" ? value.trim().toUpperCase() : "";
|
|
1409
1438
|
}
|
|
1410
|
-
async function
|
|
1411
|
-
|
|
1439
|
+
async function ensureRequestData(req) {
|
|
1440
|
+
if (req?.data && typeof req.data === "object") return req.data;
|
|
1441
|
+
try {
|
|
1442
|
+
await (0, payload.addDataAndFileToRequest)(req);
|
|
1443
|
+
} catch {}
|
|
1444
|
+
if (req?.data && typeof req.data === "object") return req.data;
|
|
1445
|
+
try {
|
|
1446
|
+
const parsed = await req?.json?.();
|
|
1447
|
+
if (parsed && typeof parsed === "object") {
|
|
1448
|
+
req.data = parsed;
|
|
1449
|
+
return parsed;
|
|
1450
|
+
}
|
|
1451
|
+
} catch {}
|
|
1452
|
+
req.data = {};
|
|
1453
|
+
return req.data;
|
|
1454
|
+
}
|
|
1455
|
+
async function findByNormalizedCode({ payload: payload$1, collection, normalizedCode }) {
|
|
1456
|
+
const normalizedQuery = await payload$1.find({
|
|
1412
1457
|
collection,
|
|
1413
1458
|
where: { normalizedCode: { equals: normalizedCode } },
|
|
1414
1459
|
limit: 1
|
|
1415
1460
|
});
|
|
1416
1461
|
if (normalizedQuery?.docs?.length) return normalizedQuery.docs[0];
|
|
1417
|
-
const lowerQuery = await payload.find({
|
|
1462
|
+
const lowerQuery = await payload$1.find({
|
|
1418
1463
|
collection,
|
|
1419
1464
|
where: { code: { equals: normalizedCode.toLowerCase() } },
|
|
1420
1465
|
limit: 1
|
|
1421
1466
|
});
|
|
1422
1467
|
if (lowerQuery?.docs?.length) return lowerQuery.docs[0];
|
|
1423
|
-
const upperQuery = await payload.find({
|
|
1468
|
+
const upperQuery = await payload$1.find({
|
|
1424
1469
|
collection,
|
|
1425
1470
|
where: { code: { equals: normalizedCode.toUpperCase() } },
|
|
1426
1471
|
limit: 1
|
|
1427
1472
|
});
|
|
1428
1473
|
if (upperQuery?.docs?.length) return upperQuery.docs[0];
|
|
1429
|
-
return (await payload.find({
|
|
1474
|
+
return (await payload$1.find({
|
|
1430
1475
|
collection,
|
|
1431
1476
|
where: { code: { equals: normalizedCode } },
|
|
1432
1477
|
limit: 1
|
|
1433
1478
|
}))?.docs?.[0] ?? null;
|
|
1434
1479
|
}
|
|
1435
1480
|
const validateCouponHandler = ({ pluginConfig }) => async (req) => {
|
|
1436
|
-
const { payload } = req;
|
|
1437
|
-
const
|
|
1438
|
-
const
|
|
1439
|
-
const
|
|
1440
|
-
const
|
|
1481
|
+
const { payload: payload$2 } = req;
|
|
1482
|
+
const data = await ensureRequestData(req);
|
|
1483
|
+
const rawCode = data?.code;
|
|
1484
|
+
const cartValue = typeof data?.cartValue === "number" ? data.cartValue : void 0;
|
|
1485
|
+
const cartIDRaw = data?.cartID;
|
|
1486
|
+
const cartID = typeof cartIDRaw === "string" || typeof cartIDRaw === "number" ? cartIDRaw : void 0;
|
|
1487
|
+
const customerEmail = typeof data?.customerEmail === "string" ? data.customerEmail : void 0;
|
|
1441
1488
|
const normalizedCode = normalizeCode(rawCode);
|
|
1442
1489
|
if (!normalizedCode) return Response.json({
|
|
1443
1490
|
success: false,
|
|
@@ -1448,13 +1495,13 @@ const validateCouponHandler = ({ pluginConfig }) => async (req) => {
|
|
|
1448
1495
|
if (!await Promise.resolve(pluginConfig.policies.canApplyReferral({
|
|
1449
1496
|
req,
|
|
1450
1497
|
user: req?.user,
|
|
1451
|
-
payload
|
|
1498
|
+
payload: payload$2
|
|
1452
1499
|
}))) return Response.json({
|
|
1453
1500
|
success: false,
|
|
1454
1501
|
error: "Forbidden"
|
|
1455
1502
|
}, { status: 403 });
|
|
1456
1503
|
return await validateReferralCode({
|
|
1457
|
-
payload,
|
|
1504
|
+
payload: payload$2,
|
|
1458
1505
|
normalizedCode,
|
|
1459
1506
|
cartID,
|
|
1460
1507
|
pluginConfig
|
|
@@ -1463,13 +1510,13 @@ const validateCouponHandler = ({ pluginConfig }) => async (req) => {
|
|
|
1463
1510
|
if (!await Promise.resolve(pluginConfig.policies.canApplyCoupon({
|
|
1464
1511
|
req,
|
|
1465
1512
|
user: req?.user,
|
|
1466
|
-
payload
|
|
1513
|
+
payload: payload$2
|
|
1467
1514
|
}))) return Response.json({
|
|
1468
1515
|
success: false,
|
|
1469
1516
|
error: "Forbidden"
|
|
1470
1517
|
}, { status: 403 });
|
|
1471
1518
|
return await validateCouponCode$1({
|
|
1472
|
-
payload,
|
|
1519
|
+
payload: payload$2,
|
|
1473
1520
|
normalizedCode,
|
|
1474
1521
|
cartValue,
|
|
1475
1522
|
customerEmail,
|
|
@@ -1483,10 +1530,10 @@ const validateCouponHandler = ({ pluginConfig }) => async (req) => {
|
|
|
1483
1530
|
}, { status: 500 });
|
|
1484
1531
|
}
|
|
1485
1532
|
};
|
|
1486
|
-
async function validateCouponCode$1({ payload, normalizedCode, cartValue, customerEmail, pluginConfig }) {
|
|
1533
|
+
async function validateCouponCode$1({ payload: payload$3, normalizedCode, cartValue, customerEmail, pluginConfig }) {
|
|
1487
1534
|
const fields = pluginConfig.integration.fields;
|
|
1488
1535
|
const couponData = await findByNormalizedCode({
|
|
1489
|
-
payload,
|
|
1536
|
+
payload: payload$3,
|
|
1490
1537
|
collection: pluginConfig.collections.couponsSlug,
|
|
1491
1538
|
normalizedCode
|
|
1492
1539
|
});
|
|
@@ -1511,7 +1558,7 @@ async function validateCouponCode$1({ payload, normalizedCode, cartValue, custom
|
|
|
1511
1558
|
}, { status: 400 });
|
|
1512
1559
|
if (couponData.perCustomerLimit != null && couponData.perCustomerLimit > 0 && typeof customerEmail === "string" && customerEmail.trim().length > 0) {
|
|
1513
1560
|
const email = customerEmail.trim();
|
|
1514
|
-
if ((await payload.find({
|
|
1561
|
+
if ((await payload$3.find({
|
|
1515
1562
|
collection: pluginConfig.orderIntegration.ordersSlug,
|
|
1516
1563
|
where: { and: [
|
|
1517
1564
|
{ [fields.orderAppliedCouponField]: { equals: couponData.id } },
|
|
@@ -1558,11 +1605,11 @@ async function validateCouponCode$1({ payload, normalizedCode, cartValue, custom
|
|
|
1558
1605
|
currency: pluginConfig.defaultCurrency
|
|
1559
1606
|
});
|
|
1560
1607
|
}
|
|
1561
|
-
async function validateReferralCode({ payload, normalizedCode, cartID, pluginConfig }) {
|
|
1608
|
+
async function validateReferralCode({ payload: payload$4, normalizedCode, cartID, pluginConfig }) {
|
|
1562
1609
|
const collections = pluginConfig.integration.collections;
|
|
1563
1610
|
const resolvers = pluginConfig.integration.resolvers;
|
|
1564
1611
|
const referralData = await findByNormalizedCode({
|
|
1565
|
-
payload,
|
|
1612
|
+
payload: payload$4,
|
|
1566
1613
|
collection: pluginConfig.collections.referralCodesSlug,
|
|
1567
1614
|
normalizedCode
|
|
1568
1615
|
});
|
|
@@ -1587,7 +1634,7 @@ async function validateReferralCode({ payload, normalizedCode, cartID, pluginCon
|
|
|
1587
1634
|
success: false,
|
|
1588
1635
|
error: "Referral program not found"
|
|
1589
1636
|
}, { status: 404 });
|
|
1590
|
-
const program = await payload.findByID({
|
|
1637
|
+
const program = await payload$4.findByID({
|
|
1591
1638
|
collection: pluginConfig.collections.referralProgramsSlug,
|
|
1592
1639
|
id: programId
|
|
1593
1640
|
});
|
|
@@ -1595,7 +1642,7 @@ async function validateReferralCode({ payload, normalizedCode, cartID, pluginCon
|
|
|
1595
1642
|
success: false,
|
|
1596
1643
|
error: "Referral program is not active"
|
|
1597
1644
|
}, { status: 400 });
|
|
1598
|
-
const cart = cartID ? await payload.findByID({
|
|
1645
|
+
const cart = cartID ? await payload$4.findByID({
|
|
1599
1646
|
collection: collections.cartsSlug,
|
|
1600
1647
|
id: cartID,
|
|
1601
1648
|
depth: 2
|
|
@@ -2132,6 +2179,55 @@ const sanitizePluginConfig = ({ pluginConfig }) => {
|
|
|
2132
2179
|
const RECALCULATE_HOOK_KEY = "__payloadEcommerceCouponRecalculateHook__";
|
|
2133
2180
|
const asArray = (value) => Array.isArray(value) ? value : [];
|
|
2134
2181
|
const hasNamedField = (collection, fieldName) => asArray(collection.fields).some((f) => f?.name === fieldName);
|
|
2182
|
+
const normalizePath$1 = (path) => {
|
|
2183
|
+
if (!path) return "/";
|
|
2184
|
+
return (path.startsWith("/") ? path : `/${path}`).replace(/\/+$/, "") || "/";
|
|
2185
|
+
};
|
|
2186
|
+
const toCollectionEndpointPath = ({ endpointPath, collectionSlug }) => {
|
|
2187
|
+
const normalizedEndpointPath = normalizePath$1(endpointPath);
|
|
2188
|
+
const normalizedCollectionPath = normalizePath$1(`/${collectionSlug}`);
|
|
2189
|
+
if (!normalizedEndpointPath.startsWith(`${normalizedCollectionPath}/`)) return null;
|
|
2190
|
+
const relative = normalizedEndpointPath.slice(normalizedCollectionPath.length);
|
|
2191
|
+
return relative.startsWith("/") ? relative : `/${relative}`;
|
|
2192
|
+
};
|
|
2193
|
+
const ensureCouponCollectionEndpoints = ({ collection, pluginConfig }) => {
|
|
2194
|
+
const couponsSlug = pluginConfig.collections.couponsSlug;
|
|
2195
|
+
const applyPath = toCollectionEndpointPath({
|
|
2196
|
+
endpointPath: pluginConfig.endpoints.applyCoupon,
|
|
2197
|
+
collectionSlug: couponsSlug
|
|
2198
|
+
});
|
|
2199
|
+
const validatePath = toCollectionEndpointPath({
|
|
2200
|
+
endpointPath: pluginConfig.endpoints.validateCoupon,
|
|
2201
|
+
collectionSlug: couponsSlug
|
|
2202
|
+
});
|
|
2203
|
+
if (!applyPath && !validatePath) return collection;
|
|
2204
|
+
const endpoints = asArray(collection.endpoints);
|
|
2205
|
+
const endpointKeys = new Set(endpoints.map((e) => `${(e?.method || "get").toLowerCase()}:${e?.path || ""}`));
|
|
2206
|
+
if (validatePath) {
|
|
2207
|
+
const validateKey = `post:${validatePath}`;
|
|
2208
|
+
if (!endpointKeys.has(validateKey)) {
|
|
2209
|
+
endpointKeys.add(validateKey);
|
|
2210
|
+
endpoints.push({
|
|
2211
|
+
path: validatePath,
|
|
2212
|
+
method: "post",
|
|
2213
|
+
handler: validateCouponEndpoint({ pluginConfig }).handler
|
|
2214
|
+
});
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
if (applyPath) {
|
|
2218
|
+
const applyKey = `post:${applyPath}`;
|
|
2219
|
+
if (!endpointKeys.has(applyKey)) {
|
|
2220
|
+
endpointKeys.add(applyKey);
|
|
2221
|
+
endpoints.push({
|
|
2222
|
+
path: applyPath,
|
|
2223
|
+
method: "post",
|
|
2224
|
+
handler: applyCouponEndpoint({ pluginConfig }).handler
|
|
2225
|
+
});
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
collection.endpoints = endpoints;
|
|
2229
|
+
return collection;
|
|
2230
|
+
};
|
|
2135
2231
|
const addFieldsToCollection = (config, targetSlug, newFields) => {
|
|
2136
2232
|
const collections = asArray(config.collections);
|
|
2137
2233
|
const idx = collections.findIndex((c) => c.slug === targetSlug);
|
|
@@ -2216,11 +2312,19 @@ const payloadEcommerceCouponPlugin = (pluginOptions = {}) => async (incomingConf
|
|
|
2216
2312
|
if (pluginConfig.referralConfig.allowBothSystems) {
|
|
2217
2313
|
let couponsCollection = createCouponsCollection(pluginConfig);
|
|
2218
2314
|
if (pluginOptions.collections?.couponsCollectionOverride) couponsCollection = await pluginOptions.collections.couponsCollectionOverride({ defaultCollection: couponsCollection });
|
|
2315
|
+
couponsCollection = ensureCouponCollectionEndpoints({
|
|
2316
|
+
collection: couponsCollection,
|
|
2317
|
+
pluginConfig
|
|
2318
|
+
});
|
|
2219
2319
|
collectionsToAdd.push(couponsCollection);
|
|
2220
2320
|
}
|
|
2221
2321
|
} else {
|
|
2222
2322
|
let couponsCollection = createCouponsCollection(pluginConfig);
|
|
2223
2323
|
if (pluginOptions.collections?.couponsCollectionOverride) couponsCollection = await pluginOptions.collections.couponsCollectionOverride({ defaultCollection: couponsCollection });
|
|
2324
|
+
couponsCollection = ensureCouponCollectionEndpoints({
|
|
2325
|
+
collection: couponsCollection,
|
|
2326
|
+
pluginConfig
|
|
2327
|
+
});
|
|
2224
2328
|
collectionsToAdd.push(couponsCollection);
|
|
2225
2329
|
}
|
|
2226
2330
|
const existingSlugs = new Set(asArray(incomingConfig.collections).map((c) => c.slug));
|