UNPKG

@devx-commerce/plugin-loyalty

Version:

A starter for Medusa plugins.

119 lines 9.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.applyLoyaltyOnCartWorkflow = void 0; const utils_1 = require("@medusajs/framework/utils"); const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk"); const core_flows_1 = require("@medusajs/medusa/core-flows"); const query_config_1 = require("../../api/store/carts/query-config"); const helper_1 = require("../../utils/helper"); const update_cart_promotion_1 = require("./custom/update-cart-promotion"); const calculate_points_on_cart_1 = require("./steps/calculate-points-on-cart"); const get_cart_promotion_1 = require("./steps/get-cart-promotion"); const validate_customer_exists_1 = require("./steps/validate-customer-exists"); exports.applyLoyaltyOnCartWorkflow = (0, workflows_sdk_1.createWorkflow)("apply-loyalty-on-cart", (input) => { const { data: carts } = (0, core_flows_1.useQueryGraphStep)({ entity: "cart", fields: query_config_1.cartFields, filters: { id: input.cart_id }, options: { throwIfKeyNotFound: true }, }); const cart = (0, workflows_sdk_1.transform)({ carts }, ({ carts }) => carts[0]); (0, validate_customer_exists_1.validateCustomerExistsStep)({ customer: cart.customer, }); // Check if loyalty promotion already exists on cart. (0, get_cart_promotion_1.getCartPromotionStep)({ cart, throwErrorOn: "found" }); // calculate amount that will be used to create loyalty promotion const amount = (0, calculate_points_on_cart_1.calculatePointsOnCartStep)({ cart, throwOnZeroPoints: input.throwOnZeroPoints, }); // Only create and apply promotion if amount > 0 (0, workflows_sdk_1.when)({ amount }, ({ amount }) => amount > 0).then(() => { // create promotion payload const promotionPayload = (0, workflows_sdk_1.transform)({ cart, amount, }, (data) => { const randomStr = Math.random().toString(36).substring(2, 8); const idSuffix = (data.cart.customer?.id || data.cart.id || "CART").slice(-6); const uniqueId = `LOYALTY-${idSuffix}-${randomStr}`.toUpperCase(); return { code: uniqueId, type: "standard", status: "active", application_method: { type: "fixed", value: data.amount, target_type: "order", currency_code: data.cart.currency_code, allocation: "across", }, rules: [ { attribute: helper_1.CUSTOMER_ID_PROMOTION_RULE_ATTRIBUTE, operator: "eq", values: [data.cart.customer.id], }, ], campaign: { name: uniqueId, description: "Loyalty points promotion for " + data.cart.customer.email, campaign_identifier: uniqueId, budget: { type: "usage", limit: 1, }, }, }; }); // create promotion const promotion = (0, core_flows_1.createPromotionsStep)([ promotionPayload, ]); // update cart with promotion const { metadata, ...updatePromoData } = (0, workflows_sdk_1.transform)({ cart, promotionPayload, promotion, }, (data) => { const promos = [ ...(data.cart.promotions ?.map((promo) => promo?.code) .filter(Boolean) || []), data.promotionPayload.code, ]; return { cart_id: data.cart.id, promo_codes: promos, action: utils_1.PromotionActions.ADD, metadata: { ...(data.cart.metadata || {}), loyalty_promo_id: data.promotion[0].id, loyalty_amount_used: data.promotion?.[0]?.application_method?.value || 0, }, }; }); // Write the metadata pointer BEFORE attaching the promotion. // // These are two separate commits and cannot be made one (the promotion // engine owns the attach). Ordering them this way makes the intermediate // state safe: the pointer may briefly name a promotion that is not yet // attached, which every reader already tolerates. The reverse order left // a promotion attached with no pointer — and under concurrency two runs // could both attach before either wrote its pointer, orphaning the loser // permanently. // // Correctness no longer depends on this ordering (readers resolve loyalty // by `LOYALTY-` code, not by the pointer), but it keeps the window benign. (0, core_flows_1.updateCartsStep)([{ id: input.cart_id, metadata }]); update_cart_promotion_1.updateCartPromotionsWorkflow.runAsStep({ input: updatePromoData }); }); return new workflows_sdk_1.WorkflowResponse({ success: true, message: "Loyalty applied on cart successfully", }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbHktbG95YWx0eS1vbi1jYXJ0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9jYXJ0L2FwcGx5LWxveWFsdHktb24tY2FydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxREFBNkQ7QUFDN0QscUVBSzJDO0FBQzNDLDREQUlxQztBQUVyQyxxRUFBZ0U7QUFDaEUsK0NBRzRCO0FBRTVCLDBFQUE4RTtBQUM5RSwrRUFBNkU7QUFDN0UsbUVBQWtFO0FBQ2xFLCtFQUcwQztBQU83QixRQUFBLDBCQUEwQixHQUFHLElBQUEsOEJBQWMsRUFDdEQsdUJBQXVCLEVBQ3ZCLENBQUMsS0FBb0IsRUFBRSxFQUFFO0lBQ3ZCLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsSUFBQSw4QkFBaUIsRUFBQztRQUN4QyxNQUFNLEVBQUUsTUFBTTtRQUNkLE1BQU0sRUFBRSx5QkFBVTtRQUNsQixPQUFPLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRTtRQUM5QixPQUFPLEVBQUUsRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUU7S0FDdEMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxJQUFJLEdBQUcsSUFBQSx5QkFBUyxFQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFhLENBQUMsQ0FBQztJQUV2RSxJQUFBLHFEQUEwQixFQUFDO1FBQ3pCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtLQUNXLENBQUMsQ0FBQztJQUV0QyxxREFBcUQ7SUFDckQsSUFBQSx5Q0FBb0IsRUFBQyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUV0RCxpRUFBaUU7SUFDakUsTUFBTSxNQUFNLEdBQUcsSUFBQSxvREFBeUIsRUFBQztRQUN2QyxJQUFJO1FBQ0os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