Adds DiscountService and TotalsService (#26)

This commit is contained in:
Oliver Windall Juhl authored and GitHub committed 2020-04-07 12:48:57 +02:00
1 parent f6d5180e5f
commit aff1ec3390
15 files changed
+1404 -2

No files matched your search

@@ -1,4 +1,5 @@
import { IdMap } from "medusa-test-utils"
import { discounts } from "./discount"
export const carts = {
emptyCart: {
@@ -255,6 +256,59 @@ export const carts = {
discounts: [],
customer_id: "",
},
discountCartWithExisting: {
_id: IdMap.getId("discount-cart-with-existing"),
discounts: [discounts.item10Percent],
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,
},
],
},
}
export const CartModelMock = {
@@ -285,6 +339,9 @@ export const CartModelMock = {
if (query._id === IdMap.getId("complete-cart")) {
return Promise.resolve(carts.completeCart)
}
if (query._id === IdMap.getId("discount-cart-with-existing")) {
return Promise.resolve(carts.discountCartWithExisting)
}
return Promise.resolve(undefined)
}),
}
@@ -0,0 +1,146 @@
import { IdMap } from "medusa-test-utils"
export const discounts = {
total10Percent: {
_id: IdMap.getId("total10"),
code: "10%OFF",
discount_rule: {
type: "percentage",
allocation: "total",
value: 10,
},
regions: [IdMap.getId("region-france")],
},
item10Percent: {
_id: IdMap.getId("item10Percent"),
code: "MEDUSA",
discount_rule: {
type: "percentage",
allocation: "item",
value: 10,
valid_for: [IdMap.getId("eur-8-us-10"), IdMap.getId("eur-10-us-12")],
},
regions: [IdMap.getId("region-france")],
},
total10Fixed: {
_id: IdMap.getId("total10Fixed"),
code: "MEDUSA",
discount_rule: {
type: "fixed",
allocation: "total",
value: 10,
},
regions: [IdMap.getId("region-france")],
},
item9Fixed: {
_id: IdMap.getId("item9Fixed"),
code: "MEDUSA",
discount_rule: {
type: "fixed",
allocation: "item",
value: 9,
valid_for: [IdMap.getId("eur-8-us-10"), IdMap.getId("eur-10-us-12")],
},
regions: [IdMap.getId("region-france")],
},
item2Fixed: {
_id: IdMap.getId("item2Fixed"),
code: "MEDUSA",
discount_rule: {
type: "fixed",
allocation: "item",
value: 2,
valid_for: [IdMap.getId("eur-8-us-10"), IdMap.getId("eur-10-us-12")],
},
regions: [IdMap.getId("region-france")],
},
item10FixedNoVariants: {
_id: IdMap.getId("item10FixedNoVariants"),
code: "MEDUSA",
discount_rule: {
type: "fixed",
allocation: "item",
value: 10,
valid_for: [],
},
regions: [IdMap.getId("region-france")],
},
expiredDiscount: {
_id: IdMap.getId("expired"),
code: "MEDUSA",
ends_at: new Date("December 17, 1995 03:24:00"),
discount_rule: {
type: "fixed",
allocation: "item",
value: 10,
valid_for: [],
},
regions: [IdMap.getId("region-france")],
},
freeShipping: {
_id: IdMap.getId("freeshipping"),
code: "FREESHIPPING",
discount_rule: {
type: "free_shipping",
allocation: "total",
value: 10,
valid_for: [],
},
regions: [IdMap.getId("region-france")],
},
USDiscount: {
_id: IdMap.getId("us-discount"),
code: "US10",
discount_rule: {
type: "free_shipping",
allocation: "total",
value: 10,
valid_for: [],
},
regions: [IdMap.getId("us")],
},
alreadyExists: {
code: "ALREADYEXISTS",
discount_rule: {
type: "percentage",
allocation: "total",
value: 20,
},
regions: [IdMap.getId("fr-cart")],
},
}
export const DiscountModelMock = {
create: jest.fn().mockReturnValue(Promise.resolve()),
updateOne: jest.fn().mockImplementation((query, update) => {
return Promise.resolve()
}),
deleteOne: jest.fn().mockReturnValue(Promise.resolve()),
findOne: jest.fn().mockImplementation(query => {
if (query._id === IdMap.getId("total10")) {
return Promise.resolve(discounts.total10Percent)
}
if (query._id === IdMap.getId("item10Percent")) {
return Promise.resolve(discounts.item10Percent)
}
if (query._id === IdMap.getId("total10Fixed")) {
return Promise.resolve(discounts.total10Fixed)
}
if (query._id === IdMap.getId("item2Fixed")) {
return Promise.resolve(discounts.item2Fixed)
}
if (query._id === IdMap.getId("item10FixedNoVariants")) {
return Promise.resolve(discounts.item10FixedNoVariants)
}
if (query._id === IdMap.getId("expired")) {
return Promise.resolve(discounts.expiredDiscount)
}
if (query.code === "10%OFF") {
return Promise.resolve(discounts.total10Percent)
}
if (query.code === "aLrEaDyExIsts") {
return Promise.resolve(discounts.alreadyExists)
}
return Promise.resolve(undefined)
}),
}
+2 -1
View File
@@ -8,6 +8,7 @@ import LineItemSchema from "./schemas/line-item"
import PaymentMethodSchema from "./schemas/payment-method"
import ShippingMethodSchema from "./schemas/shipping-method"
import AddressSchema from "./schemas/address"
import DiscountModel from "./discount"
class CartModel extends BaseModel {
static modelName = "Cart"
@@ -18,7 +19,7 @@ class CartModel extends BaseModel {
shipping_address: { type: AddressSchema, default: {} },
items: { type: [LineItemSchema], default: [] },
region_id: { type: String, required: true },
discounts: { type: [String], default: [] },
discounts: { type: [DiscountModel.schema], default: [] },
customer_id: { type: String, default: "" },
payment_sessions: { type: [PaymentMethodSchema], default: [] },
shipping_options: { type: [ShippingMethodSchema], default: [] },
+19
View File
@@ -0,0 +1,19 @@
import { BaseModel } from "medusa-interfaces"
import DiscountRule from "./schemas/discount-rule"
class DiscountModel extends BaseModel {
static modelName = "Discount"
static schema = {
code: { type: String, required: true, unique: true },
discount_rule: { type: DiscountRule, required: true },
usage_count: { type: Number, default: 0 },
disabled: { type: Boolean, default: false },
starts_at: { type: Date },
ends_at: { type: Date },
regions: { type: [String], default: [] },
metadata: { type: mongoose.Schema.Types.Mixed, default: {} },
}
}
export default DiscountModel
@@ -0,0 +1,28 @@
import mongoose from "mongoose"
export default new mongoose.Schema({
description: { type: String },
// Fixed, percentage or free shipping is allowed as type.
// The fixed discount type can be used as normal coupon code, giftcards,
// store credits and possibly more.
// The percentage discount type can be used as normal coupon code, giftcards
// and possibly more.
// The free shipping discount type is used only to give free shipping.
type: { type: String, required: true }, // Fixed, percent, free shipping
// The value is simply the amount of discount a customer or user will have.
// This depends on the type above, since percentage can not be above 100.
value: { type: Number, required: true },
// This is either total, meaning that the discount will be applied to the
// total price of the cart
// or item, meaning that the discount can be applied to the product variants
// in the valid_for array. Lastly the allocation is completely ignored if
// discount type is free shipping.
allocation: { type: String, required: true },
// Id's of product variants. Depends on allocation.
// If total is set, then the valid_for will not be used for anything,
// since the discount will work for the cart total. Else if item allocation
// is chosen, then we will go through the cart and apply the coupon code to
// all the valid product variants.
valid_for: { type: [String], default: [] },
usage_limit: { type: Number },
})