fix cart types and functions
This commit is contained in:
nflnkr 2024-03-19 18:30:11 +03:00
parent e3281be590
commit 5f17e1c730
9 changed files with 172 additions and 211 deletions

@ -1,36 +1,35 @@
import { Discount } from "./discount"; import { Discount } from "./discount";
export type PrivilegeCartData = { export type PrivilegeCartData = {
serviceKey: string; serviceKey: string;
privilegeId: string; privilegeId: string;
description: string; description: string;
price: number; price: number;
amount: number; amount: number;
appliedPrivilegeDiscount: Discount | null; };
};
export type TariffCartData = {
export type TariffCartData = { name: string;
name: string; id: string;
id: string; price: number;
price: number; isCustom: boolean;
isCustom: boolean; privileges: PrivilegeCartData[];
privileges: PrivilegeCartData[]; };
};
export type ServiceCartData = {
export type ServiceCartData = { serviceKey: string;
serviceKey: string; tariffs: TariffCartData[];
tariffs: TariffCartData[]; price: number;
price: number; appliedServiceDiscount: Discount | null;
appliedServiceDiscount: Discount | null; };
};
export type CartData = {
export type CartData = { services: ServiceCartData[];
services: ServiceCartData[]; priceBeforeDiscounts: number;
priceBeforeDiscounts: number; priceAfterDiscounts: number;
priceAfterDiscounts: number; appliedCartPurchasesDiscount: Discount | null;
itemCount: number; appliedLoyaltyDiscount: Discount | null;
appliedCartPurchasesDiscount: Discount | null; allAppliedDiscounts: Discount[];
appliedLoyaltyDiscount: Discount | null; appliedDiscountsByPrivilegeId: Map<string, Set<Discount>>;
allAppliedDiscounts: Discount[]; };
};

@ -1,40 +1,40 @@
export interface Discount { export interface Discount {
ID: string; ID: string;
Name: string; Name: string;
Layer: number; Layer: number;
Description: string; Description: string;
Condition: { Condition: {
Period: { Period: {
From: string; From: string;
To: string; To: string;
}; };
User: string; User: string;
UserType: string; UserType: string;
Coupon: string; Coupon: string;
PurchasesAmount: number; PurchasesAmount: string;
CartPurchasesAmount: number; CartPurchasesAmount: string;
Product: string; Product: string;
Term: string; Term: string;
Usage: string; Usage: string;
PriceFrom: number; PriceFrom: string;
Group: string; Group: string;
}; };
Target: { Target: {
Products: [{ Products: {
ID: string; ID: string;
Factor: number; Factor: number;
Overhelm: boolean; Overhelm: boolean;
}]; }[];
Factor: number; Factor: number;
TargetScope: string; TargetScope: string;
TargetGroup: string; TargetGroup: string;
Overhelm: boolean; Overhelm: boolean;
}; };
Audit: { Audit: {
UpdatedAt: string; UpdatedAt: string;
CreatedAt: string; CreatedAt: string;
DeletedAt?: string; DeletedAt?: string;
Deleted: boolean; Deleted: boolean;
}; };
Deprecated: boolean; Deprecated: boolean;
}; }

@ -1,19 +1,6 @@
import { CartData, Discount } from "../../model"; import { Discount } from "../../model";
import { findDiscountFactor } from "./findDiscountFactor";
export function applyCartDiscount(
cartData: CartData,
discounts: Discount[],
) {
const cartDiscount = findCartDiscount(cartData.priceAfterDiscounts, discounts);
if (!cartDiscount) return;
cartData.priceAfterDiscounts *= findDiscountFactor(cartDiscount);
cartData.allAppliedDiscounts.push(cartDiscount);
cartData.appliedCartPurchasesDiscount = cartDiscount;
}
export function findCartDiscount( export function findCartDiscount(
cartPurchasesAmount: number, cartPurchasesAmount: number,
discounts: Discount[], discounts: Discount[],
@ -21,14 +8,14 @@ export function findCartDiscount(
const applicableDiscounts = discounts.filter(discount => { const applicableDiscounts = discounts.filter(discount => {
return ( return (
discount.Layer === 3 && discount.Layer === 3 &&
cartPurchasesAmount >= discount.Condition.CartPurchasesAmount cartPurchasesAmount >= Number(discount.Condition.CartPurchasesAmount)
); );
}); });
if (!applicableDiscounts.length) return null; if (!applicableDiscounts.length) return null;
const maxValueDiscount = applicableDiscounts.reduce((prev, current) => { const maxValueDiscount = applicableDiscounts.reduce((prev, current) => {
return current.Condition.CartPurchasesAmount > prev.Condition.CartPurchasesAmount ? current : prev; return Number(current.Condition.CartPurchasesAmount) > Number(prev.Condition.CartPurchasesAmount) ? current : prev;
}); });
return maxValueDiscount; return maxValueDiscount;

@ -1,5 +1,6 @@
export * from "./cartDiscount"; export * from "./cartDiscount";
export * from "./findDiscountFactor"; export * from "./findDiscountFactor";
export * from "./loyaltyDiscount"; export * from "./loyaltyDiscount";
export * from "./privilegeDiscount"; export * from "./nkoDiscount";
export * from "./serviceDiscount"; export * from "./privilegeDiscount";
export * from "./serviceDiscount";

@ -1,37 +1,23 @@
import { CartData, Discount } from "../../model"; import { Discount } from "../../model";
import { findDiscountFactor } from "./findDiscountFactor";
export function findLoyaltyDiscount(
export function applyLoyaltyDiscount( purchasesAmount: number,
cartData: CartData, discounts: Discount[],
discounts: Discount[], ): Discount | null {
purchasesAmount: number, const applicableDiscounts = discounts.filter(discount => {
) { return (
const loyalDiscount = findLoyaltyDiscount(purchasesAmount, discounts); discount.Layer === 4 &&
if (!loyalDiscount) return; discount.Condition.UserType !== "nko" &&
purchasesAmount >= Number(discount.Condition.PurchasesAmount)
cartData.priceAfterDiscounts *= findDiscountFactor(loyalDiscount); );
cartData.allAppliedDiscounts.push(loyalDiscount); });
cartData.appliedLoyaltyDiscount = loyalDiscount;
} if (!applicableDiscounts.length) return null;
export function findLoyaltyDiscount( const maxValueDiscount = applicableDiscounts.reduce((prev, current) => {
purchasesAmount: number, return Number(current.Condition.PurchasesAmount) > Number(prev.Condition.PurchasesAmount) ? current : prev;
discounts: Discount[], });
): Discount | null {
const applicableDiscounts = discounts.filter(discount => { return maxValueDiscount;
return ( }
discount.Layer === 4 &&
discount.Condition.UserType !== "nko" &&
purchasesAmount >= discount.Condition.PurchasesAmount
);
});
if (!applicableDiscounts.length) return null;
const maxValueDiscount = applicableDiscounts.reduce((prev, current) => {
return current.Condition.PurchasesAmount > prev.Condition.PurchasesAmount ? current : prev;
});
return maxValueDiscount;
}

@ -0,0 +1,14 @@
import { Discount } from "../../model/discount";
export function findNkoDiscount(discounts: Discount[]): Discount | null {
const applicableDiscounts = discounts.filter(discount => discount.Condition.UserType === "nko");
if (!applicableDiscounts.length) return null;
const maxValueDiscount = applicableDiscounts.reduce((prev, current) => {
return Number(current.Condition.CartPurchasesAmount) > Number(prev.Condition.CartPurchasesAmount) ? current : prev;
});
return maxValueDiscount;
}

@ -1,36 +1,15 @@
import { CartData, Discount } from "../../model"; import { Discount } from "../../model";
import { findDiscountFactor } from "./findDiscountFactor";
export function applyPrivilegeDiscounts(
cartData: CartData,
discounts: Discount[],
) {
cartData.services.forEach(service => {
service.tariffs.forEach(tariff => {
tariff.privileges.forEach(privilege => {
const privilegeDiscount = findPrivilegeDiscount(privilege.privilegeId, privilege.amount, discounts);
if (!privilegeDiscount) return;
const discountAmount = privilege.price * (1 - findDiscountFactor(privilegeDiscount));
privilege.price -= discountAmount;
cartData.allAppliedDiscounts.push(privilegeDiscount);
privilege.appliedPrivilegeDiscount = privilegeDiscount;
tariff.price -= discountAmount;
service.price -= discountAmount;
cartData.priceAfterDiscounts -= discountAmount;
});
});
});
}
export function findPrivilegeDiscount( export function findPrivilegeDiscount(
privilegeId: string, privilegeId: string,
privilegePrice: number, privilegePrice: number,
discounts: Discount[], discounts: Discount[],
userId: string,
): Discount | null { ): Discount | null {
const applicableDiscounts = discounts.filter(discount => { const applicableDiscounts = discounts.filter(discount => {
if (discount.Condition.User !== "" && discount.Condition.User === userId) return true;
const conditionMinPrice = parseFloat(discount.Condition.Term); const conditionMinPrice = parseFloat(discount.Condition.Term);
if (!isFinite(conditionMinPrice)) throw new Error(`Couldn't parse Discount.Condition.Term: ${discount.Condition.Term}`); if (!isFinite(conditionMinPrice)) throw new Error(`Couldn't parse Discount.Condition.Term: ${discount.Condition.Term}`);
@ -43,9 +22,17 @@ export function findPrivilegeDiscount(
if (!applicableDiscounts.length) return null; if (!applicableDiscounts.length) return null;
const maxValueDiscount = applicableDiscounts.reduce((prev, current) => let maxValueDiscount: Discount = applicableDiscounts[0];
parseFloat(current.Condition.Term) > parseFloat(prev.Condition.Term) ? current : prev for (const discount of applicableDiscounts) {
); if (discount.Condition.User !== "" && discount.Condition.User === userId) {
maxValueDiscount = discount;
break;
}
if (Number(discount.Condition.Term) > Number(maxValueDiscount.Condition.Term)) {
maxValueDiscount = discount;
}
}
return maxValueDiscount; return maxValueDiscount;
} }

@ -1,48 +1,35 @@
import { CartData, Discount } from "../../model"; import { Discount } from "../../model";
import { findDiscountFactor } from "./findDiscountFactor";
export function findServiceDiscount(
export function applyServiceDiscounts( serviceKey: string,
cartData: CartData, currentPrice: number,
discounts: Discount[], discounts: Discount[],
) { userId: string,
cartData.services.forEach(service => { ): Discount | null {
service.tariffs.map(tariff => { const applicableDiscounts = discounts.filter(discount => {
tariff.privileges.forEach(privilege => { if (discount.Condition.User !== "" && discount.Condition.User === userId) return true;
const privilegeDiscount = findServiceDiscount(privilege.serviceKey, privilege.price, discounts);
if (!privilegeDiscount) return; return (
discount.Layer === 2 &&
const discountAmount = privilege.price * (1 - findDiscountFactor(privilegeDiscount)); discount.Condition.Group === serviceKey &&
privilege.price -= discountAmount; currentPrice >= Number(discount.Condition.PriceFrom)
cartData.allAppliedDiscounts.push(privilegeDiscount); );
service.appliedServiceDiscount = privilegeDiscount; });
tariff.price -= discountAmount; if (!applicableDiscounts.length) return null;
service.price -= discountAmount;
cartData.priceAfterDiscounts -= discountAmount; let maxValueDiscount: Discount = applicableDiscounts[0];
}); for (const discount of applicableDiscounts) {
}); if (discount.Condition.User !== "" && discount.Condition.User === userId) {
}); maxValueDiscount = discount;
} break;
}
export function findServiceDiscount(
serviceKey: string, if (Number(discount.Condition.PriceFrom) > Number(maxValueDiscount.Condition.PriceFrom)) {
currentPrice: number, maxValueDiscount = discount;
discounts: Discount[], }
): Discount | null { }
const applicableDiscounts = discounts.filter(discount => {
return ( return maxValueDiscount;
discount.Layer === 2 && }
discount.Condition.Group === serviceKey &&
currentPrice >= discount.Condition.PriceFrom
);
});
if (!applicableDiscounts.length) return null;
const maxValueDiscount = applicableDiscounts.reduce((prev, current) => {
return current.Condition.PriceFrom > prev.Condition.PriceFrom ? current : prev;
});
return maxValueDiscount;
}

@ -1,6 +1,6 @@
{ {
"name": "@frontend/kitui", "name": "@frontend/kitui",
"version": "1.0.68", "version": "1.0.69",
"description": "test", "description": "test",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.js", "module": "./dist/index.js",