Creates setRegion
This commit is contained in:
@@ -4,7 +4,7 @@ export const carts = {
|
|||||||
emptyCart: {
|
emptyCart: {
|
||||||
_id: IdMap.getId("emptyCart"),
|
_id: IdMap.getId("emptyCart"),
|
||||||
title: "test",
|
title: "test",
|
||||||
region: IdMap.getId("testRegion"),
|
region_id: IdMap.getId("testRegion"),
|
||||||
items: [],
|
items: [],
|
||||||
shippingAddress: {},
|
shippingAddress: {},
|
||||||
billingAddress: {},
|
billingAddress: {},
|
||||||
@@ -12,9 +12,9 @@ export const carts = {
|
|||||||
customer_id: "",
|
customer_id: "",
|
||||||
},
|
},
|
||||||
cartWithLine: {
|
cartWithLine: {
|
||||||
_id: IdMap.getId("emptyCart"),
|
_id: IdMap.getId("cartWithLine"),
|
||||||
title: "test",
|
title: "test",
|
||||||
region: IdMap.getId("testRegion"),
|
region_id: IdMap.getId("testRegion"),
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
_id: IdMap.getId("existingLine"),
|
_id: IdMap.getId("existingLine"),
|
||||||
@@ -39,6 +39,99 @@ export const carts = {
|
|||||||
discounts: [],
|
discounts: [],
|
||||||
customer_id: "",
|
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 = {
|
export const CartModelMock = {
|
||||||
@@ -54,6 +147,12 @@ export const CartModelMock = {
|
|||||||
if (query._id === IdMap.getId("cartWithLine")) {
|
if (query._id === IdMap.getId("cartWithLine")) {
|
||||||
return Promise.resolve(carts.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)
|
return Promise.resolve(undefined)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class CartModel extends BaseModel {
|
|||||||
billing_address: { type: AddressSchema },
|
billing_address: { type: AddressSchema },
|
||||||
shipping_address: { type: AddressSchema },
|
shipping_address: { type: AddressSchema },
|
||||||
items: { type: [LineItemSchema], default: [] },
|
items: { type: [LineItemSchema], default: [] },
|
||||||
region: { type: String, required: true },
|
region_id: { type: String },
|
||||||
discounts: { type: [String], default: [] },
|
discounts: { type: [String], default: [] },
|
||||||
customer_id: { type: String },
|
customer_id: { type: String },
|
||||||
payment_method: { type: PaymentMethodSchema },
|
payment_method: { type: PaymentMethodSchema },
|
||||||
|
|||||||
@@ -141,6 +141,25 @@ export const ProductVariantServiceMock = {
|
|||||||
|
|
||||||
return Promise.reject(new Error("Not found"))
|
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()),
|
delete: jest.fn().mockReturnValue(Promise.resolve()),
|
||||||
addOptionValue: jest.fn().mockImplementation((variantId, optionId, value) => {
|
addOptionValue: jest.fn().mockImplementation((variantId, optionId, value) => {
|
||||||
return Promise.resolve({})
|
return Promise.resolve({})
|
||||||
|
|||||||
@@ -452,4 +452,120 @@ describe("CartService", () => {
|
|||||||
expect(CartModelMock.updateOne).toHaveBeenCalledTimes(0)
|
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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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
|
* @param {Object} selector - the query object for find
|
||||||
* @return {Promise} the result of the find operation
|
* @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
|
* @param {string} regionId - the id of the region to set the cart to
|
||||||
* @return {Promise} the result of the update operation
|
* @return {Promise} the result of the update operation
|
||||||
*/
|
*/
|
||||||
setRegion(cartId, regionId) {
|
async setRegion(cartId, regionId) {
|
||||||
// Check if cart exists
|
const cart = await this.retrieve(cartId)
|
||||||
// Check if region exists
|
if (!cart) {
|
||||||
//
|
throw new MedusaError(
|
||||||
// If the cart already has items, go through the items and update the prices
|
MedusaError.Types.NOT_FOUND,
|
||||||
// based on new tax rate, new currency, region specific pricing.
|
"The cart was not found"
|
||||||
//
|
)
|
||||||
// If addresses are set, clear the country code.
|
}
|
||||||
//
|
|
||||||
// If the cart has a shipping method, clear this.
|
const region = await this.regionService_.retrieve(regionId)
|
||||||
//
|
if (!region) {
|
||||||
// Update the 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 })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user