Преглед изворни кода

Merge branch 'fw' into dev

shish пре 5 часа
родитељ
комит
3ed47cdba6

+ 2 - 0
app-ghs/controllers/CustomController.php

@@ -145,10 +145,12 @@ class CustomController extends BaseController
         $envVersion = miniUtil::normalizeMiniEnvVersion($get['env_version'] ?? 'release');
         $miniCode = miniUtil::generateUnlimitedMiniCode($merchant, $page, $scene, $ptStyle, $envVersion);
         $imageUrl = imgUtil::groupImg($miniCode);
+        // 顺带回客户当前余额,供冲销凭证海报补全「最新余额」(避免前端 query 丢参)
         util::success([
             'imgUrl' => $imageUrl,
             'ghsId' => $ghsId,
             'salt' => $salt,
+            'balance' => bcadd((string)($custom->balance ?? '0'), '0', 2),
         ]);
     }
 

+ 21 - 0
biz-ghs/forward/classes/ForwardClass.php

@@ -41,6 +41,27 @@ class ForwardClass extends BaseClass
         return bcadd($row['total'] ?? '0', '0', 2);
     }
 
+    /**
+     * 拉取时段内成功冲销凭证及关联原单支付字段,供渠道收入按原入账渠道对冲。
+     * 为何联表:挂账单冲销应扣「挂账已结」,不能一律扣「系统收款」。
+     * @return array 每行含 amount/payWay/orderId/debtPrice/remainDebtPrice/onlinePay/orderPayWay
+     */
+    public static function listForChannelIncomeDeduct($mainId, $startTime, $endTime)
+    {
+        $sql = "SELECT f.amount, f.payWay, f.orderId, f.fundType,
+                o.debtPrice, o.remainDebtPrice, o.onlinePay, o.payWay AS orderPayWay
+            FROM xhGhsForward f
+            LEFT JOIN xhGhsOrder o ON o.id = f.orderId
+            WHERE f.mainId=:mainId AND f.status=:status AND f.addTime BETWEEN :start AND :end";
+        $rows = Yii::$app->db->createCommand($sql, [
+            ':mainId' => $mainId,
+            ':status' => self::STATUS_SUCCESS,
+            ':start' => $startTime,
+            ':end' => $endTime,
+        ])->queryAll();
+        return $rows ?: [];
+    }
+
     /**
      * 按客户汇总成功冲销金额(customId => amount)
      */

+ 5 - 1
biz-ghs/forward/services/ForwardService.php

@@ -262,6 +262,7 @@ class ForwardService extends BaseService
 
         // 资金分支(原单 actPrice/tkPrice 不动)
         $thirdRefundNo = '';
+        $customBalance = bcadd((string)($custom->balance ?? '0'), '0', 2);
         if ($fundType === ForwardClass::FUND_ORIGINAL) {
             if (empty($cg)) {
                 util::fail('无原采购单,无法原路退回');
@@ -270,7 +271,8 @@ class ForwardService extends BaseService
             $ghsForward->thirdRefundNo = $thirdRefundNo;
             $ghsForward->save(false, ['thirdRefundNo']);
         } elseif ($fundType === ForwardClass::FUND_BALANCE) {
-            CustomClass::forwardReturnBalance($custom, $ghsForward, $amount);
+            // 返充后最新余额,供前端退款凭证海报展示
+            $customBalance = CustomClass::forwardReturnBalance($custom, $ghsForward, $amount);
         }
         // FUND_NONE:仅记账,不动作
 
@@ -338,6 +340,8 @@ class ForwardService extends BaseService
             'fundType' => $fundType,
             'amount' => $amount,
             'customId' => $customId,
+            'customName' => $custom->name ?? '',
+            'customBalance' => $customBalance,
             'thirdRefundNo' => $thirdRefundNo,
         ];
     }

+ 81 - 10
biz-ghs/stat/classes/StatKdClass.php

@@ -415,19 +415,90 @@ class StatKdClass extends BaseClass
                 $staffAmountList[$staffId] = ['num' => 1, 'amount' => $currentAmount, 'staffName' => $staffName];
             }
         }
-        // 方案A:渠道收入总计扣减成功冲销金额(笔数不因冲销增减)
-        $fwdAmount = ForwardClass::sumAmountByMainAndTime($mainId, $currentStartTime, $currentEndTime);
-        if (bccomp((string)$fwdAmount, '0', 2) > 0) {
-            $incomeList['system']['amount'] = bcsub((string)$incomeList['system']['amount'], (string)$fwdAmount, 2);
-            $incomeList['system']['category']['pf']['amount'] = bcsub(
-                (string)$incomeList['system']['category']['pf']['amount'],
-                (string)$fwdAmount,
-                2
-            );
-        }
+        // 方案A:按原单入账渠道扣减成功冲销金额(只减金额不减笔数;挂账已结扣 debtClear)
+        self::deductForwardFromChannelIncome($incomeList, $mainId, $currentStartTime, $currentEndTime);
 
         return ['incomeList' => $incomeList, 'staffAmountList' => $staffAmountList, 'payCodeIncome' => $payCodeIncome, 'lsAfterSale' => $lsAfterSale];
 
     }
 
+    /**
+     * 渠道收入对冲冲销:按原销售单当时计入的渠道扣金额。
+     * 挂账已结 → debtClear;挂账未结 → debt;在线付 → system;线下按 payWay。
+     * 自由冲销无原单时按凭证 payWay(多为余额)扣,避免误进系统收款。
+     */
+    protected static function deductForwardFromChannelIncome(&$incomeList, $mainId, $startTime, $endTime)
+    {
+        $rows = ForwardClass::listForChannelIncomeDeduct($mainId, $startTime, $endTime);
+        if (empty($rows)) {
+            return;
+        }
+        foreach ($rows as $row) {
+            $amount = bcadd((string)($row['amount'] ?? '0'), '0', 2);
+            if (bccomp($amount, '0', 2) <= 0) {
+                continue;
+            }
+            $channel = self::resolveForwardIncomeChannel($row);
+            if (empty($channel) || !isset($incomeList[$channel])) {
+                $channel = 'other';
+            }
+            $incomeList[$channel]['amount'] = bcsub((string)$incomeList[$channel]['amount'], $amount, 2);
+            // 批发冲销明细落在 pf;无 category 的渠道(如美团)只扣总额
+            if (isset($incomeList[$channel]['category']['pf'])) {
+                $incomeList[$channel]['category']['pf']['amount'] = bcsub(
+                    (string)$incomeList[$channel]['category']['pf']['amount'],
+                    $amount,
+                    2
+                );
+            }
+        }
+    }
+
+    /**
+     * 根据冲销凭证 + 关联原单字段,映射到 kdIncome 渠道 key(与批发开单入账分支一致)
+     */
+    protected static function resolveForwardIncomeChannel($row)
+    {
+        $debtPrice = bcadd((string)($row['debtPrice'] ?? '0'), '0', 2);
+        $remainDebt = bcadd((string)($row['remainDebtPrice'] ?? '0'), '0', 2);
+        $orderId = intval($row['orderId'] ?? 0);
+        $payWay = intval($row['orderPayWay'] ?? ($row['payWay'] ?? 0));
+        if ($orderId <= 0) {
+            $payWay = intval($row['payWay'] ?? 0);
+        }
+        $onlinePay = intval($row['onlinePay'] ?? dict::getDict('onlinePay', 'not'));
+
+        // 有挂账标记的原单:已结清进「挂账已结」,未结进「挂账未结」
+        if ($orderId > 0 && bccomp($debtPrice, '0', 2) > 0) {
+            if (bccomp($remainDebt, '0', 2) > 0) {
+                return 'debt';
+            }
+            return 'debtClear';
+        }
+
+        if ($onlinePay == dict::getDict('onlinePay', 'yes')) {
+            return 'system';
+        }
+
+        switch ($payWay) {
+            case dict::getDict('payWay', 'wxPay'):
+                return 'kfWx';
+            case dict::getDict('payWay', 'alipay'):
+                return 'aliPay';
+            case dict::getDict('payWay', 'cash'):
+                return 'cash';
+            case dict::getDict('payWay', 'balancePay'):
+                return 'balancePay';
+            case dict::getDict('payWay', 'bankCard'):
+                return 'bankCard';
+            case dict::getDict('payWay', 'debtPay'):
+                // 凭证记欠款但原单无 debtPrice 时,按已结挂账对冲(冲销前提多为已结清)
+                return 'debtClear';
+            case dict::getDict('payWay', 'unknown'):
+                return 'other';
+            default:
+                return 'other';
+        }
+    }
+
 }