chore(medusa): New totals calc. in Swap creation (#3191)

* feat(medusa): Cleanup swap creation flow

* revert test and package

* fix unit tests

* fix swap seeder that does not include the tax lines on the return line item

---------

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Adrien de Peretti
2023-02-14 10:52:45 +01:00
committed by GitHub
co-authored by Oliver Windall Juhl
parent 80452332d8
commit 5e0273a370
5 changed files with 85 additions and 38 deletions
@@ -138,9 +138,9 @@ export default async (req, res) => {
.workStage(idempotencyKey.idempotency_key, async (manager) => {
const order = await orderService
.withTransaction(manager)
.retrieve(id, {
select: ["refunded_total", "total"],
.retrieveWithTotals(id, {
relations: [
"cart",
"items",
"items.tax_lines",
"swaps",
+18 -8
View File
@@ -1,7 +1,11 @@
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
import SwapService from "../swap"
import { ProductVariantInventoryServiceMock } from "../__mocks__/product-variant-inventory"
import { LineItemAdjustmentServiceMock } from "../__mocks__/line-item-adjustment"
import {
ProductVariantInventoryServiceMock
} from "../__mocks__/product-variant-inventory"
import {
LineItemAdjustmentServiceMock
} from "../__mocks__/line-item-adjustment"
import {
CustomShippingOptionService,
EventBusService,
@@ -65,6 +69,7 @@ const lineItemService = {
create: jest.fn().mockImplementation((d) => Promise.resolve(d)),
update: jest.fn().mockImplementation((d) => Promise.resolve(d)),
retrieve: () => Promise.resolve({}),
list: () => Promise.resolve([]),
createReturnLines: jest.fn(() => Promise.resolve()),
withTransaction: function () {
return this
@@ -240,6 +245,7 @@ describe("SwapService", () => {
create: jest.fn().mockImplementation((d) => Promise.resolve(d)),
update: jest.fn().mockImplementation((d) => Promise.resolve(d)),
retrieve: () => Promise.resolve({}),
list: () => Promise.resolve([]),
createReturnLines: jest.fn(() => Promise.resolve()),
withTransaction: function () {
return this
@@ -400,7 +406,7 @@ describe("SwapService", () => {
const lineItemService = {
generate: jest
.fn()
.mockImplementation((variantId, regionId, quantity) => {
.mockImplementation(({ variantId, quantity }) => {
return {
unit_price: 100,
variant_id: variantId,
@@ -408,6 +414,7 @@ describe("SwapService", () => {
}
}),
retrieve: () => Promise.resolve({}),
list: () => Promise.resolve([]),
withTransaction: function () {
return this
},
@@ -441,11 +448,13 @@ describe("SwapService", () => {
)
expect(lineItemService.generate).toHaveBeenCalledTimes(1)
expect(lineItemService.generate).toHaveBeenCalledWith(
IdMap.getId("new-variant"),
IdMap.getId("region"),
1
)
expect(lineItemService.generate).toHaveBeenCalledWith({
quantity: 1,
variantId: IdMap.getId("new-variant")
}, {
"cart": undefined,
region_id: IdMap.getId("region")
})
})
it("creates swap", async () => {
@@ -538,6 +547,7 @@ describe("SwapService", () => {
const lineItemService = {
update: jest.fn(),
retrieve: () => Promise.resolve({}),
list: () => Promise.resolve([]),
withTransaction: function () {
return this
},
+1 -1
View File
@@ -201,7 +201,7 @@ class LineItemService extends TransactionBaseService {
? LineItem
: LineItem[]
>(
variantIdOrData: string | T,
variantIdOrData: T,
regionIdOrContext: T extends string ? string : GenerateLineItemContext,
quantity?: number,
context: GenerateLineItemContext = {}
+43 -21
View File
@@ -1,11 +1,11 @@
import { isDefined, MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import { EntityManager, In } from "typeorm"
import { buildQuery, setMetadata, validateId } from "../utils"
import { TransactionBaseService } from "../interfaces"
import LineItemAdjustmentService from "./line-item-adjustment"
import { FindConfig, Selector } from "../types/common"
import { FindConfig, Selector, WithRequiredProperty } from "../types/common"
import { SwapRepository } from "../repositories/swap"
import CartService from "./cart"
import {
@@ -314,7 +314,7 @@ class SwapService extends TransactionBaseService {
*/
async create(
order: Order,
returnItems: Partial<ReturnItem>[],
returnItems: WithRequiredProperty<Partial<ReturnItem>, "item_id">[],
additionalItems?: Pick<LineItem, "variant_id" | "quantity">[],
returnShipping?: { option_id: string; price?: number },
custom: {
@@ -335,22 +335,13 @@ class SwapService extends TransactionBaseService {
)
}
const lineItemServiceTx = this.lineItemService_.withTransaction(manager)
for (const item of returnItems) {
const line = await lineItemServiceTx.retrieve(item.item_id!, {
relations: ["order", "swap", "claim_order"],
})
const areReturnItemsValid = await this.areReturnItemsValid(returnItems)
if (
line.order?.canceled_at ||
line.swap?.canceled_at ||
line.claim_order?.canceled_at
) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`Cannot create a swap on a canceled item.`
)
}
if (!areReturnItemsValid) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`Cannot create a swap on a canceled item.`
)
}
let newItems: LineItem[] = []
@@ -364,9 +355,13 @@ class SwapService extends TransactionBaseService {
"You must include a variant when creating additional items on a swap"
)
}
return this.lineItemService_
.withTransaction(manager)
.generate(variant_id, order.region_id, quantity)
return this.lineItemService_.withTransaction(manager).generate(
{ variantId: variant_id, quantity },
{
region_id: order.region_id,
cart: order.cart,
}
)
})
)
}
@@ -1221,6 +1216,33 @@ class SwapService extends TransactionBaseService {
return result
})
}
protected async areReturnItemsValid(
returnItems: WithRequiredProperty<Partial<ReturnItem>, "item_id">[]
): Promise<boolean> {
const manager = this.transactionManager_ ?? this.manager_
const returnItemsEntities = await this.lineItemService_
.withTransaction(manager)
.list(
{
id: In(returnItems.map((r) => r.item_id)),
},
{
relations: ["order", "swap", "claim_order"],
}
)
const hasCanceledItem = returnItemsEntities.some((item) => {
return (
item.order?.canceled_at ||
item.swap?.canceled_at ||
item.claim_order?.canceled_at
)
})
return !hasCanceledItem
}
}
export default SwapService