fix: Added more tests and fixed a couple of issues with product import (#8341)

This commit is contained in:
Stevche Radevski
2024-07-30 22:14:33 +02:00
committed by GitHub
parent 2967221e73
commit 9de1d8c9c3
9 changed files with 211 additions and 12 deletions
@@ -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
}
)