fix(medusa): Draft order totals not working with custom items (#3008)
This commit is contained in:
committed by
GitHub
parent
9e3beaf531
commit
b3e4be7208
5
.changeset/wicked-cherries-sip.md
Normal file
5
.changeset/wicked-cherries-sip.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@medusajs/medusa": patch
|
||||
---
|
||||
|
||||
fix(medusa): Draft order totals not working with custom items
|
||||
@@ -1,4 +1,5 @@
|
||||
import _ from "lodash"
|
||||
import { asClass, asValue, createContainer } from "awilix"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
|
||||
import { FlagRouter } from "../../utils/flag-router"
|
||||
@@ -8,6 +9,18 @@ import { LineItemAdjustmentServiceMock } from "../__mocks__/line-item-adjustment
|
||||
import { newTotalsServiceMock } from "../__mocks__/new-totals"
|
||||
import { taxProviderServiceMock } from "../__mocks__/tax-provider"
|
||||
import { PaymentSessionStatus } from "../../models"
|
||||
import { NewTotalsService, TaxProviderService } from "../index"
|
||||
import { cacheServiceMock } from "../__mocks__/cache"
|
||||
import { EventBusServiceMock } from "../__mocks__/event-bus"
|
||||
import { PaymentProviderServiceMock } from "../__mocks__/payment-provider"
|
||||
import { ProductServiceMock } from "../__mocks__/product"
|
||||
import { ProductVariantServiceMock } from "../__mocks__/product-variant"
|
||||
import { RegionServiceMock } from "../__mocks__/region"
|
||||
import { LineItemServiceMock } from "../__mocks__/line-item"
|
||||
import { ShippingOptionServiceMock } from "../__mocks__/shipping-option"
|
||||
import { CustomerServiceMock } from "../__mocks__/customer"
|
||||
import TaxCalculationStrategy from "../../strategies/tax-calculation"
|
||||
import SystemTaxService from "../system-tax"
|
||||
|
||||
const eventBusService = {
|
||||
emit: jest.fn(),
|
||||
@@ -2512,4 +2525,96 @@ describe("CartService", () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("decorateTotals integration", () => {
|
||||
const legacyTotalServiceMock = {
|
||||
...totalsService,
|
||||
getCalculationContext: () => ({
|
||||
shipping_methods: [],
|
||||
region: {
|
||||
tax_rate: 10,
|
||||
currency_code: "eur",
|
||||
},
|
||||
allocation_map: {},
|
||||
}),
|
||||
}
|
||||
// TODO: extract that to a fixture to be used in this file in the rest of the tests. Needs some update on the registration
|
||||
// as it is for now adapted to this case
|
||||
const container = createContainer()
|
||||
container
|
||||
.register("manager", asValue(MockManager))
|
||||
.register("paymentSessionRepository", asValue(MockRepository({})))
|
||||
.register("addressRepository", asValue(MockRepository({})))
|
||||
.register("cartRepository", asValue(MockRepository({})))
|
||||
.register("lineItemRepository", asValue(MockRepository({})))
|
||||
.register("shippingMethodRepository", asValue(MockRepository({})))
|
||||
.register("paymentProviderService", asValue(PaymentProviderServiceMock))
|
||||
.register("productService", asValue(ProductServiceMock))
|
||||
.register("productVariantService", asValue(ProductVariantServiceMock))
|
||||
.register("regionService", asValue(RegionServiceMock))
|
||||
.register("lineItemService", asValue(LineItemServiceMock))
|
||||
.register("shippingOptionService", asValue(ShippingOptionServiceMock))
|
||||
.register("customerService", asValue(CustomerServiceMock))
|
||||
.register("discountService", asValue({}))
|
||||
.register("giftCardService", asValue({}))
|
||||
.register("totalsService", asValue(legacyTotalServiceMock))
|
||||
.register("customShippingOptionService", asValue({}))
|
||||
.register("lineItemAdjustmentService", asValue({}))
|
||||
.register("priceSelectionStrategy", asValue({}))
|
||||
.register("productVariantInventoryService", asValue({}))
|
||||
.register("salesChannelService", asValue({}))
|
||||
.register("storeService", asValue({}))
|
||||
.register("featureFlagRouter", asValue(new FlagRouter({})))
|
||||
.register("taxRateService", asValue({}))
|
||||
.register("systemTaxService", asValue(new SystemTaxService()))
|
||||
.register("tp_test", asValue("good"))
|
||||
.register("cacheService", asValue(cacheServiceMock))
|
||||
.register("taxProviderRepository", asValue(MockRepository))
|
||||
.register(
|
||||
"lineItemTaxLineRepository",
|
||||
asValue(MockRepository({ create: (d) => d }))
|
||||
)
|
||||
.register("shippingMethodTaxLineRepository", asValue(MockRepository))
|
||||
.register("eventBusService", asValue(EventBusServiceMock))
|
||||
// Register the real class for the service below to do the integration tests
|
||||
.register("taxCalculationStrategy", asClass(TaxCalculationStrategy))
|
||||
.register("taxProviderService", asClass(TaxProviderService))
|
||||
.register("newTotalsService", asClass(NewTotalsService))
|
||||
.register("cartService", asClass(CartService))
|
||||
|
||||
const cartService = container.resolve("cartService")
|
||||
|
||||
it("should decorate totals with a cart containing custom items", async () => {
|
||||
const cart = {
|
||||
id: IdMap.getId("cartWithPaySessions"),
|
||||
region_id: IdMap.getId("testRegion"),
|
||||
items: [
|
||||
{
|
||||
id: IdMap.getId("existingLine"),
|
||||
title: "merge line",
|
||||
description: "This is a new line",
|
||||
thumbnail: "test-img-yeah.com/thumb",
|
||||
variant_id: null,
|
||||
unit_price: 100,
|
||||
quantity: 10,
|
||||
},
|
||||
],
|
||||
shipping_address: {},
|
||||
billing_address: {},
|
||||
discounts: [],
|
||||
region: {
|
||||
tax_rate: 10,
|
||||
currency_code: "eur",
|
||||
},
|
||||
gift_cards: [],
|
||||
}
|
||||
|
||||
const totals = await cartService.decorateTotals(cart, {
|
||||
force_taxes: true,
|
||||
})
|
||||
|
||||
expect(totals.total).toEqual(1000)
|
||||
expect(totals.subtotal).toEqual(1000)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -112,13 +112,6 @@ export default class NewTotalsService extends TransactionBaseService {
|
||||
lineItemsTaxLinesMap[item.id] = item.tax_lines ?? []
|
||||
})
|
||||
} else {
|
||||
if (items.some((item) => !item.variant)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Unable to fetch tax lines to compute line item totals as one of the item variant is missing but required for the tax lines to be computed. Might be due to a missing relation items.variant"
|
||||
)
|
||||
}
|
||||
|
||||
const { lineItemsTaxLines } = await this.taxProviderService_
|
||||
.withTransaction(manager)
|
||||
.getTaxLinesMap(items, calculationContext)
|
||||
@@ -199,7 +192,7 @@ export default class NewTotalsService extends TransactionBaseService {
|
||||
? totals.tax_lines
|
||||
: (taxLines as LineItemTaxLine[])
|
||||
|
||||
if (!totals.tax_lines) {
|
||||
if (!totals.tax_lines && item.variant_id) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.UNEXPECTED_STATE,
|
||||
"Tax Lines must be joined to calculate taxes"
|
||||
@@ -208,7 +201,7 @@ export default class NewTotalsService extends TransactionBaseService {
|
||||
}
|
||||
|
||||
if (item.is_return) {
|
||||
if (!isDefined(item.tax_lines)) {
|
||||
if (!isDefined(item.tax_lines) && item.variant_id) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.UNEXPECTED_STATE,
|
||||
"Return Line Items must join tax lines"
|
||||
@@ -216,7 +209,7 @@ export default class NewTotalsService extends TransactionBaseService {
|
||||
}
|
||||
}
|
||||
|
||||
if (totals.tax_lines.length > 0) {
|
||||
if (totals.tax_lines?.length > 0) {
|
||||
totals.tax_total = await this.taxCalculationStrategy_.calculate(
|
||||
[item],
|
||||
totals.tax_lines,
|
||||
|
||||
@@ -263,7 +263,14 @@ class TaxProviderService extends TransactionBaseService {
|
||||
return null
|
||||
}
|
||||
|
||||
if (l.variant && l.variant.product_id) {
|
||||
if (l.variant_id && !l.variant) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Unable to get the tax lines for the item ${l.id}, it contains a variant_id but the variant is missing.`
|
||||
)
|
||||
}
|
||||
|
||||
if (l.variant?.product_id) {
|
||||
return {
|
||||
item: l,
|
||||
rates: await this.getRegionRatesForProduct(
|
||||
|
||||
Reference in New Issue
Block a user