Get region specific prices from the product variant service
This commit is contained in:
@@ -22,6 +22,18 @@ export const regions = {
|
||||
countries: ["US"],
|
||||
currency_code: "usd",
|
||||
},
|
||||
regionGermany: {
|
||||
_id: IdMap.getId("region-de"),
|
||||
name: "Germany",
|
||||
countries: ["DE"],
|
||||
currency_code: "eur",
|
||||
},
|
||||
regionSweden: {
|
||||
_id: IdMap.getId("region-se"),
|
||||
name: "Sweden",
|
||||
countries: ["SE"],
|
||||
currency_code: "sek",
|
||||
},
|
||||
}
|
||||
|
||||
export const RegionServiceMock = {
|
||||
@@ -35,6 +47,12 @@ export const RegionServiceMock = {
|
||||
if (regionId === IdMap.getId("region-us")) {
|
||||
return Promise.resolve(regions.regionUs)
|
||||
}
|
||||
if (regionId === IdMap.getId("region-de")) {
|
||||
return Promise.resolve(regions.regionGermany)
|
||||
}
|
||||
if (regionId === IdMap.getId("region-se")) {
|
||||
return Promise.resolve(regions.regionSweden)
|
||||
}
|
||||
return Promise.resolve(undefined)
|
||||
}),
|
||||
list: jest.fn().mockImplementation(data => {
|
||||
|
||||
@@ -659,4 +659,46 @@ describe("ProductVariantService", () => {
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("getRegionPrice", () => {
|
||||
const productVariantService = new ProductVariantService({
|
||||
productVariantModel: ProductVariantModelMock,
|
||||
regionService: RegionServiceMock,
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it("gets region specific price", async () => {
|
||||
const res = await productVariantService.getRegionPrice(
|
||||
IdMap.getId("eur-prices"),
|
||||
IdMap.getId("region-france")
|
||||
)
|
||||
|
||||
expect(res).toEqual(950)
|
||||
})
|
||||
|
||||
it("gets currency default price", async () => {
|
||||
const res = await productVariantService.getRegionPrice(
|
||||
IdMap.getId("eur-prices"),
|
||||
IdMap.getId("region-de")
|
||||
)
|
||||
|
||||
expect(res).toEqual(1000)
|
||||
})
|
||||
|
||||
it("throws if no region or currency", async () => {
|
||||
try {
|
||||
const res = await productVariantService.getRegionPrice(
|
||||
IdMap.getId("eur-prices"),
|
||||
IdMap.getId("region-se")
|
||||
)
|
||||
} catch (err) {
|
||||
expect(err.message).toEqual(
|
||||
"A price for region: Sweden could not be found"
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -196,6 +196,58 @@ class ProductVariantService extends BaseService {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the price specific to a region. If no region specific money amount
|
||||
* exists the function will try to use a currency price. If no default
|
||||
* currency price exists the function will throw an error.
|
||||
* @param {string} variantId - the id of the variant to get price from
|
||||
* @param {string} regionId - the id of the region to get price for
|
||||
* @return {number} the price specific to the region
|
||||
*/
|
||||
async getRegionPrice(variantId, regionId) {
|
||||
const variant = await this.retrieve(variantId)
|
||||
if (!variant) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_FOUND,
|
||||
`Variant: ${variantId} was not found`
|
||||
)
|
||||
}
|
||||
|
||||
const region = await this.regionService_.retrieve(regionId)
|
||||
if (!region) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_FOUND,
|
||||
`Region: ${regionId} was not found`
|
||||
)
|
||||
}
|
||||
|
||||
let price
|
||||
|
||||
variant.prices.forEach(({ region_id, amount, currency_code }) => {
|
||||
if (!price && !region_id && currency_code === region.currency_code) {
|
||||
// If we haven't yet found a price and the current money amount is
|
||||
// the default money amount for the currency of the region we have found
|
||||
// a possible price match
|
||||
price = amount
|
||||
} else if (region_id === region._id) {
|
||||
// If the region matches directly with the money amount this is the best
|
||||
// price
|
||||
price = amount
|
||||
}
|
||||
})
|
||||
|
||||
// Return the price if we found a suitable match
|
||||
if (price) {
|
||||
return price
|
||||
}
|
||||
|
||||
// If we got this far no price could be found for the region
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_FOUND,
|
||||
`A price for region: ${region.name} could not be found`
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the price of a specific region
|
||||
* @param {string} variantId - the id of the variant to update
|
||||
@@ -216,7 +268,7 @@ class ProductVariantService extends BaseService {
|
||||
if (!region) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_FOUND,
|
||||
`Region: ${region} was not found`
|
||||
`Region: ${regionId} was not found`
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user