feat: allow product selection on discounts allocated to a specific item (#395)

This commit is contained in:
Sebastian Mateos Nicolajsen
2021-10-11 13:46:32 +02:00
committed by GitHub
parent 3d891c9b4f
commit 84d4d791ea
25 changed files with 138 additions and 25 deletions
@@ -106,7 +106,13 @@ class WebshipperFulfillmentService extends FulfillmentService {
const fromOrder = await this.orderService_.retrieve(orderId, { const fromOrder = await this.orderService_.retrieve(orderId, {
select: ["total"], select: ["total"],
relations: ["discounts", "shipping_address", "returns"], relations: [
"discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_address",
"returns",
],
}) })
const methodData = returnOrder.shipping_method.data const methodData = returnOrder.shipping_method.data
@@ -286,10 +292,11 @@ class WebshipperFulfillmentService extends FulfillmentService {
)) && )) &&
this.invoiceGenerator_.createCertificateOfOrigin this.invoiceGenerator_.createCertificateOfOrigin
) { ) {
const base64Coo = await this.invoiceGenerator_.createCertificateOfOrigin( const base64Coo =
fromOrder, await this.invoiceGenerator_.createCertificateOfOrigin(
fulfillmentItems fromOrder,
) fulfillmentItems
)
certificateOfOrigin = await this.client_.documents certificateOfOrigin = await this.client_.documents
.create({ .create({
@@ -419,9 +426,8 @@ class WebshipperFulfillmentService extends FulfillmentService {
url: l.url, url: l.url,
tracking_number: l.number, tracking_number: l.number,
})) }))
const [orderId, fulfillmentIndex] = wsOrder.data.attributes.ext_ref.split( const [orderId, fulfillmentIndex] =
"." wsOrder.data.attributes.ext_ref.split(".")
)
if (orderId.charAt(0).toLowerCase() === "s") { if (orderId.charAt(0).toLowerCase() === "s") {
if (fulfillmentIndex.startsWith("ful")) { if (fulfillmentIndex.startsWith("ful")) {
@@ -44,6 +44,8 @@ class OrderSubscriber {
"billing_address", "billing_address",
"shipping_address", "shipping_address",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_methods", "shipping_methods",
"payments", "payments",
"fulfillments", "fulfillments",
@@ -146,6 +148,8 @@ class OrderSubscriber {
"billing_address", "billing_address",
"shipping_address", "shipping_address",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_methods", "shipping_methods",
"payments", "payments",
"fulfillments", "fulfillments",
@@ -253,6 +257,8 @@ class OrderSubscriber {
"billing_address", "billing_address",
"shipping_address", "shipping_address",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_methods", "shipping_methods",
"payments", "payments",
"fulfillments", "fulfillments",
@@ -320,6 +320,8 @@ class SendGridService extends NotificationService {
"billing_address", "billing_address",
"shipping_address", "shipping_address",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_methods", "shipping_methods",
"shipping_methods.shipping_option", "shipping_methods.shipping_option",
"payments", "payments",
@@ -363,6 +365,8 @@ class SendGridService extends NotificationService {
"billing_address", "billing_address",
"shipping_address", "shipping_address",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_methods", "shipping_methods",
"shipping_methods.shipping_option", "shipping_methods.shipping_option",
"payments", "payments",
@@ -496,6 +500,8 @@ class SendGridService extends NotificationService {
relations: [ relations: [
"items", "items",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_address", "shipping_address",
"returns", "returns",
"swaps", "swaps",
@@ -601,6 +607,8 @@ class SendGridService extends NotificationService {
relations: [ relations: [
"items", "items",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_address", "shipping_address",
"swaps", "swaps",
"swaps.additional_items", "swaps.additional_items",
@@ -686,7 +694,14 @@ class SendGridService extends NotificationService {
}) })
const order = await this.orderService_.retrieve(swap.order_id, { const order = await this.orderService_.retrieve(swap.order_id, {
relations: ["items", "discounts", "swaps", "swaps.additional_items"], relations: [
"items",
"discounts",
"discounts.rule",
"discounts.rule.valid_for",
"swaps",
"swaps.additional_items",
],
}) })
let merged = [...order.items] let merged = [...order.items]
@@ -40,6 +40,8 @@ class SlackService extends BaseService {
"billing_address", "billing_address",
"shipping_address", "shipping_address",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_methods", "shipping_methods",
"payments", "payments",
"fulfillments", "fulfillments",
@@ -1,4 +1,5 @@
import { MedusaError, Validator } from "medusa-core-utils" import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations } from "."
/** /**
* @oas [post] /discounts * @oas [post] /discounts
@@ -96,11 +97,10 @@ export default async (req, res) => {
const discountService = req.scope.resolve("discountService") const discountService = req.scope.resolve("discountService")
const created = await discountService.create(value) const created = await discountService.create(value)
const discount = await discountService.retrieve(created.id, [ const discount = await discountService.retrieve(
"rule", created.id,
"rule.valid_for", defaultRelations
"regions", )
])
res.status(200).json({ discount }) res.status(200).json({ discount })
} catch (err) { } catch (err) {
@@ -57,6 +57,7 @@ export const defaultCartRelations = [
"payment_sessions", "payment_sessions",
"shipping_methods.shipping_option", "shipping_methods.shipping_option",
"discounts", "discounts",
"discounts.rule",
] ]
export const defaultCartFields = [ export const defaultCartFields = [
@@ -43,7 +43,14 @@ export default async (req, res) => {
.withTransaction(manager) .withTransaction(manager)
.retrieve(draftOrder.cart_id, { .retrieve(draftOrder.cart_id, {
select: ["total"], select: ["total"],
relations: ["discounts", "shipping_methods", "region", "items"], relations: [
"discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_methods",
"region",
"items",
],
}) })
await paymentProviderService await paymentProviderService
@@ -7,6 +7,8 @@ const defaultRelations = [
"billing_address", "billing_address",
"shipping_address", "shipping_address",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_methods", "shipping_methods",
"payments", "payments",
"fulfillments", "fulfillments",
@@ -202,7 +202,12 @@ export default async (req, res) => {
const order = await orderService const order = await orderService
.withTransaction(manager) .withTransaction(manager)
.retrieve(id, { .retrieve(id, {
relations: ["items", "discounts"], relations: [
"items",
"cart",
"cart.discounts",
"cart.discounts.rule",
],
}) })
await claimService.withTransaction(manager).create({ await claimService.withTransaction(manager).create({
@@ -221,6 +221,8 @@ export const defaultRelations = [
"billing_address", "billing_address",
"shipping_address", "shipping_address",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_methods", "shipping_methods",
"payments", "payments",
"fulfillments", "fulfillments",
@@ -316,6 +318,8 @@ export const allowedRelations = [
"billing_address", "billing_address",
"shipping_address", "shipping_address",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_methods", "shipping_methods",
"payments", "payments",
"fulfillments", "fulfillments",
@@ -116,4 +116,6 @@ export const defaultRelations = [
"payment_sessions", "payment_sessions",
"shipping_methods.shipping_option", "shipping_methods.shipping_option",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
] ]
@@ -36,6 +36,8 @@ export const defaultRelations = [
"items.variant.product", "items.variant.product",
"shipping_methods", "shipping_methods",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"customer", "customer",
"payments", "payments",
"region", "region",
@@ -74,6 +76,8 @@ export const allowedRelations = [
"items.variant.product", "items.variant.product",
"shipping_methods", "shipping_methods",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"customer", "customer",
"payments", "payments",
"region", "region",
+1 -1
View File
@@ -35,7 +35,7 @@ export class Discount {
@Column({ nullable: true }) @Column({ nullable: true })
rule_id: string rule_id: string
@ManyToOne(() => DiscountRule, { cascade: true, eager: true }) @ManyToOne(() => DiscountRule, { cascade: true })
@JoinColumn({ name: "rule_id" }) @JoinColumn({ name: "rule_id" })
rule: DiscountRule rule: DiscountRule
@@ -647,12 +647,13 @@ describe("CartService", () => {
"shipping_address", "shipping_address",
"billing_address", "billing_address",
"gift_cards", "gift_cards",
"discounts",
"customer", "customer",
"region", "region",
"payment_sessions", "payment_sessions",
"region.countries", "region.countries",
"discounts",
"discounts.rule", "discounts.rule",
"discounts.rule.valid_for",
"discounts.regions", "discounts.regions",
], ],
{ {
@@ -13,6 +13,9 @@ describe("DiscountService", () => {
id: IdMap.getId("france"), id: IdMap.getId("france"),
} }
}, },
withTransaction: function() {
return this
},
} }
const discountService = new DiscountService({ const discountService = new DiscountService({
@@ -231,6 +231,8 @@ describe("OrderService", () => {
"payment", "payment",
"items", "items",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"gift_cards", "gift_cards",
"shipping_methods", "shipping_methods",
], ],
@@ -198,6 +198,7 @@ describe("SwapService", () => {
"order.swaps", "order.swaps",
"order.swaps.additional_items", "order.swaps.additional_items",
"order.discounts", "order.discounts",
"order.discounts.rule",
"additional_items", "additional_items",
"return_order", "return_order",
"return_order.items", "return_order.items",
+29 -4
View File
@@ -166,6 +166,8 @@ class CartService extends BaseService {
relationSet.add("items") relationSet.add("items")
relationSet.add("gift_cards") relationSet.add("gift_cards")
relationSet.add("discounts") relationSet.add("discounts")
relationSet.add("discounts.rule")
relationSet.add("discounts.rule.valid_for")
//relationSet.add("discounts.parent_discount") //relationSet.add("discounts.parent_discount")
//relationSet.add("discounts.parent_discount.rule") //relationSet.add("discounts.parent_discount.rule")
//relationSet.add("discounts.parent_discount.regions") //relationSet.add("discounts.parent_discount.regions")
@@ -600,12 +602,13 @@ class CartService extends BaseService {
"shipping_address", "shipping_address",
"billing_address", "billing_address",
"gift_cards", "gift_cards",
"discounts",
"customer", "customer",
"region", "region",
"payment_sessions", "payment_sessions",
"region.countries", "region.countries",
"discounts",
"discounts.rule", "discounts.rule",
"discounts.rule.valid_for",
"discounts.regions", "discounts.regions",
], ],
}) })
@@ -871,6 +874,7 @@ class CartService extends BaseService {
async applyDiscount(cart, discountCode) { async applyDiscount(cart, discountCode) {
const discount = await this.discountService_.retrieveByCode(discountCode, [ const discount = await this.discountService_.retrieveByCode(discountCode, [
"rule", "rule",
"rule.valid_for",
"regions", "regions",
]) ])
@@ -968,7 +972,13 @@ class CartService extends BaseService {
async removeDiscount(cartId, discountCode) { async removeDiscount(cartId, discountCode) {
return this.atomicPhase_(async manager => { return this.atomicPhase_(async manager => {
const cart = await this.retrieve(cartId, { const cart = await this.retrieve(cartId, {
relations: ["discounts", "payment_sessions", "shipping_methods"], relations: [
"discounts",
"discounts.rule",
"discounts.rule.valid_for",
"payment_sessions",
"shipping_methods",
],
}) })
if (cart.discounts.some(({ rule }) => rule.type === "free_shipping")) { if (cart.discounts.some(({ rule }) => rule.type === "free_shipping")) {
@@ -1165,6 +1175,8 @@ class CartService extends BaseService {
relations: [ relations: [
"items", "items",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"gift_cards", "gift_cards",
"billing_address", "billing_address",
"shipping_address", "shipping_address",
@@ -1317,6 +1329,8 @@ class CartService extends BaseService {
relations: [ relations: [
"shipping_methods", "shipping_methods",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_methods.shipping_option", "shipping_methods.shipping_option",
"items", "items",
"items.variant", "items.variant",
@@ -1353,7 +1367,12 @@ class CartService extends BaseService {
} }
const result = await this.retrieve(cartId, { const result = await this.retrieve(cartId, {
relations: ["discounts", "shipping_methods"], relations: [
"discounts",
"discounts.rule",
"discounts.rule.valid_for",
"shipping_methods",
],
}) })
// if cart has freeshipping, adjust price // if cart has freeshipping, adjust price
@@ -1507,7 +1526,13 @@ class CartService extends BaseService {
async delete(cartId) { async delete(cartId) {
return this.atomicPhase_(async manager => { return this.atomicPhase_(async manager => {
const cart = await this.retrieve(cartId, { const cart = await this.retrieve(cartId, {
relations: ["items", "discounts", "payment_sessions"], relations: [
"items",
"discounts",
"discounts.rule",
"discounts.rule.valid_for",
"payment_sessions",
],
}) })
if (cart.completed_at) { if (cart.completed_at) {
+8 -1
View File
@@ -180,12 +180,16 @@ class DiscountService extends BaseService {
const discountRepo = manager.getCustomRepository(this.discountRepository_) const discountRepo = manager.getCustomRepository(this.discountRepository_)
const ruleRepo = manager.getCustomRepository(this.discountRuleRepository_) const ruleRepo = manager.getCustomRepository(this.discountRuleRepository_)
if (discount.rule?.valid_for) {
discount.rule.valid_for = discount.rule.valid_for.map(id => ({ id }))
}
const validatedRule = this.validateDiscountRule_(discount.rule) const validatedRule = this.validateDiscountRule_(discount.rule)
if (discount.regions) { if (discount.regions) {
discount.regions = await Promise.all( discount.regions = await Promise.all(
discount.regions.map(regionId => discount.regions.map(regionId =>
this.regionService_.retrieve(regionId) this.regionService_.withTransaction(manager).retrieve(regionId)
) )
) )
} }
@@ -293,6 +297,9 @@ class DiscountService extends BaseService {
if (rule) { if (rule) {
discount.rule = this.validateDiscountRule_(rule) discount.rule = this.validateDiscountRule_(rule)
if (rule.valid_for) {
discount.rule.valid_for = discount.rule.valid_for.map(id => ({ id }))
}
} }
for (const [key, value] of Object.entries(rest)) { for (const [key, value] of Object.entries(rest)) {
+1 -1
View File
@@ -250,10 +250,10 @@ class DraftOrderService extends BaseService {
} }
const { const {
items,
shipping_methods, shipping_methods,
discounts, discounts,
no_notification_order, no_notification_order,
items,
...rest ...rest
} = data } = data
+6
View File
@@ -296,6 +296,8 @@ class OrderService extends BaseService {
relationSet.add("swaps") relationSet.add("swaps")
relationSet.add("swaps.additional_items") relationSet.add("swaps.additional_items")
relationSet.add("discounts") relationSet.add("discounts")
relationSet.add("discounts.rule")
relationSet.add("discounts.rule.valid_for")
relationSet.add("gift_cards") relationSet.add("gift_cards")
relationSet.add("gift_card_transactions") relationSet.add("gift_card_transactions")
relationSet.add("refunds") relationSet.add("refunds")
@@ -453,6 +455,8 @@ class OrderService extends BaseService {
"payment", "payment",
"items", "items",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"gift_cards", "gift_cards",
"shipping_methods", "shipping_methods",
], ],
@@ -1119,6 +1123,8 @@ class OrderService extends BaseService {
], ],
relations: [ relations: [
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"region", "region",
"fulfillments", "fulfillments",
"shipping_address", "shipping_address",
+2
View File
@@ -518,6 +518,8 @@ class ReturnService extends BaseService {
"returns", "returns",
"payments", "payments",
"discounts", "discounts",
"discounts.rule",
"discounts.rule.valid_for",
"refunds", "refunds",
"shipping_methods", "shipping_methods",
"region", "region",
+1
View File
@@ -533,6 +533,7 @@ class SwapService extends BaseService {
"order.swaps", "order.swaps",
"order.swaps.additional_items", "order.swaps.additional_items",
"order.discounts", "order.discounts",
"order.discounts.rule",
"additional_items", "additional_items",
"return_order", "return_order",
"return_order.items", "return_order.items",
+7 -1
View File
@@ -32,7 +32,13 @@ class OrderSubscriber {
handleOrderPlaced = async data => { handleOrderPlaced = async data => {
const order = await this.orderService_.retrieve(data.id, { const order = await this.orderService_.retrieve(data.id, {
select: ["subtotal"], select: ["subtotal"],
relations: ["discounts", "items", "gift_cards"], relations: [
"discounts",
"discounts.rule",
"discounts.rule.valid_for",
"items",
"gift_cards",
],
}) })
await Promise.all( await Promise.all(
+5
View File
@@ -4608,6 +4608,11 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
iso8601-duration@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/iso8601-duration/-/iso8601-duration-1.3.0.tgz#29d7b69e0574e4acdee50c5e5e09adab4137ba5a"
integrity sha512-K4CiUBzo3YeWk76FuET/dQPH03WE04R94feo5TSKQCXpoXQt9E4yx2CnY737QZnSAI3PI4WlKo/zfqizGx52QQ==
isobject@^2.0.0: isobject@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"