|
|
@@ -21,6 +21,7 @@ use common\components\dateUtil;
|
|
|
use common\components\dict;
|
|
|
use common\components\lakala\Lakala;
|
|
|
use common\components\noticeUtil;
|
|
|
+use common\components\orderSn;
|
|
|
use common\components\util;
|
|
|
use Yii;
|
|
|
use bizHd\base\classes\BaseClass;
|
|
|
@@ -39,6 +40,14 @@ class RechargeClass extends BaseClass
|
|
|
case 'system':
|
|
|
$where['onlinePay'] = 2;
|
|
|
break;
|
|
|
+ case 'online_0':
|
|
|
+ $where['onlinePay'] = 2;
|
|
|
+ $where['payWay'] = 0;
|
|
|
+ break;
|
|
|
+ case 'online_1':
|
|
|
+ $where['onlinePay'] = 2;
|
|
|
+ $where['payWay'] = 1;
|
|
|
+ break;
|
|
|
case 'pay_0':
|
|
|
$where['onlinePay!='] = 2;
|
|
|
$where['payWay'] = 0;
|
|
|
@@ -72,11 +81,7 @@ class RechargeClass extends BaseClass
|
|
|
if ((int)$io === 1) {
|
|
|
$query->andWhere('IFNULL(amount, 0) + IFNULL(giveAmount, 0) > 0');
|
|
|
} else {
|
|
|
- $query->andWhere([
|
|
|
- 'or',
|
|
|
- ['>', 'settleAmount', 0],
|
|
|
- ['>', 'clearAmount', 0],
|
|
|
- ]);
|
|
|
+ $query->andWhere(['isRefund' => 1]);
|
|
|
}
|
|
|
|
|
|
return self::getRechargePageList($query, 'addTime DESC,id DESC');
|
|
|
@@ -166,7 +171,7 @@ class RechargeClass extends BaseClass
|
|
|
}
|
|
|
|
|
|
//第三支付后流程 ssh 2021.4.27
|
|
|
- public static function thirdPay($payWay, $orderSn, $totalFee, $attach)
|
|
|
+ public static function thirdPay($payWay, $orderSn, $totalFee, $attach, $transactionId = '')
|
|
|
{
|
|
|
$recharge = RechargeClass::getByCondition(['orderSn' => $orderSn], true);
|
|
|
if (empty($recharge)) {
|
|
|
@@ -187,6 +192,8 @@ class RechargeClass extends BaseClass
|
|
|
'onlinePay' => 2,
|
|
|
'side' => 1,
|
|
|
];
|
|
|
+ $recharge->returnCode = $transactionId;
|
|
|
+ $recharge->save(false);
|
|
|
self::complete($recharge, $payWay, $params);
|
|
|
return $recharge;
|
|
|
}
|
|
|
@@ -601,6 +608,236 @@ class RechargeClass extends BaseClass
|
|
|
return $returnChange;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 花店后台:对已付款客户充值单退款。线上原路退,线下扣减客户余额;xhRecharge.isRefund 标记退款状态。
|
|
|
+ */
|
|
|
+ public static function refundPaidRecharge($rechargeId, $shop, $staff)
|
|
|
+ {
|
|
|
+ $rechargeId = intval($rechargeId);
|
|
|
+ if ($rechargeId <= 0) {
|
|
|
+ util::fail('参数错误');
|
|
|
+ }
|
|
|
+ $recharge = self::getLockById($rechargeId);
|
|
|
+ if (empty($recharge)) {
|
|
|
+ util::fail('没有找到充值记录');
|
|
|
+ }
|
|
|
+ if (intval($recharge->mainId ?? 0) !== intval($shop->mainId ?? 0) || intval($recharge->shopId ?? 0) !== intval($shop->id ?? 0)) {
|
|
|
+ util::fail('没有权限操作该充值记录');
|
|
|
+ }
|
|
|
+ if (intval($recharge->payStatus ?? 0) !== 1 || intval($recharge->status ?? 0) !== 1) {
|
|
|
+ util::fail('仅已付款的充值可退款');
|
|
|
+ }
|
|
|
+ if (self::isRechargeRefunded($recharge)) {
|
|
|
+ util::fail('该充值已退款');
|
|
|
+ }
|
|
|
+
|
|
|
+ $amount = bcadd((string)($recharge->amount ?? '0'), '0', 2);
|
|
|
+ if (bccomp($amount, '0', 2) <= 0) {
|
|
|
+ util::fail('充值金额有误');
|
|
|
+ }
|
|
|
+
|
|
|
+ $customId = intval($recharge->customId ?? 0);
|
|
|
+ $hdId = intval($recharge->hdId ?? 0);
|
|
|
+ $custom = CustomClass::getLockById($customId);
|
|
|
+ $hd = HdClass::getLockById($hdId);
|
|
|
+ if (empty($custom) || empty($hd)) {
|
|
|
+ util::fail('没有找到客户余额账户');
|
|
|
+ }
|
|
|
+
|
|
|
+ $isOnline = intval($recharge->onlinePay ?? 0) === 2;
|
|
|
+ $payWay = intval($recharge->payWay ?? -1);
|
|
|
+ $wxPay = intval(dict::getDict('payWay', 'wxPay'));
|
|
|
+ $aliPay = intval(dict::getDict('payWay', 'alipay'));
|
|
|
+ $cashPay = intval(dict::getDict('payWay', 'cash'));
|
|
|
+ $onlineMain = null;
|
|
|
+
|
|
|
+ if ($isOnline) {
|
|
|
+ if ($payWay !== $wxPay && $payWay !== $aliPay) {
|
|
|
+ util::fail('暂不支持该支付方式原路退款');
|
|
|
+ }
|
|
|
+ $returnCode = trim((string)($recharge->returnCode ?? ''));
|
|
|
+ if ($returnCode === '') {
|
|
|
+ util::fail('缺少支付流水号,无法原路退款');
|
|
|
+ }
|
|
|
+ $onlineMain = MainClass::getLockById($shop->mainId ?? 0);
|
|
|
+ if (empty($onlineMain)) {
|
|
|
+ util::fail('没有找到资产信息');
|
|
|
+ }
|
|
|
+ if (bccomp((string)($onlineMain->balance ?? '0'), $amount, 2) < 0) {
|
|
|
+ util::fail('门店余额不足,无法退款');
|
|
|
+ }
|
|
|
+ self::refundOnlineByLakala($recharge, $shop, $amount, $returnCode);
|
|
|
+ }
|
|
|
+
|
|
|
+ $giveAmount = bcadd((string)($recharge->giveAmount ?? '0'), '0', 2);
|
|
|
+ if (bccomp($giveAmount, '0', 2) < 0) {
|
|
|
+ $giveAmount = '0.00';
|
|
|
+ }
|
|
|
+ $currentGive = bcadd((string)($hd->balanceGive ?? '0'), '0', 2);
|
|
|
+ $deductGive = '0.00';
|
|
|
+ if (bccomp($giveAmount, '0', 2) === 1 && bccomp($currentGive, '0', 2) === 1) {
|
|
|
+ $deductGive = bccomp($currentGive, $giveAmount, 2) >= 0 ? $giveAmount : $currentGive;
|
|
|
+ }
|
|
|
+ $deductPay = bcadd($amount, bcsub($giveAmount, $deductGive, 2), 2);
|
|
|
+ $totalDeduct = bcadd($deductPay, $deductGive, 2);
|
|
|
+
|
|
|
+ $custom->balancePay = bcsub((string)($custom->balancePay ?? '0'), $deductPay, 2);
|
|
|
+ $hd->balancePay = bcsub((string)($hd->balancePay ?? '0'), $deductPay, 2);
|
|
|
+ if (bccomp($deductGive, '0', 2) === 1) {
|
|
|
+ $custom->balanceGive = bcsub((string)($custom->balanceGive ?? '0'), $deductGive, 2);
|
|
|
+ $hd->balanceGive = bcsub((string)($hd->balanceGive ?? '0'), $deductGive, 2);
|
|
|
+ }
|
|
|
+ $custom->balance = bcsub((string)($custom->balance ?? '0'), $totalDeduct, 2);
|
|
|
+ $hd->balance = bcsub((string)($hd->balance ?? '0'), $totalDeduct, 2);
|
|
|
+ $custom->save(false);
|
|
|
+ $hd->save(false);
|
|
|
+
|
|
|
+ if (floatval($custom->balance) != floatval($hd->balance) || floatval($custom->balancePay) != floatval($hd->balancePay) || floatval($custom->balanceGive) != floatval($hd->balanceGive)) {
|
|
|
+ util::fail('账户余额有问题,请联系管理员');
|
|
|
+ }
|
|
|
+
|
|
|
+ $staffId = intval($staff->id ?? 0);
|
|
|
+ $staffName = (string)($staff->name ?? '');
|
|
|
+ $capitalType = dict::getDict('capitalType', 'customRechargeRefund', 'id');
|
|
|
+ $event = '充值退款(操作人:' . $staffName . ')单号:' . ($recharge->orderSn ?? '');
|
|
|
+ $changeBase = [
|
|
|
+ 'hdId' => $hdId,
|
|
|
+ 'hdName' => $hd->name ?? ($recharge->hdName ?? ''),
|
|
|
+ 'customId' => $customId,
|
|
|
+ 'customName' => $custom->name ?? ($recharge->customName ?? ''),
|
|
|
+ 'relateId' => $rechargeId,
|
|
|
+ 'onlinePay' => $recharge->onlinePay ?? 1,
|
|
|
+ 'capitalType' => $capitalType,
|
|
|
+ 'side' => 0,
|
|
|
+ 'payWay' => $payWay,
|
|
|
+ 'event' => $event,
|
|
|
+ 'staffId' => $staffId,
|
|
|
+ 'staffName' => $staffName,
|
|
|
+ 'shopId' => $recharge->shopId ?? 0,
|
|
|
+ 'mainId' => $recharge->mainId ?? 0,
|
|
|
+ 'remark' => '',
|
|
|
+ ];
|
|
|
+
|
|
|
+ BalanceChangeClass::add(array_merge($changeBase, [
|
|
|
+ 'amount' => $totalDeduct,
|
|
|
+ 'balance' => $hd->balance,
|
|
|
+ 'io' => 0,
|
|
|
+ ]), true);
|
|
|
+
|
|
|
+ BalancePayChangeClass::add(array_merge($changeBase, [
|
|
|
+ 'amount' => $deductPay,
|
|
|
+ 'balance' => $hd->balancePay,
|
|
|
+ 'io' => 0,
|
|
|
+ ]), true);
|
|
|
+
|
|
|
+ if (bccomp($deductGive, '0', 2) === 1) {
|
|
|
+ BalanceGiveChangeClass::add(array_merge($changeBase, [
|
|
|
+ 'amount' => $deductGive,
|
|
|
+ 'balance' => $hd->balanceGive,
|
|
|
+ 'io' => 0,
|
|
|
+ ]), true);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($isOnline) {
|
|
|
+ $main = $onlineMain ?: MainClass::getLockById($shop->mainId ?? 0);
|
|
|
+ if (empty($main)) {
|
|
|
+ util::fail('没有找到资产信息');
|
|
|
+ }
|
|
|
+ ShopClass::customRechargeRefundReduceBalance($main, $shop, $recharge, dict::getDict('capitalType', 'xhRecharge', 'id'), $staffName);
|
|
|
+ } elseif ($payWay === $cashPay) {
|
|
|
+ self::cashRechargeRefundReduceMoney($recharge, $shop, $staffName, $amount);
|
|
|
+ }
|
|
|
+
|
|
|
+ self::markRechargeRefunded($recharge);
|
|
|
+ $recharge->balance = $hd->balance;
|
|
|
+ $recharge->save(false);
|
|
|
+
|
|
|
+ return $recharge;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected static function cashRechargeRefundReduceMoney($recharge, $shop, $staffName, $amount)
|
|
|
+ {
|
|
|
+ $main = MainClass::getLockById($shop->mainId ?? 0);
|
|
|
+ if (empty($main)) {
|
|
|
+ util::fail('没有找到现金账户');
|
|
|
+ }
|
|
|
+ if (bccomp((string)($main->money ?? '0'), $amount, 2) < 0) {
|
|
|
+ util::fail('现金不足' . floatval($amount) . '元');
|
|
|
+ }
|
|
|
+ $main->money = bcsub((string)$main->money, $amount, 2);
|
|
|
+ $main->save(false);
|
|
|
+ ShopMoneyClass::addData([
|
|
|
+ 'mainId' => $shop->mainId ?? 0,
|
|
|
+ 'sjId' => 0,
|
|
|
+ 'amount' => $amount,
|
|
|
+ 'balance' => $main->money,
|
|
|
+ 'io' => 0,
|
|
|
+ 'staffId' => $recharge->staffId ?? 0,
|
|
|
+ 'staffName' => $staffName,
|
|
|
+ 'customName' => $recharge->customName ?? '',
|
|
|
+ 'ptStyle' => dict::getDict('ptStyle', 'hd'),
|
|
|
+ 'capitalType' => dict::getDict('capitalType', 'xhRecharge', 'id'),
|
|
|
+ 'event' => ($recharge->customName ?? '客户') . '现金充值退款' . floatval($amount) . '元',
|
|
|
+ 'remark' => '操作人:' . $staffName,
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected static function refundOnlineByLakala($recharge, $shop, $amount, $returnCode)
|
|
|
+ {
|
|
|
+ $termNo = $shop->lklScanTermNo ?? '';
|
|
|
+ if (intval($recharge->payWay ?? 0) === intval(dict::getDict('payWay', 'alipay'))) {
|
|
|
+ $termNo = $shop->lklB2BTermNo ?? '';
|
|
|
+ }
|
|
|
+ if (empty($shop->lklSjNo) || empty($termNo)) {
|
|
|
+ util::fail('门店未配置拉卡拉商户信息');
|
|
|
+ }
|
|
|
+ $merchantPrivateKeyPath = Yii::getAlias('@vendor/lakala') . '/production/api_private_key.pem';
|
|
|
+ $lklCertificatePath = Yii::getAlias('@vendor/lakala') . '/production/lkl-apigw-v1.cer';
|
|
|
+ $laResource = new Lakala([
|
|
|
+ 'appid' => 'OP00002119',
|
|
|
+ 'serial_no' => '018b08cfddbd',
|
|
|
+ 'merchant_no' => $shop->lklSjNo,
|
|
|
+ 'term_no' => $termNo,
|
|
|
+ 'merchantPrivateKeyPath' => $merchantPrivateKeyPath,
|
|
|
+ 'lklCertificatePath' => $lklCertificatePath,
|
|
|
+ ]);
|
|
|
+ $response = $laResource->refund([
|
|
|
+ 'refundSn' => orderSn::getRechargeSn(),
|
|
|
+ 'orderSn' => $recharge->orderSn ?? '',
|
|
|
+ 'refundAmount' => bcmul($amount, 100),
|
|
|
+ 'refundReason' => '充值退款',
|
|
|
+ 'thirdNo' => $returnCode,
|
|
|
+ ]);
|
|
|
+ if (!isset($response['code']) || $response['code'] != 'BBS00000') {
|
|
|
+ util::fail('原路退款失败:' . ($response['msg'] ?? '退款失败'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected static function isRechargeRefunded($recharge)
|
|
|
+ {
|
|
|
+ if (empty($recharge)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (self::modelHasAttr($recharge, 'isRefund')) {
|
|
|
+ return intval($recharge->isRefund ?? 0) === 1;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected static function markRechargeRefunded($recharge)
|
|
|
+ {
|
|
|
+ if (empty($recharge) || !self::modelHasAttr($recharge, 'isRefund')) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ $recharge->isRefund = 1;
|
|
|
+ $recharge->save(false, ['isRefund']);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected static function modelHasAttr($model, $attr)
|
|
|
+ {
|
|
|
+ return is_object($model) && method_exists($model, 'hasAttribute') && $model->hasAttribute($attr);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 售后付款单是否已经充值过了 ssh 20250801
|
|
|
*/
|
|
|
@@ -613,7 +850,7 @@ class RechargeClass extends BaseClass
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public static function getStatProfile($mainId, $shopId, $params = [])
|
|
|
+ public static function getStatProfile($shopId, $params = [])
|
|
|
{
|
|
|
$searchTime = $params['searchTime'] ?? 'today';
|
|
|
$startTime = $params['startTime'] ?? '';
|
|
|
@@ -630,9 +867,9 @@ class RechargeClass extends BaseClass
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- $summary = self::getRechargeStatSummary($mainId, $shopId, $start, $end);
|
|
|
- $channelList = self::getRechargeStatChannelList($mainId, $shopId, $start, $end);
|
|
|
- $customerList = self::getRechargeStatCustomerList($mainId, $shopId, $start, $end);
|
|
|
+ $summary = self::getRechargeStatSummary($shopId, $start, $end);
|
|
|
+ $channelList = self::getRechargeStatChannelList($shopId, $start, $end);
|
|
|
+ $customerList = self::getRechargeStatCustomerList($shopId, $start, $end);
|
|
|
|
|
|
$data = [
|
|
|
'summary' => $summary,
|
|
|
@@ -645,12 +882,11 @@ class RechargeClass extends BaseClass
|
|
|
return $data;
|
|
|
}
|
|
|
|
|
|
- private static function getPaidQuery($mainId, $shopId, $start, $end)
|
|
|
+ private static function getPaidQuery($shopId, $start, $end)
|
|
|
{
|
|
|
$model = self::getActiveRecord();
|
|
|
return $model::find()
|
|
|
->where([
|
|
|
- 'mainId' => $mainId,
|
|
|
'shopId' => $shopId,
|
|
|
'payStatus' => 1,
|
|
|
'status' => 1,
|
|
|
@@ -658,15 +894,15 @@ class RechargeClass extends BaseClass
|
|
|
->andWhere(['between', 'addTime', $start, $end]);
|
|
|
}
|
|
|
|
|
|
- private static function getRechargeStatSummary($mainId, $shopId, $start, $end)
|
|
|
+ private static function getRechargeStatSummary($shopId, $start, $end)
|
|
|
{
|
|
|
- $row = self::getPaidQuery($mainId, $shopId, $start, $end)
|
|
|
+ $row = self::getPaidQuery($shopId, $start, $end)
|
|
|
->select([
|
|
|
'rechargeCount' => new Expression('SUM(CASE WHEN IFNULL(amount, 0) + IFNULL(giveAmount, 0) > 0 THEN 1 ELSE 0 END)'),
|
|
|
- 'reduceCount' => new Expression('SUM(CASE WHEN IFNULL(settleAmount, 0) > 0 THEN 1 ELSE 0 END)'),
|
|
|
+ 'reduceCount' => new Expression('SUM(CASE WHEN IFNULL(isRefund, 0) = 1 THEN 1 ELSE 0 END)'),
|
|
|
'realAmount' => new Expression('IFNULL(SUM(amount), 0)'),
|
|
|
'giveAmount' => new Expression('IFNULL(SUM(giveAmount), 0)'),
|
|
|
- 'reduceAmount' => new Expression('IFNULL(SUM(settleAmount), 0)'),
|
|
|
+ 'reduceAmount' => new Expression('IFNULL(SUM(CASE WHEN IFNULL(isRefund, 0) = 1 THEN amount ELSE 0 END), 0)'),
|
|
|
])
|
|
|
->asArray()
|
|
|
->one();
|
|
|
@@ -683,24 +919,25 @@ class RechargeClass extends BaseClass
|
|
|
];
|
|
|
}
|
|
|
|
|
|
- private static function getRechargeStatChannelList($mainId, $shopId, $start, $end)
|
|
|
+ private static function getRechargeStatChannelList($shopId, $start, $end)
|
|
|
{
|
|
|
- $rows = self::getPaidQuery($mainId, $shopId, $start, $end)
|
|
|
+ $rows = self::getPaidQuery($shopId, $start, $end)
|
|
|
->select([
|
|
|
- 'channelKey' => new Expression("IF(onlinePay = 2, 'system', CONCAT('pay_', payWay))"),
|
|
|
+ 'channelKey' => new Expression("IF(onlinePay = 2, CONCAT('online_', payWay), CONCAT('pay_', payWay))"),
|
|
|
'rechargeCount' => new Expression('SUM(CASE WHEN IFNULL(amount, 0) + IFNULL(giveAmount, 0) > 0 THEN 1 ELSE 0 END)'),
|
|
|
- 'reduceCount' => new Expression('SUM(CASE WHEN IFNULL(settleAmount, 0) > 0 THEN 1 ELSE 0 END)'),
|
|
|
+ 'reduceCount' => new Expression('SUM(CASE WHEN IFNULL(isRefund, 0) = 1 THEN 1 ELSE 0 END)'),
|
|
|
'realAmount' => new Expression('IFNULL(SUM(amount), 0)'),
|
|
|
'giveAmount' => new Expression('IFNULL(SUM(giveAmount), 0)'),
|
|
|
- 'reduceAmount' => new Expression('IFNULL(SUM(settleAmount), 0)'),
|
|
|
+ 'reduceAmount' => new Expression('IFNULL(SUM(CASE WHEN IFNULL(isRefund, 0) = 1 THEN amount ELSE 0 END), 0)'),
|
|
|
])
|
|
|
- ->groupBy(new Expression("IF(onlinePay = 2, 'system', CONCAT('pay_', payWay))"))
|
|
|
+ ->groupBy(new Expression("IF(onlinePay = 2, CONCAT('online_', payWay), CONCAT('pay_', payWay))"))
|
|
|
->asArray()
|
|
|
->all();
|
|
|
|
|
|
$payWayName = dict::getDict('payWayName');
|
|
|
$defaultList = [
|
|
|
- 'system' => '系统',
|
|
|
+ 'online_0' => '线上微信',
|
|
|
+ 'online_1' => '线上支付宝',
|
|
|
'pay_0' => '线下微信',
|
|
|
'pay_1' => '线下支付宝',
|
|
|
'pay_4' => '现金',
|
|
|
@@ -727,17 +964,17 @@ class RechargeClass extends BaseClass
|
|
|
return $list;
|
|
|
}
|
|
|
|
|
|
- private static function getRechargeStatCustomerList($mainId, $shopId, $start, $end)
|
|
|
+ private static function getRechargeStatCustomerList($shopId, $start, $end)
|
|
|
{
|
|
|
- $rows = self::getPaidQuery($mainId, $shopId, $start, $end)
|
|
|
+ $rows = self::getPaidQuery($shopId, $start, $end)
|
|
|
->select([
|
|
|
'customId',
|
|
|
'customName',
|
|
|
'rechargeCount' => new Expression('SUM(CASE WHEN IFNULL(amount, 0) + IFNULL(giveAmount, 0) > 0 THEN 1 ELSE 0 END)'),
|
|
|
- 'reduceCount' => new Expression('SUM(CASE WHEN IFNULL(settleAmount, 0) > 0 THEN 1 ELSE 0 END)'),
|
|
|
+ 'reduceCount' => new Expression('SUM(CASE WHEN IFNULL(isRefund, 0) = 1 THEN 1 ELSE 0 END)'),
|
|
|
'realAmount' => new Expression('IFNULL(SUM(amount), 0)'),
|
|
|
'giveAmount' => new Expression('IFNULL(SUM(giveAmount), 0)'),
|
|
|
- 'reduceAmount' => new Expression('IFNULL(SUM(settleAmount), 0)'),
|
|
|
+ 'reduceAmount' => new Expression('IFNULL(SUM(CASE WHEN IFNULL(isRefund, 0) = 1 THEN amount ELSE 0 END), 0)'),
|
|
|
])
|
|
|
->groupBy(['customId', 'customName'])
|
|
|
->orderBy(new Expression('IFNULL(SUM(amount), 0) + IFNULL(SUM(giveAmount), 0) DESC'))
|