Модераторы: skyboy, SamDark
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите с логикой под бонусы 
:(
    Опции темы
maxipub
Дата 11.9.2019, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 517
Регистрация: 22.10.2009

Репутация: 1
Всего: 1



Добрый день!

Разрабатываю модуль бонусов для интернет-магазина. Клиент делает покупку, через определенное время ему на счет зачисляется указанный процент бонусов от суммы покупки. Бонусами он может оплачивать последующие заказы. После зачисления бонусы действуют ограниченное время.

Например: вы получаете 5% бонусами через 10 дней после покупки, бонусы действуют в течение 30 дней.

Храню начисленные бонусы в отдельной таблице, где одна строка - это бонусы за конкретный заказ:

Код
CREATE TABLE IF NOT EXISTS `buyers_bonus` (
  `buyer_id` int(10) unsigned NOT NULL,
  `order_id` int(10) unsigned NOT NULL,
  `bonus_sum` int(10) unsigned NOT NULL,
  `bonus_valid_from` int(10) unsigned NOT NULL,
  `bonus_valid_till` int(10) unsigned NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;


Появилась маленькая загвоздка с определением текущего баланса бонусов. По первой логике, текущий баланс = действующие зачисленные бонусы - использованные бонусы этого периода. Действующие бонусы:

Код
SELECT SUM(bonus_sum) FROM buyers_bonus WHERE buyer_id=123 AND bonus_valid_from<=UNIX_TIMESTAMP() AND bonus_valid_till>=UNIX_TIMESTAMP();


Для получения использованных бонусов используется аналогичный запрос, но с джойном таблицы заказов. В ней у каждого заказа есть сумма бонусов, списанная в нем. Там в качестве привязки по времени используется время оформления заказа:

Код
... c.order_time>=b.bonus_valid_from AND c.order_time<=b.bonus_valid_till ...


Ведь нам надо убедиться, что заказ был оформлен когда бонусы уже начали действовать, и до того момента, пока срок их действия еще не истек.

И тут возникает казус. Возьмем такую хронологию:

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 массив, и проходясь по нему. Это не сложно вроде будет сделать, но как-то по ламерски что ли. smile 

Заранее спасибо за участие! smile 

Это сообщение отредактировал(а) maxipub - 11.9.2019, 12:42
PM MAIL   Вверх
Akina
Дата 11.9.2019, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20419
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 449



Первое, что приходит в голову - поле BonusUsed, в которое при использовании заносится ID заказа. И, как следствие - поле суммы списанных бонусов в таблице заказов становится лишним.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
maxipub
Дата 11.9.2019, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 517
Регистрация: 22.10.2009

Репутация: 1
Всего: 1



Цитата(Akina @  11.9.2019,  14:13 Найти цитируемый пост)
Первое, что приходит в голову - поле BonusUsed, в которое при использовании заносится ID заказа. И, как следствие - поле суммы списанных бонусов в таблице заказов становится лишним.
На одну запись бонусов может быть несколько заказов:
Цитата(maxipub @  11.9.2019,  12:39 Найти цитируемый пост)
Списание бонусов в БД ни где не фиксируется отдельной записью ... типа bonus_used_by_order_id - т.к. нет гарантии что по заказу будут списаны все начисленные этой записью бонусы (например, зачислено 500 бонусов, а списано только 100 - одним заказом, 300 - другим, и 100 "сгорели").


Добавлено через 4 минуты и 10 секунд
И помимо этого, заказ может использовать несколько бонусов. Т.е. начислилось 10 бонусов от одного заказа, 20 - от второго, 30 - от третьего. И если позволяет их bonus_valid_from и bonus_valid_till (заказы делались с коротким промежутком времени) - третий заказ может использовать все 10 + 20 + 30 бонусов.

По этим двум причинам BonusUsed не катит (несколько заказов на один бонус). И удаление поля количества списанных бонусов в таблице заказов так же (ладно, мы можем просчитать сумму по нескольким BonusUsed, но нет гарантий что по каждому будет 100% списание бонусов - поэтому будут случаи, когда таким образом не удастся установить правильное количество списанных бонусов).
PM MAIL   Вверх
Akina
Дата 11.9.2019, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20419
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 449



Цитата(maxipub @  11.9.2019,  15:54 Найти цитируемый пост)
На одну запись бонусов может быть несколько заказов:

И в то же время по одному заказу может списываться несколько бонусов. 

Итого - классическая много-ко-много. Которая требует отдельной таблицы (ИД заказа - ИД бонуса - сумма списания).

Ну и соответственно плюс дополнительные констрейнты, которые не дают заминуситься бонусу (списать больше, чем предоставил бонус).

Добавлено через 1 минуту и 58 секунд
Цитата(maxipub @  11.9.2019,  13:39 Найти цитируемый пост)
Списание бонусов в БД ни где не фиксируется отдельной записью

Речь идёт о деньгах - значит, подобной ситуации не может быть в принципе.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
maxipub
Дата 12.9.2019, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 517
Регистрация: 22.10.2009

Репутация: 1
Всего: 1



Цитата(Akina @  11.9.2019,  15:05 Найти цитируемый пост)
Итого - классическая много-ко-много.

Интересный термин, не знал. smile 

Цитата(Akina @  11.9.2019,  15:05 Найти цитируемый пост)
Которая требует отдельной таблицы (ИД заказа - ИД бонуса - сумма списания).

Ну да, решение очевидное. Конечно, хотелось бы без этой "лишней" таблицы. Но похоже придется или с ней, или на логике через PHP.

Цитата(Akina @  11.9.2019,  15:05 Найти цитируемый пост)
Речь идёт о деньгах - значит, подобной ситуации не может быть в принципе.

Принятие заказа на выполнение сменяет его статус. При смене статуса фиксируется доступное количество бонусов. Все это происходит при блокировке таблиц. Как мне кажется, если явно не накосячить - проблем быть не должно. smile
PM MAIL   Вверх
Google
  Дата 19.9.2019, 02:56 (ссылка)  





  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.1003 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.