From c726ed54f5a1c4f22199f095a679e746358257e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frane=20Poli=C4=87?= <16856471+fPolic@users.noreply.github.com> Date: Tue, 1 Oct 2024 10:37:56 +0200 Subject: [PATCH] fix(pricing): price set update deletes price list prices (#9308) **Why** - price set update uses `upsertWithReplace` so price list prices are removed since we "ignore" them in regular price set operations and use price list methods to manage them **What** - preserve price list prices when updating price sets --- FIXES CC-516 --- .../services/pricing-module/price-set.spec.ts | 87 +++++++++++++++++++ .../pricing/src/services/pricing-module.ts | 37 ++++++-- 2 files changed, 116 insertions(+), 8 deletions(-) diff --git a/packages/modules/pricing/integration-tests/__tests__/services/pricing-module/price-set.spec.ts b/packages/modules/pricing/integration-tests/__tests__/services/pricing-module/price-set.spec.ts index a28a95af78..505e34dd88 100644 --- a/packages/modules/pricing/integration-tests/__tests__/services/pricing-module/price-set.spec.ts +++ b/packages/modules/pricing/integration-tests/__tests__/services/pricing-module/price-set.spec.ts @@ -402,6 +402,93 @@ moduleIntegrationTestRunner({ ) }) + it("should update price set prices and preserve price list prices", async () => { + const priceSetBefore = await service.retrievePriceSet(id, { + relations: ["prices"], + }) + + const [pl] = await service.createPriceLists([ + { + title: "test", + description: "test", + + prices: [ + { + amount: 400, + currency_code: "EUR", + price_set_id: priceSetBefore.id, + }, + ], + }, + ]) + + const updateResponse = await service.updatePriceSets( + priceSetBefore.id, + { + prices: [ + { amount: 100, currency_code: "USD" }, + { amount: 200, currency_code: "EUR" }, + ], + } + ) + + const priceSetAfter = await service.retrievePriceSet(id, { + relations: ["prices"], + }) + + expect(priceSetBefore.prices).toHaveLength(1) + expect(priceSetBefore.prices?.[0]).toEqual( + expect.objectContaining({ + amount: 500, + currency_code: "USD", + }) + ) + + // Price list prices are not present in this response + expect(priceSetAfter.prices).toHaveLength(2) + expect(priceSetAfter.prices).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + amount: 100, + currency_code: "USD", + }), + expect.objectContaining({ + amount: 200, + currency_code: "EUR", + }), + ]) + ) + expect(updateResponse.prices).toHaveLength(2) + expect(updateResponse.prices).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + amount: 100, + currency_code: "USD", + }), + expect.objectContaining({ + amount: 200, + currency_code: "EUR", + }), + ]) + ) + + const plAfter = await service.retrievePriceList(pl.id, { + relations: ["prices"], + }) + + // Price list prices are preserved + expect(plAfter.prices).toHaveLength(1) + expect(plAfter.prices).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + amount: 400, + currency_code: "EUR", + price_set_id: priceSetBefore.id, + }), + ]) + ) + }) + it("should upsert the later price when setting a price set with existing equivalent rules", async () => { await service.updatePriceSets(id, { prices: [ diff --git a/packages/modules/pricing/src/services/pricing-module.ts b/packages/modules/pricing/src/services/pricing-module.ts index c6d9d0d457..0d02c2defa 100644 --- a/packages/modules/pricing/src/services/pricing-module.ts +++ b/packages/modules/pricing/src/services/pricing-module.ts @@ -515,6 +515,11 @@ export default class PricingModuleService // We can make the `insert` inside upsertWithReplace do an `upsert` instead to avoid this const normalizedData = await this.normalizeUpdateData(data) + const priceListPrices = await this.priceService_.list({ + price_set_id: normalizedData.map(({ id }) => id), + price_list_id: { $ne: null }, + }) + const prices = normalizedData.flatMap((priceSet) => priceSet.prices || []) const { entities: upsertedPrices } = await this.priceService_.upsertWithReplace( @@ -527,13 +532,23 @@ export default class PricingModuleService 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 - }), + prices: [ + ...upsertedPrices + .filter((p) => p.price_set_id === priceSet.id) + .map((price) => { + // @ts-ignore + delete price.price_rules + return price + }), + ...priceListPrices + .filter((p) => p.price_set_id === priceSet.id) + .map((price) => ({ + id: price.id, + amount: price.amount, + price_set_id: price.price_set_id, + price_list_id: price.price_list_id, + })), + ], } }) @@ -544,7 +559,13 @@ export default class PricingModuleService sharedContext ) - return priceSets + return priceSets.map((ps) => { + if (ps.prices) { + ps.prices = (ps.prices as any).filter((p) => !p.price_list_id) + } + + return ps + }) } private async normalizeUpdateData(data: ServiceTypes.UpdatePriceSetInput[]) {