fix(medusa): Order/Cart decorate totals should assign the items totals (#2546)

**What**

If `total` or `subtotal` are selected then get the line item totals and assign them to the items.

I also had to remove the totals from the cart update service since they are not used and that by having them the items get the tax lines attached and since the update is performed by passing the entire cart, it is trying to insert the tax lines with the cart update

**Tests**

Add an integration tests to validate that the items includes the totals in the order and draft order

FIXES CORE-687
This commit is contained in:
Adrien de Peretti authored and GitHub committed 2022-11-07 13:54:41 +00:00
1 parent 15d6f92964
commit 129ad4b687
9 files changed
+174 -74

No files matched your search

@@ -785,6 +785,40 @@ describe("/admin/draft-orders", () => {
}) })
}) })
describe("GET /admin/draft-orders/:id", () => {
beforeEach(async () => {
await adminSeeder(dbConnection)
await draftOrderSeeder(dbConnection)
})
afterEach(async () => {
const db = useDb()
await db.teardown()
})
it("retrieves a draft-order should include the items totals", async () => {
const api = useApi()
const order = await api.get("/admin/draft-orders/test-draft-order", {
headers: {
authorization: "Bearer test_token",
},
})
expect(order.status).toEqual(200)
expect(order.data.draft_order).toEqual(
expect.objectContaining({
id: "test-draft-order",
})
)
order.data.draft_order.cart.items.forEach((item) => {
expect(item.total).toBeDefined()
expect(item.subtotal).toBeDefined()
})
})
})
describe("DELETE /admin/draft-orders/:id", () => { describe("DELETE /admin/draft-orders/:id", () => {
beforeEach(async () => { beforeEach(async () => {
await adminSeeder(dbConnection) await adminSeeder(dbConnection)
@@ -2284,6 +2284,28 @@ describe("/admin/orders", () => {
) )
}) })
it("retrieves an order should include the items totals", async () => {
const api = useApi()
const order = await api.get("/admin/orders/test-order", {
headers: {
authorization: "Bearer test_token",
},
})
expect(order.status).toEqual(200)
expect(order.data.order).toEqual(
expect.objectContaining({
id: "test-order",
})
)
order.data.order.items.forEach((item) => {
expect(item.total).toBeDefined()
expect(item.subtotal).toBeDefined()
})
})
it("throws on invalid relation", async () => { it("throws on invalid relation", async () => {
const api = useApi() const api = useApi()
@@ -432,6 +432,7 @@ Object {
"claim_order_id": null, "claim_order_id": null,
"created_at": Any<Date>, "created_at": Any<Date>,
"description": "", "description": "",
"discount_total": 0,
"fulfilled_quantity": 2, "fulfilled_quantity": 2,
"has_shipping": null, "has_shipping": null,
"id": Any<String>, "id": Any<String>,
@@ -439,10 +440,13 @@ Object {
"is_return": false, "is_return": false,
"metadata": null, "metadata": null,
"order_id": Any<String>, "order_id": Any<String>,
"original_tax_total": 400,
"original_total": 2400,
"quantity": 2, "quantity": 2,
"returned_quantity": 1, "returned_quantity": 1,
"shipped_quantity": 2, "shipped_quantity": 2,
"should_merge": true, "should_merge": true,
"subtotal": 2000,
"swap_id": null, "swap_id": null,
"tax_lines": Array [ "tax_lines": Array [
Object { Object {
@@ -456,8 +460,10 @@ Object {
"updated_at": Any<Date>, "updated_at": Any<Date>,
}, },
], ],
"tax_total": 400,
"thumbnail": "", "thumbnail": "",
"title": "Intelligent Plastic Chips", "title": "Intelligent Plastic Chips",
"total": 2400,
"unit_price": 1000, "unit_price": 1000,
"updated_at": Any<Date>, "updated_at": Any<Date>,
"variant": Object { "variant": Object {
@@ -768,6 +774,7 @@ Object {
"claim_order_id": null, "claim_order_id": null,
"created_at": Any<Date>, "created_at": Any<Date>,
"description": "", "description": "",
"discount_total": 0,
"fulfilled_quantity": null, "fulfilled_quantity": null,
"has_shipping": null, "has_shipping": null,
"id": "test-item", "id": "test-item",
@@ -775,11 +782,14 @@ Object {
"is_return": false, "is_return": false,
"metadata": null, "metadata": null,
"order_id": Any<String>, "order_id": Any<String>,
"original_tax_total": 400,
"original_total": 2400,
"price": "10.00 USD", "price": "10.00 USD",
"quantity": 2, "quantity": 2,
"returned_quantity": null, "returned_quantity": null,
"shipped_quantity": null, "shipped_quantity": null,
"should_merge": true, "should_merge": true,
"subtotal": 2000,
"swap_id": null, "swap_id": null,
"tax_lines": Array [ "tax_lines": Array [
Object { Object {
@@ -793,8 +803,10 @@ Object {
"updated_at": Any<Date>, "updated_at": Any<Date>,
}, },
], ],
"tax_total": 400,
"thumbnail": null, "thumbnail": null,
"title": "Intelligent Plastic Chips", "title": "Intelligent Plastic Chips",
"total": 2400,
"unit_price": 1000, "unit_price": 1000,
"updated_at": Any<Date>, "updated_at": Any<Date>,
"variant": Object { "variant": Object {
@@ -991,6 +1003,7 @@ Object {
"claim_order_id": null, "claim_order_id": null,
"created_at": Any<Date>, "created_at": Any<Date>,
"description": "", "description": "",
"discount_total": 0,
"discounted_price": "12.00 USD", "discounted_price": "12.00 USD",
"fulfilled_quantity": 2, "fulfilled_quantity": 2,
"has_shipping": null, "has_shipping": null,
@@ -999,11 +1012,14 @@ Object {
"is_return": false, "is_return": false,
"metadata": null, "metadata": null,
"order_id": Any<String>, "order_id": Any<String>,
"original_tax_total": 400,
"original_total": 2400,
"price": "12.00 USD", "price": "12.00 USD",
"quantity": 2, "quantity": 2,
"returned_quantity": null, "returned_quantity": null,
"shipped_quantity": 2, "shipped_quantity": 2,
"should_merge": true, "should_merge": true,
"subtotal": 2000,
"swap_id": null, "swap_id": null,
"tax_lines": Array [ "tax_lines": Array [
Object { Object {
@@ -1017,8 +1033,10 @@ Object {
"updated_at": Any<Date>, "updated_at": Any<Date>,
}, },
], ],
"tax_total": 400,
"thumbnail": null, "thumbnail": null,
"title": "Intelligent Plastic Chips", "title": "Intelligent Plastic Chips",
"total": 2400,
"totals": Object { "totals": Object {
"discount_total": 0, "discount_total": 0,
"original_tax_total": 400, "original_tax_total": 400,
@@ -1258,6 +1276,7 @@ Object {
"claim_order_id": null, "claim_order_id": null,
"created_at": Any<Date>, "created_at": Any<Date>,
"description": "", "description": "",
"discount_total": 0,
"fulfilled_quantity": 2, "fulfilled_quantity": 2,
"has_shipping": null, "has_shipping": null,
"id": "test-item", "id": "test-item",
@@ -1265,10 +1284,13 @@ Object {
"is_return": false, "is_return": false,
"metadata": null, "metadata": null,
"order_id": Any<String>, "order_id": Any<String>,
"original_tax_total": 400,
"original_total": 2400,
"quantity": 2, "quantity": 2,
"returned_quantity": null, "returned_quantity": null,
"shipped_quantity": 2, "shipped_quantity": 2,
"should_merge": true, "should_merge": true,
"subtotal": 2000,
"swap_id": null, "swap_id": null,
"tax_lines": Array [ "tax_lines": Array [
Object { Object {
@@ -1282,8 +1304,10 @@ Object {
"updated_at": Any<Date>, "updated_at": Any<Date>,
}, },
], ],
"tax_total": 400,
"thumbnail": "", "thumbnail": "",
"title": "Intelligent Plastic Chips", "title": "Intelligent Plastic Chips",
"total": 2400,
"unit_price": 1000, "unit_price": 1000,
"updated_at": Any<Date>, "updated_at": Any<Date>,
"variant": Object { "variant": Object {
@@ -1579,6 +1603,7 @@ Object {
"claim_order_id": null, "claim_order_id": null,
"created_at": Any<Date>, "created_at": Any<Date>,
"description": "", "description": "",
"discount_total": 0,
"fulfilled_quantity": 2, "fulfilled_quantity": 2,
"has_shipping": null, "has_shipping": null,
"id": Any<String>, "id": Any<String>,
@@ -1586,10 +1611,13 @@ Object {
"is_return": false, "is_return": false,
"metadata": null, "metadata": null,
"order_id": Any<String>, "order_id": Any<String>,
"original_tax_total": 400,
"original_total": 2400,
"quantity": 2, "quantity": 2,
"returned_quantity": null, "returned_quantity": null,
"shipped_quantity": 2, "shipped_quantity": 2,
"should_merge": true, "should_merge": true,
"subtotal": 2000,
"swap_id": null, "swap_id": null,
"tax_lines": Array [ "tax_lines": Array [
Object { Object {
@@ -1603,8 +1631,10 @@ Object {
"updated_at": Any<Date>, "updated_at": Any<Date>,
}, },
], ],
"tax_total": 400,
"thumbnail": "", "thumbnail": "",
"title": "Intelligent Plastic Chips", "title": "Intelligent Plastic Chips",
"total": 2400,
"unit_price": 1000, "unit_price": 1000,
"updated_at": Any<Date>, "updated_at": Any<Date>,
"variant": Object { "variant": Object {
@@ -1,6 +1,5 @@
import { CartService, DraftOrderService } from "../../../../services" import { CartService, DraftOrderService } from "../../../../services"
import { import {
defaultAdminDraftOrdersCartFields,
defaultAdminDraftOrdersCartRelations, defaultAdminDraftOrdersCartRelations,
defaultAdminDraftOrdersFields, defaultAdminDraftOrdersFields,
defaultAdminDraftOrdersRelations, defaultAdminDraftOrdersRelations,
@@ -72,9 +71,8 @@ export default async (req, res) => {
relations: defaultAdminDraftOrdersRelations, relations: defaultAdminDraftOrdersRelations,
}) })
draftOrder.cart = await cartService.retrieve(draftOrder.cart_id, { draftOrder.cart = await cartService.retrieveWithTotals(draftOrder.cart_id, {
relations: defaultAdminDraftOrdersCartRelations, relations: defaultAdminDraftOrdersCartRelations,
select: defaultAdminDraftOrdersCartFields,
}) })
res.json({ draft_order: draftOrder }) res.json({ draft_order: draftOrder })
@@ -37,6 +37,9 @@ export const TotalsServiceMock = {
getCalculationContext: jest.fn().mockImplementation((order, lineItems) => { getCalculationContext: jest.fn().mockImplementation((order, lineItems) => {
return Promise.resolve({}) return Promise.resolve({})
}), }),
getLineItemTotals: jest.fn().mockImplementation(() => {
return Promise.resolve({})
}),
} }
const mock = jest.fn().mockImplementation(() => { const mock = jest.fn().mockImplementation(() => {
+55 -64
View File
@@ -5,6 +5,7 @@ import CartService from "../cart"
import { InventoryServiceMock } from "../__mocks__/inventory" import { InventoryServiceMock } from "../__mocks__/inventory"
import { LineItemAdjustmentServiceMock } from "../__mocks__/line-item-adjustment" import { LineItemAdjustmentServiceMock } from "../__mocks__/line-item-adjustment"
import { FlagRouter } from "../../utils/flag-router" import { FlagRouter } from "../../utils/flag-router"
import { taxProviderServiceMock } from "../__mocks__/tax-provider"
const eventBusService = { const eventBusService = {
emit: jest.fn(), emit: jest.fn(),
@@ -57,6 +58,7 @@ describe("CartService", () => {
manager: MockManager, manager: MockManager,
totalsService, totalsService,
cartRepository, cartRepository,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
result = await cartService.retrieve(IdMap.getId("emptyCart")) result = await cartService.retrieve(IdMap.getId("emptyCart"))
@@ -90,6 +92,7 @@ describe("CartService", () => {
totalsService, totalsService,
cartRepository, cartRepository,
eventBusService, eventBusService,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -179,6 +182,7 @@ describe("CartService", () => {
customerService, customerService,
regionService, regionService,
eventBusService, eventBusService,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -352,6 +356,7 @@ describe("CartService", () => {
inventoryService, inventoryService,
productVariantService, productVariantService,
lineItemAdjustmentService: LineItemAdjustmentServiceMock, lineItemAdjustmentService: LineItemAdjustmentServiceMock,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -585,6 +590,7 @@ describe("CartService", () => {
inventoryService, inventoryService,
productVariantService, productVariantService,
lineItemAdjustmentService: LineItemAdjustmentServiceMock, lineItemAdjustmentService: LineItemAdjustmentServiceMock,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({ sales_channels: true }), featureFlagRouter: new FlagRouter({ sales_channels: true }),
}) })
@@ -680,6 +686,7 @@ describe("CartService", () => {
shippingOptionService, shippingOptionService,
eventBusService, eventBusService,
lineItemAdjustmentService: LineItemAdjustmentServiceMock, lineItemAdjustmentService: LineItemAdjustmentServiceMock,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -786,6 +793,7 @@ describe("CartService", () => {
cartRepository, cartRepository,
totalsService, totalsService,
eventBusService, eventBusService,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -798,7 +806,7 @@ describe("CartService", () => {
await cartService.update("withpays", {}) await cartService.update("withpays", {})
expect(cartRepository.findOneWithRelations).toHaveBeenCalledWith( expect(cartRepository.findOneWithRelations).toHaveBeenCalledWith(
[ expect.arrayContaining([
"items", "items",
"shipping_methods", "shipping_methods",
"shipping_address", "shipping_address",
@@ -811,9 +819,7 @@ describe("CartService", () => {
"discounts", "discounts",
"discounts.rule", "discounts.rule",
"discounts.regions", "discounts.regions",
"items.tax_lines", ]),
"region.tax_rates",
],
{ {
where: { id: "withpays" }, where: { id: "withpays" },
} }
@@ -876,6 +882,7 @@ describe("CartService", () => {
eventBusService, eventBusService,
inventoryService, inventoryService,
lineItemAdjustmentService: LineItemAdjustmentServiceMock, lineItemAdjustmentService: LineItemAdjustmentServiceMock,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -958,6 +965,7 @@ describe("CartService", () => {
cartRepository, cartRepository,
eventBusService, eventBusService,
customerService, customerService,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -977,19 +985,16 @@ describe("CartService", () => {
) )
expect(cartRepository.save).toHaveBeenCalledTimes(1) expect(cartRepository.save).toHaveBeenCalledTimes(1)
expect(cartRepository.save).toHaveBeenCalledWith({ expect(cartRepository.save).toHaveBeenCalledWith(
expect.objectContaining({
customer_id: IdMap.getId("existing"), customer_id: IdMap.getId("existing"),
customer: { customer: {
id: IdMap.getId("existing"), id: IdMap.getId("existing"),
email: "test@testdom.com", email: "test@testdom.com",
}, },
email: "test@testdom.com", email: "test@testdom.com",
discount_total: 0,
shipping_total: 0,
subtotal: 0,
tax_total: 0,
total: 0,
}) })
)
}) })
it("creates a new customer", async () => { it("creates a new customer", async () => {
@@ -1004,16 +1009,13 @@ describe("CartService", () => {
) )
expect(cartRepository.save).toHaveBeenCalledTimes(1) expect(cartRepository.save).toHaveBeenCalledTimes(1)
expect(cartRepository.save).toHaveBeenCalledWith({ expect(cartRepository.save).toHaveBeenCalledWith(
expect.objectContaining({
customer_id: IdMap.getId("newCus"), customer_id: IdMap.getId("newCus"),
customer: { id: IdMap.getId("newCus"), email: "no@mail.com" }, customer: { id: IdMap.getId("newCus"), email: "no@mail.com" },
email: "no@mail.com", email: "no@mail.com",
discount_total: 0,
shipping_total: 0,
subtotal: 0,
tax_total: 0,
total: 0,
}) })
)
}) })
it("throws on invalid email", async () => { it("throws on invalid email", async () => {
@@ -1039,6 +1041,7 @@ describe("CartService", () => {
cartRepository, cartRepository,
addressRepository, addressRepository,
eventBusService, eventBusService,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -1074,15 +1077,12 @@ describe("CartService", () => {
country_code: "us", country_code: "us",
}) })
expect(cartRepository.save).toHaveBeenCalledWith({ expect(cartRepository.save).toHaveBeenCalledWith(
expect.objectContaining({
region: { countries: [{ iso_2: "us" }] }, region: { countries: [{ iso_2: "us" }] },
discount_total: 0,
shipping_total: 0,
subtotal: 0,
tax_total: 0,
total: 0,
billing_address: address, billing_address: address,
}) })
)
}) })
}) })
@@ -1101,6 +1101,7 @@ describe("CartService", () => {
totalsService, totalsService,
cartRepository, cartRepository,
eventBusService, eventBusService,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -1135,15 +1136,12 @@ describe("CartService", () => {
...address, ...address,
}) })
expect(cartRepository.save).toHaveBeenCalledWith({ expect(cartRepository.save).toHaveBeenCalledWith(
expect.objectContaining({
region: { countries: [{ iso_2: "us" }] }, region: { countries: [{ iso_2: "us" }] },
discount_total: 0,
shipping_total: 0,
subtotal: 0,
tax_total: 0,
total: 0,
shipping_address: address, shipping_address: address,
}) })
)
}) })
it("throws if country not in region", async () => { it("throws if country not in region", async () => {
@@ -1256,6 +1254,7 @@ describe("CartService", () => {
eventBusService, eventBusService,
paymentSessionRepository: MockRepository(), paymentSessionRepository: MockRepository(),
priceSelectionStrategy: priceSelectionStrat, priceSelectionStrategy: priceSelectionStrat,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -1287,7 +1286,8 @@ describe("CartService", () => {
) )
expect(cartRepository.save).toHaveBeenCalledTimes(1) expect(cartRepository.save).toHaveBeenCalledTimes(1)
expect(cartRepository.save).toHaveBeenCalledWith({ expect(cartRepository.save).toHaveBeenCalledWith(
expect.objectContaining({
region_id: "region", region_id: "region",
region: { region: {
id: "region", id: "region",
@@ -1300,11 +1300,6 @@ describe("CartService", () => {
payment_session: null, payment_session: null,
payment_sessions: [], payment_sessions: [],
gift_cards: [], gift_cards: [],
discount_total: 0,
shipping_total: 0,
subtotal: 0,
tax_total: 0,
total: 0,
discounts: [ discounts: [
{ {
id: IdMap.getId("stays"), id: IdMap.getId("stays"),
@@ -1312,6 +1307,7 @@ describe("CartService", () => {
}, },
], ],
}) })
)
}) })
}) })
@@ -1326,6 +1322,8 @@ describe("CartService", () => {
}, },
], ],
}, },
items: [],
shipping_methods: [],
payment_sessions: [ payment_sessions: [
{ {
id: IdMap.getId("test-session"), id: IdMap.getId("test-session"),
@@ -1344,6 +1342,7 @@ describe("CartService", () => {
totalsService, totalsService,
cartRepository, cartRepository,
eventBusService, eventBusService,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -1380,6 +1379,7 @@ describe("CartService", () => {
const cart1 = { const cart1 = {
total: 100, total: 100,
items: [{ subtotal: 100 }], items: [{ subtotal: 100 }],
shipping_methods: [],
payment_sessions: [], payment_sessions: [],
region: { region: {
payment_providers: [{ id: "provider_1" }, { id: "provider_2" }], payment_providers: [{ id: "provider_1" }, { id: "provider_2" }],
@@ -1388,6 +1388,8 @@ describe("CartService", () => {
const cart2 = { const cart2 = {
total: 100, total: 100,
items: [],
shipping_methods: [],
payment_sessions: [{ provider_id: "provider_1" }], payment_sessions: [{ provider_id: "provider_1" }],
region: { region: {
payment_providers: [{ id: "provider_1" }, { id: "provider_2" }], payment_providers: [{ id: "provider_1" }, { id: "provider_2" }],
@@ -1464,6 +1466,7 @@ describe("CartService", () => {
cartRepository, cartRepository,
paymentProviderService, paymentProviderService,
eventBusService, eventBusService,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -1655,6 +1658,7 @@ describe("CartService", () => {
lineItemService, lineItemService,
eventBusService, eventBusService,
customShippingOptionService, customShippingOptionService,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -2010,6 +2014,7 @@ describe("CartService", () => {
discountService, discountService,
eventBusService, eventBusService,
lineItemAdjustmentService: LineItemAdjustmentServiceMock, lineItemAdjustmentService: LineItemAdjustmentServiceMock,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -2032,14 +2037,10 @@ describe("CartService", () => {
) )
expect(cartRepository.save).toHaveBeenCalledTimes(1) expect(cartRepository.save).toHaveBeenCalledTimes(1)
expect(cartRepository.save).toHaveBeenCalledWith({ expect(cartRepository.save).toHaveBeenCalledWith(
expect.objectContaining({
id: IdMap.getId("cart"), id: IdMap.getId("cart"),
region_id: IdMap.getId("good"), region_id: IdMap.getId("good"),
discount_total: 0,
shipping_total: 0,
subtotal: 0,
tax_total: 0,
total: 0,
items: [ items: [
{ {
id: "li1", id: "li1",
@@ -2063,6 +2064,7 @@ describe("CartService", () => {
}, },
], ],
}) })
)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1) expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({ expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({
@@ -2085,14 +2087,10 @@ describe("CartService", () => {
}) })
expect(cartRepository.save).toHaveBeenCalledTimes(1) expect(cartRepository.save).toHaveBeenCalledTimes(1)
expect(cartRepository.save).toHaveBeenCalledWith({ expect(cartRepository.save).toHaveBeenCalledWith(
expect.objectContaining({
id: IdMap.getId("cart"), id: IdMap.getId("cart"),
region_id: IdMap.getId("good"), region_id: IdMap.getId("good"),
discount_total: 0,
shipping_total: 0,
subtotal: 0,
tax_total: 0,
total: 0,
items: [ items: [
{ {
id: "li1", id: "li1",
@@ -2116,6 +2114,7 @@ describe("CartService", () => {
}, },
], ],
}) })
)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1) expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({ expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({
@@ -2139,7 +2138,8 @@ describe("CartService", () => {
expect(discountService.retrieveByCode).toHaveBeenCalledTimes(2) expect(discountService.retrieveByCode).toHaveBeenCalledTimes(2)
expect(cartRepository.save).toHaveBeenCalledTimes(1) expect(cartRepository.save).toHaveBeenCalledTimes(1)
expect(cartRepository.save).toHaveBeenCalledWith({ expect(cartRepository.save).toHaveBeenCalledWith(
expect.objectContaining({
id: IdMap.getId("cart"), id: IdMap.getId("cart"),
discounts: [ discounts: [
{ {
@@ -2171,13 +2171,9 @@ describe("CartService", () => {
unit_price: 500, unit_price: 500,
}, },
], ],
discount_total: 0,
shipping_total: 0,
subtotal: 0,
tax_total: 0,
total: 0,
region_id: IdMap.getId("good"), region_id: IdMap.getId("good"),
}) })
)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1) expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledTimes(1)
expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({ expect(LineItemAdjustmentServiceMock.delete).toHaveBeenCalledWith({
@@ -2209,14 +2205,10 @@ describe("CartService", () => {
) )
expect(cartRepository.save).toHaveBeenCalledTimes(1) expect(cartRepository.save).toHaveBeenCalledTimes(1)
expect(cartRepository.save).toHaveBeenCalledWith({ expect(cartRepository.save).toHaveBeenCalledWith(
expect.objectContaining({
id: "with-d-and-customer", id: "with-d-and-customer",
region_id: IdMap.getId("good"), region_id: IdMap.getId("good"),
discount_total: 0,
shipping_total: 0,
subtotal: 0,
tax_total: 0,
total: 0,
discounts: [ discounts: [
{ {
id: "ApplicableForCustomer", id: "ApplicableForCustomer",
@@ -2231,6 +2223,7 @@ describe("CartService", () => {
}, },
], ],
}) })
)
}) })
it("successfully remove all discounts that have been applied", async () => { it("successfully remove all discounts that have been applied", async () => {
@@ -2244,14 +2237,10 @@ describe("CartService", () => {
) )
expect(cartRepository.save).toHaveBeenCalledTimes(1) expect(cartRepository.save).toHaveBeenCalledTimes(1)
expect(cartRepository.save).toHaveBeenCalledWith({ expect(cartRepository.save).toHaveBeenCalledWith(
expect.objectContaining({
id: IdMap.getId("cart"), id: IdMap.getId("cart"),
region_id: IdMap.getId("good"), region_id: IdMap.getId("good"),
discount_total: 0,
shipping_total: 0,
subtotal: 0,
tax_total: 0,
total: 0,
items: [ items: [
{ {
id: "li1", id: "li1",
@@ -2266,6 +2255,7 @@ describe("CartService", () => {
], ],
discounts: [], discounts: [],
}) })
)
}) })
}) })
@@ -2298,6 +2288,7 @@ describe("CartService", () => {
totalsService, totalsService,
cartRepository, cartRepository,
eventBusService, eventBusService,
taxProviderService: taxProviderServiceMock,
featureFlagRouter: new FlagRouter({}), featureFlagRouter: new FlagRouter({}),
}) })
@@ -8,6 +8,12 @@ describe("OrderService", () => {
withTransaction: function () { withTransaction: function () {
return this return this
}, },
getCalculationContext: jest.fn().mockImplementation((order, lineItems) => {
return Promise.resolve({})
}),
getLineItemTotals: jest.fn().mockImplementation(() => {
return Promise.resolve({})
}),
getLineItemRefund: () => {}, getLineItemRefund: () => {},
getTotal: (o) => { getTotal: (o) => {
return o.total || 0 return o.total || 0
@@ -1249,6 +1255,7 @@ describe("OrderService", () => {
{ {
order: { order: {
id: IdMap.getId("order"), id: IdMap.getId("order"),
items: [],
shipping_methods: [ shipping_methods: [
{ {
shipping_option: { shipping_option: {
@@ -1278,6 +1285,7 @@ describe("OrderService", () => {
{ {
order: { order: {
id: IdMap.getId("order"), id: IdMap.getId("order"),
items: [],
shipping_methods: [ shipping_methods: [
{ {
shipping_option: { shipping_option: {
-7
View File
@@ -920,13 +920,6 @@ class CartService extends TransactionBaseService {
} }
const cart = await this.retrieve(cartId, { const cart = await this.retrieve(cartId, {
select: [
"subtotal",
"tax_total",
"shipping_total",
"discount_total",
"total",
],
relations, relations,
}) })
+21
View File
@@ -1412,6 +1412,27 @@ class OrderService extends TransactionBaseService {
order: Order, order: Order,
totalsFields: string[] = [] totalsFields: string[] = []
): Promise<Order> { ): Promise<Order> {
if (totalsFields.some((field) => ["subtotal", "total"].includes(field))) {
const calculationContext =
await this.totalsService_.getCalculationContext(order, {
exclude_shipping: true,
})
order.items = await Promise.all(
(order.items || []).map(async (item) => {
const itemTotals = await this.totalsService_.getLineItemTotals(
item,
order,
{
include_tax: true,
calculation_context: calculationContext,
}
)
return Object.assign(item, itemTotals)
})
)
}
for (const totalField of totalsFields) { for (const totalField of totalsFields) {
switch (totalField) { switch (totalField) {
case "shipping_total": { case "shipping_total": {