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:
1 parent
80452332d8
commit
5e0273a370
5 files changed
+85
-38
No files matched your search
@@ -11,10 +11,18 @@ const {
|
|||||||
const {
|
const {
|
||||||
CustomShippingOption,
|
CustomShippingOption,
|
||||||
} = require("@medusajs/medusa/dist/models/custom-shipping-option")
|
} = 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 = {}) => {
|
module.exports = async (connection, data = {}) => {
|
||||||
const manager = connection.manager
|
const manager = connection.manager
|
||||||
|
|
||||||
|
regionId = "test-region"
|
||||||
|
|
||||||
|
region = await manager.findOne(Region, { id: regionId })
|
||||||
|
|
||||||
let orderWithSwap = manager.create(Order, {
|
let orderWithSwap = manager.create(Order, {
|
||||||
id: "order-with-swap",
|
id: "order-with-swap",
|
||||||
customer_id: "test-customer",
|
customer_id: "test-customer",
|
||||||
@@ -30,7 +38,7 @@ module.exports = async (connection, data = {}) => {
|
|||||||
first_name: "lebron",
|
first_name: "lebron",
|
||||||
country_code: "us",
|
country_code: "us",
|
||||||
},
|
},
|
||||||
region_id: "test-region",
|
region_id: regionId,
|
||||||
currency_code: "usd",
|
currency_code: "usd",
|
||||||
tax_rate: 0,
|
tax_rate: 0,
|
||||||
discounts: [],
|
discounts: [],
|
||||||
@@ -56,7 +64,7 @@ module.exports = async (connection, data = {}) => {
|
|||||||
email: "test-customer@email.com",
|
email: "test-customer@email.com",
|
||||||
shipping_address_id: "test-shipping-address",
|
shipping_address_id: "test-shipping-address",
|
||||||
billing_address_id: "test-billing-address",
|
billing_address_id: "test-billing-address",
|
||||||
region_id: "test-region",
|
region_id: regionId,
|
||||||
type: "swap",
|
type: "swap",
|
||||||
metadata: {
|
metadata: {
|
||||||
swap_id: "test-swap",
|
swap_id: "test-swap",
|
||||||
@@ -103,7 +111,7 @@ module.exports = async (connection, data = {}) => {
|
|||||||
email: "test-customer@email.com",
|
email: "test-customer@email.com",
|
||||||
shipping_address_id: "test-shipping-address",
|
shipping_address_id: "test-shipping-address",
|
||||||
billing_address_id: "test-billing-address",
|
billing_address_id: "test-billing-address",
|
||||||
region_id: "test-region",
|
region_id: regionId,
|
||||||
type: "swap",
|
type: "swap",
|
||||||
metadata: {
|
metadata: {
|
||||||
swap_id: "test-swap",
|
swap_id: "test-swap",
|
||||||
@@ -170,7 +178,7 @@ module.exports = async (connection, data = {}) => {
|
|||||||
email: "test-customer@email.com",
|
email: "test-customer@email.com",
|
||||||
shipping_address_id: "test-shipping-address",
|
shipping_address_id: "test-shipping-address",
|
||||||
billing_address_id: "test-billing-address",
|
billing_address_id: "test-billing-address",
|
||||||
region_id: "test-region",
|
region_id: regionId,
|
||||||
type: "swap",
|
type: "swap",
|
||||||
metadata: {},
|
metadata: {},
|
||||||
...data,
|
...data,
|
||||||
@@ -349,7 +357,7 @@ const createSwap = async (options, manager) => {
|
|||||||
is_disabled: false,
|
is_disabled: false,
|
||||||
rule: dRule,
|
rule: dRule,
|
||||||
})
|
})
|
||||||
let discountDb = await manager.save(discount)
|
const discountDb = await manager.save(discount)
|
||||||
|
|
||||||
const cart = manager.create(Cart, {
|
const cart = manager.create(Cart, {
|
||||||
id: `${swapId}-cart`,
|
id: `${swapId}-cart`,
|
||||||
@@ -357,7 +365,7 @@ const createSwap = async (options, manager) => {
|
|||||||
email: "test-customer@email.com",
|
email: "test-customer@email.com",
|
||||||
shipping_address_id: "test-shipping-address",
|
shipping_address_id: "test-shipping-address",
|
||||||
billing_address_id: "test-billing-address",
|
billing_address_id: "test-billing-address",
|
||||||
region_id: "test-region",
|
region_id: regionId,
|
||||||
type: "swap",
|
type: "swap",
|
||||||
discounts: [discount],
|
discounts: [discount],
|
||||||
metadata: {
|
metadata: {
|
||||||
@@ -396,6 +404,13 @@ const createSwap = async (options, manager) => {
|
|||||||
thumbnail: "https://test.js/1234",
|
thumbnail: "https://test.js/1234",
|
||||||
unit_price: 8000,
|
unit_price: 8000,
|
||||||
quantity: 1,
|
quantity: 1,
|
||||||
|
tax_lines: [
|
||||||
|
{
|
||||||
|
rate: region.tax_rate,
|
||||||
|
code: region.name,
|
||||||
|
name: region.name,
|
||||||
|
},
|
||||||
|
],
|
||||||
adjustments: [
|
adjustments: [
|
||||||
{
|
{
|
||||||
amount: -800,
|
amount: -800,
|
||||||
|
|||||||
@@ -138,9 +138,9 @@ export default async (req, res) => {
|
|||||||
.workStage(idempotencyKey.idempotency_key, async (manager) => {
|
.workStage(idempotencyKey.idempotency_key, async (manager) => {
|
||||||
const order = await orderService
|
const order = await orderService
|
||||||
.withTransaction(manager)
|
.withTransaction(manager)
|
||||||
.retrieve(id, {
|
.retrieveWithTotals(id, {
|
||||||
select: ["refunded_total", "total"],
|
|
||||||
relations: [
|
relations: [
|
||||||
|
"cart",
|
||||||
"items",
|
"items",
|
||||||
"items.tax_lines",
|
"items.tax_lines",
|
||||||
"swaps",
|
"swaps",
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
|
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
|
||||||
import SwapService from "../swap"
|
import SwapService from "../swap"
|
||||||
import { ProductVariantInventoryServiceMock } from "../__mocks__/product-variant-inventory"
|
import {
|
||||||
import { LineItemAdjustmentServiceMock } from "../__mocks__/line-item-adjustment"
|
ProductVariantInventoryServiceMock
|
||||||
|
} from "../__mocks__/product-variant-inventory"
|
||||||
|
import {
|
||||||
|
LineItemAdjustmentServiceMock
|
||||||
|
} from "../__mocks__/line-item-adjustment"
|
||||||
import {
|
import {
|
||||||
CustomShippingOptionService,
|
CustomShippingOptionService,
|
||||||
EventBusService,
|
EventBusService,
|
||||||
@@ -65,6 +69,7 @@ const lineItemService = {
|
|||||||
create: jest.fn().mockImplementation((d) => Promise.resolve(d)),
|
create: jest.fn().mockImplementation((d) => Promise.resolve(d)),
|
||||||
update: jest.fn().mockImplementation((d) => Promise.resolve(d)),
|
update: jest.fn().mockImplementation((d) => Promise.resolve(d)),
|
||||||
retrieve: () => Promise.resolve({}),
|
retrieve: () => Promise.resolve({}),
|
||||||
|
list: () => Promise.resolve([]),
|
||||||
createReturnLines: jest.fn(() => Promise.resolve()),
|
createReturnLines: jest.fn(() => Promise.resolve()),
|
||||||
withTransaction: function () {
|
withTransaction: function () {
|
||||||
return this
|
return this
|
||||||
@@ -240,6 +245,7 @@ describe("SwapService", () => {
|
|||||||
create: jest.fn().mockImplementation((d) => Promise.resolve(d)),
|
create: jest.fn().mockImplementation((d) => Promise.resolve(d)),
|
||||||
update: jest.fn().mockImplementation((d) => Promise.resolve(d)),
|
update: jest.fn().mockImplementation((d) => Promise.resolve(d)),
|
||||||
retrieve: () => Promise.resolve({}),
|
retrieve: () => Promise.resolve({}),
|
||||||
|
list: () => Promise.resolve([]),
|
||||||
createReturnLines: jest.fn(() => Promise.resolve()),
|
createReturnLines: jest.fn(() => Promise.resolve()),
|
||||||
withTransaction: function () {
|
withTransaction: function () {
|
||||||
return this
|
return this
|
||||||
@@ -400,7 +406,7 @@ describe("SwapService", () => {
|
|||||||
const lineItemService = {
|
const lineItemService = {
|
||||||
generate: jest
|
generate: jest
|
||||||
.fn()
|
.fn()
|
||||||
.mockImplementation((variantId, regionId, quantity) => {
|
.mockImplementation(({ variantId, quantity }) => {
|
||||||
return {
|
return {
|
||||||
unit_price: 100,
|
unit_price: 100,
|
||||||
variant_id: variantId,
|
variant_id: variantId,
|
||||||
@@ -408,6 +414,7 @@ describe("SwapService", () => {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
retrieve: () => Promise.resolve({}),
|
retrieve: () => Promise.resolve({}),
|
||||||
|
list: () => Promise.resolve([]),
|
||||||
withTransaction: function () {
|
withTransaction: function () {
|
||||||
return this
|
return this
|
||||||
},
|
},
|
||||||
@@ -441,11 +448,13 @@ describe("SwapService", () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
expect(lineItemService.generate).toHaveBeenCalledTimes(1)
|
expect(lineItemService.generate).toHaveBeenCalledTimes(1)
|
||||||
expect(lineItemService.generate).toHaveBeenCalledWith(
|
expect(lineItemService.generate).toHaveBeenCalledWith({
|
||||||
IdMap.getId("new-variant"),
|
quantity: 1,
|
||||||
IdMap.getId("region"),
|
variantId: IdMap.getId("new-variant")
|
||||||
1
|
}, {
|
||||||
)
|
"cart": undefined,
|
||||||
|
region_id: IdMap.getId("region")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("creates swap", async () => {
|
it("creates swap", async () => {
|
||||||
@@ -538,6 +547,7 @@ describe("SwapService", () => {
|
|||||||
const lineItemService = {
|
const lineItemService = {
|
||||||
update: jest.fn(),
|
update: jest.fn(),
|
||||||
retrieve: () => Promise.resolve({}),
|
retrieve: () => Promise.resolve({}),
|
||||||
|
list: () => Promise.resolve([]),
|
||||||
withTransaction: function () {
|
withTransaction: function () {
|
||||||
return this
|
return this
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ class LineItemService extends TransactionBaseService {
|
|||||||
? LineItem
|
? LineItem
|
||||||
: LineItem[]
|
: LineItem[]
|
||||||
>(
|
>(
|
||||||
variantIdOrData: string | T,
|
variantIdOrData: T,
|
||||||
regionIdOrContext: T extends string ? string : GenerateLineItemContext,
|
regionIdOrContext: T extends string ? string : GenerateLineItemContext,
|
||||||
quantity?: number,
|
quantity?: number,
|
||||||
context: GenerateLineItemContext = {}
|
context: GenerateLineItemContext = {}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { isDefined, MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager, In } from "typeorm"
|
||||||
|
|
||||||
import { buildQuery, setMetadata, validateId } from "../utils"
|
import { buildQuery, setMetadata, validateId } from "../utils"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
|
|
||||||
import LineItemAdjustmentService from "./line-item-adjustment"
|
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 { SwapRepository } from "../repositories/swap"
|
||||||
import CartService from "./cart"
|
import CartService from "./cart"
|
||||||
import {
|
import {
|
||||||
@@ -314,7 +314,7 @@ class SwapService extends TransactionBaseService {
|
|||||||
*/
|
*/
|
||||||
async create(
|
async create(
|
||||||
order: Order,
|
order: Order,
|
||||||
returnItems: Partial<ReturnItem>[],
|
returnItems: WithRequiredProperty<Partial<ReturnItem>, "item_id">[],
|
||||||
additionalItems?: Pick<LineItem, "variant_id" | "quantity">[],
|
additionalItems?: Pick<LineItem, "variant_id" | "quantity">[],
|
||||||
returnShipping?: { option_id: string; price?: number },
|
returnShipping?: { option_id: string; price?: number },
|
||||||
custom: {
|
custom: {
|
||||||
@@ -335,22 +335,13 @@ class SwapService extends TransactionBaseService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const lineItemServiceTx = this.lineItemService_.withTransaction(manager)
|
const areReturnItemsValid = await this.areReturnItemsValid(returnItems)
|
||||||
for (const item of returnItems) {
|
|
||||||
const line = await lineItemServiceTx.retrieve(item.item_id!, {
|
|
||||||
relations: ["order", "swap", "claim_order"],
|
|
||||||
})
|
|
||||||
|
|
||||||
if (
|
if (!areReturnItemsValid) {
|
||||||
line.order?.canceled_at ||
|
throw new MedusaError(
|
||||||
line.swap?.canceled_at ||
|
MedusaError.Types.INVALID_DATA,
|
||||||
line.claim_order?.canceled_at
|
`Cannot create a swap on a canceled item.`
|
||||||
) {
|
)
|
||||||
throw new MedusaError(
|
|
||||||
MedusaError.Types.INVALID_DATA,
|
|
||||||
`Cannot create a swap on a canceled item.`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let newItems: LineItem[] = []
|
let newItems: LineItem[] = []
|
||||||
@@ -364,9 +355,13 @@ class SwapService extends TransactionBaseService {
|
|||||||
"You must include a variant when creating additional items on a swap"
|
"You must include a variant when creating additional items on a swap"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return this.lineItemService_
|
return this.lineItemService_.withTransaction(manager).generate(
|
||||||
.withTransaction(manager)
|
{ variantId: variant_id, quantity },
|
||||||
.generate(variant_id, order.region_id, quantity)
|
{
|
||||||
|
region_id: order.region_id,
|
||||||
|
cart: order.cart,
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1221,6 +1216,33 @@ class SwapService extends TransactionBaseService {
|
|||||||
return result
|
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
|
export default SwapService
|
||||||
Reference in new issue
Block a user