Изменение таблицы, дополнение привелегий
This commit is contained in:
parent
035e3f0655
commit
724d17fe75
30
src/hooks/useCombinedPrivileges.hook.ts
Normal file
30
src/hooks/useCombinedPrivileges.hook.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { usePrivilegeStore } from "@root/stores/privileges";
|
||||
|
||||
import { usePrivilegies } from "./privilege.hook";
|
||||
|
||||
export type mergedPrivilege = {
|
||||
createdAt?: string;
|
||||
description: string;
|
||||
isDeleted?: boolean;
|
||||
name: string;
|
||||
price: string | number;
|
||||
privilegeId: string;
|
||||
serviceKey: string;
|
||||
type: "count" | "day" | "mb";
|
||||
updatedAt?: string;
|
||||
value?: string;
|
||||
_id?: string;
|
||||
};
|
||||
|
||||
export const useCombinedPrivileges = () => {
|
||||
const { privilegies, isError, errorMessage } = usePrivilegies();
|
||||
const examplePrivileges = usePrivilegeStore((state) => state.privileges);
|
||||
|
||||
const mergedPrivileges: mergedPrivilege[] = [];
|
||||
|
||||
if (privilegies) {
|
||||
mergedPrivileges.push(...privilegies.Шаблонизатор, ...examplePrivileges);
|
||||
}
|
||||
|
||||
return { mergedPrivileges, isError, errorMessage };
|
||||
};
|
||||
@ -102,8 +102,8 @@ root.render(
|
||||
</PrivateRoute>
|
||||
}
|
||||
/>
|
||||
{componentsArray.map((e: any, i) => (
|
||||
<Route key={e} path={e[0]} element={e[1]} />
|
||||
{componentsArray.map((element: any) => (
|
||||
<Route key={element} path={element[0]} element={element[1]} />
|
||||
))}
|
||||
</Route>
|
||||
|
||||
|
||||
@ -1,263 +1,291 @@
|
||||
import { CartItem, AnyDiscount, CartTotal, CartItemTotal, PrivilegeDiscount, CartPurchasesAmountDiscount, PurchasesAmountDiscount, ServiceToPriceMap, ServiceDiscount, UserDiscount } from "@root/model/cart";
|
||||
import {
|
||||
CartItem,
|
||||
AnyDiscount,
|
||||
CartTotal,
|
||||
CartItemTotal,
|
||||
PrivilegeDiscount,
|
||||
CartPurchasesAmountDiscount,
|
||||
PurchasesAmountDiscount,
|
||||
ServiceToPriceMap,
|
||||
ServiceDiscount,
|
||||
UserDiscount,
|
||||
} from "@root/model/cart";
|
||||
import { ServiceType, SERVICE_LIST, Tariff } from "../../model/tariff";
|
||||
import { User } from "../../model/user";
|
||||
import { findPrivilegeById } from "@root/stores/privileges";
|
||||
|
||||
|
||||
export function calcCartData({ user, purchasesAmount, cartItems, discounts, isNonCommercial = false, coupon }: {
|
||||
user: User;
|
||||
purchasesAmount: number;
|
||||
cartItems: CartItem[];
|
||||
discounts: AnyDiscount[];
|
||||
isNonCommercial?: boolean;
|
||||
coupon?: string;
|
||||
export function calcCartData({
|
||||
user,
|
||||
purchasesAmount,
|
||||
cartItems,
|
||||
discounts,
|
||||
isNonCommercial = false,
|
||||
coupon,
|
||||
}: {
|
||||
user: User;
|
||||
purchasesAmount: number;
|
||||
cartItems: CartItem[];
|
||||
discounts: AnyDiscount[];
|
||||
isNonCommercial?: boolean;
|
||||
coupon?: string;
|
||||
}): CartTotal | Error | null {
|
||||
let isIncompatibleTariffs = false;
|
||||
let isIncompatibleTariffs = false;
|
||||
|
||||
const defaultTariffTypePresent: { [Key in ServiceType]: boolean } = {
|
||||
dwarfener: false,
|
||||
squiz: false,
|
||||
templategen: false,
|
||||
};
|
||||
const defaultTariffTypePresent: { [Key in ServiceType]: boolean } = {
|
||||
dwarfener: false,
|
||||
squiz: false,
|
||||
templategen: false,
|
||||
};
|
||||
|
||||
cartItems.forEach(cartItem => {
|
||||
const privilege = findPrivilegeById(cartItem.tariff.privilegeId);
|
||||
if (!privilege) throw new Error(`Привилегия с id ${cartItem.tariff} не найдена в тарифе ${cartItem.tariff.name} с id ${cartItem.tariff.id}`);
|
||||
cartItems.forEach((cartItem) => {
|
||||
const privilege = findPrivilegeById(cartItem.tariff.privilegeId);
|
||||
if (!privilege)
|
||||
throw new Error(
|
||||
`Привилегия с id ${cartItem.tariff} не найдена в тарифе ${cartItem.tariff.name} с id ${cartItem.tariff.id}`
|
||||
);
|
||||
|
||||
if (cartItem.tariff.customPricePerUnit === undefined) return defaultTariffTypePresent[privilege.serviceKey] = true;
|
||||
if (cartItem.tariff.customPricePerUnit === undefined)
|
||||
return (defaultTariffTypePresent[privilege.serviceKey] = true);
|
||||
|
||||
if (
|
||||
defaultTariffTypePresent[privilege.serviceKey] &&
|
||||
cartItem.tariff.customPricePerUnit !== undefined
|
||||
) isIncompatibleTariffs = true;
|
||||
if (defaultTariffTypePresent[privilege.serviceKey] && cartItem.tariff.customPricePerUnit !== undefined)
|
||||
isIncompatibleTariffs = true;
|
||||
});
|
||||
|
||||
if (isIncompatibleTariffs)
|
||||
return new Error("Если взят готовый тариф, то кастомный на этот сервис сделать уже нельзя");
|
||||
|
||||
if (!cartItems.length) return null;
|
||||
|
||||
const cartTotal: CartTotal = {
|
||||
items: [],
|
||||
totalPrice: 0,
|
||||
priceByService: {
|
||||
templategen: 0,
|
||||
squiz: 0,
|
||||
dwarfener: 0,
|
||||
},
|
||||
discountsByService: {
|
||||
templategen: null,
|
||||
squiz: null,
|
||||
dwarfener: null,
|
||||
},
|
||||
envolvedCartDiscounts: [],
|
||||
couponState: coupon ? "not found" : null,
|
||||
};
|
||||
|
||||
// layer 0
|
||||
for (const discount of discounts) {
|
||||
if (discount.conditionType !== "userType" || !isNonCommercial) continue;
|
||||
|
||||
cartItems.forEach((cartItem) => {
|
||||
cartTotal.items.push({
|
||||
envolvedDiscounts: [],
|
||||
tariff: cartItem.tariff,
|
||||
totalPrice: cartItem.price,
|
||||
});
|
||||
|
||||
const privilege = findPrivilegeById(cartItem.tariff.privilegeId);
|
||||
if (!privilege)
|
||||
throw new Error(`Привилегия не найдена в тарифе ${cartItem.tariff.name} с id ${cartItem.tariff.id}`);
|
||||
|
||||
cartTotal.priceByService[privilege.serviceKey] += cartItem.price;
|
||||
cartTotal.totalPrice += cartItem.price;
|
||||
});
|
||||
|
||||
if (isIncompatibleTariffs) return new Error("Если взят готовый тариф, то кастомный на этот сервис сделать уже нельзя");
|
||||
|
||||
if (!cartItems.length) return null;
|
||||
|
||||
const cartTotal: CartTotal = {
|
||||
items: [],
|
||||
totalPrice: 0,
|
||||
priceByService: {
|
||||
templategen: 0,
|
||||
squiz: 0,
|
||||
dwarfener: 0,
|
||||
},
|
||||
discountsByService: {
|
||||
templategen: null,
|
||||
squiz: null,
|
||||
dwarfener: null,
|
||||
},
|
||||
envolvedCartDiscounts: [],
|
||||
couponState: coupon ? "not found" : null,
|
||||
};
|
||||
|
||||
// layer 0
|
||||
for (const discount of discounts) {
|
||||
if (discount.conditionType !== "userType" || !isNonCommercial) continue;
|
||||
|
||||
cartItems.forEach(cartItem => {
|
||||
cartTotal.items.push({
|
||||
envolvedDiscounts: [],
|
||||
tariff: cartItem.tariff,
|
||||
totalPrice: cartItem.price,
|
||||
});
|
||||
|
||||
const privilege = findPrivilegeById(cartItem.tariff.privilegeId);
|
||||
if (!privilege) throw new Error(`Привилегия не найдена в тарифе ${cartItem.tariff.name} с id ${cartItem.tariff.id}`);
|
||||
|
||||
cartTotal.priceByService[privilege.serviceKey] += cartItem.price;
|
||||
cartTotal.totalPrice += cartItem.price;
|
||||
});
|
||||
|
||||
cartTotal.totalPrice *= discount.target.factor;
|
||||
cartTotal.envolvedCartDiscounts.push(discount);
|
||||
|
||||
return cartTotal;
|
||||
}
|
||||
|
||||
const couponDiscount = coupon ? findUserDiscount(discounts, user, coupon) : null;
|
||||
|
||||
// layer 1
|
||||
for (const cartItem of cartItems) {
|
||||
const cartItemTotal: CartItemTotal = {
|
||||
tariff: cartItem.tariff,
|
||||
envolvedDiscounts: [],
|
||||
totalPrice: cartItem.price,
|
||||
};
|
||||
|
||||
const tariff = cartItem.tariff;
|
||||
const privilegesAffectedByCoupon: string[] = [];
|
||||
|
||||
couponDiscount?.target.products.forEach(product => {
|
||||
if (product.privilegeId !== tariff.privilegeId) return;
|
||||
if (tariff.customPricePerUnit !== undefined && !couponDiscount.overwhelm) return;
|
||||
|
||||
cartItemTotal.totalPrice *= product.factor;
|
||||
cartItemTotal.envolvedDiscounts.push(couponDiscount);
|
||||
cartTotal.couponState = "applied";
|
||||
privilegesAffectedByCoupon.push(product.privilegeId);
|
||||
});
|
||||
|
||||
const privilegeDiscount = findMaxApplicablePrivilegeDiscount(discounts, tariff);
|
||||
|
||||
privilegeDiscount?.target.products.forEach(product => {
|
||||
if (product.privilegeId !== tariff.privilegeId) return;
|
||||
if (tariff.customPricePerUnit !== undefined) return;
|
||||
if (privilegesAffectedByCoupon.includes(privilegeDiscount.condition.privilege.id)) return;
|
||||
|
||||
cartItemTotal.totalPrice *= product.factor;
|
||||
cartItemTotal.envolvedDiscounts.push(privilegeDiscount);
|
||||
});
|
||||
|
||||
const privilege = findPrivilegeById(cartItem.tariff.privilegeId);
|
||||
if (!privilege) throw new Error(`Привилегия не найдена в тарифе ${cartItem.tariff.name} с id ${cartItem.tariff.id}`);
|
||||
|
||||
cartTotal.items.push(cartItemTotal);
|
||||
cartTotal.priceByService[privilege.serviceKey] += cartItemTotal.totalPrice;
|
||||
}
|
||||
|
||||
// layer 2
|
||||
SERVICE_LIST.map(service => service.serviceKey).forEach(service => {
|
||||
const serviceDiscount = findMaxServiceDiscount(service, discounts, cartTotal.priceByService);
|
||||
if (serviceDiscount) {
|
||||
cartTotal.priceByService[service] *= serviceDiscount.target.factor;
|
||||
cartTotal.discountsByService[service] = serviceDiscount;
|
||||
}
|
||||
|
||||
cartTotal.totalPrice += cartTotal.priceByService[service];
|
||||
});
|
||||
|
||||
// layer 3
|
||||
const cartPurchasesAmountDiscount = findMaxCartPurchasesAmountDiscount(discounts, cartTotal);
|
||||
if (cartPurchasesAmountDiscount) {
|
||||
cartTotal.totalPrice *= cartPurchasesAmountDiscount.factor;
|
||||
cartTotal.envolvedCartDiscounts.push(cartPurchasesAmountDiscount);
|
||||
}
|
||||
|
||||
// layer 4
|
||||
const totalPurchasesAmountDiscount = findMaxTotalPurchasesAmountDiscount(discounts, purchasesAmount);
|
||||
if (totalPurchasesAmountDiscount) {
|
||||
cartTotal.totalPrice *= totalPurchasesAmountDiscount.factor;
|
||||
cartTotal.envolvedCartDiscounts.push(totalPurchasesAmountDiscount);
|
||||
}
|
||||
cartTotal.totalPrice *= discount.target.factor;
|
||||
cartTotal.envolvedCartDiscounts.push(discount);
|
||||
|
||||
return cartTotal;
|
||||
}
|
||||
|
||||
const couponDiscount = coupon ? findUserDiscount(discounts, user, coupon) : null;
|
||||
|
||||
// layer 1
|
||||
for (const cartItem of cartItems) {
|
||||
const cartItemTotal: CartItemTotal = {
|
||||
tariff: cartItem.tariff,
|
||||
envolvedDiscounts: [],
|
||||
totalPrice: cartItem.price,
|
||||
};
|
||||
|
||||
const tariff = cartItem.tariff;
|
||||
const privilegesAffectedByCoupon: string[] = [];
|
||||
|
||||
couponDiscount?.target.products.forEach((product) => {
|
||||
if (product.privilegeId !== tariff.privilegeId) return;
|
||||
if (tariff.customPricePerUnit !== undefined && !couponDiscount.overwhelm) return;
|
||||
|
||||
cartItemTotal.totalPrice *= product.factor;
|
||||
cartItemTotal.envolvedDiscounts.push(couponDiscount);
|
||||
cartTotal.couponState = "applied";
|
||||
privilegesAffectedByCoupon.push(product.privilegeId);
|
||||
});
|
||||
|
||||
const privilegeDiscount = findMaxApplicablePrivilegeDiscount(discounts, tariff);
|
||||
|
||||
privilegeDiscount?.target.products.forEach((product) => {
|
||||
if (product.privilegeId !== tariff.privilegeId) return;
|
||||
if (tariff.customPricePerUnit !== undefined) return;
|
||||
if (privilegesAffectedByCoupon.includes(privilegeDiscount.condition.privilege.id)) return;
|
||||
|
||||
cartItemTotal.totalPrice *= product.factor;
|
||||
cartItemTotal.envolvedDiscounts.push(privilegeDiscount);
|
||||
});
|
||||
|
||||
const privilege = findPrivilegeById(cartItem.tariff.privilegeId);
|
||||
if (!privilege)
|
||||
throw new Error(`Привилегия не найдена в тарифе ${cartItem.tariff.name} с id ${cartItem.tariff.id}`);
|
||||
|
||||
cartTotal.items.push(cartItemTotal);
|
||||
cartTotal.priceByService[privilege.serviceKey] += cartItemTotal.totalPrice;
|
||||
}
|
||||
|
||||
// layer 2
|
||||
SERVICE_LIST.map((service) => service.serviceKey).forEach((service) => {
|
||||
const serviceDiscount = findMaxServiceDiscount(service, discounts, cartTotal.priceByService);
|
||||
if (serviceDiscount) {
|
||||
cartTotal.priceByService[service] *= serviceDiscount.target.factor;
|
||||
cartTotal.discountsByService[service] = serviceDiscount;
|
||||
}
|
||||
|
||||
cartTotal.totalPrice += cartTotal.priceByService[service];
|
||||
});
|
||||
|
||||
// layer 3
|
||||
const cartPurchasesAmountDiscount = findMaxCartPurchasesAmountDiscount(discounts, cartTotal);
|
||||
if (cartPurchasesAmountDiscount) {
|
||||
cartTotal.totalPrice *= cartPurchasesAmountDiscount.factor;
|
||||
cartTotal.envolvedCartDiscounts.push(cartPurchasesAmountDiscount);
|
||||
}
|
||||
|
||||
// layer 4
|
||||
const totalPurchasesAmountDiscount = findMaxTotalPurchasesAmountDiscount(discounts, purchasesAmount);
|
||||
if (totalPurchasesAmountDiscount) {
|
||||
cartTotal.totalPrice *= totalPurchasesAmountDiscount.factor;
|
||||
cartTotal.envolvedCartDiscounts.push(totalPurchasesAmountDiscount);
|
||||
}
|
||||
|
||||
return cartTotal;
|
||||
}
|
||||
|
||||
function findMaxApplicablePrivilegeDiscount(discounts: AnyDiscount[], tariff: Tariff): PrivilegeDiscount | null {
|
||||
const applicableDiscounts = discounts.filter((discount): discount is PrivilegeDiscount => {
|
||||
return (
|
||||
discount.conditionType === "privilege" &&
|
||||
tariff.privilegeId === discount.condition.privilege.id &&
|
||||
tariff.amount >= discount.condition.privilege.value
|
||||
);
|
||||
});
|
||||
|
||||
if (!applicableDiscounts.length) return null;
|
||||
|
||||
const maxValueDiscount = applicableDiscounts.reduce(
|
||||
(prev, current) => current.condition.privilege.value > prev.condition.privilege.value ? current : prev
|
||||
const applicableDiscounts = discounts.filter((discount): discount is PrivilegeDiscount => {
|
||||
return (
|
||||
discount.conditionType === "privilege" &&
|
||||
tariff.privilegeId === discount.condition.privilege.id &&
|
||||
tariff.amount >= discount.condition.privilege.value
|
||||
);
|
||||
});
|
||||
|
||||
return maxValueDiscount;
|
||||
if (!applicableDiscounts.length) return null;
|
||||
|
||||
const maxValueDiscount = applicableDiscounts.reduce((prev, current) =>
|
||||
current.condition.privilege.value > prev.condition.privilege.value ? current : prev
|
||||
);
|
||||
|
||||
return maxValueDiscount;
|
||||
}
|
||||
|
||||
function findMaxCartPurchasesAmountDiscount(discounts: AnyDiscount[], cartTotal: CartTotal): CartPurchasesAmountDiscount | null {
|
||||
const applicableDiscounts = discounts.filter((discount): discount is CartPurchasesAmountDiscount => {
|
||||
return discount.conditionType === "cartPurchasesAmount" && cartTotal.totalPrice >= discount.condition.cartPurchasesAmount;
|
||||
});
|
||||
|
||||
if (!applicableDiscounts.length) return null;
|
||||
|
||||
const maxValueDiscount = applicableDiscounts.reduce(
|
||||
(prev, current) => current.condition.cartPurchasesAmount > prev.condition.cartPurchasesAmount ? current : prev
|
||||
function findMaxCartPurchasesAmountDiscount(
|
||||
discounts: AnyDiscount[],
|
||||
cartTotal: CartTotal
|
||||
): CartPurchasesAmountDiscount | null {
|
||||
const applicableDiscounts = discounts.filter((discount): discount is CartPurchasesAmountDiscount => {
|
||||
return (
|
||||
discount.conditionType === "cartPurchasesAmount" && cartTotal.totalPrice >= discount.condition.cartPurchasesAmount
|
||||
);
|
||||
});
|
||||
|
||||
return maxValueDiscount;
|
||||
if (!applicableDiscounts.length) return null;
|
||||
|
||||
const maxValueDiscount = applicableDiscounts.reduce((prev, current) =>
|
||||
current.condition.cartPurchasesAmount > prev.condition.cartPurchasesAmount ? current : prev
|
||||
);
|
||||
|
||||
return maxValueDiscount;
|
||||
}
|
||||
|
||||
function findMaxTotalPurchasesAmountDiscount(discounts: AnyDiscount[], purchasesAmount: number): PurchasesAmountDiscount | null {
|
||||
const applicableDiscounts = discounts.filter((discount): discount is PurchasesAmountDiscount => {
|
||||
return discount.conditionType === "purchasesAmount" && purchasesAmount >= discount.condition.purchasesAmount;
|
||||
});
|
||||
function findMaxTotalPurchasesAmountDiscount(
|
||||
discounts: AnyDiscount[],
|
||||
purchasesAmount: number
|
||||
): PurchasesAmountDiscount | null {
|
||||
const applicableDiscounts = discounts.filter((discount): discount is PurchasesAmountDiscount => {
|
||||
return discount.conditionType === "purchasesAmount" && purchasesAmount >= discount.condition.purchasesAmount;
|
||||
});
|
||||
|
||||
if (!applicableDiscounts.length) return null;
|
||||
if (!applicableDiscounts.length) return null;
|
||||
|
||||
const maxValueDiscount = applicableDiscounts.reduce(
|
||||
(prev, current) => current.condition.purchasesAmount > prev.condition.purchasesAmount ? current : prev
|
||||
);
|
||||
const maxValueDiscount = applicableDiscounts.reduce((prev, current) =>
|
||||
current.condition.purchasesAmount > prev.condition.purchasesAmount ? current : prev
|
||||
);
|
||||
|
||||
return maxValueDiscount;
|
||||
return maxValueDiscount;
|
||||
}
|
||||
|
||||
function findMaxServiceDiscount(
|
||||
service: ServiceType,
|
||||
discounts: AnyDiscount[],
|
||||
priceByService: ServiceToPriceMap,
|
||||
service: ServiceType,
|
||||
discounts: AnyDiscount[],
|
||||
priceByService: ServiceToPriceMap
|
||||
): ServiceDiscount | null {
|
||||
const discountsForTariffService = discounts.filter((discount): discount is ServiceDiscount => {
|
||||
return (
|
||||
discount.conditionType === "service" &&
|
||||
discount.condition.service.id === service &&
|
||||
priceByService[service] >= discount.condition.service.value
|
||||
);
|
||||
});
|
||||
const discountsForTariffService = discounts.filter((discount): discount is ServiceDiscount => {
|
||||
return (
|
||||
discount.conditionType === "service" &&
|
||||
discount.condition.service.id === service &&
|
||||
priceByService[service] >= discount.condition.service.value
|
||||
);
|
||||
});
|
||||
|
||||
if (!discountsForTariffService.length) return null;
|
||||
if (!discountsForTariffService.length) return null;
|
||||
|
||||
const maxValueDiscount = discountsForTariffService.reduce((prev, current) => {
|
||||
return current.condition.service.value > prev.condition.service.value ? current : prev;
|
||||
});
|
||||
const maxValueDiscount = discountsForTariffService.reduce((prev, current) => {
|
||||
return current.condition.service.value > prev.condition.service.value ? current : prev;
|
||||
});
|
||||
|
||||
return maxValueDiscount;
|
||||
return maxValueDiscount;
|
||||
}
|
||||
|
||||
function findUserDiscount(discounts: AnyDiscount[], user: User, coupon: string,): UserDiscount | null {
|
||||
const userDiscount = discounts.find((discount): discount is UserDiscount => {
|
||||
return (
|
||||
discount.conditionType === "user" &&
|
||||
discount.condition.user === user.ID &&
|
||||
discount.condition.coupon === coupon
|
||||
);
|
||||
});
|
||||
function findUserDiscount(discounts: AnyDiscount[], user: User, coupon: string): UserDiscount | null {
|
||||
const userDiscount = discounts.find((discount): discount is UserDiscount => {
|
||||
return (
|
||||
discount.conditionType === "user" && discount.condition.user === user.ID && discount.condition.coupon === coupon
|
||||
);
|
||||
});
|
||||
|
||||
return userDiscount ?? null;
|
||||
return userDiscount ?? null;
|
||||
}
|
||||
|
||||
export function createCartItem(tariff: Tariff): CartItem {
|
||||
const pricePerUnit = tariff.customPricePerUnit ?? findPrivilegeById(tariff.privilegeId)?.pricePerUnit ?? 0;
|
||||
const price = pricePerUnit * tariff.amount;
|
||||
const pricePerUnit = tariff.customPricePerUnit ?? findPrivilegeById(tariff.privilegeId)?.price ?? 0;
|
||||
const price = pricePerUnit * tariff.amount;
|
||||
|
||||
return { tariff, price, id: "someId" };
|
||||
return { tariff, price, id: "someId" };
|
||||
}
|
||||
|
||||
export function findDiscountFactor(discount: AnyDiscount): number {
|
||||
switch (discount.conditionType) {
|
||||
case "cartPurchasesAmount":
|
||||
return discount.factor;
|
||||
case "purchasesAmount":
|
||||
return discount.factor;
|
||||
case "privilege": {
|
||||
const product = discount.target.products[0];
|
||||
if (!product) throw new Error("Discount target product not found");
|
||||
switch (discount.conditionType) {
|
||||
case "cartPurchasesAmount":
|
||||
return discount.factor;
|
||||
case "purchasesAmount":
|
||||
return discount.factor;
|
||||
case "privilege": {
|
||||
const product = discount.target.products[0];
|
||||
if (!product) throw new Error("Discount target product not found");
|
||||
|
||||
return product.factor;
|
||||
}
|
||||
case "user": {
|
||||
const product = discount.target.products[0];
|
||||
if (!product) throw new Error("Discount target product not found");
|
||||
|
||||
return product.factor;
|
||||
}
|
||||
case "service":
|
||||
return discount.target.factor;
|
||||
case "userType":
|
||||
return discount.target.factor;
|
||||
return product.factor;
|
||||
}
|
||||
case "user": {
|
||||
const product = discount.target.products[0];
|
||||
if (!product) throw new Error("Discount target product not found");
|
||||
|
||||
return product.factor;
|
||||
}
|
||||
case "service":
|
||||
return discount.target.factor;
|
||||
case "userType":
|
||||
return discount.target.factor;
|
||||
}
|
||||
}
|
||||
|
||||
export function formatDiscountFactor(factor: number): string {
|
||||
return `${((1 - factor) * 100).toFixed(1)}%`;
|
||||
return `${((1 - factor) * 100).toFixed(1)}%`;
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ export interface Privilege {
|
||||
/** Единица измерения привелегии: время в днях/кол-во */
|
||||
type: "day" | "count";
|
||||
/** Стоимость одной единицы привелегии */
|
||||
pricePerUnit: number;
|
||||
price: number;
|
||||
}
|
||||
|
||||
export interface Tariff {
|
||||
|
||||
@ -7,9 +7,9 @@ import ModeEditOutlineOutlinedIcon from "@mui/icons-material/ModeEditOutlineOutl
|
||||
interface CardPrivilegie {
|
||||
name: string;
|
||||
type: "count" | "day" | "mb";
|
||||
price: string;
|
||||
price: string | number;
|
||||
description: string;
|
||||
value: string;
|
||||
value?: string;
|
||||
privilegeId: string;
|
||||
serviceKey: string;
|
||||
}
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
import { Typography } from "@mui/material";
|
||||
import { СardPrivilegie } from "./CardPrivilegie";
|
||||
import { usePrivilegies } from "@root/hooks/privilege.hook";
|
||||
import { useCombinedPrivileges } from "@root/hooks/useCombinedPrivileges.hook";
|
||||
|
||||
export default function ListPrivilegie() {
|
||||
const { privilegies, isError, isLoading, errorMessage } = usePrivilegies();
|
||||
const { mergedPrivileges, isError, errorMessage } = useCombinedPrivileges();
|
||||
|
||||
return (
|
||||
<>
|
||||
{isError ? (
|
||||
<Typography>{errorMessage}</Typography>
|
||||
) : (
|
||||
privilegies?.Шаблонизатор.map(({ name, type, price, description, value, privilegeId, serviceKey, _id }) => (
|
||||
mergedPrivileges.map(({ name, type, price, description, value, privilegeId, serviceKey, _id }) => (
|
||||
<СardPrivilegie
|
||||
key={_id}
|
||||
name={name}
|
||||
|
||||
@ -1,131 +1,158 @@
|
||||
import { Typography, Container, Button, Select, MenuItem, FormControl, InputLabel, useTheme, Box } from "@mui/material";
|
||||
import { useCombinedPrivileges } from "@root/hooks/useCombinedPrivileges.hook";
|
||||
import { CustomTextField } from "@root/kitUI/CustomTextField";
|
||||
import { Tariff } from "@root/model/tariff";
|
||||
import { findPrivilegeById, usePrivilegeStore } from "@root/stores/privileges";
|
||||
import { addTariffs } from "@root/stores/tariffs";
|
||||
import { nanoid } from "nanoid";
|
||||
import { useState } from "react";
|
||||
|
||||
|
||||
export default function CreateTariff() {
|
||||
const theme = useTheme();
|
||||
const privileges = usePrivilegeStore(store => store.privileges);
|
||||
const [nameField, setNameField] = useState<string>("");
|
||||
const [amountField, setAmountField] = useState<string>("");
|
||||
const [customPriceField, setCustomPriceField] = useState<string>("");
|
||||
const [privilegeIdField, setPrivilegeIdField] = useState<string | "">("");
|
||||
const theme = useTheme();
|
||||
const [nameField, setNameField] = useState<string>("");
|
||||
const [amountField, setAmountField] = useState<string>("");
|
||||
const [customPriceField, setCustomPriceField] = useState<string>("");
|
||||
const [privilegeIdField, setPrivilegeIdField] = useState<string>("");
|
||||
const { mergedPrivileges, isError, errorMessage } = useCombinedPrivileges();
|
||||
|
||||
const privilege = findPrivilegeById(privilegeIdField);
|
||||
const findPrivilegeById = (privilegeId: string) => {
|
||||
return mergedPrivileges.find((privilege) => privilege.privilegeId === privilegeId) ?? null;
|
||||
};
|
||||
|
||||
function handleCreateTariffClick() {
|
||||
const amount = Number(amountField);
|
||||
const customPrice = Number(customPriceField);
|
||||
const privilege = findPrivilegeById(privilegeIdField);
|
||||
|
||||
if (isNaN(amount) || !privilege) return;
|
||||
function handleCreateTariffClick() {
|
||||
const amount = Number(amountField);
|
||||
const customPrice = Number(customPriceField);
|
||||
|
||||
const newTariff: Tariff = {
|
||||
id: nanoid(5),
|
||||
name: nameField,
|
||||
amount,
|
||||
privilegeId: privilege.privilegeId,
|
||||
customPricePerUnit: customPrice ? customPrice / amount : undefined,
|
||||
};
|
||||
if (isNaN(amount) || !privilege) return;
|
||||
|
||||
addTariffs([newTariff]);
|
||||
}
|
||||
const newTariff: Tariff = {
|
||||
id: nanoid(5),
|
||||
name: nameField,
|
||||
amount,
|
||||
privilegeId: privilege.privilegeId,
|
||||
customPricePerUnit: customPrice ? customPrice / amount : undefined,
|
||||
};
|
||||
|
||||
return (
|
||||
<Container sx={{
|
||||
p: "20px",
|
||||
border: "1px solid rgba(224, 224, 224, 1)",
|
||||
borderRadius: "4px",
|
||||
addTariffs([newTariff]);
|
||||
}
|
||||
|
||||
console.log(mergedPrivileges);
|
||||
|
||||
return (
|
||||
<Container
|
||||
sx={{
|
||||
p: "20px",
|
||||
border: "1px solid rgba(224, 224, 224, 1)",
|
||||
borderRadius: "4px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "12px",
|
||||
}}
|
||||
>
|
||||
<Typography variant="h6" sx={{ textAlign: "center", mb: "16px" }}>
|
||||
Создание тарифа
|
||||
</Typography>
|
||||
<FormControl
|
||||
fullWidth
|
||||
sx={{
|
||||
height: "52px",
|
||||
color: theme.palette.secondary.main,
|
||||
"& .MuiInputLabel-outlined": {
|
||||
color: theme.palette.secondary.main,
|
||||
},
|
||||
"& .MuiInputLabel-outlined.MuiInputLabel-shrink": {
|
||||
color: theme.palette.secondary.main,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<InputLabel
|
||||
id="privilege-select-label"
|
||||
sx={{
|
||||
color: theme.palette.secondary.main,
|
||||
fontSize: "16px",
|
||||
lineHeight: "19px",
|
||||
}}
|
||||
>
|
||||
Привелегия
|
||||
</InputLabel>
|
||||
{isError ? (
|
||||
<Typography>{errorMessage}</Typography>
|
||||
) : (
|
||||
<Select
|
||||
labelId="privilege-select-label"
|
||||
id="privilege-select"
|
||||
value={privilegeIdField}
|
||||
label="Привелегия"
|
||||
onChange={(e) => setPrivilegeIdField(e.target.value)}
|
||||
sx={{
|
||||
color: theme.palette.secondary.main,
|
||||
borderColor: theme.palette.secondary.main,
|
||||
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
|
||||
borderColor: theme.palette.secondary.main,
|
||||
border: "1px solid",
|
||||
},
|
||||
".MuiSvgIcon-root ": {
|
||||
fill: theme.palette.secondary.main,
|
||||
},
|
||||
}}
|
||||
inputProps={{ sx: { pt: "12px" } }}
|
||||
>
|
||||
{mergedPrivileges.map((privilege) => (
|
||||
<MenuItem key={privilege.description} value={privilege.privilegeId}>
|
||||
{privilege.description}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
)}
|
||||
</FormControl>
|
||||
{privilege && (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "12px",
|
||||
}}>
|
||||
<Typography variant="h6" sx={{ textAlign: "center", mb: "16px" }}>Создание тарифа</Typography>
|
||||
<FormControl
|
||||
fullWidth
|
||||
sx={{
|
||||
height: "52px",
|
||||
color: theme.palette.secondary.main,
|
||||
"& .MuiInputLabel-outlined": {
|
||||
color: theme.palette.secondary.main,
|
||||
},
|
||||
"& .MuiInputLabel-outlined.MuiInputLabel-shrink": {
|
||||
color: theme.palette.secondary.main,
|
||||
}
|
||||
}}
|
||||
>
|
||||
<InputLabel
|
||||
id="privilege-select-label"
|
||||
sx={{
|
||||
color: theme.palette.secondary.main,
|
||||
fontSize: "16px",
|
||||
lineHeight: "19px",
|
||||
}}
|
||||
>Привелегия</InputLabel>
|
||||
<Select
|
||||
labelId="privilege-select-label"
|
||||
id="privilege-select"
|
||||
value={privilegeIdField}
|
||||
label="Привелегия"
|
||||
onChange={e => setPrivilegeIdField(e.target.value)}
|
||||
sx={{
|
||||
color: theme.palette.secondary.main,
|
||||
borderColor: theme.palette.secondary.main,
|
||||
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
|
||||
borderColor: theme.palette.secondary.main,
|
||||
border: "1px solid",
|
||||
},
|
||||
".MuiSvgIcon-root ": {
|
||||
fill: theme.palette.secondary.main,
|
||||
}
|
||||
}}
|
||||
inputProps={{ sx: { pt: "12px" } }}
|
||||
>
|
||||
{privileges.map((privilege, index) => (
|
||||
<MenuItem key={index} value={privilege.privilegeId}>
|
||||
{privilege.description}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
{privilege &&
|
||||
<Box sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
}}>
|
||||
<Typography>Имя: <span>{privilege.name}</span></Typography>
|
||||
<Typography>Сервис: <span>{privilege.serviceKey}</span></Typography>
|
||||
<Typography>Единица: <span>{privilege.type}</span></Typography>
|
||||
<Typography>Стандартная цена за единицу: <span>{privilege.pricePerUnit}</span></Typography>
|
||||
</Box>
|
||||
}
|
||||
<CustomTextField
|
||||
id="tariff-name"
|
||||
label="Название тарифа"
|
||||
value={nameField}
|
||||
onChange={e => setNameField(e.target.value)}
|
||||
/>
|
||||
<CustomTextField
|
||||
id="tariff-amount"
|
||||
label="Кол-во единиц привилегии"
|
||||
value={amountField}
|
||||
onChange={e => setAmountField(e.target.value)}
|
||||
type="number"
|
||||
/>
|
||||
<CustomTextField
|
||||
id="tariff-custom-price"
|
||||
label="Кастомная цена (не обязательно)"
|
||||
value={customPriceField}
|
||||
onChange={e => setCustomPriceField(e.target.value)}
|
||||
type="number"
|
||||
/>
|
||||
<Button
|
||||
onClick={handleCreateTariffClick}
|
||||
disabled={privilegeIdField === "" || amountField === "" || nameField === ""}
|
||||
>Создать</Button>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Typography>
|
||||
Имя: <span>{privilege.name}</span>
|
||||
</Typography>
|
||||
<Typography>
|
||||
Сервис: <span>{privilege.serviceKey}</span>
|
||||
</Typography>
|
||||
<Typography>
|
||||
Единица: <span>{privilege.type}</span>
|
||||
</Typography>
|
||||
<Typography>
|
||||
Стандартная цена за единицу: <span>{privilege.price}</span>
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
<CustomTextField
|
||||
id="tariff-name"
|
||||
label="Название тарифа"
|
||||
value={nameField}
|
||||
onChange={(e) => setNameField(e.target.value)}
|
||||
/>
|
||||
<CustomTextField
|
||||
id="tariff-amount"
|
||||
label="Кол-во единиц привилегии"
|
||||
value={amountField}
|
||||
onChange={(e) => setAmountField(e.target.value)}
|
||||
type="number"
|
||||
/>
|
||||
<CustomTextField
|
||||
id="tariff-custom-price"
|
||||
label="Кастомная цена (не обязательно)"
|
||||
value={customPriceField}
|
||||
onChange={(e) => setCustomPriceField(e.target.value)}
|
||||
type="number"
|
||||
/>
|
||||
<Button
|
||||
onClick={handleCreateTariffClick}
|
||||
disabled={privilegeIdField === "" || amountField === "" || nameField === ""}
|
||||
>
|
||||
Создать
|
||||
</Button>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,42 +1,43 @@
|
||||
import { Box, Button, Dialog, useTheme } from "@mui/material";
|
||||
import { CustomTextField } from "@root/kitUI/CustomTextField";
|
||||
import { changeModalPriceField, changePrivilegePrice, closePrivilegePriceModal, usePrivilegeStore } from "@root/stores/privileges";
|
||||
import {
|
||||
changeModalPriceField,
|
||||
changePrivilegePrice,
|
||||
closePrivilegePriceModal,
|
||||
usePrivilegeStore,
|
||||
} from "@root/stores/privileges";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
|
||||
|
||||
export default function ChangePriceModal() {
|
||||
const theme = useTheme();
|
||||
const isModalOpen = usePrivilegeStore(state => state.isModalOpen);
|
||||
const modalPriceField = usePrivilegeStore(state => state.modalPriceField);
|
||||
const theme = useTheme();
|
||||
const isModalOpen = usePrivilegeStore((state) => state.isModalOpen);
|
||||
const modalPriceField = usePrivilegeStore((state) => state.modalPriceField);
|
||||
|
||||
function handleSaveChange() {
|
||||
const errorMessage = changePrivilegePrice();
|
||||
if (errorMessage) enqueueSnackbar(errorMessage);
|
||||
}
|
||||
function handleSaveChange() {
|
||||
const errorMessage = changePrivilegePrice();
|
||||
if (errorMessage) enqueueSnackbar(errorMessage);
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={isModalOpen}
|
||||
onClose={closePrivilegePriceModal}
|
||||
>
|
||||
<Box sx={{
|
||||
p: "20px",
|
||||
backgroundColor: theme.palette.grayLight.main,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "8px",
|
||||
}}>
|
||||
<CustomTextField
|
||||
id="privilege-custom-price"
|
||||
label="Цена"
|
||||
value={modalPriceField}
|
||||
onChange={e => changeModalPriceField(e.target.value)}
|
||||
type="number"
|
||||
/>
|
||||
<Button
|
||||
onClick={handleSaveChange}
|
||||
>Сохранить</Button>
|
||||
</Box>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Dialog open={isModalOpen} onClose={closePrivilegePriceModal}>
|
||||
<Box
|
||||
sx={{
|
||||
p: "20px",
|
||||
backgroundColor: theme.palette.grayLight.main,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "8px",
|
||||
}}
|
||||
>
|
||||
<CustomTextField
|
||||
id="privilege-custom-price"
|
||||
label="Цена"
|
||||
value={modalPriceField}
|
||||
onChange={(e) => changeModalPriceField(e.target.value)}
|
||||
type="number"
|
||||
/>
|
||||
<Button onClick={handleSaveChange}>Сохранить</Button>
|
||||
</Box>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,51 +1,38 @@
|
||||
import { GridColDef } from "@mui/x-data-grid";
|
||||
import DataGrid from "@kitUI/datagrid";
|
||||
import { openPrivilegePriceModal, usePrivilegeStore } from "@stores/privileges";
|
||||
import { IconButton } from "@mui/material";
|
||||
import { MouseEventHandler } from "react";
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
|
||||
import { useCombinedPrivileges } from "@root/hooks/useCombinedPrivileges.hook";
|
||||
import { Typography } from "@mui/material";
|
||||
|
||||
const columns: GridColDef[] = [
|
||||
{ field: 'id', headerName: 'id', width: 40 },
|
||||
{ field: 'name', headerName: 'Привелегия', width: 150 },
|
||||
{ field: 'description', headerName: 'Описание', width: 550 },//инфо из гитлаба.
|
||||
{ field: 'type', headerName: 'Тип', width: 150 },
|
||||
{ field: 'price', headerName: 'Стоимость', width: 50 },
|
||||
{
|
||||
field: "changeValue",
|
||||
headerName: "Изменить",
|
||||
sortable: false,
|
||||
renderCell: (params) => {
|
||||
const onClick: MouseEventHandler<HTMLButtonElement> = () => {
|
||||
openPrivilegePriceModal(params.row.id, params.row.price);
|
||||
};
|
||||
|
||||
return (
|
||||
<IconButton onClick={onClick}>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
);
|
||||
},
|
||||
},
|
||||
{ field: "id", headerName: "id", width: 40 },
|
||||
{ field: "name", headerName: "Привелегия", width: 150 },
|
||||
{ field: "description", headerName: "Описание", width: 550 }, //инфо из гитлаба.
|
||||
{ field: "type", headerName: "Тип", width: 150 },
|
||||
{ field: "price", headerName: "Стоимость", width: 100 },
|
||||
];
|
||||
|
||||
export default function Privileges() {
|
||||
const privileges = usePrivilegeStore(state => state.privileges);
|
||||
const { mergedPrivileges, isError, errorMessage } = useCombinedPrivileges();
|
||||
|
||||
const privilegesGridData = privileges.map(privilege => ({
|
||||
id: privilege.privilegeId,
|
||||
name: privilege.name,
|
||||
description: privilege.description,
|
||||
type: privilege.type,
|
||||
price: privilege.pricePerUnit,
|
||||
}));
|
||||
const privilegesGridData = mergedPrivileges.map((privilege) => ({
|
||||
id: privilege.privilegeId,
|
||||
name: privilege.name,
|
||||
description: privilege.description,
|
||||
type: privilege.type,
|
||||
price: privilege.price,
|
||||
}));
|
||||
|
||||
return (
|
||||
return (
|
||||
<>
|
||||
{isError ? (
|
||||
<Typography>{errorMessage}</Typography>
|
||||
) : (
|
||||
<DataGrid
|
||||
// checkboxSelection={true}
|
||||
rows={privilegesGridData}
|
||||
columns={columns}
|
||||
// checkboxSelection={true}
|
||||
rows={privilegesGridData}
|
||||
columns={columns}
|
||||
/>
|
||||
);
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@ -29,13 +29,17 @@ export default function TariffsDG({ handleSelectionChange }: Props) {
|
||||
const gridData = tariffs.map((tariff) => ({
|
||||
id: tariff.id,
|
||||
name: tariff.name,
|
||||
serviceName: SERVICE_LIST.find((service) => service.serviceKey === findPrivilegeById(tariff.privilegeId)?.serviceKey)?.displayName,
|
||||
privilege: `(${tariff.privilegeId}) ${findPrivilegeById(tariff.privilegeId)?.description ?? "Привилегия не найдена"}`,
|
||||
serviceName: SERVICE_LIST.find(
|
||||
(service) => service.serviceKey === findPrivilegeById(tariff.privilegeId)?.serviceKey
|
||||
)?.displayName,
|
||||
privilege: `(${tariff.privilegeId}) ${
|
||||
findPrivilegeById(tariff.privilegeId)?.description ?? "Привилегия не найдена"
|
||||
}`,
|
||||
amount: tariff.amount,
|
||||
type: findPrivilegeById(tariff.privilegeId)?.type === "count" ? "день" : "шт.",
|
||||
pricePerUnit: tariff.customPricePerUnit ?? findPrivilegeById(tariff.privilegeId)?.pricePerUnit,
|
||||
pricePerUnit: tariff.customPricePerUnit ?? findPrivilegeById(tariff.privilegeId)?.price,
|
||||
isCustomPrice: tariff.customPricePerUnit === undefined ? "Нет" : "Да",
|
||||
total: tariff.amount * (tariff.customPricePerUnit ?? findPrivilegeById(tariff.privilegeId)?.pricePerUnit ?? 0),
|
||||
total: tariff.amount * (tariff.customPricePerUnit ?? findPrivilegeById(tariff.privilegeId)?.price ?? 0),
|
||||
}));
|
||||
|
||||
return (
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -3,66 +3,62 @@ import { create } from "zustand";
|
||||
import { devtools } from "zustand/middleware";
|
||||
import { exampleCartValues } from "./mocks/exampleCartValues";
|
||||
|
||||
|
||||
interface PrivilegeStore {
|
||||
privileges: Privilege[];
|
||||
isModalOpen: boolean;
|
||||
modalPrivilegeId: string | null;
|
||||
modalPriceField: string;
|
||||
addPrivileges: (newPrivileges: Privilege[]) => void;
|
||||
privileges: Privilege[];
|
||||
isModalOpen: boolean;
|
||||
modalPrivilegeId: string | null;
|
||||
modalPriceField: string;
|
||||
addPrivileges: (newPrivileges: Privilege[]) => void;
|
||||
}
|
||||
|
||||
export const usePrivilegeStore = create<PrivilegeStore>()(
|
||||
devtools(
|
||||
(set, get) => ({
|
||||
privileges: exampleCartValues.privileges,
|
||||
isModalOpen: false,
|
||||
modalPrivilegeId: null,
|
||||
modalPriceField: "",
|
||||
addPrivileges: newPrivileges => set(state => (
|
||||
{ privileges: [...state.privileges, ...newPrivileges] }
|
||||
)),
|
||||
}),
|
||||
{
|
||||
name: "Privilege store"
|
||||
}
|
||||
)
|
||||
devtools(
|
||||
(set, get) => ({
|
||||
privileges: exampleCartValues.privileges,
|
||||
isModalOpen: false,
|
||||
modalPrivilegeId: null,
|
||||
modalPriceField: "",
|
||||
addPrivileges: (newPrivileges) => set((state) => ({ privileges: [...state.privileges, ...newPrivileges] })),
|
||||
}),
|
||||
{
|
||||
name: "Privilege store",
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
export const closePrivilegePriceModal = () => usePrivilegeStore.setState({ isModalOpen: false });
|
||||
export const openPrivilegePriceModal = (modalPrivilegeId: string | null, defaultPrice: number) => usePrivilegeStore.setState(
|
||||
{
|
||||
isModalOpen: true,
|
||||
modalPriceField: defaultPrice.toString(),
|
||||
modalPrivilegeId,
|
||||
}
|
||||
);
|
||||
export const openPrivilegePriceModal = (modalPrivilegeId: string | null, defaultPrice: number) =>
|
||||
usePrivilegeStore.setState({
|
||||
isModalOpen: true,
|
||||
modalPriceField: defaultPrice.toString(),
|
||||
modalPrivilegeId,
|
||||
});
|
||||
|
||||
export const changeModalPriceField = (modalPriceField: string) => usePrivilegeStore.setState({ modalPriceField });
|
||||
|
||||
export const changePrivilegePrice = () => {
|
||||
const { privileges, modalPrivilegeId, modalPriceField } = usePrivilegeStore.getState();
|
||||
const { privileges, modalPrivilegeId, modalPriceField } = usePrivilegeStore.getState();
|
||||
|
||||
const privilegeIndex = privileges.findIndex(privilege => privilege.privilegeId === modalPrivilegeId);
|
||||
if (privilegeIndex === -1) throw new Error("Privilege not found by id");
|
||||
const privilegeIndex = privileges.findIndex((privilege) => privilege.privilegeId === modalPrivilegeId);
|
||||
if (privilegeIndex === -1) throw new Error("Privilege not found by id");
|
||||
|
||||
const price = parseFloat(modalPriceField.replace(",", "."));
|
||||
if (!isFinite(price)) return "Error parsing price";
|
||||
const price = parseFloat(modalPriceField.replace(",", "."));
|
||||
if (!isFinite(price)) return "Error parsing price";
|
||||
|
||||
const newPrivilege: Privilege = {
|
||||
...privileges[privilegeIndex],
|
||||
pricePerUnit: price,
|
||||
};
|
||||
const newPrivilege: Privilege = {
|
||||
...privileges[privilegeIndex],
|
||||
price: price,
|
||||
};
|
||||
|
||||
const newPrivileges = [...privileges];
|
||||
newPrivileges.splice(privilegeIndex, 1, newPrivilege);
|
||||
const newPrivileges = [...privileges];
|
||||
newPrivileges.splice(privilegeIndex, 1, newPrivilege);
|
||||
|
||||
usePrivilegeStore.setState({
|
||||
privileges: newPrivileges,
|
||||
isModalOpen: false,
|
||||
});
|
||||
usePrivilegeStore.setState({
|
||||
privileges: newPrivileges,
|
||||
isModalOpen: false,
|
||||
});
|
||||
};
|
||||
|
||||
export const findPrivilegeById = (privilegeId: string) => {
|
||||
return usePrivilegeStore.getState().privileges.find(privilege => privilege.privilegeId === privilegeId) ?? null;
|
||||
};
|
||||
return usePrivilegeStore.getState().privileges.find((privilege) => privilege.privilegeId === privilegeId) ?? null;
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user