feat: Add necessary middlewares for tax inclusive pricing (#7827)
We are adding tax inclusive pricing calculation when listing products. Two things to keep in mind: - `region_id` will be required if you request calculated prices. - We won't accept `currency_code` anymore, as that will come from the region info (since ultimately a cart and its currency are tied to a region) REF CORE-2376 DEPENDS ON #8003
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
export interface BaseCalculatedPriceSet {
|
||||
/**
|
||||
* The ID of the price set.
|
||||
*/
|
||||
id: string
|
||||
|
||||
/**
|
||||
* Whether the calculated price is associated with a price list. During the calculation process, if no valid price list is found,
|
||||
* the calculated price is set to the original price, which doesn't belong to a price list. In that case, the value of this property is `false`.
|
||||
*/
|
||||
is_calculated_price_price_list?: boolean
|
||||
|
||||
/**
|
||||
* Whether the calculated price is tax inclusive.
|
||||
*/
|
||||
is_calculated_price_tax_inclusive?: boolean
|
||||
|
||||
/**
|
||||
* The amount of the calculated price, or `null` if there isn't a calculated price.
|
||||
*/
|
||||
calculated_amount: number | null
|
||||
|
||||
/**
|
||||
* The amount of the calculated price with taxes included. If the calculated price is tax inclusive, this field will be the same as `calculated_amount`.
|
||||
*/
|
||||
calculated_amount_with_tax?: number | null
|
||||
|
||||
/**
|
||||
* The amount of the calculated price without taxes included. If the calculated price is tax exclusive, this field will be the same as `calculated_amount`.
|
||||
*/
|
||||
calculated_amount_without_tax?: number | null
|
||||
|
||||
/**
|
||||
* Whether the original price is associated with a price list. During the calculation process, if the price list of the calculated price is of type override,
|
||||
* the original price will be the same as the calculated price. In that case, the value of this property is `true`.
|
||||
*/
|
||||
is_original_price_price_list?: boolean
|
||||
|
||||
/**
|
||||
* Whether the original price is tax inclusive.
|
||||
*/
|
||||
is_original_price_tax_inclusive?: boolean
|
||||
|
||||
/**
|
||||
* The amount of the original price, or `null` if there isn't a calculated price.
|
||||
*/
|
||||
original_amount: number | null
|
||||
|
||||
/**
|
||||
* The currency code of the calculated price, or null if there isn't a calculated price.
|
||||
*/
|
||||
currency_code: string | null
|
||||
|
||||
/**
|
||||
* The details of the calculated price.
|
||||
*/
|
||||
calculated_price?: {
|
||||
/**
|
||||
* The ID of the price selected as the calculated price.
|
||||
*/
|
||||
id: string | null
|
||||
/**
|
||||
* The ID of the associated price list, if any.
|
||||
*/
|
||||
price_list_id: string | null
|
||||
/**
|
||||
* The type of the associated price list, if any.
|
||||
*/
|
||||
price_list_type: string | null
|
||||
/**
|
||||
* The `min_quantity` field defined on a price.
|
||||
*/
|
||||
min_quantity: number | null
|
||||
/**
|
||||
* The `max_quantity` field defined on a price.
|
||||
*/
|
||||
max_quantity: number | null
|
||||
}
|
||||
|
||||
/**
|
||||
* The details of the original price.
|
||||
*/
|
||||
original_price?: {
|
||||
/**
|
||||
* The ID of the price selected as the original price.
|
||||
*/
|
||||
id: string | null
|
||||
/**
|
||||
* The ID of the associated price list, if any.
|
||||
*/
|
||||
price_list_id: string | null
|
||||
/**
|
||||
* The type of the associated price list, if any.
|
||||
*/
|
||||
price_list_type: string | null
|
||||
/**
|
||||
* The `min_quantity` field defined on a price.
|
||||
*/
|
||||
min_quantity: number | null
|
||||
/**
|
||||
* The `max_quantity` field defined on a price.
|
||||
*/
|
||||
max_quantity: number | null
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,8 @@ export interface AdminCreateProductVariantPrice {
|
||||
amount: number
|
||||
min_quantity?: number | null
|
||||
max_quantity?: number | null
|
||||
// Note: Although the BE is generic, we only use region_id for price rules for now, so it's better to keep the typings stricter.
|
||||
rules?: { region_id: string } | null
|
||||
}
|
||||
|
||||
export interface AdminCreateProductVariant {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { BaseFilterable, OperatorMap } from "../../dal"
|
||||
import { BaseCollection } from "../collection/common"
|
||||
import { FindParams } from "../common"
|
||||
import { BaseCalculatedPriceSet } from "../pricing/common"
|
||||
import { BaseProductCategory } from "../product-category/common"
|
||||
import { BaseProductType } from "../product-type/common"
|
||||
|
||||
@@ -56,10 +57,11 @@ export interface BaseProductVariant {
|
||||
length: number | null
|
||||
height: number | null
|
||||
width: number | null
|
||||
variant_rank?: number | null
|
||||
options: BaseProductOptionValue[] | null
|
||||
product?: BaseProduct | null
|
||||
product_id?: string
|
||||
variant_rank?: number | null
|
||||
calculated_price?: BaseCalculatedPriceSet
|
||||
created_at: string
|
||||
updated_at: string
|
||||
deleted_at: string | null
|
||||
|
||||
@@ -305,11 +305,11 @@ export interface ProductCategoryDTO {
|
||||
*
|
||||
* @expandable
|
||||
*/
|
||||
parent_category?: ProductCategoryDTO | null
|
||||
parent_category: ProductCategoryDTO | null
|
||||
/**
|
||||
* The associated parent category id.
|
||||
*/
|
||||
parent_category_id?: string | null
|
||||
parent_category_id: string | null
|
||||
/**
|
||||
* The associated child categories.
|
||||
*
|
||||
@@ -330,6 +330,10 @@ export interface ProductCategoryDTO {
|
||||
* When the product category was updated.
|
||||
*/
|
||||
updated_at: string | Date
|
||||
/**
|
||||
* When the product category was deleted.
|
||||
*/
|
||||
deleted_at?: string | Date
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -513,7 +513,7 @@ interface TaxLineDTO {
|
||||
/**
|
||||
* The rate of the tax line.
|
||||
*/
|
||||
rate: number | null
|
||||
rate: number
|
||||
|
||||
/**
|
||||
* The code of the tax line.
|
||||
|
||||
@@ -2,6 +2,7 @@ export * from "./cart"
|
||||
export * from "./create-raw-properties-from-bignumber"
|
||||
export * from "./line-item"
|
||||
export * from "./math"
|
||||
export * from "./tax"
|
||||
export * from "./promotion"
|
||||
export * from "./shipping-method"
|
||||
export * from "./transform-properties-to-bignumber"
|
||||
|
||||
@@ -31,3 +31,24 @@ export function calculateTaxTotal({
|
||||
|
||||
return taxTotal
|
||||
}
|
||||
|
||||
export function calculateAmountsWithTax({
|
||||
taxLines,
|
||||
amount,
|
||||
includesTax,
|
||||
}: {
|
||||
taxLines: Pick<TaxLineDTO, "rate">[]
|
||||
amount: number
|
||||
includesTax?: boolean
|
||||
}) {
|
||||
const tax = calculateTaxTotal({
|
||||
taxLines,
|
||||
includesTax,
|
||||
taxableAmount: amount,
|
||||
})
|
||||
|
||||
return {
|
||||
priceWithTax: includesTax ? amount : MathBN.add(tax, amount).toNumber(),
|
||||
priceWithoutTax: includesTax ? MathBN.sub(amount, tax).toNumber() : amount,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user