From c78915c7c5e91a99c1b1bae932656c8d86b17daf Mon Sep 17 00:00:00 2001 From: Adrien de Peretti Date: Thu, 11 Apr 2024 18:34:55 +0200 Subject: [PATCH] feat: Add support for shipping options prices update (#7028) --- .changeset/stale-spiders-applaud.md | 8 + .../promotion/admin/promotion-rules.spec.ts | 10 +- .../admin/shipping-options.spec.ts | 47 ++++- .../workflows/update-shipping-options.ts | 76 +++++-- .../core-flows/src/fulfillment/steps/index.ts | 1 + .../steps/set-shipping-options-prices.ts | 193 ++++++++++++++++++ .../workflows/create-shipping-options.ts | 3 +- .../workflows/update-shipping-options.ts | 44 ++-- .../admin/shipping-options/validators.ts | 22 ++ packages/medusa/src/utils/get-query-config.ts | 17 +- .../pricing/src/services/pricing-module.ts | 93 ++++++++- .../fulfillment/update-shipping-options.ts | 10 +- .../internal-module-service-factory.ts | 3 +- 13 files changed, 450 insertions(+), 77 deletions(-) create mode 100644 .changeset/stale-spiders-applaud.md create mode 100644 packages/core-flows/src/fulfillment/steps/set-shipping-options-prices.ts diff --git a/.changeset/stale-spiders-applaud.md b/.changeset/stale-spiders-applaud.md new file mode 100644 index 0000000000..d46953740a --- /dev/null +++ b/.changeset/stale-spiders-applaud.md @@ -0,0 +1,8 @@ +--- +"@medusajs/medusa": patch +"@medusajs/core-flows": patch +"@medusajs/pricing": patch +"@medusajs/types": patch +--- + +feat(): Add support for shipping options prices update diff --git a/integration-tests/modules/__tests__/promotion/admin/promotion-rules.spec.ts b/integration-tests/modules/__tests__/promotion/admin/promotion-rules.spec.ts index 6c0aab2bee..4dc8a88393 100644 --- a/integration-tests/modules/__tests__/promotion/admin/promotion-rules.spec.ts +++ b/integration-tests/modules/__tests__/promotion/admin/promotion-rules.spec.ts @@ -856,8 +856,14 @@ medusaIntegrationTestRunner({ expect(response.data.values.length).toEqual(2) expect(response.data.values).toEqual( expect.arrayContaining([ - { label: "Afghanistan", value: "af" }, - { label: "Albania", value: "al" }, + { + label: "Andorra", + value: "ad", + }, + { + label: "United Arab Emirates", + value: "ae", + }, ]) ) diff --git a/integration-tests/modules/__tests__/shipping-options/admin/shipping-options.spec.ts b/integration-tests/modules/__tests__/shipping-options/admin/shipping-options.spec.ts index 3e248186a7..dfdacdc4f0 100644 --- a/integration-tests/modules/__tests__/shipping-options/admin/shipping-options.spec.ts +++ b/integration-tests/modules/__tests__/shipping-options/admin/shipping-options.spec.ts @@ -264,7 +264,7 @@ medusaIntegrationTestRunner({ }) }) - it("should create a shipping option successfully", async () => { + it("should update a shipping option successfully", async () => { const shippingOptionPayload = { name: "Test shipping option", service_zone_id: fulfillmentSet.service_zones[0].id, @@ -295,15 +295,44 @@ medusaIntegrationTestRunner({ adminHeaders ) - expect(response.status).toEqual(200) - expect(response.data.shipping_option).toEqual( + const shippingOptionId = response.data.shipping_option.id + + const eurPrice = response.data.shipping_option.prices.find( + (p) => p.currency_code === "eur" + ) + const updateShippingOptionPayload = { + id: shippingOptionId, + name: "Updated shipping option", + provider_id: "manual_test-provider", + price_type: "flat", + prices: [ + { + currency_code: "dkk", + amount: 10, + }, + { + id: eurPrice.id, + amount: 10000, + }, + ], + } + + const updateResponse = await api.post( + `/admin/shipping-options/${shippingOptionId}`, + updateShippingOptionPayload, + adminHeaders + ) + + expect(updateResponse.status).toEqual(200) + expect(updateResponse.data.shipping_option.prices).toHaveLength(2) + expect(updateResponse.data.shipping_option).toEqual( expect.objectContaining({ id: expect.any(String), - name: shippingOptionPayload.name, + name: updateShippingOptionPayload.name, provider: expect.objectContaining({ id: shippingOptionPayload.provider_id, }), - price_type: shippingOptionPayload.price_type, + price_type: updateShippingOptionPayload.price_type, type: expect.objectContaining({ id: expect.any(String), label: shippingOptionPayload.type.label, @@ -315,13 +344,15 @@ medusaIntegrationTestRunner({ prices: expect.arrayContaining([ expect.objectContaining({ id: expect.any(String), - currency_code: "usd", - amount: 1000, + currency_code: "dkk", + rules_count: 0, + amount: 10, }), expect.objectContaining({ id: expect.any(String), currency_code: "eur", - amount: 1000, + rules_count: 1, + amount: 10000, }), ]), rules: expect.arrayContaining([ diff --git a/integration-tests/modules/__tests__/shipping-options/workflows/update-shipping-options.ts b/integration-tests/modules/__tests__/shipping-options/workflows/update-shipping-options.ts index a786771465..36768de3a6 100644 --- a/integration-tests/modules/__tests__/shipping-options/workflows/update-shipping-options.ts +++ b/integration-tests/modules/__tests__/shipping-options/workflows/update-shipping-options.ts @@ -97,6 +97,10 @@ medusaIntegrationTestRunner({ region_id: region.id, amount: 100, }, + { + currency_code: "dkk", + amount: 1000, + }, ], rules: [ { @@ -111,26 +115,11 @@ medusaIntegrationTestRunner({ input: [shippingOptionData], }) - const updateData: UpdateShippingOptionsWorkflowInput = { - id: result[0].id, - name: "Test shipping option", - price_type: "flat", - type: { - code: "manual-type", - label: "Manual Type", - description: "Manual Type Description", - }, - } - - await updateShippingOptionsWorkflow(container).run({ - input: [updateData], - }) - const remoteQuery = container.resolve( ContainerRegistrationKeys.REMOTE_QUERY ) - const remoteQueryObject = remoteQueryObjectFromString({ + let remoteQueryObject = remoteQueryObjectFromString({ entryPoint: "shipping_option", variables: { id: result[0].id, @@ -155,10 +144,50 @@ medusaIntegrationTestRunner({ const [createdShippingOption] = await remoteQuery(remoteQueryObject) - const prices = createdShippingOption.prices - delete createdShippingOption.prices + const usdPrice = createdShippingOption.prices.find((price) => { + return price.currency_code === "usd" + }) - expect(createdShippingOption).toEqual( + const dkkPrice = createdShippingOption.prices.find((price) => { + return price.currency_code === "dkk" + }) + + const updateData: UpdateShippingOptionsWorkflowInput = { + id: createdShippingOption.id, + name: "Test shipping option", + price_type: "flat", + type: { + code: "manual-type", + label: "Manual Type", + description: "Manual Type Description", + }, + prices: [ + // We keep the usd price as is + // update the dkk price to 100 + // delete the third price eur + // create a new eur one instead + usdPrice, + { + ...dkkPrice, + amount: 100, + }, + { + region_id: region.id, + amount: 1000, + }, + ], + } + + await updateShippingOptionsWorkflow(container).run({ + input: [updateData], + }) + + const [updatedShippingOption] = await remoteQuery(remoteQueryObject) + + const prices = updatedShippingOption.prices + delete updatedShippingOption.prices + + expect(updatedShippingOption).toEqual( expect.objectContaining({ id: result[0].id, name: updateData.name, @@ -178,7 +207,7 @@ medusaIntegrationTestRunner({ }) ) - expect(prices).toHaveLength(2) + expect(prices).toHaveLength(3) expect(prices).toContainEqual( expect.objectContaining({ currency_code: "usd", @@ -188,8 +217,13 @@ medusaIntegrationTestRunner({ expect(prices).toContainEqual( expect.objectContaining({ currency_code: "eur", + amount: 1000, + }) + ) + expect(prices).toContainEqual( + expect.objectContaining({ + currency_code: "dkk", amount: 100, - rules_count: 1, }) ) }) diff --git a/packages/core-flows/src/fulfillment/steps/index.ts b/packages/core-flows/src/fulfillment/steps/index.ts index 33b35f206d..f0698b8416 100644 --- a/packages/core-flows/src/fulfillment/steps/index.ts +++ b/packages/core-flows/src/fulfillment/steps/index.ts @@ -7,3 +7,4 @@ export * from "./delete-service-zones" export * from "./delete-shipping-options" export * from "./create-shipping-profiles" export * from "./remove-rules-from-fulfillment-shipping-option" +export * from "./set-shipping-options-prices" diff --git a/packages/core-flows/src/fulfillment/steps/set-shipping-options-prices.ts b/packages/core-flows/src/fulfillment/steps/set-shipping-options-prices.ts new file mode 100644 index 0000000000..8374c5993f --- /dev/null +++ b/packages/core-flows/src/fulfillment/steps/set-shipping-options-prices.ts @@ -0,0 +1,193 @@ +import { + CreatePriceDTO, + CreatePricesDTO, + FulfillmentWorkflow, + IPricingModuleService, + IRegionModuleService, + PriceDTO, + PriceSetDTO, + RemoteQueryFunction, +} from "@medusajs/types" +import { createStep, StepResponse } from "@medusajs/workflows-sdk" +import { + ContainerRegistrationKeys, + isDefined, + LINKS, + remoteQueryObjectFromString, +} from "@medusajs/utils" +import { ModuleRegistrationName } from "@medusajs/modules-sdk" + +interface PriceRegionId { + region_id: string + amount: number +} + +type SetShippingOptionsPricesStepInput = { + id: string + prices?: FulfillmentWorkflow.UpdateShippingOptionsWorkflowInput["prices"] +}[] + +async function getCurrentShippingOptionPrices( + shippingOptionIds: string[], + { remoteQuery }: { remoteQuery: RemoteQueryFunction } +): Promise< + { shipping_option_id: string; price_set_id: string; prices: PriceDTO[] }[] +> { + const query = remoteQueryObjectFromString({ + service: LINKS.ShippingOptionPriceSet, + variables: { + filters: { shipping_option_id: shippingOptionIds }, + take: null, + }, + fields: ["shipping_option_id", "price_set_id", "price_set.prices.*"], + }) + + const shippingOptionPrices = (await remoteQuery(query)) as { + shipping_option_id: string + price_set_id: string + price_set: PriceSetDTO + }[] + + return shippingOptionPrices.map((shippingOption) => { + const prices = shippingOption.price_set?.prices ?? [] + const price_set_id = shippingOption.price_set_id + return { + shipping_option_id: shippingOption.shipping_option_id, + price_set_id, + prices, + } + }) +} + +function buildPrices( + prices: SetShippingOptionsPricesStepInput[0]["prices"], + regionToCurrencyMap: Map +): CreatePriceDTO[] { + if (!prices) { + return [] + } + + const shippingOptionPrices = prices.map((price) => { + if ("region_id" in price) { + const currency_code = regionToCurrencyMap.get(price.region_id!)! + const regionId = price.region_id + delete price.region_id + return { + ...price, + currency_code: currency_code, + amount: price.amount, + rules: { + region_id: regionId, + }, + } + } + + return price + }) + + return shippingOptionPrices as CreatePriceDTO[] +} + +export const setShippingOptionsPricesStepId = "set-shipping-options-prices-step" +export const setShippingOptionsPricesStep = createStep( + setShippingOptionsPricesStepId, + async (data: SetShippingOptionsPricesStepInput, { container }) => { + if (!data.length) { + return + } + + const regionIds = data + .map((input) => input.prices) + .flat() + .filter((price): price is PriceRegionId => "region_id" in (price ?? {})) + .map((price) => price.region_id) + + let regionToCurrencyMap: Map = new Map() + + if (regionIds.length) { + const regionService = container.resolve( + ModuleRegistrationName.REGION + ) + const regions = await regionService.list( + { + id: [...new Set(regionIds)], + }, + { + select: ["id", "currency_code"], + } + ) + + regionToCurrencyMap = new Map( + regions.map((region) => [region.id, region.currency_code]) + ) + } + + const remoteQuery = container.resolve( + ContainerRegistrationKeys.REMOTE_QUERY + ) + + const currentShippingOptionPricesData = + await getCurrentShippingOptionPrices( + data.map((d) => d.id), + { remoteQuery } + ) + + const shippingOptionPricesMap = new Map( + currentShippingOptionPricesData.map((currentShippingOptionDataItem) => { + const shippingOptionData = data.find( + (d) => d.id === currentShippingOptionDataItem.shipping_option_id + )! + const pricesData = shippingOptionData?.prices?.map((priceData) => { + return { + ...priceData, + price_set_id: currentShippingOptionDataItem.price_set_id, + } + }) + const buildPricesData = + pricesData && buildPrices(pricesData, regionToCurrencyMap) + return [ + currentShippingOptionDataItem.shipping_option_id, + { + price_set_id: currentShippingOptionDataItem.price_set_id, + prices: buildPricesData, + }, + ] + }) + ) + + const pricingService = container.resolve( + ModuleRegistrationName.PRICING + ) + + for (const data_ of data) { + const shippingOptionData = shippingOptionPricesMap.get(data_.id)! + + if (!isDefined(shippingOptionData.prices)) { + continue + } + + await pricingService.update(shippingOptionData.price_set_id, { + prices: shippingOptionData.prices, + }) + } + + return new StepResponse(void 0, currentShippingOptionPricesData) + }, + async (rollbackData, { container }) => { + if (!rollbackData?.length) { + return + } + + const pricingService = container.resolve( + ModuleRegistrationName.PRICING + ) + + for (const data_ of rollbackData) { + const prices = data_.prices as CreatePricesDTO[] + if (!isDefined(prices)) { + continue + } + await pricingService.update(data_.price_set_id, { prices }) + } + } +) diff --git a/packages/core-flows/src/fulfillment/workflows/create-shipping-options.ts b/packages/core-flows/src/fulfillment/workflows/create-shipping-options.ts index ff5b3eacfa..2a7dd5c722 100644 --- a/packages/core-flows/src/fulfillment/workflows/create-shipping-options.ts +++ b/packages/core-flows/src/fulfillment/workflows/create-shipping-options.ts @@ -22,9 +22,10 @@ export const createShippingOptionsWorkflow = createWorkflow( ): WorkflowData => { const data = transform(input, (data) => { const shippingOptionsIndexToPrices = data.map((option, index) => { + const prices = option.prices return { shipping_option_index: index, - prices: option.prices, + prices, } }) diff --git a/packages/core-flows/src/fulfillment/workflows/update-shipping-options.ts b/packages/core-flows/src/fulfillment/workflows/update-shipping-options.ts index 32bd321cc6..25bb86c3fb 100644 --- a/packages/core-flows/src/fulfillment/workflows/update-shipping-options.ts +++ b/packages/core-flows/src/fulfillment/workflows/update-shipping-options.ts @@ -1,10 +1,18 @@ -import { FulfillmentWorkflow } from "@medusajs/types" +import { + CreateRuleTypeDTO, + FulfillmentWorkflow, + RuleTypeDTO, +} from "@medusajs/types" import { createWorkflow, transform, WorkflowData, } from "@medusajs/workflows-sdk" -import { upsertShippingOptionsStep } from "../steps" +import { + setShippingOptionsPricesStep, + upsertShippingOptionsStep, +} from "../steps" +import { createPricingRuleTypesStep } from "../../pricing" export const updateShippingOptionsWorkflowId = "update-shipping-options-workflow" @@ -17,9 +25,11 @@ export const updateShippingOptionsWorkflow = createWorkflow( ): WorkflowData => { const data = transform(input, (data) => { const shippingOptionsIndexToPrices = data.map((option, index) => { + const prices = option.prices + delete option.prices return { shipping_option_index: index, - prices: option.prices, + prices, } }) @@ -33,7 +43,7 @@ export const updateShippingOptionsWorkflow = createWorkflow( data.shippingOptions ) - /*const normalizedShippingOptionsPrices = transform( + const normalizedShippingOptionsPrices = transform( { shippingOptions: updatedShippingOptions, shippingOptionsIndexToPrices: data.shippingOptionsIndexToPrices, @@ -60,32 +70,16 @@ export const updateShippingOptionsWorkflow = createWorkflow( return { shippingOptionsPrices, - ruleTypes: Array.from(ruleTypes) as UpdateRuleTypeDTO[], + ruleTypes: Array.from(ruleTypes) as CreateRuleTypeDTO[], } } - )*/ - - /*updatePricingRuleTypesStep(normalizedShippingOptionsPrices.ruleTypes)*/ - - /*const shippingOptionsPriceSetsLinkData = updateShippingOptionsPriceSetsStep( - normalizedShippingOptionsPrices.shippingOptionsPrices ) - const normalizedLinkData = transform( - { - shippingOptionsPriceSetsLinkData, - }, - (data) => { - return data.shippingOptionsPriceSetsLinkData.map((item) => { - return { - id: item.id, - price_sets: [item.priceSetId], - } - }) - } - )*/ + createPricingRuleTypesStep(normalizedShippingOptionsPrices.ruleTypes) - /*setShippingOptionsPriceSetsStep(normalizedLinkData)*/ + setShippingOptionsPricesStep( + normalizedShippingOptionsPrices.shippingOptionsPrices + ) return updatedShippingOptions } diff --git a/packages/medusa/src/api-v2/admin/shipping-options/validators.ts b/packages/medusa/src/api-v2/admin/shipping-options/validators.ts index da95a5c5f2..8cd120f805 100644 --- a/packages/medusa/src/api-v2/admin/shipping-options/validators.ts +++ b/packages/medusa/src/api-v2/admin/shipping-options/validators.ts @@ -70,6 +70,23 @@ export const AdminCreateShippingOptionPriceWithRegion = z }) .strict() +export const AdminUpdateShippingOptionPriceWithCurrency =z + .object({ + id: z.string().optional(), + currency_code: z.string().optional(), + amount: z.number().optional(), + }) + .strict() + +export const AdminUpdateShippingOptionPriceWithRegion = + z + .object({ + id: z.string().optional(), + region_id: z.string().optional(), + amount: z.number().optional(), + }) + .strict() + export const AdminCreateShippingOption = z .object({ name: z.string(), @@ -98,6 +115,11 @@ export const AdminUpdateShippingOption = z price_type: z.nativeEnum(ShippingOptionPriceTypeEnum).optional(), provider_id: z.string().optional(), type: AdminCreateShippingOptionTypeObject.optional(), + prices: AdminUpdateShippingOptionPriceWithCurrency.or( + AdminUpdateShippingOptionPriceWithRegion + ) + .array() + .optional(), }) .strict() diff --git a/packages/medusa/src/utils/get-query-config.ts b/packages/medusa/src/utils/get-query-config.ts index 94f6a2458b..283d8eaecb 100644 --- a/packages/medusa/src/utils/get-query-config.ts +++ b/packages/medusa/src/utils/get-query-config.ts @@ -1,8 +1,14 @@ -import { getSetDifference, stringToSelectRelationObject } from "@medusajs/utils" +import { + getSetDifference, + isPresent, + stringToSelectRelationObject, +} from "@medusajs/utils" import { pick } from "lodash" -import { MedusaError, isDefined } from "medusa-core-utils" +import { isDefined, MedusaError } from "medusa-core-utils" import { BaseEntity } from "../interfaces" import { FindConfig, QueryConfig, RequestQueryFields } from "../types/common" +import { featureFlagRouter } from "../loaders/feature-flags" +import MedusaV2 from "../loaders/feature-flags/medusa-v2" export function pickByConfig( obj: TModel | TModel[], @@ -24,7 +30,7 @@ export function prepareListQuery< T extends RequestQueryFields, TEntity extends BaseEntity >(validated: T, queryConfig: QueryConfig = {}) { - const isMedusaV2 = process.env.MEDUSA_FF_MEDUSA_V2 == "true" + const isMedusaV2 = featureFlagRouter.isFeatureEnabled(MedusaV2.key) // TODO: this function will be simplified a lot once we drop support for the old api const { order, fields, limit = 50, expand, offset = 0 } = validated @@ -189,13 +195,14 @@ export function prepareListQuery< } } + const finalOrder = isPresent(orderBy) ? orderBy : undefined return { listConfig: { select: select.length ? select : undefined, relations: Array.from(allRelations), skip: offset, take: limit ?? defaultLimit, - order: orderBy, + order: finalOrder, }, remoteQueryConfig: { // Add starFields that are relations only on which we want all properties with a dedicated format to the remote query @@ -207,7 +214,7 @@ export function prepareListQuery< ? { skip: offset, take: limit ?? defaultLimit, - order: orderBy, + order: finalOrder, } : {}, }, diff --git a/packages/pricing/src/services/pricing-module.ts b/packages/pricing/src/services/pricing-module.ts index aa0dbd451d..75a7cf7c95 100644 --- a/packages/pricing/src/services/pricing-module.ts +++ b/packages/pricing/src/services/pricing-module.ts @@ -2,8 +2,8 @@ import { AddPricesDTO, Context, CreatePriceListRuleDTO, - CreatePriceSetDTO, CreatePricesDTO, + CreatePriceSetDTO, DAL, InternalModuleDeclaration, ModuleJoinerConfig, @@ -23,7 +23,7 @@ import { groupBy, InjectManager, InjectTransactionManager, - isDefined, + isDefined, isPresent, isString, MedusaContext, MedusaError, @@ -44,12 +44,12 @@ import { RuleType, } from "@models" -import { PriceListService, RuleTypeService } from "@services" -import { validatePriceListDates } from "@utils" -import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config" -import { PriceSetIdPrefix } from "../models/price-set" -import { PriceListIdPrefix } from "../models/price-list" -import { UpdatePriceSetInput } from "src/types/services" +import {PriceListService, RuleTypeService} from "@services" +import {validatePriceListDates} from "@utils" +import {entityNameToLinkableKeysMap, joinerConfig} from "../joiner-config" +import {PriceSetIdPrefix} from "../models/price-set" +import {PriceListIdPrefix} from "../models/price-list" +import {UpdatePriceSetInput} from "src/types/services" type InjectedDependencies = { baseRepository: DAL.RepositoryService @@ -336,6 +336,54 @@ export default class PricingModuleService< return isString(idOrSelector) ? priceSets[0] : priceSets } + private async normalizeUpdateData( + data: UpdatePriceSetInput[], + sharedContext + ) { + const ruleAttributes = data + .map((d) => d.prices?.map((p) => Object.keys(p.rules ?? [])) ?? []) + .flat(Infinity) + .filter(Boolean) + + const ruleTypes = await this.ruleTypeService_.list( + { rule_attribute: ruleAttributes }, + { take: null }, + sharedContext + ) + + const ruleTypeMap = ruleTypes.reduce((acc, curr) => { + acc.set(curr.rule_attribute, curr) + return acc + }, new Map()) + + return data.map((priceSet) => { + const prices = priceSet.prices?.map((price) => { + const rules = Object.entries(price.rules ?? {}).map( + ([attribute, value]) => { + return { + price_set_id: priceSet.id, + rule_type_id: ruleTypeMap.get(attribute)!.id, + value, + } + } + ) + const hasRulesInput = isPresent(price.rules) + delete price.rules + return { + ...price, + price_set_id: priceSet.id, + price_rules: hasRulesInput ? rules : undefined, + rules_count: hasRulesInput ? rules.length : undefined + } + }) + + return { + ...priceSet, + prices, + } + }) + } + @InjectTransactionManager("baseRepository_") protected async update_( data: UpdatePriceSetInput[], @@ -344,8 +392,33 @@ export default class PricingModuleService< // TODO: We are not handling rule types, rules, etc. here, add support after data models are finalized // TODO: Since money IDs are rarely passed, this will delete all previous data and insert new entries. // We can make the `insert` inside upsertWithReplace do an `upsert` instead to avoid this - return this.priceSetService_.upsertWithReplace( - data, + const normalizedData = await this.normalizeUpdateData(data, sharedContext) + + const prices = normalizedData.flatMap((priceSet) => priceSet.prices || []) + const upsertedPrices = await this.priceService_.upsertWithReplace( + prices, + { + relations: ["price_rules"], + }, + sharedContext + ) + + const priceSetsToUpsert = normalizedData.map((priceSet) => { + const { prices, ...rest } = priceSet + return { + ...rest, + prices: upsertedPrices + .filter((p) => p.price_set_id === priceSet.id) + .map((price) => { + // @ts-ignore + delete price.price_rules + return price + }), + } + }) + + return await this.priceSetService_.upsertWithReplace( + priceSetsToUpsert, { relations: ["prices"] }, sharedContext ) diff --git a/packages/types/src/workflow/fulfillment/update-shipping-options.ts b/packages/types/src/workflow/fulfillment/update-shipping-options.ts index 184fc43cf9..6718ced15b 100644 --- a/packages/types/src/workflow/fulfillment/update-shipping-options.ts +++ b/packages/types/src/workflow/fulfillment/update-shipping-options.ts @@ -16,12 +16,14 @@ export interface UpdateShippingOptionsWorkflowInput { } prices?: ( | { - currency_code: string - amount: number + id?: string + currency_code?: string + amount?: number } | { - region_id: string - amount: number + id?: string + region_id?: string + amount?: number } )[] rules?: { diff --git a/packages/utils/src/modules-sdk/internal-module-service-factory.ts b/packages/utils/src/modules-sdk/internal-module-service-factory.ts index 4d8a4dbc94..7fbce62391 100644 --- a/packages/utils/src/modules-sdk/internal-module-service-factory.ts +++ b/packages/utils/src/modules-sdk/internal-module-service-factory.ts @@ -13,6 +13,7 @@ import { doNotForceTransaction, isDefined, isObject, + isPresent, isString, lowerCaseFirst, MedusaError, @@ -85,7 +86,7 @@ export function internalModuleServiceFactory< * @param config */ static applyDefaultOrdering(config: FindConfig) { - if (config.order) { + if (isPresent(config.order)) { return }