php – 从电子钱包系统计算可用余额,不包括过期信用
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了php – 从电子钱包系统计算可用余额,不包括过期信用,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7247字,纯文字阅读大概需要11分钟。
内容图文
![php – 从电子钱包系统计算可用余额,不包括过期信用](/upload/InfoBanner/zyjiaocheng/747/bb355f36afaf4b9ab0c7f64426def2e5.jpg)
在信用表我有
(id, user_id, process, amount, date_add, date_exp, date_redeemed, remark)
SELECT * FROM credits WHERE user_id = 2;
+----+---------+---------+--------+------------+------------+---------------+----------+
| id | user_id | process | amount | date_add | date_exp | date_redeemed | remark |
+----+---------+---------+--------+------------+------------+---------------+----------+
| 22 | 2 | Add | 200.00 | 2018-01-01 | 2019-01-01 | | Credit1 |
| 23 | 2 | Add | 200.00 | 2018-03-31 | 2019-03-31 | | Credit2 |
| 24 | 2 | Deduct | 200.00 | | | 2018-04-28 | Redeemed |
| 25 | 2 | Add | 200.00 | 2018-07-11 | 2018-10-11 | | Campaign |
| 26 | 2 | Deduct | 50.00 | | | 2018-08-30 | Redeemed |
| 27 | 2 | Add | 200.00 | 2018-10-01 | 2019-09-30 | | Credit3 |
| 28 | 2 | Deduct | 198.55 | | | 2018-10-20 | Redeemed |
+----+---------+---------+--------+------------+------------+---------------+----------+
我写的以下查询只会计算余额,但我不知道信用是否过期并在过期之前使用.
SELECT
u.id,
email,
CONCAT(first_name, ' ', last_name) AS name,
type,
(CASE
WHEN (SUM(amount) IS NULL) THEN 0.00
ELSE CASE
WHEN
(SUM(CASE
WHEN process = 'Add' THEN amount
END) - SUM(CASE
WHEN process = 'Deduct' THEN amount
END)) IS NULL
THEN
SUM(CASE
WHEN process = 'Add' THEN amount
END)
ELSE SUM(CASE
WHEN process = 'Add' THEN amount
END) - SUM(CASE
WHEN process = 'Deduct' THEN amount
END)
END
END) AS balance
FROM
users u
LEFT JOIN
credits c ON u.id = c.user_id
GROUP BY u.id;
或者我是以错误的方式做到的?也许我应该在后端而不是SQL中完成计算?
编辑1:
我想计算每个用户的电子钱包的余额,但信用额度将到期,
如果它已过期且未兑换,则从余额中扣除
ELSE如果在到期之前使用并且兑换金额<到期金额
然后(余额 – (到期金额 – 赎回金额))
ELSE如果在到期之前使用并且兑换金额>到期金额
然后,可用余额将被扣除,因为到期金额不足以扣除兑换金额
编辑2:
上面的查询将输出351.45,我的预期输出为201.45.由于赎回金额低于到期金额,因此不会计算2018-08-30的赎回金额
编辑3:
用户表:
+----+------------+-----------+----------+----------------+----------+
| id | first_name | last_name | type | email | password |
+----+------------+-----------+----------+----------------+----------+
| 2 | Test | Oyster | Employee | test@gmail.com | NULL |
+----+------------+-----------+----------+----------------+----------+
我的输出:
+----+----------------+-------------+----------+---------+
| id | email | name | type | balance |
+----+----------------+-------------+----------+---------+
| 2 | test@gmail.com | Test Oyster | Employee | 351.45 |
+----+----------------+-------------+----------+---------+
预期产量:
总计(200 200 200)600
已兑换金额448.55(200 50 198.55)
剩余余额为151.45
+----+----------------+-------------+----------+---------+
| id | email | name | type | balance |
+----+----------------+-------------+----------+---------+
| 2 | test@gmail.com | Test Oyster | Employee | 151.45 |
+----+----------------+-------------+----------+---------+
解决方法:
您当前的表存在基本的结构问题.所以我建议对表结构和随后的应用程序代码进行一些更改.钱包系统的表结构可以非常详细;但我建议尽可能少改变.我并不是说这是理想的方式;但它应该工作.最初,我将用当前的方法来布局一些问题.
问题:
>如果有多个Credits尚未过期怎么办?
>在这些可用的积分中,有些可能实际上已经被使用,但尚未过期.我们如何忽略它们的可用余额?
>此外,有些可能已被部分利用.我们如何解释部分利用?
>可能存在兑换金额跨越多个未到期信用额的情况.有些可能会被部分利用;有些人可能会得到充分利用.
一般实践:
我们通常遵循先进先出(先入先出)的方法,为客户提供最大的利益.因此,首先使用较旧的信用(具有较高的未使用过期的可能性).
为了遵循FIFO,我们必须每次在查询/应用程序代码中有效地使用循环技术,以便计算基本的东西,例如“可用的钱包余额”,“过期和未充分利用的信用”等.为此编写查询将是麻烦的,并且在更大的范围内可能效率低下
解:
我们可以在当前表中再添加一列amount_redeemed.它基本上代表已经兑换特定信贷的金额.
ALTER TABLE credits ADD COLUMN amount_redeemed DECIMAL (8,2);
因此,填充表格如下所示:
+----+---------+---------+--------+-----------------+------------+---------------+---------------+----------+
| id | user_id | process | amount | amount_redeemed | date_add | date_exp | date_redeemed | remark |
+----+---------+---------+--------+-----------------+------------+---------------+---------------+----------+
| 22 | 2 | Add | 200.00 | 200.00 | 2018-01-01 | 2019-01-01 | | Credit1 |
| 23 | 2 | Add | 200.00 | 200.00 | 2018-03-31 | 2019-03-31 | | Credit2 |
| 24 | 2 | Deduct | 200.00 | | | | 2018-04-28 | Redeemed |
| 25 | 2 | Add | 200.00 | 0.00 | 2018-07-11 | 2018-10-11 | | Campaign |
| 26 | 2 | Deduct | 50.00 | | | | 2018-08-30 | Redeemed |
| 27 | 2 | Add | 200.00 | 48.55 | 2018-10-01 | 2019-09-30 | | Credit3 |
| 28 | 2 | Deduct | 198.55 | | | | 2018-10-20 | Redeemed |
+----+---------+---------+--------+-----------------+------------+---------------+---------------+----------+
请注意,使用FIFO方法,对于id = 25的Credit,amount_redeemed为0.00.它有机会在2018-10-20兑换,但到那时,它已经到期(date_exp = 2018-10-11)
所以,现在我们有了这个设置,你可以在你的应用程序代码中做以下事情:
>在表中的现有行中填充amount_redeemed值:
这将是一次性活动.为此,制定单个查询将是困难的(这就是为什么我们首先在这里).因此,我建议您使用循环和FIFO方法在您的应用程序代码(例如:PHP)中执行一次.请看下面的第3点,了解如何在应用程序代码中执行此操作.
>获取当前可用余额:
现在对此的查询变得微不足道,因为我们只需要计算所有Add过程的金额 – amount_redeemed,它们尚未过期.
SELECT SUM(amount - amount_redeemed) AS total_available_credit
FROM credits
WHERE process = 'Add' AND
date_exp > CURDATE() AND
user_id = 2
>兑换时更新amount_redeemed:
在此,您可以首先获得所有可用的积分,其中有可用于兑换的金额,但尚未过期.
SELECT id, (amount - amount_redeemed) AS available_credit
FROM credits
WHERE process = 'Add' AND
date_exp > CURDATE() AND
user_id = 2 AND
amount - amount_redeemed > 0
ORDER BY id
现在,我们可以循环上面的查询结果,并相应地使用金额
// PHP code example
// amount to redeem
$amount_to_redeem = 100;
// Map storing amount_redeemed against id
$amount_redeemed_map = array();
foreach ($rows as $row) {
// Calculate the amount that can be used against a specific credit
// It will be the minimum of available credit and amount left to redeem
$amount_redeemed = min($row['available_credit'], $amount_to_redeem);
// Populate the map
$amount_redeemed_map[$row['id']] = $amount_redeemed;
// Adjust the amount_to_redeem
$amount_to_redeem -= $amount_redeemed;
// If no more amount_to_redeem, we can finish the loop
if ($amount_to_redeem == 0) {
break;
} elseif ($amount_to_redeem < 0) {
// This should never happen, still if it happens, throw error
throw new Exception ("Something wrong with logic!");
exit();
}
// if we are here, that means some more amount left to redeem
}
现在,您可以使用两个Update查询.第一个将根据所有Credit id更新amount_redeemed值.第二个是使用所有单个amount_redeemed值的总和插入Deduct行.
内容总结
以上是互联网集市为您收集整理的php – 从电子钱包系统计算可用余额,不包括过期信用全部内容,希望文章能够帮你解决php – 从电子钱包系统计算可用余额,不包括过期信用所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。