fix: Added more tests and fixed a couple of issues with product import (#8341)
This commit is contained in:
@@ -1 +1,2 @@
|
||||
export * from "./send-notifications"
|
||||
export * from "./notify-on-failure"
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { INotificationModuleService } from "@medusajs/types"
|
||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
type NotifyOnFailureStepInput = {
|
||||
to: string
|
||||
channel: string
|
||||
template: string
|
||||
data?: Record<string, unknown> | null
|
||||
trigger_type?: string | null
|
||||
resource_id?: string | null
|
||||
resource_type?: string | null
|
||||
receiver_id?: string | null
|
||||
original_notification_id?: string | null
|
||||
idempotency_key?: string | null
|
||||
}[]
|
||||
|
||||
export const notifyOnFailureStepId = "notify-on-failure"
|
||||
export const notifyOnFailureStep = createStep(
|
||||
notifyOnFailureStepId,
|
||||
async (data: NotifyOnFailureStepInput) => {
|
||||
return new StepResponse(void 0, data)
|
||||
},
|
||||
|
||||
async (data, { container }) => {
|
||||
if (!data) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<INotificationModuleService>(
|
||||
ModuleRegistrationName.NOTIFICATION
|
||||
)
|
||||
await service.createNotifications(data)
|
||||
}
|
||||
)
|
||||
@@ -1,9 +1,10 @@
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
import { HttpTypes, RegionTypes } from "@medusajs/types"
|
||||
import { MedusaError, lowerCaseFirst } from "@medusajs/utils"
|
||||
|
||||
// We want to convert the csv data format to a standard DTO format.
|
||||
export const normalizeForImport = (
|
||||
rawProducts: object[]
|
||||
rawProducts: object[],
|
||||
regions: RegionTypes.RegionDTO[]
|
||||
): HttpTypes.AdminCreateProduct[] => {
|
||||
const productMap = new Map<
|
||||
string,
|
||||
@@ -12,13 +13,14 @@ export const normalizeForImport = (
|
||||
variants: HttpTypes.AdminCreateProductVariant[]
|
||||
}
|
||||
>()
|
||||
const regionsMap = new Map(regions.map((r) => [r.id, r]))
|
||||
|
||||
rawProducts.forEach((rawProduct) => {
|
||||
const productInMap = productMap.get(rawProduct["Product Handle"])
|
||||
if (!productInMap) {
|
||||
productMap.set(rawProduct["Product Handle"], {
|
||||
product: normalizeProductForImport(rawProduct),
|
||||
variants: [normalizeVariantForImport(rawProduct)],
|
||||
variants: [normalizeVariantForImport(rawProduct, regionsMap)],
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -27,7 +29,7 @@ export const normalizeForImport = (
|
||||
product: productInMap.product,
|
||||
variants: [
|
||||
...productInMap.variants,
|
||||
normalizeVariantForImport(rawProduct),
|
||||
normalizeVariantForImport(rawProduct, regionsMap),
|
||||
],
|
||||
})
|
||||
})
|
||||
@@ -125,7 +127,8 @@ const normalizeProductForImport = (
|
||||
}
|
||||
|
||||
const normalizeVariantForImport = (
|
||||
rawProduct: object
|
||||
rawProduct: object,
|
||||
regionsMap: Map<string, RegionTypes.RegionDTO>
|
||||
): HttpTypes.AdminCreateProductVariant => {
|
||||
const response = {}
|
||||
const options = new Map<number, { name?: string; value?: string }>()
|
||||
@@ -148,10 +151,19 @@ const normalizeVariantForImport = (
|
||||
{ currency_code: priceKey.toLowerCase(), amount: normalizedValue },
|
||||
]
|
||||
} else {
|
||||
const region = regionsMap.get(priceKey)
|
||||
if (!region) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Region with ID ${priceKey} not found`
|
||||
)
|
||||
}
|
||||
|
||||
response["prices"] = [
|
||||
...(response["prices"] || []),
|
||||
{
|
||||
amount: normalizedValue,
|
||||
currency_code: region.currency_code,
|
||||
rules: { region_id: priceKey },
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
import { MedusaError, convertCsvToJson } from "@medusajs/utils"
|
||||
import {
|
||||
MedusaError,
|
||||
ModuleRegistrationName,
|
||||
convertCsvToJson,
|
||||
} from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { normalizeForImport } from "../helpers/normalize-for-import"
|
||||
import { IRegionModuleService } from "@medusajs/types"
|
||||
|
||||
export const parseProductCsvStepId = "parse-product-csv"
|
||||
export const parseProductCsvStep = createStep(
|
||||
parseProductCsvStepId,
|
||||
async (fileContent: string) => {
|
||||
async (fileContent: string, { container }) => {
|
||||
const regionService = container.resolve<IRegionModuleService>(
|
||||
ModuleRegistrationName.REGION
|
||||
)
|
||||
const csvProducts = convertCsvToJson(fileContent)
|
||||
|
||||
csvProducts.forEach((product: any) => {
|
||||
@@ -17,7 +25,12 @@ export const parseProductCsvStep = createStep(
|
||||
}
|
||||
})
|
||||
|
||||
const normalizedData = normalizeForImport(csvProducts)
|
||||
const allRegions = await regionService.listRegions(
|
||||
{},
|
||||
{ select: ["id", "currency_code"], take: null }
|
||||
)
|
||||
|
||||
const normalizedData = normalizeForImport(csvProducts, allRegions)
|
||||
return new StepResponse(normalizedData)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
transform,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { WorkflowTypes } from "@medusajs/types"
|
||||
import { sendNotificationsStep } from "../../notification"
|
||||
import { notifyOnFailureStep, sendNotificationsStep } from "../../notification"
|
||||
import {
|
||||
waitConfirmationProductImportStep,
|
||||
groupProductsForBatchStep,
|
||||
@@ -30,6 +30,23 @@ export const importProductsWorkflow = createWorkflow(
|
||||
|
||||
waitConfirmationProductImportStep()
|
||||
|
||||
// Q: Can we somehow access the error from the step that threw here? Or in a compensate step at least?
|
||||
const failureNotification = transform({ input }, (data) => {
|
||||
return [
|
||||
{
|
||||
// We don't need the recipient here for now, but if we want to push feed notifications to a specific user we could add it.
|
||||
to: "",
|
||||
channel: "feed",
|
||||
template: "admin-ui",
|
||||
data: {
|
||||
title: "Product import",
|
||||
description: `Failed to import products from file ${data.input.filename}`,
|
||||
},
|
||||
},
|
||||
]
|
||||
})
|
||||
notifyOnFailureStep(failureNotification)
|
||||
|
||||
batchProductsWorkflow.runAsStep({ input: batchRequest })
|
||||
|
||||
const notifications = transform({ input }, (data) => {
|
||||
@@ -46,8 +63,8 @@ export const importProductsWorkflow = createWorkflow(
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
sendNotificationsStep(notifications)
|
||||
|
||||
return summary
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user