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:
committed by
GitHub
parent
80452332d8
commit
5e0273a370
@@ -11,10 +11,18 @@ const {
|
||||
const {
|
||||
CustomShippingOption,
|
||||
} = require("@medusajs/medusa/dist/models/custom-shipping-option")
|
||||
const { Region } = require("@medusajs/medusa/dist/models/region")
|
||||
|
||||
let regionId
|
||||
let region
|
||||
|
||||
module.exports = async (connection, data = {}) => {
|
||||
const manager = connection.manager
|
||||
|
||||
regionId = "test-region"
|
||||
|
||||
region = await manager.findOne(Region, { id: regionId })
|
||||
|
||||
let orderWithSwap = manager.create(Order, {
|
||||
id: "order-with-swap",
|
||||
customer_id: "test-customer",
|
||||
@@ -30,7 +38,7 @@ module.exports = async (connection, data = {}) => {
|
||||
first_name: "lebron",
|
||||
country_code: "us",
|
||||
},
|
||||
region_id: "test-region",
|
||||
region_id: regionId,
|
||||
currency_code: "usd",
|
||||
tax_rate: 0,
|
||||
discounts: [],
|
||||
@@ -56,7 +64,7 @@ module.exports = async (connection, data = {}) => {
|
||||
email: "test-customer@email.com",
|
||||
shipping_address_id: "test-shipping-address",
|
||||
billing_address_id: "test-billing-address",
|
||||
region_id: "test-region",
|
||||
region_id: regionId,
|
||||
type: "swap",
|
||||
metadata: {
|
||||
swap_id: "test-swap",
|
||||
@@ -103,7 +111,7 @@ module.exports = async (connection, data = {}) => {
|
||||
email: "test-customer@email.com",
|
||||
shipping_address_id: "test-shipping-address",
|
||||
billing_address_id: "test-billing-address",
|
||||
region_id: "test-region",
|
||||
region_id: regionId,
|
||||
type: "swap",
|
||||
metadata: {
|
||||
swap_id: "test-swap",
|
||||
@@ -170,7 +178,7 @@ module.exports = async (connection, data = {}) => {
|
||||
email: "test-customer@email.com",
|
||||
shipping_address_id: "test-shipping-address",
|
||||
billing_address_id: "test-billing-address",
|
||||
region_id: "test-region",
|
||||
region_id: regionId,
|
||||
type: "swap",
|
||||
metadata: {},
|
||||
...data,
|
||||
@@ -349,7 +357,7 @@ const createSwap = async (options, manager) => {
|
||||
is_disabled: false,
|
||||
rule: dRule,
|
||||
})
|
||||
let discountDb = await manager.save(discount)
|
||||
const discountDb = await manager.save(discount)
|
||||
|
||||
const cart = manager.create(Cart, {
|
||||
id: `${swapId}-cart`,
|
||||
@@ -357,7 +365,7 @@ const createSwap = async (options, manager) => {
|
||||
email: "test-customer@email.com",
|
||||
shipping_address_id: "test-shipping-address",
|
||||
billing_address_id: "test-billing-address",
|
||||
region_id: "test-region",
|
||||
region_id: regionId,
|
||||
type: "swap",
|
||||
discounts: [discount],
|
||||
metadata: {
|
||||
@@ -396,6 +404,13 @@ const createSwap = async (options, manager) => {
|
||||
thumbnail: "https://test.js/1234",
|
||||
unit_price: 8000,
|
||||
quantity: 1,
|
||||
tax_lines: [
|
||||
{
|
||||
rate: region.tax_rate,
|
||||
code: region.name,
|
||||
name: region.name,
|
||||
},
|
||||
],
|
||||
adjustments: [
|
||||
{
|
||||
amount: -800,
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
},
|
||||
|
||||
@@ -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 = {}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user