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

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

@ -1,19 +1,6 @@
import { CartData, Discount } from "../../model";
import { findDiscountFactor } from "./findDiscountFactor";
import { Discount } from "../../model";
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(
cartPurchasesAmount: number,
discounts: Discount[],
@ -21,14 +8,14 @@ export function findCartDiscount(
const applicableDiscounts = discounts.filter(discount => {
return (
discount.Layer === 3 &&
cartPurchasesAmount >= discount.Condition.CartPurchasesAmount
cartPurchasesAmount >= Number(discount.Condition.CartPurchasesAmount)
);
});
if (!applicableDiscounts.length) return null;
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;

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

@ -1,37 +1,23 @@
import { CartData, Discount } from "../../model";
import { findDiscountFactor } from "./findDiscountFactor";
export function applyLoyaltyDiscount(
cartData: CartData,
discounts: Discount[],
purchasesAmount: number,
) {
const loyalDiscount = findLoyaltyDiscount(purchasesAmount, discounts);
if (!loyalDiscount) return;
cartData.priceAfterDiscounts *= findDiscountFactor(loyalDiscount);
cartData.allAppliedDiscounts.push(loyalDiscount);
cartData.appliedLoyaltyDiscount = loyalDiscount;
}
export function findLoyaltyDiscount(
purchasesAmount: number,
discounts: Discount[],
): Discount | null {
const applicableDiscounts = discounts.filter(discount => {
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;
}
import { Discount } from "../../model";
export function findLoyaltyDiscount(
purchasesAmount: number,
discounts: Discount[],
): Discount | null {
const applicableDiscounts = discounts.filter(discount => {
return (
discount.Layer === 4 &&
discount.Condition.UserType !== "nko" &&
purchasesAmount >= Number(discount.Condition.PurchasesAmount)
);
});
if (!applicableDiscounts.length) return null;
const maxValueDiscount = applicableDiscounts.reduce((prev, current) => {
return Number(current.Condition.PurchasesAmount) > Number(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 { findDiscountFactor } from "./findDiscountFactor";
import { Discount } from "../../model";
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(
privilegeId: string,
privilegePrice: number,
discounts: Discount[],
userId: string,
): Discount | null {
const applicableDiscounts = discounts.filter(discount => {
if (discount.Condition.User !== "" && discount.Condition.User === userId) return true;
const conditionMinPrice = parseFloat(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;
const maxValueDiscount = applicableDiscounts.reduce((prev, current) =>
parseFloat(current.Condition.Term) > parseFloat(prev.Condition.Term) ? current : prev
);
let maxValueDiscount: Discount = applicableDiscounts[0];
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;
}

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

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