Skip to content

Commit

Permalink
feat: add check stackability for the shipping discount
Browse files Browse the repository at this point in the history
Signed-off-by: vanpho93 <[email protected]>
  • Loading branch information
vanpho93 committed May 19, 2023
1 parent b768b1b commit d943372
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable no-unused-vars */
import { createRequire } from "module";
import _ from "lodash";
import Logger from "@reactioncommerce/logger";
Expand All @@ -7,6 +6,7 @@ import formatMoney from "../../utils/formatMoney.js";
import getEligibleShipping from "../../utils/getEligibleIShipping.js";
import calculateDiscountAmount from "../../utils/calculateDiscountAmount.js";
import recalculateQuoteDiscount from "../../utils/recalculateQuoteDiscount.js";
import checkShippingStackable from "./checkShippingStackable.js";

const require = createRequire(import.meta.url);

Expand Down Expand Up @@ -137,8 +137,14 @@ export async function estimateShipmentQuoteDiscount(context, cart, params) {
const canBeDiscounted = canBeApplyDiscountToShipping(shipmentQuote, promotion);
if (!canBeDiscounted) continue;

const shippingDiscount = createDiscountRecord(params, item);

if (!shipmentQuote.discounts) shipmentQuote.discounts = [];
shipmentQuote.discounts.push(createDiscountRecord(params, item));
// eslint-disable-next-line no-await-in-loop
const canStackable = await checkShippingStackable(context, shipmentQuote, shippingDiscount);
if (!canStackable) continue;

shipmentQuote.discounts.push(shippingDiscount);

affectedItemsLength += 1;
recalculateQuoteDiscount(context, shipmentQuote, actionParameters);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import mockContext from "@reactioncommerce/api-utils/tests/mockContext.js";
import * as applyShippingDiscountToCart from "./applyShippingDiscountToCart.js";
import checkShippingStackable from "./checkShippingStackable.js";

jest.mock("./checkShippingStackable.js", () => jest.fn());

test("createDiscountRecord should create discount record", () => {
const parameters = {
Expand Down Expand Up @@ -79,6 +82,7 @@ test("should apply shipping discount to cart", async () => {
mockContext.discountCalculationMethods = {
fixed: jest.fn().mockReturnValue(2)
};
checkShippingStackable.mockReturnValue(true);

const { cart: updatedCart, affected } = await applyShippingDiscountToCart.default(mockContext, parameters, cart);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* eslint-disable no-await-in-loop */
import _ from "lodash";

/**
* @summary check if a promotion is applicable to a cart
* @param {Object} context - The application context
* @param {Object} shipping - The cart we are trying to apply the promotion to
* @param {Object} discount - The promotion we are trying to apply
* @returns {Promise<Boolean>} - Whether the promotion is applicable to the shipping
*/
export default async function checkShippingStackable(context, shipping, discount) {
const { promotions } = context;
const stackabilityByKey = _.keyBy(promotions.stackabilities, "key");

for (const appliedDiscount of shipping.discounts) {
if (!appliedDiscount.stackability) continue;

const stackHandler = stackabilityByKey[discount.stackability.key];
const appliedStackHandler = stackabilityByKey[appliedDiscount.stackability.key];

const stackResult = await stackHandler.handler(context, null, { promotion: discount, appliedPromotion: appliedDiscount });
const appliedStackResult = await appliedStackHandler.handler(context, {}, { promotion: appliedDiscount, appliedPromotion: discount });

if (!stackResult || !appliedStackResult) return false;
}

return true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import mockContext from "@reactioncommerce/api-utils/tests/mockContext.js";
import checkShippingStackable from "./checkShippingStackable.js";

test("should returns true if no the current discount is stackable", async () => {
const shipping = {
discounts: [
{
stackability: { key: "all" }
}
]
};
const discount = {
stackability: { key: "all" }
};

mockContext.promotions = {
stackabilities: [{ key: "all", handler: () => true }]
};

const result = await checkShippingStackable(mockContext, shipping, discount);
expect(result).toBe(true);
});

test("should returns false if the current discount is not stackable", async () => {
const shipping = {
discounts: [
{
stackability: { key: "all" }
}
]
};
const discount = {
stackability: { key: "none" }
};

mockContext.promotions = {
stackabilities: [
{ key: "all", handler: () => true },
{ key: "none", handler: () => false }
]
};

const result = await checkShippingStackable(mockContext, shipping, discount);
expect(result).toBe(false);
});

0 comments on commit d943372

Please sign in to comment.