fix(medusa): allow price list prices update when region_id is provided (#1472)

This commit is contained in:
Frane Polić
2022-05-11 07:43:19 +02:00
committed by GitHub
parent 327614e126
commit 03c5617896
4 changed files with 279 additions and 4 deletions

View File

@@ -149,6 +149,37 @@ Object {
}
`;
exports[`/admin/price-lists POST /admin/price-lists/:id updates price list prices (inser a new MA for a specific region) 1`] = `
Array [
Object {
"amount": 101,
"created_at": Any<String>,
"currency_code": "eur",
"deleted_at": null,
"id": Any<String>,
"max_quantity": null,
"min_quantity": null,
"price_list_id": "pl_with_some_ma",
"region_id": "region-pl",
"updated_at": Any<String>,
"variant_id": "test-variant",
},
Object {
"amount": 1001,
"created_at": Any<String>,
"currency_code": "usd",
"deleted_at": null,
"id": "ma_test_4",
"max_quantity": null,
"min_quantity": null,
"price_list_id": "pl_with_some_ma",
"region_id": null,
"updated_at": Any<String>,
"variant_id": "test-variant",
},
]
`;
exports[`/admin/price-lists POST /admin/price-lists/:id updates the amount and currency of a price in the price list 1`] = `
Object {
"amount": 250,
@@ -291,3 +322,47 @@ Array [
},
]
`;
exports[`/admin/price-lists POST /admin/price-lists/:id/prices/batch Adds a batch of new prices where a MA record have a \`region_id\` instead of \`currency_code\` 1`] = `
Array [
Object {
"amount": 70,
"created_at": Any<String>,
"currency_code": "usd",
"deleted_at": null,
"id": "ma_test_4",
"max_quantity": null,
"min_quantity": null,
"price_list_id": "pl_with_some_ma",
"region_id": null,
"updated_at": Any<String>,
"variant_id": "test-variant",
},
Object {
"amount": 100,
"created_at": Any<String>,
"currency_code": "eur",
"deleted_at": null,
"id": Any<String>,
"max_quantity": null,
"min_quantity": null,
"price_list_id": "pl_with_some_ma",
"region_id": "region-pl",
"updated_at": Any<String>,
"variant_id": "test-variant",
},
Object {
"amount": 200,
"created_at": Any<String>,
"currency_code": "usd",
"deleted_at": null,
"id": Any<String>,
"max_quantity": null,
"min_quantity": null,
"price_list_id": "pl_with_some_ma",
"region_id": null,
"updated_at": Any<String>,
"variant_id": "test-variant",
},
]
`;

View File

@@ -509,6 +509,68 @@ describe("/admin/price-lists", () => {
updated_at: expect.any(String),
})
})
it("updates price list prices (inser a new MA for a specific region)", async () => {
const api = useApi()
const payload = {
prices: [
// update MA
{
id: "ma_test_4",
amount: 1001,
currency_code: "usd",
variant_id: "test-variant",
},
// create MA
{
amount: 101,
variant_id: "test-variant",
region_id: "region-pl",
},
],
}
const response = await api
.post("/admin/price-lists/pl_with_some_ma", payload, {
headers: {
Authorization: "Bearer test_token",
},
})
.catch((err) => {
console.warn(err.response.data)
})
expect(response.status).toEqual(200)
expect(response.data.price_list.prices.length).toEqual(2)
expect(response.data.price_list.prices).toMatchSnapshot([
{
id: expect.any(String),
currency_code: "eur",
amount: 101,
min_quantity: null,
max_quantity: null,
price_list_id: "pl_with_some_ma",
variant_id: "test-variant",
region_id: "region-pl",
created_at: expect.any(String),
updated_at: expect.any(String),
deleted_at: null,
},
{
id: "ma_test_4",
currency_code: "usd",
amount: 1001,
price_list_id: "pl_with_some_ma",
variant_id: "test-variant",
region_id: null,
created_at: expect.any(String),
updated_at: expect.any(String),
deleted_at: null,
},
])
})
})
describe("POST /admin/price-lists/:id/prices/batch", () => {
@@ -573,7 +635,9 @@ describe("/admin/price-lists", () => {
expect(response.status).toEqual(200)
expect(response.data.price_list.prices.length).toEqual(6)
expect(response.data.price_list.prices).toMatchSnapshot([
expect(
response.data.price_list.prices.sort((a, b) => b.amount - a.amount)
).toMatchSnapshot([
{
id: expect.any(String),
price_list_id: "pl_no_customer_groups",
@@ -725,6 +789,78 @@ describe("/admin/price-lists", () => {
},
])
})
it("Adds a batch of new prices where a MA record have a `region_id` instead of `currency_code`", async () => {
const api = useApi()
const payload = {
prices: [
{
amount: 100,
variant_id: "test-variant",
region_id: "region-pl",
},
{
amount: 200,
variant_id: "test-variant",
currency_code: "usd",
},
],
}
const response = await api
.post("/admin/price-lists/pl_with_some_ma/prices/batch", payload, {
headers: {
Authorization: "Bearer test_token",
},
})
.catch((err) => {
console.warn(err.response.data)
})
expect(response.status).toEqual(200)
expect(response.data.price_list.prices.length).toEqual(3) // initially this PL has 1 MA record
expect(response.data.price_list.prices).toMatchSnapshot([
{
id: "ma_test_4",
currency_code: "usd",
amount: 70,
price_list_id: "pl_with_some_ma",
variant_id: "test-variant",
region_id: null,
created_at: expect.any(String),
updated_at: expect.any(String),
deleted_at: null,
},
{
id: expect.any(String),
currency_code: "eur",
amount: 100,
min_quantity: null,
max_quantity: null,
price_list_id: "pl_with_some_ma",
variant_id: "test-variant",
region_id: "region-pl",
created_at: expect.any(String),
updated_at: expect.any(String),
deleted_at: null,
},
{
id: expect.any(String),
currency_code: "usd",
amount: 200,
min_quantity: null,
max_quantity: null,
price_list_id: "pl_with_some_ma",
variant_id: "test-variant",
region_id: null,
created_at: expect.any(String),
updated_at: expect.any(String),
deleted_at: null,
},
])
})
})
describe("DELETE /admin/price-lists/:id", () => {

View File

@@ -1,4 +1,4 @@
const { PriceList, MoneyAmount } = require("@medusajs/medusa")
const { Region, PriceList, MoneyAmount } = require("@medusajs/medusa")
module.exports = async (connection, data = {}) => {
const manager = connection.manager
@@ -15,6 +15,13 @@ module.exports = async (connection, data = {}) => {
await manager.save(priceListNoCustomerGroups)
await manager.insert(Region, {
id: "region-pl",
name: "Test Region",
currency_code: "eur",
tax_rate: 0,
})
const moneyAmount1 = await manager.create(MoneyAmount, {
id: "ma_test_1",
amount: 100,
@@ -50,4 +57,27 @@ module.exports = async (connection, data = {}) => {
})
await manager.save(moneyAmount3)
const moneyAmount4 = await manager.create(MoneyAmount, {
id: "ma_test_4",
amount: 70,
currency_code: "usd",
variant_id: "test-variant",
})
await manager.save(moneyAmount4)
const priceListWithMA = await manager.create(PriceList, {
id: "pl_with_some_ma",
name: "Weeken sale",
description: "Desc. of the list",
type: "sale",
status: "active",
starts_at: "2022-07-01T00:00:00.000Z",
ends_at: "2022-07-31T00:00:00.000Z",
})
priceListWithMA.prices = [moneyAmount4]
await manager.save(priceListWithMA)
}

View File

@@ -12,14 +12,17 @@ import {
CreatePriceListInput,
FilterablePriceListProps,
PriceListPriceCreateInput,
PriceListPriceUpdateInput,
UpdatePriceListInput,
} from "../types/price-list"
import { formatException } from "../utils/exception-formatter"
import RegionService from "./region"
import ProductService from "./product"
type PriceListConstructorProps = {
manager: EntityManager
customerGroupService: CustomerGroupService
regionService: RegionService
productService: ProductService
priceListRepository: typeof PriceListRepository
moneyAmountRepository: typeof MoneyAmountRepository
@@ -32,6 +35,7 @@ type PriceListConstructorProps = {
class PriceListService extends BaseService {
private manager_: EntityManager
private customerGroupService_: CustomerGroupService
private regionService_: RegionService
private productService_: ProductService
private priceListRepo_: typeof PriceListRepository
private moneyAmountRepo_: typeof MoneyAmountRepository
@@ -39,6 +43,7 @@ class PriceListService extends BaseService {
constructor({
manager,
customerGroupService,
regionService,
productService,
priceListRepository,
moneyAmountRepository,
@@ -47,6 +52,7 @@ class PriceListService extends BaseService {
this.manager_ = manager
this.customerGroupService_ = customerGroupService
this.productService_ = productService
this.regionService_ = regionService
this.priceListRepo_ = priceListRepository
this.moneyAmountRepo_ = moneyAmountRepository
}
@@ -60,6 +66,7 @@ class PriceListService extends BaseService {
manager: transactionManager,
customerGroupService: this.customerGroupService_,
productService: this.productService_,
regionService: this.regionService_,
priceListRepository: this.priceListRepo_,
moneyAmountRepository: this.moneyAmountRepo_,
})
@@ -152,7 +159,8 @@ class PriceListService extends BaseService {
await priceListRepo.save(priceList)
if (prices) {
await moneyAmountRepo.updatePriceListPrices(id, prices)
const prices_ = await this.addCurrencyFromRegion(prices)
await moneyAmountRepo.updatePriceListPrices(id, prices_)
}
if (customer_groups) {
@@ -184,7 +192,8 @@ class PriceListService extends BaseService {
const priceList = await this.retrieve(id, { select: ["id"] })
await moneyAmountRepo.addPriceListPrices(priceList.id, prices, replace)
const prices_ = await this.addCurrencyFromRegion(prices)
await moneyAmountRepo.addPriceListPrices(priceList.id, prices_, replace)
const result = await this.retrieve(priceList.id, {
relations: ["prices"],
@@ -336,6 +345,31 @@ class PriceListService extends BaseService {
return [productsWithPrices, count]
})
}
/**
* Add `currency_code` to an MA record if `region_id`is passed.
* @param prices - a list of PriceListPrice(Create/Update)Input records
* @return {Promise} updated `prices` list
*/
protected async addCurrencyFromRegion<
T extends PriceListPriceUpdateInput | PriceListPriceCreateInput
>(prices: T[]): Promise<T[]> {
const prices_: typeof prices = []
for (const p of prices) {
if (p.region_id) {
const region = await this.regionService_
.withTransaction(this.manager_)
.retrieve(p.region_id)
p.currency_code = region.currency_code
}
prices_.push(p)
}
return prices_
}
}
export default PriceListService