Get region specific prices from the product variant service
This commit is contained in:
1 parent
8fb5845874
commit
64afe158bb
3 files changed
+113
-1
No files matched your search
@@ -22,6 +22,18 @@ export const regions = {
|
|||||||
countries: ["US"],
|
countries: ["US"],
|
||||||
currency_code: "usd",
|
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 = {
|
export const RegionServiceMock = {
|
||||||
@@ -35,6 +47,12 @@ export const RegionServiceMock = {
|
|||||||
if (regionId === IdMap.getId("region-us")) {
|
if (regionId === IdMap.getId("region-us")) {
|
||||||
return Promise.resolve(regions.regionUs)
|
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)
|
return Promise.resolve(undefined)
|
||||||
}),
|
}),
|
||||||
list: jest.fn().mockImplementation(data => {
|
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
|
* Sets the price of a specific region
|
||||||
* @param {string} variantId - the id of the variant to update
|
* @param {string} variantId - the id of the variant to update
|
||||||
@@ -216,7 +268,7 @@ class ProductVariantService extends BaseService {
|
|||||||
if (!region) {
|
if (!region) {
|
||||||
throw new MedusaError(
|
throw new MedusaError(
|
||||||
MedusaError.Types.NOT_FOUND,
|
MedusaError.Types.NOT_FOUND,
|
||||||
`Region: ${region} was not found`
|
`Region: ${regionId} was not found`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user