fix(medusa): Update cart sales channel should not remove all line items (#5980)

This commit is contained in:
Adrien de Peretti authored and GitHub committed 2024-01-03 14:06:07 +01:00
1 parent 42cc8ae3f8
commit 278b7fb203
6 files changed
+140 -76

No files matched your search

@@ -744,9 +744,9 @@ describe("CartService", () => {
)
expect(lineItemService.delete).toHaveBeenCalledTimes(1)
expect(lineItemService.delete).toHaveBeenCalledWith(
IdMap.getId("itemToRemove")
)
expect(lineItemService.delete).toHaveBeenCalledWith([
IdMap.getId("itemToRemove"),
])
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({
@@ -267,21 +267,23 @@ const unknownVariantId = "unknown-variant"
})
describe("delete", () => {
const lineItemRepository = MockRepository({
findOne: () =>
Promise.resolve({
id: IdMap.getId("test-line-item"),
variant_id: IdMap.getId("test-variant"),
variant: {
id: IdMap.getId("test-variant"),
title: "Test variant",
find: () =>
Promise.resolve([
{
id: IdMap.getId("test-line-item"),
variant_id: IdMap.getId("test-variant"),
variant: {
id: IdMap.getId("test-variant"),
title: "Test variant",
},
cart_id: IdMap.getId("test-cart"),
title: "Test product",
description: "Test variant",
thumbnail: "",
unit_price: 50,
quantity: 1,
},
cart_id: IdMap.getId("test-cart"),
title: "Test product",
description: "Test variant",
thumbnail: "",
unit_price: 50,
quantity: 1,
}),
]),
})
const lineItemService = new LineItemService({
@@ -297,20 +299,22 @@ const unknownVariantId = "unknown-variant"
await lineItemService.delete(IdMap.getId("test-line-item"))
expect(lineItemRepository.remove).toHaveBeenCalledTimes(1)
expect(lineItemRepository.remove).toHaveBeenCalledWith({
id: IdMap.getId("test-line-item"),
variant_id: IdMap.getId("test-variant"),
variant: {
id: IdMap.getId("test-variant"),
title: "Test variant",
expect(lineItemRepository.remove).toHaveBeenCalledWith([
{
id: IdMap.getId("test-line-item"),
variant_id: IdMap.getId("test-variant"),
variant: {
id: IdMap.getId("test-variant"),
title: "Test variant",
},
cart_id: IdMap.getId("test-cart"),
title: "Test product",
description: "Test variant",
thumbnail: "",
unit_price: 50,
quantity: 1,
},
cart_id: IdMap.getId("test-cart"),
title: "Test product",
description: "Test variant",
thumbnail: "",
unit_price: 50,
quantity: 1,
})
])
})
})
})
+23 -21
View File
@@ -560,23 +560,29 @@ class CartService extends TransactionBaseService {
/**
* Removes a line item from the cart.
* @param cartId - the id of the cart that we will remove from
* @param lineItemId - the line item to remove.
* @param lineItemId - the line item(s) to remove.
* @return the result of the update operation
*/
async removeLineItem(cartId: string, lineItemId: string): Promise<Cart> {
async removeLineItem(
cartId: string,
lineItemId: string | string[]
): Promise<void> {
return await this.atomicPhase_(
async (transactionManager: EntityManager) => {
const cart = await this.retrieve(cartId, {
relations: [
"items.variant.product.profiles",
"payment_sessions",
"shipping_methods",
],
relations: ["items.variant.product.profiles", "shipping_methods"],
})
const lineItem = cart.items.find((item) => item.id === lineItemId)
if (!lineItem) {
return cart
const lineItemIdsToRemove = new Set(
Array.isArray(lineItemId) ? lineItemId : [lineItemId]
)
const lineItems = cart.items.filter((item) =>
lineItemIdsToRemove.has(item.id)
)
if (!lineItems.length) {
return
}
if (cart.shipping_methods?.length) {
@@ -599,12 +605,11 @@ class CartService extends TransactionBaseService {
await this.lineItemService_
.withTransaction(transactionManager)
.delete(lineItem.id)
.delete([...lineItemIdsToRemove])
const result = await this.retrieve(cartId, {
relations: [
"items.variant.product.profiles",
"discounts",
"discounts.rule",
"region",
],
@@ -618,8 +623,6 @@ class CartService extends TransactionBaseService {
.emit(CartService.Events.UPDATED, {
id: cart.id,
})
return this.retrieve(cartId)
}
)
}
@@ -1423,14 +1426,13 @@ class CartService extends TransactionBaseService {
return !productIdsToKeep.has(item.variant.product_id)
})
if (itemsToRemove.length) {
const results = await promiseAll(
itemsToRemove.map(async (item) => {
return this.removeLineItem(cart.id, item.id)
})
)
cart.items = results.pop()?.items ?? []
if (!itemsToRemove.length) {
return
}
const itemIdsToRemove = new Set(itemsToRemove.map((item) => item.id))
await this.removeLineItem(cart.id, [...itemIdsToRemove])
cart.items = cart.items.filter((item) => !itemIdsToRemove.has(item.id))
}
/**
+30 -21
View File
@@ -1,28 +1,27 @@
import {MedusaError} from "medusa-core-utils"
import {EntityManager, In} from "typeorm"
import {DeepPartial} from "typeorm/common/DeepPartial"
import { MedusaError } from "medusa-core-utils"
import { EntityManager, In } from "typeorm"
import { DeepPartial } from "typeorm/common/DeepPartial"
import {
FlagRouter,
MedusaV2Flag,
selectorConstraintsToString
selectorConstraintsToString,
} from "@medusajs/utils"
import {TransactionBaseService} from "../interfaces"
import TaxInclusivePricingFeatureFlag
from "../loaders/feature-flags/tax-inclusive-pricing"
import { TransactionBaseService } from "../interfaces"
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
import {
LineItem,
LineItemAdjustment,
LineItemTaxLine,
ProductVariant,
} from "../models"
import {CartRepository} from "../repositories/cart"
import {LineItemRepository} from "../repositories/line-item"
import {LineItemTaxLineRepository} from "../repositories/line-item-tax-line"
import {FindConfig, Selector} from "../types/common"
import {GenerateInputData, GenerateLineItemContext} from "../types/line-item"
import {ProductVariantPricing} from "../types/pricing"
import {buildQuery, isString, setMetadata} from "../utils"
import { CartRepository } from "../repositories/cart"
import { LineItemRepository } from "../repositories/line-item"
import { LineItemTaxLineRepository } from "../repositories/line-item-tax-line"
import { FindConfig, Selector } from "../types/common"
import { GenerateInputData, GenerateLineItemContext } from "../types/line-item"
import { ProductVariantPricing } from "../types/pricing"
import { buildQuery, isString, setMetadata } from "../utils"
import {
PricingService,
ProductService,
@@ -484,23 +483,33 @@ class LineItemService extends TransactionBaseService {
)
}
async delete(ids: string[]): Promise<LineItem[]>
async delete(id: string): Promise<LineItem | void>
/**
* Deletes a line item.
* @param id - the id of the line item to delete
* @return the result of the delete operation
*/
async delete(id: string): Promise<LineItem | undefined | null> {
async delete(id: string | string[]): Promise<LineItem[] | LineItem | void> {
const ids = Array.isArray(id) ? id : [id]
return await this.atomicPhase_(
async (transactionManager: EntityManager) => {
const lineItemRepository = transactionManager.withRepository(
this.lineItemRepository_
)
return await lineItemRepository
.findOne({ where: { id } })
.then(
async (lineItem) => lineItem && lineItemRepository.remove(lineItem)
)
const lineItems = await lineItemRepository.find({
where: { id: In(ids) },
})
if (!lineItems?.length) {
return Array.isArray(id) ? [] : void 0
}
const removedItems = await lineItemRepository.remove(lineItems)
return Array.isArray(id) ? removedItems : removedItems[0]
}
)
}
@@ -511,7 +520,7 @@ class LineItemService extends TransactionBaseService {
* @param id - the id of the line item to delete
* @return the result of the delete operation
*/
async deleteWithTaxLines(id: string): Promise<LineItem | undefined | null> {
async deleteWithTaxLines(id: string): Promise<LineItem | void> {
return await this.atomicPhase_(
async (transactionManager: EntityManager) => {
await this.taxProviderService_