Merge branch 'dev' into 'main'

Dev

See merge request frontend/marketplace!75
This commit is contained in:
Mikhail 2023-12-27 07:24:13 +00:00
commit 1e0714721f
9 changed files with 24663 additions and 504 deletions

24027
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

@ -36,6 +36,7 @@
"react-router-dom": "^6.15.0", "react-router-dom": "^6.15.0",
"react-slick": "^0.29.0", "react-slick": "^0.29.0",
"slick-carousel": "^1.8.1", "slick-carousel": "^1.8.1",
"use-debounce": "^10.0.0",
"web-vitals": "^2.1.0", "web-vitals": "^2.1.0",
"yup": "^1.1.1", "yup": "^1.1.1",
"zustand": "^4.3.8" "zustand": "^4.3.8"

@ -169,6 +169,7 @@ export default function CustomWrapperDrawer({ serviceData, outsideFactor }: Prop
serviceData.tariffs.map((tariff) => { serviceData.tariffs.map((tariff) => {
const privilege = tariff.privileges[0]; const privilege = tariff.privileges[0];
console.log('CD', tariff)
return tariff.privileges.length > 1 ? ( return tariff.privileges.length > 1 ? (
<CustomTariffAccordion outsideFactor={outsideFactor} key={tariff.id} tariffCartData={tariff} /> <CustomTariffAccordion outsideFactor={outsideFactor} key={tariff.id} tariffCartData={tariff} />
) : ( ) : (

@ -10,15 +10,17 @@ import { useDiscountStore } from "@root/stores/discounts"
import { useUserStore } from "@root/stores/user" import { useUserStore } from "@root/stores/user"
import { getDeclension } from "@root/utils/declension" import { getDeclension } from "@root/utils/declension"
import { useEffect, useState } from "react" import { useEffect, useState } from "react"
import { useDebouncedCallback } from 'use-debounce';
const sliderSettingsByType: Record<PrivilegeValueType, Partial<SliderProps>> = { const sliderSettingsByType = {
день: { max: 365 }, день: { max: 365, min: 30 },
шаблон: { max: 5000 }, шаблон: { max: 5000, min: 100 },
МБ: { max: 5000 }, МБ: { max: 5000, min: 100 },
} }
type PrivilegeName = "день" | "шаблон" | "МБ"
interface Props { interface Props {
privilege: Privilege; privilege: Privilege;
} }
export default function TariffPrivilegeSlider({ privilege }: Props) { export default function TariffPrivilegeSlider({ privilege }: Props) {
@ -47,20 +49,29 @@ export default function TariffPrivilegeSlider({ privilege }: Props) {
[currentCartTotal, discounts, purchasesAmount, privilege._id, privilege.serviceKey, throttledValue, isUserNko] [currentCartTotal, discounts, purchasesAmount, privilege._id, privilege.serviceKey, throttledValue, isUserNko]
) )
function handleSliderChange(measurement: string) { function handleSliderChange(measurement: PrivilegeName) {
return (value: number | number[]) => { return (value: number | number[]) => {
if (value < 30 && measurement === "день") {
setValue(0)
return
}
if (Array.isArray(value)) throw new Error("Slider uses multiple values instead of one") if (Number(value) < Number(sliderSettingsByType[measurement]?.min)) {
setValue(0)
return
}
setValue(value) if (Array.isArray(value)) throw new Error("Slider uses multiple values instead of one")
}
} setValue(value)
}
}
const quantityText = `${value} ${getDeclension(value, privilege.value)}` const quantityText = `${value} ${getDeclension(value, privilege.value)}`
const setNotSmallNumber = useDebouncedCallback(() => {
if (value === 0) return
if (Number(value) < Number(sliderSettingsByType[privilege.value]?.min)) {
setValue(sliderSettingsByType[privilege.value]?.min)
}
}, 600)
const quantityElement = ( const quantityElement = (
<Box <Box
@ -89,18 +100,21 @@ export default function TariffPrivilegeSlider({ privilege }: Props) {
id={"privilege_input_" + privilege._id} id={"privilege_input_" + privilege._id}
value={value} value={value}
adornmentText={getDeclension(0, privilege.value)} adornmentText={getDeclension(0, privilege.value)}
onChange={(value) => setValue(value)} onChange={(value) => {
setValue(value)
setNotSmallNumber()
}}
/> />
</Box> </Box>
</Box> </Box>
) )
const icon = const icon =
privilege.type === "day" ? ( privilege.type === "day" ? (
<CalendarIcon color={theme.palette.orange.main} bgcolor="#FEDFD0" /> <CalendarIcon color={theme.palette.orange.main} bgcolor="#FEDFD0" />
) : ( ) : (
<PieChartIcon color={theme.palette.orange.main} bgcolor="#FEDFD0" /> <PieChartIcon color={theme.palette.orange.main} bgcolor="#FEDFD0" />
) )
return ( return (
<Box> <Box>

@ -51,10 +51,10 @@ export const addCartTariffs = (tariffs: Tariff[], discounts: Discount[], purchas
useCartStore.setState( useCartStore.setState(
produce<CartStore>((state) => { produce<CartStore>((state) => {
tariffs.forEach((tariff) => { tariffs.forEach((tariff) => {
if (tariff.isCustom && tariff.privileges[0].serviceKey !== "custom") { // if (tariff.isCustom && tariff.privileges[0].serviceKey !== "custom") {
tariff.privileges[0].serviceKey = "custom" // tariff.privileges[0].serviceKey = "custom"
} // }
//
state.cartTariffMap[tariff._id] = tariff state.cartTariffMap[tariff._id] = tariff
}) })
const cartTariffs = Object.values(state.cartTariffMap).filter( const cartTariffs = Object.values(state.cartTariffMap).filter(

@ -153,6 +153,7 @@ export const setCustomTariffsUserValue = (
const loyaltyDiscount = findLoyaltyDiscount(purchasesAmount, discounts) const loyaltyDiscount = findLoyaltyDiscount(purchasesAmount, discounts)
priceAfterDiscounts *= findDiscountFactor(loyaltyDiscount) priceAfterDiscounts *= findDiscountFactor(loyaltyDiscount)
} }
console.log('cTC', cart)
state.summaryPriceBeforeDiscountsMap[serviceKey] = priceWithoutDiscounts state.summaryPriceBeforeDiscountsMap[serviceKey] = priceWithoutDiscounts
state.summaryPriceAfterDiscountsMap[serviceKey] = priceAfterDiscounts state.summaryPriceAfterDiscountsMap[serviceKey] = priceAfterDiscounts

@ -1,4 +1,4 @@
import { CartData, Discount, PrivilegeCartData, Tariff, TariffCartData, applyCartDiscount, findPrivilegeDiscount, findDiscountFactor, applyLoyaltyDiscount, applyServiceDiscounts } from "@frontend/kitui" import { CartData, Discount, PrivilegeCartData, Tariff, TariffCartData, findPrivilegeDiscount, findDiscountFactor, applyLoyaltyDiscount} from "@frontend/kitui";
function applyPrivilegeDiscounts( function applyPrivilegeDiscounts(
cartData: CartData, cartData: CartData,
@ -28,7 +28,92 @@ function applyPrivilegeDiscounts(
}); });
}); });
} }
function findServiceDiscount(
serviceKey: string,
currentPrice: number,
discounts: Discount[],
): Discount | null {
const applicableDiscounts = discounts.filter(discount => {
return (
discount.Layer === 2 &&
discount.Condition.Group === serviceKey &&
currentPrice >= Number(discount.Condition.PriceFrom)
);
});
if (!applicableDiscounts.length) return null;
const maxValueDiscount = applicableDiscounts.reduce((prev, current) => {
return Number(current.Condition.PriceFrom) > Number(prev.Condition.PriceFrom) ? current : prev;
});
return maxValueDiscount;
}
function findCartDiscount(
cartPurchasesAmount: number,
discounts: Discount[],
): Discount | null {
const applicableDiscounts = discounts.filter(discount => {
return (
discount.Layer === 3 &&
cartPurchasesAmount >= Number(discount.Condition.CartPurchasesAmount)
);
});
console.log('FCD', applicableDiscounts)
if (!applicableDiscounts.length) return null;
const maxValueDiscount = applicableDiscounts.reduce((prev, current) => {
return Number(current.Condition.CartPurchasesAmount) > Number(prev.Condition.CartPurchasesAmount) ? current : prev;
});
return maxValueDiscount;
}
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;
}
function applyServiceDiscounts(
cartData: CartData,
discounts: Discount[],
) {
const privMap = new Map()
cartData.services.forEach(service => {
service.tariffs.forEach(tariff => tariff.privileges.forEach(p => {
privMap.set(p.serviceKey, p.price + (privMap.get(p.serviceKey)||0))
}))
})
cartData.services.forEach(service => {
service.tariffs.map(tariff => {
tariff.privileges.forEach(privilege => {
const privilegeDiscount = findServiceDiscount(privilege.serviceKey, privMap.get(privilege.serviceKey), 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 calcCart(tariffs: Tariff[], discounts: Discount[], purchasesAmount: number, isUserNko?: boolean): CartData { export function calcCart(tariffs: Tariff[], discounts: Discount[], purchasesAmount: number, isUserNko?: boolean): CartData {
const cartData: CartData = { const cartData: CartData = {
@ -47,10 +132,12 @@ export function calcCart(tariffs: Tariff[], discounts: Discount[], purchasesAmou
&& tariff.privileges.length !== 1 && tariff.privileges.length !== 1
) throw new Error("Price is defined for tariff with several") ) throw new Error("Price is defined for tariff with several")
let serviceData = cartData.services.find(service => service.serviceKey === tariff.privileges[0].serviceKey) let serviceData =cartData.services.find(service => (service.serviceKey === "custom" && tariff.isCustom))
if (!serviceData && !tariff.isCustom) serviceData = cartData.services.find(service => service.serviceKey === tariff.privileges[0].serviceKey)
if (!serviceData) { if (!serviceData) {
serviceData = { serviceData = {
serviceKey: tariff.privileges[0].serviceKey, serviceKey: tariff.isCustom ?"custom" :tariff.privileges[0].serviceKey,
tariffs: [], tariffs: [],
price: 0, price: 0,
appliedServiceDiscount: null, appliedServiceDiscount: null,

@ -16,6 +16,7 @@ export function calcIndividualTariffPrices(
let priceAfterDiscounts = 0 let priceAfterDiscounts = 0
const cart = calcCart([...currentTariffs, tariff], discounts, purchasesAmount, isUserNko) const cart = calcCart([...currentTariffs, tariff], discounts, purchasesAmount, isUserNko)
if (cart.allAppliedDiscounts[0]?.Target.Overhelm) return {priceBeforeDiscounts: priceBeforeDiscounts, priceAfterDiscounts: priceBeforeDiscounts * cart.allAppliedDiscounts[0].Target.Factor }
cart.services.forEach(s => { cart.services.forEach(s => {
if (s.serviceKey === tariff.privileges[0].serviceKey) { if (s.serviceKey === tariff.privileges[0].serviceKey) {
let processed = false let processed = false

979
yarn.lock

File diff suppressed because it is too large Load Diff