Feat(orders,utils, cart): orders get endpoints and cart totals (#7010)

This commit is contained in:
Carlos R. L. Rodrigues
2024-04-22 11:01:18 +02:00
committed by GitHub
parent 89143e1032
commit cc557c8752
23 changed files with 2411 additions and 30 deletions
+9
View File
@@ -0,0 +1,9 @@
---
"@medusajs/medusa": patch
"@medusajs/order": patch
"@medusajs/types": patch
"@medusajs/utils": patch
"@medusajs/cart": patch
---
Order endpoints and Cart totals
@@ -0,0 +1,484 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import {
ICartModuleService,
ICustomerModuleService,
IFulfillmentModuleService,
IInventoryServiceNext,
IOrderModuleService,
IPaymentModuleService,
IPricingModuleService,
IProductModuleService,
IRegionModuleService,
ISalesChannelModuleService,
IStockLocationServiceNext,
ITaxModuleService,
} from "@medusajs/types"
import { ContainerRegistrationKeys } from "@medusajs/utils"
import { medusaIntegrationTestRunner } from "medusa-test-utils"
import {
adminHeaders,
createAdminUser,
} from "../../../helpers/create-admin-user"
jest.setTimeout(50000)
const env = { MEDUSA_FF_MEDUSA_V2: true }
medusaIntegrationTestRunner({
debug: true,
env,
testSuite: ({ dbConnection, getContainer, api }) => {
let appContainer
let cartModuleService: ICartModuleService
let regionModuleService: IRegionModuleService
let scModuleService: ISalesChannelModuleService
let customerModule: ICustomerModuleService
let productModule: IProductModuleService
let pricingModule: IPricingModuleService
let paymentModule: IPaymentModuleService
let inventoryModule: IInventoryServiceNext
let stockLocationModule: IStockLocationServiceNext
let fulfillmentModule: IFulfillmentModuleService
let locationModule: IStockLocationServiceNext
let taxModule: ITaxModuleService
let orderModule: IOrderModuleService
let remoteLink, remoteQuery
beforeAll(async () => {
appContainer = getContainer()
cartModuleService = appContainer.resolve(ModuleRegistrationName.CART)
regionModuleService = appContainer.resolve(ModuleRegistrationName.REGION)
scModuleService = appContainer.resolve(
ModuleRegistrationName.SALES_CHANNEL
)
customerModule = appContainer.resolve(ModuleRegistrationName.CUSTOMER)
productModule = appContainer.resolve(ModuleRegistrationName.PRODUCT)
pricingModule = appContainer.resolve(ModuleRegistrationName.PRICING)
paymentModule = appContainer.resolve(ModuleRegistrationName.PAYMENT)
inventoryModule = appContainer.resolve(ModuleRegistrationName.INVENTORY)
stockLocationModule = appContainer.resolve(
ModuleRegistrationName.STOCK_LOCATION
)
fulfillmentModule = appContainer.resolve(
ModuleRegistrationName.FULFILLMENT
)
locationModule = appContainer.resolve(
ModuleRegistrationName.STOCK_LOCATION
)
taxModule = appContainer.resolve(ModuleRegistrationName.TAX)
remoteLink = appContainer.resolve(ContainerRegistrationKeys.REMOTE_LINK)
remoteQuery = appContainer.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
orderModule = appContainer.resolve(ModuleRegistrationName.ORDER)
})
beforeEach(async () => {
await createAdminUser(dbConnection, adminHeaders, appContainer)
})
describe("Orders - Admin", () => {
it("should get an order", async () => {
const created = await orderModule.create({
region_id: "test_region_idclear",
email: "foo@bar.com",
items: [
{
title: "Custom Item 2",
quantity: 1,
unit_price: 50,
adjustments: [
{
code: "VIP_25 ETH",
amount: "0.000000000000000005",
description: "VIP discount",
promotion_id: "prom_123",
provider_id: "coupon_kings",
},
],
},
],
sales_channel_id: "test",
shipping_address: {
first_name: "Test",
last_name: "Test",
address_1: "Test",
city: "Test",
country_code: "US",
postal_code: "12345",
phone: "12345",
},
billing_address: {
first_name: "Test",
last_name: "Test",
address_1: "Test",
city: "Test",
country_code: "US",
postal_code: "12345",
},
shipping_methods: [
{
name: "Test shipping method",
amount: 10,
data: {},
tax_lines: [
{
description: "shipping Tax 1",
tax_rate_id: "tax_usa_shipping",
code: "code",
rate: 10,
},
],
adjustments: [
{
code: "VIP_10",
amount: 1,
description: "VIP discount",
promotion_id: "prom_123",
},
],
},
],
currency_code: "usd",
customer_id: "joe",
})
const response = await api.get(
"/admin/orders/" +
created.id +
"?fields=%2Braw_total,%2Braw_subtotal,%2Braw_discount_total",
adminHeaders
)
const order = response.data.order
expect(order).toEqual({
id: expect.any(String),
status: "pending",
version: 1,
summary: {
total: 50,
},
total: 59.8,
subtotal: 50,
tax_total: 0.9,
discount_total: 1,
discount_tax_total: 0.1,
original_total: 61,
original_tax_total: 1,
item_total: 50,
item_subtotal: 50,
item_tax_total: 0,
original_item_total: 50,
original_item_subtotal: 50,
original_item_tax_total: 0,
shipping_total: 9.9,
shipping_subtotal: 10,
shipping_tax_total: 0.9,
original_shipping_tax_total: 1,
original_shipping_tax_subtotal: 10,
original_shipping_total: 11,
created_at: expect.any(String),
updated_at: expect.any(String),
raw_total: {
value: "59.799999999999999995",
precision: 20,
},
raw_subtotal: {
value: "50",
precision: 20,
},
raw_discount_total: {
value: "1.000000000000000005",
precision: 20,
},
items: [
{
id: expect.any(String),
title: "Custom Item 2",
subtitle: null,
thumbnail: null,
variant_id: null,
product_id: null,
product_title: null,
product_description: null,
product_subtitle: null,
product_type: null,
product_collection: null,
product_handle: null,
variant_sku: null,
variant_barcode: null,
variant_title: null,
variant_option_values: null,
requires_shipping: true,
is_discountable: true,
is_tax_inclusive: false,
raw_compare_at_unit_price: null,
raw_unit_price: {
value: "50",
precision: 20,
},
metadata: null,
created_at: expect.any(String),
updated_at: expect.any(String),
tax_lines: [],
adjustments: [
{
id: expect.any(String),
description: "VIP discount",
promotion_id: expect.any(String),
code: "VIP_25 ETH",
raw_amount: {
value: "5.0000000000000000000e-18",
precision: 20,
},
provider_id: expect.any(String),
created_at: expect.any(String),
updated_at: expect.any(String),
item_id: expect.any(String),
amount: 5e-18,
subtotal: 5e-18,
total: 5e-18,
raw_subtotal: {
value: "5.0000000000000000000e-18",
precision: 20,
},
raw_total: {
value: "5.0000000000000000000e-18",
precision: 20,
},
},
],
compare_at_unit_price: null,
unit_price: 50,
quantity: 1,
raw_quantity: {
value: "1",
precision: 20,
},
detail: {
id: expect.any(String),
order_id: expect.any(String),
version: 1,
item_id: expect.any(String),
raw_quantity: {
value: "1",
precision: 20,
},
raw_fulfilled_quantity: {
value: "0",
precision: 20,
},
raw_shipped_quantity: {
value: "0",
precision: 20,
},
raw_return_requested_quantity: {
value: "0",
precision: 20,
},
raw_return_received_quantity: {
value: "0",
precision: 20,
},
raw_return_dismissed_quantity: {
value: "0",
precision: 20,
},
raw_written_off_quantity: {
value: "0",
precision: 20,
},
metadata: null,
created_at: expect.any(String),
updated_at: expect.any(String),
quantity: 1,
fulfilled_quantity: 0,
shipped_quantity: 0,
return_requested_quantity: 0,
return_received_quantity: 0,
return_dismissed_quantity: 0,
written_off_quantity: 0,
},
subtotal: 50,
total: 50,
original_total: 50,
discount_total: 5e-18,
discount_tax_total: 0,
tax_total: 0,
original_tax_total: 0,
raw_subtotal: {
value: "50",
precision: 20,
},
raw_total: {
value: "49.999999999999999995",
precision: 20,
},
raw_original_total: {
value: "50",
precision: 20,
},
raw_discount_total: {
value: "5.0000000000000000000e-18",
precision: 20,
},
raw_discount_tax_total: {
value: "0",
precision: 20,
},
raw_tax_total: {
value: "0",
precision: 20,
},
raw_original_tax_total: {
value: "0",
precision: 20,
},
},
],
shipping_address: {
id: expect.any(String),
customer_id: null,
company: null,
first_name: "Test",
last_name: "Test",
address_1: "Test",
address_2: null,
city: "Test",
country_code: "US",
province: null,
postal_code: "12345",
phone: "12345",
metadata: null,
created_at: expect.any(String),
updated_at: expect.any(String),
},
billing_address: {
id: expect.any(String),
customer_id: null,
company: null,
first_name: "Test",
last_name: "Test",
address_1: "Test",
address_2: null,
city: "Test",
country_code: "US",
province: null,
postal_code: "12345",
phone: null,
metadata: null,
created_at: expect.any(String),
updated_at: expect.any(String),
},
shipping_methods: [
{
id: expect.any(String),
order_id: expect.any(String),
version: 1,
name: "Test shipping method",
description: null,
raw_amount: {
value: "10",
precision: 20,
},
is_tax_inclusive: false,
shipping_option_id: null,
data: {},
metadata: null,
created_at: expect.any(String),
updated_at: expect.any(String),
tax_lines: [
{
id: expect.any(String),
description: "shipping Tax 1",
tax_rate_id: expect.any(String),
code: "code",
raw_rate: {
value: "10",
precision: 20,
},
provider_id: null,
created_at: expect.any(String),
updated_at: expect.any(String),
shipping_method_id: expect.any(String),
rate: 10,
total: 0.9,
subtotal: 1,
raw_total: {
value: "0.9",
precision: 20,
},
raw_subtotal: {
value: "1",
precision: 20,
},
},
],
adjustments: [
{
id: expect.any(String),
description: "VIP discount",
promotion_id: expect.any(String),
code: "VIP_10",
raw_amount: {
value: "1",
precision: 20,
},
provider_id: null,
created_at: expect.any(String),
updated_at: expect.any(String),
shipping_method_id: expect.any(String),
amount: 1,
subtotal: 1,
total: 1.1,
raw_subtotal: {
value: "1",
precision: 20,
},
raw_total: {
value: "1.1",
precision: 20,
},
},
],
amount: 10,
subtotal: 10,
total: 9.9,
original_total: 11,
discount_total: 1,
discount_tax_total: 0.1,
tax_total: 0.9,
original_tax_total: 1,
raw_subtotal: {
value: "10",
precision: 20,
},
raw_total: {
value: "9.9",
precision: 20,
},
raw_original_total: {
value: "11",
precision: 20,
},
raw_discount_total: {
value: "1",
precision: 20,
},
raw_discount_tax_total: {
value: "0.1",
precision: 20,
},
raw_tax_total: {
value: "0.9",
precision: 20,
},
raw_original_tax_total: {
value: "1",
precision: 20,
},
},
],
})
})
})
},
})
@@ -1,5 +1,6 @@
import { Modules } from "@medusajs/modules-sdk"
import { ICartModuleService } from "@medusajs/types"
import { BigNumber } from "@medusajs/utils"
import { CheckConstraintViolationException } from "@mikro-orm/core"
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
@@ -2341,5 +2342,409 @@ moduleIntegrationTestRunner({
})
})
})
it("should calculate totals of a cart", async () => {
const [createdCart] = await service.create([
{
currency_code: "eur",
},
])
const [itemOne] = await service.addLineItems(createdCart.id, [
{
quantity: 1,
unit_price: 100,
title: "test",
},
])
const [itemTwo] = await service.addLineItems(createdCart.id, [
{
quantity: 2,
unit_price: 200,
title: "test-2",
},
])
await service.setLineItemAdjustments(createdCart.id, [
{
item_id: itemOne.id,
amount: 100,
code: "FREE",
},
{
item_id: itemTwo.id,
amount: 200,
code: "FREE-2",
},
])
await service.addShippingMethods(createdCart.id, [
{
amount: 10,
name: "Test",
},
])
const cart = await service.retrieve(createdCart.id, { select: ["total"] })
expect(cart.total).toBeInstanceOf(BigNumber)
const asJson = JSON.parse(JSON.stringify(cart))
expect(asJson).toEqual({
id: createdCart.id,
items: [
{
id: itemOne.id,
cart_id: createdCart.id,
title: "test",
subtitle: null,
thumbnail: null,
quantity: 1,
variant_id: null,
product_id: null,
product_title: null,
product_description: null,
product_subtitle: null,
product_type: null,
product_collection: null,
product_handle: null,
variant_sku: null,
variant_barcode: null,
variant_title: null,
variant_option_values: null,
requires_shipping: true,
is_discountable: true,
is_tax_inclusive: false,
raw_compare_at_unit_price: null,
raw_unit_price: {
value: "100",
precision: 20,
},
metadata: null,
created_at: expect.any(String),
updated_at: expect.any(String),
deleted_at: null,
tax_lines: [],
adjustments: [
{
id: expect.any(String),
description: null,
code: "FREE",
raw_amount: {
value: "100",
precision: 20,
},
provider_id: null,
metadata: null,
created_at: expect.any(String),
updated_at: expect.any(String),
item_id: expect.any(String),
promotion_id: null,
deleted_at: null,
amount: 100,
subtotal: 100,
total: 100,
raw_subtotal: {
value: "100",
precision: 20,
},
raw_total: {
value: "100",
precision: 20,
},
},
],
compare_at_unit_price: null,
unit_price: 100,
subtotal: 100,
total: 0,
original_total: 100,
discount_total: 100,
discount_tax_total: 0,
tax_total: 0,
original_tax_total: 0,
raw_subtotal: {
value: "100",
precision: 20,
},
raw_total: {
value: "0",
precision: 20,
},
raw_original_total: {
value: "100",
precision: 20,
},
raw_discount_total: {
value: "100",
precision: 20,
},
raw_discount_tax_total: {
value: "0",
precision: 20,
},
raw_tax_total: {
value: "0",
precision: 20,
},
raw_original_tax_total: {
value: "0",
precision: 20,
},
},
{
id: itemTwo.id,
cart_id: createdCart.id,
title: "test-2",
subtitle: null,
thumbnail: null,
quantity: 2,
variant_id: null,
product_id: null,
product_title: null,
product_description: null,
product_subtitle: null,
product_type: null,
product_collection: null,
product_handle: null,
variant_sku: null,
variant_barcode: null,
variant_title: null,
variant_option_values: null,
requires_shipping: true,
is_discountable: true,
is_tax_inclusive: false,
raw_compare_at_unit_price: null,
raw_unit_price: {
value: "200",
precision: 20,
},
metadata: null,
created_at: expect.any(String),
updated_at: expect.any(String),
deleted_at: null,
tax_lines: [],
adjustments: [
{
id: expect.any(String),
description: null,
code: "FREE-2",
raw_amount: {
value: "200",
precision: 20,
},
provider_id: null,
metadata: null,
created_at: expect.any(String),
updated_at: expect.any(String),
item_id: expect.any(String),
promotion_id: null,
deleted_at: null,
amount: 200,
subtotal: 200,
total: 200,
raw_subtotal: {
value: "200",
precision: 20,
},
raw_total: {
value: "200",
precision: 20,
},
},
],
compare_at_unit_price: null,
unit_price: 200,
subtotal: 400,
total: 200,
original_total: 400,
discount_total: 200,
discount_tax_total: 0,
tax_total: 0,
original_tax_total: 0,
raw_subtotal: {
value: "400",
precision: 20,
},
raw_total: {
value: "200",
precision: 20,
},
raw_original_total: {
value: "400",
precision: 20,
},
raw_discount_total: {
value: "200",
precision: 20,
},
raw_discount_tax_total: {
value: "0",
precision: 20,
},
raw_tax_total: {
value: "0",
precision: 20,
},
raw_original_tax_total: {
value: "0",
precision: 20,
},
},
],
shipping_methods: [
{
id: expect.any(String),
cart_id: expect.any(String),
name: "Test",
description: null,
raw_amount: {
value: "10",
precision: 20,
},
is_tax_inclusive: false,
shipping_option_id: null,
data: null,
metadata: null,
created_at: expect.any(String),
updated_at: expect.any(String),
deleted_at: null,
tax_lines: [],
adjustments: [],
amount: 10,
subtotal: 10,
total: 10,
original_total: 10,
discount_total: 0,
discount_tax_total: 0,
tax_total: 0,
original_tax_total: 0,
raw_subtotal: {
value: "10",
precision: 20,
},
raw_total: {
value: "10",
precision: 20,
},
raw_original_total: {
value: "10",
precision: 20,
},
raw_discount_total: {
value: "0",
precision: 20,
},
raw_discount_tax_total: {
value: "0",
precision: 20,
},
raw_tax_total: {
value: "0",
precision: 20,
},
raw_original_tax_total: {
value: "0",
precision: 20,
},
},
],
total: 210,
subtotal: 500,
tax_total: 0,
discount_total: 300,
discount_tax_total: 0,
original_total: 210,
original_tax_total: 0,
item_total: 200,
item_subtotal: 500,
item_tax_total: 0,
original_item_total: 500,
original_item_subtotal: 500,
original_item_tax_total: 0,
shipping_total: 10,
shipping_subtotal: 10,
shipping_tax_total: 0,
original_shipping_tax_total: 0,
original_shipping_tax_subtotal: 10,
original_shipping_total: 10,
raw_total: {
value: "210",
precision: 20,
},
raw_subtotal: {
value: "500",
precision: 20,
},
raw_tax_total: {
value: "0",
precision: 20,
},
raw_discount_total: {
value: "300",
precision: 20,
},
raw_discount_tax_total: {
value: "0",
precision: 20,
},
raw_original_total: {
value: "210",
precision: 20,
},
raw_original_tax_total: {
value: "0",
precision: 20,
},
raw_item_total: {
value: "200",
precision: 20,
},
raw_item_subtotal: {
value: "500",
precision: 20,
},
raw_item_tax_total: {
value: "0",
precision: 20,
},
raw_original_item_total: {
value: "500",
precision: 20,
},
raw_original_item_subtotal: {
value: "500",
precision: 20,
},
raw_original_item_tax_total: {
value: "0",
precision: 20,
},
raw_shipping_total: {
value: "10",
precision: 20,
},
raw_shipping_subtotal: {
value: "10",
precision: 20,
},
raw_shipping_tax_total: {
value: "0",
precision: 20,
},
raw_original_shipping_tax_total: {
value: "0",
precision: 20,
},
raw_original_shipping_tax_subtotal: {
value: "10",
precision: 20,
},
raw_original_shipping_total: {
value: "10",
precision: 20,
},
})
})
},
})
+124
View File
@@ -1,7 +1,9 @@
import {
CartDTO,
CartTypes,
Context,
DAL,
FindConfig,
ICartModuleService,
InternalModuleDeclaration,
ModuleJoinerConfig,
@@ -13,6 +15,9 @@ import {
MedusaContext,
MedusaError,
ModulesSdkUtils,
createRawPropertiesFromBigNumber,
decorateCartTotals,
deduplicate,
isObject,
isString,
} from "@medusajs/utils"
@@ -126,6 +131,125 @@ export default class CartModuleService<
return joinerConfig
}
private shouldIncludeTotals(config: FindConfig<any>): boolean {
const totalFields = [
"total",
"subtotal",
"tax_total",
"discount_total",
"discount_tax_total",
"original_total",
"original_tax_total",
"item_total",
"item_subtotal",
"item_tax_total",
"original_item_total",
"original_item_subtotal",
"original_item_tax_total",
"shipping_total",
"shipping_subtotal",
"shipping_tax_total",
"original_shipping_tax_total",
"original_shipping_tax_subtotal",
"original_shipping_total",
]
const includeTotals = (config?.select ?? []).some((field) =>
totalFields.includes(field as string)
)
if (includeTotals) {
this.addRelationsToCalculateTotals(config, totalFields)
}
return includeTotals
}
private addRelationsToCalculateTotals(config: FindConfig<any>, totalFields) {
config.relations ??= []
config.select ??= []
const requiredFieldsForTotals = [
"items",
"items.tax_lines",
"items.adjustments",
"shipping_methods",
"shipping_methods.tax_lines",
"shipping_methods.adjustments",
]
config.relations = deduplicate([
...config.relations,
...requiredFieldsForTotals,
])
config.select = config.select.filter((field) => {
return (
!requiredFieldsForTotals.some((val) =>
val.startsWith(field as string)
) && !totalFields.includes(field)
)
})
}
async retrieve(
id: string,
config?: FindConfig<any> | undefined,
sharedContext?: Context | undefined
): Promise<CartDTO> {
config ??= {}
const includeTotals = this.shouldIncludeTotals(config)
const cart = await super.retrieve(id, config, sharedContext)
if (includeTotals) {
createRawPropertiesFromBigNumber(decorateCartTotals(cart))
}
return cart
}
async list(
filters?: any,
config?: FindConfig<any> | undefined,
sharedContext?: Context | undefined
): Promise<CartDTO[]> {
config ??= {}
const includeTotals = this.shouldIncludeTotals(config)
const carts = await super.list(filters, config, sharedContext)
if (includeTotals) {
carts.forEach((cart) => {
createRawPropertiesFromBigNumber(decorateCartTotals(cart))
})
}
return carts
}
async listAndCount(
filters?: any,
config?: FindConfig<any> | undefined,
sharedContext?: Context | undefined
): Promise<[CartDTO[], number]> {
config ??= {}
const includeTotals = this.shouldIncludeTotals(config)
const [carts, count] = await super.listAndCount(
filters,
config,
sharedContext
)
if (includeTotals) {
carts.forEach((cart) => {
createRawPropertiesFromBigNumber(decorateCartTotals(cart))
})
}
return [carts, count]
}
async create(
data: CartTypes.CreateCartDTO[],
sharedContext?: Context
@@ -0,0 +1,17 @@
import { remoteQueryObjectFromString } from "@medusajs/utils"
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
const remoteQuery = req.scope.resolve("remoteQuery")
const variables = { id: req.params.id }
const queryObject = remoteQueryObjectFromString({
entryPoint: "order",
variables,
fields: req.remoteQueryConfig.fields,
})
const [order] = await remoteQuery(queryObject)
res.status(200).json({ order })
}
@@ -0,0 +1,33 @@
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
import { authenticate } from "../../../utils/authenticate-middleware"
import { validateAndTransformQuery } from "../../utils/validate-query"
import * as QueryConfig from "./query-config"
import { AdminGetOrdersOrderParams, AdminGetOrdersParams } from "./validators"
export const adminOrderRoutesMiddlewares: MiddlewareRoute[] = [
{
method: ["ALL"],
matcher: "/admin/orders*",
middlewares: [authenticate("admin", ["bearer", "session", "api-key"])],
},
{
method: ["GET"],
matcher: "/admin/orders",
middlewares: [
validateAndTransformQuery(
AdminGetOrdersParams,
QueryConfig.listTransformQueryConfig
),
],
},
{
method: ["GET"],
matcher: "/admin/orders/:id",
middlewares: [
validateAndTransformQuery(
AdminGetOrdersOrderParams,
QueryConfig.retrieveTransformQueryConfig
),
],
},
]
@@ -0,0 +1,59 @@
export const defaultAdminOrderFields = [
"id",
"status",
"version",
"summary",
"metadata",
"created_at",
"updated_at",
]
export const defaultAdminRetrieveOrderFields = [
"id",
"status",
"version",
"summary",
"total",
"subtotal",
"tax_total",
"discount_total",
"discount_tax_total",
"original_total",
"original_tax_total",
"item_total",
"item_subtotal",
"item_tax_total",
"original_item_total",
"original_item_subtotal",
"original_item_tax_total",
"shipping_total",
"shipping_subtotal",
"shipping_tax_total",
"original_shipping_tax_total",
"original_shipping_tax_subtotal",
"original_shipping_total",
"created_at",
"updated_at",
"*items",
"*items.tax_lines",
"*items.adjustments",
"*items.detail",
"*items.tax_lines",
"*items.adjustments",
"*shipping_address",
"*billing_address",
"*shipping_methods",
"*shipping_methods.tax_lines",
"*shipping_methods.adjustments",
]
export const retrieveTransformQueryConfig = {
defaultFields: defaultAdminRetrieveOrderFields,
isList: false,
}
export const listTransformQueryConfig = {
defaults: defaultAdminOrderFields,
defaultLimit: 20,
isList: true,
}
@@ -0,0 +1,27 @@
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
const queryObject = remoteQueryObjectFromString({
entryPoint: "order",
variables: {
filters: req.filterableFields,
...req.remoteQueryConfig.pagination,
},
fields: req.remoteQueryConfig.fields,
})
const { rows: orders, metadata } = await remoteQuery(queryObject)
res.json({
orders,
count: metadata.count,
offset: metadata.skip,
limit: metadata.take,
})
}
@@ -0,0 +1,38 @@
import { z } from "zod"
import {
createFindParams,
createOperatorMap,
createSelectParams,
} from "../../utils/validators"
export const AdminGetOrdersOrderParams = createSelectParams().merge(
z.object({
id: z.union([z.string(), z.array(z.string())]).optional(),
status: z.union([z.string(), z.array(z.string())]).optional(),
created_at: createOperatorMap().optional(),
updated_at: createOperatorMap().optional(),
deleted_at: createOperatorMap().optional(),
})
)
export type AdminGetOrdersOrderParamsType = z.infer<
typeof AdminGetOrdersOrderParams
>
/**
* Parameters used to filter and configure the pagination of the retrieved order.
*/
export const AdminGetOrdersParams = createFindParams({
limit: 15,
offset: 0,
}).merge(
z.object({
id: z.union([z.string(), z.array(z.string())]).optional(),
status: z.union([z.string(), z.array(z.string())]).optional(),
created_at: createOperatorMap().optional(),
updated_at: createOperatorMap().optional(),
deleted_at: createOperatorMap().optional(),
})
)
export type AdminGetOrdersParamsType = z.infer<typeof AdminGetOrdersParams>
@@ -10,6 +10,7 @@ import { adminFulfillmentSetsRoutesMiddlewares } from "./admin/fulfillment-sets/
import { adminFulfillmentsRoutesMiddlewares } from "./admin/fulfillments/middlewares"
import { adminInventoryRoutesMiddlewares } from "./admin/inventory-items/middlewares"
import { adminInviteRoutesMiddlewares } from "./admin/invites/middlewares"
import { adminOrderRoutesMiddlewares } from "./admin/orders/middlewares"
import { adminPaymentRoutesMiddlewares } from "./admin/payments/middlewares"
import { adminPriceListsRoutesMiddlewares } from "./admin/price-lists/middlewares"
import { adminPricingRoutesMiddlewares } from "./admin/pricing/middlewares"
@@ -71,6 +72,7 @@ export const config: MiddlewaresConfig = {
...adminProductTypeRoutesMiddlewares,
...adminUploadRoutesMiddlewares,
...adminFulfillmentSetsRoutesMiddlewares,
...adminOrderRoutesMiddlewares,
...adminReservationRoutesMiddlewares,
...adminProductCategoryRoutesMiddlewares,
...adminReservationRoutesMiddlewares,
@@ -4,6 +4,25 @@ export const defaultStoreCartFields = [
"email",
"created_at",
"updated_at",
"total",
"subtotal",
"tax_total",
"discount_total",
"discount_tax_total",
"original_total",
"original_tax_total",
"item_total",
"item_subtotal",
"item_tax_total",
"original_item_total",
"original_item_subtotal",
"original_item_tax_total",
"shipping_total",
"shipping_subtotal",
"shipping_tax_total",
"original_shipping_tax_total",
"original_shipping_tax_subtotal",
"original_shipping_total",
"items.id",
"items.variant_id",
"items.product_id",
@@ -34,6 +34,7 @@ export function transformQuery<
req.query,
config
)
req.validatedQuery = validated
req.filterableFields = getFilterableFields(validated)
@@ -179,14 +179,77 @@ export default class OrderModuleService<
return joinerConfig
}
private shouldIncludeTotals(config: FindConfig<any>): boolean {
const totalFields = [
"total",
"subtotal",
"tax_total",
"discount_total",
"discount_tax_total",
"original_total",
"original_tax_total",
"item_total",
"item_subtotal",
"item_tax_total",
"original_item_total",
"original_item_subtotal",
"original_item_tax_total",
"shipping_total",
"shipping_subtotal",
"shipping_tax_total",
"original_shipping_tax_total",
"original_shipping_tax_subtotal",
"original_shipping_total",
]
const includeTotals = (config?.select ?? []).some((field) =>
totalFields.includes(field as string)
)
if (includeTotals) {
this.addRelationsToCalculateTotals(config, totalFields)
}
return includeTotals
}
private addRelationsToCalculateTotals(config: FindConfig<any>, totalFields) {
config.relations ??= []
config.select ??= []
const requiredFieldsForTotals = [
"items",
"items.tax_lines",
"items.adjustments",
"shipping_methods",
"shipping_methods.tax_lines",
"shipping_methods.adjustments",
]
config.relations = deduplicate([
...config.relations,
...requiredFieldsForTotals,
])
config.select = config.select.filter((field) => {
return (
!requiredFieldsForTotals.some((val) =>
val.startsWith(field as string)
) && !totalFields.includes(field)
)
})
}
async retrieve(
id: string,
config?: FindConfig<any> | undefined,
sharedContext?: Context | undefined
): Promise<OrderTypes.OrderDTO> {
config ??= {}
const includeTotals = this.shouldIncludeTotals(config)
const order = await super.retrieve(id, config, sharedContext)
return formatOrder(order) as OrderTypes.OrderDTO
return formatOrder(order, { includeTotals }) as OrderTypes.OrderDTO
}
async list(
@@ -194,9 +257,14 @@ export default class OrderModuleService<
config?: FindConfig<any> | undefined,
sharedContext?: Context | undefined
): Promise<OrderTypes.OrderDTO[]> {
config ??= {}
const includeTotals = this.shouldIncludeTotals(config)
const orders = await super.list(filters, config, sharedContext)
return formatOrder(orders) as OrderTypes.OrderDTO[]
return formatOrder(orders, {
includeTotals,
}) as OrderTypes.OrderDTO[]
}
async listAndCount(
@@ -204,13 +272,19 @@ export default class OrderModuleService<
config?: FindConfig<any> | undefined,
sharedContext?: Context | undefined
): Promise<[OrderTypes.OrderDTO[], number]> {
config ??= {}
const includeTotals = this.shouldIncludeTotals(config)
const [orders, count] = await super.listAndCount(
filters,
config,
sharedContext
)
return [formatOrder(orders) as OrderTypes.OrderDTO[], count]
return [
formatOrder(orders, { includeTotals }) as OrderTypes.OrderDTO[],
count,
]
}
async create(
+13 -3
View File
@@ -1,8 +1,16 @@
import { OrderTypes } from "@medusajs/types"
import { decorateCartTotals, deduplicate, isDefined } from "@medusajs/utils"
import {
createRawPropertiesFromBigNumber,
decorateCartTotals,
deduplicate,
isDefined,
} from "@medusajs/utils"
export function formatOrder(
order
order,
options: {
includeTotals?: boolean
}
): OrderTypes.OrderDTO | OrderTypes.OrderDTO[] {
const isArray = Array.isArray(order)
const orders = [...(isArray ? order : [order])]
@@ -23,7 +31,9 @@ export function formatOrder(
order.summary = order.summary?.[0]?.totals
return decorateCartTotals(order)
return options?.includeTotals
? createRawPropertiesFromBigNumber(decorateCartTotals(order))
: order
})
return isArray ? orders : orders[0]
+231 -6
View File
@@ -1,6 +1,6 @@
import { BaseFilterable } from "../dal"
import { OperatorMap } from "../dal/utils"
import { BigNumberValue } from "../totals"
import { BigNumberRawValue, BigNumberValue } from "../totals"
/**
* The adjustment line details.
@@ -22,6 +22,11 @@ export interface AdjustmentLineDTO {
*/
amount: BigNumberValue
/**
* The raw amount to adjust the original amount with.
*/
raw_amount: BigNumberRawValue
/**
* The ID of the associated cart.
*/
@@ -153,6 +158,16 @@ export interface ShippingMethodTaxLineDTO extends TaxLineDTO {
* The subtotal tax relative to the shipping method.
*/
subtotal: BigNumberValue
/**
* The raw total tax relative to the shipping method.
*/
raw_total: BigNumberRawValue
/**
* The raw subtotal tax relative to the shipping method.
*/
raw_subtotal: BigNumberRawValue
}
/**
@@ -178,6 +193,16 @@ export interface LineItemTaxLineDTO extends TaxLineDTO {
* The subtotal tax relative to the item.
*/
subtotal: BigNumberValue
/**
* The raw total tax relative to the item.
*/
raw_total: BigNumberRawValue
/**
* The raw subtotal tax relative to the item.
*/
raw_subtotal: BigNumberRawValue
}
/**
@@ -372,6 +397,46 @@ export interface CartShippingMethodDTO {
* The discount tax total of the cart shipping method.
*/
discount_tax_total: BigNumberValue
/**
* The raw original total of the cart shipping method.
*/
raw_original_total: BigNumberRawValue
/**
* The raw original subtotal of the cart shipping method.
*/
raw_original_subtotal: BigNumberRawValue
/**
* The raw original tax total of the cart shipping method.
*/
raw_original_tax_total: BigNumberRawValue
/**
* The raw total of the cart shipping method.
*/
raw_total: BigNumberRawValue
/**
* The raw subtotal of the cart shipping method.
*/
raw_subtotal: BigNumberRawValue
/**
* The raw tax total of the cart shipping method.
*/
raw_tax_total: BigNumberRawValue
/**
* The raw discount total of the cart shipping method.
*/
raw_discount_total: BigNumberRawValue
/**
* The raw discount tax total of the cart shipping method.
*/
raw_discount_tax_total: BigNumberRawValue
}
/**
@@ -432,6 +497,61 @@ export interface CartLineItemTotalsDTO {
* The discount tax total of the cart line item.
*/
discount_tax_total: BigNumberValue
/**
* The raw original total of the cart line item.
*/
raw_original_total: BigNumberRawValue
/**
* The raw original subtotal of the cart line item.
*/
raw_original_subtotal: BigNumberRawValue
/**
* The raw original tax total of the cart line item.
*/
raw_original_tax_total: BigNumberRawValue
/**
* The raw item total of the cart line item.
*/
raw_item_total: BigNumberRawValue
/**
* The raw item subtotal of the cart line item.
*/
raw_item_subtotal: BigNumberRawValue
/**
* The raw item tax total of the cart line item.
*/
raw_item_tax_total: BigNumberRawValue
/**
* The raw total of the cart line item.
*/
raw_total: BigNumberRawValue
/**
* The raw subtotal of the cart line item.
*/
raw_subtotal: BigNumberRawValue
/**
* The raw tax total of the cart line item.
*/
raw_tax_total: BigNumberRawValue
/**
* The raw discount total of the cart line item.
*/
raw_discount_total: BigNumberRawValue
/**
* The raw discount tax total of the cart line item.
*/
raw_discount_tax_total: BigNumberRawValue
}
/**
@@ -737,11 +857,6 @@ export interface CartDTO {
*/
discount_total: BigNumberValue
/**
* The raw discount total of the cart.
*/
raw_discount_total: any
/**
* The discount tax total of the cart.
*/
@@ -786,6 +901,116 @@ export interface CartDTO {
* The original shipping tax total of the cart.
*/
original_shipping_tax_total: BigNumberValue
/**
* The raw original item total of the cart.
*/
raw_original_item_total: BigNumberRawValue
/**
* The raw original item subtotal of the cart.
*/
raw_original_item_subtotal: BigNumberRawValue
/**
* The raw original item tax total of the cart.
*/
raw_original_item_tax_total: BigNumberRawValue
/**
* The raw item total of the cart.
*/
raw_item_total: BigNumberRawValue
/**
* The raw item subtotal of the cart.
*/
raw_item_subtotal: BigNumberRawValue
/**
* The raw item tax total of the cart.
*/
raw_item_tax_total: BigNumberRawValue
/**
* The raw original total of the cart.
*/
raw_original_total: BigNumberRawValue
/**
* The raw original subtotal of the cart.
*/
raw_original_subtotal: BigNumberRawValue
/**
* The raw original tax total of the cart.
*/
raw_original_tax_total: BigNumberRawValue
/**
* The raw total of the cart.
*/
raw_total: BigNumberRawValue
/**
* The raw subtotal of the cart. (Excluding taxes)
*/
raw_subtotal: BigNumberRawValue
/**
* The raw tax total of the cart.
*/
raw_tax_total: BigNumberRawValue
/**
* The raw discount total of the cart.
*/
raw_discount_total: BigNumberRawValue
/**
* The raw discount tax total of the cart.
*/
raw_discount_tax_total: BigNumberRawValue
/**
* The raw gift card total of the cart.
*/
raw_gift_card_total: BigNumberRawValue
/**
* The raw gift card tax total of the cart.
*/
raw_gift_card_tax_total: BigNumberRawValue
/**
* The raw shipping total of the cart.
*/
raw_shipping_total: BigNumberRawValue
/**
* The raw shipping subtotal of the cart.
*/
raw_shipping_subtotal: BigNumberRawValue
/**
* The raw shipping tax total of the cart.
*/
raw_shipping_tax_total: BigNumberRawValue
/**
* The raw original shipping total of the cart.
*/
raw_original_shipping_total: BigNumberRawValue
/**
* The raw original shipping subtotal of the cart.
*/
raw_original_shipping_subtotal: BigNumberRawValue
/**
* The raw original shipping tax total of the cart.
*/
raw_original_shipping_tax_total: BigNumberRawValue
}
/**
+2 -1
View File
@@ -2,8 +2,9 @@ export * from "./api-key"
export * from "./customer"
export * from "./fulfillment"
export * from "./inventory"
export * from "./order"
export * from "./pricing"
export * from "./product-category"
export * from "./sales-channel"
export * from "./stock-locations"
export * from "./tax"
export * from "./product-category"
@@ -0,0 +1,314 @@
import { BigNumberRawValue } from "../../../totals"
import { PaginatedResponse } from "../../common"
interface OrderSummary {
total: number
subtotal: number
total_tax: number
ordered_total: number
fulfilled_total: number
returned_total: number
return_request_total: number
write_off_total: number
projected_total: number
net_total: number
net_subtotal: number
net_total_tax: number
future_total: number
future_subtotal: number
future_total_tax: number
future_projected_total: number
balance: number
future_balance: number
}
interface OrderAdjustmentLine {
id: string
code?: string
amount: number
order_id: string
description?: string
promotion_id?: string
provider_id?: string
created_at: Date | string
updated_at: Date | string
}
interface OrderShippingMethodAdjustment extends OrderAdjustmentLine {
shipping_method: OrderShippingMethod
shipping_method_id: string
}
interface OrderLineItemAdjustment extends OrderAdjustmentLine {
item: OrderLineItem
item_id: string
}
interface OrderTaxLine {
id: string
description?: string
tax_rate_id?: string
code: string
rate: number
provider_id?: string
created_at: Date | string
updated_at: Date | string
}
interface OrderShippingMethodTaxLine extends OrderTaxLine {
shipping_method: OrderShippingMethod
shipping_method_id: string
total: number
subtotal: number
raw_total?: BigNumberRawValue
raw_subtotal?: BigNumberRawValue
}
interface OrderLineItemTaxLine extends OrderTaxLine {
item: OrderLineItem
item_id: string
total: number
subtotal: number
raw_total?: BigNumberRawValue
raw_subtotal?: BigNumberRawValue
}
interface OrderAddress {
id: string
customer_id?: string
first_name?: string
last_name?: string
phone?: string
company?: string
address_1?: string
address_2?: string
city?: string
country_code?: string
province?: string
postal_code?: string
metadata: Record<string, unknown> | null
created_at: Date | string
updated_at: Date | string
}
interface OrderShippingMethod {
id: string
order_id: string
name: string
description?: string
amount: number
raw_amount?: BigNumberRawValue
is_tax_inclusive: boolean
shipping_option_id: string | null
data: Record<string, unknown> | null
metadata: Record<string, unknown> | null
tax_lines?: OrderShippingMethodTaxLine[]
adjustments?: OrderShippingMethodAdjustment[]
created_at: Date | string
updated_at: Date | string
}
interface OrderLineItem {
id: string
title: string
subtitle: string | null
thumbnail: string | null
variant_id: string | null
product_id: string | null
product_title: string | null
product_description: string | null
product_subtitle: string | null
product_type: string | null
product_collection: string | null
product_handle: string | null
variant_sku: string | null
variant_barcode: string | null
variant_title: string | null
variant_option_values: Record<string, unknown> | null
requires_shipping: boolean
is_discountable: boolean
is_tax_inclusive: boolean
compare_at_unit_price?: number
raw_compare_at_unit_price?: BigNumberRawValue
unit_price: number
raw_unit_price?: BigNumberRawValue
quantity: number
raw_quantity?: BigNumberRawValue
tax_lines?: OrderLineItemTaxLine[]
adjustments?: OrderLineItemAdjustment[]
detail: OrderItemDetail
created_at: Date
updated_at: Date
metadata: Record<string, unknown> | null
original_total: number
original_subtotal: number
original_tax_total: number
item_total: number
item_subtotal: number
item_tax_total: number
total: number
subtotal: number
tax_total: number
discount_total: number
discount_tax_total: number
raw_original_total?: BigNumberRawValue
raw_original_subtotal?: BigNumberRawValue
raw_original_tax_total?: BigNumberRawValue
raw_item_total?: BigNumberRawValue
raw_item_subtotal?: BigNumberRawValue
raw_item_tax_total?: BigNumberRawValue
raw_total?: BigNumberRawValue
raw_subtotal?: BigNumberRawValue
raw_tax_total?: BigNumberRawValue
raw_discount_total?: BigNumberRawValue
raw_discount_tax_total?: BigNumberRawValue
}
interface OrderItemDetail {
id: string
item_id: string
item: OrderLineItem
quantity: number
fulfilled_quantity: number
shipped_quantity: number
return_requested_quantity: number
return_received_quantity: number
return_dismissed_quantity: number
written_off_quantity: number
raw_quantity?: BigNumberRawValue
raw_fulfilled_quantity?: BigNumberRawValue
raw_shipped_quantity?: BigNumberRawValue
raw_return_requested_quantity?: BigNumberRawValue
raw_return_received_quantity?: BigNumberRawValue
raw_return_dismissed_quantity?: BigNumberRawValue
raw_written_off_quantity?: BigNumberRawValue
metadata: Record<string, unknown> | null
created_at: Date
updated_at: Date
}
interface OrderChange {
id: string
order_id: string
actions: OrderChangeAction[]
status: string
requested_by: string | null
requested_at: Date | string | null
confirmed_by: string | null
confirmed_at: Date | string | null
declined_by: string | null
declined_reason: string | null
metadata: Record<string, unknown> | null
declined_at: Date | string | null
canceled_by: string | null
canceled_at: Date | string | null
created_at: Date | string
updated_at: Date | string
}
interface OrderChangeAction {
id: string
order_change_id: string | null
order_change: OrderChange | null
order_id: string | null
reference: string
reference_id: string
action: string
details: Record<string, unknown> | null
internal_note: string | null
created_at: Date | string
updated_at: Date | string
}
interface OrderTransaction {
id: string
order_id: string
amount: number
raw_amount?: BigNumberRawValue
currency_code: string
reference: string
reference_id: string
metadata: Record<string, unknown> | null
created_at: Date | string
updated_at: Date | string
}
/**
* @experimental
*/
export interface OrderResponse {
id: string
version: number
region_id: string | null
customer_id: string | null
sales_channel_id: string | null
email: string | null
currency_code: string
shipping_address?: OrderAddress
billing_address?: OrderAddress
items: OrderLineItem[] | null
shipping_methods: OrderShippingMethod[] | null
transactions?: OrderTransaction[]
summary: OrderSummary
metadata: Record<string, unknown> | null
created_at: string | Date
updated_at: string | Date
original_item_total: number
original_item_subtotal: number
original_item_tax_total: number
item_total: number
item_subtotal: number
item_tax_total: number
original_total: number
original_subtotal: number
original_tax_total: number
total: number
subtotal: number
tax_total: number
discount_total: number
discount_tax_total: number
gift_card_total: number
gift_card_tax_total: number
shipping_total: number
shipping_subtotal: number
shipping_tax_total: number
original_shipping_total: number
original_shipping_subtotal: number
original_shipping_tax_total: number
raw_original_item_total?: BigNumberRawValue
raw_original_item_subtotal?: BigNumberRawValue
raw_original_item_tax_total?: BigNumberRawValue
raw_item_total?: BigNumberRawValue
raw_item_subtotal?: BigNumberRawValue
raw_item_tax_total?: BigNumberRawValue
raw_original_total?: BigNumberRawValue
raw_original_subtotal?: BigNumberRawValue
raw_original_tax_total?: BigNumberRawValue
raw_total?: BigNumberRawValue
raw_subtotal?: BigNumberRawValue
raw_tax_total?: BigNumberRawValue
raw_discount_total?: BigNumberRawValue
raw_discount_tax_total?: BigNumberRawValue
raw_gift_card_total?: BigNumberRawValue
raw_gift_card_tax_total?: BigNumberRawValue
raw_shipping_total?: BigNumberRawValue
raw_shipping_subtotal?: BigNumberRawValue
raw_shipping_tax_total?: BigNumberRawValue
raw_original_shipping_total?: BigNumberRawValue
raw_original_shipping_subtotal?: BigNumberRawValue
raw_original_shipping_tax_total?: BigNumberRawValue
}
/**
* @experimental
*/
export interface AdminOrderListResponse extends PaginatedResponse {
orders: OrderResponse[]
}
/**
* @experimental
*/
export interface AdminOrderResponse {
order: OrderResponse
}
+1
View File
@@ -0,0 +1 @@
export * from "./admin"
+398 -13
View File
@@ -144,6 +144,16 @@ export interface OrderShippingMethodTaxLineDTO extends OrderTaxLineDTO {
* The subtotal tax relative to the shipping method.
*/
subtotal: BigNumberValue
/**
* The raw total tax relative to the shipping method.
*/
raw_total: BigNumberRawValue
/**
* The raw subtotal tax relative to the shipping method.
*/
raw_subtotal: BigNumberRawValue
}
export interface OrderLineItemTaxLineDTO extends OrderTaxLineDTO {
@@ -165,6 +175,16 @@ export interface OrderLineItemTaxLineDTO extends OrderTaxLineDTO {
* The subtotal tax relative to the item.
*/
subtotal: BigNumberValue
/**
* The raw total tax relative to the item.
*/
raw_total: BigNumberRawValue
/**
* The raw subtotal tax relative to the item.
*/
raw_subtotal: BigNumberRawValue
}
export interface OrderAddressDTO {
@@ -253,7 +273,12 @@ export interface OrderShippingMethodDTO {
/**
* The price of the shipping method
*/
amount: BigNumberRawValue
amount: BigNumberValue
/**
* The raw price of the shipping method
*/
raw_amount: BigNumberRawValue
/**
* Whether the shipping method price is tax inclusive or not
*/
@@ -335,22 +360,158 @@ export interface OrderShippingMethodDTO {
* The discount tax total of the order shipping method.
*/
discount_tax_total: BigNumberValue
/**
* The raw original total of the order shipping method.
*/
raw_original_total: BigNumberRawValue
/**
* The raw original subtotal of the order shipping method.
*/
raw_original_subtotal: BigNumberRawValue
/**
* The raw original tax total of the order shipping method.
*/
raw_original_tax_total: BigNumberRawValue
/**
* The raw total of the order shipping method.
*/
raw_total: BigNumberRawValue
/**
* The raw subtotal of the order shipping method.
*/
raw_subtotal: BigNumberRawValue
/**
* The raw tax total of the order shipping method.
*/
raw_tax_total: BigNumberRawValue
/**
* The raw discount total of the order shipping method.
*/
raw_discount_total: BigNumberRawValue
/**
* The raw discount tax total of the order shipping method.
*/
raw_discount_tax_total: BigNumberRawValue
}
export interface OrderLineItemTotalsDTO {
original_total: number
original_subtotal: number
original_tax_total: number
/**
* The original total of the order line item.
*/
original_total: BigNumberValue
item_total: number
item_subtotal: number
item_tax_total: number
/**
* The original subtotal of the order line item.
*/
original_subtotal: BigNumberValue
total: number
subtotal: number
tax_total: number
discount_total: number
discount_tax_total: number
/**
* The original tax total of the order line item.
*/
original_tax_total: BigNumberValue
/**
* The item total of the order line item.
*/
item_total: BigNumberValue
/**
* The item subtotal of the order line item.
*/
item_subtotal: BigNumberValue
/**
* The item tax total of the order line item.
*/
item_tax_total: BigNumberValue
/**
* The total of the order line item.
*/
total: BigNumberValue
/**
* The subtotal of the order line item.
*/
subtotal: BigNumberValue
/**
* The tax total of the order line item.
*/
tax_total: BigNumberValue
/**
* The discount total of the order line item.
*/
discount_total: BigNumberValue
/**
* The discount tax total of the order line item.
*/
discount_tax_total: BigNumberValue
/**
* The raw original total of the order line item.
*/
raw_original_total: BigNumberRawValue
/**
* The raw original subtotal of the order line item.
*/
raw_original_subtotal: BigNumberRawValue
/**
* The raw original tax total of the order line item.
*/
raw_original_tax_total: BigNumberRawValue
/**
* The raw item total of the order line item.
*/
raw_item_total: BigNumberRawValue
/**
* The raw item subtotal of the order line item.
*/
raw_item_subtotal: BigNumberRawValue
/**
* The raw item tax total of the order line item.
*/
raw_item_tax_total: BigNumberRawValue
/**
* The raw total of the order line item.
*/
raw_total: BigNumberRawValue
/**
* The raw subtotal of the order line item.
*/
raw_subtotal: BigNumberRawValue
/**
* The raw tax total of the order line item.
*/
raw_tax_total: BigNumberRawValue
/**
* The raw discount total of the order line item.
*/
raw_discount_total: BigNumberRawValue
/**
* The raw discount tax total of the order line item.
*/
raw_discount_tax_total: BigNumberRawValue
}
export interface OrderLineItemDTO extends OrderLineItemTotalsDTO {
@@ -691,6 +852,226 @@ export interface OrderDTO {
* When the order was updated.
*/
updated_at?: string | Date
/**
* The original item total of the order.
*/
original_item_total: BigNumberValue
/**
* The original item subtotal of the order.
*/
original_item_subtotal: BigNumberValue
/**
* The original item tax total of the order.
*/
original_item_tax_total: BigNumberValue
/**
* The item total of the order.
*/
item_total: BigNumberValue
/**
* The item subtotal of the order.
*/
item_subtotal: BigNumberValue
/**
* The item tax total of the order.
*/
item_tax_total: BigNumberValue
/**
* The original total of the order.
*/
original_total: BigNumberValue
/**
* The original subtotal of the order.
*/
original_subtotal: BigNumberValue
/**
* The original tax total of the order.
*/
original_tax_total: BigNumberValue
/**
* The total of the order.
*/
total: BigNumberValue
/**
* The subtotal of the order. (Excluding taxes)
*/
subtotal: BigNumberValue
/**
* The tax total of the order.
*/
tax_total: BigNumberValue
/**
* The discount total of the order.
*/
discount_total: BigNumberValue
/**
* The discount tax total of the order.
*/
discount_tax_total: BigNumberValue
/**
* The gift card total of the order.
*/
gift_card_total: BigNumberValue
/**
* The gift card tax total of the order.
*/
gift_card_tax_total: BigNumberValue
/**
* The shipping total of the order.
*/
shipping_total: BigNumberValue
/**
* The shipping subtotal of the order.
*/
shipping_subtotal: BigNumberValue
/**
* The shipping tax total of the order.
*/
shipping_tax_total: BigNumberValue
/**
* The original shipping total of the order.
*/
original_shipping_total: BigNumberValue
/**
* The original shipping subtotal of the order.
*/
original_shipping_subtotal: BigNumberValue
/**
* The original shipping tax total of the order.
*/
original_shipping_tax_total: BigNumberValue
/**
* The raw original item total of the order.
*/
raw_original_item_total: BigNumberRawValue
/**
* The raw original item subtotal of the order.
*/
raw_original_item_subtotal: BigNumberRawValue
/**
* The raw original item tax total of the order.
*/
raw_original_item_tax_total: BigNumberRawValue
/**
* The raw item total of the order.
*/
raw_item_total: BigNumberRawValue
/**
* The raw item subtotal of the order.
*/
raw_item_subtotal: BigNumberRawValue
/**
* The raw item tax total of the order.
*/
raw_item_tax_total: BigNumberRawValue
/**
* The raw original total of the order.
*/
raw_original_total: BigNumberRawValue
/**
* The raw original subtotal of the order.
*/
raw_original_subtotal: BigNumberRawValue
/**
* The raw original tax total of the order.
*/
raw_original_tax_total: BigNumberRawValue
/**
* The raw total of the order.
*/
raw_total: BigNumberRawValue
/**
* The raw subtotal of the order. (Excluding taxes)
*/
raw_subtotal: BigNumberRawValue
/**
* The raw tax total of the order.
*/
raw_tax_total: BigNumberRawValue
/**
* The raw discount total of the order.
*/
raw_discount_total: BigNumberRawValue
/**
* The raw discount tax total of the order.
*/
raw_discount_tax_total: BigNumberRawValue
/**
* The raw gift card total of the order.
*/
raw_gift_card_total: BigNumberRawValue
/**
* The raw gift card tax total of the order.
*/
raw_gift_card_tax_total: BigNumberRawValue
/**
* The raw shipping total of the order.
*/
raw_shipping_total: BigNumberRawValue
/**
* The raw shipping subtotal of the order.
*/
raw_shipping_subtotal: BigNumberRawValue
/**
* The raw shipping tax total of the order.
*/
raw_shipping_tax_total: BigNumberRawValue
/**
* The raw original shipping total of the order.
*/
raw_original_shipping_total: BigNumberRawValue
/**
* The raw original shipping subtotal of the order.
*/
raw_original_shipping_subtotal: BigNumberRawValue
/**
* The raw original shipping tax total of the order.
*/
raw_original_shipping_tax_total: BigNumberRawValue
}
export interface OrderChangeDTO {
@@ -843,7 +1224,11 @@ export interface OrderTransactionDTO {
/**
* The amount of the transaction
*/
amount: number
amount: BigNumberValue
/**
* The raw amount of the transaction
*/
raw_amount: BigNumberRawValue
/**
* The currency code of the transaction
*/
@@ -0,0 +1,88 @@
import { BigNumber } from "../big-number"
import { createRawPropertiesFromBigNumber } from "../create-raw-properties-from-bignumber"
describe("Create Raw properties from BigNumber", function () {
it("should create raw properties from BigNumber properties", function () {
const obj = {
price: new BigNumber({
value: "42",
precision: 10,
}),
field: 111,
metadata: {
numeric_field: new BigNumber({
value: "100",
}),
random_field: 134,
},
abc: null,
raw_abc: {
value: "9.00000010000103991234",
precision: 20,
},
}
createRawPropertiesFromBigNumber(obj)
expect(obj).toEqual(
expect.objectContaining({
raw_price: {
value: "42",
precision: 10,
},
field: 111,
metadata: expect.objectContaining({
raw_numeric_field: {
value: "100",
precision: 20,
},
random_field: 134,
}),
abc: null,
raw_abc: {
value: "9.00000010000103991234",
precision: 20,
},
})
)
})
it("should create all properties containing BigNumber properties excluding selected ones", function () {
const obj = {
price: new BigNumber({
value: "42",
precision: 10,
}),
field: 111,
metadata: {
numeric_field: new BigNumber({
value: "100",
}),
random_field: 134,
},
}
createRawPropertiesFromBigNumber(obj, {
exclude: ["metadata.numeric_field"],
})
expect(obj).toEqual({
price: new BigNumber({
value: "42",
precision: 10,
}),
raw_price: {
value: "42",
precision: 10,
},
field: 111,
metadata: {
numeric_field: new BigNumber({
value: "100",
}),
random_field: 134,
},
})
})
})
+9 -4
View File
@@ -63,22 +63,24 @@ export function decorateCartTotals(
let discountTaxTotal = MathBN.convert(0)
let itemsSubtotal = MathBN.convert(0)
let itemsSubtotalWithoutTaxes = MathBN.convert(0)
let itemsTotal = MathBN.convert(0)
let itemsOriginalTotal = MathBN.convert(0)
let itemsOriginalSubtotal = MathBN.convert(0)
let itemsTaxTotal = MathBN.convert(0)
let itemsOriginalTaxTotal = MathBN.convert(0)
let shippingSubtotal = MathBN.convert(0)
let shippingTotal = MathBN.convert(0)
let shippingOriginalTotal = MathBN.convert(0)
let shippingOriginalSubtotal = MathBN.convert(0)
let shippingTaxTotal = MathBN.convert(0)
let shippingTaxSubTotal = MathBN.convert(0)
let shippingOriginalTaxTotal = MathBN.convert(0)
let shippingOriginalTaxSubtotal = MathBN.convert(0)
@@ -94,6 +96,7 @@ export function decorateCartTotals(
const itemOriginalTaxTotal = MathBN.convert(itemTotals.original_tax_total)
const itemDiscountTotal = MathBN.convert(itemTotals.discount_total)
const itemDiscountTaxTotal = MathBN.convert(itemTotals.discount_tax_total)
subtotal = MathBN.add(subtotal, itemSubtotal)
@@ -108,6 +111,7 @@ export function decorateCartTotals(
itemsSubtotal = MathBN.add(itemsSubtotal, itemSubtotal)
itemsTaxTotal = MathBN.add(itemsTaxTotal, itemTaxTotal)
itemsOriginalTaxTotal = MathBN.add(
itemsOriginalTaxTotal,
itemOriginalTaxTotal
@@ -164,6 +168,7 @@ export function decorateCartTotals(
})
const taxTotal = MathBN.add(itemsTaxTotal, shippingTaxTotal)
const originalTaxTotal = MathBN.add(
itemsOriginalTaxTotal,
shippingOriginalTaxTotal
@@ -181,7 +186,7 @@ export function decorateCartTotals(
const tempTotal = MathBN.add(subtotal, shippingTotal, taxTotal)
const total = MathBN.sub(tempTotal, discountTotal)
const cart = { ...cartLike } as any
const cart = cartLike as any
cart.total = new BigNumber(total)
cart.subtotal = new BigNumber(subtotal)
@@ -0,0 +1,59 @@
import { isDefined, trimZeros } from "../common"
import { BigNumber } from "./big-number"
export function createRawPropertiesFromBigNumber(
obj,
{
prefix = "raw_",
exclude = [],
}: {
prefix?: string
exclude?: string[]
} = {}
) {
const stack = [{ current: obj, path: "" }]
while (stack.length > 0) {
const { current, path } = stack.pop()!
if (
current == null ||
typeof current !== "object" ||
current instanceof BigNumber
) {
continue
}
if (Array.isArray(current)) {
current.forEach((element, index) =>
stack.push({ current: element, path })
)
} else {
for (const key of Object.keys(current)) {
const value = current[key]
const currentPath = path ? `${path}.${key}` : key
if (value != null && !exclude.includes(currentPath)) {
const isBigNumber =
typeof value === "object" &&
isDefined(value.raw_) &&
isDefined(value.numeric_)
if (isBigNumber) {
const newKey = prefix + key
const newPath = path ? `${path}.${newKey}` : newKey
if (!exclude.includes(newPath)) {
current[newKey] = {
...value.raw_,
value: trimZeros(value.raw_.value),
}
continue
}
}
}
stack.push({ current: value, path: currentPath })
}
}
}
}
+1
View File
@@ -1,4 +1,5 @@
export * from "./cart"
export * from "./create-raw-properties-from-bignumber"
export * from "./line-item"
export * from "./math"
export * from "./promotion"