| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > MySQL > Помогите с логикой под бонусы |
| Автор: maxipub 11.9.2019, 12:39 | ||||||
| Добрый день! Разрабатываю модуль бонусов для интернет-магазина. Клиент делает покупку, через определенное время ему на счет зачисляется указанный процент бонусов от суммы покупки. Бонусами он может оплачивать последующие заказы. После зачисления бонусы действуют ограниченное время. Например: вы получаете 5% бонусами через 10 дней после покупки, бонусы действуют в течение 30 дней. Храню начисленные бонусы в отдельной таблице, где одна строка - это бонусы за конкретный заказ:
Появилась маленькая загвоздка с определением текущего баланса бонусов. По первой логике, текущий баланс = действующие зачисленные бонусы - использованные бонусы этого периода. Действующие бонусы:
Для получения использованных бонусов используется аналогичный запрос, но с джойном таблицы заказов. В ней у каждого заказа есть сумма бонусов, списанная в нем. Там в качестве привязки по времени используется время оформления заказа:
Ведь нам надо убедиться, что заказ был оформлен когда бонусы уже начали действовать, и до того момента, пока срок их действия еще не истек. И тут возникает казус. Возьмем такую хронологию: 01 сентября: зачислено 100 бонусов с периодом действия по 30 сентября (баланс 100 бонусов - ok); 10 сентября: зачислено 50 бонусов с периодом действия по 10 октября (баланс 150 бонусов - ok); 20 сентября: приходит заказ и списывает 100 бонусов (баланс 50 бонусов - ok); 01 октября: баланс -50 бонусов - !!! Все дело в том, что 1 октября заканчивается срок действия бонусов с 1 по 30 сентября, но еще действуют бонусы с 10 сентября по 10 октября - именно они и списываются. Можно как то решить эту проблему средствами MySQL? Второй день бьюсь, ни к чему не пришел. Списание бонусов в БД ни где не фиксируется отдельной записью (т.е. просто рассчитывается на основании начисленных бонусов и их периодов действия - с одной стороны, и количества списываемых бонусов с датой поступления заказов - с другой стороны) типа bonus_used_by_order_id - т.к. нет гарантии что по заказу будут списаны все начисленные этой записью бонусы (например, зачислено 500 бонусов, а списано только 100 - одним заказом, 300 - другим, и 100 "сгорели"). Единственное решение которое я пока вижу - выгружать данные в PHP массив, и проходясь по нему. Это не сложно вроде будет сделать, но как-то по ламерски что ли. Заранее спасибо за участие! |
| Автор: Akina 11.9.2019, 14:13 |
| Первое, что приходит в голову - поле BonusUsed, в которое при использовании заносится ID заказа. И, как следствие - поле суммы списанных бонусов в таблице заказов становится лишним. |
| Автор: Akina 11.9.2019, 15:05 |
И в то же время по одному заказу может списываться несколько бонусов. Итого - классическая много-ко-много. Которая требует отдельной таблицы (ИД заказа - ИД бонуса - сумма списания). Ну и соответственно плюс дополнительные констрейнты, которые не дают заминуситься бонусу (списать больше, чем предоставил бонус). Добавлено через 1 минуту и 58 секунд Речь идёт о деньгах - значит, подобной ситуации не может быть в принципе. |
| Автор: maxipub 12.9.2019, 11:54 | ||||
Интересный термин, не знал.
Ну да, решение очевидное. Конечно, хотелось бы без этой "лишней" таблицы. Но похоже придется или с ней, или на логике через PHP.
Принятие заказа на выполнение сменяет его статус. При смене статуса фиксируется доступное количество бонусов. Все это происходит при блокировке таблиц. Как мне кажется, если явно не накосячить - проблем быть не должно. |