Update README.md

This commit is contained in:
Mikhail 2024-03-20 19:57:35 +00:00
parent 3bee10b347
commit b8c7fad3c2

@ -113,43 +113,17 @@ Si = A1 * P1 * F1 + A2 * P2 * F2 + ... + An * Pn * Fn
## Новая логика рассчёта скидки
Логика слоёв вычисления скидок почти та же самая. Но есть нюанс - суммирование можно делать только в самом конце
Слой 1:
Подготовка - если у привилегии в тарифе есть ненулевой price, то берём его в качестве цены. если нет - умножаем стоимость привилегии на amount этой привилегии в рамках тарифа. создаём map с ключем - айдишником привилегии, значением - суммарным количеством всех amount привилегий с таким же айдишником. это надо потому что в корзине может быть много тарифов с одной и той же привилегией, но разным количеством оной, а скидка применяется к общему количеству этой привилегии в корзине. Создаём map(будем далее называть Применяемые скидки) с ключем - айдишником привилегии, а значение - массив скидок, который применится к этой привилегии
Фильтрация - если userType == nko - выбираем единственную скидку за nko. Иначе - выбираем все скидки у которых layer 1 и Term <= amount привилегии или скидки у которых есть UserInformation.ID == Condition.User
Макс - если выбрана nko, то этот пункт пропускаем. Иначе - для каждой привилегии выбираем скидку с максимальным Term. Если есть скидка с Condition.User != "" - берём её, остальные на эту привилегию игнорируем
Применение - добавляем в массив применяемых к привилегии скидок в ПрименяемыеСкидки. т.е. по итогам работы этого слоя мы получим на выходе ПрименяемыеСкидки размером с количество уникальных привилегий в рамках и со значениями в виде пустого массива или массива с одним элементом - скидкой за этот слой. Перефразирую: за этот слой может быть получена только скидка с Condition.User != "" или скидкой за эту привилегию. если выбрана скидка nko, то суммируем все стоимости привилегий, умножаем на Factor скидки за nko и прерываем рассчёт скидки, ибо остальные слои в случае nko не принимаются
Слой 2:
Подготовка - суммируем список привилегий с их стоимостями после применения скидок первого слоя, формируя map с ключём - serviceKey, а значением - стоимостью всех привилегий по этому сервису
Фильтрация - выбираем скидки где layer == 2, group == ключ подготовленной map, PriceFrom <= значение подготовленной map или скидки у которых есть UserInformation.ID == Condition.User
Mакс - оставляем скидки с максимальным PriceFrom в рамках group. Если есть скидка с Condition.User != "" - берём её, остальные на этот сервис игнорируем
Применение - если есть скидка с Condition.User != "", то очищаем массив скидок применяемых к этой привилегии и складываем туда эту найденную. Иначе - складываем в массив максимальную подходящую скидку к этому сервису.
Слой 3:
Подготовка - суммируем map подготовленную на прошлом слое, после применения всех скидок. Это размер корзины
Фильтрация - выбираем скидки где layer == 3, CartPurchasesAmount <= полученное значение после суммирования
Макс - выбираем скидку с максимальным значением CartPurchasesAmount
Применение - умножаем на Factor из найденной скидки, если в списке скидок, применяемых к привилегии всего один элемент, где layer == 2 и Condition.User != "" - не добавляем скидку в массив применяемых скидок. иначе - добавляем
Слой 4:
Подготовка - никакой, всё сделано на прошлом слое
Фильтрация - выбираем скидки где layer == 4, purchasesAmount <= значение после применения скидки предыдущего слоя
Макс - выбираем скидку с максимальным значением purchasesAmount
Применения - умножаем на Factor выбранной скидки, если в списке скидок, применяемых к привилегии всего один элемент, где layer == 2 и Condition.User != "" - не добавляем скидку в массив применяемых скидок. иначе - добавляем. Когда формирование массивов применяемых скидок окончено - проходимся в цикле по всей ПрименяемыеСкидки, и применяем к стоимости привилегии, полученной в слое 1 каждый Factor из скидок, которые соответствуют этой привилегии. после применения, суммируем. это - результат вычисления стоимости корзины
- вычисляем количество привилегий во всей корзине - создаём map[Product]amount
- вычисляем стоимость каждой привилегии в корзине - создаём map[Product]price
- вычисляем стоимость каждой привилегии в корзине - создаём map[Product]serviceKey
- если в CommonConditions есть UserType == "nko", то ищем скидку за nko, суммируем ассоциативный массив цен за привилегии, умножаем на эту скидку и возвращаем
- иначе, выбираем скидки за 1 Слой. убедись, что запрос способен получать скидки с Condition.User. если не способен - можешь получить скидки на юзера отдельным запросом в самом начале расчета - это всё равно всегда одна скидка
- проходимся по ассоциативному массиву цен, ищем в списке скидок скидки за этот продукт. если есть скидка на этого юзера с layer == 1, то применяем её вместо скидки, которую нашли по getLayer. если есть скидка на этого юзера слоя 2 на этот сервис, не применяем никакой скидк(вернее применяем никакую скидку). что значит примеменить скидку - умножить стоимость этой привилегии на фактор скидки и добавить к текущему значению в ассоциативном массиве цен за сервис
- выбираем 2 Слой
- проходимся по ассоциативному массиву стоимости сервисов. если есть скидка на юзера со слоем 2 и на этот сервис - применяем её. иначе применяем скидку на этот сервис. т.е. умножаем стоимости сервиса на фактор скидки и обновляем значение в самом ассоциативном массиве
- суммируем ассоциативный массив стоимости сервисов
- выбираем 3 Слой с учетом просуммированной стоимости корзины на прошлом этапе
- применяем эту скидку ко всем стоимостям сервисов по отдельности, кроме того, на который есть скидка 2 уровня у этого юзера
- выбираем 4 Слой
- применяем эту скидку ко всем стоимостям сервисов по отдельности, кроме того, на который есть скидка 2 уровня у этого юзера
- суммируем и возвращаем