chore(core-flows): product events (#8769)

This commit is contained in:
Carlos R. L. Rodrigues
2024-08-26 18:38:30 -03:00
committed by GitHub
parent 3b4eea08ef
commit 571f0c7629
17 changed files with 360 additions and 32 deletions

View File

@@ -169,6 +169,12 @@ medusaIntegrationTestRunner({
],
currency_code: "usd",
customer_id: customer.id,
transactions: [
{
amount: 61,
currency_code: "usd",
},
],
})
order2 = await orderModule.createOrders({
@@ -1006,6 +1012,104 @@ medusaIntegrationTestRunner({
expect(orderResult.fulfillment_status).toEqual("shipped")
})
})
describe("with only inbound items", () => {
beforeEach(async () => {
await api.post(
`/admin/orders/${order.id}/fulfillments`,
{
items: [
{
id: item.id,
quantity: 2,
},
],
},
adminHeaders
)
baseClaim = (
await api.post(
"/admin/claims",
{
order_id: order.id,
type: ClaimType.REPLACE,
description: "Base claim",
},
adminHeaders
)
).data.claim
claimId = baseClaim.id
item = order.items[0]
let result = await api.post(
`/admin/claims/${claimId}/inbound/items`,
{
items: [
{
id: item.id,
reason_id: returnReason.id,
quantity: 1,
},
],
},
adminHeaders
)
await api.post(
`/admin/claims/${claimId}/inbound/shipping-method`,
{ shipping_option_id: returnShippingOption.id },
adminHeaders
)
// Claim Items
await api.post(
`/admin/claims/${claimId}/claim-items`,
{
items: [
{
id: item.id,
reason: ClaimReason.PRODUCTION_FAILURE,
quantity: 1,
},
],
},
adminHeaders
)
await api.post(`/admin/claims/${claimId}/request`, {}, adminHeaders)
result = (
await api.get(
`/admin/claims?fields=*claim_items,*additional_items`,
adminHeaders
)
).data.claims
expect(result).toHaveLength(1)
expect(result[0].additional_items).toHaveLength(0)
expect(result[0].claim_items).toHaveLength(1)
expect(result[0].canceled_at).toBeNull()
})
it.only("test inbound only", async () => {
const orderCheck = (
await api.get(`/admin/orders/${order.id}`, adminHeaders)
).data.order
expect(orderCheck.summary).toEqual(
expect.objectContaining({
pending_difference: -10,
current_order_total: 51,
original_order_total: 61,
temporary_difference: 15,
})
)
expect(true).toBe(true)
})
})
})
describe("GET /admin/claims/:id", () => {

View File

@@ -1,5 +1,5 @@
import { OrderDTO } from "@medusajs/types"
import { Modules, OrderEvents, OrderStatus } from "@medusajs/utils"
import { Modules, OrderStatus, OrderWorkflowEvents } from "@medusajs/utils"
import {
WorkflowData,
WorkflowResponse,
@@ -171,7 +171,10 @@ export const completeCartWorkflow = createWorkflow(
},
])
emitEventStep({ eventName: OrderEvents.PLACED, data: { id: order.id } })
emitEventStep({
eventName: OrderWorkflowEvents.PLACED,
data: { id: order.id },
})
return new WorkflowResponse(order)
}

View File

@@ -15,7 +15,7 @@ type Input = {
*/
options?: Record<string, any>
/**
* Metadata that the subscriber receives in the `metadata` property
* Metadata that the subscriber receives in the `metadata` property
* of its first parameter.
*/
metadata?: Record<string, any>
@@ -33,15 +33,15 @@ export const emitEventStepId = "emit-event-step"
/**
* Emit an event.
*
*
* @example
* import {
* import {
* createWorkflow
* } from "@medusajs/workflows-sdk"
* import {
* emitEventStep
* } from "@medusajs/core-flows"
*
*
* const helloWorldWorkflow = createWorkflow(
* "hello-world",
* () => {
@@ -57,7 +57,7 @@ export const emitEventStepId = "emit-event-step"
export const emitEventStep = createStep(
emitEventStepId,
async (input: Input, context) => {
if (!input) {
if (!input?.data) {
return
}
@@ -78,11 +78,16 @@ export const emitEventStep = createStep(
metadata.eventGroupId = context.eventGroupId
}
const message: EventBusTypes.Message = {
const dataArray = Array.isArray(data_) ? data_ : [data_]
const message: EventBusTypes.Message[] = dataArray.map((dt) => ({
name: input.eventName,
data: data_,
data: dt,
options: input.options,
metadata,
}))
if (!message.length) {
return
}
await eventBus.emit(message)

View File

@@ -1,9 +1,12 @@
import { ProductCategoryWorkflow } from "@medusajs/types"
import { ProductCategoryWorkflowEvents } from "@medusajs/utils"
import {
WorkflowData,
WorkflowResponse,
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import { emitEventStep } from "../../common"
import { createProductCategoriesStep } from "../steps"
export const createProductCategoriesWorkflowId = "create-product-categories"
@@ -12,7 +15,25 @@ export const createProductCategoriesWorkflowId = "create-product-categories"
*/
export const createProductCategoriesWorkflow = createWorkflow(
createProductCategoriesWorkflowId,
(input: WorkflowData<ProductCategoryWorkflow.CreateProductCategoriesWorkflowInput>) => {
return new WorkflowResponse(createProductCategoriesStep(input))
(
input: WorkflowData<ProductCategoryWorkflow.CreateProductCategoriesWorkflowInput>
) => {
const createdProducts = createProductCategoriesStep(input)
const productCategoryIdEvents = transform(
{ createdProducts },
({ createdProducts }) => {
return createdProducts.map((v) => {
return { id: v.id }
})
}
)
emitEventStep({
eventName: ProductCategoryWorkflowEvents.CREATED,
data: productCategoryIdEvents,
})
return new WorkflowResponse(createdProducts)
}
)

View File

@@ -1,4 +1,11 @@
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
import { ProductCategoryWorkflowEvents } from "@medusajs/utils"
import {
WorkflowData,
WorkflowResponse,
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import { emitEventStep } from "../../common"
import { deleteProductCategoriesStep } from "../steps"
export const deleteProductCategoriesWorkflowId = "delete-product-categories"
@@ -8,6 +15,19 @@ export const deleteProductCategoriesWorkflowId = "delete-product-categories"
export const deleteProductCategoriesWorkflow = createWorkflow(
deleteProductCategoriesWorkflowId,
(input: WorkflowData<string[]>) => {
return deleteProductCategoriesStep(input)
const deleted = deleteProductCategoriesStep(input)
const productCategoryIdEvents = transform({ input }, ({ input }) => {
return input?.map((id) => {
return { id }
})
})
emitEventStep({
eventName: ProductCategoryWorkflowEvents.DELETED,
data: productCategoryIdEvents,
})
return new WorkflowResponse(deleted)
}
)

View File

@@ -1,9 +1,12 @@
import { ProductCategoryWorkflow } from "@medusajs/types"
import { ProductCategoryWorkflowEvents } from "@medusajs/utils"
import {
WorkflowData,
WorkflowResponse,
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import { emitEventStep } from "../../common"
import { updateProductCategoriesStep } from "../steps"
export const updateProductCategoriesWorkflowId = "update-product-categories"
@@ -12,7 +15,25 @@ export const updateProductCategoriesWorkflowId = "update-product-categories"
*/
export const updateProductCategoriesWorkflow = createWorkflow(
updateProductCategoriesWorkflowId,
(input: WorkflowData<ProductCategoryWorkflow.UpdateProductCategoriesWorkflowInput>) => {
return new WorkflowResponse(updateProductCategoriesStep(input))
(
input: WorkflowData<ProductCategoryWorkflow.UpdateProductCategoriesWorkflowInput>
) => {
const updatedCategories = updateProductCategoriesStep(input)
const productCategoryIdEvents = transform(
{ updatedCategories },
({ updatedCategories }) => {
return updatedCategories.map((v) => {
return { id: v.id }
})
}
)
emitEventStep({
eventName: ProductCategoryWorkflowEvents.UPDATED,
data: productCategoryIdEvents,
})
return new WorkflowResponse(updatedCategories)
}
)

View File

@@ -1,10 +1,13 @@
import { AdditionalData, ProductTypes } from "@medusajs/types"
import { ProductCollectionWorkflowEvents } from "@medusajs/utils"
import {
WorkflowData,
WorkflowResponse,
createHook,
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import { emitEventStep } from "../../common"
import { createCollectionsStep } from "../steps"
export type CreateCollectionsWorkflowInput = {
@@ -19,6 +22,18 @@ export const createCollectionsWorkflow = createWorkflow(
createCollectionsWorkflowId,
(input: WorkflowData<CreateCollectionsWorkflowInput>) => {
const collections = createCollectionsStep(input.collections)
const collectionIdEvents = transform({ collections }, ({ collections }) => {
return collections.map((v) => {
return { id: v.id }
})
})
emitEventStep({
eventName: ProductCollectionWorkflowEvents.CREATED,
data: collectionIdEvents,
})
const collectionsCreated = createHook("collectionsCreated", {
collections,
additional_data: input.additional_data,

View File

@@ -5,7 +5,7 @@ import {
PricingTypes,
ProductTypes,
} from "@medusajs/types"
import { Modules } from "@medusajs/utils"
import { Modules, ProductVariantWorkflowEvents } from "@medusajs/utils"
import {
WorkflowData,
WorkflowResponse,
@@ -13,6 +13,7 @@ import {
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import { emitEventStep } from "../../common"
import { createLinksWorkflow } from "../../common/workflows/create-links"
import { validateInventoryItems } from "../../inventory/steps/validate-inventory-items"
import { createInventoryItemsWorkflow } from "../../inventory/workflows/create-inventory-items"
@@ -234,6 +235,17 @@ export const createProductVariantsWorkflow = createWorkflow(
}
)
const variantIdEvents = transform({ response }, ({ response }) => {
return response.map((v) => {
return { id: v.id }
})
})
emitEventStep({
eventName: ProductVariantWorkflowEvents.CREATED,
data: variantIdEvents,
})
const productVariantsCreated = createHook("productVariantsCreated", {
product_variants: response,
additional_data: input.additional_data,

View File

@@ -4,7 +4,7 @@ import {
PricingTypes,
ProductTypes,
} from "@medusajs/types"
import { isPresent } from "@medusajs/utils"
import { ProductWorkflowEvents, isPresent } from "@medusajs/utils"
import {
WorkflowData,
WorkflowResponse,
@@ -12,6 +12,7 @@ import {
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import { emitEventStep } from "../../common"
import { associateProductsWithSalesChannelsStep } from "../../sales-channel"
import { createProductsStep } from "../steps/create-products"
import { createProductVariantsWorkflow } from "./create-product-variants"
@@ -101,6 +102,17 @@ export const createProductsWorkflow = createWorkflow(
}
)
const productIdEvents = transform({ response }, ({ response }) => {
return response.map((v) => {
return { id: v.id }
})
})
emitEventStep({
eventName: ProductWorkflowEvents.CREATED,
data: productIdEvents,
})
const productsCreated = createHook("productsCreated", {
products: response,
additional_data: input.additional_data,

View File

@@ -1,9 +1,12 @@
import { ProductCollectionWorkflowEvents } from "@medusajs/utils"
import {
WorkflowData,
WorkflowResponse,
createHook,
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import { emitEventStep } from "../../common"
import { deleteCollectionsStep } from "../steps"
export type DeleteCollectionsWorkflowInput = { ids: string[] }
@@ -16,6 +19,18 @@ export const deleteCollectionsWorkflow = createWorkflow(
deleteCollectionsWorkflowId,
(input: WorkflowData<DeleteCollectionsWorkflowInput>) => {
const deletedCollections = deleteCollectionsStep(input.ids)
const collectionIdEvents = transform({ input }, ({ input }) => {
return input.ids?.map((id) => {
return { id }
})
})
emitEventStep({
eventName: ProductCollectionWorkflowEvents.DELETED,
data: collectionIdEvents,
})
const collectionsDeleted = createHook("collectionsDeleted", {
ids: input.ids,
})

View File

@@ -1,12 +1,13 @@
import { Modules, ProductVariantWorkflowEvents } from "@medusajs/utils"
import {
createHook,
createWorkflow,
WorkflowData,
WorkflowResponse,
createHook,
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import { emitEventStep, removeRemoteLinkStep } from "../../common"
import { deleteProductVariantsStep } from "../steps"
import { removeRemoteLinkStep } from "../../common"
import { Modules } from "@medusajs/utils"
export type DeleteProductVariantsWorkflowInput = { ids: string[] }
@@ -22,6 +23,18 @@ export const deleteProductVariantsWorkflow = createWorkflow(
}).config({ name: "remove-variant-link-step" })
const deletedProductVariants = deleteProductVariantsStep(input.ids)
const variantIdEvents = transform({ input }, ({ input }) => {
return input.ids?.map((id) => {
return { id }
})
})
emitEventStep({
eventName: ProductVariantWorkflowEvents.DELETED,
data: variantIdEvents,
})
const productVariantsDeleted = createHook("productVariantsDeleted", {
ids: input.ids,
})

View File

@@ -1,15 +1,15 @@
import { Modules, ProductWorkflowEvents } from "@medusajs/utils"
import {
WorkflowData,
WorkflowResponse,
createHook,
createWorkflow,
parallelize,
transform,
WorkflowData,
WorkflowResponse,
} from "@medusajs/workflows-sdk"
import { removeRemoteLinkStep } from "../../common"
import { emitEventStep, removeRemoteLinkStep } from "../../common"
import { deleteProductsStep } from "../steps/delete-products"
import { getProductsStep } from "../steps/get-products"
import { Modules } from "@medusajs/utils"
export type DeleteProductsWorkflowInput = { ids: string[] }
@@ -37,6 +37,17 @@ export const deleteProductsWorkflow = createWorkflow(
deleteProductsStep(input.ids)
)
const productIdEvents = transform({ input }, ({ input }) => {
return input.ids?.map((id) => {
return { id }
})
})
emitEventStep({
eventName: ProductWorkflowEvents.DELETED,
data: productIdEvents,
})
const productsDeleted = createHook("productsDeleted", {
ids: input.ids,
})

View File

@@ -1,10 +1,13 @@
import { AdditionalData, ProductTypes } from "@medusajs/types"
import { ProductCollectionWorkflowEvents } from "@medusajs/utils"
import {
WorkflowData,
WorkflowResponse,
createHook,
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import { emitEventStep } from "../../common"
import { updateCollectionsStep } from "../steps"
export type UpdateCollectionsWorkflowInput = {
@@ -20,6 +23,21 @@ export const updateCollectionsWorkflow = createWorkflow(
updateCollectionsWorkflowId,
(input: WorkflowData<UpdateCollectionsWorkflowInput>) => {
const updatedCollections = updateCollectionsStep(input)
const collectionIdEvents = transform(
{ updatedCollections },
({ updatedCollections }) => {
return updatedCollections.map((v) => {
return { id: v.id }
})
}
)
emitEventStep({
eventName: ProductCollectionWorkflowEvents.UPDATED,
data: collectionIdEvents,
})
const collectionsUpdated = createHook("collectionsUpdated", {
additional_data: input.additional_data,
collections: updatedCollections,

View File

@@ -1,4 +1,5 @@
import { AdditionalData, PricingTypes, ProductTypes } from "@medusajs/types"
import { ProductVariantWorkflowEvents } from "@medusajs/utils"
import {
WorkflowData,
WorkflowResponse,
@@ -6,8 +7,9 @@ import {
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import { updateProductVariantsStep } from "../steps"
import { emitEventStep } from "../../common"
import { updatePriceSetsStep } from "../../pricing"
import { updateProductVariantsStep } from "../steps"
import { getVariantPricingLinkStep } from "../steps/get-variant-pricing-link"
export type UpdateProductVariantsWorkflowInput =
@@ -29,7 +31,9 @@ export const updateProductVariantsWorkflowId = "update-product-variants"
*/
export const updateProductVariantsWorkflow = createWorkflow(
updateProductVariantsWorkflowId,
(input: WorkflowData<UpdateProductVariantsWorkflowInput & AdditionalData>) => {
(
input: WorkflowData<UpdateProductVariantsWorkflowInput & AdditionalData>
) => {
// Passing prices to the product module will fail, we want to keep them for after the variant is updated.
const updateWithoutPrices = transform({ input }, (data) => {
if ("product_variants" in data.input) {
@@ -134,6 +138,17 @@ export const updateProductVariantsWorkflow = createWorkflow(
}
)
const variantIdEvents = transform({ response }, ({ response }) => {
return response.map((v) => {
return { id: v.id }
})
})
emitEventStep({
eventName: ProductVariantWorkflowEvents.UPDATED,
data: variantIdEvents,
})
const productVariantsUpdated = createHook("productVariantsUpdated", {
product_variants: response,
additional_data: input.additional_data,

View File

@@ -6,17 +6,22 @@ import {
ProductTypes,
UpdateProductVariantWorkflowInputDTO,
} from "@medusajs/types"
import { arrayDifference, Modules } from "@medusajs/utils"
import {
Modules,
ProductWorkflowEvents,
arrayDifference,
} from "@medusajs/utils"
import {
WorkflowData,
WorkflowResponse,
createHook,
createWorkflow,
transform,
WorkflowData,
WorkflowResponse,
} from "@medusajs/workflows-sdk"
import {
createRemoteLinkStep,
dismissRemoteLinkStep,
emitEventStep,
useRemoteQueryStep,
} from "../../common"
import { upsertVariantPricesWorkflow } from "./upsert-variant-prices"
@@ -36,7 +41,7 @@ export type UpdateProductsWorkflowInputProducts = {
})[]
} & AdditionalData
export type UpdateProductWorkflowInput =
export type UpdateProductWorkflowInput =
| UpdateProductsWorkflowInputSelector
| UpdateProductsWorkflowInputProducts
@@ -279,6 +284,20 @@ export const updateProductsWorkflow = createWorkflow(
dismissRemoteLinkStep(toDeleteSalesChannelLinks)
createRemoteLinkStep(salesChannelLinks)
const productIdEvents = transform(
{ updatedProductIds },
({ updatedProductIds }) => {
return updatedProductIds.map((id) => {
return { id }
})
}
)
emitEventStep({
eventName: ProductWorkflowEvents.UPDATED,
data: productIdEvents,
})
const productsUpdated = createHook("productsUpdated", {
products: updatedProducts,
additional_data: input.additional_data,

View File

@@ -1,4 +1,4 @@
export const OrderEvents = {
export const OrderWorkflowEvents = {
PLACED: "order.placed",
CANCELED: "order.canceled",
COMPLETED: "order.completed",

View File

@@ -21,3 +21,27 @@ export const ProductEvents = buildEventNamesFromEntityName(
eventBaseNames,
Modules.PRODUCT
)
export const ProductCategoryWorkflowEvents = {
CREATED: "product-category.created",
UPDATED: "product-category.updated",
DELETED: "product-category.deleted",
}
export const ProductCollectionWorkflowEvents = {
CREATED: "product-collection.created",
UPDATED: "product-collection.updated",
DELETED: "product-collection.deleted",
}
export const ProductVariantWorkflowEvents = {
UPDATED: "product-variant.updated",
CREATED: "product-variant.created",
DELETED: "product-variant.deleted",
}
export const ProductWorkflowEvents = {
UPDATED: "product.updated",
CREATED: "product.created",
DELETED: "product.deleted",
}