@hartl-services/medusa-affiliate 0.3.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.
Files changed (169) hide show
  1. package/.medusa/server/src/admin/index.js +3739 -0
  2. package/.medusa/server/src/admin/index.mjs +3738 -0
  3. package/.medusa/server/src/api/admin/affiliate-applications/[id]/approve/route.js +28 -0
  4. package/.medusa/server/src/api/admin/affiliate-applications/[id]/reject/route.js +19 -0
  5. package/.medusa/server/src/api/admin/affiliate-applications/route.js +23 -0
  6. package/.medusa/server/src/api/admin/affiliate-distribution-reports/query.js +171 -0
  7. package/.medusa/server/src/api/admin/affiliate-distribution-reports/route.js +13 -0
  8. package/.medusa/server/src/api/admin/affiliate-program-settings/route.js +27 -0
  9. package/.medusa/server/src/api/admin/affiliate-reports/[id]/route.js +45 -0
  10. package/.medusa/server/src/api/admin/affiliate-reports/route.js +27 -0
  11. package/.medusa/server/src/api/admin/affiliates/[id]/consignment-reminders/route.js +31 -0
  12. package/.medusa/server/src/api/admin/affiliates/[id]/consignment-transfers/route.js +41 -0
  13. package/.medusa/server/src/api/admin/affiliates/[id]/coupon-codes/[coupon_id]/reconcile/route.js +34 -0
  14. package/.medusa/server/src/api/admin/affiliates/[id]/coupon-codes/[coupon_id]/revoke/route.js +36 -0
  15. package/.medusa/server/src/api/admin/affiliates/[id]/coupon-codes/[coupon_id]/rotate/route.js +40 -0
  16. package/.medusa/server/src/api/admin/affiliates/[id]/coupon-codes/route.js +56 -0
  17. package/.medusa/server/src/api/admin/affiliates/[id]/distribution/route.js +45 -0
  18. package/.medusa/server/src/api/admin/affiliates/[id]/inactive/route.js +20 -0
  19. package/.medusa/server/src/api/admin/affiliates/[id]/route.js +50 -0
  20. package/.medusa/server/src/api/admin/affiliates/[id]/slugs/[slug_id]/route.js +19 -0
  21. package/.medusa/server/src/api/admin/affiliates/[id]/slugs/route.js +26 -0
  22. package/.medusa/server/src/api/admin/affiliates/route.js +43 -0
  23. package/.medusa/server/src/api/admin/consignment-report-response.js +36 -0
  24. package/.medusa/server/src/api/admin/consignment-reports/[id]/approve/route.js +25 -0
  25. package/.medusa/server/src/api/admin/consignment-reports/[id]/correct/route.js +18 -0
  26. package/.medusa/server/src/api/admin/consignment-reports/[id]/reject/route.js +15 -0
  27. package/.medusa/server/src/api/admin/consignment-reports/[id]/route.js +11 -0
  28. package/.medusa/server/src/api/admin/consignment-reports/route.js +27 -0
  29. package/.medusa/server/src/api/admin/customers/[id]/affiliate/route.js +50 -0
  30. package/.medusa/server/src/api/admin/orders/[id]/affiliate-attribution/route.js +30 -0
  31. package/.medusa/server/src/api/affiliate-coupon-http.js +152 -0
  32. package/.medusa/server/src/api/affiliate-referral-cookie.js +34 -0
  33. package/.medusa/server/src/api/affiliate-self-service-http.js +37 -0
  34. package/.medusa/server/src/api/middlewares.js +786 -0
  35. package/.medusa/server/src/api/store/affiliate-referrals/apply-coupon/route.js +47 -0
  36. package/.medusa/server/src/api/store/affiliate-referrals/capture/route.js +76 -0
  37. package/.medusa/server/src/api/store/affiliate-referrals/carts/[cart_id]/route.js +20 -0
  38. package/.medusa/server/src/api/store/affiliates/consignment-inventory/route.js +53 -0
  39. package/.medusa/server/src/api/store/affiliates/consignment-report-response.js +31 -0
  40. package/.medusa/server/src/api/store/affiliates/consignment-reports/[id]/submit/route.js +40 -0
  41. package/.medusa/server/src/api/store/affiliates/consignment-reports/route.js +43 -0
  42. package/.medusa/server/src/api/store/affiliates/coupon-labels/route.js +14 -0
  43. package/.medusa/server/src/api/store/affiliates/me/commissions/route.js +35 -0
  44. package/.medusa/server/src/api/store/affiliates/me/coupon-codes/[coupon_id]/revoke/route.js +36 -0
  45. package/.medusa/server/src/api/store/affiliates/me/coupon-codes/[coupon_id]/rotate/route.js +40 -0
  46. package/.medusa/server/src/api/store/affiliates/me/coupon-codes/route.js +55 -0
  47. package/.medusa/server/src/api/store/affiliates/me/dashboard/route.js +15 -0
  48. package/.medusa/server/src/api/store/affiliates/me/route.js +85 -0
  49. package/.medusa/server/src/api/store/affiliates/me/slugs/[slug_id]/route.js +29 -0
  50. package/.medusa/server/src/api/store/affiliates/me/slugs/route.js +34 -0
  51. package/.medusa/server/src/api/store/affiliates/own-order-discount/route.js +22 -0
  52. package/.medusa/server/src/api/store/affiliates/own-order-promotion/route.js +30 -0
  53. package/.medusa/server/src/api/store/affiliates/register/route.js +27 -0
  54. package/.medusa/server/src/api/store/affiliates/resolve-referral/route.js +34 -0
  55. package/.medusa/server/src/api/validators.js +52 -0
  56. package/.medusa/server/src/api/wire-response.js +10 -0
  57. package/.medusa/server/src/integration/email-events.js +51 -0
  58. package/.medusa/server/src/integrations/inventory-transfer/batch-management-transfer-adapter.js +36 -0
  59. package/.medusa/server/src/integrations/inventory-transfer/native-inventory-transfer-adapter.js +30 -0
  60. package/.medusa/server/src/integrations/inventory-transfer/resolve-inventory-transfer-adapter.js +46 -0
  61. package/.medusa/server/src/integrations/inventory-transfer/types.js +3 -0
  62. package/.medusa/server/src/jobs/affiliate-attribution-expiry.js +20 -0
  63. package/.medusa/server/src/jobs/affiliate-consignment-report-reminders.js +15 -0
  64. package/.medusa/server/src/jobs/affiliate-promotion-freshness.js +24 -0
  65. package/.medusa/server/src/lib/query-string.js +15 -0
  66. package/.medusa/server/src/modules/affiliate/domain/affiliate-attribution-policy.js +81 -0
  67. package/.medusa/server/src/modules/affiliate/domain/affiliate-coupon-policy.js +61 -0
  68. package/.medusa/server/src/modules/affiliate/domain/commission-policy.js +33 -0
  69. package/.medusa/server/src/modules/affiliate/domain/consignment-reminder-rules.js +74 -0
  70. package/.medusa/server/src/modules/affiliate/domain/email-normalization.js +20 -0
  71. package/.medusa/server/src/modules/affiliate/domain/own-order-coupon-code.js +37 -0
  72. package/.medusa/server/src/modules/affiliate/domain/plugin-options.js +40 -0
  73. package/.medusa/server/src/modules/affiliate/index.js +13 -0
  74. package/.medusa/server/src/modules/affiliate/migrations/Migration20260827085154.js +423 -0
  75. package/.medusa/server/src/modules/affiliate/models/affiliate-application.js +38 -0
  76. package/.medusa/server/src/modules/affiliate/models/affiliate-cart-referral.js +65 -0
  77. package/.medusa/server/src/modules/affiliate/models/affiliate-code-redemption.js +41 -0
  78. package/.medusa/server/src/modules/affiliate/models/affiliate-coupon.js +55 -0
  79. package/.medusa/server/src/modules/affiliate/models/affiliate-distribution-settings.js +22 -0
  80. package/.medusa/server/src/modules/affiliate/models/affiliate-order-attribution.js +49 -0
  81. package/.medusa/server/src/modules/affiliate/models/affiliate-program-settings.js +28 -0
  82. package/.medusa/server/src/modules/affiliate/models/affiliate-referral-session.js +34 -0
  83. package/.medusa/server/src/modules/affiliate/models/affiliate-slug.js +27 -0
  84. package/.medusa/server/src/modules/affiliate/models/affiliate.js +49 -0
  85. package/.medusa/server/src/modules/affiliate/models/commission-entry.js +62 -0
  86. package/.medusa/server/src/modules/affiliate/models/consignment-report-line.js +21 -0
  87. package/.medusa/server/src/modules/affiliate/models/consignment-report.js +31 -0
  88. package/.medusa/server/src/modules/affiliate/models/consignment-transfer-line.js +16 -0
  89. package/.medusa/server/src/modules/affiliate/models/consignment-transfer.js +20 -0
  90. package/.medusa/server/src/modules/affiliate/models/customer-affiliate-assignment.js +58 -0
  91. package/.medusa/server/src/modules/affiliate/service.js +2321 -0
  92. package/.medusa/server/src/modules/affiliate/services/affiliate-application-manager.js +171 -0
  93. package/.medusa/server/src/modules/affiliate/services/affiliate-coupon-manager.js +441 -0
  94. package/.medusa/server/src/modules/affiliate/services/affiliate-discount.service.js +55 -0
  95. package/.medusa/server/src/modules/affiliate/services/affiliate-manager.js +242 -0
  96. package/.medusa/server/src/modules/affiliate/services/affiliate-partner-portal.service.js +138 -0
  97. package/.medusa/server/src/modules/affiliate/services/affiliate-report.service.js +436 -0
  98. package/.medusa/server/src/modules/affiliate/services/affiliate-slug-manager.js +163 -0
  99. package/.medusa/server/src/modules/affiliate/services/commission-ledger.service.js +729 -0
  100. package/.medusa/server/src/modules/affiliate/services/customer-affiliate-assignment-manager.js +350 -0
  101. package/.medusa/server/src/modules/affiliate/services/order-attribution-manager.js +1051 -0
  102. package/.medusa/server/src/modules/affiliate/services/referral-lifecycle-manager.js +1420 -0
  103. package/.medusa/server/src/modules/affiliate/services/utils.js +49 -0
  104. package/.medusa/server/src/modules/affiliate/types/internal.js +3 -0
  105. package/.medusa/server/src/paths/affiliate.js +7 -0
  106. package/.medusa/server/src/paths/index.js +18 -0
  107. package/.medusa/server/src/schemas/index.js +18 -0
  108. package/.medusa/server/src/schemas/store.js +24 -0
  109. package/.medusa/server/src/subscribers/affiliate-cart-updated.js +92 -0
  110. package/.medusa/server/src/subscribers/affiliate-order-canceled.js +70 -0
  111. package/.medusa/server/src/subscribers/affiliate-order-placed.js +63 -0
  112. package/.medusa/server/src/subscribers/affiliate-order-return-received.js +67 -0
  113. package/.medusa/server/src/subscribers/affiliate-product-eligibility-updated.js +87 -0
  114. package/.medusa/server/src/types/admin-api.js +3 -0
  115. package/.medusa/server/src/types/enums.js +53 -0
  116. package/.medusa/server/src/types/index.js +32 -0
  117. package/.medusa/server/src/types/public.js +3 -0
  118. package/.medusa/server/src/types/store-api.js +3 -0
  119. package/.medusa/server/src/utils/affiliate-cart-operation-lock.js +316 -0
  120. package/.medusa/server/src/utils/affiliate-promotion-mutation-authorization.js +49 -0
  121. package/.medusa/server/src/utils/cart-promotions.js +9 -0
  122. package/.medusa/server/src/utils/money.js +79 -0
  123. package/.medusa/server/src/utils/promotion-code-availability.js +34 -0
  124. package/.medusa/server/src/utils/registered-email-checkout.js +101 -0
  125. package/.medusa/server/src/utils/resolve-services.js +7 -0
  126. package/.medusa/server/src/utils/settle-cart-promotions.js +44 -0
  127. package/.medusa/server/src/workflows/affiliate/affiliate-coupon-cart.js +215 -0
  128. package/.medusa/server/src/workflows/affiliate/affiliate-coupon-command-authorization.js +20 -0
  129. package/.medusa/server/src/workflows/affiliate/apply-affiliate-coupon.js +174 -0
  130. package/.medusa/server/src/workflows/affiliate/apply-own-order-promotion.js +89 -0
  131. package/.medusa/server/src/workflows/affiliate/approve-consignment-report.js +186 -0
  132. package/.medusa/server/src/workflows/affiliate/correct-approved-consignment-report.js +263 -0
  133. package/.medusa/server/src/workflows/affiliate/create-affiliate-coupon.js +35 -0
  134. package/.medusa/server/src/workflows/affiliate/create-commission-correction-for-cancellation.js +21 -0
  135. package/.medusa/server/src/workflows/affiliate/create-commission-correction-for-refund.js +24 -0
  136. package/.medusa/server/src/workflows/affiliate/create-commission-for-order.js +17 -0
  137. package/.medusa/server/src/workflows/affiliate/deactivate-affiliate.js +89 -0
  138. package/.medusa/server/src/workflows/affiliate/enable-distribution.js +120 -0
  139. package/.medusa/server/src/workflows/affiliate/enrich-affiliate-report.js +75 -0
  140. package/.medusa/server/src/workflows/affiliate/ensure-affiliate-coupon-promotion.js +410 -0
  141. package/.medusa/server/src/workflows/affiliate/ensure-affiliate-own-order-promotion.js +240 -0
  142. package/.medusa/server/src/workflows/affiliate/ensure-default-affiliate-coupon.js +32 -0
  143. package/.medusa/server/src/workflows/affiliate/expire-affiliate-attribution-state.js +131 -0
  144. package/.medusa/server/src/workflows/affiliate/finalize-affiliate-order-attribution.js +82 -0
  145. package/.medusa/server/src/workflows/affiliate/payment-authorization.js +33 -0
  146. package/.medusa/server/src/workflows/affiliate/promotion-eligibility.js +179 -0
  147. package/.medusa/server/src/workflows/affiliate/reconcile-affiliate-cart-referral.js +219 -0
  148. package/.medusa/server/src/workflows/affiliate/reconcile-affiliate-coupon.js +388 -0
  149. package/.medusa/server/src/workflows/affiliate/refresh-affiliate-promotions.js +114 -0
  150. package/.medusa/server/src/workflows/affiliate/resolve-coupon-labels.js +40 -0
  151. package/.medusa/server/src/workflows/affiliate/revoke-affiliate-coupon.js +29 -0
  152. package/.medusa/server/src/workflows/affiliate/rotate-affiliate-coupon.js +36 -0
  153. package/.medusa/server/src/workflows/affiliate/run-consignment-report-reminders.js +58 -0
  154. package/.medusa/server/src/workflows/affiliate/submit-consignment-report.js +279 -0
  155. package/.medusa/server/src/workflows/affiliate/transfer-batch-aware-inventory.js +172 -0
  156. package/.medusa/server/src/workflows/affiliate/transfer-consignment-stock.js +106 -0
  157. package/.medusa/server/src/workflows/affiliate/update-affiliate-coupon-discounts.js +129 -0
  158. package/.medusa/server/src/workflows/affiliate/utils.js +118 -0
  159. package/.medusa/server/src/workflows/hooks/complete-cart-affiliate-attribution.js +57 -0
  160. package/.medusa/server/src/workflows/hooks/complete-cart-order-created-composition.js +111 -0
  161. package/.medusa/server/src/workflows/hooks/complete-cart-own-order-discount.js +75 -0
  162. package/.medusa/server/src/workflows/hooks/enforce-unique-promotion-codes.js +33 -0
  163. package/.medusa/server/src/workflows/hooks/validate-affiliate-customer-code.js +239 -0
  164. package/.medusa/server/src/workflows/hooks/validate-complete-cart-affiliate-referral.js +137 -0
  165. package/LICENSE +21 -0
  166. package/README.md +799 -0
  167. package/dist/integration/email-events.d.ts +20 -0
  168. package/dist/integration/email-events.js +50 -0
  169. package/package.json +84 -0
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isDefiniteAffiliatePromotionRejection = exports.affiliatePromotionVariantAllowlist = exports.affiliateEligibleItemTargetRules = exports.affiliateEligibleVariantRuleValues = exports.AFFILIATE_CUSTOMER_CAMPAIGN_IDENTIFIER = void 0;
4
+ exports.assertAuthenticAffiliateCouponPromotion = assertAuthenticAffiliateCouponPromotion;
5
+ exports.listAffiliateEligibleVariantIds = listAffiliateEligibleVariantIds;
6
+ exports.ensureAffiliateEligibleItemTargetRules = ensureAffiliateEligibleItemTargetRules;
7
+ const utils_1 = require("@medusajs/framework/utils");
8
+ exports.AFFILIATE_CUSTOMER_CAMPAIGN_IDENTIFIER = "affiliate-customer-codes";
9
+ const NO_ELIGIBLE_VARIANT_ID = "variant_affiliate_no_eligible_physical_product";
10
+ const affiliateEligibleVariantRuleValues = (eligibleVariantIds) => eligibleVariantIds.length
11
+ ? [...new Set(eligibleVariantIds)].sort()
12
+ : [NO_ELIGIBLE_VARIANT_ID];
13
+ exports.affiliateEligibleVariantRuleValues = affiliateEligibleVariantRuleValues;
14
+ exports.affiliateEligibleItemTargetRules = [
15
+ {
16
+ attribute: "items.variant.id",
17
+ operator: "eq",
18
+ values: NO_ELIGIBLE_VARIANT_ID,
19
+ },
20
+ ];
21
+ const isVariantAllowlistRule = (rule) => rule.attribute === "items.variant.id" &&
22
+ rule.operator === "eq" &&
23
+ (rule.values ?? []).some(({ value }) => Boolean(value));
24
+ /**
25
+ * The variant ids a promotion's target rules actually let through. Medusa
26
+ * requires every target rule to match, so while an allowlist is being
27
+ * replaced (new rule added before the old one is removed) the effective list
28
+ * is the intersection - never wider than either list.
29
+ */
30
+ const affiliatePromotionVariantAllowlist = (targetRules) => {
31
+ const [first, ...rest] = (targetRules ?? []).map((rule) => new Set((rule.values ?? [])
32
+ .map(({ value }) => value)
33
+ .filter((value) => Boolean(value))));
34
+ if (!first) {
35
+ return new Set();
36
+ }
37
+ return new Set([...first].filter((value) => rest.every((values) => values.has(value))));
38
+ };
39
+ exports.affiliatePromotionVariantAllowlist = affiliatePromotionVariantAllowlist;
40
+ /**
41
+ * True only for the definite outcomes of `assertAuthenticAffiliateCouponPromotion`
42
+ * (rejected, or the promotion no longer exists). Anything else, such as a
43
+ * database error, may be transient and must not be treated as invalidity.
44
+ */
45
+ const isDefiniteAffiliatePromotionRejection = (error) => utils_1.MedusaError.isMedusaError(error) &&
46
+ (error.type === utils_1.MedusaError.Types.NOT_ALLOWED ||
47
+ error.type === utils_1.MedusaError.Types.NOT_FOUND);
48
+ exports.isDefiniteAffiliatePromotionRejection = isDefiniteAffiliatePromotionRejection;
49
+ /**
50
+ * Cart and checkout gate for an Affiliate coupon promotion: it must be the
51
+ * plugin's own, active, correctly shaped promotion for this coupon. Whether its
52
+ * rate and variant allowlist are up to date is deliberately not checked here:
53
+ * after a rate or catalogue change every promotion lags until provisioning
54
+ * (admin actions, the product-eligibility subscriber and the periodic
55
+ * affiliate-promotion-freshness job) catches up, and failing carts in that
56
+ * window would strip customers of their coupon.
57
+ */
58
+ async function assertAuthenticAffiliateCouponPromotion(promotionService, input) {
59
+ if (input.coupon.affiliate_id !== input.affiliate.id ||
60
+ input.coupon.lifecycle_status !== "enabled" ||
61
+ input.coupon.provisioning_status !== "ready" ||
62
+ !input.coupon.promotion_id ||
63
+ input.affiliate.status !== "active") {
64
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "The Affiliate coupon is inactive or not prepared.");
65
+ }
66
+ const promotion = await promotionService.retrievePromotion(input.coupon.promotion_id, {
67
+ relations: [
68
+ "campaign",
69
+ "rules",
70
+ "application_method",
71
+ "application_method.target_rules",
72
+ "application_method.target_rules.values",
73
+ ],
74
+ });
75
+ const campaign = promotion.campaign_id
76
+ ? await promotionService.retrieveCampaign(promotion.campaign_id, {
77
+ relations: ["budget"],
78
+ })
79
+ : null;
80
+ const campaignBudget = campaign?.budget;
81
+ const targetRules = promotion.application_method?.target_rules ?? [];
82
+ const rate = Number(promotion.application_method?.value);
83
+ const valid = promotion.id === input.coupon.promotion_id &&
84
+ promotion.code === input.coupon.code &&
85
+ promotion.type === "standard" &&
86
+ promotion.status === "active" &&
87
+ promotion.is_automatic === false &&
88
+ campaign !== null &&
89
+ promotion.campaign_id === campaign?.id &&
90
+ promotion.campaign?.id === campaign.id &&
91
+ campaign.campaign_identifier ===
92
+ exports.AFFILIATE_CUSTOMER_CAMPAIGN_IDENTIFIER &&
93
+ campaignBudget?.type === "use_by_attribute" &&
94
+ campaignBudget.attribute === "customer_email" &&
95
+ Number(campaignBudget.limit) === 1 &&
96
+ (promotion.rules?.length ?? 0) === 0 &&
97
+ promotion.application_method?.type === "percentage" &&
98
+ promotion.application_method.target_type === "items" &&
99
+ promotion.application_method.allocation === "across" &&
100
+ Number.isFinite(rate) &&
101
+ rate > 0 &&
102
+ rate <= 100 &&
103
+ targetRules.length > 0 &&
104
+ targetRules.every(isVariantAllowlistRule);
105
+ if (!valid) {
106
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "The Affiliate coupon promotion is inactive or no longer belongs to this coupon.");
107
+ }
108
+ return promotion;
109
+ }
110
+ async function listAffiliateEligibleVariantIds(query) {
111
+ const eligibleVariantIds = [];
112
+ const pageSize = 200;
113
+ let skip = 0;
114
+ while (true) {
115
+ const { data } = await query.graph({
116
+ entity: "product",
117
+ fields: [
118
+ "id",
119
+ "is_giftcard",
120
+ "metadata",
121
+ "variants.id",
122
+ "variants.inventory_items.inventory.requires_shipping",
123
+ ],
124
+ pagination: { skip, take: pageSize },
125
+ });
126
+ const products = data;
127
+ for (const product of products) {
128
+ if (product.is_giftcard ||
129
+ product.metadata?.affiliate_commission_excluded === true) {
130
+ continue;
131
+ }
132
+ for (const variant of product.variants ?? []) {
133
+ const requiresShipping = variant.inventory_items?.some((item) => item.inventory?.requires_shipping === true);
134
+ if (requiresShipping) {
135
+ eligibleVariantIds.push(variant.id);
136
+ }
137
+ }
138
+ }
139
+ if (products.length < pageSize) {
140
+ break;
141
+ }
142
+ skip += pageSize;
143
+ }
144
+ return [...new Set(eligibleVariantIds)].sort();
145
+ }
146
+ async function ensureAffiliateEligibleItemTargetRules(promotionService, query, promotionId, prefetchedEligibleVariantIds) {
147
+ const eligibleVariantIds = prefetchedEligibleVariantIds ??
148
+ (await listAffiliateEligibleVariantIds(query));
149
+ const desiredValues = (0, exports.affiliateEligibleVariantRuleValues)(eligibleVariantIds);
150
+ const promotion = await promotionService.retrievePromotion(promotionId, {
151
+ relations: [
152
+ "application_method",
153
+ "application_method.target_rules",
154
+ "application_method.target_rules.values",
155
+ ],
156
+ });
157
+ const existingRules = promotion.application_method?.target_rules ?? [];
158
+ const currentRule = existingRules.find((rule) => rule.attribute === "items.variant.id" &&
159
+ rule.operator === "eq");
160
+ const currentValues = (currentRule?.values ?? [])
161
+ .map((value) => value.value)
162
+ .sort();
163
+ const alreadyCurrent = currentValues.length === desiredValues.length &&
164
+ currentValues.every((value, index) => value === desiredValues[index]);
165
+ if (alreadyCurrent && existingRules.length === 1) {
166
+ return;
167
+ }
168
+ await promotionService.addPromotionTargetRules(promotionId, [
169
+ {
170
+ attribute: "items.variant.id",
171
+ operator: "eq",
172
+ values: desiredValues,
173
+ },
174
+ ]);
175
+ if (existingRules.length) {
176
+ await promotionService.removePromotionTargetRules(promotionId, existingRules.map((rule) => rule.id));
177
+ }
178
+ }
179
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvbW90aW9uLWVsaWdpYmlsaXR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9hZmZpbGlhdGUvcHJvbW90aW9uLWVsaWdpYmlsaXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQW9GQSwwRkF1RUM7QUFrQkQsMEVBK0NDO0FBRUQsd0ZBaURDO0FBM1FELHFEQUF1RDtBQUkxQyxRQUFBLHNDQUFzQyxHQUNqRCwwQkFBMEIsQ0FBQTtBQUU1QixNQUFNLHNCQUFzQixHQUMxQixnREFBZ0QsQ0FBQTtBQUUzQyxNQUFNLGtDQUFrQyxHQUFHLENBQ2hELGtCQUFxQyxFQUMzQixFQUFFLENBQ1osa0JBQWtCLENBQUMsTUFBTTtJQUN2QixDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUU7SUFDekMsQ0FBQyxDQUFDLENBQUMsc0JBQXNCLENBQUMsQ0FBQTtBQUxqQixRQUFBLGtDQUFrQyxzQ0FLakI7QUFFakIsUUFBQSxnQ0FBZ0MsR0FBRztJQUM5QztRQUNFLFNBQVMsRUFBRSxrQkFBa0I7UUFDN0IsUUFBUSxFQUFFLElBQWE7UUFDdkIsTUFBTSxFQUFFLHNCQUFzQjtLQUMvQjtDQUNGLENBQUE7QUFRRCxNQUFNLHNCQUFzQixHQUFHLENBQUMsSUFBZ0IsRUFBVyxFQUFFLENBQzNELElBQUksQ0FBQyxTQUFTLEtBQUssa0JBQWtCO0lBQ3JDLElBQUksQ0FBQyxRQUFRLEtBQUssSUFBSTtJQUN0QixDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUE7QUFFekQ7Ozs7O0dBS0c7QUFDSSxNQUFNLGtDQUFrQyxHQUFHLENBQ2hELFdBQXFELEVBQ3hDLEVBQUU7SUFDZixN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
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reconcileAffiliateCartReferralWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const utils_1 = require("@medusajs/framework/utils");
6
+ const resolve_services_1 = require("../../utils/resolve-services");
7
+ const cart_promotions_1 = require("../../utils/cart-promotions");
8
+ const affiliate_cart_operation_lock_1 = require("../../utils/affiliate-cart-operation-lock");
9
+ const affiliate_coupon_cart_1 = require("./affiliate-coupon-cart");
10
+ const apply_affiliate_coupon_1 = require("./apply-affiliate-coupon");
11
+ const payment_authorization_1 = require("./payment-authorization");
12
+ const promotion_eligibility_1 = require("./promotion-eligibility");
13
+ const emptyCompensation = (cartId) => ({
14
+ cart_id: cartId,
15
+ created_referral_ids: [],
16
+ previous_referrals: []
17
+ });
18
+ const restoreReconciliation = async (container, compensation) => {
19
+ const affiliateService = (0, resolve_services_1.resolveAffiliateService)(container);
20
+ const restored = await affiliateService.compensateAffiliateCouponReferralMutation(compensation.referral, container.resolve(utils_1.ContainerRegistrationKeys.QUERY));
21
+ let target = null;
22
+ try {
23
+ target = await (0, apply_affiliate_coupon_1.resolveAppliedAffiliateCouponForCart)(container, compensation.cart_id, new Set(restored.restorable_affiliate_coupon_ids));
24
+ }
25
+ catch {
26
+ target = null;
27
+ }
28
+ const settings = await affiliateService.retrieveProgramSettings();
29
+ await (0, affiliate_coupon_cart_1.syncAffiliateCouponCartPromotion)({
30
+ container,
31
+ affiliate_service: affiliateService,
32
+ cart_id: compensation.cart_id,
33
+ target_coupon: target,
34
+ promotion_stacking: settings.promotion_stacking,
35
+ base_promotions: compensation.previous_promotions,
36
+ force_replace: true
37
+ });
38
+ };
39
+ const reconcileAffiliateCartReferralStep = (0, workflows_sdk_1.createStep)("reconcile-affiliate-cart-referral", async (input, { container }) => {
40
+ const affiliateService = (0, resolve_services_1.resolveAffiliateService)(container);
41
+ const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
42
+ const { data } = await query.graph({
43
+ entity: "cart",
44
+ fields: [
45
+ "id",
46
+ "email",
47
+ "customer_id",
48
+ "promotions.id",
49
+ "promotions.code",
50
+ "payment_collection.status",
51
+ "payment_collection.payment_sessions.status"
52
+ ],
53
+ filters: { id: input.cart_id }
54
+ });
55
+ const cart = data[0];
56
+ if (!cart) {
57
+ return new workflows_sdk_1.StepResponse({ reconciled: false }, {
58
+ cart_id: input.cart_id,
59
+ previous_promotions: [],
60
+ referral: emptyCompensation(input.cart_id)
61
+ });
62
+ }
63
+ if ((0, payment_authorization_1.hasPaymentAuthorizationStarted)(cart.payment_collection)) {
64
+ return new workflows_sdk_1.StepResponse({ reconciled: false }, {
65
+ cart_id: cart.id,
66
+ previous_promotions: (0, cart_promotions_1.readCartPromotions)(cart.promotions),
67
+ referral: emptyCompensation(cart.id)
68
+ });
69
+ }
70
+ const previousPromotions = (0, cart_promotions_1.readCartPromotions)(cart.promotions);
71
+ const bindings = await (0, affiliate_coupon_cart_1.loadAffiliateCouponCartBindings)(affiliateService, previousPromotions);
72
+ const [pendingReferrals, activeReferrals, expiredReferrals] = await Promise.all([
73
+ affiliateService.listAffiliateCartReferrals({
74
+ cart_id: cart.id,
75
+ source: "coupon",
76
+ status: "pending_email_validation"
77
+ }, { take: 1, order: { captured_at: "DESC" } }),
78
+ affiliateService.listAffiliateCartReferrals({ cart_id: cart.id, status: "active" }, { take: 1, order: { captured_at: "DESC" } }),
79
+ affiliateService.listAffiliateCartReferrals({
80
+ cart_id: cart.id,
81
+ status: "expired",
82
+ applied_promotion_id: { $ne: null }
83
+ }, { order: { captured_at: "DESC", id: "DESC" } })
84
+ ]);
85
+ const pending = pendingReferrals[0] ?? null;
86
+ const active = activeReferrals[0] ?? null;
87
+ let referralCompensation = emptyCompensation(cart.id);
88
+ const compensation = () => ({
89
+ cart_id: cart.id,
90
+ previous_promotions: previousPromotions,
91
+ referral: referralCompensation
92
+ });
93
+ const finish = async (reconciled) => {
94
+ const cleanup = expiredReferrals.flatMap((referral) => referral.applied_promotion_id
95
+ ? [
96
+ {
97
+ referral_id: referral.id,
98
+ applied_promotion_id: referral.applied_promotion_id
99
+ }
100
+ ]
101
+ : []);
102
+ if (cleanup.length) {
103
+ await affiliateService.completeExpiredCartReferralPromotionCleanup({
104
+ referrals: cleanup
105
+ });
106
+ }
107
+ return new workflows_sdk_1.StepResponse({ reconciled }, compensation());
108
+ };
109
+ const removeCouponState = async (reason) => {
110
+ referralCompensation =
111
+ await affiliateService.invalidateAffiliateCouponReferrals({ cart_id: cart.id, reason }, query);
112
+ const settings = await affiliateService.retrieveProgramSettings();
113
+ await (0, affiliate_coupon_cart_1.syncAffiliateCouponCartPromotion)({
114
+ container,
115
+ affiliate_service: affiliateService,
116
+ cart_id: cart.id,
117
+ target_coupon: null,
118
+ promotion_stacking: settings.promotion_stacking
119
+ });
120
+ };
121
+ try {
122
+ if (cart.customer_id &&
123
+ (await affiliateService.isCustomerAffiliate(cart.customer_id))) {
124
+ referralCompensation =
125
+ await affiliateService.invalidateAffiliateCartReferrals({ cart_id: cart.id, reason: "affiliate_customer" }, query);
126
+ const settings = await affiliateService.retrieveProgramSettings();
127
+ await (0, affiliate_coupon_cart_1.syncAffiliateCouponCartPromotion)({
128
+ container,
129
+ affiliate_service: affiliateService,
130
+ cart_id: cart.id,
131
+ target_coupon: null,
132
+ promotion_stacking: settings.promotion_stacking
133
+ });
134
+ return await finish(true);
135
+ }
136
+ if (bindings.length > 1 || bindings.some(({ exact }) => !exact)) {
137
+ await removeCouponState("multiple_or_mismatched_affiliate_promotions");
138
+ return await finish(true);
139
+ }
140
+ const candidateCouponId = pending?.source_affiliate_coupon_id ??
141
+ active?.applied_affiliate_coupon_id ??
142
+ (active?.source === "coupon"
143
+ ? active.source_affiliate_coupon_id
144
+ : null) ??
145
+ (active ? null : bindings[0]?.coupon.id) ??
146
+ null;
147
+ if (!candidateCouponId) {
148
+ if (bindings.length ||
149
+ active?.source === "coupon" ||
150
+ active?.applied_affiliate_coupon_id) {
151
+ await removeCouponState("affiliate_coupon_binding_missing");
152
+ return await finish(true);
153
+ }
154
+ return await finish(false);
155
+ }
156
+ const coupon = await affiliateService.retrieveAffiliateCouponRecord(candidateCouponId);
157
+ const affiliate = await affiliateService.retrieveAffiliateRecord(coupon.affiliate_id);
158
+ if (coupon.lifecycle_status !== "enabled" ||
159
+ coupon.provisioning_status !== "ready" ||
160
+ !coupon.promotion_id ||
161
+ affiliate.status !== "active") {
162
+ await removeCouponState("affiliate_coupon_inactive");
163
+ return await finish(true);
164
+ }
165
+ const settings = await affiliateService.retrieveProgramSettings();
166
+ try {
167
+ await (0, promotion_eligibility_1.assertAuthenticAffiliateCouponPromotion)(container.resolve(utils_1.Modules.PROMOTION), { coupon, affiliate });
168
+ }
169
+ catch (error) {
170
+ // Removing the coupon is permanent for this cart, so only a definite
171
+ // rejection may do it. A transient failure is rethrown and the event
172
+ // retried, leaving the customer's coupon in place.
173
+ if (!(0, promotion_eligibility_1.isDefiniteAffiliatePromotionRejection)(error)) {
174
+ throw error;
175
+ }
176
+ await removeCouponState("affiliate_coupon_promotion_invalid");
177
+ return await finish(true);
178
+ }
179
+ const result = await affiliateService.applyAffiliateCouponReferral({
180
+ cart_id: cart.id,
181
+ email: cart.email ?? null,
182
+ customer_id: cart.customer_id ?? null,
183
+ affiliate,
184
+ coupon
185
+ }, query);
186
+ referralCompensation = result.compensation;
187
+ const target = [
188
+ "pending_email_validation",
189
+ "coupon_already_redeemed",
190
+ "ignored_existing_assignment"
191
+ ].includes(result.status)
192
+ ? null
193
+ : await (0, apply_affiliate_coupon_1.resolveAppliedAffiliateCouponForCart)(container, cart.id);
194
+ await (0, affiliate_coupon_cart_1.syncAffiliateCouponCartPromotion)({
195
+ container,
196
+ affiliate_service: affiliateService,
197
+ cart_id: cart.id,
198
+ target_coupon: target,
199
+ promotion_stacking: settings.promotion_stacking
200
+ });
201
+ return await finish(true);
202
+ }
203
+ catch (error) {
204
+ await restoreReconciliation(container, compensation());
205
+ throw error;
206
+ }
207
+ }, async (compensation, { container }) => {
208
+ if (compensation)
209
+ await restoreReconciliation(container, compensation);
210
+ });
211
+ const reconcileAffiliateCartReferralWorkflowInternal = (0, workflows_sdk_1.createWorkflow)("reconcile-affiliate-cart-referral", (input) => new workflows_sdk_1.WorkflowResponse(reconcileAffiliateCartReferralStep(input)));
212
+ const reconcileAffiliateCartReferralWorkflow = (container) => {
213
+ const workflow = reconcileAffiliateCartReferralWorkflowInternal(container);
214
+ return {
215
+ run: async (options) => await (0, affiliate_cart_operation_lock_1.withAffiliateCartOperationLock)(container, options.input.cart_id, async () => await workflow.run(options))
216
+ };
217
+ };
218
+ exports.reconcileAffiliateCartReferralWorkflow = reconcileAffiliateCartReferralWorkflow;
219
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb25jaWxlLWFmZmlsaWF0ZS1jYXJ0LXJlZmVycmFsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9hZmZpbGlhdGUvcmVjb25jaWxlLWFmZmlsaWF0ZS1jYXJ0LXJlZmVycmFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUlBLHFFQUswQztBQUMxQyxxREFBOEU7QUFJOUUsbUVBQXNFO0FBQ3RFLGlFQUFnRTtBQUNoRSw2RkFBMEY7QUFDMUYsbUVBSWdDO0FBQ2hDLHFFQUErRTtBQUMvRSxtRUFHZ0M7QUFDaEMsbUVBR2dDO0FBb0JoQyxNQUFNLGlCQUFpQixHQUFHLENBQ3hCLE1BQWMsRUFDdUIsRUFBRSxDQUFDLENBQUM7SUFDekMsT0FBTyxFQUFFLE1BQU07SUFDZixvQkFBb0IsRUFBRSxFQUFFO0lBQ3hCLGtCQUFrQixFQUFFLEVBQUU7Q0FDdkIsQ0FBQyxDQUFBO0FBRUYsTUFBTSxxQkFBcUIsR0FBRyxLQUFLLEVBQ2pDLFNBQTBCLEVBQzFCLFlBQXdDLEVBQ3pCLEVBQUU7SUFDakIsTUFBTSxnQkFBZ0IsR0FBRyxJQUFBLDBDQUF1QixFQUFDLFNBQVMsQ0FBQyxDQUFBO0lBQzNELE1BQU0sUUFBUSxHQUNaLE1BQU0sZ0JBQWdCLENBQUMseUNBQXlDLENBQzlELFlBQVksQ0FBQyxRQUFRLEVBQ3JCLFNBQVMsQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsS0FBSyxDQUFDLENBQ25ELENBQUE7SUFDSCxJQUFJLE1BQU0sR0FBOEIsSUFBSSxDQUFBO0lBQzVDLElBQUksQ0FBQztRQUNILE1BQU0sR0FBRyxNQUFNLElBQUEsNkRBQW9DLEVBQ2pELFNBQVMsRUFDVCxZQUFZLENBQUMsT0FBTyxFQUNwQixJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsK0JBQStCLENBQUMsQ0FDbEQsQ0FBQTtJQUNILENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxNQUFNLEdBQUcsSUFBSSxDQUFB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