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
This commit is contained in:
Frane Polić
2024-10-01 08:37:56 +00:00
committed by GitHub
parent 0e35e312e5
commit c726ed54f5
2 changed files with 116 additions and 8 deletions
@@ -402,6 +402,93 @@ moduleIntegrationTestRunner<IPricingModuleService>({
)
})
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: [
@@ -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[]) {