Отслеживайте очки лояльности, срок действия которых истекает, используя PHP - PullRequest
0 голосов
/ 30 августа 2018

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

Это то, что происходит. У нас есть система карт лояльности, где люди получают баллы за покупки. Затем они могут использовать эти очки для покупки вещей. Причиной проблемы является правило, согласно которому срок действия баллов истекает через 6 месяцев.

Код, который сейчас используется, но содержит ошибку, просто говорит что-то вроде:

$currentPoints = array_sum($lastSixMonths);

где $ lastSixMonths - массив, содержащий все положительные и отрицательные точки за предыдущие месяцы. Возможно, что-то вроде этого:

$lastSixMonths = array (
'2018-01-10' => -1000,  
'2018-02-10' => 10, 
'2018-03-10' => 10, 
'2018-04-10' => 10, 
'2018-05-10' => 10);

В этом случае $ currentPoints = -960, что должно быть невозможно. Причина в том, что если бы я взял последние 7 месяцев, я бы получил что-то вроде этого (в большинстве случаев это очень упрощенная версия):

$lastSevenMonths = array (
'2017-12-10' => 1000,
'2018-01-10' => -1000,  
'2018-02-10' => 10, 
'2018-03-10' => 10, 
'2018-04-10' => 10, 
'2018-05-10' => 10);

Скажем, сегодня 1 июля 2018 года. Последние 6 месяцев будут 1 января - 30 июня 2018 года. Последние 7 месяцев будут 1 декабря 2017 года - 30 июня 2018 года.

Итак, 10 декабря клиент набрал 1000 очков и использовал их 10 января, когда срок их действия еще не истек. Но сегодня срок действия транзакции «декабрь» истек, но не транзакции «январь».

Как это можно сделать?

Имейте в виду, что клиент может использовать столько баллов, сколько он хочет, поэтому он мог использовать только 2 балла или любую другую сумму в январе (до 1000), поэтому я не могу просто отметить транзакции в декабре и январе как "завершено".

Единственный способ, которым я могу думать об этом, - это брать каждую отрицательную транзакцию и даже сравнивать ее со всеми положительными транзакциями, прошедшими 6 месяцев назад. Я не написал код, но кажется, что он будет очень трудоемким, если я сделаю это таким образом, как я должен сделать это для миллионов строк транзакций и десятков тысяч клиентов, и каждая строка проходит по циклу каждый день последних шести месяцев, начиная с первого дня.

Есть предложения по лучшему методу?

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

Похоже, что любой ответ должен был бы отчетливо записывать, когда очки заработаны и когда эти конкретные очки потрачены.

Таким образом, для каждой записи баллов у вас могут быть следующие поля:

«очки», «потрачено», «дата и год»

Затем, когда человек тратит очки, он отмечает самые старые (все еще действительные) записи очков как потраченные. У вас может быть запись, которая выглядит следующим образом:

Points: 10, Spent: 7, Date Earned: 2018-03-15

Затем вы ищете очки, заработанные за последние шесть месяцев, и вычитаете общую сумму, потраченную из тех же записей. Что-то вроде (псевдо-SQL):

SELECT ( sum(points) - sum(spent) ) AS points_remaining FROM loyalty_points WHERE date_earned > [date six months ago] AND user_id=?

Сложная часть - это начисление баллов по мере их расходования - поскольку расходование 150 баллов может охватить несколько записей заработанных баллов, переходя от самых старых к новейшим.

0 голосов
/ 30 августа 2018

Поскольку срок действия очков, заработанных более 6 месяцев назад, истек, вы можете рассматривать их, как если бы их баланс равнялся нулю шесть месяцев назад. Любые покупки до получения первой награды в $lastSixMonths должны быть сделаны с использованием очков, срок действия которых истек, поэтому вы можете их игнорировать. Так что если у вас есть

$lastSixMonths = array (
'2018-01-10' => -1000,  
'2018-02-10' => 10, 
'2018-03-10' => 10, 
'2018-04-10' => 10, 
'2018-05-10' => 10);

Вы можете удалить любые начальные отрицательные записи:

foreach ($lastSixMonths as $date => $amount) {
    if ($amount >= 0) {
        break;
    } else {
        unset($lastSixMonths[$date]);
    }
}

Затем вы можете использовать array_sum($lastSixMonths), чтобы получить их текущий баланс.

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