@medusajs/core-flows
Version:
Set of workflow definitions for Medusa
209 lines • 8.86 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.refreshCartItemsWorkflow = exports.refreshCartItemsWorkflowId = void 0;
const utils_1 = require("@medusajs/framework/utils");
const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
const use_remote_query_1 = require("../../common/steps/use-remote-query");
const steps_1 = require("../steps");
const validate_variant_prices_1 = require("../steps/validate-variant-prices");
const fields_1 = require("../utils/fields");
const prepare_line_item_data_1 = require("../utils/prepare-line-item-data");
const refresh_cart_shipping_methods_1 = require("./refresh-cart-shipping-methods");
const refresh_payment_collection_1 = require("./refresh-payment-collection");
const update_cart_promotions_1 = require("./update-cart-promotions");
const update_tax_lines_1 = require("./update-tax-lines");
const upsert_tax_lines_1 = require("./upsert-tax-lines");
const schemas_1 = require("../utils/schemas");
exports.refreshCartItemsWorkflowId = "refresh-cart-items";
/**
* This workflow refreshes a cart to ensure its prices, promotion codes, taxes, and other details are applied correctly. It's useful
* after making a chnge to a cart, such as after adding an item to the cart or adding a promotion code.
*
* This workflow is used by other cart-related workflows, such as the {@link addToCartWorkflow} after an item
* is added to the cart.
*
* You can use this workflow within your own customizations or custom workflows, allowing you to refresh the cart after making updates to it in your
* custom flows.
*
* @example
* const { result } = await refreshCartItemsWorkflow(container)
* .run({
* input: {
* cart_id: "cart_123",
* }
* })
*
* @summary
*
* Refresh a cart's details after an update.
*
* @property hooks.setPricingContext - This hook is executed before the cart is refreshed. You can consume this hook to return any custom context useful for the prices retrieval of the variants in the cart.
*
* For example, assuming you have the following custom pricing rule:
*
* ```json
* {
* "attribute": "location_id",
* "operator": "eq",
* "value": "sloc_123",
* }
* ```
*
* You can consume the `setPricingContext` hook to add the `location_id` context to the prices calculation:
*
* ```ts
* import { refreshCartItemsWorkflow } from "@medusajs/medusa/core-flows";
* import { StepResponse } from "@medusajs/workflows-sdk";
*
* refreshCartItemsWorkflow.hooks.setPricingContext((
* { cart, items, additional_data }, { container }
* ) => {
* return new StepResponse({
* location_id: "sloc_123", // Special price for in-store purchases
* });
* });
* ```
*
* The variants' prices will now be retrieved using the context you return.
*
* :::note
*
* Learn more about prices calculation context in the [Prices Calculation](https://docs.medusajs.com/resources/commerce-modules/pricing/price-calculation) documentation.
*
* :::
*
*/
exports.refreshCartItemsWorkflow = (0, workflows_sdk_1.createWorkflow)(exports.refreshCartItemsWorkflowId, (input) => {
const setPricingContext = (0, workflows_sdk_1.createHook)("setPricingContext", {
cart_id: input.cart_id,
items: input.items,
additional_data: input.additional_data,
}, {
resultValidator: schemas_1.pricingContextResult,
});
const setPricingContextResult = setPricingContext.getResult();
(0, workflows_sdk_1.when)({ input }, ({ input }) => {
return !!input.force_refresh;
}).then(() => {
const cart = (0, use_remote_query_1.useRemoteQueryStep)({
entry_point: "cart",
fields: fields_1.cartFieldsForRefreshSteps,
variables: { id: input.cart_id },
list: false,
});
const variantIds = (0, workflows_sdk_1.transform)({ cart }, (data) => {
return (data.cart.items ?? []).map((i) => i.variant_id).filter(Boolean);
});
const cartPricingContext = (0, workflows_sdk_1.transform)({ cart, setPricingContextResult }, (data) => {
return {
...(0, utils_1.filterObjectByKeys)(data.cart, fields_1.cartFieldsForPricingContext),
...(data.setPricingContextResult
? data.setPricingContextResult
: {}),
currency_code: data.cart.currency_code,
region_id: data.cart.region_id,
region: data.cart.region,
customer_id: data.cart.customer_id,
customer: data.cart.customer,
};
});
const variants = (0, use_remote_query_1.useRemoteQueryStep)({
entry_point: "variants",
fields: fields_1.productVariantsFields,
variables: {
id: variantIds,
calculated_price: {
context: cartPricingContext,
},
},
}).config({ name: "fetch-variants" });
(0, validate_variant_prices_1.validateVariantPricesStep)({ variants });
const lineItems = (0, workflows_sdk_1.transform)({ cart, variants }, ({ cart, variants }) => {
const items = cart.items.map((item) => {
const variant = (variants ?? []).find((v) => v.id === item.variant_id);
const input = {
item,
variant: variant,
cartId: cart.id,
unitPrice: item.unit_price,
isTaxInclusive: item.is_tax_inclusive,
};
if (variant && !item.is_custom_price) {
input.unitPrice = variant.calculated_price?.calculated_amount;
input.isTaxInclusive =
variant.calculated_price?.is_calculated_price_tax_inclusive;
}
const preparedItem = (0, prepare_line_item_data_1.prepareLineItemData)(input);
return {
selector: { id: item.id },
data: preparedItem,
};
});
return items;
});
(0, steps_1.updateLineItemsStep)({
id: cart.id,
items: lineItems,
});
});
const refetchedCart = (0, use_remote_query_1.useRemoteQueryStep)({
entry_point: "cart",
fields: fields_1.cartFieldsForRefreshSteps,
variables: { id: input.cart_id },
list: false,
}).config({ name: "refetch–cart" });
const refreshCartInput = (0, workflows_sdk_1.transform)({ refetchedCart, input }, ({ refetchedCart, input }) => {
return {
cart: !input.force_refresh ? refetchedCart : undefined,
cart_id: !!input.force_refresh ? input.cart_id : undefined,
};
});
refresh_cart_shipping_methods_1.refreshCartShippingMethodsWorkflow.runAsStep({
input: refreshCartInput,
});
(0, workflows_sdk_1.when)({ input }, ({ input }) => {
return !!input.force_refresh;
}).then(() => {
update_tax_lines_1.updateTaxLinesWorkflow.runAsStep({
input: refreshCartInput,
});
});
(0, workflows_sdk_1.when)({ input }, ({ input }) => {
return (!input.force_refresh &&
(!!input.items?.length || !!input.shipping_methods?.length));
}).then(() => {
upsert_tax_lines_1.upsertTaxLinesWorkflow.runAsStep({
input: (0, workflows_sdk_1.transform)({ refetchedCart, input }, ({ refetchedCart, input }) => {
return {
cart: refetchedCart,
items: input.items ?? [],
shipping_methods: input.shipping_methods ?? [],
force_tax_calculation: input.force_tax_calculation,
};
}),
});
});
const cartPromoCodes = (0, workflows_sdk_1.transform)({ refetchedCart, input }, ({ refetchedCart, input }) => {
if ((0, utils_1.isDefined)(input.promo_codes)) {
return input.promo_codes;
}
else {
return refetchedCart.promotions.map((p) => p?.code).filter(Boolean);
}
});
update_cart_promotions_1.updateCartPromotionsWorkflow.runAsStep({
input: {
cart_id: input.cart_id,
promo_codes: cartPromoCodes,
action: utils_1.PromotionActions.REPLACE,
},
});
const beforeRefreshingPaymentCollection = (0, workflows_sdk_1.createHook)("beforeRefreshingPaymentCollection", { input });
refresh_payment_collection_1.refreshPaymentCollectionForCartWorkflow.runAsStep({
input: { cart_id: input.cart_id },
});
return new workflows_sdk_1.WorkflowResponse(refetchedCart, {
hooks: [setPricingContext, beforeRefreshingPaymentCollection],
});
});
//# sourceMappingURL=refresh-cart-items.js.map
;