@medusajs/core-flows
Version:
Set of workflow definitions for Medusa
130 lines • 6.45 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.prepareConfirmInventoryInput = void 0;
const utils_1 = require("@medusajs/framework/utils");
/**
* This function prepares the input for the confirm inventory workflow.
* In essesnce, it maps a list of cart items to a list of inventory items,
* serving as a bridge between the cart and inventory domains.
*
* @throws {MedusaError} INVALID_DATA if any cart item is for a variant that has no inventory items.
* @throws {MedusaError} INVALID_DATA if any cart item is for a variant with no stock locations in the input.sales_channel_id. An exception is made for variants with allow_backorder set to true.
*
* @returns {ConfirmInventoryPreparationInput}
* A list of inventory items to confirm. Only inventory items for variants with managed inventory are included.
*/
const prepareConfirmInventoryInput = (data) => {
const productVariantInventoryItems = new Map();
const stockLocationIds = new Set();
const allVariants = new Map();
const mapLocationAvailability = new Map();
const variantsWithLocationForChannel = new Set();
let hasManagedInventory = false;
const salesChannelId = data.input.sales_channel_id;
for (const updateItem of data.input.itemsToUpdate ?? []) {
const updateItem_ = "data" in updateItem ? updateItem.data : updateItem;
const item = data.input.items.find((item) => item.variant_id === updateItem_.variant_id);
if (item && updateItem_.quantity) {
item.quantity = updateItem_.quantity;
}
}
(0, utils_1.deepFlatMap)(data.input, "variants.inventory_items.inventory.location_levels.stock_locations.sales_channels", ({ variants, inventory_items, location_levels, stock_locations, sales_channels, }) => {
if (!variants) {
return;
}
if (salesChannelId && sales_channels?.id === salesChannelId) {
variantsWithLocationForChannel.add(variants.id);
}
if (location_levels && inventory_items) {
const availability = utils_1.MathBN.sub(location_levels.raw_stocked_quantity ??
location_levels.stocked_quantity ??
0, location_levels.raw_reserved_quantity ??
location_levels.reserved_quantity ??
0);
if (!mapLocationAvailability.has(location_levels.location_id)) {
mapLocationAvailability.set(location_levels.location_id, new Map());
}
const locationMap = mapLocationAvailability.get(location_levels.location_id);
locationMap.set(inventory_items.inventory_item_id, new utils_1.BigNumber(availability));
}
if (stock_locations && sales_channels?.id === salesChannelId) {
stockLocationIds.add(stock_locations.id);
}
if (inventory_items) {
const inventoryItemId = inventory_items.inventory_item_id;
const mapKey = `${inventoryItemId}-${inventory_items.variant_id}`;
if (!productVariantInventoryItems.has(mapKey)) {
productVariantInventoryItems.set(mapKey, {
variant_id: inventory_items.variant_id,
inventory_item_id: inventoryItemId,
required_quantity: inventory_items.required_quantity,
});
}
}
if (!allVariants.has(variants.id)) {
if (!hasManagedInventory && variants.manage_inventory) {
hasManagedInventory = true;
}
allVariants.set(variants.id, {
id: variants.id,
manage_inventory: variants.manage_inventory,
allow_backorder: variants.allow_backorder,
});
}
});
if (!hasManagedInventory) {
return { items: [] };
}
if (salesChannelId) {
for (const variant of allVariants.values()) {
if (variant.manage_inventory &&
!variantsWithLocationForChannel.has(variant.id) &&
!variant.allow_backorder) {
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Sales channel ${salesChannelId} is not associated with any stock location for variant ${variant.id}.`);
}
}
}
const items = formatInventoryInput({
product_variant_inventory_items: Array.from(productVariantInventoryItems.values()),
location_ids: Array.from(stockLocationIds),
stockAvailability: mapLocationAvailability,
items: data.input.items,
variants: Array.from(allVariants.values()),
});
return { items };
};
exports.prepareConfirmInventoryInput = prepareConfirmInventoryInput;
const formatInventoryInput = ({ product_variant_inventory_items, location_ids, items, stockAvailability, variants, }) => {
if (!product_variant_inventory_items.length) {
return [];
}
const variantsMap = new Map(variants.map((v) => [v.id, v]));
const itemsToConfirm = [];
items.forEach((item) => {
const variant = variantsMap.get(item.variant_id);
if (!variant?.manage_inventory) {
return;
}
const variantInventoryItems = product_variant_inventory_items.filter((i) => i.variant_id === item.variant_id);
if (!variantInventoryItems.length) {
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Variant ${item.variant_id} does not have any inventory items associated with it.`);
}
variantInventoryItems.forEach((variantInventoryItem) => {
const locationsWithAvailability = location_ids.filter((locId) => utils_1.MathBN.gte(stockAvailability
.get(locId)
?.get(variantInventoryItem.inventory_item_id) ?? 0, utils_1.MathBN.mult(variantInventoryItem.required_quantity, item.quantity)));
itemsToConfirm.push({
id: item.id,
inventory_item_id: variantInventoryItem.inventory_item_id,
required_quantity: variantInventoryItem.required_quantity,
allow_backorder: !!variant.allow_backorder,
quantity: item.quantity,
location_ids: locationsWithAvailability.length
? locationsWithAvailability
: location_ids,
});
});
});
return itemsToConfirm;
};
//# sourceMappingURL=prepare-confirm-inventory-input.js.map
;