feat: Add support for managing tax inclusivity (#7943)
UI / HTTP / Workflows will come in separate PRs REF CORE-2376
This commit is contained in:
@@ -918,8 +918,10 @@ medusaIntegrationTestRunner({
|
|||||||
calculated_price: {
|
calculated_price: {
|
||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 3000,
|
calculated_amount: 3000,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 3000,
|
original_amount: 3000,
|
||||||
currency_code: "usd",
|
currency_code: "usd",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -1228,8 +1230,10 @@ medusaIntegrationTestRunner({
|
|||||||
calculated_price: {
|
calculated_price: {
|
||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 3000,
|
calculated_amount: 3000,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 3000,
|
original_amount: 3000,
|
||||||
currency_code: "usd",
|
currency_code: "usd",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
|
|||||||
@@ -3,4 +3,5 @@ export * from "./price"
|
|||||||
export * from "./price-list"
|
export * from "./price-list"
|
||||||
export * from "./price-rule"
|
export * from "./price-rule"
|
||||||
export * from "./price-set"
|
export * from "./price-set"
|
||||||
|
export * from "./price-preference"
|
||||||
export * from "./pricing-context"
|
export * from "./pricing-context"
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
import { BaseFilterable } from "../../dal"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @interface
|
||||||
|
*
|
||||||
|
* A price preference's data.
|
||||||
|
*/
|
||||||
|
export interface PricePreferenceDTO {
|
||||||
|
/**
|
||||||
|
* The ID of a price preference.
|
||||||
|
*/
|
||||||
|
id: string
|
||||||
|
/**
|
||||||
|
* The rule attribute for the preference
|
||||||
|
*/
|
||||||
|
attribute: string | null
|
||||||
|
/**
|
||||||
|
* The rule value for the preference
|
||||||
|
*/
|
||||||
|
value: string | null
|
||||||
|
/**
|
||||||
|
* Flag specifying whether prices for the specified rule are tax inclusive.
|
||||||
|
*/
|
||||||
|
is_tax_inclusive: boolean
|
||||||
|
/**
|
||||||
|
* When the price preference was created.
|
||||||
|
*/
|
||||||
|
created_at: Date
|
||||||
|
/**
|
||||||
|
* When the price preference was updated.
|
||||||
|
*/
|
||||||
|
updated_at: Date
|
||||||
|
/**
|
||||||
|
* When the price preference was deleted.
|
||||||
|
*/
|
||||||
|
deleted_at: null | Date
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpsertPricePreferenceDTO extends UpdatePricePreferenceDTO {
|
||||||
|
/**
|
||||||
|
* The ID of a price preference.
|
||||||
|
*/
|
||||||
|
id?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdatePricePreferenceDTO {
|
||||||
|
/**
|
||||||
|
* The rule attribute for the preference
|
||||||
|
*/
|
||||||
|
attribute?: string | null
|
||||||
|
/**
|
||||||
|
* The rule value for the preference
|
||||||
|
*/
|
||||||
|
value?: string | null
|
||||||
|
/**
|
||||||
|
* Flag specifying whether prices for the specified rule are tax inclusive.
|
||||||
|
*/
|
||||||
|
is_tax_inclusive?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreatePricePreferenceDTO {
|
||||||
|
/**
|
||||||
|
* The rule attribute for the preference
|
||||||
|
*/
|
||||||
|
attribute?: string
|
||||||
|
/**
|
||||||
|
* The rule value for the preference
|
||||||
|
*/
|
||||||
|
value?: string
|
||||||
|
/**
|
||||||
|
* Flag specifying whether prices for the specified rule are tax inclusive.
|
||||||
|
*/
|
||||||
|
is_tax_inclusive?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @interface
|
||||||
|
*
|
||||||
|
* Filters to apply on prices.
|
||||||
|
*/
|
||||||
|
export interface FilterablePricePreferenceProps
|
||||||
|
extends BaseFilterable<FilterablePricePreferenceProps> {
|
||||||
|
/**
|
||||||
|
* The IDs to filter the price preferences by.
|
||||||
|
*/
|
||||||
|
id?: string[]
|
||||||
|
/**
|
||||||
|
* Attributes to filter price preferences by.
|
||||||
|
*/
|
||||||
|
attribute?: string | string[]
|
||||||
|
/**
|
||||||
|
* Values to filter price preferences by.
|
||||||
|
*/
|
||||||
|
value?: string | string[]
|
||||||
|
}
|
||||||
@@ -121,6 +121,10 @@ export interface CalculatedPriceSet {
|
|||||||
* 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`.
|
* 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
|
is_calculated_price_price_list?: boolean
|
||||||
|
/**
|
||||||
|
* Whether the calculated price is tax inclusive or not.
|
||||||
|
*/
|
||||||
|
is_calculated_price_tax_inclusive?: boolean
|
||||||
/**
|
/**
|
||||||
* The amount of the calculated price, or `null` if there isn't a calculated price.
|
* The amount of the calculated price, or `null` if there isn't a calculated price.
|
||||||
*/
|
*/
|
||||||
@@ -131,6 +135,10 @@ export interface CalculatedPriceSet {
|
|||||||
* the original price will be the same as the calculated price. In that case, the value of this property is `true`.
|
* 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
|
is_original_price_price_list?: boolean
|
||||||
|
/**
|
||||||
|
* Whether the original price is tax inclusive or not.
|
||||||
|
*/
|
||||||
|
is_original_price_tax_inclusive?: boolean
|
||||||
/**
|
/**
|
||||||
* The amount of the original price, or `null` if there isn't a calculated price.
|
* The amount of the original price, or `null` if there isn't a calculated price.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -29,6 +29,13 @@ import {
|
|||||||
UpdatePriceSetDTO,
|
UpdatePriceSetDTO,
|
||||||
UpsertPriceSetDTO,
|
UpsertPriceSetDTO,
|
||||||
} from "./common"
|
} from "./common"
|
||||||
|
import {
|
||||||
|
CreatePricePreferenceDTO,
|
||||||
|
FilterablePricePreferenceProps,
|
||||||
|
PricePreferenceDTO,
|
||||||
|
UpdatePricePreferenceDTO,
|
||||||
|
UpsertPricePreferenceDTO,
|
||||||
|
} from "./common/price-preference"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main service interface for the Pricing Module.
|
* The main service interface for the Pricing Module.
|
||||||
@@ -1488,4 +1495,261 @@ export interface IPricingModuleService extends IModuleService {
|
|||||||
* ])
|
* ])
|
||||||
*/
|
*/
|
||||||
removePrices(ids: string[], sharedContext?: Context): Promise<void>
|
removePrices(ids: string[], sharedContext?: Context): Promise<void>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to retrieve a price preference by its ID.
|
||||||
|
*
|
||||||
|
* @param {string} id - The ID of the price preference to retrieve.
|
||||||
|
* @param {FindConfig<PricePreferenceDTO>} config -
|
||||||
|
* The configurations determining how the price preference is retrieved. Its properties, such as `select` or `relations`, accept the
|
||||||
|
* attributes or relations associated with a price preference.
|
||||||
|
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
|
||||||
|
* @returns {Promise<PricePreferenceDTO>} The retrieved price preference.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* A simple example that retrieves a price preference by its ID:
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* const pricePreference =
|
||||||
|
* await pricingModuleService.retrievePricePreference("prpref_123")
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
retrievePricePreference(
|
||||||
|
id: string,
|
||||||
|
config?: FindConfig<PricePreferenceDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to retrieve a paginated list of price preferences based on optional filters and configuration.
|
||||||
|
*
|
||||||
|
* @param {FilterablePricePreferenceProps} filters - The filters to apply on the retrieved price lists.
|
||||||
|
* @param {FindConfig<PricePreferenceDTO>} config -
|
||||||
|
* The configurations determining how the price preferences are retrieved. Its properties, such as `select` or `relations`, accept the
|
||||||
|
* attributes or relations associated with a price preference.
|
||||||
|
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
|
||||||
|
* @returns {Promise<PricePreferenceDTO[]>} The list of price preferences.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* To retrieve a list of price preferences using their IDs:
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* const pricePreferences = await pricingModuleService.listPricePreferences({
|
||||||
|
* id: ["prpref_123", "prpref_321"],
|
||||||
|
* })
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* To specify relations that should be retrieved within the price preferences:
|
||||||
|
*
|
||||||
|
* By default, only the first `15` records are retrieved. You can control pagination by specifying the `skip` and `take` properties of the `config` parameter:
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* const pricePreferences = await pricingModuleService.listPricePreferences(
|
||||||
|
* {
|
||||||
|
* id: ["prpref_123", "prpref_321"],
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* take: 20,
|
||||||
|
* skip: 2,
|
||||||
|
* }
|
||||||
|
* )
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
listPricePreferences(
|
||||||
|
filters?: FilterablePricePreferenceProps,
|
||||||
|
config?: FindConfig<PricePreferenceDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO[]>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to create a new price preference.
|
||||||
|
*
|
||||||
|
* @param {CreatePricePreferenceDTO} data - The attributes of the price preference to create.
|
||||||
|
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
|
||||||
|
* @returns {Promise<PricePreferenceDTO>} The created price preference.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* To create a price preference with rule:
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* const pricePreference = await pricingModuleService.createPricePreferences({
|
||||||
|
* attribute: 'region_id',
|
||||||
|
* value: 'DE',
|
||||||
|
* is_tax_inclusive: true
|
||||||
|
* })
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
createPricePreferences(
|
||||||
|
data: CreatePricePreferenceDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to create multiple price preferences.
|
||||||
|
*
|
||||||
|
* @param {CreatePricePreferenceDTO[]} data - The price preferences to create.
|
||||||
|
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
|
||||||
|
* @returns {Promise<PricePreferenceDTO[]>} The list of created price preferences.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const pricePreferences = await pricingModuleService.createPricePreferences([{
|
||||||
|
* attribute: 'region_id',
|
||||||
|
* value: 'DE',
|
||||||
|
* is_tax_inclusive: true
|
||||||
|
* }])
|
||||||
|
*/
|
||||||
|
createPricePreferences(
|
||||||
|
data: CreatePricePreferenceDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO[]>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method updates existing price preferences, or creates new ones if they don't exist.
|
||||||
|
*
|
||||||
|
* @param {UpsertPricePreferenceDTO[]} data - The attributes to update or create for each price preference.
|
||||||
|
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
|
||||||
|
* @returns {Promise<PricePreferenceDTO[]>} The updated and created price preferences.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const pricePreferences = await pricingModuleService.upsertPricePreferences([
|
||||||
|
* {
|
||||||
|
* id: "prpref_123",
|
||||||
|
* attribute: 'region_id',
|
||||||
|
* value: 'DE',
|
||||||
|
* is_tax_inclusive: true
|
||||||
|
* },
|
||||||
|
* ])
|
||||||
|
*/
|
||||||
|
upsertPricePreferences(
|
||||||
|
data: UpsertPricePreferenceDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO[]>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method updates the price preference if it exists, or creates a new ones if it doesn't.
|
||||||
|
*
|
||||||
|
* @param {UpsertPricePreferenceDTO} data - The attributes to update or create for the new price preference.
|
||||||
|
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
|
||||||
|
* @returns {Promise<PricePreferenceDTO>} The updated or created price preference.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const pricePreference = await pricingModuleService.upsertPricePreferences(
|
||||||
|
* {
|
||||||
|
* id: "prpref_123",
|
||||||
|
* attribute: 'region_id',
|
||||||
|
* value: 'DE',
|
||||||
|
* is_tax_inclusive: true
|
||||||
|
* }
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
upsertPricePreferences(
|
||||||
|
data: UpsertPricePreferenceDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to update a price preference.
|
||||||
|
*
|
||||||
|
* @param {string} id - The ID of the price preference to be updated.
|
||||||
|
* @param {UpdatePricePreferenceDTO} data - The attributes of the price preference to be updated
|
||||||
|
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
|
||||||
|
* @returns {Promise<PricePreferenceDTO>} The updated price preference.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const pricePreference = await pricingModuleService.updatePricePreferences(
|
||||||
|
* "prpref_123",
|
||||||
|
* {
|
||||||
|
* is_tax_inclusive: false
|
||||||
|
* }
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
updatePricePreferences(
|
||||||
|
id: string,
|
||||||
|
data: UpdatePricePreferenceDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to update a list of price preferences determined by the selector filters.
|
||||||
|
*
|
||||||
|
* @param {FilterablePricePreferenceProps} selector - The filters that will determine which price preferences will be updated.
|
||||||
|
* @param {UpdatePricePreferenceDTO} data - The attributes to be updated on the selected price preferences
|
||||||
|
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
|
||||||
|
* @returns {Promise<PricePreferenceDTO[]>} The updated price preferences.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const pricePreferences = await pricingModuleService.updatePricePreferences(
|
||||||
|
* {
|
||||||
|
* id: ["prpref_123", "prpref_321"],
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* is_tax_inclusive: false
|
||||||
|
* }
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
updatePricePreferences(
|
||||||
|
selector: FilterablePricePreferenceProps,
|
||||||
|
data: UpdatePricePreferenceDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO[]>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method soft deletes price preferences by their IDs.
|
||||||
|
*
|
||||||
|
* @param {string[]} pricePreferenceIds - The IDs of the price preferences.
|
||||||
|
* @param {SoftDeleteReturn<TReturnableLinkableKeys>} config - An object that is used to specify an entity's related entities that should be soft-deleted when the main entity is soft-deleted.
|
||||||
|
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
|
||||||
|
* @returns {Promise<void | Record<string, string[]>>} An object that includes the IDs of related records that were also soft deleted.
|
||||||
|
* The object's keys are the ID attribute names of the price preference entity's relations, and its value is an array of strings, each being the ID of a record associated.
|
||||||
|
*
|
||||||
|
* If there are no related records, the promise resolves to `void`.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* await pricingModuleService.softDeletePricePreferences([
|
||||||
|
* "prpref_123",
|
||||||
|
* "prpref_321",
|
||||||
|
* ])
|
||||||
|
*/
|
||||||
|
softDeletePricePreferences<TReturnableLinkableKeys extends string = string>(
|
||||||
|
pricePreferenceIds: string[],
|
||||||
|
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<Record<string, string[]> | void>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method restores soft deleted price preferences by their IDs.
|
||||||
|
*
|
||||||
|
* @param {string[]} pricePreferenceIds - The IDs of the price preferences.
|
||||||
|
* @param {RestoreReturn<TReturnableLinkableKeys>} config - Configurations determining which relations to restore along with each of the price preferences.
|
||||||
|
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
|
||||||
|
* @returns {Promise<void | Record<string, string[]>>} An object that includes the IDs of related records that were restored.
|
||||||
|
* The object's keys are the ID attribute names of the price preferences entity's relations,
|
||||||
|
* and its value is an array of strings, each being the ID of the record associated with the price preferences through this relation.
|
||||||
|
*
|
||||||
|
* If there are no related records restored, the promise resolves to `void`.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* await pricingModuleService.restorePricePreferences([
|
||||||
|
* "prpref_123",
|
||||||
|
* "prpref_321",
|
||||||
|
* ])
|
||||||
|
*/
|
||||||
|
restorePricePreferences<TReturnableLinkableKeys extends string = string>(
|
||||||
|
pricePreferenceIds: string[],
|
||||||
|
config?: RestoreReturn<TReturnableLinkableKeys>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<Record<string, string[]> | void>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method deletes price preferences by their IDs.
|
||||||
|
*
|
||||||
|
* @param {string[]} ids - The IDs of the price preferences to delete.
|
||||||
|
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
|
||||||
|
* @returns {Promise<void>} Resolves when the price preferences are successfully deleted.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* await pricingModuleService.deletePricePreferences(["prpref_123", "prpref_321"])
|
||||||
|
*/
|
||||||
|
deletePricePreferences(ids: string[], sharedContext?: Context): Promise<void>
|
||||||
}
|
}
|
||||||
|
|||||||
+149
-1
@@ -319,8 +319,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 1000,
|
calculated_amount: 1000,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 1000,
|
original_amount: 1000,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -353,8 +355,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 300,
|
calculated_amount: 300,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 300,
|
original_amount: 300,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -387,8 +391,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 1000,
|
calculated_amount: 1000,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 1000,
|
original_amount: 1000,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -432,8 +438,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 300,
|
calculated_amount: 300,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 300,
|
original_amount: 300,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -466,8 +474,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 1000,
|
calculated_amount: 1000,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 1000,
|
original_amount: 1000,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -500,8 +510,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 250,
|
calculated_amount: 250,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 250,
|
original_amount: 250,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -539,8 +551,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 300,
|
calculated_amount: 300,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 300,
|
original_amount: 300,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -579,8 +593,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 100,
|
calculated_amount: 100,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 100,
|
original_amount: 100,
|
||||||
currency_code: "EUR",
|
currency_code: "EUR",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -619,8 +635,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 300,
|
calculated_amount: 300,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 300,
|
original_amount: 300,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -659,8 +677,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 1000,
|
calculated_amount: 1000,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 1000,
|
original_amount: 1000,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -708,8 +728,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 300,
|
calculated_amount: 300,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 300,
|
original_amount: 300,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -750,8 +772,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: true,
|
is_calculated_price_price_list: true,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 232,
|
calculated_amount: 232,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 400,
|
original_amount: 400,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -799,8 +823,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: true,
|
is_calculated_price_price_list: true,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 232,
|
calculated_amount: 232,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 400,
|
original_amount: 400,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -840,8 +866,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: true,
|
is_calculated_price_price_list: true,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 232,
|
calculated_amount: 232,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 400,
|
original_amount: 400,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -878,8 +906,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: true,
|
is_calculated_price_price_list: true,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 232,
|
calculated_amount: 232,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 1000,
|
original_amount: 1000,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -919,8 +949,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: true,
|
is_calculated_price_price_list: true,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 232,
|
calculated_amount: 232,
|
||||||
is_original_price_price_list: true,
|
is_original_price_price_list: true,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 232,
|
original_amount: 232,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -959,8 +991,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 300,
|
calculated_amount: 300,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 300,
|
original_amount: 300,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -999,8 +1033,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 300,
|
calculated_amount: 300,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 300,
|
original_amount: 300,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -1052,8 +1088,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: true,
|
is_calculated_price_price_list: true,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 232,
|
calculated_amount: 232,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 400,
|
original_amount: 400,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -1106,8 +1144,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 400,
|
calculated_amount: 400,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 400,
|
original_amount: 400,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -1159,8 +1199,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: false,
|
is_calculated_price_price_list: false,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 400,
|
calculated_amount: 400,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 400,
|
original_amount: 400,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -1181,7 +1223,7 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should return price list prices for price list with customer groupst", async () => {
|
it("should return price list prices for price list with customer groups", async () => {
|
||||||
const [{ id }] = await createPriceLists(
|
const [{ id }] = await createPriceLists(
|
||||||
service,
|
service,
|
||||||
{},
|
{},
|
||||||
@@ -1214,8 +1256,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-EUR",
|
id: "price-set-EUR",
|
||||||
is_calculated_price_price_list: true,
|
is_calculated_price_price_list: true,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 200,
|
calculated_amount: 200,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: null,
|
original_amount: null,
|
||||||
currency_code: "EUR",
|
currency_code: "EUR",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -1265,8 +1309,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: true,
|
is_calculated_price_price_list: true,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 111,
|
calculated_amount: 111,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 400,
|
original_amount: 400,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -1316,8 +1362,10 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
{
|
{
|
||||||
id: "price-set-PLN",
|
id: "price-set-PLN",
|
||||||
is_calculated_price_price_list: true,
|
is_calculated_price_price_list: true,
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
calculated_amount: 232,
|
calculated_amount: 232,
|
||||||
is_original_price_price_list: false,
|
is_original_price_price_list: false,
|
||||||
|
is_original_price_tax_inclusive: false,
|
||||||
original_amount: 400,
|
original_amount: 400,
|
||||||
currency_code: "PLN",
|
currency_code: "PLN",
|
||||||
calculated_price: {
|
calculated_price: {
|
||||||
@@ -1338,6 +1386,106 @@ moduleIntegrationTestRunner<IPricingModuleService>({
|
|||||||
])
|
])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("Tax inclusivity", () => {
|
||||||
|
it("should return the currency tax inclusivity for the selected price when it is not region-based", async () => {
|
||||||
|
await (service as any).createPricePreferences([
|
||||||
|
{
|
||||||
|
attribute: "currency_code",
|
||||||
|
value: "PLN",
|
||||||
|
is_tax_inclusive: true,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const priceSetsResult = await service.calculatePrices(
|
||||||
|
{ id: ["price-set-PLN"] },
|
||||||
|
{
|
||||||
|
context: { currency_code: "PLN" },
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(priceSetsResult).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "price-set-PLN",
|
||||||
|
is_calculated_price_tax_inclusive: true,
|
||||||
|
calculated_amount: 1000,
|
||||||
|
is_original_price_tax_inclusive: true,
|
||||||
|
original_amount: 1000,
|
||||||
|
currency_code: "PLN",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should return the region tax inclusivity for the selected price when it is region-based", async () => {
|
||||||
|
await (service as any).createPricePreferences([
|
||||||
|
{
|
||||||
|
attribute: "currency_code",
|
||||||
|
value: "PLN",
|
||||||
|
is_tax_inclusive: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
attribute: "region_id",
|
||||||
|
value: "PL",
|
||||||
|
is_tax_inclusive: true,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const priceSetsResult = await service.calculatePrices(
|
||||||
|
{ id: ["price-set-PLN"] },
|
||||||
|
{
|
||||||
|
context: { currency_code: "PLN", region_id: "PL" },
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(priceSetsResult).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "price-set-PLN",
|
||||||
|
is_calculated_price_tax_inclusive: true,
|
||||||
|
calculated_amount: 300,
|
||||||
|
is_original_price_tax_inclusive: true,
|
||||||
|
original_amount: 300,
|
||||||
|
currency_code: "PLN",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should return the appropriate tax inclusive setting for each calculated and original price", async () => {
|
||||||
|
await createPriceLists(service, {}, {})
|
||||||
|
await (service as any).createPricePreferences([
|
||||||
|
{
|
||||||
|
attribute: "currency_code",
|
||||||
|
value: "PLN",
|
||||||
|
is_tax_inclusive: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
attribute: "region_id",
|
||||||
|
value: "PL",
|
||||||
|
is_tax_inclusive: true,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const priceSetsResult = await service.calculatePrices(
|
||||||
|
{ id: ["price-set-PLN"] },
|
||||||
|
{
|
||||||
|
context: {
|
||||||
|
currency_code: "PLN",
|
||||||
|
region_id: "PL",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(priceSetsResult).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "price-set-PLN",
|
||||||
|
is_calculated_price_tax_inclusive: false,
|
||||||
|
calculated_amount: 232,
|
||||||
|
is_original_price_tax_inclusive: true,
|
||||||
|
original_amount: 300,
|
||||||
|
currency_code: "PLN",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { defineJoinerConfig, Modules } from "@medusajs/utils"
|
import { defineJoinerConfig, Modules } from "@medusajs/utils"
|
||||||
import { Price, PriceList, PriceSet } from "@models"
|
import { Price, PriceList, PricePreference, PriceSet } from "@models"
|
||||||
|
|
||||||
export const joinerConfig = defineJoinerConfig(Modules.PRICING, {
|
export const joinerConfig = defineJoinerConfig(Modules.PRICING, {
|
||||||
models: [PriceSet, PriceList, Price],
|
models: [PriceSet, PriceList, Price],
|
||||||
@@ -7,5 +7,6 @@ export const joinerConfig = defineJoinerConfig(Modules.PRICING, {
|
|||||||
price_set_id: PriceSet.name,
|
price_set_id: PriceSet.name,
|
||||||
price_list_id: PriceList.name,
|
price_list_id: PriceList.name,
|
||||||
price_id: Price.name,
|
price_id: Price.name,
|
||||||
|
price_preference_id: PricePreference.name,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -271,6 +271,112 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"attribute": {
|
||||||
|
"name": "attribute",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"is_tax_inclusive": {
|
||||||
|
"name": "is_tax_inclusive",
|
||||||
|
"type": "boolean",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"default": "false",
|
||||||
|
"mappedType": "boolean"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"name": "created_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"name": "updated_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"deleted_at": {
|
||||||
|
"name": "deleted_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"length": 6,
|
||||||
|
"mappedType": "datetime"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "price_preference",
|
||||||
|
"schema": "public",
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"keyName": "IDX_price_preference_deleted_at",
|
||||||
|
"columnNames": [
|
||||||
|
"deleted_at"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": false,
|
||||||
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_price_preference_deleted_at\" ON \"price_preference\" (deleted_at) WHERE deleted_at IS NOT NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "IDX_price_preference_attribute_value",
|
||||||
|
"columnNames": [],
|
||||||
|
"composite": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": false,
|
||||||
|
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_price_preference_attribute_value\" ON \"price_preference\" (attribute, value) WHERE deleted_at IS NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "price_preference_pkey",
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"primary": true,
|
||||||
|
"unique": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checks": [],
|
||||||
|
"foreignKeys": {}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { Migration } from '@mikro-orm/migrations';
|
||||||
|
|
||||||
|
export class Migration20240704094505 extends Migration {
|
||||||
|
|
||||||
|
async up(): Promise<void> {
|
||||||
|
this.addSql('create table if not exists "price_preference" ("id" text not null, "attribute" text not null, "value" text null, "is_tax_inclusive" boolean not null default false, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "price_preference_pkey" primary key ("id"));');
|
||||||
|
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_price_preference_deleted_at" ON "price_preference" (deleted_at) WHERE deleted_at IS NOT NULL;');
|
||||||
|
this.addSql('CREATE UNIQUE INDEX IF NOT EXISTS "IDX_price_preference_attribute_value" ON "price_preference" (attribute, value) WHERE deleted_at IS NULL;');
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(): Promise<void> {
|
||||||
|
this.addSql('drop table if exists "price_preference" cascade;');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,3 +3,4 @@ export { default as PriceList } from "./price-list"
|
|||||||
export { default as PriceListRule } from "./price-list-rule"
|
export { default as PriceListRule } from "./price-list-rule"
|
||||||
export { default as PriceRule } from "./price-rule"
|
export { default as PriceRule } from "./price-rule"
|
||||||
export { default as PriceSet } from "./price-set"
|
export { default as PriceSet } from "./price-set"
|
||||||
|
export { default as PricePreference } from "./price-preference"
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
import {
|
||||||
|
createPsqlIndexStatementHelper,
|
||||||
|
DALUtils,
|
||||||
|
generateEntityId,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
import {
|
||||||
|
BeforeCreate,
|
||||||
|
Entity,
|
||||||
|
Filter,
|
||||||
|
OnInit,
|
||||||
|
PrimaryKey,
|
||||||
|
Property,
|
||||||
|
} from "@mikro-orm/core"
|
||||||
|
|
||||||
|
export const uniquePreferenceRuleIndexName =
|
||||||
|
"IDX_price_preference_attribute_value"
|
||||||
|
const UniquePreferenceRuleIndexStatement = createPsqlIndexStatementHelper({
|
||||||
|
name: uniquePreferenceRuleIndexName,
|
||||||
|
tableName: "price_preference",
|
||||||
|
columns: ["attribute", "value"],
|
||||||
|
unique: true,
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
})
|
||||||
|
|
||||||
|
const DeletedAtIndex = createPsqlIndexStatementHelper({
|
||||||
|
tableName: "price_preference",
|
||||||
|
columns: "deleted_at",
|
||||||
|
where: "deleted_at IS NOT NULL",
|
||||||
|
})
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||||
|
@UniquePreferenceRuleIndexStatement.MikroORMIndex()
|
||||||
|
export default class PricePreference {
|
||||||
|
@PrimaryKey({ columnType: "text" })
|
||||||
|
id: string
|
||||||
|
|
||||||
|
@Property({ columnType: "text" })
|
||||||
|
attribute: string
|
||||||
|
|
||||||
|
@Property({ columnType: "text", nullable: true })
|
||||||
|
value: string | null = null
|
||||||
|
|
||||||
|
@Property({ default: false })
|
||||||
|
is_tax_inclusive: boolean
|
||||||
|
|
||||||
|
@Property({
|
||||||
|
onCreate: () => new Date(),
|
||||||
|
columnType: "timestamptz",
|
||||||
|
defaultRaw: "now()",
|
||||||
|
})
|
||||||
|
created_at: Date
|
||||||
|
|
||||||
|
@Property({
|
||||||
|
onCreate: () => new Date(),
|
||||||
|
onUpdate: () => new Date(),
|
||||||
|
columnType: "timestamptz",
|
||||||
|
defaultRaw: "now()",
|
||||||
|
})
|
||||||
|
updated_at: Date
|
||||||
|
|
||||||
|
@DeletedAtIndex.MikroORMIndex()
|
||||||
|
@Property({ columnType: "timestamptz", nullable: true })
|
||||||
|
deleted_at: Date | null = null
|
||||||
|
|
||||||
|
@BeforeCreate()
|
||||||
|
onCreate() {
|
||||||
|
this.id = generateEntityId(this.id, "prpref")
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnInit()
|
||||||
|
onInit() {
|
||||||
|
this.id = generateEntityId(this.id, "prpref")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -83,10 +83,6 @@ export class PricingRepository
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
.leftJoin("price_list_rule as plr", "plr.price_list_id", "pl.id")
|
.leftJoin("price_list_rule as plr", "plr.price_list_id", "pl.id")
|
||||||
.orderBy([
|
|
||||||
{ column: "rules_count", order: "desc" },
|
|
||||||
{ column: "pl.rules_count", order: "desc" },
|
|
||||||
])
|
|
||||||
.groupBy("price.id", "pl.id")
|
.groupBy("price.id", "pl.id")
|
||||||
.having(
|
.having(
|
||||||
knex.raw(
|
knex.raw(
|
||||||
@@ -168,7 +164,6 @@ export class PricingRepository
|
|||||||
),
|
),
|
||||||
})
|
})
|
||||||
.join(priceSubQueryKnex.as("price"), "price.price_set_id", "ps.id")
|
.join(priceSubQueryKnex.as("price"), "price.price_set_id", "ps.id")
|
||||||
.leftJoin("price_rule as pr", "pr.price_id", "price.id")
|
|
||||||
.whereIn("ps.id", pricingFilters.id)
|
.whereIn("ps.id", pricingFilters.id)
|
||||||
.andWhere("price.currency_code", "=", currencyCode)
|
.andWhere("price.currency_code", "=", currencyCode)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
AddPricesDTO,
|
AddPricesDTO,
|
||||||
Context,
|
Context,
|
||||||
|
CreatePricePreferenceDTO,
|
||||||
CreatePriceRuleDTO,
|
CreatePriceRuleDTO,
|
||||||
CreatePricesDTO,
|
CreatePricesDTO,
|
||||||
CreatePriceSetDTO,
|
CreatePriceSetDTO,
|
||||||
@@ -9,15 +10,18 @@ import {
|
|||||||
InternalModuleDeclaration,
|
InternalModuleDeclaration,
|
||||||
ModuleJoinerConfig,
|
ModuleJoinerConfig,
|
||||||
ModulesSdkTypes,
|
ModulesSdkTypes,
|
||||||
|
PricePreferenceDTO,
|
||||||
PriceSetDTO,
|
PriceSetDTO,
|
||||||
PricingContext,
|
PricingContext,
|
||||||
PricingFilters,
|
PricingFilters,
|
||||||
PricingRepositoryService,
|
PricingRepositoryService,
|
||||||
PricingTypes,
|
PricingTypes,
|
||||||
|
UpsertPricePreferenceDTO,
|
||||||
UpsertPriceSetDTO,
|
UpsertPriceSetDTO,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
import {
|
import {
|
||||||
arrayDifference,
|
arrayDifference,
|
||||||
|
deduplicate,
|
||||||
EmitEvents,
|
EmitEvents,
|
||||||
GetIsoStringFromDate,
|
GetIsoStringFromDate,
|
||||||
groupBy,
|
groupBy,
|
||||||
@@ -34,7 +38,14 @@ import {
|
|||||||
simpleHash,
|
simpleHash,
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
|
|
||||||
import { Price, PriceList, PriceListRule, PriceRule, PriceSet } from "@models"
|
import {
|
||||||
|
Price,
|
||||||
|
PriceList,
|
||||||
|
PriceListRule,
|
||||||
|
PriceRule,
|
||||||
|
PriceSet,
|
||||||
|
PricePreference,
|
||||||
|
} from "@models"
|
||||||
|
|
||||||
import { ServiceTypes } from "@types"
|
import { ServiceTypes } from "@types"
|
||||||
import { eventBuilders, validatePriceListDates } from "@utils"
|
import { eventBuilders, validatePriceListDates } from "@utils"
|
||||||
@@ -48,6 +59,7 @@ type InjectedDependencies = {
|
|||||||
priceRuleService: ModulesSdkTypes.IMedusaInternalService<any>
|
priceRuleService: ModulesSdkTypes.IMedusaInternalService<any>
|
||||||
priceService: ModulesSdkTypes.IMedusaInternalService<any>
|
priceService: ModulesSdkTypes.IMedusaInternalService<any>
|
||||||
priceListService: ModulesSdkTypes.IMedusaInternalService<any>
|
priceListService: ModulesSdkTypes.IMedusaInternalService<any>
|
||||||
|
pricePreferenceService: ModulesSdkTypes.IMedusaInternalService<any>
|
||||||
priceListRuleService: ModulesSdkTypes.IMedusaInternalService<any>
|
priceListRuleService: ModulesSdkTypes.IMedusaInternalService<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +69,7 @@ const generateMethodForModels = {
|
|||||||
PriceListRule,
|
PriceListRule,
|
||||||
PriceRule,
|
PriceRule,
|
||||||
Price,
|
Price,
|
||||||
|
PricePreference,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class PricingModuleService
|
export default class PricingModuleService
|
||||||
@@ -70,6 +83,8 @@ export default class PricingModuleService
|
|||||||
}
|
}
|
||||||
PriceList: { dto: PricingTypes.PriceListDTO }
|
PriceList: { dto: PricingTypes.PriceListDTO }
|
||||||
PriceListRule: { dto: PricingTypes.PriceListRuleDTO }
|
PriceListRule: { dto: PricingTypes.PriceListRuleDTO }
|
||||||
|
// PricePreference: { dto: PricingTypes.PricePreferenceDTO }
|
||||||
|
PricePreference: { dto: any }
|
||||||
}>(generateMethodForModels)
|
}>(generateMethodForModels)
|
||||||
implements PricingTypes.IPricingModuleService
|
implements PricingTypes.IPricingModuleService
|
||||||
{
|
{
|
||||||
@@ -80,6 +95,7 @@ export default class PricingModuleService
|
|||||||
protected readonly priceService_: ModulesSdkTypes.IMedusaInternalService<Price>
|
protected readonly priceService_: ModulesSdkTypes.IMedusaInternalService<Price>
|
||||||
protected readonly priceListService_: ModulesSdkTypes.IMedusaInternalService<PriceList>
|
protected readonly priceListService_: ModulesSdkTypes.IMedusaInternalService<PriceList>
|
||||||
protected readonly priceListRuleService_: ModulesSdkTypes.IMedusaInternalService<PriceListRule>
|
protected readonly priceListRuleService_: ModulesSdkTypes.IMedusaInternalService<PriceListRule>
|
||||||
|
protected readonly pricePreferenceService_: ModulesSdkTypes.IMedusaInternalService<PricePreference>
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
{
|
{
|
||||||
@@ -88,6 +104,7 @@ export default class PricingModuleService
|
|||||||
priceSetService,
|
priceSetService,
|
||||||
priceRuleService,
|
priceRuleService,
|
||||||
priceService,
|
priceService,
|
||||||
|
pricePreferenceService,
|
||||||
priceListService,
|
priceListService,
|
||||||
priceListRuleService,
|
priceListRuleService,
|
||||||
}: InjectedDependencies,
|
}: InjectedDependencies,
|
||||||
@@ -101,6 +118,7 @@ export default class PricingModuleService
|
|||||||
this.priceSetService_ = priceSetService
|
this.priceSetService_ = priceSetService
|
||||||
this.priceRuleService_ = priceRuleService
|
this.priceRuleService_ = priceRuleService
|
||||||
this.priceService_ = priceService
|
this.priceService_ = priceService
|
||||||
|
this.pricePreferenceService_ = pricePreferenceService
|
||||||
this.priceListService_ = priceListService
|
this.priceListService_ = priceListService
|
||||||
this.priceListRuleService_ = priceListRuleService
|
this.priceListRuleService_ = priceListRuleService
|
||||||
}
|
}
|
||||||
@@ -240,41 +258,93 @@ export default class PricingModuleService
|
|||||||
)
|
)
|
||||||
|
|
||||||
const pricesSetPricesMap = groupBy(results, "price_set_id")
|
const pricesSetPricesMap = groupBy(results, "price_set_id")
|
||||||
|
const priceIds: string[] = []
|
||||||
|
pricesSetPricesMap.forEach(
|
||||||
|
(prices: PricingTypes.CalculatedPriceSetDTO[], key) => {
|
||||||
|
const priceListPrice = prices.find((p) => p.price_list_id)
|
||||||
|
const defaultPrice = prices?.find((p) => !p.price_list_id)
|
||||||
|
if (!prices.length || (!priceListPrice && !defaultPrice)) {
|
||||||
|
pricesSetPricesMap.delete(key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let calculatedPrice: PricingTypes.CalculatedPriceSetDTO | undefined =
|
||||||
|
defaultPrice
|
||||||
|
let originalPrice: PricingTypes.CalculatedPriceSetDTO | undefined =
|
||||||
|
defaultPrice
|
||||||
|
if (priceListPrice) {
|
||||||
|
calculatedPrice = priceListPrice
|
||||||
|
|
||||||
|
if (priceListPrice.price_list_type === PriceListType.OVERRIDE) {
|
||||||
|
originalPrice = priceListPrice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pricesSetPricesMap.set(key, { calculatedPrice, originalPrice })
|
||||||
|
priceIds.push(
|
||||||
|
...(deduplicate(
|
||||||
|
[calculatedPrice?.id, originalPrice?.id].filter(Boolean)
|
||||||
|
) as string[])
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// We use the price rules to get the right preferences for the price
|
||||||
|
const priceRulesForPrices = await this.priceRuleService_.list(
|
||||||
|
{ price_id: priceIds },
|
||||||
|
{ take: null }
|
||||||
|
)
|
||||||
|
|
||||||
|
const priceRulesPriceMap = groupBy(priceRulesForPrices, "price_id")
|
||||||
|
|
||||||
|
// Note: For now the preferences are intentionally kept very simple and explicit - they use either the region or currency,
|
||||||
|
// so we hard-code those as the possible filters here. This can be made more flexible if needed later on.
|
||||||
|
const pricingPreferences = await this.pricePreferenceService_.list(
|
||||||
|
{
|
||||||
|
$or: Object.entries(pricingContext)
|
||||||
|
.filter(([key, val]) => {
|
||||||
|
return key === "region_id" || key === "currency_code"
|
||||||
|
})
|
||||||
|
.map(([key, val]) => ({
|
||||||
|
attribute: key,
|
||||||
|
value: val,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
const calculatedPrices: PricingTypes.CalculatedPriceSet[] =
|
const calculatedPrices: PricingTypes.CalculatedPriceSet[] =
|
||||||
pricingFilters.id
|
pricingFilters.id
|
||||||
.map((priceSetId: string): PricingTypes.CalculatedPriceSet | null => {
|
.map((priceSetId: string): PricingTypes.CalculatedPriceSet | null => {
|
||||||
// This is where we select prices, for now we just do a first match based on the database results
|
const prices = pricesSetPricesMap.get(priceSetId)
|
||||||
// which is prioritized by rules_count first for exact match and then deafult_priority of the rule_type
|
if (!prices) {
|
||||||
|
|
||||||
// TODO: inject custom price selection here
|
|
||||||
|
|
||||||
const prices = pricesSetPricesMap.get(priceSetId) || []
|
|
||||||
if (!prices.length) {
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
const {
|
||||||
const priceListPrice = prices.find((p) => p.price_list_id)
|
calculatedPrice,
|
||||||
|
originalPrice,
|
||||||
const defaultPrice = prices?.find((p) => !p.price_list_id)
|
}: {
|
||||||
|
calculatedPrice: PricingTypes.CalculatedPriceSetDTO
|
||||||
let calculatedPrice: PricingTypes.CalculatedPriceSetDTO = defaultPrice
|
originalPrice: PricingTypes.CalculatedPriceSetDTO | undefined
|
||||||
let originalPrice: PricingTypes.CalculatedPriceSetDTO = defaultPrice
|
} = prices
|
||||||
|
|
||||||
if (priceListPrice) {
|
|
||||||
calculatedPrice = priceListPrice
|
|
||||||
|
|
||||||
if (priceListPrice.price_list_type === PriceListType.OVERRIDE) {
|
|
||||||
originalPrice = priceListPrice
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: priceSetId,
|
id: priceSetId,
|
||||||
is_calculated_price_price_list: !!calculatedPrice?.price_list_id,
|
is_calculated_price_price_list: !!calculatedPrice?.price_list_id,
|
||||||
|
is_calculated_price_tax_inclusive: isTaxInclusive(
|
||||||
|
priceRulesPriceMap.get(calculatedPrice.id),
|
||||||
|
pricingPreferences
|
||||||
|
),
|
||||||
calculated_amount: parseInt(calculatedPrice?.amount || "") || null,
|
calculated_amount: parseInt(calculatedPrice?.amount || "") || null,
|
||||||
|
|
||||||
is_original_price_price_list: !!originalPrice?.price_list_id,
|
is_original_price_price_list: !!originalPrice?.price_list_id,
|
||||||
|
is_original_price_tax_inclusive: originalPrice?.id
|
||||||
|
? isTaxInclusive(
|
||||||
|
priceRulesPriceMap.get(originalPrice.id),
|
||||||
|
pricingPreferences
|
||||||
|
)
|
||||||
|
: false,
|
||||||
original_amount: parseInt(originalPrice?.amount || "") || null,
|
original_amount: parseInt(originalPrice?.amount || "") || null,
|
||||||
|
|
||||||
currency_code: calculatedPrice?.currency_code || null,
|
currency_code: calculatedPrice?.currency_code || null,
|
||||||
@@ -641,6 +711,102 @@ export default class PricingModuleService
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
|
async createPricePreferences(
|
||||||
|
data: PricingTypes.CreatePricePreferenceDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO>
|
||||||
|
async createPricePreferences(
|
||||||
|
data: PricingTypes.CreatePricePreferenceDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO[]>
|
||||||
|
|
||||||
|
@InjectManager("baseRepository_")
|
||||||
|
@EmitEvents()
|
||||||
|
async createPricePreferences(
|
||||||
|
data:
|
||||||
|
| PricingTypes.CreatePricePreferenceDTO
|
||||||
|
| PricingTypes.CreatePricePreferenceDTO[],
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<PricePreferenceDTO | PricePreferenceDTO[]> {
|
||||||
|
const preferences = await this.pricePreferenceService_.create(
|
||||||
|
data,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
|
||||||
|
return await this.baseRepository_.serialize<any[]>(preferences)
|
||||||
|
}
|
||||||
|
|
||||||
|
async upsertPricePreferences(
|
||||||
|
data: UpsertPricePreferenceDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO[]>
|
||||||
|
async upsertPricePreferences(
|
||||||
|
data: UpsertPricePreferenceDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO>
|
||||||
|
|
||||||
|
@InjectManager("baseRepository_")
|
||||||
|
async upsertPricePreferences(
|
||||||
|
data: UpsertPricePreferenceDTO | UpsertPricePreferenceDTO[],
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<PricePreferenceDTO | PricePreferenceDTO[]> {
|
||||||
|
const input = Array.isArray(data) ? data : [data]
|
||||||
|
const forUpdate = input.filter(
|
||||||
|
(
|
||||||
|
pricePreference
|
||||||
|
): pricePreference is ServiceTypes.UpdatePricePreferenceInput =>
|
||||||
|
!!pricePreference.id
|
||||||
|
)
|
||||||
|
const forCreate = input.filter(
|
||||||
|
(pricePreference): pricePreference is CreatePricePreferenceDTO =>
|
||||||
|
!pricePreference.id
|
||||||
|
)
|
||||||
|
|
||||||
|
const operations: Promise<PricePreference[]>[] = []
|
||||||
|
|
||||||
|
if (forCreate.length) {
|
||||||
|
operations.push(
|
||||||
|
this.pricePreferenceService_.create(forCreate, sharedContext)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (forUpdate.length) {
|
||||||
|
operations.push(
|
||||||
|
this.pricePreferenceService_.update(forUpdate, sharedContext)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = (await promiseAll(operations)).flat()
|
||||||
|
return await this.baseRepository_.serialize<
|
||||||
|
PricePreferenceDTO[] | PricePreferenceDTO
|
||||||
|
>(Array.isArray(data) ? result : result[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
|
async updatePricePreferences(
|
||||||
|
id: string,
|
||||||
|
data: PricingTypes.UpdatePricePreferenceDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO>
|
||||||
|
async updatePricePreferences(
|
||||||
|
selector: PricingTypes.FilterablePricePreferenceProps,
|
||||||
|
data: PricingTypes.UpdatePricePreferenceDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PricePreferenceDTO[]>
|
||||||
|
|
||||||
|
@InjectManager("baseRepository_")
|
||||||
|
async updatePricePreferences(
|
||||||
|
idOrSelector: string | PricingTypes.FilterablePricePreferenceProps,
|
||||||
|
data: PricingTypes.UpdatePricePreferenceDTO,
|
||||||
|
@MedusaContext() sharedContext: Context = {}
|
||||||
|
): Promise<PricePreferenceDTO | PricePreferenceDTO[]> {
|
||||||
|
const preferences = await this.pricePreferenceService_.update(
|
||||||
|
data,
|
||||||
|
sharedContext
|
||||||
|
)
|
||||||
|
return await this.baseRepository_.serialize<any[]>(preferences)
|
||||||
|
}
|
||||||
|
|
||||||
@InjectTransactionManager("baseRepository_")
|
@InjectTransactionManager("baseRepository_")
|
||||||
protected async createPriceSets_(
|
protected async createPriceSets_(
|
||||||
data: PricingTypes.CreatePriceSetDTO[],
|
data: PricingTypes.CreatePriceSetDTO[],
|
||||||
@@ -1253,6 +1419,31 @@ export default class PricingModuleService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isTaxInclusive = (
|
||||||
|
priceRules: PriceRule[],
|
||||||
|
preferences: PricePreference[]
|
||||||
|
) => {
|
||||||
|
const regionPreference = preferences.find((p) => p.attribute === "region_id")
|
||||||
|
const currencyPreference = preferences.find(
|
||||||
|
(p) => p.attribute === "currency_code"
|
||||||
|
)
|
||||||
|
const regionRule = priceRules?.find((rule) => rule.attribute === "region_id")
|
||||||
|
|
||||||
|
if (
|
||||||
|
regionRule &&
|
||||||
|
regionPreference &&
|
||||||
|
regionRule.value === regionPreference.value
|
||||||
|
) {
|
||||||
|
return regionPreference.is_tax_inclusive
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currencyPreference) {
|
||||||
|
return currencyPreference.is_tax_inclusive
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
const hashPrice = (
|
const hashPrice = (
|
||||||
price: PricingTypes.PriceDTO | PricingTypes.CreatePricesDTO
|
price: PricingTypes.PriceDTO | PricingTypes.CreatePricesDTO
|
||||||
): string => {
|
): string => {
|
||||||
|
|||||||
@@ -1,3 +1,36 @@
|
|||||||
export * from "./price-list"
|
import { PriceListStatus, PricingTypes } from "@medusajs/types"
|
||||||
export * from "./price-set"
|
|
||||||
export * from "./price"
|
export interface CreatePriceListDTO extends PricingTypes.CreatePriceListDTO {
|
||||||
|
rules_count?: number
|
||||||
|
price_list_rules?: {
|
||||||
|
attribute: string
|
||||||
|
value: string
|
||||||
|
}[]
|
||||||
|
prices?: PricingTypes.CreatePriceListPriceDTO[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdatePriceListDTO {
|
||||||
|
id: string
|
||||||
|
title?: string
|
||||||
|
description?: string | null
|
||||||
|
starts_at?: string | null
|
||||||
|
ends_at?: string | null
|
||||||
|
status?: PriceListStatus
|
||||||
|
number_rules?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdatePriceSetInput extends PricingTypes.UpdatePriceSetDTO {
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpsertPriceDTO
|
||||||
|
extends Omit<PricingTypes.CreatePriceDTO, "rules"> {
|
||||||
|
id?: string
|
||||||
|
price_list_id?: string
|
||||||
|
price_rules: PricingTypes.CreatePriceRuleDTO[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdatePricePreferenceInput
|
||||||
|
extends PricingTypes.UpdatePricePreferenceDTO {
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
import { PriceListStatus, PricingTypes } from "@medusajs/types"
|
|
||||||
|
|
||||||
export interface CreatePriceListDTO extends PricingTypes.CreatePriceListDTO {
|
|
||||||
rules_count?: number
|
|
||||||
price_list_rules?: {
|
|
||||||
attribute: string
|
|
||||||
value: string
|
|
||||||
}[]
|
|
||||||
prices?: PricingTypes.CreatePriceListPriceDTO[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UpdatePriceListDTO {
|
|
||||||
id: string
|
|
||||||
title?: string
|
|
||||||
description?: string | null
|
|
||||||
starts_at?: string | null
|
|
||||||
ends_at?: string | null
|
|
||||||
status?: PriceListStatus
|
|
||||||
number_rules?: number
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import { UpdatePriceSetDTO } from "@medusajs/types"
|
|
||||||
|
|
||||||
export interface UpdatePriceSetInput extends UpdatePriceSetDTO {
|
|
||||||
id: string
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import { PricingTypes } from "@medusajs/types"
|
|
||||||
|
|
||||||
export interface UpsertPriceDTO
|
|
||||||
extends Omit<PricingTypes.CreatePriceDTO, "rules"> {
|
|
||||||
id?: string
|
|
||||||
price_list_id?: string
|
|
||||||
price_rules: PricingTypes.CreatePriceRuleDTO[]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user