feat: Cart SalesChannel link + clean-up (#6418)

This commit is contained in:
Oli Juhl
2024-02-16 20:48:56 +01:00
committed by GitHub
parent 1df14de183
commit 1ba35b02dd
29 changed files with 276 additions and 919 deletions

View File

@@ -1,238 +0,0 @@
import {
TransactionStepsDefinition,
WorkflowManager,
} from "@medusajs/orchestration"
import { CartWorkflow } from "@medusajs/types"
import { Workflows } from "../../definitions"
import {
AddressHandlers,
CartHandlers,
CommonHandlers,
CustomerHandlers,
RegionHandlers,
SalesChannelHandlers,
} from "../../handlers"
import { exportWorkflow, pipe } from "@medusajs/workflows-sdk"
enum CreateCartActions {
setContext = "setContext",
attachLineItems = "attachLineItems",
attachToSalesChannel = "attachToSalesChannel",
findRegion = "findRegion",
findSalesChannel = "findSalesChannel",
createCart = "createCart",
findOrCreateAddresses = "findOrCreateAddresses",
findOrCreateCustomer = "findOrCreateCustomer",
removeCart = "removeCart",
removeAddresses = "removeAddresses",
}
const workflowAlias = "cart"
const getWorkflowInput = (alias = workflowAlias) => ({
inputAlias: workflowAlias,
invoke: {
from: workflowAlias,
alias,
},
})
const workflowSteps: TransactionStepsDefinition = {
next: [
{
action: CreateCartActions.findOrCreateCustomer,
noCompensation: true,
},
{
action: CreateCartActions.findSalesChannel,
noCompensation: true,
},
{
action: CreateCartActions.setContext,
noCompensation: true,
},
{
action: CreateCartActions.findRegion,
noCompensation: true,
next: {
action: CreateCartActions.findOrCreateAddresses,
noCompensation: true,
next: {
action: CreateCartActions.createCart,
next: [
{
action: CreateCartActions.attachLineItems,
noCompensation: true,
},
{ action: CreateCartActions.attachToSalesChannel },
],
},
},
},
],
}
const handlers = new Map([
[
CreateCartActions.findOrCreateCustomer,
{
invoke: pipe(
getWorkflowInput(
CustomerHandlers.findOrCreateCustomer.aliases.Customer
),
CustomerHandlers.findOrCreateCustomer
),
},
],
[
CreateCartActions.findSalesChannel,
{
invoke: pipe(
getWorkflowInput(
SalesChannelHandlers.findSalesChannel.aliases.SalesChannel
),
SalesChannelHandlers.findSalesChannel
),
},
],
[
CreateCartActions.setContext,
{
invoke: pipe(
getWorkflowInput(CommonHandlers.setContext.aliases.Context),
CommonHandlers.setContext
),
},
],
[
CreateCartActions.findRegion,
{
invoke: pipe(
getWorkflowInput(RegionHandlers.findRegion.aliases.Region),
RegionHandlers.findRegion
),
},
],
[
CreateCartActions.findOrCreateAddresses,
{
invoke: pipe(
{
invoke: [
getWorkflowInput(
AddressHandlers.findOrCreateAddresses.aliases.Addresses
).invoke,
{
from: CreateCartActions.findRegion,
alias: AddressHandlers.findOrCreateAddresses.aliases.Region,
},
],
},
AddressHandlers.findOrCreateAddresses
),
},
],
[
CreateCartActions.createCart,
{
invoke: pipe(
{
invoke: [
{
from: CreateCartActions.findSalesChannel,
alias: CartHandlers.createCart.aliases.SalesChannel,
},
{
from: CreateCartActions.findRegion,
alias: CartHandlers.createCart.aliases.Region,
},
{
from: CreateCartActions.setContext,
alias: CartHandlers.createCart.aliases.Context,
},
{
from: CreateCartActions.findOrCreateCustomer,
alias: CartHandlers.createCart.aliases.Customer,
},
{
from: CreateCartActions.findOrCreateAddresses,
alias: CartHandlers.createCart.aliases.Addresses,
},
],
},
CartHandlers.createCart
),
compensate: pipe(
{
invoke: [
{
from: CreateCartActions.createCart,
alias: CartHandlers.removeCart.aliases.Cart,
},
],
},
CartHandlers.removeCart
),
},
],
[
CreateCartActions.attachLineItems,
{
invoke: pipe(
{
invoke: [
getWorkflowInput(
CartHandlers.attachLineItemsToCart.aliases.LineItems
).invoke,
{
from: CreateCartActions.createCart,
alias: CartHandlers.attachLineItemsToCart.aliases.Cart,
},
],
},
CartHandlers.attachLineItemsToCart
),
},
],
[
CreateCartActions.attachToSalesChannel,
{
invoke: pipe(
{
invoke: [
{
from: CreateCartActions.createCart,
alias: CartHandlers.attachCartToSalesChannel.aliases.Cart,
},
{
from: CreateCartActions.findSalesChannel,
alias: CartHandlers.attachCartToSalesChannel.aliases.SalesChannel,
},
],
},
CartHandlers.attachCartToSalesChannel
),
compensate: pipe(
{
invoke: [
{
from: CreateCartActions.findSalesChannel,
alias:
CartHandlers.detachCartFromSalesChannel.aliases.SalesChannel,
},
],
},
CartHandlers.detachCartFromSalesChannel
),
},
],
])
WorkflowManager.register(Workflows.CreateCart, workflowSteps, handlers)
type CreateCartWorkflowOutput = Record<any, any>
export const createCart = exportWorkflow<
CartWorkflow.CreateCartWorkflowInputDTO,
CreateCartWorkflowOutput
>(Workflows.CreateCart, CreateCartActions.createCart)

View File

@@ -1,4 +1,3 @@
export * from "./create-cart"
export * from "./steps"
export * from "./workflows"

View File

@@ -6,12 +6,12 @@ import {
} from "@medusajs/workflows-sdk"
import { createCartsStep, findOneOrAnyRegionStep } from "../steps"
type WorkflowInput = CreateCartWorkflowInputDTO
export const createCartWorkflowId = "create-cart"
export const createCartWorkflow = createWorkflow(
createCartWorkflowId,
(input: WorkflowData<WorkflowInput>): WorkflowData<CartDTO[]> => {
(
input: WorkflowData<CreateCartWorkflowInputDTO>
): WorkflowData<CartDTO[]> => {
const region = findOneOrAnyRegionStep({
regionId: input.region_id,
})

View File

@@ -1,43 +0,0 @@
import { MedusaV2Flag } from "@medusajs/utils"
import { WorkflowArguments } from "@medusajs/workflows-sdk"
import { Modules } from "@medusajs/modules-sdk"
type HandlerInputData = {
cart: {
id: string
}
sales_channel: {
sales_channel_id: string
}
}
enum Aliases {
Cart = "cart",
SalesChannel = "sales_channel",
}
export async function attachCartToSalesChannel({
container,
data,
}: WorkflowArguments<HandlerInputData>): Promise<void> {
const featureFlagRouter = container.resolve("featureFlagRouter")
const remoteLink = container.resolve("remoteLink")
if (!featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
return
}
const cart = data[Aliases.Cart]
const salesChannel = data[Aliases.SalesChannel]
await remoteLink.create({
[Modules.CART]: {
cart_id: cart.id,
},
[Modules.SALES_CHANNEL]: {
sales_channel_id: salesChannel.sales_channel_id,
},
})
}
attachCartToSalesChannel.aliases = Aliases

View File

@@ -1,57 +0,0 @@
import { CartWorkflow } from "@medusajs/types"
import { SalesChannelFeatureFlag } from "@medusajs/utils"
import { WorkflowArguments } from "@medusajs/workflows-sdk"
type HandlerInputData = {
line_items: {
items?: CartWorkflow.CreateLineItemInputDTO[]
}
cart: {
id: string
customer_id: string
region_id: string
}
}
enum Aliases {
LineItems = "line_items",
Cart = "cart",
}
export async function attachLineItemsToCart({
container,
context,
data,
}: WorkflowArguments<HandlerInputData>): Promise<void> {
const { manager } = context
const featureFlagRouter = container.resolve("featureFlagRouter")
const lineItemService = container.resolve("lineItemService")
const cartService = container.resolve("cartService")
const lineItemServiceTx = lineItemService.withTransaction(manager)
const cartServiceTx = cartService.withTransaction(manager)
let lineItems = data[Aliases.LineItems].items
const cart = data[Aliases.Cart]
if (lineItems?.length) {
const generateInputData = lineItems.map((item) => ({
variantId: item.variant_id,
quantity: item.quantity,
}))
lineItems = await lineItemServiceTx.generate(generateInputData, {
region_id: cart.region_id,
customer_id: cart.customer_id,
})
await cartServiceTx.addOrUpdateLineItems(cart.id, lineItems, {
validateSalesChannels: featureFlagRouter.isFeatureEnabled(
SalesChannelFeatureFlag.key
),
})
}
}
attachLineItemsToCart.aliases = Aliases

View File

@@ -1,59 +0,0 @@
import { AddressDTO, CustomerDTO, RegionDTO, legacy_CartDTO } from "@medusajs/types"
import { WorkflowArguments } from "@medusajs/workflows-sdk"
enum Aliases {
SalesChannel = "SalesChannel",
Addresses = "addresses",
Customer = "customer",
Region = "region",
Context = "context",
}
type HandlerInputData = {
sales_channel: {
sales_channel_id?: string
}
addresses: {
shipping_address?: AddressDTO
shipping_address_id: string
billing_address?: AddressDTO
billing_address_id: string
}
customer: {
customer?: CustomerDTO
customer_id?: string
email?: string
}
region: {
region?: RegionDTO
region_id: string
}
context: {
context: Record<any, any>
}
}
type HandlerOutputData = {
cart: legacy_CartDTO
}
export async function createCart({
container,
context,
data,
}: WorkflowArguments<HandlerInputData>): Promise<HandlerOutputData> {
const { manager } = context
const cartService = container.resolve("cartService")
const cartServiceTx = cartService.withTransaction(manager)
return await cartServiceTx.create({
...data[Aliases.SalesChannel],
...data[Aliases.Addresses],
...data[Aliases.Customer],
...data[Aliases.Region],
...data[Aliases.Context],
})
}
createCart.aliases = Aliases

View File

@@ -1,43 +0,0 @@
import { MedusaV2Flag } from "@medusajs/utils"
import { WorkflowArguments } from "@medusajs/workflows-sdk"
import { Modules } from "@medusajs/modules-sdk"
type HandlerInputData = {
cart: {
id: string
}
sales_channel: {
sales_channel_id: string
}
}
enum Aliases {
Cart = "cart",
SalesChannel = "sales_channel",
}
export async function detachCartFromSalesChannel({
container,
data,
}: WorkflowArguments<HandlerInputData>): Promise<void> {
const featureFlagRouter = container.resolve("featureFlagRouter")
const remoteLink = container.resolve("remoteLink")
if (!featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)) {
return
}
const cart = data[Aliases.Cart]
const salesChannel = data[Aliases.SalesChannel]
await remoteLink.dismiss({
[Modules.CART]: {
cart_id: cart.id,
},
[Modules.SALES_CHANNEL]: {
sales_channel_id: salesChannel.sales_channel_id,
},
})
}
detachCartFromSalesChannel.aliases = Aliases

View File

@@ -1,6 +0,0 @@
export * from "./attach-line-items-to-cart"
export * from "./create-cart"
export * from "./remove-cart"
export * from "./retrieve-cart"
export * from "./attach-cart-to-sales-channel"
export * from "./detach-cart-from-sales-channel"

View File

@@ -1,28 +0,0 @@
import { WorkflowArguments } from "@medusajs/workflows-sdk"
enum Aliases {
Cart = "cart",
}
type HandlerInputData = {
cart: {
id: string
}
}
export async function removeCart({
container,
context,
data,
}: WorkflowArguments<HandlerInputData>): Promise<void> {
const { manager } = context
const cartService = container.resolve("cartService")
const cartServiceTx = cartService.withTransaction(manager)
const cart = data[Aliases.Cart]
await cartServiceTx.delete(cart.id)
}
removeCart.aliases = Aliases

View File

@@ -1,40 +0,0 @@
import { legacy_CartDTO } from "@medusajs/types"
import { WorkflowArguments } from "@medusajs/workflows-sdk"
type HandlerInputData = {
cart: {
id: string
}
config: {
retrieveConfig: {
select: string[]
relations: string[]
}
}
}
enum Aliases {
Cart = "cart",
Config = "config",
}
export async function retrieveCart({
container,
context,
data,
}: WorkflowArguments<HandlerInputData>): Promise<legacy_CartDTO> {
const { manager } = context
const cartService = container.resolve("cartService")
const cartServiceTx = cartService.withTransaction(manager)
const retrieved = await cartServiceTx.retrieve(
data[Aliases.Cart].id,
data[Aliases.Config].retrieveConfig
)
return retrieved
}
retrieveCart.aliases = Aliases

View File

@@ -1,5 +1,4 @@
export * as AddressHandlers from "./address"
export * as CartHandlers from "./cart"
export * as CommonHandlers from "./common"
export * as CustomerHandlers from "./customer"
export * as InventoryHandlers from "./inventory"