我正在尝试改善我尚未编写的代码。有人用另一种语言写了一个代码,但是有一个错误,所以我试图写类似的东西而没有这个错误,但是我想不出一种整洁的方式。
这是怎么回事。 我们有一个会员卡系统,人们可以在其中获得购买积分。 然后,他们可以使用这些积分购买商品。 引起问题的是一条规则,规定积分在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);
让我们说今天是2018年7月1日。 最后6个月将是2018年1月1日至6月30日。 最后7个月为2017年12月1日至2018年6月30日。
因此,在12月10日,一位客户获得了1000分,并在1月10日还没有到期时使用了它们。但是今天,Dec交易已过期,但Jan交易尚未过期。
这怎么办?
请记住,客户可以使用任意数量的积分,因此他可能在一月份只使用了2个积分或任何其他金额(最多1000个积分),所以我不能只标记12月和1月的交易为“已完成”。
我能想到的唯一方法是在过去的6个月中,将所有负交易都带走,甚至将所有正交易都带走。 我还没有写出代码,但是如果这样做的话,那感觉会非常耗时,因为我必须对数百万个交易行和数万个客户执行此操作,并且每行都会循环从第1天开始,过去六个月中的每一天。
有没有更好的方法建议?
答案 0 :(得分:0)
由于六个月前赢得的任何积分都已过期,因此您可以将其视为六个月前的余额为零。在...
.Range("A2:AA" & lastRow).Sort Key1:=.Cells(2, 19), Order1:=xlAscending, _
Key2:=.Cells(2, 16), Order2:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlNo
...
中获得第一个奖励之前的任何购买都必须使用已过期的积分进行,因此您可以忽略它们。所以如果你有
$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]);
}
}
来获取其当前余额。
答案 1 :(得分:0)
似乎所有答案都必须明确记录何时获得积分以及何时花费这些特定积分。
因此对于每个点记录,您可能具有以下字段:
“积分”,“消费”,“获得日期”
然后,当该人花费积分时,它会标记出最旧(仍有效)的积分记录。您可能有一条类似以下的记录:
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积分可能会跨越所获得积分的多条记录,从最早到最新。