Creates setRegion

This commit is contained in:
Sebastian Rindom
2020-02-05 16:20:04 +01:00
parent 2f2dd5eae3
commit 8fb5845874
5 changed files with 334 additions and 16 deletions
+102 -3
View File
@@ -4,7 +4,7 @@ export const carts = {
emptyCart: {
_id: IdMap.getId("emptyCart"),
title: "test",
region: IdMap.getId("testRegion"),
region_id: IdMap.getId("testRegion"),
items: [],
shippingAddress: {},
billingAddress: {},
@@ -12,9 +12,9 @@ export const carts = {
customer_id: "",
},
cartWithLine: {
_id: IdMap.getId("emptyCart"),
_id: IdMap.getId("cartWithLine"),
title: "test",
region: IdMap.getId("testRegion"),
region_id: IdMap.getId("testRegion"),
items: [
{
_id: IdMap.getId("existingLine"),
@@ -39,6 +39,99 @@ export const carts = {
discounts: [],
customer_id: "",
},
completeCart: {
_id: IdMap.getId("complete-cart"),
title: "test",
region_id: IdMap.getId("region-france"),
items: [],
payment_method: {
provider_id: "stripe",
data: {
yes: "sir",
},
},
shipping_method: {
provider_id: "gls",
data: {
yes: "sir",
},
},
shipping_address: {
first_name: "hi",
last_name: "you",
country_code: "DK",
city: "of lights",
address_1: "You bet street",
postal_code: "4242",
},
billing_address: {
first_name: "hi",
last_name: "you",
country_code: "DK",
city: "of lights",
address_1: "You bet street",
postal_code: "4242",
},
discounts: [],
customer_id: "",
},
frCart: {
_id: IdMap.getId("fr-cart"),
title: "test",
region_id: IdMap.getId("region-france"),
items: [
{
_id: IdMap.getId("line"),
title: "merge line",
description: "This is a new line",
thumbnail: "test-img-yeah.com/thumb",
content: [
{
unit_price: 8,
variant: {
_id: IdMap.getId("eur-8-us-10"),
},
product: {
_id: IdMap.getId("product"),
},
quantity: 1,
},
{
unit_price: 10,
variant: {
_id: IdMap.getId("eur-10-us-12"),
},
product: {
_id: IdMap.getId("product"),
},
quantity: 1,
},
],
quantity: 10,
},
{
_id: IdMap.getId("existingLine"),
title: "merge line",
description: "This is a new line",
thumbnail: "test-img-yeah.com/thumb",
content: {
unit_price: 10,
variant: {
_id: IdMap.getId("eur-10-us-12"),
},
product: {
_id: IdMap.getId("product"),
},
quantity: 1,
},
quantity: 10,
},
],
shippingAddress: {},
billingAddress: {},
discounts: [],
customer_id: "",
},
}
export const CartModelMock = {
@@ -54,6 +147,12 @@ export const CartModelMock = {
if (query._id === IdMap.getId("cartWithLine")) {
return Promise.resolve(carts.cartWithLine)
}
if (query._id === IdMap.getId("fr-cart")) {
return Promise.resolve(carts.frCart)
}
if (query._id === IdMap.getId("complete-cart")) {
return Promise.resolve(carts.completeCart)
}
return Promise.resolve(undefined)
}),
}
+1 -1
View File
@@ -17,7 +17,7 @@ class CartModel extends BaseModel {
billing_address: { type: AddressSchema },
shipping_address: { type: AddressSchema },
items: { type: [LineItemSchema], default: [] },
region: { type: String, required: true },
region_id: { type: String },
discounts: { type: [String], default: [] },
customer_id: { type: String },
payment_method: { type: PaymentMethodSchema },
@@ -141,6 +141,25 @@ export const ProductVariantServiceMock = {
return Promise.reject(new Error("Not found"))
}),
getRegionPrice: jest.fn().mockImplementation((variantId, regionId) => {
if (variantId === IdMap.getId("eur-10-us-12")) {
if (regionId === IdMap.getId("region-france")) {
return Promise.resolve(10)
} else {
return Promise.resolve(12)
}
}
if (variantId === IdMap.getId("eur-8-us-10")) {
if (regionId === IdMap.getId("region-france")) {
return Promise.resolve(8)
} else {
return Promise.resolve(10)
}
}
return Promise.reject(new Error("Not found"))
}),
delete: jest.fn().mockReturnValue(Promise.resolve()),
addOptionValue: jest.fn().mockImplementation((variantId, optionId, value) => {
return Promise.resolve({})
@@ -452,4 +452,120 @@ describe("CartService", () => {
expect(CartModelMock.updateOne).toHaveBeenCalledTimes(0)
})
})
describe("setRegion", () => {
const cartService = new CartService({
cartModel: CartModelMock,
regionService: RegionServiceMock,
productVariantService: ProductVariantServiceMock,
})
beforeEach(() => {
jest.clearAllMocks()
})
it("successfully set new region", async () => {
await cartService.setRegion(
IdMap.getId("fr-cart"),
IdMap.getId("region-us")
)
expect(CartModelMock.updateOne).toHaveBeenCalledTimes(1)
expect(CartModelMock.updateOne).toHaveBeenCalledWith(
{
_id: IdMap.getId("fr-cart"),
},
{
$set: {
region_id: IdMap.getId("region-us"),
items: [
{
_id: IdMap.getId("line"),
title: "merge line",
description: "This is a new line",
thumbnail: "test-img-yeah.com/thumb",
content: [
{
unit_price: 10,
variant: {
_id: IdMap.getId("eur-8-us-10"),
},
product: {
_id: IdMap.getId("product"),
},
quantity: 1,
},
{
unit_price: 12,
variant: {
_id: IdMap.getId("eur-10-us-12"),
},
product: {
_id: IdMap.getId("product"),
},
quantity: 1,
},
],
quantity: 10,
},
{
_id: IdMap.getId("existingLine"),
title: "merge line",
description: "This is a new line",
thumbnail: "test-img-yeah.com/thumb",
content: {
unit_price: 12,
variant: {
_id: IdMap.getId("eur-10-us-12"),
},
product: {
_id: IdMap.getId("product"),
},
quantity: 1,
},
quantity: 10,
},
],
},
}
)
})
it("successfully set new region", async () => {
await cartService.setRegion(
IdMap.getId("complete-cart"),
IdMap.getId("region-us")
)
expect(CartModelMock.updateOne).toHaveBeenCalledTimes(1)
expect(CartModelMock.updateOne).toHaveBeenCalledWith(
{
_id: IdMap.getId("complete-cart"),
},
{
$set: {
region_id: IdMap.getId("region-us"),
shipping_method: undefined,
payment_method: undefined,
shipping_address: {
first_name: "hi",
last_name: "you",
country_code: "",
city: "of lights",
address_1: "You bet street",
postal_code: "4242",
},
billing_address: {
first_name: "hi",
last_name: "you",
country_code: "",
city: "of lights",
address_1: "You bet street",
postal_code: "4242",
},
},
}
)
})
})
})
+96 -12
View File
@@ -138,6 +138,38 @@ class CartService extends BaseService {
)
}
/**
* Transforms some line item content to have unit_prices corresponding to a
* given region's pricing scheme.
* @param {(LineItemContent | LineItemContentArray)} - the content of the line
* item
* @param {string} regionId - the id of the region whose price we should
* update to
* @return {(LineItemContent | LineItemContentArray)} true if the inventory
* covers the line item.
*/
async updateContentPrice_(content, regionId) {
if (Array.isArray(content)) {
return await Promise.all(
content.map(async c => {
const unitPrice = await this.productVariantService_.getRegionPrice(
c.variant._id,
regionId
)
c.unit_price = unitPrice
return c
})
)
}
const unitPrice = await this.productVariantService_.getRegionPrice(
content.variant._id,
regionId
)
content.unit_price = unitPrice
return content
}
/**
* @param {Object} selector - the query object for find
* @return {Promise} the result of the find operation
@@ -348,18 +380,70 @@ class CartService extends BaseService {
* @param {string} regionId - the id of the region to set the cart to
* @return {Promise} the result of the update operation
*/
setRegion(cartId, regionId) {
// Check if cart exists
// Check if region exists
//
// If the cart already has items, go through the items and update the prices
// based on new tax rate, new currency, region specific pricing.
//
// If addresses are set, clear the country code.
//
// If the cart has a shipping method, clear this.
//
// Update the region
async setRegion(cartId, regionId) {
const cart = await this.retrieve(cartId)
if (!cart) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
"The cart was not found"
)
}
const region = await this.regionService_.retrieve(regionId)
if (!region) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`The region: ${regionId} was not found`
)
}
let update = {
region_id: region._id,
}
// If the cart contains items we want to change the unit_price field of each
// item to correspond to the price given in the region
if (cart.items.length) {
const newItems = await Promise.all(
cart.items.map(async lineItem => {
lineItem.content = await this.updateContentPrice_(
lineItem.content,
region._id
)
return lineItem
})
)
update.items = newItems
}
// If the country code of a shipping address is set we need to clear it
let shippingAddress = cart.shipping_address
if (!_.isEmpty(shippingAddress) && shippingAddress.country_code) {
shippingAddress.country_code = ""
update.shipping_address = shippingAddress
}
// If the country code of a billing address is set we need to clear it
let billingAddress = cart.billing_address
if (!_.isEmpty(billingAddress) && billingAddress.country_code) {
billingAddress.country_code = ""
update.billing_address = billingAddress
}
// Shipping methods are determined by region so the user needs to find a
// new shipping method
if (!_.isEmpty(cart.shipping_method)) {
update.shipping_method = undefined
}
// Payment methods are region specific so the user needs to find a
// new payment method
if (!_.isEmpty(cart.payment_method)) {
update.payment_method = undefined
}
return this.cartModel_.updateOne({ _id: cart._id }, { $set: update })
}
/**