UNPKG

@medusajs/core-flows

Version:

Set of workflow definitions for Medusa

221 lines • 9.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createProductVariantsWorkflow = exports.createProductVariantsWorkflowId = void 0; const utils_1 = require("@medusajs/framework/utils"); const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk"); const common_1 = require("../../common"); const create_links_1 = require("../../common/workflows/create-links"); const validate_inventory_items_1 = require("../../inventory/steps/validate-inventory-items"); const create_inventory_items_1 = require("../../inventory/workflows/create-inventory-items"); const pricing_1 = require("../../pricing"); const create_product_variants_1 = require("../steps/create-product-variants"); const create_variant_pricing_link_1 = require("../steps/create-variant-pricing-link"); const buildLink = (variant_id, inventory_item_id, required_quantity) => { const link = { [utils_1.Modules.PRODUCT]: { variant_id }, [utils_1.Modules.INVENTORY]: { inventory_item_id: inventory_item_id }, data: { required_quantity: required_quantity }, }; return link; }; const validateVariantsDuplicateInventoryItemIds = (variantsData) => { const erroredVariantIds = []; for (const variantData of variantsData) { const inventoryItemIds = variantData.inventory_items.map((item) => item.inventory_item_id); const duplicatedInventoryItemIds = inventoryItemIds.filter((id, index) => inventoryItemIds.indexOf(id) !== index); if (duplicatedInventoryItemIds.length) { erroredVariantIds.push(variantData.variantId); } } if (erroredVariantIds.length) { throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Cannot associate duplicate inventory items to variant(s) ${erroredVariantIds.join("\n")}`); } }; const buildLinksToCreate = (data) => { let index = 0; const linksToCreate = []; validateVariantsDuplicateInventoryItemIds((data.createdVariants ?? []).map((variant, index) => { const variantInput = data.input.product_variants[index]; const inventoryItems = variantInput.inventory_items || []; return { variantId: variant.id, inventory_items: inventoryItems, }; })); for (const variant of data.createdVariants) { const variantInput = data.input.product_variants[index]; const shouldManageInventory = variant.manage_inventory; const hasInventoryItems = variantInput.inventory_items?.length; index += 1; if (!shouldManageInventory) { continue; } if (!hasInventoryItems) { const inventoryItem = data.inventoryIndexMap[index]; linksToCreate.push(buildLink(variant.id, inventoryItem.id, 1)); continue; } for (const inventoryInput of variantInput.inventory_items || []) { linksToCreate.push(buildLink(variant.id, inventoryInput.inventory_item_id, inventoryInput.required_quantity ?? 1)); } } return linksToCreate; }; const buildVariantItemCreateMap = (data) => { let index = 0; const map = {}; for (const variant of data.createdVariants || []) { const variantInput = data.input.product_variants[index]; const shouldManageInventory = variant.manage_inventory; const hasInventoryItems = variantInput.inventory_items?.length; index += 1; if (!shouldManageInventory || hasInventoryItems) { continue; } // Create a default inventory item if the above conditions arent met map[index] = { sku: variantInput.sku, origin_country: variantInput.origin_country, mid_code: variantInput.mid_code, material: variantInput.material, weight: variantInput.weight, length: variantInput.length, height: variantInput.height, width: variantInput.width, title: variantInput.title, description: variantInput.title, hs_code: variantInput.hs_code, requires_shipping: true, }; } return map; }; exports.createProductVariantsWorkflowId = "create-product-variants"; /** * This workflow creates one or more product variants. It's used by the [Create Product Variant Admin API Route](https://docs.medusajs.com/api/admin#products_postproductsidvariants). * * This workflow has a hook that allows you to perform custom actions on the created product variants. For example, you can pass under `additional_data` custom data that * allows you to create custom data models linked to the product variants. * * You can also use this workflow within your customizations or your own custom workflows, allowing you to wrap custom logic around product-variant creation. * * :::note * * Learn more about adding rules to the product variant's prices in the Pricing Module's * [Price Rules](https://docs.medusajs.com/resources/commerce-modules/pricing/price-rules) documentation. * * ::: * * @example * const { result } = await createProductVariantsWorkflow(container) * .run({ * input: { * product_variants: [ * { * product_id: "prod_123", * sku: "SHIRT-123", * title: "Small Shirt", * prices: [ * { * amount: 10, * currency_code: "USD", * }, * ], * options: { * Size: "Small", * }, * }, * ], * additional_data: { * erp_id: "123" * } * } * }) * * @summary * * Create one or more product variants. * * @property hooks.productVariantsCreated - This hook is executed after the product variants are created. You can consume this hook to perform custom actions on the created product variants. */ exports.createProductVariantsWorkflow = (0, workflows_sdk_1.createWorkflow)(exports.createProductVariantsWorkflowId, (input) => { // Passing prices to the product module will fail, we want to keep them for after the variant is created. const variantsWithoutPrices = (0, workflows_sdk_1.transform)({ input }, (data) => data.input.product_variants.map((v) => ({ ...v, prices: undefined, }))); const createdVariants = (0, create_product_variants_1.createProductVariantsStep)(variantsWithoutPrices); // Setup variants inventory const inventoryItemIds = (0, workflows_sdk_1.transform)(input, (data) => { return data.product_variants .map((variant) => variant.inventory_items || []) .flat() .map((item) => item.inventory_item_id) .flat(); }); (0, validate_inventory_items_1.validateInventoryItems)(inventoryItemIds); const variantItemCreateMap = (0, workflows_sdk_1.transform)({ createdVariants, input }, buildVariantItemCreateMap); const createdInventoryItems = create_inventory_items_1.createInventoryItemsWorkflow.runAsStep({ input: { items: (0, workflows_sdk_1.transform)(variantItemCreateMap, (data) => Object.values(data)), }, }); const inventoryIndexMap = (0, workflows_sdk_1.transform)({ createdInventoryItems, variantItemCreateMap }, (data) => { const map = {}; let inventoryIndex = 0; for (const variantIndex of Object.keys(data.variantItemCreateMap)) { map[variantIndex] = data.createdInventoryItems[inventoryIndex]; inventoryIndex += 1; } return map; }); const linksToCreate = (0, workflows_sdk_1.transform)({ createdVariants, inventoryIndexMap, input }, buildLinksToCreate); create_links_1.createLinksWorkflow.runAsStep({ input: linksToCreate }); // Note: We rely on the same order of input and output when creating variants here, make sure that assumption holds const pricesToCreate = (0, workflows_sdk_1.transform)({ input, createdVariants }, (data) => data.createdVariants.map((v, i) => { return { prices: data.input.product_variants[i]?.prices, }; })); const createdPriceSets = (0, pricing_1.createPriceSetsStep)(pricesToCreate); const variantAndPriceSets = (0, workflows_sdk_1.transform)({ createdVariants, createdPriceSets }, (data) => { return data.createdVariants.map((variant, i) => ({ variant: variant, price_set: data.createdPriceSets[i], })); }); const variantAndPriceSetLinks = (0, workflows_sdk_1.transform)({ variantAndPriceSets }, (data) => { return { links: data.variantAndPriceSets.map((entry) => ({ variant_id: entry.variant.id, price_set_id: entry.price_set.id, })), }; }); (0, create_variant_pricing_link_1.createVariantPricingLinkStep)(variantAndPriceSetLinks); const response = (0, workflows_sdk_1.transform)({ variantAndPriceSets, }, (data) => { return data.variantAndPriceSets.map((variantAndPriceSet) => ({ ...variantAndPriceSet.variant, prices: variantAndPriceSet?.price_set?.prices || [], })); }); const variantIdEvents = (0, workflows_sdk_1.transform)({ response }, ({ response }) => { return response.map((v) => { return { id: v.id }; }); }); (0, common_1.emitEventStep)({ eventName: utils_1.ProductVariantWorkflowEvents.CREATED, data: variantIdEvents, }); const productVariantsCreated = (0, workflows_sdk_1.createHook)("productVariantsCreated", { product_variants: response, additional_data: input.additional_data, }); return new workflows_sdk_1.WorkflowResponse(response, { hooks: [productVariantsCreated], }); }); //# sourceMappingURL=create-product-variants.js.map