chore(core-flows): Cleanup old code (#7547)
Remove the old handlers and definitions that does not work anymore or are not used anymore. This legacy was bothering a refactoring we have with @thetutlage
This commit is contained in:
committed by
GitHub
parent
eeb8225b5e
commit
4e20588522
@@ -1,5 +1,3 @@
|
||||
export * from "./cart"
|
||||
export * from "./inventory"
|
||||
export * from "./line-item"
|
||||
export * from "./payment-collection"
|
||||
export * from "./product"
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
import { Workflows } from "../../definitions"
|
||||
import {
|
||||
TransactionStepsDefinition,
|
||||
WorkflowManager,
|
||||
} from "@medusajs/orchestration"
|
||||
import { exportWorkflow, pipe } from "@medusajs/workflows-sdk"
|
||||
|
||||
import { InventoryTypes, WorkflowTypes } from "@medusajs/types"
|
||||
import { InventoryHandlers } from "../../handlers"
|
||||
|
||||
export enum CreateInventoryItemActions {
|
||||
prepare = "prepare",
|
||||
createInventoryItems = "createInventoryItems",
|
||||
}
|
||||
|
||||
const workflowSteps: TransactionStepsDefinition = {
|
||||
next: {
|
||||
action: CreateInventoryItemActions.createInventoryItems,
|
||||
},
|
||||
}
|
||||
|
||||
const handlers = new Map([
|
||||
[
|
||||
CreateInventoryItemActions.createInventoryItems,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
inputAlias: CreateInventoryItemActions.prepare,
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: CreateInventoryItemActions.prepare,
|
||||
},
|
||||
},
|
||||
InventoryHandlers.createInventoryItems
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: CreateInventoryItemActions.createInventoryItems,
|
||||
alias:
|
||||
InventoryHandlers.removeInventoryItems.aliases.inventoryItems,
|
||||
},
|
||||
},
|
||||
InventoryHandlers.removeInventoryItems
|
||||
),
|
||||
},
|
||||
],
|
||||
])
|
||||
|
||||
WorkflowManager.register(
|
||||
Workflows.CreateInventoryItems,
|
||||
workflowSteps,
|
||||
handlers
|
||||
)
|
||||
|
||||
export const createInventoryItems = exportWorkflow<
|
||||
WorkflowTypes.InventoryWorkflow.CreateInventoryItemsWorkflowInputDTO,
|
||||
{ tag: string; inventoryItem: InventoryTypes.InventoryItemDTO }[]
|
||||
>(
|
||||
Workflows.CreateInventoryItems,
|
||||
CreateInventoryItemActions.createInventoryItems,
|
||||
async (data) => data
|
||||
)
|
||||
@@ -1 +0,0 @@
|
||||
export * from "./create-inventory-item"
|
||||
@@ -1,121 +0,0 @@
|
||||
import {
|
||||
TransactionStepsDefinition,
|
||||
WorkflowManager,
|
||||
} from "@medusajs/orchestration"
|
||||
import { InputAlias, Workflows } from "../../definitions"
|
||||
import { exportWorkflow, pipe } from "@medusajs/workflows-sdk"
|
||||
|
||||
import { ProductTypes, WorkflowTypes } from "@medusajs/types"
|
||||
import { ProductHandlers } from "../../handlers"
|
||||
|
||||
export enum CreateProductVariantsActions {
|
||||
prepare = "prepare",
|
||||
createProductVariants = "createProductVariants",
|
||||
revertProductVariantsCreate = "revertProductVariantsCreate",
|
||||
upsertPrices = "upsertPrices",
|
||||
}
|
||||
|
||||
export const workflowSteps: TransactionStepsDefinition = {
|
||||
next: {
|
||||
action: CreateProductVariantsActions.prepare,
|
||||
noCompensation: true,
|
||||
next: {
|
||||
action: CreateProductVariantsActions.createProductVariants,
|
||||
next: [
|
||||
{
|
||||
action: CreateProductVariantsActions.upsertPrices,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const handlers = new Map([
|
||||
[
|
||||
CreateProductVariantsActions.prepare,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
inputAlias: InputAlias.ProductVariantsCreateInputData,
|
||||
invoke: {
|
||||
from: InputAlias.ProductVariantsCreateInputData,
|
||||
},
|
||||
},
|
||||
ProductHandlers.createProductVariantsPrepareData
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
CreateProductVariantsActions.createProductVariants,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: CreateProductVariantsActions.prepare,
|
||||
},
|
||||
},
|
||||
ProductHandlers.createProductVariants
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: CreateProductVariantsActions.prepare,
|
||||
},
|
||||
{
|
||||
from: CreateProductVariantsActions.createProductVariants,
|
||||
},
|
||||
],
|
||||
},
|
||||
ProductHandlers.removeProductVariants
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
CreateProductVariantsActions.upsertPrices,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: CreateProductVariantsActions.createProductVariants,
|
||||
},
|
||||
],
|
||||
},
|
||||
ProductHandlers.upsertVariantPrices
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: CreateProductVariantsActions.prepare,
|
||||
},
|
||||
{
|
||||
from: CreateProductVariantsActions.upsertPrices,
|
||||
},
|
||||
],
|
||||
},
|
||||
ProductHandlers.revertVariantPrices
|
||||
),
|
||||
},
|
||||
],
|
||||
])
|
||||
|
||||
WorkflowManager.register(
|
||||
Workflows.CreateProductVariants,
|
||||
workflowSteps,
|
||||
handlers
|
||||
)
|
||||
|
||||
export const createProductVariants = exportWorkflow<
|
||||
WorkflowTypes.ProductWorkflow.CreateProductVariantsWorkflowInputDTO,
|
||||
ProductTypes.ProductVariantDTO[]
|
||||
>(
|
||||
Workflows.CreateProductVariants,
|
||||
CreateProductVariantsActions.createProductVariants
|
||||
)
|
||||
@@ -1,274 +0,0 @@
|
||||
import { InputAlias, Workflows } from "../../definitions"
|
||||
import {
|
||||
TransactionStepsDefinition,
|
||||
WorkflowManager,
|
||||
} from "@medusajs/orchestration"
|
||||
import { exportWorkflow, pipe } from "@medusajs/workflows-sdk"
|
||||
|
||||
import { ProductTypes, WorkflowTypes } from "@medusajs/types"
|
||||
import {
|
||||
InventoryHandlers,
|
||||
MiddlewaresHandlers,
|
||||
ProductHandlers,
|
||||
} from "../../handlers"
|
||||
import { prepareCreateInventoryItems } from "./prepare-create-inventory-items"
|
||||
|
||||
export enum CreateProductsActions {
|
||||
prepare = "prepare",
|
||||
createProducts = "createProducts",
|
||||
attachToSalesChannel = "attachToSalesChannel",
|
||||
attachShippingProfile = "attachShippingProfile",
|
||||
createPrices = "createPrices",
|
||||
createInventoryItems = "createInventoryItems",
|
||||
attachInventoryItems = "attachInventoryItems",
|
||||
}
|
||||
|
||||
export const workflowSteps: TransactionStepsDefinition = {
|
||||
next: {
|
||||
action: CreateProductsActions.prepare,
|
||||
noCompensation: true,
|
||||
next: {
|
||||
action: CreateProductsActions.createProducts,
|
||||
next: [
|
||||
{
|
||||
action: CreateProductsActions.attachShippingProfile,
|
||||
saveResponse: false,
|
||||
},
|
||||
{
|
||||
action: CreateProductsActions.attachToSalesChannel,
|
||||
saveResponse: false,
|
||||
},
|
||||
{
|
||||
action: CreateProductsActions.createPrices,
|
||||
next: {
|
||||
action: CreateProductsActions.createInventoryItems,
|
||||
next: {
|
||||
action: CreateProductsActions.attachInventoryItems,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const handlers = new Map([
|
||||
[
|
||||
CreateProductsActions.prepare,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
inputAlias: InputAlias.ProductsInputData,
|
||||
invoke: {
|
||||
from: InputAlias.ProductsInputData,
|
||||
},
|
||||
},
|
||||
ProductHandlers.createProductsPrepareData
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
CreateProductsActions.createProducts,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: CreateProductsActions.prepare,
|
||||
},
|
||||
},
|
||||
ProductHandlers.createProducts
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: CreateProductsActions.createProducts,
|
||||
alias: ProductHandlers.removeProducts.aliases.products,
|
||||
},
|
||||
},
|
||||
ProductHandlers.removeProducts
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
CreateProductsActions.attachShippingProfile,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: CreateProductsActions.prepare,
|
||||
},
|
||||
{
|
||||
from: CreateProductsActions.createProducts,
|
||||
alias:
|
||||
ProductHandlers.attachShippingProfileToProducts.aliases
|
||||
.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
ProductHandlers.attachShippingProfileToProducts
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: CreateProductsActions.prepare,
|
||||
},
|
||||
{
|
||||
from: CreateProductsActions.createProducts,
|
||||
alias:
|
||||
ProductHandlers.detachShippingProfileFromProducts.aliases
|
||||
.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
ProductHandlers.detachShippingProfileFromProducts
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
CreateProductsActions.attachToSalesChannel,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: CreateProductsActions.prepare,
|
||||
},
|
||||
{
|
||||
from: CreateProductsActions.createProducts,
|
||||
alias:
|
||||
ProductHandlers.attachSalesChannelToProducts.aliases.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
ProductHandlers.attachSalesChannelToProducts
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: CreateProductsActions.prepare,
|
||||
},
|
||||
{
|
||||
from: CreateProductsActions.createProducts,
|
||||
alias:
|
||||
ProductHandlers.detachSalesChannelFromProducts.aliases.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
ProductHandlers.detachSalesChannelFromProducts
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
CreateProductsActions.createInventoryItems,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: CreateProductsActions.createProducts,
|
||||
alias: prepareCreateInventoryItems.aliases.products,
|
||||
},
|
||||
},
|
||||
prepareCreateInventoryItems,
|
||||
InventoryHandlers.createInventoryItems
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: CreateProductsActions.createInventoryItems,
|
||||
alias:
|
||||
InventoryHandlers.removeInventoryItems.aliases.inventoryItems,
|
||||
},
|
||||
},
|
||||
InventoryHandlers.removeInventoryItems
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
CreateProductsActions.attachInventoryItems,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: CreateProductsActions.createInventoryItems,
|
||||
alias:
|
||||
InventoryHandlers.attachInventoryItems.aliases.inventoryItems,
|
||||
},
|
||||
},
|
||||
InventoryHandlers.attachInventoryItems
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: CreateProductsActions.createInventoryItems,
|
||||
alias:
|
||||
InventoryHandlers.detachInventoryItems.aliases.inventoryItems,
|
||||
},
|
||||
},
|
||||
InventoryHandlers.detachInventoryItems
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
CreateProductsActions.createPrices,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: CreateProductsActions.prepare,
|
||||
},
|
||||
{
|
||||
from: CreateProductsActions.createProducts,
|
||||
alias:
|
||||
ProductHandlers.updateProductsVariantsPrices.aliases.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
ProductHandlers.updateProductsVariantsPrices
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: CreateProductsActions.prepare,
|
||||
alias:
|
||||
MiddlewaresHandlers
|
||||
.createProductsPrepareCreatePricesCompensation.aliases
|
||||
.preparedData,
|
||||
},
|
||||
{
|
||||
from: CreateProductsActions.createProducts,
|
||||
alias:
|
||||
ProductHandlers.updateProductsVariantsPrices.aliases.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
MiddlewaresHandlers.createProductsPrepareCreatePricesCompensation,
|
||||
ProductHandlers.updateProductsVariantsPrices
|
||||
),
|
||||
},
|
||||
],
|
||||
])
|
||||
|
||||
WorkflowManager.register(Workflows.CreateProducts, workflowSteps, handlers)
|
||||
|
||||
export const createProducts = exportWorkflow<
|
||||
WorkflowTypes.ProductWorkflow.CreateProductsWorkflowInputDTO,
|
||||
ProductTypes.ProductDTO[]
|
||||
>(Workflows.CreateProducts, CreateProductsActions.createProducts)
|
||||
@@ -1,4 +0,0 @@
|
||||
export * as CreateProductVariants from "./create-product-variants"
|
||||
export * from "./create-products"
|
||||
export * as UpdateProductVariants from "./update-product-variants"
|
||||
export * from "./update-products"
|
||||
@@ -1,46 +0,0 @@
|
||||
import { ProductTypes } from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type AssociationTaggedVariant = ProductTypes.ProductVariantDTO & {
|
||||
_associationTag?: string
|
||||
}
|
||||
|
||||
type ObjectWithVariant = { variants: ProductTypes.ProductVariantDTO[] }
|
||||
|
||||
export async function prepareCreateInventoryItems({
|
||||
data,
|
||||
}: WorkflowArguments<{
|
||||
products: ObjectWithVariant[]
|
||||
}>) {
|
||||
const taggedVariants = data.products.reduce<AssociationTaggedVariant[]>(
|
||||
(acc, product: ObjectWithVariant) => {
|
||||
const cleanVariants = product.variants.reduce<AssociationTaggedVariant[]>(
|
||||
(acc, variant: AssociationTaggedVariant) => {
|
||||
if (!variant.manage_inventory) {
|
||||
return acc
|
||||
}
|
||||
|
||||
variant._associationTag = variant.id
|
||||
|
||||
acc.push(variant)
|
||||
return acc
|
||||
},
|
||||
[]
|
||||
)
|
||||
return acc.concat(cleanVariants)
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
return {
|
||||
alias: prepareCreateInventoryItems.aliases.output,
|
||||
value: {
|
||||
inventoryItems: taggedVariants,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
prepareCreateInventoryItems.aliases = {
|
||||
products: "products",
|
||||
output: "prepareCreateInventoryItemsOutput",
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
import {
|
||||
TransactionStepsDefinition,
|
||||
WorkflowManager,
|
||||
} from "@medusajs/orchestration"
|
||||
import { InputAlias, Workflows } from "../../definitions"
|
||||
import { exportWorkflow, pipe } from "@medusajs/workflows-sdk"
|
||||
|
||||
import { ProductTypes, WorkflowTypes } from "@medusajs/types"
|
||||
import { ProductHandlers } from "../../handlers"
|
||||
|
||||
export enum UpdateProductVariantsActions {
|
||||
prepare = "prepare",
|
||||
updateProductVariants = "updateProductVariants",
|
||||
revertProductVariantsUpdate = "revertProductVariantsUpdate",
|
||||
upsertPrices = "upsertPrices",
|
||||
}
|
||||
|
||||
export const workflowSteps: TransactionStepsDefinition = {
|
||||
next: {
|
||||
action: UpdateProductVariantsActions.prepare,
|
||||
noCompensation: true,
|
||||
next: {
|
||||
action: UpdateProductVariantsActions.updateProductVariants,
|
||||
noCompensation: true,
|
||||
next: [
|
||||
{
|
||||
action: UpdateProductVariantsActions.upsertPrices,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const handlers = new Map([
|
||||
[
|
||||
UpdateProductVariantsActions.prepare,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
inputAlias: InputAlias.ProductVariantsUpdateInputData,
|
||||
invoke: {
|
||||
from: InputAlias.ProductVariantsUpdateInputData,
|
||||
},
|
||||
},
|
||||
ProductHandlers.updateProductVariantsPrepareData
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
UpdateProductVariantsActions.updateProductVariants,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: UpdateProductVariantsActions.prepare,
|
||||
},
|
||||
},
|
||||
ProductHandlers.updateProductVariants
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
UpdateProductVariantsActions.upsertPrices,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: UpdateProductVariantsActions.prepare,
|
||||
},
|
||||
],
|
||||
},
|
||||
ProductHandlers.upsertVariantPrices
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: UpdateProductVariantsActions.prepare,
|
||||
},
|
||||
{
|
||||
from: UpdateProductVariantsActions.upsertPrices,
|
||||
},
|
||||
],
|
||||
},
|
||||
ProductHandlers.revertVariantPrices
|
||||
),
|
||||
},
|
||||
],
|
||||
])
|
||||
|
||||
WorkflowManager.register(
|
||||
Workflows.UpdateProductVariants,
|
||||
workflowSteps,
|
||||
handlers
|
||||
)
|
||||
|
||||
export const updateProductVariants = exportWorkflow<
|
||||
WorkflowTypes.ProductWorkflow.UpdateProductVariantsWorkflowInputDTO,
|
||||
ProductTypes.ProductVariantDTO[]
|
||||
>(
|
||||
Workflows.UpdateProductVariants,
|
||||
UpdateProductVariantsActions.updateProductVariants
|
||||
)
|
||||
@@ -1,400 +0,0 @@
|
||||
import { ProductTypes, WorkflowTypes } from "@medusajs/types"
|
||||
|
||||
import {
|
||||
TransactionStepsDefinition,
|
||||
WorkflowManager,
|
||||
} from "@medusajs/orchestration"
|
||||
import { InputAlias, Workflows } from "../../definitions"
|
||||
import { InventoryHandlers, ProductHandlers } from "../../handlers"
|
||||
import * as MiddlewareHandlers from "../../handlers/middlewares"
|
||||
import { detachSalesChannelFromProducts } from "../../handlers/product"
|
||||
import { exportWorkflow, pipe } from "@medusajs/workflows-sdk"
|
||||
import { CreateProductsActions } from "./create-products"
|
||||
import { prepareCreateInventoryItems } from "./prepare-create-inventory-items"
|
||||
import { UpdateProductVariantsActions } from "./update-product-variants"
|
||||
|
||||
export enum UpdateProductsActions {
|
||||
prepare = "prepare",
|
||||
updateProducts = "updateProducts",
|
||||
|
||||
attachSalesChannels = "attachSalesChannels",
|
||||
detachSalesChannels = "detachSalesChannels",
|
||||
|
||||
createInventoryItems = "createInventoryItems",
|
||||
attachInventoryItems = "attachInventoryItems",
|
||||
detachInventoryItems = "detachInventoryItems",
|
||||
removeInventoryItems = "removeInventoryItems",
|
||||
}
|
||||
|
||||
export const updateProductsWorkflowSteps: TransactionStepsDefinition = {
|
||||
next: {
|
||||
action: CreateProductsActions.prepare,
|
||||
noCompensation: true,
|
||||
next: {
|
||||
action: UpdateProductsActions.updateProducts,
|
||||
next: [
|
||||
{
|
||||
action: UpdateProductVariantsActions.upsertPrices,
|
||||
saveResponse: false,
|
||||
},
|
||||
{
|
||||
action: UpdateProductsActions.attachSalesChannels,
|
||||
saveResponse: false,
|
||||
},
|
||||
{
|
||||
action: UpdateProductsActions.detachSalesChannels,
|
||||
saveResponse: false,
|
||||
},
|
||||
{
|
||||
// for created variants
|
||||
action: UpdateProductsActions.createInventoryItems,
|
||||
next: {
|
||||
action: UpdateProductsActions.attachInventoryItems,
|
||||
},
|
||||
},
|
||||
{
|
||||
// for deleted variants
|
||||
action: UpdateProductsActions.detachInventoryItems,
|
||||
next: {
|
||||
action: UpdateProductsActions.removeInventoryItems,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const handlers = new Map<string, any>([
|
||||
[
|
||||
UpdateProductsActions.prepare,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
inputAlias: InputAlias.ProductsInputData,
|
||||
invoke: {
|
||||
from: InputAlias.ProductsInputData,
|
||||
},
|
||||
},
|
||||
ProductHandlers.updateProductsPrepareData
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
UpdateProductsActions.updateProducts,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: InputAlias.ProductsInputData,
|
||||
alias: ProductHandlers.updateProducts.aliases.products,
|
||||
},
|
||||
{
|
||||
from: UpdateProductsActions.prepare,
|
||||
},
|
||||
],
|
||||
},
|
||||
ProductHandlers.updateProducts
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: UpdateProductsActions.prepare,
|
||||
alias: ProductHandlers.revertUpdateProducts.aliases.preparedData,
|
||||
},
|
||||
{
|
||||
from: UpdateProductsActions.updateProducts,
|
||||
alias:
|
||||
MiddlewareHandlers.updateProductsExtractDeletedVariants.aliases
|
||||
.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
MiddlewareHandlers.updateProductsExtractDeletedVariants,
|
||||
ProductHandlers.revertUpdateProducts
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
UpdateProductsActions.attachSalesChannels,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: UpdateProductsActions.prepare,
|
||||
alias: "preparedData",
|
||||
},
|
||||
{
|
||||
from: UpdateProductsActions.updateProducts,
|
||||
alias:
|
||||
ProductHandlers.attachSalesChannelToProducts.aliases.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
MiddlewareHandlers.mapData((d: any) => ({
|
||||
productsHandleSalesChannelsMap:
|
||||
d.preparedData.productHandleAddedChannelsMap,
|
||||
})),
|
||||
ProductHandlers.attachSalesChannelToProducts
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: UpdateProductsActions.prepare,
|
||||
alias: "preparedData",
|
||||
},
|
||||
{
|
||||
from: UpdateProductsActions.updateProducts,
|
||||
alias: detachSalesChannelFromProducts.aliases.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
MiddlewareHandlers.mapData((d: any) => ({
|
||||
productsHandleSalesChannelsMap:
|
||||
d.preparedData.productHandleAddedChannelsMap,
|
||||
})),
|
||||
ProductHandlers.detachSalesChannelFromProducts
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
UpdateProductsActions.detachSalesChannels,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: UpdateProductsActions.prepare,
|
||||
alias: "preparedData",
|
||||
},
|
||||
{
|
||||
from: UpdateProductsActions.updateProducts,
|
||||
alias:
|
||||
ProductHandlers.detachSalesChannelFromProducts.aliases.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
MiddlewareHandlers.mapData((d: any) => ({
|
||||
productsHandleSalesChannelsMap:
|
||||
d.preparedData.productHandleRemovedChannelsMap,
|
||||
})),
|
||||
ProductHandlers.detachSalesChannelFromProducts
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: UpdateProductsActions.prepare,
|
||||
alias: "preparedData",
|
||||
},
|
||||
{
|
||||
from: UpdateProductsActions.updateProducts,
|
||||
alias:
|
||||
ProductHandlers.attachSalesChannelToProducts.aliases.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
MiddlewareHandlers.mapData((d: any) => ({
|
||||
productsHandleSalesChannelsMap:
|
||||
d.preparedData.productHandleRemovedChannelsMap,
|
||||
})),
|
||||
ProductHandlers.attachSalesChannelToProducts
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
UpdateProductsActions.createInventoryItems,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: UpdateProductsActions.prepare,
|
||||
alias:
|
||||
MiddlewareHandlers.updateProductsExtractCreatedVariants.aliases
|
||||
.preparedData,
|
||||
},
|
||||
{
|
||||
from: UpdateProductsActions.updateProducts,
|
||||
alias:
|
||||
MiddlewareHandlers.updateProductsExtractCreatedVariants.aliases
|
||||
.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
MiddlewareHandlers.updateProductsExtractCreatedVariants,
|
||||
prepareCreateInventoryItems,
|
||||
InventoryHandlers.createInventoryItems
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: UpdateProductsActions.createInventoryItems,
|
||||
alias:
|
||||
InventoryHandlers.removeInventoryItems.aliases.inventoryItems,
|
||||
},
|
||||
},
|
||||
InventoryHandlers.removeInventoryItems
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
UpdateProductsActions.attachInventoryItems,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: UpdateProductsActions.createInventoryItems,
|
||||
alias:
|
||||
InventoryHandlers.attachInventoryItems.aliases.inventoryItems,
|
||||
},
|
||||
},
|
||||
InventoryHandlers.attachInventoryItems
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: UpdateProductsActions.attachInventoryItems,
|
||||
alias:
|
||||
InventoryHandlers.detachInventoryItems.aliases.inventoryItems,
|
||||
},
|
||||
},
|
||||
InventoryHandlers.detachInventoryItems
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
UpdateProductsActions.detachInventoryItems,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: UpdateProductsActions.prepare,
|
||||
alias:
|
||||
MiddlewareHandlers.updateProductsExtractDeletedVariants.aliases
|
||||
.preparedData,
|
||||
},
|
||||
{
|
||||
from: UpdateProductsActions.updateProducts,
|
||||
alias:
|
||||
MiddlewareHandlers.updateProductsExtractDeletedVariants.aliases
|
||||
.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
MiddlewareHandlers.updateProductsExtractDeletedVariants,
|
||||
MiddlewareHandlers.useVariantsInventoryItems,
|
||||
InventoryHandlers.detachInventoryItems
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: UpdateProductsActions.prepare,
|
||||
alias:
|
||||
MiddlewareHandlers.updateProductsExtractDeletedVariants.aliases
|
||||
.preparedData,
|
||||
},
|
||||
{
|
||||
from: UpdateProductsActions.updateProducts,
|
||||
alias:
|
||||
MiddlewareHandlers.updateProductsExtractDeletedVariants.aliases
|
||||
.products,
|
||||
},
|
||||
],
|
||||
},
|
||||
MiddlewareHandlers.updateProductsExtractDeletedVariants,
|
||||
MiddlewareHandlers.useVariantsInventoryItems,
|
||||
InventoryHandlers.attachInventoryItems
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
UpdateProductsActions.removeInventoryItems,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: {
|
||||
from: UpdateProductsActions.detachInventoryItems,
|
||||
alias:
|
||||
InventoryHandlers.removeInventoryItems.aliases.inventoryItems,
|
||||
},
|
||||
},
|
||||
InventoryHandlers.removeInventoryItems
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: UpdateProductsActions.removeInventoryItems,
|
||||
alias:
|
||||
InventoryHandlers.restoreInventoryItems.aliases.inventoryItems,
|
||||
},
|
||||
],
|
||||
},
|
||||
InventoryHandlers.restoreInventoryItems
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
UpdateProductVariantsActions.upsertPrices,
|
||||
{
|
||||
invoke: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: InputAlias.ProductsInputData,
|
||||
alias: ProductHandlers.updateProducts.aliases.products,
|
||||
},
|
||||
{
|
||||
from: UpdateProductsActions.prepare,
|
||||
},
|
||||
],
|
||||
},
|
||||
ProductHandlers.upsertVariantPrices
|
||||
),
|
||||
compensate: pipe(
|
||||
{
|
||||
merge: true,
|
||||
invoke: [
|
||||
{
|
||||
from: UpdateProductVariantsActions.upsertPrices,
|
||||
},
|
||||
],
|
||||
},
|
||||
ProductHandlers.revertVariantPrices
|
||||
),
|
||||
},
|
||||
],
|
||||
])
|
||||
|
||||
WorkflowManager.register(
|
||||
Workflows.UpdateProducts,
|
||||
updateProductsWorkflowSteps,
|
||||
handlers
|
||||
)
|
||||
|
||||
export const updateProducts = exportWorkflow<
|
||||
WorkflowTypes.ProductWorkflow.UpdateProductsWorkflowInputDTO,
|
||||
ProductTypes.ProductDTO[]
|
||||
>(Workflows.UpdateProducts, UpdateProductsActions.updateProducts)
|
||||
@@ -1,40 +0,0 @@
|
||||
export enum Workflows {
|
||||
// Product workflows
|
||||
CreateProducts = "create-products-old",
|
||||
UpdateProducts = "update-products-old",
|
||||
|
||||
// Product Variant workflows
|
||||
CreateProductVariants = "create-product-variants-old",
|
||||
UpdateProductVariants = "update-product-variants-old",
|
||||
|
||||
// Cart workflows
|
||||
CreateCart = "create-cart-old",
|
||||
|
||||
CreateInventoryItems = "create-inventory-items-old",
|
||||
|
||||
// Price list workflows
|
||||
CreatePriceList = "create-price-list-old",
|
||||
UpdatePriceLists = "update-price-lists-old",
|
||||
DeletePriceLists = "delete-price-lists-old",
|
||||
RemovePriceListProductPrices = "remove-price-list-products-old",
|
||||
RemovePriceListVariantPrices = "remove-price-list-variants-old",
|
||||
RemovePriceListPrices = "remove-price-list-prices-old",
|
||||
}
|
||||
|
||||
export enum InputAlias {
|
||||
Products = "products",
|
||||
ProductsInputData = "productsInputData",
|
||||
RemovedProducts = "removedProducts",
|
||||
|
||||
ProductVariants = "productVariants",
|
||||
ProductVariantsUpdateInputData = "productVariantsUpdateInputData",
|
||||
ProductVariantsCreateInputData = "productVariantsCreateInputData",
|
||||
|
||||
InventoryItems = "inventoryItems",
|
||||
RemovedInventoryItems = "removedInventoryItems",
|
||||
|
||||
AttachedInventoryItems = "attachedInventoryItems",
|
||||
DetachedInventoryItems = "detachedInventoryItems",
|
||||
|
||||
InventoryItemsInputData = "inventoryItemsInputData",
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
import { AddressDTO } from "@medusajs/types"
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type AddressesDTO = {
|
||||
shipping_address_id?: string
|
||||
shipping_address?: AddressDTO
|
||||
billing_address_id?: string
|
||||
billing_address?: AddressDTO
|
||||
}
|
||||
|
||||
type HandlerInputData = {
|
||||
addresses: AddressesDTO & {
|
||||
billing_address?: AddressDTO
|
||||
shipping_address?: AddressDTO
|
||||
}
|
||||
region: {
|
||||
region_id?: string
|
||||
}
|
||||
}
|
||||
|
||||
enum Aliases {
|
||||
Addresses = "addresses",
|
||||
Region = "region",
|
||||
}
|
||||
|
||||
export async function findOrCreateAddresses({
|
||||
container,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInputData>): Promise<AddressesDTO> {
|
||||
const regionService = container.resolve("regionService")
|
||||
const addressRepository = container.resolve("addressRepository")
|
||||
|
||||
const shippingAddress = data[Aliases.Addresses].shipping_address
|
||||
const shippingAddressId = data[Aliases.Addresses].shipping_address_id
|
||||
const billingAddress = data[Aliases.Addresses].billing_address
|
||||
const billingAddressId = data[Aliases.Addresses].billing_address_id
|
||||
const addressesDTO: AddressesDTO = {}
|
||||
|
||||
const region = await regionService.retrieve(data[Aliases.Region].region_id, {
|
||||
relations: ["countries"],
|
||||
})
|
||||
|
||||
const regionCountries = region.countries.map(({ iso_2 }) => iso_2)
|
||||
|
||||
if (!shippingAddress && !shippingAddressId) {
|
||||
if (region.countries.length === 1) {
|
||||
const shippingAddress = addressRepository.create({
|
||||
country_code: regionCountries[0],
|
||||
})
|
||||
|
||||
addressesDTO.shipping_address = shippingAddress
|
||||
addressesDTO.shipping_address_id = shippingAddress?.id
|
||||
}
|
||||
} else {
|
||||
if (shippingAddress) {
|
||||
if (!regionCountries.includes(shippingAddress.country_code!)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_ALLOWED,
|
||||
"Shipping country not in region"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (shippingAddressId) {
|
||||
const address = await regionService.findOne({
|
||||
where: { id: shippingAddressId },
|
||||
})
|
||||
|
||||
if (
|
||||
address?.country_code &&
|
||||
!regionCountries.includes(address.country_code)
|
||||
) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_ALLOWED,
|
||||
"Shipping country not in region"
|
||||
)
|
||||
}
|
||||
|
||||
addressesDTO.shipping_address = address
|
||||
addressesDTO.shipping_address_id = address.id
|
||||
}
|
||||
}
|
||||
|
||||
if (billingAddress) {
|
||||
if (!regionCountries.includes(billingAddress.country_code!)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_ALLOWED,
|
||||
"Billing country not in region"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (billingAddressId) {
|
||||
const address = await regionService.findOne({
|
||||
where: { id: billingAddressId },
|
||||
})
|
||||
|
||||
if (
|
||||
address?.country_code &&
|
||||
!regionCountries.includes(address.country_code)
|
||||
) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_ALLOWED,
|
||||
"Billing country not in region"
|
||||
)
|
||||
}
|
||||
|
||||
addressesDTO.billing_address = address
|
||||
addressesDTO.billing_address_id = billingAddressId
|
||||
}
|
||||
|
||||
return addressesDTO
|
||||
}
|
||||
|
||||
findOrCreateAddresses.aliases = Aliases
|
||||
@@ -1 +0,0 @@
|
||||
export * from "./find-or-create-addresses"
|
||||
@@ -1 +0,0 @@
|
||||
export * from "./set-context"
|
||||
@@ -1,27 +0,0 @@
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type ContextDTO = {
|
||||
context?: Record<any, any>
|
||||
}
|
||||
|
||||
enum Aliases {
|
||||
Context = "context",
|
||||
}
|
||||
|
||||
type HandlerInputData = {
|
||||
context: {
|
||||
context?: Record<any, any>
|
||||
}
|
||||
}
|
||||
|
||||
export async function setContext({
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInputData>): Promise<ContextDTO> {
|
||||
const contextDTO: ContextDTO = {
|
||||
context: data[Aliases.Context].context,
|
||||
}
|
||||
|
||||
return contextDTO
|
||||
}
|
||||
|
||||
setContext.aliases = Aliases
|
||||
@@ -1,67 +0,0 @@
|
||||
import { validateEmail } from "@medusajs/utils"
|
||||
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
import { CustomerTypes } from "@medusajs/types"
|
||||
|
||||
type CustomerResultDTO = {
|
||||
customer?: CustomerTypes.CustomerDTO
|
||||
customer_id?: string
|
||||
email?: string
|
||||
}
|
||||
|
||||
type HandlerInputData = {
|
||||
customer: {
|
||||
customer_id?: string
|
||||
email?: string
|
||||
}
|
||||
}
|
||||
|
||||
enum Aliases {
|
||||
Customer = "customer",
|
||||
}
|
||||
|
||||
export async function findOrCreateCustomer({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInputData>): Promise<CustomerResultDTO> {
|
||||
const { manager } = context
|
||||
|
||||
const customerService = container.resolve("customerService")
|
||||
|
||||
const customerDataDTO: CustomerResultDTO = {}
|
||||
const customerId = data[Aliases.Customer].customer_id
|
||||
const customerServiceTx = customerService.withTransaction(manager)
|
||||
|
||||
if (customerId) {
|
||||
const customer = await customerServiceTx
|
||||
.retrieve(customerId)
|
||||
.catch(() => undefined)
|
||||
|
||||
customerDataDTO.customer = customer
|
||||
customerDataDTO.customer_id = customer?.id
|
||||
customerDataDTO.email = customer?.email
|
||||
}
|
||||
|
||||
const customerEmail = data[Aliases.Customer].email
|
||||
|
||||
if (customerEmail) {
|
||||
const validatedEmail = validateEmail(customerEmail)
|
||||
|
||||
let customer = await customerServiceTx
|
||||
.retrieveUnregisteredByEmail(validatedEmail)
|
||||
.catch(() => undefined)
|
||||
|
||||
if (!customer) {
|
||||
customer = await customerServiceTx.create({ email: validatedEmail })
|
||||
}
|
||||
|
||||
customerDataDTO.customer = customer
|
||||
customerDataDTO.customer_id = customer.id
|
||||
customerDataDTO.email = customer.email
|
||||
}
|
||||
|
||||
return customerDataDTO
|
||||
}
|
||||
|
||||
findOrCreateCustomer.aliases = Aliases
|
||||
@@ -1 +0,0 @@
|
||||
export * from "./find-or-create-customer"
|
||||
@@ -1,8 +0,0 @@
|
||||
export * as AddressHandlers from "./address"
|
||||
export * as CommonHandlers from "./common"
|
||||
export * as CustomerHandlers from "./customer"
|
||||
export * as InventoryHandlers from "./inventory"
|
||||
export * as MiddlewaresHandlers from "./middlewares"
|
||||
export * as ProductHandlers from "./product"
|
||||
export * as RegionHandlers from "./region"
|
||||
export * as SalesChannelHandlers from "./sales-channel"
|
||||
@@ -1,35 +0,0 @@
|
||||
import { InventoryItemDTO } from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
export async function attachInventoryItems({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<{
|
||||
inventoryItems: {
|
||||
tag: string
|
||||
inventoryItem: InventoryItemDTO
|
||||
}[]
|
||||
}>) {
|
||||
const { manager } = context
|
||||
const productVariantInventoryService = container
|
||||
.resolve("productVariantInventoryService")
|
||||
.withTransaction(manager)
|
||||
|
||||
if (!data?.inventoryItems?.length) {
|
||||
return []
|
||||
}
|
||||
|
||||
const inventoryData = data.inventoryItems.map(({ tag, inventoryItem }) => ({
|
||||
variantId: tag,
|
||||
inventoryItemId: inventoryItem.id,
|
||||
}))
|
||||
|
||||
await productVariantInventoryService.attachInventoryItem(inventoryData)
|
||||
|
||||
return data.inventoryItems
|
||||
}
|
||||
|
||||
attachInventoryItems.aliases = {
|
||||
inventoryItems: "inventoryItems",
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
import { IInventoryService, InventoryItemDTO } from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
import { promiseAll } from "@medusajs/utils"
|
||||
|
||||
type Result = {
|
||||
tag: string
|
||||
inventoryItem: InventoryItemDTO
|
||||
}[]
|
||||
|
||||
export async function createInventoryItems({
|
||||
container,
|
||||
data,
|
||||
}: WorkflowArguments<{
|
||||
inventoryItems: (InventoryItemDTO & { _associationTag?: string })[]
|
||||
}>): Promise<Result | void> {
|
||||
const inventoryService: IInventoryService =
|
||||
container.resolve("inventoryService")
|
||||
|
||||
if (!inventoryService) {
|
||||
const logger = container.resolve("logger")
|
||||
logger.warn(
|
||||
`Inventory service not found. You should install the @medusajs/inventory package to use inventory. The 'createInventoryItems' will be skipped.`
|
||||
)
|
||||
return void 0
|
||||
}
|
||||
|
||||
return await promiseAll(
|
||||
data.inventoryItems.map(async (item) => {
|
||||
const inventoryItem = await inventoryService!.createInventoryItem({
|
||||
sku: item.sku!,
|
||||
origin_country: item.origin_country!,
|
||||
hs_code: item.hs_code!,
|
||||
mid_code: item.mid_code!,
|
||||
material: item.material!,
|
||||
weight: item.weight!,
|
||||
length: item.length!,
|
||||
height: item.height!,
|
||||
width: item.width!,
|
||||
})
|
||||
|
||||
return { tag: item._associationTag ?? inventoryItem.id, inventoryItem }
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
createInventoryItems.aliases = {
|
||||
payload: "payload",
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
import { InventoryItemDTO } from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
import { promiseAll } from "@medusajs/utils"
|
||||
|
||||
export async function detachInventoryItems({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<{
|
||||
inventoryItems: {
|
||||
tag: string
|
||||
inventoryItem: InventoryItemDTO
|
||||
}[]
|
||||
}>) {
|
||||
const { manager } = context
|
||||
|
||||
const productVariantInventoryService = container
|
||||
.resolve("productVariantInventoryService")
|
||||
.withTransaction(manager)
|
||||
|
||||
if (!data?.inventoryItems?.length) {
|
||||
return []
|
||||
}
|
||||
|
||||
await promiseAll(
|
||||
data.inventoryItems.map(async ({ tag, inventoryItem }) => {
|
||||
return await productVariantInventoryService.detachInventoryItem(
|
||||
inventoryItem.id,
|
||||
tag
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
return data.inventoryItems
|
||||
}
|
||||
|
||||
detachInventoryItems.aliases = {
|
||||
inventoryItems: "inventoryItems",
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
export * from "./detach-inventory-items"
|
||||
export * from "./attach-inventory-items"
|
||||
export * from "./create-inventory-items"
|
||||
export * from "./remove-inventory-items"
|
||||
export * from "./restore-inventory-items"
|
||||
@@ -1,29 +0,0 @@
|
||||
import { InventoryItemDTO } from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
export async function removeInventoryItems({
|
||||
container,
|
||||
data,
|
||||
}: WorkflowArguments<{
|
||||
inventoryItems: { inventoryItem: InventoryItemDTO }[]
|
||||
}>) {
|
||||
const inventoryService = container.resolve("inventoryService")
|
||||
|
||||
if (!inventoryService) {
|
||||
const logger = container.resolve("logger")
|
||||
logger.warn(
|
||||
`Inventory service not found. You should install the @medusajs/inventory package to use inventory. The 'removeInventoryItems' will be skipped.`
|
||||
)
|
||||
return []
|
||||
}
|
||||
|
||||
await inventoryService!.deleteInventoryItem(
|
||||
data.inventoryItems.map(({ inventoryItem }) => inventoryItem.id)
|
||||
)
|
||||
|
||||
return data.inventoryItems
|
||||
}
|
||||
|
||||
removeInventoryItems.aliases = {
|
||||
inventoryItems: "inventoryItems",
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
import {
|
||||
IInventoryService,
|
||||
InventoryItemDTO,
|
||||
SharedContext,
|
||||
} from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
export async function restoreInventoryItems({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<{
|
||||
inventoryItems: { inventoryItem: InventoryItemDTO }[]
|
||||
}>) {
|
||||
const { manager } = context as SharedContext
|
||||
const inventoryService: IInventoryService =
|
||||
container.resolve("inventoryService")
|
||||
|
||||
if (!inventoryService) {
|
||||
const logger = container.resolve("logger")
|
||||
logger.warn(
|
||||
`Inventory service not found. You should install the @medusajs/inventory package to use inventory. The 'removeInventoryItems' will be skipped.`
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
return await inventoryService!.restoreInventoryItem(
|
||||
data.inventoryItems.map(({ inventoryItem }) => inventoryItem.id),
|
||||
{ transactionManager: manager }
|
||||
)
|
||||
}
|
||||
|
||||
restoreInventoryItems.aliases = {
|
||||
inventoryItems: "inventoryItems",
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
import { ProductTypes, WorkflowTypes } from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type ProductHandle = string
|
||||
type VariantIndexAndPrices = {
|
||||
index: number
|
||||
prices: WorkflowTypes.ProductWorkflow.CreateProductVariantPricesInputDTO[]
|
||||
}
|
||||
|
||||
export async function createProductsPrepareCreatePricesCompensation({
|
||||
data,
|
||||
}: WorkflowArguments<{
|
||||
preparedData: {
|
||||
productsHandleVariantsIndexPricesMap: Map<
|
||||
ProductHandle,
|
||||
VariantIndexAndPrices[]
|
||||
>
|
||||
}
|
||||
products: ProductTypes.ProductDTO[]
|
||||
}>) {
|
||||
const productsHandleVariantsIndexPricesMap =
|
||||
data.preparedData.productsHandleVariantsIndexPricesMap
|
||||
const products = data.products
|
||||
|
||||
const updatedProductsHandleVariantsIndexPricesMap = new Map()
|
||||
productsHandleVariantsIndexPricesMap.forEach(
|
||||
(existingItems, productHandle) => {
|
||||
const items =
|
||||
updatedProductsHandleVariantsIndexPricesMap.get(productHandle) ?? []
|
||||
|
||||
existingItems.forEach(({ index }) => {
|
||||
items.push({
|
||||
index,
|
||||
prices: [],
|
||||
})
|
||||
})
|
||||
|
||||
updatedProductsHandleVariantsIndexPricesMap.set(productHandle, items)
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
alias: createProductsPrepareCreatePricesCompensation.aliases.output,
|
||||
value: {
|
||||
productsHandleVariantsIndexPricesMap:
|
||||
updatedProductsHandleVariantsIndexPricesMap,
|
||||
products,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
createProductsPrepareCreatePricesCompensation.aliases = {
|
||||
preparedData: "preparedData",
|
||||
output: "createProductsPrepareCreatePricesCompensationOutput",
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { ProductTypes } from "@medusajs/types"
|
||||
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
export async function extractVariants({
|
||||
data,
|
||||
}: WorkflowArguments<{
|
||||
object: { variants?: ProductTypes.ProductVariantDTO[] }[]
|
||||
}>) {
|
||||
const variants = data.object.reduce((acc, object) => {
|
||||
if (object.variants?.length) {
|
||||
return acc.concat(object.variants)
|
||||
}
|
||||
return acc
|
||||
}, [] as ProductTypes.ProductVariantDTO[])
|
||||
|
||||
return {
|
||||
alias: extractVariants.aliases.output,
|
||||
value: {
|
||||
variants,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
extractVariants.aliases = {
|
||||
output: "extractVariantsFromProductOutput",
|
||||
object: "object",
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
export * from "./create-products-prepare-create-prices-compensation"
|
||||
export * from "./update-products-extract-created-variants"
|
||||
export * from "./update-products-extract-deleted-variants"
|
||||
export * from "./use-variants-inventory-items"
|
||||
export * from "./extract-variants"
|
||||
export * from "./map-data"
|
||||
@@ -1,16 +0,0 @@
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
/**
|
||||
* Middleware for map input data to a key/s.
|
||||
*
|
||||
* @param mapFn - apply function on the input data and return result as the middleware output
|
||||
* @param alias - key to save output under (if `merge === false`)
|
||||
*/
|
||||
export function mapData<T, S>(mapFn: (arg: T) => S, alias = "mapData") {
|
||||
return async function ({ data }: WorkflowArguments<T>) {
|
||||
return {
|
||||
alias,
|
||||
value: mapFn(data),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import { ProductTypes, ProductVariantDTO } from "@medusajs/types"
|
||||
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
import { UpdateProductsPreparedData } from "../product"
|
||||
|
||||
export async function updateProductsExtractCreatedVariants({
|
||||
data,
|
||||
}: WorkflowArguments<{
|
||||
preparedData: UpdateProductsPreparedData // products state before the update
|
||||
products: ProductTypes.ProductDTO[] // updated products
|
||||
}>) {
|
||||
const createdVariants: ProductVariantDTO[] = []
|
||||
|
||||
data.products.forEach((product) => {
|
||||
const addedVariants: ProductVariantDTO[] = []
|
||||
|
||||
const originalProduct = data.preparedData.originalProducts.find(
|
||||
(p) => p.id === product.id
|
||||
)!
|
||||
|
||||
product.variants.forEach((variant) => {
|
||||
if (!originalProduct.variants.find((v) => v.id === variant.id)) {
|
||||
addedVariants.push(variant)
|
||||
}
|
||||
})
|
||||
|
||||
createdVariants.push(...addedVariants)
|
||||
})
|
||||
|
||||
return {
|
||||
alias: updateProductsExtractCreatedVariants.aliases.output,
|
||||
value: [{ variants: createdVariants }],
|
||||
}
|
||||
}
|
||||
|
||||
updateProductsExtractCreatedVariants.aliases = {
|
||||
preparedData: "preparedData",
|
||||
products: "products",
|
||||
output: "products",
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
import { ProductTypes, ProductVariantDTO } from "@medusajs/types"
|
||||
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
import { UpdateProductsPreparedData } from "../product"
|
||||
|
||||
export async function updateProductsExtractDeletedVariants({
|
||||
data,
|
||||
container,
|
||||
}: WorkflowArguments<{
|
||||
preparedData: UpdateProductsPreparedData // products state before the update
|
||||
products: ProductTypes.ProductDTO[] // updated products
|
||||
}>) {
|
||||
const deletedVariants: ProductVariantDTO[] = []
|
||||
|
||||
data.products.forEach((product) => {
|
||||
const removedVariants: ProductVariantDTO[] = []
|
||||
|
||||
const originalProduct = data.preparedData.originalProducts.find(
|
||||
(p) => p.id === product.id
|
||||
)!
|
||||
|
||||
originalProduct.variants.forEach((variant) => {
|
||||
if (!product.variants.find((v) => v.id === variant.id)) {
|
||||
removedVariants.push(variant)
|
||||
}
|
||||
})
|
||||
|
||||
deletedVariants.push(...removedVariants)
|
||||
})
|
||||
|
||||
return {
|
||||
alias: updateProductsExtractDeletedVariants.aliases.output,
|
||||
value: {
|
||||
variants: deletedVariants,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
updateProductsExtractDeletedVariants.aliases = {
|
||||
preparedData: "preparedData",
|
||||
products: "products",
|
||||
output: "updateProductsExtractDeletedVariantsOutput",
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
import { IInventoryService, ProductVariantDTO } from "@medusajs/types"
|
||||
|
||||
export async function useVariantsInventoryItems({
|
||||
data,
|
||||
container,
|
||||
}: WorkflowArguments<{
|
||||
updateProductsExtractDeletedVariantsOutput: { variants: ProductVariantDTO[] }
|
||||
}>) {
|
||||
const inventoryService: IInventoryService =
|
||||
container.resolve("inventoryService")
|
||||
|
||||
if (!inventoryService) {
|
||||
const logger = container.resolve("logger")
|
||||
logger.warn(
|
||||
`Inventory service not found. You should install the @medusajs/inventory package to use inventory. The 'useVariantsInventoryItems' will be skipped.`
|
||||
)
|
||||
return {
|
||||
alias: useVariantsInventoryItems.aliases.output,
|
||||
value: null,
|
||||
}
|
||||
}
|
||||
|
||||
const [inventoryItems] = await inventoryService!.listInventoryItems({
|
||||
sku: data.updateProductsExtractDeletedVariantsOutput.variants.map(
|
||||
(v) => v.id
|
||||
),
|
||||
})
|
||||
|
||||
const variantItems = inventoryItems.map((item) => ({
|
||||
inventoryItem: item,
|
||||
tag: data.updateProductsExtractDeletedVariantsOutput.variants.find(
|
||||
(variant) => variant.sku === item.sku
|
||||
)!.id,
|
||||
}))
|
||||
|
||||
return {
|
||||
alias: useVariantsInventoryItems.aliases.output,
|
||||
value: { inventoryItems: variantItems },
|
||||
}
|
||||
}
|
||||
|
||||
useVariantsInventoryItems.aliases = {
|
||||
variants: "variants",
|
||||
output: "useVariantsInventoryItemsOutput",
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
import { MedusaV2Flag, promiseAll } from "@medusajs/utils"
|
||||
import { Modules } from "@medusajs/modules-sdk"
|
||||
|
||||
type ProductHandle = string
|
||||
type SalesChannelId = string
|
||||
|
||||
type PartialProduct = { handle: string; id: string }
|
||||
|
||||
type HandlerInput = {
|
||||
productsHandleSalesChannelsMap: Map<ProductHandle, SalesChannelId[]>
|
||||
products: PartialProduct[]
|
||||
}
|
||||
|
||||
export async function attachSalesChannelToProducts({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInput>): Promise<void> {
|
||||
const { manager } = context
|
||||
const featureFlagRouter = container.resolve("featureFlagRouter")
|
||||
|
||||
const productsHandleSalesChannelsMap = data.productsHandleSalesChannelsMap
|
||||
const products = data.products
|
||||
|
||||
const salesChannelService = container.resolve("salesChannelService")
|
||||
const salesChannelServiceTx = salesChannelService.withTransaction(manager)
|
||||
|
||||
const salesChannelIdProductIdsMap = new Map<ProductHandle, SalesChannelId[]>()
|
||||
products.forEach((product) => {
|
||||
const salesChannelIds = productsHandleSalesChannelsMap.get(product.handle!)
|
||||
if (salesChannelIds) {
|
||||
salesChannelIds.forEach((salesChannelId) => {
|
||||
const productIds = salesChannelIdProductIdsMap.get(salesChannelId) || []
|
||||
productIds.push(product.id)
|
||||
salesChannelIdProductIdsMap.set(salesChannelId, productIds)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
|
||||
const remoteLink = container.resolve("remoteLink")
|
||||
const links: any[] = []
|
||||
|
||||
for (const [
|
||||
salesChannelId,
|
||||
productIds,
|
||||
] of salesChannelIdProductIdsMap.entries()) {
|
||||
productIds.forEach((id) =>
|
||||
links.push({
|
||||
[Modules.PRODUCT]: {
|
||||
product_id: id,
|
||||
},
|
||||
[Modules.SALES_CHANNEL]: {
|
||||
sales_channel_id: salesChannelId,
|
||||
},
|
||||
})
|
||||
)
|
||||
|
||||
await remoteLink.create(links)
|
||||
}
|
||||
|
||||
return
|
||||
} else {
|
||||
await promiseAll(
|
||||
Array.from(salesChannelIdProductIdsMap.entries()).map(
|
||||
async ([salesChannelId, productIds]) => {
|
||||
return await salesChannelServiceTx.addProducts(
|
||||
salesChannelId,
|
||||
productIds
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
attachSalesChannelToProducts.aliases = {
|
||||
products: "products",
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
import { promiseAll } from "@medusajs/utils"
|
||||
|
||||
type ProductHandle = string
|
||||
type ShippingProfileId = string
|
||||
type PartialProduct = { handle: string; id: string }
|
||||
type handlerInput = {
|
||||
productsHandleShippingProfileIdMap: Map<ProductHandle, ShippingProfileId>
|
||||
products: PartialProduct[]
|
||||
}
|
||||
|
||||
export async function attachShippingProfileToProducts({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<handlerInput>): Promise<void> {
|
||||
const { manager } = context
|
||||
|
||||
const productsHandleShippingProfileIdMap =
|
||||
data.productsHandleShippingProfileIdMap
|
||||
const products = data.products
|
||||
|
||||
const shippingProfileService = container.resolve("shippingProfileService")
|
||||
const shippingProfileServiceTx =
|
||||
shippingProfileService.withTransaction(manager)
|
||||
|
||||
const profileIdProductIdsMap = new Map<ShippingProfileId, ProductHandle[]>()
|
||||
products.forEach((product) => {
|
||||
const profileId = productsHandleShippingProfileIdMap.get(product.handle!)
|
||||
if (profileId) {
|
||||
const productIds = profileIdProductIdsMap.get(profileId) || []
|
||||
productIds.push(product.id)
|
||||
profileIdProductIdsMap.set(profileId, productIds)
|
||||
}
|
||||
})
|
||||
|
||||
await promiseAll(
|
||||
Array.from(profileIdProductIdsMap.entries()).map(
|
||||
async ([profileId, productIds]) => {
|
||||
return await shippingProfileServiceTx.addProducts(profileId, productIds)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
attachShippingProfileToProducts.aliases = {
|
||||
products: "products",
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
import { BigNumberInput, ProductWorkflow, WorkflowTypes } from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type VariantPrice = {
|
||||
region_id?: string
|
||||
currency_code?: string
|
||||
amount: BigNumberInput
|
||||
min_quantity?: BigNumberInput
|
||||
max_quantity?: BigNumberInput
|
||||
}
|
||||
|
||||
export type CreateProductVariantsPreparedData = {
|
||||
productVariants: ProductWorkflow.CreateProductVariantsInputDTO[]
|
||||
variantIndexPricesMap: Map<number, VariantPrice[]>
|
||||
productVariantsMap: Map<
|
||||
string,
|
||||
ProductWorkflow.CreateProductVariantsInputDTO[]
|
||||
>
|
||||
}
|
||||
|
||||
export async function createProductVariantsPrepareData({
|
||||
container,
|
||||
data,
|
||||
}: // eslint-disable-next-line max-len
|
||||
WorkflowArguments<WorkflowTypes.ProductWorkflow.CreateProductVariantsWorkflowInputDTO>): Promise<CreateProductVariantsPreparedData> {
|
||||
const productVariants: ProductWorkflow.CreateProductVariantsInputDTO[] =
|
||||
data.productVariants || []
|
||||
|
||||
const variantIndexPricesMap = new Map<number, VariantPrice[]>()
|
||||
const productVariantsMap = new Map<
|
||||
string,
|
||||
ProductWorkflow.CreateProductVariantsInputDTO[]
|
||||
>()
|
||||
|
||||
for (const [index, productVariantData] of productVariants.entries()) {
|
||||
if (!productVariantData.product_id) {
|
||||
continue
|
||||
}
|
||||
|
||||
variantIndexPricesMap.set(index, productVariantData.prices || [])
|
||||
|
||||
delete productVariantData.prices
|
||||
|
||||
const productVariants = productVariantsMap.get(
|
||||
productVariantData.product_id
|
||||
)
|
||||
|
||||
if (productVariants) {
|
||||
productVariants.push(productVariantData)
|
||||
} else {
|
||||
productVariantsMap.set(productVariantData.product_id, [
|
||||
productVariantData,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
productVariants,
|
||||
variantIndexPricesMap,
|
||||
productVariantsMap,
|
||||
}
|
||||
}
|
||||
|
||||
createProductVariantsPrepareData.aliases = {
|
||||
payload: "payload",
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
|
||||
import { BigNumberInput, ProductTypes } from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type VariantPrice = {
|
||||
region_id?: string
|
||||
currency_code?: string
|
||||
amount: BigNumberInput
|
||||
min_quantity?: BigNumberInput
|
||||
max_quantity?: BigNumberInput
|
||||
}
|
||||
|
||||
type HandlerInput = {
|
||||
productVariantsMap: Map<string, ProductTypes.CreateProductVariantDTO[]>
|
||||
variantIndexPricesMap: Map<number, VariantPrice[]>
|
||||
}
|
||||
|
||||
export async function createProductVariants({
|
||||
container,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInput>): Promise<{
|
||||
productVariants: ProductTypes.ProductVariantDTO[]
|
||||
variantPricesMap: Map<string, VariantPrice[]>
|
||||
}> {
|
||||
const { productVariantsMap, variantIndexPricesMap } = data
|
||||
const variantPricesMap = new Map<string, VariantPrice[]>()
|
||||
const productModuleService: ProductTypes.IProductModuleService =
|
||||
container.resolve(ModulesDefinition[Modules.PRODUCT].registrationName)
|
||||
|
||||
const productVariants = await productModuleService.createVariants(
|
||||
[...productVariantsMap.values()].flat()
|
||||
)
|
||||
|
||||
productVariants.forEach((variant, index) => {
|
||||
variantPricesMap.set(variant.id, variantIndexPricesMap.get(index) || [])
|
||||
})
|
||||
|
||||
return {
|
||||
productVariants,
|
||||
variantPricesMap,
|
||||
}
|
||||
}
|
||||
|
||||
createProductVariants.aliases = {
|
||||
payload: "payload",
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
import {
|
||||
BigNumberInput,
|
||||
ProductTypes,
|
||||
SalesChannelTypes,
|
||||
WorkflowTypes,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
FeatureFlagUtils,
|
||||
ShippingProfileUtils,
|
||||
kebabCase,
|
||||
} from "@medusajs/utils"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type ShippingProfileId = string
|
||||
type SalesChannelId = string
|
||||
type ProductHandle = string
|
||||
type VariantIndexAndPrices = {
|
||||
index: number
|
||||
prices: {
|
||||
region_id?: string
|
||||
currency_code?: string
|
||||
amount: BigNumberInput
|
||||
min_quantity?: BigNumberInput
|
||||
max_quantity?: BigNumberInput
|
||||
}[]
|
||||
}
|
||||
|
||||
export type CreateProductsPreparedData = {
|
||||
products: ProductTypes.CreateProductDTO[]
|
||||
productsHandleShippingProfileIdMap: Map<ProductHandle, ShippingProfileId>
|
||||
productsHandleSalesChannelsMap: Map<ProductHandle, SalesChannelId[]>
|
||||
productsHandleVariantsIndexPricesMap: Map<
|
||||
ProductHandle,
|
||||
VariantIndexAndPrices[]
|
||||
>
|
||||
}
|
||||
|
||||
export async function createProductsPrepareData({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<WorkflowTypes.ProductWorkflow.CreateProductsWorkflowInputDTO>): Promise<CreateProductsPreparedData> {
|
||||
const { manager } = context
|
||||
let products = data.products
|
||||
|
||||
const shippingProfileService = container
|
||||
.resolve("shippingProfileService")
|
||||
.withTransaction(manager)
|
||||
const featureFlagRouter = container.resolve("featureFlagRouter")
|
||||
const salesChannelService = container
|
||||
.resolve("salesChannelService")
|
||||
.withTransaction(manager)
|
||||
const salesChannelFeatureFlagKey =
|
||||
FeatureFlagUtils.SalesChannelFeatureFlag.key
|
||||
|
||||
const shippingProfileServiceTx =
|
||||
shippingProfileService.withTransaction(manager)
|
||||
|
||||
const shippingProfiles = await shippingProfileServiceTx.list({
|
||||
type: [
|
||||
ShippingProfileUtils.ShippingProfileType.DEFAULT,
|
||||
ShippingProfileUtils.ShippingProfileType.GIFT_CARD,
|
||||
],
|
||||
})
|
||||
const defaultShippingProfile = shippingProfiles.find(
|
||||
(sp) => sp.type === ShippingProfileUtils.ShippingProfileType.DEFAULT
|
||||
)
|
||||
const gitCardShippingProfile = shippingProfiles.find(
|
||||
(sp) => sp.type === ShippingProfileUtils.ShippingProfileType.GIFT_CARD
|
||||
)
|
||||
|
||||
let defaultSalesChannel: SalesChannelTypes.SalesChannelDTO | undefined
|
||||
if (featureFlagRouter.isFeatureEnabled(salesChannelFeatureFlagKey)) {
|
||||
defaultSalesChannel = await salesChannelService
|
||||
.withTransaction(manager)
|
||||
.retrieveDefault()
|
||||
}
|
||||
|
||||
const productsHandleShippingProfileIdMap = new Map<
|
||||
ProductHandle,
|
||||
ShippingProfileId
|
||||
>()
|
||||
const productsHandleSalesChannelsMap = new Map<
|
||||
ProductHandle,
|
||||
SalesChannelId[]
|
||||
>()
|
||||
const productsHandleVariantsIndexPricesMap = new Map<
|
||||
ProductHandle,
|
||||
VariantIndexAndPrices[]
|
||||
>()
|
||||
|
||||
for (const product of products) {
|
||||
product.handle ??= kebabCase(product.title)
|
||||
|
||||
if (product.is_giftcard) {
|
||||
productsHandleShippingProfileIdMap.set(
|
||||
product.handle!,
|
||||
gitCardShippingProfile!.id
|
||||
)
|
||||
} else {
|
||||
productsHandleShippingProfileIdMap.set(
|
||||
product.handle!,
|
||||
defaultShippingProfile!.id
|
||||
)
|
||||
}
|
||||
|
||||
if (
|
||||
featureFlagRouter.isFeatureEnabled(salesChannelFeatureFlagKey) &&
|
||||
!product.sales_channels?.length
|
||||
) {
|
||||
productsHandleSalesChannelsMap.set(product.handle!, [
|
||||
defaultSalesChannel!.id,
|
||||
])
|
||||
} else {
|
||||
productsHandleSalesChannelsMap.set(
|
||||
product.handle!,
|
||||
product.sales_channels!.map((s) => s.id)
|
||||
)
|
||||
}
|
||||
|
||||
if (product.variants) {
|
||||
const items =
|
||||
productsHandleVariantsIndexPricesMap.get(product.handle!) ?? []
|
||||
|
||||
product.variants.forEach((variant, index) => {
|
||||
items.push({
|
||||
index,
|
||||
prices: variant.prices!,
|
||||
})
|
||||
})
|
||||
|
||||
productsHandleVariantsIndexPricesMap.set(product.handle!, items)
|
||||
}
|
||||
}
|
||||
|
||||
products = products.map((productData) => {
|
||||
delete productData.sales_channels
|
||||
return productData
|
||||
})
|
||||
|
||||
return {
|
||||
products: products as ProductTypes.CreateProductDTO[],
|
||||
productsHandleShippingProfileIdMap,
|
||||
productsHandleSalesChannelsMap,
|
||||
productsHandleVariantsIndexPricesMap,
|
||||
}
|
||||
}
|
||||
|
||||
createProductsPrepareData.aliases = {
|
||||
payload: "payload",
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import { ProductTypes } from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
|
||||
|
||||
type HandlerInput = {
|
||||
products: ProductTypes.CreateProductDTO[]
|
||||
}
|
||||
|
||||
export async function createProducts({
|
||||
container,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInput>): Promise<ProductTypes.ProductDTO[]> {
|
||||
const data_ = data.products
|
||||
|
||||
const productModuleService: ProductTypes.IProductModuleService =
|
||||
container.resolve(ModulesDefinition[Modules.PRODUCT].registrationName)
|
||||
|
||||
return await productModuleService.create(data_)
|
||||
}
|
||||
|
||||
createProducts.aliases = {
|
||||
payload: "payload",
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
import { MedusaV2Flag, promiseAll } from "@medusajs/utils"
|
||||
import { Modules } from "@medusajs/modules-sdk"
|
||||
|
||||
type ProductHandle = string
|
||||
type SalesChannelId = string
|
||||
type PartialProduct = { handle: string; id: string }
|
||||
type HandlerInput = {
|
||||
productsHandleSalesChannelsMap: Map<ProductHandle, SalesChannelId[]>
|
||||
products: PartialProduct[]
|
||||
}
|
||||
|
||||
export async function detachSalesChannelFromProducts({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInput>): Promise<void> {
|
||||
const { manager } = context
|
||||
const featureFlagRouter = container.resolve("featureFlagRouter")
|
||||
|
||||
const productsHandleSalesChannelsMap = data.productsHandleSalesChannelsMap
|
||||
const products = data.products
|
||||
|
||||
const salesChannelService = container.resolve("salesChannelService")
|
||||
const salesChannelServiceTx = salesChannelService.withTransaction(manager)
|
||||
|
||||
const salesChannelIdProductIdsMap = new Map<ProductHandle, SalesChannelId[]>()
|
||||
products.forEach((product) => {
|
||||
const salesChannelIds = productsHandleSalesChannelsMap.get(product.handle!)
|
||||
if (salesChannelIds) {
|
||||
salesChannelIds.forEach((salesChannelId) => {
|
||||
const productIds = salesChannelIdProductIdsMap.get(salesChannelId) || []
|
||||
productIds.push(product.id)
|
||||
salesChannelIdProductIdsMap.set(salesChannelId, productIds)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
|
||||
const remoteLink = container.resolve("remoteLink")
|
||||
|
||||
for (const [
|
||||
salesChannelId,
|
||||
productIds,
|
||||
] of salesChannelIdProductIdsMap.entries()) {
|
||||
await promiseAll(
|
||||
productIds.map((id) =>
|
||||
remoteLink.dismiss({
|
||||
[Modules.PRODUCT]: {
|
||||
product_id: id,
|
||||
},
|
||||
[Modules.SALES_CHANNEL]: {
|
||||
sales_channel_id: salesChannelId,
|
||||
},
|
||||
})
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
await promiseAll(
|
||||
Array.from(salesChannelIdProductIdsMap.entries()).map(
|
||||
async ([salesChannelId, productIds]) => {
|
||||
return await salesChannelServiceTx.removeProducts(
|
||||
salesChannelId,
|
||||
productIds
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
detachSalesChannelFromProducts.aliases = {
|
||||
products: "products",
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
import { promiseAll } from "@medusajs/utils"
|
||||
|
||||
type ProductHandle = string
|
||||
type ShippingProfileId = string
|
||||
type PartialProduct = { handle: string; id: string }
|
||||
type HandlerInput = {
|
||||
productsHandleShippingProfileIdMap: Map<ProductHandle, ShippingProfileId>
|
||||
products: PartialProduct[]
|
||||
}
|
||||
|
||||
export async function detachShippingProfileFromProducts({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInput>): Promise<void> {
|
||||
const { manager } = context
|
||||
const productsHandleShippingProfileIdMap =
|
||||
data.productsHandleShippingProfileIdMap
|
||||
const products = data.products
|
||||
|
||||
const shippingProfileService = container.resolve("shippingProfileService")
|
||||
const shippingProfileServiceTx =
|
||||
shippingProfileService.withTransaction(manager)
|
||||
|
||||
const profileIdProductIdsMap = new Map<ShippingProfileId, ProductHandle[]>()
|
||||
products.forEach((product) => {
|
||||
const profileId = productsHandleShippingProfileIdMap.get(product.handle!)
|
||||
if (profileId) {
|
||||
const productIds = profileIdProductIdsMap.get(profileId) || []
|
||||
productIds.push(product.id)
|
||||
profileIdProductIdsMap.set(profileId, productIds)
|
||||
}
|
||||
})
|
||||
|
||||
await promiseAll(
|
||||
Array.from(profileIdProductIdsMap.entries()).map(
|
||||
async ([profileId, productIds]) => {
|
||||
return await shippingProfileServiceTx.removeProducts(
|
||||
profileId,
|
||||
productIds
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
detachShippingProfileFromProducts.aliases = {
|
||||
products: "products",
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
export * from "./attach-sales-channel-to-products"
|
||||
export * from "./attach-shipping-profile-to-products"
|
||||
export * from "./create-product-variants"
|
||||
export * from "./create-product-variants-prepare-data"
|
||||
export * from "./create-products"
|
||||
export * from "./create-products-prepare-data"
|
||||
export * from "./detach-sales-channel-from-products"
|
||||
export * from "./detach-shipping-profile-from-products"
|
||||
export * from "./list-products"
|
||||
export * from "./remove-product-variants"
|
||||
export * from "./remove-products"
|
||||
export * from "./revert-update-products"
|
||||
export * from "./revert-variant-prices"
|
||||
export * from "./update-product-variants"
|
||||
export * from "./update-product-variants-prepare-data"
|
||||
export * from "./update-products"
|
||||
export * from "./update-products-prepare-data"
|
||||
export * from "./update-products-variants-prices"
|
||||
export * from "./upsert-variant-prices"
|
||||
@@ -1,47 +0,0 @@
|
||||
import { ProductTypes, WorkflowTypes } from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type HandlerInput = {
|
||||
ids: string[]
|
||||
config?: WorkflowTypes.CommonWorkflow.WorkflowInputConfig
|
||||
}
|
||||
|
||||
export async function listProducts({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: // TODO: should return product DTO or priced product but needs to be created in the types package
|
||||
WorkflowArguments<HandlerInput>): Promise<ProductTypes.ProductDTO[]> {
|
||||
const { manager } = context
|
||||
|
||||
const productIds = data.ids
|
||||
const listConfig = data.config?.listConfig ?? {}
|
||||
|
||||
const productService = container.resolve("productService")
|
||||
const pricingService = container.resolve("pricingService")
|
||||
|
||||
const config = {}
|
||||
let shouldUseConfig = false
|
||||
|
||||
if (listConfig.select) {
|
||||
shouldUseConfig = !!listConfig.select.length
|
||||
Object.assign(config, { select: listConfig.select })
|
||||
}
|
||||
|
||||
if (listConfig.relations) {
|
||||
shouldUseConfig = shouldUseConfig || !!listConfig.relations.length
|
||||
Object.assign(config, { relations: listConfig.relations })
|
||||
}
|
||||
|
||||
const rawProducts = await productService
|
||||
.withTransaction(manager as any)
|
||||
.list({ id: productIds }, shouldUseConfig ? config : undefined)
|
||||
|
||||
return await pricingService
|
||||
.withTransaction(manager as any)
|
||||
.setProductPrices(rawProducts)
|
||||
}
|
||||
|
||||
listProducts.aliases = {
|
||||
ids: "ids",
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
|
||||
import { IProductModuleService } from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type HandlerInput = { productVariants: { id: string }[] }
|
||||
|
||||
export async function removeProductVariants({
|
||||
container,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInput>): Promise<void> {
|
||||
if (!data.productVariants.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const productModuleService: IProductModuleService = container.resolve(
|
||||
ModulesDefinition[Modules.PRODUCT].registrationName
|
||||
)
|
||||
|
||||
await productModuleService.deleteVariants(
|
||||
data.productVariants.map((p) => p.id)
|
||||
)
|
||||
}
|
||||
|
||||
removeProductVariants.aliases = {
|
||||
productVariants: "productVariants",
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import { ProductTypes } from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
|
||||
|
||||
type HandlerInput = { products: { id: string }[] }
|
||||
|
||||
export async function removeProducts({
|
||||
container,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInput>): Promise<void> {
|
||||
if (!data.products.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const productModuleService: ProductTypes.IProductModuleService =
|
||||
container.resolve(ModulesDefinition[Modules.PRODUCT].registrationName)
|
||||
|
||||
await productModuleService.softDelete(data.products.map((p) => p.id))
|
||||
}
|
||||
|
||||
removeProducts.aliases = {
|
||||
products: "products",
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
ProductDTO,
|
||||
ProductTypes,
|
||||
ProductVariantDTO,
|
||||
UpdateProductDTO,
|
||||
} from "@medusajs/types"
|
||||
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
import { UpdateProductsPreparedData } from "./update-products-prepare-data"
|
||||
|
||||
type HandlerInput = UpdateProductsPreparedData & {
|
||||
variants: ProductVariantDTO[]
|
||||
}
|
||||
|
||||
export async function revertUpdateProducts({
|
||||
container,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInput>): Promise<ProductDTO[]> {
|
||||
const productModuleService: ProductTypes.IProductModuleService =
|
||||
container.resolve(ModulesDefinition[Modules.PRODUCT].registrationName)
|
||||
|
||||
// restore variants that have been soft deleted during update products step
|
||||
await productModuleService.restoreVariants(data.variants.map((v) => v.id))
|
||||
data.originalProducts.forEach((product) => {
|
||||
// @ts-ignore
|
||||
product.variants = product.variants.map((v) => ({ id: v.id }))
|
||||
})
|
||||
|
||||
return await productModuleService.upsert(
|
||||
data.originalProducts as unknown as UpdateProductDTO[]
|
||||
)
|
||||
}
|
||||
|
||||
revertUpdateProducts.aliases = {
|
||||
preparedData: "preparedData",
|
||||
variants: "variants",
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
import { PricingTypes } from "@medusajs/types"
|
||||
import { MedusaV2Flag } from "@medusajs/utils"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type HandlerInput = {
|
||||
createdLinks: Record<any, any>[]
|
||||
originalMoneyAmounts: PricingTypes.MoneyAmountDTO[]
|
||||
createdPriceSets: PricingTypes.PriceSetDTO[]
|
||||
}
|
||||
|
||||
export async function revertVariantPrices({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInput>): Promise<void> {
|
||||
const {
|
||||
createdLinks = [],
|
||||
originalMoneyAmounts = [],
|
||||
createdPriceSets = [],
|
||||
} = data
|
||||
|
||||
const featureFlagRouter = container.resolve("featureFlagRouter")
|
||||
const isPricingDomainEnabled = featureFlagRouter.isFeatureEnabled(
|
||||
MedusaV2Flag.key
|
||||
)
|
||||
|
||||
if (!isPricingDomainEnabled) {
|
||||
return
|
||||
}
|
||||
|
||||
const pricingModuleService = container.resolve("pricingModuleService")
|
||||
const remoteLink = container.resolve("remoteLink")
|
||||
|
||||
await remoteLink.remove(createdLinks)
|
||||
|
||||
if (originalMoneyAmounts.length) {
|
||||
await pricingModuleService.updateMoneyAmounts(originalMoneyAmounts)
|
||||
}
|
||||
|
||||
if (createdPriceSets.length) {
|
||||
await pricingModuleService.delete({
|
||||
id: createdPriceSets.map((cps) => cps.id),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
revertVariantPrices.aliases = {
|
||||
productVariantsPrices: "productVariantsPrices",
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
|
||||
import {
|
||||
BigNumberInput,
|
||||
ProductTypes,
|
||||
ProductWorkflow,
|
||||
WorkflowTypes,
|
||||
} from "@medusajs/types"
|
||||
import { MedusaV2Flag } from "@medusajs/utils"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type VariantPrice = {
|
||||
region_id?: string
|
||||
currency_code?: string
|
||||
amount: BigNumberInput
|
||||
min_quantity?: BigNumberInput
|
||||
max_quantity?: BigNumberInput
|
||||
}
|
||||
|
||||
export type UpdateProductVariantsPreparedData = {
|
||||
productVariants: ProductWorkflow.UpdateProductVariantsInputDTO[]
|
||||
variantPricesMap: Map<string, VariantPrice[]>
|
||||
productVariantsMap: Map<
|
||||
string,
|
||||
ProductWorkflow.UpdateProductVariantsInputDTO[]
|
||||
>
|
||||
}
|
||||
|
||||
export async function updateProductVariantsPrepareData({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<WorkflowTypes.ProductWorkflow.UpdateProductVariantsWorkflowInputDTO>): Promise<UpdateProductVariantsPreparedData> {
|
||||
const featureFlagRouter = container.resolve("featureFlagRouter")
|
||||
const isPricingDomainEnabled = featureFlagRouter.isFeatureEnabled(
|
||||
MedusaV2Flag.key
|
||||
)
|
||||
let productVariants: ProductWorkflow.UpdateProductVariantsInputDTO[] =
|
||||
data.productVariants || []
|
||||
|
||||
const variantsDataMap = new Map<
|
||||
string,
|
||||
ProductWorkflow.UpdateProductVariantsInputDTO
|
||||
>(
|
||||
productVariants.map((productVariantData) => [
|
||||
productVariantData.id,
|
||||
productVariantData,
|
||||
])
|
||||
)
|
||||
|
||||
const variantIds = productVariants.map((pv) => pv.id) as string[]
|
||||
const productVariantsMap = new Map<
|
||||
string,
|
||||
ProductWorkflow.UpdateProductVariantsInputDTO[]
|
||||
>()
|
||||
const variantPricesMap = new Map<string, VariantPrice[]>()
|
||||
|
||||
const productModuleService: ProductTypes.IProductModuleService =
|
||||
container.resolve(ModulesDefinition[Modules.PRODUCT].registrationName)
|
||||
|
||||
const variantsWithProductIds = await productModuleService.listVariants(
|
||||
{
|
||||
id: variantIds,
|
||||
},
|
||||
{
|
||||
select: ["id", "product_id"],
|
||||
take: null,
|
||||
}
|
||||
)
|
||||
|
||||
for (const variantWithProductID of variantsWithProductIds) {
|
||||
const variantData = variantsDataMap.get(variantWithProductID.id)
|
||||
|
||||
if (!variantData) {
|
||||
continue
|
||||
}
|
||||
|
||||
variantPricesMap.set(variantWithProductID.id, variantData.prices || [])
|
||||
if (isPricingDomainEnabled) {
|
||||
delete variantData.prices
|
||||
}
|
||||
|
||||
const variantsData: ProductWorkflow.UpdateProductVariantsInputDTO[] =
|
||||
productVariantsMap.get(variantWithProductID.product_id!) || []
|
||||
|
||||
if (variantData) {
|
||||
variantsData.push(variantData)
|
||||
}
|
||||
|
||||
productVariantsMap.set(variantWithProductID.product_id!, variantsData)
|
||||
}
|
||||
|
||||
return {
|
||||
productVariants,
|
||||
variantPricesMap,
|
||||
productVariantsMap,
|
||||
}
|
||||
}
|
||||
|
||||
updateProductVariantsPrepareData.aliases = {
|
||||
payload: "payload",
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
|
||||
import { ProductTypes, UpdateProductVariantDTO } from "@medusajs/types"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type HandlerInput = {
|
||||
productVariantsMap: Map<string, ProductTypes.UpdateProductVariantDTO[]>
|
||||
}
|
||||
|
||||
export async function updateProductVariants({
|
||||
container,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInput>): Promise<
|
||||
ProductTypes.UpdateProductVariantDTO[]
|
||||
> {
|
||||
const { productVariantsMap } = data
|
||||
const productsVariants: ProductTypes.UpdateProductVariantDTO[] = []
|
||||
const updateVariantsData: ProductTypes.UpdateProductVariantDTO[] = []
|
||||
const productModuleService: ProductTypes.IProductModuleService =
|
||||
container.resolve(ModulesDefinition[Modules.PRODUCT].registrationName)
|
||||
|
||||
for (const [product_id, variantsUpdateData = []] of productVariantsMap) {
|
||||
updateVariantsData.push(
|
||||
...variantsUpdateData.map((update) => ({ ...update, product_id }))
|
||||
)
|
||||
|
||||
productsVariants.push(...variantsUpdateData)
|
||||
}
|
||||
|
||||
if (updateVariantsData.length) {
|
||||
await productModuleService.upsertVariants(updateVariantsData)
|
||||
}
|
||||
|
||||
return productsVariants
|
||||
}
|
||||
|
||||
updateProductVariants.aliases = {
|
||||
payload: "payload",
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
import {
|
||||
BigNumberInput,
|
||||
ProductDTO,
|
||||
SalesChannelDTO,
|
||||
WorkflowTypes,
|
||||
} from "@medusajs/types"
|
||||
import { MedusaV2Flag } from "@medusajs/utils"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type ProductWithSalesChannelsDTO = ProductDTO & {
|
||||
sales_channels?: SalesChannelDTO[]
|
||||
}
|
||||
|
||||
type VariantPrice = {
|
||||
region_id?: string
|
||||
currency_code?: string
|
||||
amount: BigNumberInput
|
||||
min_quantity?: BigNumberInput
|
||||
max_quantity?: BigNumberInput
|
||||
}
|
||||
|
||||
export type UpdateProductsPreparedData = {
|
||||
originalProducts: ProductWithSalesChannelsDTO[]
|
||||
productHandleAddedChannelsMap: Map<string, string[]>
|
||||
productHandleRemovedChannelsMap: Map<string, string[]>
|
||||
variantPricesMap: Map<string, VariantPrice[]>
|
||||
}
|
||||
|
||||
export async function updateProductsPrepareData({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<WorkflowTypes.ProductWorkflow.UpdateProductsWorkflowInputDTO>): Promise<UpdateProductsPreparedData> {
|
||||
const featureFlagRouter = container.resolve("featureFlagRouter")
|
||||
const isPricingDomainEnabled = featureFlagRouter.isFeatureEnabled(
|
||||
MedusaV2Flag.key
|
||||
)
|
||||
|
||||
const variantPricesMap = new Map<string, VariantPrice[]>()
|
||||
const ids = data.products.map((product) => product.id)
|
||||
|
||||
const productHandleAddedChannelsMap = new Map<string, string[]>()
|
||||
const productHandleRemovedChannelsMap = new Map<string, string[]>()
|
||||
|
||||
const productService = container.resolve("productService")
|
||||
const productServiceTx = productService.withTransaction(context.manager)
|
||||
|
||||
const products = await productServiceTx.list(
|
||||
// TODO: use RemoteQuery - sales_channels needs to be added to the joiner config
|
||||
{ id: ids },
|
||||
{
|
||||
relations: [
|
||||
"variants",
|
||||
"variants.options",
|
||||
"images",
|
||||
"options",
|
||||
"tags",
|
||||
"collection",
|
||||
"sales_channels",
|
||||
],
|
||||
take: null,
|
||||
}
|
||||
)
|
||||
|
||||
const productsMap = new Map(products.map((product) => [product.id, product]))
|
||||
|
||||
data.products.forEach((productInput) => {
|
||||
const removedChannels: string[] = []
|
||||
const addedChannels: string[] = []
|
||||
|
||||
const currentProduct = productsMap.get(
|
||||
productInput.id
|
||||
) as unknown as ProductWithSalesChannelsDTO
|
||||
|
||||
if (productInput.sales_channels) {
|
||||
productInput.sales_channels.forEach((channel) => {
|
||||
if (
|
||||
!currentProduct.sales_channels?.find((sc) => sc.id === channel.id)
|
||||
) {
|
||||
addedChannels.push(channel.id)
|
||||
}
|
||||
})
|
||||
|
||||
currentProduct.sales_channels?.forEach((channel) => {
|
||||
if (!productInput.sales_channels!.find((sc) => sc.id === channel.id)) {
|
||||
removedChannels.push(channel.id)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
for (const variantInput of productInput.variants || []) {
|
||||
if (variantInput.id) {
|
||||
variantPricesMap.set(variantInput.id, variantInput.prices || [])
|
||||
}
|
||||
|
||||
if (isPricingDomainEnabled) {
|
||||
delete variantInput.prices
|
||||
}
|
||||
}
|
||||
|
||||
productHandleAddedChannelsMap.set(currentProduct.handle!, addedChannels)
|
||||
productHandleRemovedChannelsMap.set(currentProduct.handle!, removedChannels)
|
||||
})
|
||||
|
||||
return {
|
||||
originalProducts: products,
|
||||
productHandleAddedChannelsMap,
|
||||
productHandleRemovedChannelsMap,
|
||||
variantPricesMap,
|
||||
}
|
||||
}
|
||||
|
||||
updateProductsPrepareData.aliases = {
|
||||
preparedData: "preparedData",
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
import { ProductTypes, WorkflowTypes } from "@medusajs/types"
|
||||
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { MedusaError, MedusaV2Flag } from "@medusajs/utils"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type ProductHandle = string
|
||||
type VariantIndexAndPrices = {
|
||||
index: number
|
||||
prices: WorkflowTypes.ProductWorkflow.CreateProductVariantPricesInputDTO[]
|
||||
}
|
||||
type HandlerInput = {
|
||||
productsHandleVariantsIndexPricesMap: Map<
|
||||
ProductHandle,
|
||||
VariantIndexAndPrices[]
|
||||
>
|
||||
products: ProductTypes.ProductDTO[]
|
||||
}
|
||||
|
||||
export async function updateProductsVariantsPrices({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInput>) {
|
||||
const { manager } = context
|
||||
const products = data.products
|
||||
const productsHandleVariantsIndexPricesMap =
|
||||
data.productsHandleVariantsIndexPricesMap
|
||||
|
||||
const productVariantService = container.resolve("productVariantService")
|
||||
const regionService = container.resolve("regionService")
|
||||
const featureFlagRouter = container.resolve("featureFlagRouter")
|
||||
const productVariantServiceTx = productVariantService.withTransaction(manager)
|
||||
const variantIdsPricesData: any[] = []
|
||||
const variantPricesMap = new Map<string, any[]>()
|
||||
|
||||
const productsMap = new Map<string, ProductTypes.ProductDTO>(
|
||||
products.map((p) => [p.handle!, p])
|
||||
)
|
||||
|
||||
const regionIds = new Set()
|
||||
|
||||
for (const mapData of productsHandleVariantsIndexPricesMap.entries()) {
|
||||
const [handle, variantData] = mapData
|
||||
|
||||
const product = productsMap.get(handle)
|
||||
if (!product) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Product with handle ${handle} not found`
|
||||
)
|
||||
}
|
||||
|
||||
variantData.forEach((item, index) => {
|
||||
const variant = product.variants[index]
|
||||
variantIdsPricesData.push({
|
||||
variantId: variant.id,
|
||||
prices: item.prices,
|
||||
})
|
||||
|
||||
const prices: any[] = []
|
||||
variantPricesMap.set(variant.id, prices)
|
||||
|
||||
item.prices.forEach((price) => {
|
||||
const obj = {
|
||||
amount: price.amount,
|
||||
currency_code: price.currency_code,
|
||||
}
|
||||
|
||||
if (price.region_id) {
|
||||
regionIds.add(price.region_id)
|
||||
;(obj as any).region_id = price.region_id
|
||||
}
|
||||
|
||||
prices.push(obj)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (regionIds.size) {
|
||||
const regions = await regionService.list({
|
||||
id: [...regionIds],
|
||||
})
|
||||
const regionMap = new Map<string, any>(regions.map((r) => [r.id, r]))
|
||||
|
||||
for (const [, prices] of variantPricesMap.entries()) {
|
||||
prices.forEach((price) => {
|
||||
if (price.region_id) {
|
||||
const region = regionMap.get(price.region_id)
|
||||
price.currency_code = region?.currency_code
|
||||
price.rules = {
|
||||
region_id: price.region_id,
|
||||
}
|
||||
|
||||
delete price.region_id
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
|
||||
const remoteLink = container.resolve("remoteLink")
|
||||
const pricingModuleService = container.resolve(
|
||||
ModuleRegistrationName.PRICING
|
||||
)
|
||||
|
||||
const priceSetsToCreate = variantIdsPricesData.map(({ variantId }) => ({
|
||||
rules: [{ rule_attribute: "region_id" }],
|
||||
prices: variantPricesMap.get(variantId),
|
||||
}))
|
||||
|
||||
const priceSets = await pricingModuleService.create(priceSetsToCreate)
|
||||
|
||||
const links = priceSets.map((priceSet, index) => ({
|
||||
productService: {
|
||||
variant_id: variantIdsPricesData[index].variantId,
|
||||
},
|
||||
pricingService: {
|
||||
price_set_id: priceSet.id,
|
||||
},
|
||||
}))
|
||||
|
||||
await remoteLink.create(links)
|
||||
} else {
|
||||
await productVariantServiceTx.updateVariantPrices(variantIdsPricesData)
|
||||
}
|
||||
}
|
||||
|
||||
updateProductsVariantsPrices.aliases = {
|
||||
products: "products",
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import { Modules, ModulesDefinition } from "@medusajs/modules-sdk"
|
||||
import { ProductDTO, ProductTypes } from "@medusajs/types"
|
||||
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type HandlerInput = {
|
||||
products: ProductTypes.UpdateProductDTO[]
|
||||
}
|
||||
|
||||
export async function updateProducts({
|
||||
container,
|
||||
context,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInput>): Promise<ProductDTO[]> {
|
||||
if (!data.products.length) {
|
||||
return []
|
||||
}
|
||||
|
||||
const productModuleService: ProductTypes.IProductModuleService =
|
||||
container.resolve(ModulesDefinition[Modules.PRODUCT].registrationName)
|
||||
|
||||
const products = await productModuleService.upsert(data.products)
|
||||
|
||||
return await productModuleService.list(
|
||||
{ id: products.map((p) => p.id) },
|
||||
{
|
||||
relations: [
|
||||
"variants",
|
||||
"variants.options",
|
||||
"images",
|
||||
"options",
|
||||
"tags",
|
||||
// "type",
|
||||
"collection",
|
||||
// "profiles",
|
||||
// "sales_channels",
|
||||
],
|
||||
take: null,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
updateProducts.aliases = {
|
||||
products: "products",
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
import { BigNumberInput, PricingTypes } from "@medusajs/types"
|
||||
import { MedusaV2Flag } from "@medusajs/utils"
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type VariantPrice = {
|
||||
id?: string
|
||||
region_id?: string
|
||||
currency_code: string
|
||||
amount: BigNumberInput
|
||||
min_quantity?: BigNumberInput
|
||||
max_quantity?: BigNumberInput
|
||||
rules: Record<string, string>
|
||||
}
|
||||
|
||||
type RegionDTO = {
|
||||
id: string
|
||||
currency_code: string
|
||||
}
|
||||
|
||||
type HandlerInput = {
|
||||
variantPricesMap: Map<string, VariantPrice[]>
|
||||
}
|
||||
|
||||
export async function upsertVariantPrices({
|
||||
container,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInput>) {
|
||||
const { variantPricesMap } = data
|
||||
const featureFlagRouter = container.resolve("featureFlagRouter")
|
||||
|
||||
if (!featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
|
||||
return {
|
||||
createdLinks: [],
|
||||
originalMoneyAmounts: [],
|
||||
createdPriceSets: [],
|
||||
}
|
||||
}
|
||||
|
||||
const pricingModuleService = container.resolve("pricingModuleService")
|
||||
const regionService = container.resolve("regionService")
|
||||
const remoteLink = container.resolve("remoteLink")
|
||||
const remoteQuery = container.resolve("remoteQuery")
|
||||
|
||||
const variables = {
|
||||
variant_id: [...variantPricesMap.keys()],
|
||||
}
|
||||
|
||||
const query = {
|
||||
product_variant_price_set: {
|
||||
__args: variables,
|
||||
fields: ["variant_id", "price_set_id"],
|
||||
},
|
||||
}
|
||||
|
||||
const variantPriceSets = await remoteQuery(query)
|
||||
|
||||
const variantIdToPriceSetIdMap: Map<string, string> = new Map(
|
||||
variantPriceSets.map((variantPriceSet) => [
|
||||
variantPriceSet.variant_id,
|
||||
variantPriceSet.price_set_id,
|
||||
])
|
||||
)
|
||||
|
||||
const moneyAmountsToUpdate: PricingTypes.UpdateMoneyAmountDTO[] = []
|
||||
const createdPriceSets: PricingTypes.PriceSetDTO[] = []
|
||||
const ruleSetPricesToAdd: PricingTypes.CreatePricesDTO[] = []
|
||||
const linksToCreate: any[] = []
|
||||
|
||||
for (const [variantId, prices = []] of variantPricesMap) {
|
||||
const priceSetToCreate: PricingTypes.CreatePriceSetDTO = {
|
||||
rules: [{ rule_attribute: "region_id" }],
|
||||
prices: [],
|
||||
}
|
||||
const regionIds = prices.map((price) => price.region_id)
|
||||
const regions = await regionService.list({ id: regionIds })
|
||||
const regionsMap: Map<string, RegionDTO> = new Map(
|
||||
regions.map((region: RegionDTO) => [region.id, region])
|
||||
)
|
||||
|
||||
for (const price of prices) {
|
||||
const region = price.region_id && regionsMap.get(price.region_id)
|
||||
let region_currency_code: string | undefined
|
||||
let region_rules: Record<string, string> | undefined
|
||||
|
||||
if (region) {
|
||||
region_currency_code = region.currency_code
|
||||
region_rules = {
|
||||
region_id: region.id,
|
||||
}
|
||||
}
|
||||
|
||||
if (price.id) {
|
||||
const priceToUpdate = {
|
||||
id: price.id,
|
||||
min_quantity: price.min_quantity,
|
||||
max_quantity: price.max_quantity,
|
||||
amount: price.amount,
|
||||
currency_code: (
|
||||
region_currency_code ?? price.currency_code
|
||||
).toLowerCase(),
|
||||
}
|
||||
|
||||
moneyAmountsToUpdate.push(priceToUpdate)
|
||||
} else {
|
||||
const variantPrice: PricingTypes.CreatePricesDTO = {
|
||||
min_quantity: price.min_quantity,
|
||||
max_quantity: price.max_quantity,
|
||||
amount: price.amount,
|
||||
currency_code: (
|
||||
region_currency_code ?? price.currency_code
|
||||
).toLowerCase(),
|
||||
rules: region_rules ?? {},
|
||||
}
|
||||
|
||||
delete price.region_id
|
||||
|
||||
if (variantIdToPriceSetIdMap.get(variantId)) {
|
||||
ruleSetPricesToAdd.push(variantPrice)
|
||||
} else {
|
||||
priceSetToCreate.prices?.push(variantPrice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let priceSetId = variantIdToPriceSetIdMap.get(variantId)
|
||||
|
||||
if (priceSetId) {
|
||||
await pricingModuleService.addPrices({
|
||||
priceSetId,
|
||||
prices: ruleSetPricesToAdd,
|
||||
})
|
||||
} else {
|
||||
const createdPriceSet = await pricingModuleService.create(
|
||||
priceSetToCreate
|
||||
)
|
||||
priceSetId = createdPriceSet?.id
|
||||
|
||||
createdPriceSets.push(createdPriceSet)
|
||||
|
||||
linksToCreate.push({
|
||||
productService: {
|
||||
variant_id: variantId,
|
||||
},
|
||||
pricingService: {
|
||||
price_set_id: priceSetId,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const createdLinks = await remoteLink.create(linksToCreate)
|
||||
|
||||
let originalMoneyAmounts = await pricingModuleService.listMoneyAmounts(
|
||||
{
|
||||
id: moneyAmountsToUpdate.map((matu) => matu.id),
|
||||
},
|
||||
{
|
||||
select: ["id", "currency_code", "amount", "min_quantity", "max_quantity"],
|
||||
take: null,
|
||||
}
|
||||
)
|
||||
|
||||
if (moneyAmountsToUpdate.length) {
|
||||
await pricingModuleService.updateMoneyAmounts(moneyAmountsToUpdate)
|
||||
}
|
||||
|
||||
return {
|
||||
createdLinks,
|
||||
originalMoneyAmounts,
|
||||
createdPriceSets,
|
||||
}
|
||||
}
|
||||
|
||||
upsertVariantPrices.aliases = {
|
||||
productVariantsPrices: "productVariantsPrices",
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
import { RegionTypes } from "@medusajs/types"
|
||||
import { isDefined, MedusaError } from "@medusajs/utils"
|
||||
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type RegionResultDTO = {
|
||||
region_id?: string
|
||||
// TODO: Replace with RegionDTO from Region Module
|
||||
region?: RegionTypes.RegionDTO__legacy
|
||||
}
|
||||
|
||||
type HandlerInputData = {
|
||||
region: {
|
||||
region_id: string
|
||||
}
|
||||
}
|
||||
|
||||
enum Aliases {
|
||||
Region = "region",
|
||||
}
|
||||
|
||||
export async function findRegion({
|
||||
container,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInputData>): Promise<RegionResultDTO> {
|
||||
const regionService = container.resolve("regionService")
|
||||
|
||||
let regionId: string
|
||||
const regionDTO: RegionResultDTO = {}
|
||||
|
||||
if (isDefined(data[Aliases.Region].region_id)) {
|
||||
regionDTO.region_id = data[Aliases.Region].region_id
|
||||
regionDTO.region = await regionService.retrieve(regionDTO.region_id, {
|
||||
relations: ["countries"],
|
||||
})
|
||||
} else {
|
||||
const regions = await regionService.list(
|
||||
{},
|
||||
{
|
||||
relations: ["countries"],
|
||||
}
|
||||
)
|
||||
|
||||
if (!regions?.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`A region is required to create a cart`
|
||||
)
|
||||
}
|
||||
|
||||
regionDTO.region_id = regions[0].id
|
||||
regionDTO.region = regions[0]
|
||||
}
|
||||
|
||||
return regionDTO
|
||||
}
|
||||
|
||||
findRegion.aliases = Aliases
|
||||
@@ -1 +0,0 @@
|
||||
export * from "./find-region"
|
||||
@@ -1,73 +0,0 @@
|
||||
import { isDefined, MedusaError } from "@medusajs/utils"
|
||||
|
||||
import { WorkflowArguments } from "@medusajs/workflows-sdk"
|
||||
|
||||
type AttachSalesChannelDTO = {
|
||||
sales_channel_id?: string
|
||||
}
|
||||
|
||||
type HandlerInputData = {
|
||||
sales_channel: {
|
||||
sales_channel_id?: string
|
||||
publishableApiKeyScopes?: {
|
||||
sales_channel_ids?: string[]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Aliases {
|
||||
SalesChannel = "sales_channel",
|
||||
}
|
||||
|
||||
export async function findSalesChannel({
|
||||
container,
|
||||
data,
|
||||
}: WorkflowArguments<HandlerInputData>): Promise<AttachSalesChannelDTO> {
|
||||
const salesChannelService = container.resolve("salesChannelService")
|
||||
const storeService = container.resolve("storeService")
|
||||
|
||||
let salesChannelId = data[Aliases.SalesChannel].sales_channel_id
|
||||
let salesChannel
|
||||
const salesChannelDTO: AttachSalesChannelDTO = {}
|
||||
const publishableApiKeyScopes =
|
||||
data[Aliases.SalesChannel].publishableApiKeyScopes || {}
|
||||
|
||||
delete data[Aliases.SalesChannel].publishableApiKeyScopes
|
||||
|
||||
if (
|
||||
!isDefined(salesChannelId) &&
|
||||
publishableApiKeyScopes?.sales_channel_ids?.length
|
||||
) {
|
||||
if (publishableApiKeyScopes.sales_channel_ids.length > 1) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.UNEXPECTED_STATE,
|
||||
"The provided PublishableApiKey has multiple associated sales channels."
|
||||
)
|
||||
}
|
||||
|
||||
salesChannelId = publishableApiKeyScopes.sales_channel_ids[0]
|
||||
}
|
||||
|
||||
if (isDefined(salesChannelId)) {
|
||||
salesChannel = await salesChannelService.retrieve(salesChannelId)
|
||||
} else {
|
||||
salesChannel = (
|
||||
await storeService.retrieve({
|
||||
relations: ["default_sales_channel"],
|
||||
})
|
||||
).default_sales_channel
|
||||
}
|
||||
|
||||
if (salesChannel.is_disabled) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Unable to assign the cart to a disabled Sales Channel "${salesChannel.name}"`
|
||||
)
|
||||
}
|
||||
|
||||
salesChannelDTO.sales_channel_id = salesChannel?.id
|
||||
|
||||
return salesChannelDTO
|
||||
}
|
||||
|
||||
findSalesChannel.aliases = Aliases
|
||||
@@ -1 +0,0 @@
|
||||
export * from "./find-sales-channel"
|
||||
@@ -5,10 +5,8 @@ export * from "./customer"
|
||||
export * from "./customer-group"
|
||||
export * from "./defaults"
|
||||
export * from "./definition"
|
||||
export * from "./definitions"
|
||||
export * from "./file"
|
||||
export * from "./fulfillment"
|
||||
export * as Handlers from "./handlers"
|
||||
export * from "./inventory"
|
||||
export * from "./invite"
|
||||
export * from "./order"
|
||||
|
||||
Reference in New Issue
Block a user