@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,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rotateAffiliateCouponWorkflow = exports.rotateAffiliateCoupon = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const affiliate_coupon_policy_1 = require("../../modules/affiliate/domain/affiliate-coupon-policy");
6
+ const promotion_code_availability_1 = require("../../utils/promotion-code-availability");
7
+ const resolve_services_1 = require("../../utils/resolve-services");
8
+ const ensure_affiliate_coupon_promotion_1 = require("./ensure-affiliate-coupon-promotion");
9
+ const reconcile_affiliate_coupon_1 = require("./reconcile-affiliate-coupon");
10
+ const affiliate_coupon_command_authorization_1 = require("./affiliate-coupon-command-authorization");
11
+ const rotateAffiliateCoupon = async (container, input) => {
12
+ const affiliateService = (0, resolve_services_1.resolveAffiliateService)(container);
13
+ // Same guard as coupon creation: a native promotion with this code in any
14
+ // casing must refuse the rotation before a successor coupon exists.
15
+ if (input.code !== undefined) {
16
+ await (0, promotion_code_availability_1.assertPromotionCodeAvailable)(container, (0, affiliate_coupon_policy_1.normalizeAffiliateCouponCode)(input.code));
17
+ }
18
+ const rotation = await (0, affiliate_coupon_command_authorization_1.withAuthorizedAffiliateCouponCommand)(container, (0, ensure_affiliate_coupon_promotion_1.affiliateCouponProvisioningLockKeys)(input.affiliate_id), {
19
+ affiliate_id: input.affiliate_id,
20
+ actor_type: input.created_by_type,
21
+ actor_id: input.created_by_id,
22
+ }, async () => await affiliateService.createAffiliateCouponRotation(input));
23
+ const reconciled = await (0, reconcile_affiliate_coupon_1.reconcileAffiliateCoupon)(container, {
24
+ coupon_id: rotation.coupon.id,
25
+ });
26
+ const predecessor = reconciled.revoked_coupon ??
27
+ (await affiliateService.retrieveAffiliateCouponRecord(input.coupon_id, input.affiliate_id));
28
+ return {
29
+ coupon: reconciled.coupon,
30
+ revoked_coupon: predecessor,
31
+ };
32
+ };
33
+ exports.rotateAffiliateCoupon = rotateAffiliateCoupon;
34
+ const rotateAffiliateCouponStep = (0, workflows_sdk_1.createStep)("rotate-affiliate-coupon", async (input, { container }) => new workflows_sdk_1.StepResponse(await (0, exports.rotateAffiliateCoupon)(container, input)));
35
+ exports.rotateAffiliateCouponWorkflow = (0, workflows_sdk_1.createWorkflow)("rotate-affiliate-coupon", (input) => new workflows_sdk_1.WorkflowResponse(rotateAffiliateCouponStep(input)));
36
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm90YXRlLWFmZmlsaWF0ZS1jb3Vwb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL2FmZmlsaWF0ZS9yb3RhdGUtYWZmaWxpYXRlLWNvdXBvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxRUFLMEM7QUFJMUMsb0dBQXFHO0FBQ3JHLHlGQUFzRjtBQUN0RixtRUFBc0U7QUFDdEUsMkZBQXlGO0FBQ3pGLDZFQUF1RTtBQUN2RSxxR0FBK0Y7QUFnQnhGLE1BQU0scUJBQXFCLEdBQUcsS0FBSyxFQUN4QyxTQUEwQixFQUMxQixLQUF5QyxFQUNLLEVBQUU7SUFDaEQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFBLDBDQUF1QixFQUFDLFNBQVMsQ0FBQyxDQUFBO0lBQzNELDBFQUEwRTtJQUMxRSxvRUFBb0U7SUFDcEUsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzdCLE1BQU0sSUFBQSwwREFBNEIsRUFDaEMsU0FBUyxFQUNULElBQUEsc0RBQTRCLEVBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUN6QyxDQUFBO0lBQ0gsQ0FBQztJQUNELE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBQSw2RUFBb0MsRUFDekQsU0FBUyxFQUNULElBQUEsdUVBQW1DLEVBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxFQUN2RDtRQUNFLFlBQVksRUFBRSxLQUFLLENBQUMsWUFBWTtRQUNoQyxVQUFVLEVBQUUsS0FBSyxDQUFDLGVBQWU7UUFDakMsUUFBUSxFQUFFLEtBQUssQ0FBQyxhQUFhO0tBQzlCLEVBQ0QsS0FBSyxJQUFJLEVBQUUsQ0FBQyxNQUFNLGdCQUFnQixDQUFDLDZCQUE2QixDQUFDLEtBQUssQ0FBQyxDQUN4RSxDQUFBO0lBQ0QsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFBLHFEQUF3QixFQUFDLFNBQVMsRUFBRTtRQUMzRCxTQUFTLEVBQUUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFO0tBQzlCLENBQUMsQ0FBQTtJQUNGLE1BQU0sV0FBVyxHQUNmLFVBQVUsQ0FBQyxjQUFjO1FBQ3pCLENBQUMsTUFBTSxnQkFBZ0IsQ0FBQyw2QkFBNkIsQ0FDbkQsS0FBSyxDQUFDLFNBQVMsRUFDZixLQUFLLENBQUMsWUFBWSxDQUNuQixDQUFDLENBQUE7SUFDSixPQUFPO1FBQ0wsTUFBTSxFQUFFLFVBQVUsQ0FBQyxNQUFNO1FBQ3pCLGNBQWMsRUFBRSxXQUFXO0tBQzVCLENBQUE7QUFDSCxDQUFDLENBQUE7QUFwQ1ksUUFBQSxxQkFBcUIseUJBb0NqQztBQUVELE1BQU0seUJBQXlCLEdBQUcsSUFBQSwwQkFBVSxFQUMxQyx5QkFBeUIsRUFDekIsS0FBSyxFQUNILEtBQXlDLEVBQ3pDLEVBQUUsU0FBUyxFQUFFLEVBQytDLEVBQUUsQ0FDOUQsSUFBSSw0QkFBWSxDQUFDLE1BQU0sSUFBQSw2QkFBcUIsRUFBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FDbEUsQ0FBQTtBQUVZLFFBQUEsNkJBQTZCLEdBQUcsSUFBQSw4QkFBYyxFQUN6RCx5QkFBeUIsRUFDekIsQ0FBQyxLQUF5QyxFQUFFLEVBQUUsQ0FDNUMsSUFBSSxnQ0FBZ0IsQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUN6RCxDQUFBIn0=
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runConsignmentReportRemindersWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const utils_1 = require("@medusajs/framework/utils");
6
+ const affiliate_1 = require("../../modules/affiliate");
7
+ const consignment_reminder_rules_1 = require("../../modules/affiliate/domain/consignment-reminder-rules");
8
+ const email_events_1 = require("../../integration/email-events");
9
+ const runConsignmentReportRemindersStep = (0, workflows_sdk_1.createStep)("affiliate-run-consignment-report-reminders", async (input, { container }) => {
10
+ const affiliateService = container.resolve(affiliate_1.AFFILIATE_MODULE);
11
+ const options = await affiliateService.getPluginOptions();
12
+ const periodStart = (0, consignment_reminder_rules_1.getDueConsignmentPeriod)({
13
+ now: new Date(input.now),
14
+ due_day: options.consignment_reminders.due_day,
15
+ timezone: options.consignment_reminders.timezone,
16
+ });
17
+ if (!periodStart) {
18
+ return new workflows_sdk_1.StepResponse({
19
+ period_start: null,
20
+ reminders: [],
21
+ });
22
+ }
23
+ const settings = (await affiliateService.listAffiliateDistributionSettings({
24
+ enabled: true,
25
+ }));
26
+ const eventBus = container.resolve(utils_1.Modules.EVENT_BUS);
27
+ const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
28
+ const reminders = [];
29
+ for (const setting of settings) {
30
+ try {
31
+ const candidate = await affiliateService.getConsignmentReportReminderCandidate({
32
+ affiliate_id: setting.affiliate_id,
33
+ period_start: periodStart,
34
+ due_day: options.consignment_reminders.due_day,
35
+ trigger: "scheduled",
36
+ });
37
+ if (!candidate) {
38
+ continue;
39
+ }
40
+ await eventBus.emit({
41
+ name: email_events_1.AFFILIATE_CONSIGNMENT_REPORT_REMINDER_DUE_EVENT,
42
+ data: candidate,
43
+ });
44
+ reminders.push(candidate);
45
+ }
46
+ catch {
47
+ logger.error(`Affiliate reminder failed affiliate_id=${setting.affiliate_id} period_start=${periodStart}`);
48
+ }
49
+ }
50
+ return new workflows_sdk_1.StepResponse({
51
+ period_start: periodStart,
52
+ reminders,
53
+ });
54
+ });
55
+ exports.runConsignmentReportRemindersWorkflow = (0, workflows_sdk_1.createWorkflow)("affiliate-run-consignment-report-reminders-workflow", function (input) {
56
+ return new workflows_sdk_1.WorkflowResponse(runConsignmentReportRemindersStep(input));
57
+ });
58
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLWNvbnNpZ25tZW50LXJlcG9ydC1yZW1pbmRlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL2FmZmlsaWF0ZS9ydW4tY29uc2lnbm1lbnQtcmVwb3J0LXJlbWluZGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxRUFLMkM7QUFDM0MscURBQStFO0FBRS9FLHVEQUEyRDtBQUMzRCwwR0FBb0c7QUFFcEcsaUVBR3dDO0FBZXhDLE1BQU0saUNBQWlDLEdBQUcsSUFBQSwwQkFBVSxFQUtsRCw0Q0FBNEMsRUFDNUMsS0FBSyxFQUFFLEtBQXlDLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFO0lBQ2pFLE1BQU0sZ0JBQWdCLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FDeEMsNEJBQWdCLENBQ1MsQ0FBQztJQUM1QixNQUFNLE9BQU8sR0FBRyxNQUFNLGdCQUFnQixDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDMUQsTUFBTSxXQUFXLEdBQUcsSUFBQSxvREFBdUIsRUFBQztRQUMxQyxHQUFHLEVBQUUsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQztRQUN4QixPQUFPLEVBQUUsT0FBTyxDQUFDLHFCQUFxQixDQUFDLE9BQU87UUFDOUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxRQUFRO0tBQ2pELENBQUMsQ0FBQztJQUNILElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNqQixPQUFPLElBQUksNEJBQVksQ0FBc0M7WUFDM0QsWUFBWSxFQUFFLElBQUk7WUFDbEIsU0FBUyxFQUFFLEVBQUU7U0FDZCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsTUFBTSxRQUFRLEdBQUcsQ0FBQyxNQUFNLGdCQUFnQixDQUFDLGlDQUFpQyxDQUFDO1FBQ3pFLE9BQU8sRUFBRSxJQUFJO0tBQ2QsQ0FBQyxDQUEyQixDQUFDO0lBQzlCLE1BQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQ2hDLGVBQU8sQ0FBQyxTQUFTLENBQ1EsQ0FBQztJQUM1QixNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUM5QixpQ0FBeUIsQ0FBQyxNQUFNLENBQ3ZCLENBQUM7SUFDWixNQUFNLFNBQVMsR0FBaUQsRUFBRSxDQUFDO0lBRW5FLEtBQUssTUFBTSxPQUFPLElBQUksUUFBUSxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxTQUFTLEdBQ2IsTUFBTSxnQkFBZ0IsQ0FBQyxxQ0FBcUMsQ0FBQztnQkFDM0QsWUFBWSxFQUFFLE9BQU8sQ0FBQyxZQUFZO2dCQUNsQyxZQUFZLEVBQUUsV0FBVztnQkFDekIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxPQUFPO2dCQUM5QyxPQUFPLEVBQUUsV0FBVzthQUNyQixDQUFDLENBQUM7WUFDTCxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ2YsU0FBUztZQUNYLENBQUM7WUFFRCxNQUFNLFFBQVEsQ0FBQyxJQUFJLENBQUM7Z0JBQ2xCLElBQUksRUFBRSw4REFBK0M7Z0JBQ3JELElBQUksRUFBRSxTQUFTO2FBQ2hCLENBQUMsQ0FBQztZQUNILFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDNUIsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE1BQU0sQ0FBQyxLQUFLLENBQ1YsMENBQTBDLE9BQU8sQ0FBQyxZQUFZLGlCQUFpQixXQUFXLEVBQUUsQ0FDN0YsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxJQUFJLDRCQUFZLENBQXNDO1FBQzNELFlBQVksRUFBRSxXQUFXO1FBQ3pCLFNBQVM7S0FDVixDQUFDLENBQUM7QUFDTCxDQUFDLENBQ0YsQ0FBQztBQUVXLFFBQUEscUNBQXFDLEdBQUcsSUFBQSw4QkFBYyxFQUNqRSxxREFBcUQsRUFDckQsVUFBVSxLQUF5QztJQUNqRCxPQUFPLElBQUksZ0NBQWdCLENBQUMsaUNBQWlDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUN4RSxDQUFDLENBQ0YsQ0FBQyJ9
@@ -0,0 +1,279 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.submitConsignmentReportWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const utils_1 = require("@medusajs/framework/utils");
6
+ const core_flows_1 = require("@medusajs/medusa/core-flows");
7
+ const resolve_services_1 = require("../../utils/resolve-services");
8
+ const tryResolve = (container, name) => {
9
+ try {
10
+ return container.resolve(name);
11
+ }
12
+ catch (error) {
13
+ if (error instanceof Error &&
14
+ error.message.includes("Missing registration")) {
15
+ return null;
16
+ }
17
+ throw error;
18
+ }
19
+ };
20
+ const resolveConsignmentSubmissionStep = (0, workflows_sdk_1.createStep)("affiliate-resolve-consignment-submission", async (input, { container }) => {
21
+ const affiliateService = (0, resolve_services_1.resolveAffiliateService)(container);
22
+ const affiliate = await affiliateService.retrieveAffiliateRecord(input.affiliate_id);
23
+ if (affiliate.status !== "active" || !affiliate.customer_id) {
24
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Monatsmeldungen sind nur für aktive Affiliates mit Kundenkonto erlaubt.");
25
+ }
26
+ if (input.expected_inventory_snapshot) {
27
+ return new workflows_sdk_1.StepResponse({
28
+ input: {
29
+ ...input,
30
+ expected_inventory_snapshot: input.expected_inventory_snapshot,
31
+ },
32
+ draft_context: input.draft_order_context ?? null,
33
+ own_order_discount_rate: affiliate.own_order_discount_rate,
34
+ internal_fixture_context: Boolean(input.draft_order_context),
35
+ });
36
+ }
37
+ const settings = await affiliateService.getAffiliateDistributionSettings(affiliate.id);
38
+ if (!settings?.enabled) {
39
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Der Kommissionsvertrieb ist für diesen Affiliate nicht aktiviert.");
40
+ }
41
+ const [customer, region] = await Promise.all([
42
+ container.resolve(utils_1.Modules.CUSTOMER).retrieveCustomer(affiliate.customer_id, {
43
+ relations: ["addresses"],
44
+ }),
45
+ container.resolve(utils_1.Modules.REGION).retrieveRegion(settings.region_id),
46
+ ]);
47
+ if (!customer.email) {
48
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Das Kundenkonto des Affiliates benötigt eine E-Mail-Adresse.");
49
+ }
50
+ const promotionId = settings.own_order_promotion_id ?? affiliate.own_order_promotion_id;
51
+ if (!promotionId) {
52
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Die Eigenbestellungs-Promotion des Affiliates fehlt.");
53
+ }
54
+ const promotion = await container.resolve(utils_1.Modules.PROMOTION).retrievePromotion(promotionId);
55
+ if (!promotion.code) {
56
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Die Eigenbestellungs-Promotion besitzt keinen Code.");
57
+ }
58
+ const inventory = container.resolve(utils_1.Modules.INVENTORY);
59
+ const levels = (await inventory.listInventoryLevels({
60
+ location_id: settings.stock_location_id,
61
+ }));
62
+ const batchService = tryResolve(container, "batch_management");
63
+ const batches = batchService
64
+ ? await batchService.listBatches({ location_id: settings.stock_location_id }, {})
65
+ : null;
66
+ const inventoryItemIds = [
67
+ ...new Set((batches ?? levels).map((record) => record.inventory_item_id)),
68
+ ];
69
+ const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
70
+ const graph = inventoryItemIds.length
71
+ ? await query.graph({
72
+ entity: "inventory_item",
73
+ fields: [
74
+ "id",
75
+ "variants.id",
76
+ "variants.title",
77
+ "variants.product_id",
78
+ "variants.product.title",
79
+ "variants.calculated_price.calculated_amount",
80
+ ],
81
+ filters: { id: inventoryItemIds },
82
+ context: {
83
+ region_id: settings.region_id,
84
+ currency_code: region.currency_code,
85
+ },
86
+ })
87
+ : { data: [] };
88
+ const variants = new Map(graph.data.map((row) => [
89
+ row.id,
90
+ row.variants?.[0] ?? null,
91
+ ]));
92
+ const toSnapshot = (inventoryItemId, batchId, quantity) => {
93
+ const variant = variants.get(inventoryItemId);
94
+ return {
95
+ inventory_item_id: inventoryItemId,
96
+ batch_id: batchId,
97
+ expected_quantity: quantity,
98
+ variant_id: variant?.id ?? null,
99
+ title: variant?.product?.title ?? variant?.title ?? inventoryItemId,
100
+ webshop_unit_price: variant?.calculated_price?.calculated_amount ?? null,
101
+ currency_code: region.currency_code,
102
+ };
103
+ };
104
+ const expected = batches
105
+ ? batches.map((batch) => toSnapshot(batch.inventory_item_id, batch.id, Number(batch.quantity)))
106
+ : levels.map((level) => toSnapshot(level.inventory_item_id, null, Number(level.stocked_quantity)));
107
+ const addresses = (customer.addresses ?? []);
108
+ const shippingAddress = addresses.find((address) => address.is_default_shipping) ?? addresses[0];
109
+ const billingAddress = addresses.find((address) => address.is_default_billing) ??
110
+ shippingAddress;
111
+ return new workflows_sdk_1.StepResponse({
112
+ input: {
113
+ ...input,
114
+ expected_inventory_snapshot: expected,
115
+ },
116
+ draft_context: {
117
+ customer_id: affiliate.customer_id,
118
+ email: customer.email,
119
+ region_id: settings.region_id,
120
+ sales_channel_id: settings.internal_sales_channel_id,
121
+ shipping_option_id: settings.shipping_option_id,
122
+ own_order_promotion_code: promotion.code,
123
+ currency_code: region.currency_code,
124
+ shipping_address_id: shippingAddress?.id ?? null,
125
+ billing_address_id: billingAddress?.id ?? null,
126
+ },
127
+ own_order_discount_rate: affiliate.own_order_discount_rate,
128
+ internal_fixture_context: false,
129
+ });
130
+ });
131
+ const prepareConsignmentReportStep = (0, workflows_sdk_1.createStep)("affiliate-prepare-consignment-report", async (resolved, { container }) => new workflows_sdk_1.StepResponse(await (0, resolve_services_1.resolveAffiliateService)(container).prepareConsignmentReport(resolved.input)));
132
+ const attachConsignmentDraftOrderStep = (0, workflows_sdk_1.createStep)("affiliate-attach-consignment-draft-order", async (input, { container }) => {
133
+ const affiliateService = (0, resolve_services_1.resolveAffiliateService)(container);
134
+ const draftOrderId = input.draft_order?.id ?? input.existing_draft_order_id ?? null;
135
+ if (!draftOrderId) {
136
+ return new workflows_sdk_1.StepResponse({
137
+ report: await affiliateService.retrieveConsignmentReportRecord(input.report_id),
138
+ draft_order: null,
139
+ });
140
+ }
141
+ const order = await container.resolve(utils_1.Modules.ORDER).retrieveOrder(draftOrderId, {
142
+ relations: ["items", "items.adjustments", "shipping_methods"],
143
+ });
144
+ const orderItems = (order.items ?? []);
145
+ const report = await affiliateService.retrieveConsignmentReportRecord(input.report_id);
146
+ const updates = report.lines
147
+ .filter((line) => line.confirmed_sale_quantity > 0)
148
+ .map((line) => {
149
+ const orderLine = orderItems.find((item) => item.metadata?.consignment_report_line_id === line.id);
150
+ const resolvedUnitPrice = Number(orderLine?.unit_price ?? line.resolved_unit_price ?? 0);
151
+ const discountedTotal = Number(orderLine?.discounted_total ??
152
+ resolvedUnitPrice * line.confirmed_sale_quantity -
153
+ (orderLine?.adjustments ?? []).reduce((sum, adjustment) => sum + Number(adjustment.amount), 0));
154
+ return {
155
+ report_line_id: line.id,
156
+ order_line_item_id: orderLine?.id ?? null,
157
+ resolved_unit_price: resolvedUnitPrice,
158
+ discounted_line_total: discountedTotal,
159
+ };
160
+ });
161
+ const attached = await affiliateService.attachConsignmentDraftOrder({
162
+ report_id: report.id,
163
+ draft_order_id: order.id,
164
+ lines: updates,
165
+ });
166
+ return new workflows_sdk_1.StepResponse({
167
+ report: attached,
168
+ draft_order: {
169
+ id: order.id,
170
+ promo_codes: input.promo_codes,
171
+ },
172
+ });
173
+ });
174
+ exports.submitConsignmentReportWorkflow = (0, workflows_sdk_1.createWorkflow)("affiliate-submit-consignment-report", (input) => {
175
+ const lockKey = (0, workflows_sdk_1.transform)(input, (data) => `affiliate-consignment-report:${data.submission_idempotency_key}`);
176
+ (0, core_flows_1.acquireLockStep)({ key: lockKey, timeout: 10, ttl: 60 });
177
+ const resolved = resolveConsignmentSubmissionStep(input);
178
+ const prepared = prepareConsignmentReportStep(resolved);
179
+ const draftPreparation = (0, workflows_sdk_1.transform)({ resolved, prepared }, ({ resolved, prepared }) => {
180
+ const billable = prepared.report.lines.filter((line) => line.confirmed_sale_quantity > 0);
181
+ if (prepared.report.draft_order_id ||
182
+ !billable.length ||
183
+ !resolved.draft_context) {
184
+ return {
185
+ create: false,
186
+ internal_fixture_context: resolved.internal_fixture_context,
187
+ report_id: prepared.report.id,
188
+ promo_codes: resolved.draft_context
189
+ ? [resolved.draft_context.own_order_promotion_code]
190
+ : [],
191
+ order_input: {},
192
+ };
193
+ }
194
+ const draftContext = resolved.draft_context;
195
+ const items = billable.map((line) => {
196
+ const unitPrice = line.resolved_unit_price;
197
+ if (unitPrice === null || unitPrice === undefined) {
198
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Für Inventory Item ${line.inventory_item_id} konnte kein Webshoppreis ermittelt werden.`);
199
+ }
200
+ const fixtureDiscount = resolved.internal_fixture_context &&
201
+ resolved.own_order_discount_rate > 0
202
+ ? [
203
+ {
204
+ code: draftContext.own_order_promotion_code,
205
+ amount: (unitPrice *
206
+ line.confirmed_sale_quantity *
207
+ resolved.own_order_discount_rate) /
208
+ 100,
209
+ },
210
+ ]
211
+ : undefined;
212
+ return {
213
+ title: line.inventory_item_id,
214
+ variant_id: typeof line.metadata?.variant_id === "string"
215
+ ? line.metadata.variant_id
216
+ : undefined,
217
+ quantity: line.confirmed_sale_quantity,
218
+ unit_price: unitPrice,
219
+ is_discountable: true,
220
+ adjustments: fixtureDiscount,
221
+ metadata: {
222
+ inventory_item_id: line.inventory_item_id,
223
+ batch_id: line.batch_id,
224
+ consignment_report_line_id: line.id,
225
+ },
226
+ };
227
+ });
228
+ const orderInput = {
229
+ status: utils_1.OrderStatus.DRAFT,
230
+ is_draft_order: true,
231
+ customer_id: draftContext.customer_id,
232
+ email: draftContext.email,
233
+ region_id: draftContext.region_id,
234
+ sales_channel_id: draftContext.sales_channel_id,
235
+ currency_code: draftContext.currency_code ??
236
+ prepared.report.lines.find((line) => line.currency_code)
237
+ ?.currency_code ??
238
+ undefined,
239
+ shipping_address_id: draftContext.shipping_address_id ?? undefined,
240
+ billing_address_id: draftContext.billing_address_id ?? undefined,
241
+ items,
242
+ shipping_methods: [
243
+ {
244
+ name: "Interne Kommissionsabrechnung",
245
+ amount: 0,
246
+ shipping_option_id: draftContext.shipping_option_id,
247
+ },
248
+ ],
249
+ promo_codes: [draftContext.own_order_promotion_code],
250
+ no_notification: true,
251
+ metadata: {
252
+ consignment: true,
253
+ consignment_report_id: prepared.report.id,
254
+ affiliate_id: resolved.input.affiliate_id,
255
+ },
256
+ };
257
+ return {
258
+ create: true,
259
+ internal_fixture_context: resolved.internal_fixture_context,
260
+ report_id: prepared.report.id,
261
+ promo_codes: [draftContext.own_order_promotion_code],
262
+ order_input: orderInput,
263
+ };
264
+ });
265
+ const createdProductionDraft = (0, workflows_sdk_1.when)("affiliate-create-production-consignment-draft-order", draftPreparation, (data) => data.create && !data.internal_fixture_context).then(() => core_flows_1.createOrderWorkflow.runAsStep({
266
+ input: draftPreparation.order_input,
267
+ }));
268
+ const createdFixtureDrafts = (0, workflows_sdk_1.when)("affiliate-create-fixture-consignment-draft-order", draftPreparation, (data) => data.create && data.internal_fixture_context).then(() => (0, core_flows_1.createOrdersStep)([draftPreparation.order_input]));
269
+ const createdDraft = (0, workflows_sdk_1.transform)({ createdProductionDraft, createdFixtureDrafts }, ({ createdProductionDraft, createdFixtureDrafts }) => createdProductionDraft ?? createdFixtureDrafts?.[0] ?? null);
270
+ const output = attachConsignmentDraftOrderStep((0, workflows_sdk_1.transform)({ draftPreparation, prepared, createdDraft }, ({ draftPreparation, prepared, createdDraft }) => ({
271
+ report_id: prepared.report.id,
272
+ promo_codes: draftPreparation.promo_codes,
273
+ existing_draft_order_id: prepared.report.draft_order_id,
274
+ draft_order: createdDraft ?? null,
275
+ })));
276
+ (0, core_flows_1.releaseLockStep)({ key: lockKey });
277
+ return new workflows_sdk_1.WorkflowResponse(output);
278
+ });
279
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VibWl0LWNvbnNpZ25tZW50LXJlcG9ydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3MvYWZmaWxpYXRlL3N1Ym1pdC1jb25zaWdubWVudC1yZXBvcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBUUEscUVBTzBDO0FBQzFDLHFEQUtrQztBQUNsQyw0REFLb0M7QUFRcEMsbUVBQXNFO0FBdUR0RSxNQUFNLFVBQVUsR0FBRyxDQUFJLFNBRXRCLEVBQUUsSUFBWSxFQUFZLEVBQUU7SUFDM0IsSUFBSSxDQUFDO1FBQ0gsT0FBTyxTQUFTLENBQUMsT0FBTyxDQUFJLElBQUksQ0FBQyxDQUFBO0lBQ25DLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsSUFDRSxLQUFLLFlBQVksS0FBSztZQUN0QixLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxzQkFBc0IsQ0FBQyxFQUM5QyxDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUE7UUFDYixDQUFDO1FBQ0QsTUFBTSxLQUFLLENBQUE7SUFDYixDQUFDO0FBQ0gsQ0FBQyxDQUFBO0FBRUQsTUFBTSxnQ0FBZ0MsR0FBRyxJQUFBLDBCQUFVLEVBQ2pELDBDQUEwQyxFQUMxQyxLQUFLLEVBQ0gsS0FBbUMsRUFDbkMsRUFBRSxTQUFTLEVBQUUsRUFDOEIsRUFBRTtJQUM3QyxNQUFNLGdCQUFnQixHQUFHLElBQUEsMENBQXVCLEVBQUMsU0FBUyxDQUFDLENBQUE7SUFDM0QsTUFBTSxTQUFTLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyx1QkFBdUIsQ0FDOUQsS0FBSyxDQUFDLFlBQVksQ0FDbkIsQ0FBQTtJQUNELElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDNUQsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFDN0IseUVB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
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transferNativeInventoryWorkflow = exports.transferBatchAwareInventoryWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const utils_1 = require("@medusajs/framework/utils");
6
+ const core_flows_1 = require("@medusajs/medusa/core-flows");
7
+ const BATCH_REGISTRATION = "batch_management";
8
+ const UPGRADE_MESSAGE = "Batch Management ist installiert, unterstützt aber keine chargensicheren Transfers. Aktualisiere das Batch-Management-Plugin.";
9
+ const resolveBatchService = (container) => {
10
+ const service = container.resolve(BATCH_REGISTRATION);
11
+ if (typeof service !== "object" ||
12
+ service === null ||
13
+ !("transferBatches" in service) ||
14
+ typeof service.transferBatches !== "function" ||
15
+ !("completeBatchTransferRun" in service) ||
16
+ typeof service.completeBatchTransferRun !== "function" ||
17
+ !("reverseBatchTransferRun" in service) ||
18
+ typeof service.reverseBatchTransferRun !== "function") {
19
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, UPGRADE_MESSAGE);
20
+ }
21
+ return service;
22
+ };
23
+ const prepareBatchTransferStep = (0, workflows_sdk_1.createStep)("affiliate-prepare-batch-inventory-transfer", async (input, { container }) => {
24
+ const batchService = resolveBatchService(container);
25
+ const transfer = await batchService.transferBatches({
26
+ idempotency_key: input.idempotency_key,
27
+ lines: input.lines.map((line) => ({
28
+ batch_id: line.batch_id,
29
+ destination_location_id: line.destination_location_id,
30
+ quantity: line.quantity,
31
+ })),
32
+ });
33
+ if (transfer.status === "reversed") {
34
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.CONFLICT, "Die chargenspezifische Umbuchung wurde bereits zurückgesetzt und kann nicht fortgesetzt werden.");
35
+ }
36
+ return new workflows_sdk_1.StepResponse(transfer, transfer.status === "batches_applied"
37
+ ? transfer.transfer_run_id
38
+ : undefined);
39
+ }, async (transferRunId, { container }) => {
40
+ if (!transferRunId)
41
+ return;
42
+ await resolveBatchService(container).reverseBatchTransferRun(transferRunId);
43
+ });
44
+ const completeBatchTransferStep = (0, workflows_sdk_1.createStep)("affiliate-complete-batch-inventory-transfer", async (transfer, { container }) => {
45
+ if (transfer.status === "batches_applied") {
46
+ await resolveBatchService(container).completeBatchTransferRun(transfer.transfer_run_id);
47
+ }
48
+ return new workflows_sdk_1.StepResponse(transfer);
49
+ });
50
+ exports.transferBatchAwareInventoryWorkflow = (0, workflows_sdk_1.createWorkflow)("affiliate-batch-aware-inventory-transfer", (input) => {
51
+ const transfer = prepareBatchTransferStep(input);
52
+ const adjustments = (0, workflows_sdk_1.transform)(transfer, (result) => result.status === "batches_applied"
53
+ ? result.lines.flatMap((line) => [
54
+ {
55
+ inventory_item_id: line.inventory_item_id,
56
+ location_id: line.source_location_id,
57
+ adjustment: -line.quantity,
58
+ },
59
+ {
60
+ inventory_item_id: line.inventory_item_id,
61
+ location_id: line.destination_location_id,
62
+ adjustment: line.quantity,
63
+ },
64
+ ])
65
+ : []);
66
+ (0, core_flows_1.adjustInventoryLevelsStep)(adjustments);
67
+ completeBatchTransferStep(transfer);
68
+ return new workflows_sdk_1.WorkflowResponse(transfer);
69
+ });
70
+ const nativeLockKeys = (lines) => [...new Set(lines.map((line) => line.inventory_item_id))].sort((left, right) => left.localeCompare(right));
71
+ const stockedQuantity = async (inventory, adjustment) => {
72
+ const levels = await inventory.listInventoryLevels({
73
+ inventory_item_id: adjustment.inventoryItemId,
74
+ location_id: adjustment.locationId,
75
+ });
76
+ const level = levels.find((candidate) => candidate.inventory_item_id === adjustment.inventoryItemId &&
77
+ candidate.location_id === adjustment.locationId);
78
+ if (!level) {
79
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Inventarbestand am Lagerort wurde nicht gefunden.");
80
+ }
81
+ return level.stocked_quantity;
82
+ };
83
+ const reverseNativeAdjustments = async (inventory, adjustments) => {
84
+ for (const adjustment of [...adjustments].reverse()) {
85
+ await inventory.adjustInventory([
86
+ {
87
+ inventoryItemId: adjustment.inventoryItemId,
88
+ locationId: adjustment.locationId,
89
+ adjustment: -adjustment.adjustment,
90
+ },
91
+ ], {});
92
+ }
93
+ };
94
+ const applyNativeAdjustments = async (inventory, adjustments) => {
95
+ const applied = [];
96
+ for (const adjustment of adjustments) {
97
+ const before = await stockedQuantity(inventory, adjustment);
98
+ try {
99
+ await inventory.adjustInventory([adjustment], {});
100
+ applied.push(adjustment);
101
+ }
102
+ catch (error) {
103
+ const after = await stockedQuantity(inventory, adjustment);
104
+ const actualDelta = after - before;
105
+ if (actualDelta !== 0)
106
+ applied.push({ ...adjustment, adjustment: actualDelta });
107
+ await reverseNativeAdjustments(inventory, applied);
108
+ throw error;
109
+ }
110
+ }
111
+ return applied;
112
+ };
113
+ const transferNativeInventoryStep = (0, workflows_sdk_1.createStep)("affiliate-transfer-native-inventory", async (input, { container }) => {
114
+ if (input.lines.some((line) => line.batch_id !== undefined)) {
115
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Diese Installation verwaltet keine Chargen; eine chargenspezifische Umbuchung ist nicht möglich.");
116
+ }
117
+ const inventory = container.resolve(utils_1.Modules.INVENTORY);
118
+ const locking = container.resolve(utils_1.Modules.LOCKING);
119
+ const locations = container.resolve(utils_1.Modules.STOCK_LOCATION);
120
+ const adjustments = await locking.execute(nativeLockKeys(input.lines), async () => {
121
+ const totals = new Map();
122
+ for (const line of input.lines) {
123
+ if (!Number.isSafeInteger(line.quantity) || line.quantity <= 0) {
124
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Transfermengen müssen positive ganze Zahlen sein.");
125
+ }
126
+ if (line.source_location_id === line.destination_location_id) {
127
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Quelle und Ziel einer Bestandsumbuchung müssen unterschiedlich sein.");
128
+ }
129
+ await Promise.all([
130
+ locations.retrieveStockLocation(line.source_location_id),
131
+ locations.retrieveStockLocation(line.destination_location_id),
132
+ inventory.retrieveInventoryItem(line.inventory_item_id),
133
+ inventory.retrieveInventoryLevelByItemAndLocation(line.inventory_item_id, line.source_location_id),
134
+ inventory.retrieveInventoryLevelByItemAndLocation(line.inventory_item_id, line.destination_location_id),
135
+ ]);
136
+ const key = `${line.inventory_item_id}:${line.source_location_id}`;
137
+ totals.set(key, (totals.get(key) ?? 0) + line.quantity);
138
+ }
139
+ for (const [key, quantity] of totals) {
140
+ const [itemId, locationId] = key.split(":", 2);
141
+ if (Number(await inventory.retrieveAvailableQuantity(itemId, [locationId])) < quantity) {
142
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Der Bestand am Quelllager reicht für die Umbuchung nicht aus.");
143
+ }
144
+ }
145
+ return await applyNativeAdjustments(inventory, input.lines.flatMap((line) => [
146
+ {
147
+ inventoryItemId: line.inventory_item_id,
148
+ locationId: line.source_location_id,
149
+ adjustment: -line.quantity,
150
+ },
151
+ {
152
+ inventoryItemId: line.inventory_item_id,
153
+ locationId: line.destination_location_id,
154
+ adjustment: line.quantity,
155
+ },
156
+ ]));
157
+ });
158
+ return new workflows_sdk_1.StepResponse(input, { adjustments });
159
+ }, async (compensation, { container }) => {
160
+ if (!compensation?.adjustments.length)
161
+ return;
162
+ const inventory = container.resolve(utils_1.Modules.INVENTORY);
163
+ const locking = container.resolve(utils_1.Modules.LOCKING);
164
+ await locking.execute(nativeLockKeys(compensation.adjustments.map((adjustment) => ({
165
+ inventory_item_id: adjustment.inventoryItemId,
166
+ }))), async () => await reverseNativeAdjustments(inventory, compensation.adjustments));
167
+ });
168
+ exports.transferNativeInventoryWorkflow = (0, workflows_sdk_1.createWorkflow)("affiliate-native-inventory-transfer", (input) => {
169
+ const transfer = transferNativeInventoryStep(input);
170
+ return new workflows_sdk_1.WorkflowResponse(transfer);
171
+ });
172
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmZXItYmF0Y2gtYXdhcmUtaW52ZW50b3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9hZmZpbGlhdGUvdHJhbnNmZXItYmF0Y2gtYXdhcmUtaW52ZW50b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQU0yQztBQUszQyxxREFBaUU7QUFDakUsNERBQXdFO0FBaUN4RSxNQUFNLGtCQUFrQixHQUFHLGtCQUFrQixDQUFDO0FBQzlDLE1BQU0sZUFBZSxHQUNuQiwrSEFBK0gsQ0FBQztBQUVsSSxNQUFNLG1CQUFtQixHQUFHLENBQUMsU0FFNUIsRUFBZ0IsRUFBRTtJQUNqQixNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDdEQsSUFDRSxPQUFPLE9BQU8sS0FBSyxRQUFRO1FBQzNCLE9BQU8sS0FBSyxJQUFJO1FBQ2hCLENBQUMsQ0FBQyxpQkFBaUIsSUFBSSxPQUFPLENBQUM7UUFDL0IsT0FBTyxPQUFPLENBQUMsZUFBZSxLQUFLLFVBQVU7UUFDN0MsQ0FBQyxDQUFDLDBCQUEwQixJQUFJLE9BQU8sQ0FBQztRQUN4QyxPQUFPLE9BQU8sQ0FBQyx3QkFBd0IsS0FBSyxVQUFVO1FBQ3RELENBQUMsQ0FBQyx5QkFBeUIsSUFBSSxPQUFPLENBQUM7UUFDdkMsT0FBTyxPQUFPLENBQUMsdUJBQXVCLEtBQUssVUFBVSxFQUNyRCxDQUFDO1FBQ0QsTUFBTSxJQUFJLG1CQUFXLENBQUMsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLGVBQWUsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFRCxPQUFPLE9BQXVCLENBQUM7QUFDakMsQ0FBQyxDQUFDO0FBRUYsTUFBTSx3QkFBd0IsR0FBRyxJQUFBLDBCQUFVLEVBQ3pDLDRDQUE0QyxFQUM1QyxLQUFLLEVBQUUsS0FBNkIsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUU7SUFDckQsTUFBTSxZQUFZLEdBQUcsbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDcEQsTUFBTSxRQUFRLEdBQUcsTUFBTSxZQUFZLENBQUMsZUFBZSxDQUFDO1FBQ2xELGVBQWUsRUFBRSxLQUFLLENBQUMsZUFBZTtRQUN0QyxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDaEMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFrQjtZQUNqQyx1QkFBdUIsRUFBRSxJQUFJLENBQUMsdUJBQXVCO1lBQ3JELFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtTQUN4QixDQUFDLENBQUM7S0FDSixDQUFDLENBQUM7SUFDSCxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDbkMsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFDMUIsaUdBQWlHLENBQ2xHLENBQUM7SUFDSixDQUFDO0lBRUQsT0FBTyxJQUFJLDRCQUFZLENBQ3JCLFFBQVEsRUFDUixRQUFRLENBQUMsTUFBTSxLQUFLLGlCQUFpQjtRQUNuQyxDQUFDLENBQUMsUUFBUSxDQUFDLGVBQWU7UUFDMUIsQ0FBQyxDQUFDLFNBQVMsQ0FDZCxDQUFDO0FBQ0osQ0FBQyxFQUNELEtBQUssRUFBRSxhQUFhLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFO0lBQ3JDLElBQUksQ0FBQyxhQUFhO1FBQUUsT0FBTztJQUMzQixNQUFNLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxDQUFDLHVCQUF1QixDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQzlFLENBQUMsQ0FDRixDQUFDO0FBRUYsTUFBTSx5QkFBeUIsR0FBRyxJQUFBLDBCQUFVLEVBQzFDLDZDQUE2QyxFQUM3QyxLQUFLLEVBQUUsUUFBNkIsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUU7SUFDckQsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLGlCQUFpQixFQUFFLENBQUM7UUFDMUMsTUFBTSxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyx3QkFBd0IsQ0FDM0QsUUFBUSxDQUFDLGVBQWUsQ0FDekIsQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLElBQUksNEJBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNwQyxDQUFDLENBQ0YsQ0FBQztBQUVXLFFBQUEsbUNBQW1DLEdBQUcsSUFBQSw4QkFBYyxFQUMvRCwwQ0FBMEMsRUFDMUMsQ0FBQyxLQUE2QixFQUFFLEVBQUU7SUFDaEMsTUFBTSxRQUFRLEdBQUcsd0JBQXdCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakQsTUFBTSxXQUFXLEdBQUcsSUFBQSx5QkFBUyxFQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQ2pELE1BQU0sQ0FBQyxNQUFNLEtBQUssaUJBQWlCO1FBQ2pDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7WUFDN0I7Z0JBQ0UsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLGlCQUFpQjtnQkFDekMsV0FBVyxFQUFFLElBQUksQ0FBQyxrQkFBa0I7Z0JBQ3BDLFVBQVUsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRO2FBQzNCO1lBQ0Q7Z0JBQ0UsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLGlCQUFpQjtnQkFDekMsV0FBVyxFQUFFLElBQUksQ0FBQyx1QkFBdUI7Z0JBQ3pDLFVBQVUsRUFBRSxJQUFJLENBQUMsUUFBUTthQUMxQjtTQUNGLENBQUM7UUFDSixDQUFDLENBQUMsRUFBRSxDQUNQLENBQUM7SUFFRixJQUFBLHNDQUF5QixFQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3ZDLHlCQUF5QixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRXBDLE9BQU8sSUFBSSxnQ0FBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUN4QyxDQUFDLENBQ0YsQ0FBQztBQVlGLE1BQU0sY0FBYyxHQUFHLENBQ3JCLEtBRUMsRUFDUyxFQUFFLENBQ1osQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQzVELENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FDM0MsQ0FBQztBQUVKLE1BQU0sZUFBZSxHQUFHLEtBQUssRUFDM0IsU0FBNEIsRUFDNUIsVUFBNkUsRUFDNUQsRUFBRTtJQUNuQixNQUFNLE1BQU0sR0FBRyxNQUFNLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQztRQUNqRCxpQkFBaUIsRUFBRSxVQUFVLENBQUMsZUFBZTtRQUM3QyxXQUFXLEVBQUUsVUFBVSxDQUFDLFVBQVU7S0FDbkMsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FDdkIsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUNaLFNBQVMsQ0FBQyxpQkFBaUIsS0FBSyxVQUFVLENBQUMsZUFBZTtRQUMxRCxTQUFTLENBQUMsV0FBVyxLQUFLLFVBQVUsQ0FBQyxVQUFVLENBQ2xELENBQUM7SUFDRixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUMzQixtREFBbUQsQ0FDcEQsQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQztBQUNoQyxDQUFDLENBQUM7QUFFRixNQUFNLHdCQUF3QixHQUFHLEtBQUssRUFDcEMsU0FBNEIsRUFDNUIsV0FBd0MsRUFDekIsRUFBRTtJQUNqQixLQUFLLE1BQU0sVUFBVSxJQUFJLENBQUMsR0FBRyxXQUFXLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1FBQ3BELE1BQU0sU0FBUyxDQUFDLGVBQWUsQ0FDN0I7WUFDRTtnQkFDRSxlQUFlLEVBQUUsVUFBVSxDQUFDLGVBQWU7Z0JBQzNDLFVBQVUsRUFBRSxVQUFVLENBQUMsVUFBVTtnQkFDakMsVUFBVSxFQUFFLENBQUMsVUFBVSxDQUFDLFVBQVU7YUFDbkM7U0FDRixFQUNELEVBQUUsQ0FDSCxDQUFDO0lBQ0osQ0FBQztBQUNILENBQUMsQ0FBQztBQUVGLE1BQU0sc0JBQXNCLEdBQUcsS0FBSyxFQUNsQyxTQUE0QixFQUM1QixXQUF3QyxFQUNGLEVBQUU7SUFDeEMsTUFBTSxPQUFPLEdBQWdDLEVBQUUsQ0FBQztJQUNoRCxLQUFLLE1BQU0sVUFBVSxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQ3JDLE1BQU0sTUFBTSxHQUFHLE1BQU0sZUFBZSxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUM7WUFDSCxNQUFNLFNBQVMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNsRCxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzNCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxLQUFLLEdBQUcsTUFBTSxlQUFlLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQzNELE1BQU0sV0FBVyxHQUFHLEtBQUssR0FBRyxNQUFNLENBQUM7WUFDbkMsSUFBSSxXQUFXLEtBQUssQ0FBQztnQkFDbkIsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsVUFBVSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO1lBQzNELE1BQU0sd0JBQXdCLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ25ELE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDLENBQUM7QUFFRixNQUFNLDJCQUEyQixHQUFHLElBQUEsMEJBQVUsRUFDNUMscUNBQXFDLEVBQ3JDLEtBQUssRUFBRSxLQUE2QixFQUFFLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRTtJQUNyRCxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDNUQsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsa0dBQWtHLENBQ25HLENBQUM7SUFDSixDQUFDO0lBQ0QsTUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxlQUFPLENBQUMsU0FBUyxDQUFzQixDQUFDO0lBQzVFLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsZUFBTyxDQUFDLE9BQU8sQ0FBbUIsQ0FBQztJQUNyRSxNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLGVBQU8sQ0FBQyxjQUFjLENBRXpELENBQUM7SUFDRixNQUFNLFdBQVcsR0FBRyxNQUFNLE9BQU8sQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNoRixNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztRQUN6QyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMvQixJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDL0QsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsbURBQW1ELENBQ3BELENBQUM7WUFDSixDQUFDO1lBQ0QsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEtBQUssSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7Z0JBQzdELE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLHNFQUFzRSxDQUN2RSxDQUFDO1lBQ0osQ0FBQztZQUNELE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztnQkFDaEIsU0FBUyxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztnQkFDeEQsU0FBUyxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQztnQkFDN0QsU0FBUyxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztnQkFDdkQsU0FBUyxDQUFDLHVDQUF1QyxDQUMvQyxJQUFJLENBQUMsaUJBQWlCLEVBQ3RCLElBQUksQ0FBQyxrQkFBa0IsQ0FDeEI7Z0JBQ0QsU0FBUyxDQUFDLHVDQUF1QyxDQUMvQyxJQUFJLENBQUMsaUJBQWlCLEVBQ3RCLElBQUksQ0FBQyx1QkFBdUIsQ0FDN0I7YUFDRixDQUFDLENBQUM7WUFDSCxNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUNuRSxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzFELENBQUM7UUFDRCxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLElBQUksTUFBTSxFQUFFLENBQUM7WUFDckMsTUFBTSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMvQyxJQUNFLE1BQU0sQ0FDSixNQUFNLFNBQVMsQ0FBQyx5QkFBeUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUNoRSxHQUFHLFFBQVEsRUFDWixDQUFDO2dCQUNELE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLCtEQUErRCxDQUNoRSxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLE1BQU0sc0JBQXNCLENBQ2pDLFNBQVMsRUFDVCxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7WUFDNUI7Z0JBQ0UsZUFBZSxFQUFFLElBQUksQ0FBQyxpQkFBaUI7Z0JBQ3ZDLFVBQVUsRUFBRSxJQUFJLENBQUMsa0JBQWtCO2dCQUNuQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUTthQUMzQjtZQUNEO2dCQUNFLGVBQWUsRUFBRSxJQUFJLENBQUMsaUJBQWlCO2dCQUN2QyxVQUFVLEVBQUUsSUFBSSxDQUFDLHVCQUF1QjtnQkFDeEMsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRO2FBQzFCO1NBQ0YsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJQUVILE9BQU8sSUFBSSw0QkFBWSxDQUNyQixLQUFLLEVBQ0wsRUFBRSxXQUFXLEVBQUUsQ0FDaEIsQ0FBQztBQUNKLENBQUMsRUFDRCxLQUFLLEVBQUUsWUFBWSxFQUFFLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRTtJQUNwQyxJQUFJLENBQUMsWUFBWSxFQUFFLFdBQVcsQ0FBQyxNQUFNO1FBQUUsT0FBTztJQUM5QyxNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLGVBQU8sQ0FBQyxTQUFTLENBQXNCLENBQUM7SUFDNUUsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxlQUFPLENBQUMsT0FBTyxDQUFtQixDQUFDO0lBQ3JFLE1BQU0sT0FBTyxDQUFDLE9BQU8sQ0FDbkIsY0FBYyxDQUNaLFlBQVksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLGlCQUFpQixFQUFFLFVBQVUsQ0FBQyxlQUFlO0tBQzlDLENBQUMsQ0FBQyxDQUNKLEVBQ0QsS0FBSyxJQUFJLEVBQUUsQ0FDVCxNQUFNLHdCQUF3QixDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsV0FBVyxDQUFDLENBQ3RFLENBQUM7QUFDSixDQUFDLENBQ0YsQ0FBQztBQUVXLFFBQUEsK0JBQStCLEdBQUcsSUFBQSw4QkFBYyxFQUMzRCxxQ0FBcUMsRUFDckMsQ0FBQyxLQUE2QixFQUFFLEVBQUU7SUFDaEMsTUFBTSxRQUFRLEdBQUcsMkJBQTJCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDcEQsT0FBTyxJQUFJLGdDQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3hDLENBQUMsQ0FDRixDQUFDIn0=