Feat(medusa): remove item from order (#2273)

* wait for update to order edit model

* delete line item tests

* create remove method for lineitem with tax lines

* add remove item tests

* split delete allocation tests into two: more and less than total

* remove unused import

* cleanup

* add medusa-js and react endpoints

* pr feedback fixes

* linting

* remove unused relation from query

* remove removed-event and unused imports

* add await
This commit is contained in:
Philip Korsholm
2022-09-30 09:48:18 +02:00
committed by GitHub
parent 95c0dc653a
commit 00959f79bc
15 changed files with 811 additions and 11 deletions

View File

@@ -1419,7 +1419,8 @@ describe("[MEDUSA_FF_ORDER_EDITING] /admin/order-edits", () => {
})
describe("POST /admin/order-edits/:id/confirm", () => {
let product, product2
let product
let product2
const prodId1 = IdMap.getId("product-1")
const prodId2 = IdMap.getId("product-2")
const lineItemId1 = IdMap.getId("line-item-1")
@@ -1623,7 +1624,8 @@ describe("[MEDUSA_FF_ORDER_EDITING] /admin/order-edits", () => {
})
describe("POST /admin/order-edits/:id/items/:item_id", () => {
let product, product2
let product
let product2
const orderId = IdMap.getId("order-1")
const prodId1 = IdMap.getId("product-1")
const prodId2 = IdMap.getId("product-2")
@@ -2332,4 +2334,511 @@ describe("[MEDUSA_FF_ORDER_EDITING] /admin/order-edits", () => {
)
})
})
describe("DELETE /admin/order-edits/:id/items/:item_id", () => {
let product
let product2
let discountCode
let discountCodeLarge
let cart
const orderId = IdMap.getId("order-1")
const discountOrderId = IdMap.getId("order-2")
const prodId1 = IdMap.getId("product-1")
const prodId2 = IdMap.getId("product-2")
const lineItemId1 = IdMap.getId("line-item-1")
const lineItemId2 = IdMap.getId("line-item-2")
const lineItemId1Discount = IdMap.getId("line-item-1-discount")
const lineItemId2Discount = IdMap.getId("line-item-2-discount")
beforeEach(async () => {
const api = useApi()
await adminSeeder(dbConnection)
product = await simpleProductFactory(dbConnection, {
id: prodId1,
})
product2 = await simpleProductFactory(dbConnection, {
id: prodId2,
})
const reagion = await simpleRegionFactory(dbConnection, {
id: "test-region",
name: "Test region",
tax_rate: 12.5,
})
await simpleOrderFactory(dbConnection, {
id: orderId,
email: "test-2@testson.com",
tax_rate: null,
fulfillment_status: "fulfilled",
payment_status: "captured",
region_id: "test-region",
line_items: [
{
id: lineItemId1,
variant_id: product.variants[0].id,
quantity: 1,
fulfilled_quantity: 1,
shipped_quantity: 1,
unit_price: 1000,
tax_lines: [
{
item_id: lineItemId1,
rate: 12.5,
code: "default",
name: "default",
},
],
},
{
id: lineItemId2,
variant_id: product2.variants[0].id,
quantity: 1,
fulfilled_quantity: 1,
shipped_quantity: 1,
unit_price: 1000,
tax_lines: [
{
item_id: lineItemId2,
rate: 12.5,
code: "default",
name: "default",
},
],
},
],
})
discountCode = "FIX_DISCOUNT_SMALL"
const discount = await simpleDiscountFactory(dbConnection, {
code: discountCode,
rule: {
type: "fixed",
allocation: "total",
value: 500,
},
regions: ["test-region"],
})
discountCodeLarge = "FIX_DISCOUNT_LARGE"
const discountLarge = await simpleDiscountFactory(dbConnection, {
code: discountCodeLarge,
rule: {
type: "fixed",
allocation: "total",
value: 1200,
},
regions: ["test-region"],
})
cart = await simpleCartFactory(dbConnection, {
email: "adrien@test.com",
region: "test-region",
line_items: [
{
id: lineItemId1Discount,
variant_id: product.variants[0].id,
quantity: 1,
unit_price: 1000,
},
{
id: lineItemId2Discount,
variant_id: product2.variants[0].id,
quantity: 1,
unit_price: 1000,
},
],
})
})
afterEach(async () => {
const db = useDb()
return await db.teardown()
})
it("creates an order edit item change of type delete on line item delete", async () => {
const api = useApi()
const {
data: { order_edit },
} = await api
.post(
`/admin/order-edits/`,
{
order_id: orderId,
},
adminHeaders
)
.catch(console.log)
const orderEditId = order_edit.id
const editLineItemId = order_edit.items.find(
(it) => it.original_item_id === lineItemId1
).id
const response = await api
.delete(
`/admin/order-edits/${orderEditId}/items/${editLineItemId}`,
adminHeaders
)
.catch(console.log)
expect(response.status).toEqual(200)
expect(response.data.order_edit.changes).toHaveLength(1)
expect(response.data.order_edit).toEqual(
expect.objectContaining({
id: orderEditId,
changes: expect.arrayContaining([
expect.objectContaining({
id: expect.any(String),
created_at: expect.any(String),
updated_at: expect.any(String),
deleted_at: null,
type: "item_remove",
order_edit_id: orderEditId,
original_line_item_id: lineItemId1,
line_item_id: null,
line_item: null,
original_line_item: expect.objectContaining({
id: lineItemId1,
created_at: expect.any(String),
updated_at: expect.any(String),
cart_id: null,
order_id: orderId,
swap_id: null,
claim_order_id: null,
title: expect.any(String),
description: "",
thumbnail: "",
is_return: false,
is_giftcard: false,
should_merge: true,
allow_discounts: true,
has_shipping: null,
unit_price: 1000,
variant_id: expect.any(String),
quantity: 1,
fulfilled_quantity: 1,
returned_quantity: null,
shipped_quantity: 1,
metadata: null,
variant: expect.any(Object),
}),
}),
]),
status: "created",
order_id: orderId,
created_by: "admin_user",
items: [
expect.objectContaining({
id: expect.any(String),
original_item_id: lineItemId2,
order_edit_id: orderEditId,
cart_id: null,
order_id: null,
swap_id: null,
claim_order_id: null,
title: expect.any(String),
is_return: false,
is_giftcard: false,
should_merge: true,
allow_discounts: true,
has_shipping: null,
unit_price: 1000,
variant_id: expect.any(String),
quantity: 1,
fulfilled_quantity: 1,
returned_quantity: null,
shipped_quantity: 1,
metadata: null,
tax_lines: expect.arrayContaining([
expect.objectContaining({
rate: 12.5,
name: "default",
code: "default",
}),
]),
}),
],
discount_total: 0,
gift_card_total: 0,
gift_card_tax_total: 0,
shipping_total: 0,
subtotal: 1000,
tax_total: 125,
total: 1125,
})
)
})
it("creates an order edit item change of type delete on line item delete and adjusts discount allocation from one to two items", async () => {
const api = useApi()
await api.post(`/store/carts/${cart.id}`, {
discounts: [{ code: discountCode }],
})
await api.post(`/store/carts/${cart.id}/payment-sessions`)
const completeRes = await api.post(`/store/carts/${cart.id}/complete`)
const discountOrder = completeRes.data.data
const {
data: { order_edit },
} = await api.post(
`/admin/order-edits/`,
{
order_id: discountOrder.id,
},
adminHeaders
)
const editLineItemId = order_edit.items.find(
(it) => it.original_item_id === lineItemId1Discount
).id
const orderEditId = order_edit.id
await api.delete(
`/admin/order-edits/${orderEditId}/items/${editLineItemId}`,
adminHeaders
)
const response = await api.get(
`/admin/order-edits/${orderEditId}`,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.order_edit.changes).toHaveLength(1)
expect(response.data.order_edit).toEqual(
expect.objectContaining({
id: orderEditId,
changes: [
expect.objectContaining({
id: expect.any(String),
created_at: expect.any(String),
updated_at: expect.any(String),
deleted_at: null,
type: "item_remove",
order_edit_id: orderEditId,
original_line_item_id: lineItemId1Discount,
line_item_id: null,
original_line_item: expect.objectContaining({
id: lineItemId1Discount,
created_at: expect.any(String),
updated_at: expect.any(String),
cart_id: expect.any(String),
order_id: discountOrder.id,
swap_id: null,
claim_order_id: null,
title: expect.any(String),
description: "",
thumbnail: "",
is_return: false,
is_giftcard: false,
should_merge: true,
allow_discounts: true,
has_shipping: null,
unit_price: 1000,
variant_id: expect.any(String),
quantity: 1,
returned_quantity: null,
shipped_quantity: null,
metadata: null,
variant: expect.any(Object),
}),
}),
],
status: "created",
order_id: discountOrder.id,
created_by: "admin_user",
items: [
expect.objectContaining({
id: expect.any(String),
original_item_id: lineItemId2Discount,
order_edit_id: orderEditId,
cart_id: null,
order_id: null,
swap_id: null,
claim_order_id: null,
title: expect.any(String),
description: "",
thumbnail: "",
is_return: false,
is_giftcard: false,
should_merge: true,
allow_discounts: true,
has_shipping: null,
unit_price: 1000,
variant_id: expect.any(String),
quantity: 1,
returned_quantity: null,
metadata: null,
adjustments: [
expect.objectContaining({
id: expect.any(String),
item_id: expect.any(String),
description: "discount",
discount_id: expect.any(String),
amount: 500,
metadata: null,
}),
],
tax_lines: expect.arrayContaining([
expect.objectContaining({
rate: 12.5,
name: "default",
code: "default",
}),
]),
}),
],
discount_total: 500,
gift_card_total: 0,
gift_card_tax_total: 0,
shipping_total: 0,
subtotal: 1000,
tax_total: 63,
total: 563,
})
)
})
it("creates an order edit item change of type delete on line item delete and adjusts discount allocation from one to two items with discount amount being larger than the unit price of the remaining line item", async () => {
const api = useApi()
await api.post(`/store/carts/${cart.id}`, {
discounts: [{ code: discountCodeLarge }],
})
await api.post(`/store/carts/${cart.id}/payment-sessions`)
const completeRes = await api.post(`/store/carts/${cart.id}/complete`)
const discountOrder = completeRes.data.data
const {
data: { order_edit },
} = await api.post(
`/admin/order-edits/`,
{
order_id: discountOrder.id,
},
adminHeaders
)
const editLineItemId = order_edit.items.find(
(it) => it.original_item_id === lineItemId1Discount
).id
const orderEditId = order_edit.id
await api.delete(
`/admin/order-edits/${orderEditId}/items/${editLineItemId}`,
adminHeaders
)
const response = await api.get(
`/admin/order-edits/${orderEditId}`,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.order_edit.changes).toHaveLength(1)
expect(response.data.order_edit).toEqual(
expect.objectContaining({
id: orderEditId,
changes: [
expect.objectContaining({
id: expect.any(String),
created_at: expect.any(String),
updated_at: expect.any(String),
deleted_at: null,
type: "item_remove",
order_edit_id: orderEditId,
original_line_item_id: lineItemId1Discount,
line_item_id: null,
original_line_item: expect.objectContaining({
id: lineItemId1Discount,
created_at: expect.any(String),
updated_at: expect.any(String),
cart_id: expect.any(String),
order_id: discountOrder.id,
swap_id: null,
claim_order_id: null,
title: expect.any(String),
description: "",
thumbnail: "",
is_return: false,
is_giftcard: false,
should_merge: true,
allow_discounts: true,
has_shipping: null,
unit_price: 1000,
variant_id: expect.any(String),
quantity: 1,
returned_quantity: null,
shipped_quantity: null,
metadata: null,
variant: expect.any(Object),
}),
}),
],
status: "created",
order_id: discountOrder.id,
created_by: "admin_user",
items: [
expect.objectContaining({
id: expect.any(String),
original_item_id: lineItemId2Discount,
order_edit_id: orderEditId,
cart_id: null,
order_id: null,
swap_id: null,
claim_order_id: null,
title: expect.any(String),
description: "",
thumbnail: "",
is_return: false,
is_giftcard: false,
should_merge: true,
allow_discounts: true,
has_shipping: null,
unit_price: 1000,
variant_id: expect.any(String),
quantity: 1,
returned_quantity: null,
metadata: null,
adjustments: [
expect.objectContaining({
id: expect.any(String),
item_id: expect.any(String),
description: "discount",
discount_id: expect.any(String),
amount: 1000,
metadata: null,
}),
],
tax_lines: expect.arrayContaining([
expect.objectContaining({
rate: 12.5,
name: "default",
code: "default",
}),
]),
}),
],
discount_total: 1000,
gift_card_total: 0,
gift_card_tax_total: 0,
shipping_total: 0,
subtotal: 1000,
tax_total: 0,
total: 0,
})
)
})
})
})

View File

@@ -95,6 +95,15 @@ class AdminOrderEditsResource extends BaseResource {
const path = `/admin/order-edits/${orderEditId}/items/${itemId}`
return this.client.request("POST", path, payload, {}, customHeaders)
}
removeLineItem(
orderEditId: string,
itemId: string,
customHeaders: Record<string, any> = {}
): ResponsePromise<AdminOrderEditsRes> {
const path = `/admin/order-edits/${orderEditId}/items/${itemId}`
return this.client.request("DELETE", path, undefined, {}, customHeaders)
}
}
export default AdminOrderEditsResource

View File

@@ -1783,6 +1783,22 @@ export const adminHandlers = [
})
)
}),
rest.delete("/admin/order-edits/:id/items/:item_id", (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
order_edit: {
...fixtures.get("order_edit"),
changes: [
{
type: 'item_remove'
},
],
},
})
)
}),
rest.get("/admin/auth", (req, res, ctx) => {
return res(

View File

@@ -93,6 +93,27 @@ export const useAdminOrderEditUpdateLineItem = (
)
}
export const useAdminOrderEditDeleteLineItem = (
orderEditId: string,
itemId: string,
options?: UseMutationOptions<
Response<AdminOrderEditsRes>,
Error
>
) => {
const { client } = useMedusa()
const queryClient = useQueryClient()
return useMutation(
(() => client.admin.orderEdits.removeLineItem(orderEditId, itemId)),
buildOptions(
queryClient,
[adminOrderEditsKeys.detail(orderEditId), adminOrderEditsKeys.lists()],
options
)
)
}
export const useAdminUpdateOrderEdit = (
id: string,
options?: UseMutationOptions<

View File

@@ -10,6 +10,7 @@ import {
useAdminOrderEditLineItem,
useAdminCancelOrderEdit,
useAdminUpdateOrderEdit,
useAdminOrderEditDeleteLineItem,
} from "../../../../src/"
import { fixtures } from "../../../../mocks/data"
import { createWrapper } from "../../../utils"
@@ -247,3 +248,32 @@ describe("useAdminConfirmOrderEdit hook", () => {
)
})
})
describe("useAdminOrderEditDeleteLineItem hook", () => {
test("Remove line item of an order edit and create an item change", async () => {
const id = "oe_1"
const itemId = "item_1"
const { result, waitFor } = renderHook(
() => useAdminOrderEditDeleteLineItem(id, itemId),
{
wrapper: createWrapper(),
}
)
result.current.mutate()
await waitFor(() => result.current.isSuccess)
expect(result.current.data.response.status).toEqual(200)
expect(result.current.data.order_edit).toEqual(
expect.objectContaining({
...fixtures.get("order_edit"),
changes: expect.arrayContaining([
expect.objectContaining({
type: 'item_remove'
}),
]),
})
)
})
})

View File

@@ -0,0 +1,42 @@
import { IdMap } from "medusa-test-utils"
import { request } from "../../../../../helpers/test-request"
import OrderEditingFeatureFlag from "../../../../../loaders/feature-flags/order-editing"
import { orderEditServiceMock } from "../../../../../services/__mocks__/order-edit"
describe("DELETE /admin/order-edits/:id/items/:item_id", () => {
describe("deletes a line item", () => {
const lineItemId = IdMap.getId("testLineItem")
const orderEditId = IdMap.getId("testCreatedOrder")
let subject
beforeAll(async () => {
subject = await request("DELETE", `/admin/order-edits/${orderEditId}/items/${lineItemId}`, {
adminSession: {
jwt: {
userId: IdMap.getId("admin_user"),
},
},
flags: [OrderEditingFeatureFlag],
})
})
afterAll(() => {
jest.clearAllMocks()
})
it("calls orderService removeLineItem", () => {
expect(orderEditServiceMock.removeLineItem).toHaveBeenCalledTimes(1)
expect(orderEditServiceMock.removeLineItem).toHaveBeenCalledWith(orderEditId, lineItemId)
})
it("returns 200", () => {
expect(subject.status).toEqual(200)
})
it("returns retrieve result", () => {
expect(subject.body.order_edit).toEqual(expect.objectContaining({
id: orderEditId,
}))
})
})
})

View File

@@ -0,0 +1,85 @@
import { EntityManager } from "typeorm"
import { OrderEditService } from "../../../../services"
import { Request, Response } from "express"
import { IsNumber } from "class-validator"
import {
defaultOrderEditFields,
defaultOrderEditRelations,
} from "../../../../types/order-edit"
/**
* @oas [delete] /order-edits/{id}/items/{item_id}
* operationId: "DeleteOrderEditsOrderEditLineItemsLineItem"
* summary: "Delete line items from an order edit and create change item"
* description: "Delete line items from an order edit and create change item"
* x-authenticated: true
* parameters:
* - (path) id=* {string} The ID of the Order Edit to delete from.
* - (path) item_id=* {string} The ID of the order edit item to delete from order.
* x-codeSamples:
* - lang: JavaScript
* label: JS Client
* source: |
* import Medusa from "@medusajs/medusa-js"
* const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3 })
* // must be previously logged in or use api token
* medusa.admin.orderEdits.removeLineItem(order_edit_id, line_item_id)
* .then(({ order_edit }) => {
* console.log(order_edit.id)
* })
* - lang: Shell
* label: cURL
* source: |
* curl --location --request DELETE 'https://medusa-url.com/admin/order-edits/{id}/items/{item_id}' \
* --header 'Authorization: Bearer {api_token}'
* security:
* - api_token: []
* - cookie_auth: []
* tags:
* - OrderEdit
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order_edit:
* $ref: "#/components/schemas/order_edit"
* "400":
* $ref: "#/components/responses/400_error"
* "401":
* $ref: "#/components/responses/unauthorized"
* "404":
* $ref: "#/components/responses/not_found_error"
* "409":
* $ref: "#/components/responses/invalid_state_error"
* "422":
* $ref: "#/components/responses/invalid_request_error"
* "500":
* $ref: "#/components/responses/500_error"
*/
export default async (req: Request, res: Response) => {
const { id, item_id } = req.params
const orderEditService: OrderEditService =
req.scope.resolve("orderEditService")
const manager: EntityManager = req.scope.resolve("manager")
await manager.transaction(async (transactionManager) => {
await orderEditService
.withTransaction(transactionManager)
.removeLineItem(id, item_id)
})
let orderEdit = await orderEditService.retrieve(id, {
select: defaultOrderEditFields,
relations: defaultOrderEditRelations,
})
orderEdit = await orderEditService.decorateTotals(orderEdit)
res.status(200).send({
order_edit: orderEdit,
})
}

View File

@@ -82,6 +82,11 @@ export default (app) => {
middlewares.wrap(require("./update-order-edit-line-item").default)
)
route.delete(
"/:id/items/:item_id",
middlewares.wrap(require("./delete-line-item").default)
)
return app
}

View File

@@ -14,7 +14,7 @@ import {
* description: "Create or update the order edit change holding the line item changes"
* x-authenticated: true
* parameters:
* - (path) id=* {string} The ID of the Order Edit to delete.
* - (path) id=* {string} The ID of the Order Edit to update.
* - (path) item_id=* {string} The ID of the order edit item to update.
* x-codeSamples:
* - lang: JavaScript
@@ -30,7 +30,7 @@ import {
* - lang: Shell
* label: cURL
* source: |
* curl --location --request DELETE 'https://medusa-url.com/admin/order-edits/{id}/items/{item_id}' \
* curl --location --request POST 'https://medusa-url.com/admin/order-edits/{id}/items/{item_id}' \
* --header 'Authorization: Bearer {api_token}'
* -d '{ "quantity": 5 }'
* security:

View File

@@ -22,10 +22,6 @@ export default (app, featureFlagRouter: FlagRouter) => {
relations.push("sales_channel")
}
if (featureFlagRouter.isFeatureEnabled(OrderEditingFeatureFlag.key)) {
relations.push("edits")
}
/**
* List orders
*/

View File

@@ -146,6 +146,9 @@ export const orderEditServiceMock = {
updateLineItem: jest.fn().mockImplementation((_) => {
return Promise.resolve()
}),
removeLineItem: jest.fn().mockImplementation((_) => {
return Promise.resolve()
}),
}
const mock = jest.fn().mockImplementation(() => {

View File

@@ -16,6 +16,7 @@ import {
ProductService,
ProductVariantService,
RegionService,
TaxProviderService,
} from "./index"
import { buildQuery, setMetadata } from "../utils"
import { TransactionBaseService } from "../interfaces"
@@ -30,6 +31,7 @@ type InjectedDependencies = {
pricingService: PricingService
regionService: RegionService
lineItemAdjustmentService: LineItemAdjustmentService
taxProviderService: TaxProviderService
featureFlagRouter: FlagRouter
}
@@ -46,6 +48,7 @@ class LineItemService extends TransactionBaseService {
protected readonly regionService_: RegionService
protected readonly featureFlagRouter_: FlagRouter
protected readonly lineItemAdjustmentService_: LineItemAdjustmentService
protected readonly taxProviderService_: TaxProviderService
constructor({
manager,
@@ -57,6 +60,7 @@ class LineItemService extends TransactionBaseService {
regionService,
cartRepository,
lineItemAdjustmentService,
taxProviderService,
featureFlagRouter,
}: InjectedDependencies) {
super(arguments[0])
@@ -70,6 +74,7 @@ class LineItemService extends TransactionBaseService {
this.regionService_ = regionService
this.cartRepository_ = cartRepository
this.lineItemAdjustmentService_ = lineItemAdjustmentService
this.taxProviderService_ = taxProviderService
this.featureFlagRouter_ = featureFlagRouter
}
@@ -352,6 +357,27 @@ class LineItemService extends TransactionBaseService {
)
}
/**
* Deletes a line item with the tax lines.
* @param id - the id of the line item to delete
* @return the result of the delete operation
*/
async deleteWithTaxLines(id: string): Promise<LineItem | undefined> {
return await this.atomicPhase_(
async (transactionManager: EntityManager) => {
const lineItemRepository = transactionManager.getCustomRepository(
this.lineItemRepository_
)
await this.taxProviderService_
.withTransaction(transactionManager)
.clearLineItemsTaxLines([id])
return await this.delete(id)
}
)
}
/**
* Create a line item tax line.
* @param args - tax line partial passed to the repo create method

View File

@@ -38,7 +38,7 @@ export default class OrderEditItemChangeService extends TransactionBaseService {
lineItemService,
taxProviderService,
}: InjectedDependencies) {
// @ts-ignore
// eslint-disable-next-line prefer-rest-params
super(arguments[0])
this.manager_ = manager
@@ -125,7 +125,9 @@ export default class OrderEditItemChangeService extends TransactionBaseService {
const lineItemServiceTx = this.lineItemService_.withTransaction(manager)
await Promise.all([
...lineItemIdsToRemove.map((id) => lineItemServiceTx.delete(id)),
...lineItemIdsToRemove.map(
async (id) => await lineItemServiceTx.delete(id)
),
this.taxProviderService_
.withTransaction(manager)
.clearLineItemsTaxLines(lineItemIdsToRemove),

View File

@@ -389,6 +389,63 @@ export default class OrderEditService extends TransactionBaseService {
})
}
async removeLineItem(orderEditId: string, lineItemId: string): Promise<void> {
return await this.atomicPhase_(async (manager) => {
const orderEdit = await this.retrieve(orderEditId, {
select: [
"id",
"created_at",
"requested_at",
"confirmed_at",
"declined_at",
"canceled_at",
],
})
const isOrderEditActive = OrderEditService.isOrderEditActive(orderEdit)
if (!isOrderEditActive) {
throw new MedusaError(
MedusaError.Types.NOT_ALLOWED,
`Can not update an item on the order edit ${orderEditId} with the status ${orderEdit.status}`
)
}
const lineItem = await this.lineItemService_
.withTransaction(manager)
.retrieve(lineItemId, {
select: ["id", "order_edit_id", "original_item_id"],
})
.catch(() => void 0)
if (!lineItem) {
return
}
if (
lineItem.order_edit_id !== orderEditId ||
!lineItem.original_item_id
) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`Invalid line item id ${lineItemId} it does not belong to the same order edit ${orderEdit.order_id}.`
)
}
await this.lineItemService_
.withTransaction(manager)
.deleteWithTaxLines(lineItem.id)
await this.refreshAdjustments(orderEditId)
await this.orderEditItemChangeService_.withTransaction(manager).create({
original_line_item_id: lineItem.original_item_id,
type: OrderEditItemChangeType.ITEM_REMOVE,
order_edit_id: orderEdit.id,
})
})
}
async refreshAdjustments(orderEditId: string) {
const manager = this.transactionManager_ ?? this.manager_

View File

@@ -966,4 +966,3 @@ const SalesChannelsSchema: ProductImportCsvSchema = {
},
],
}