فهرست منبع

隔天售后与统计

shish 1 روز پیش
والد
کامیت
288b87e6ab

+ 98 - 6
app-ghs/controllers/OrderController.php

@@ -9,6 +9,7 @@ use bizGhs\custom\classes\CustomDebtChangeClass;
 use bizGhs\express\classes\GhsDeliveryOrderClass;
 use bizGhs\express\services\DadaExpressServices;
 use bizGhs\ghs\classes\GhsClass;
+use bizGhs\order\classes\NextDayRefundClass;
 use bizGhs\order\classes\OrderItemClass;
 use bizGhs\order\classes\RefundOrderClass;
 use bizHd\purchase\classes\PurchaseClass;
@@ -2973,7 +2974,10 @@ class OrderController extends BaseController
         }
     }
 
-    //应收款统计 ssh 20240528
+    /**
+     * 应收统计:按支付日汇总。
+     * originAmount=未扣隔天;nextDayAmount=隔天售后;amount=已扣隔天(净额)。
+     */
     public function actionAccountList()
     {
         $get = Yii::$app->request->get();
@@ -3000,7 +3004,9 @@ class OrderController extends BaseController
         $where['payTime'] = ['between', [$currentStartTime, $currentEndTime]];
         $orderList = OrderClass::getAllByCondition($where, null, '*');
         $list = [];
+        $totalOriginAmount = 0;
         $totalAmount = 0;
+        $nextDayDeduct = '0.00';
         if (!empty($orderList)) {
             foreach ($orderList as $orderInfo) {
                 $actPrice = $orderInfo['actPrice'] ?? 0;
@@ -3014,16 +3020,54 @@ class OrderController extends BaseController
                     continue;
                 }
                 if (isset($list[$customId])) {
+                    $list[$customId]['originAmount'] = bcadd($list[$customId]['originAmount'], $actPrice, 2);
                     $list[$customId]['amount'] = bcadd($list[$customId]['amount'], $actPrice, 2);
                     $list[$customId]['num'] = bcadd($list[$customId]['num'], 1);
                 } else {
                     $name = $customList[$customId] && $customList[$customId]['name'] ? $customList[$customId]['name'] : '未命名';
-                    $list[$customId] = ['id' => $customId, 'name' => $name, 'amount' => $actPrice, 'num' => 1];
+                    $list[$customId] = [
+                        'id' => $customId,
+                        'name' => $name,
+                        'originAmount' => $actPrice,
+                        'amount' => $actPrice,
+                        'num' => 1,
+                        'nextDayAmount' => '0.00',
+                    ];
                 }
+                $totalOriginAmount = bcadd($totalOriginAmount, $actPrice, 2);
                 $totalAmount = bcadd($totalAmount, $actPrice, 2);
             }
-            $list = array_values($list);
         }
+
+        // 隔天售后:只扣 amount,originAmount 保持未扣口径
+        $fwdMap = NextDayRefundClass::sumAmountGroupByCustom($mainId, $currentStartTime, $currentEndTime);
+        foreach ($fwdMap as $cid => $amt) {
+            if (bccomp((string)$amt, '0', 2) == 0) {
+                continue;
+            }
+            if (!isset($list[$cid])) {
+                $list[$cid] = [
+                    'id' => $cid,
+                    'name' => $customList[$cid]['name'] ?? '未命名',
+                    'originAmount' => '0.00',
+                    'amount' => '0.00',
+                    'num' => 0,
+                    'nextDayAmount' => '0.00',
+                ];
+            }
+            if (!isset($list[$cid]['originAmount'])) {
+                $list[$cid]['originAmount'] = (string)($list[$cid]['amount'] ?? '0');
+            }
+            if (!isset($list[$cid]['nextDayAmount'])) {
+                $list[$cid]['nextDayAmount'] = '0.00';
+            }
+            $list[$cid]['amount'] = bcsub((string)$list[$cid]['amount'], (string)$amt, 2);
+            $list[$cid]['nextDayAmount'] = bcadd((string)$list[$cid]['nextDayAmount'], (string)$amt, 2);
+            $totalAmount = bcsub((string)$totalAmount, (string)$amt, 2);
+            $nextDayDeduct = bcadd($nextDayDeduct, (string)$amt, 2);
+        }
+        $list = array_values($list);
+
         if ($export == 1) {
             if (empty($list)) {
                 util::fail('没有数据需要导出');
@@ -3033,7 +3077,12 @@ class OrderController extends BaseController
             OrderClass::exportAccountList($list, $mainId);
             util::stop();
         }
-        util::success(['list' => $list, 'totalAmount' => $totalAmount]);
+        util::success([
+            'list' => $list,
+            'totalOriginAmount' => $totalOriginAmount,
+            'totalAmount' => $totalAmount,
+            'nextDayDeduct' => floatval($nextDayDeduct),
+        ]);
     }
 
 
@@ -3075,7 +3124,10 @@ class OrderController extends BaseController
     }
 
 
-    //客户业绩,有多个地方,需要同步,搜索关键词 customYj ssh 20240628
+    /**
+     * 客户业绩(PC):按支付日汇总开单;隔天售后按通过日扣实际金额并计入退款。
+     * 与小程序 statCustomCg 同步,搜索关键词 customYj。
+     */
     public function actionYj()
     {
         $get = Yii::$app->request->get();
@@ -3237,6 +3289,7 @@ class OrderController extends BaseController
                     ];
                 }
             }
+            // 有开单时补全无单客户行,便于与隔天负金额行一并展示
             foreach ($customList as $key => $custom) {
                 $customId = $custom['id'] ?? 0;
                 if (isset($list[$customId]) == false) {
@@ -3247,6 +3300,7 @@ class OrderController extends BaseController
                         'actPrice' => 0,
                         'num' => 0,
                         'carton' => 0,
+                        'cartonNum' => 0,
                         'pack' => 0,
                         'freight' => 0,
                         'tkPrice' => 0,
@@ -3254,8 +3308,45 @@ class OrderController extends BaseController
                     ];
                 }
             }
-            $list = array_values($list);
         }
+
+        // 隔天售后:按通过日扣实际金额、计入退款;无当日开单也建负行;订单笔数不减
+        $fwdMap = NextDayRefundClass::sumAmountGroupByCustom($mainId, $currentStartTime, $currentEndTime);
+        $nextDayDeduct = '0.00';
+        foreach ($fwdMap as $cid => $amt) {
+            if (bccomp((string)$amt, '0', 2) == 0) {
+                continue;
+            }
+            if (!isset($list[$cid])) {
+                $list[$cid] = [
+                    'id' => $cid,
+                    'name' => $customList[$cid]['name'] ?? '未命名',
+                    'mobile' => $customList[$cid]['mobile'] ?? '0',
+                    'actPrice' => 0,
+                    'num' => 0,
+                    'carton' => 0,
+                    'cartonNum' => 0,
+                    'pack' => 0,
+                    'freight' => 0,
+                    'tkPrice' => 0,
+                    'orderPrice' => 0,
+                ];
+            }
+            $list[$cid]['actPrice'] = bcsub((string)$list[$cid]['actPrice'], (string)$amt, 2);
+            // 退款列含隔天通过金额,便于与实际金额对照
+            $list[$cid]['tkPrice'] = bcadd((string)$list[$cid]['tkPrice'], (string)$amt, 2);
+            $totalActPrice = bcsub((string)$totalActPrice, (string)$amt, 2);
+            $totalTkPrice = bcadd((string)$totalTkPrice, (string)$amt, 2);
+            $nextDayDeduct = bcadd($nextDayDeduct, (string)$amt, 2);
+        }
+        // 隔天仅退款并入「仅退款」合计(当天仅退款已在开单循环统计)
+        $totalOnlyTkPrice = bcadd(
+            (string)$totalOnlyTkPrice,
+            NextDayRefundClass::sumMoneyOnlyAmountByMainAndTime($mainId, $currentStartTime, $currentEndTime),
+            2
+        );
+
+        $list = array_values($list);
         if ($export == 1) {
             if (empty($list)) {
                 util::fail('没有数据需要导出');
@@ -3277,6 +3368,7 @@ class OrderController extends BaseController
             'totalTkPrice' => $totalTkPrice,
             //增加项
             'totalOnlyTkPrice' => $totalOnlyTkPrice,
+            'nextDayDeduct' => floatval($nextDayDeduct),
         ]);
     }
 

+ 53 - 4
app-ghs/controllers/PurchaseOrderController.php

@@ -2,6 +2,7 @@
 
 namespace ghs\controllers;
 
+use bizGhs\cg\classes\CgPurchaseNextDayClass;
 use biz\ghs\classes\GhsClass;
 use biz\sj\classes\SjClass;
 use bizGhs\book\classes\BookItemClass;
@@ -939,7 +940,10 @@ class PurchaseOrderController extends BaseController
         util::complete('修改成功');
     }
 
-    //应付款统计 ssh 20240528
+    /**
+     * 应付统计:按入库日汇总。
+     * originAmount=未扣隔天;nextDayAmount=隔天售后;amount=已扣隔天(净额)。
+     */
     public function actionDueList()
     {
         $get = Yii::$app->request->get();
@@ -965,22 +969,62 @@ class PurchaseOrderController extends BaseController
         $cgWhere['entryTime'] = ['between', [$currentStartTime, $currentEndTime]];
         $cgList = PurchaseOrderClass::getAllByCondition($cgWhere, null, '*');
         $list = [];
+        $totalOriginAmount = 0;
         $totalAmount = 0;
+        $nextDayDeduct = '0.00';
         if (!empty($cgList)) {
             foreach ($cgList as $cgInfo) {
                 $actPrice = $cgInfo['actPrice'] ?? 0;
                 $ghsId = $cgInfo['ghsId'] ?? 0;
                 if (isset($list[$ghsId])) {
+                    $list[$ghsId]['originAmount'] = bcadd($list[$ghsId]['originAmount'], $actPrice, 2);
                     $list[$ghsId]['amount'] = bcadd($list[$ghsId]['amount'], $actPrice, 2);
                     $list[$ghsId]['num'] = bcadd($list[$ghsId]['num'], 1);
                 } else {
                     $name = $ghsList[$ghsId] && $ghsList[$ghsId]['name'] ? $ghsList[$ghsId]['name'] : '未命名';
-                    $list[$ghsId] = ['id' => $ghsId, 'name' => $name, 'amount' => $actPrice, 'num' => 1];
+                    $list[$ghsId] = [
+                        'id' => $ghsId,
+                        'name' => $name,
+                        'originAmount' => $actPrice,
+                        'amount' => $actPrice,
+                        'num' => 1,
+                        'nextDayAmount' => '0.00',
+                    ];
                 }
+                $totalOriginAmount = bcadd($totalOriginAmount, $actPrice, 2);
                 $totalAmount = bcadd($totalAmount, $actPrice, 2);
             }
-            $list = array_values($list);
         }
+
+        // 隔天售后:只扣 amount,originAmount 保持未扣口径
+        $nextMap = CgPurchaseNextDayClass::sumAmountGroupByGhs($mainId, $currentStartTime, $currentEndTime);
+        foreach ($nextMap as $ghsId => $amt) {
+            if (bccomp((string)$amt, '0', 2) <= 0) {
+                continue;
+            }
+            if (!isset($list[$ghsId])) {
+                $list[$ghsId] = [
+                    'id' => $ghsId,
+                    'name' => $ghsList[$ghsId]['name'] ?? '未命名',
+                    'originAmount' => '0.00',
+                    'amount' => '0.00',
+                    'num' => 0,
+                    'nextDayAmount' => '0.00',
+                ];
+            }
+            if (!isset($list[$ghsId]['originAmount'])) {
+                $list[$ghsId]['originAmount'] = (string)($list[$ghsId]['amount'] ?? '0');
+            }
+            if (!isset($list[$ghsId]['nextDayAmount'])) {
+                $list[$ghsId]['nextDayAmount'] = '0.00';
+            }
+            $list[$ghsId]['amount'] = bcsub((string)$list[$ghsId]['amount'], (string)$amt, 2);
+            $list[$ghsId]['nextDayAmount'] = bcadd((string)$list[$ghsId]['nextDayAmount'], (string)$amt, 2);
+            $totalAmount = bcsub((string)$totalAmount, (string)$amt, 2);
+            $nextDayDeduct = bcadd($nextDayDeduct, (string)$amt, 2);
+        }
+        $list = array_values($list);
+
         if ($export == 1) {
             if (empty($list)) {
                 util::fail('没有数据需要导出');
@@ -990,7 +1034,12 @@ class PurchaseOrderController extends BaseController
             PurchaseOrderClass::exportDueList($list, $mainId);
             util::stop();
         }
-        util::success(['list' => $list, 'totalAmount' => $totalAmount]);
+        util::success([
+            'list' => $list,
+            'totalOriginAmount' => $totalOriginAmount,
+            'totalAmount' => $totalAmount,
+            'nextDayDeduct' => floatval($nextDayDeduct),
+        ]);
     }
 
     //修改入库时间 ssh 20240511

+ 6 - 0
app-ghs/controllers/StatCgGhsController.php

@@ -172,6 +172,12 @@ class StatCgGhsController extends BaseController
             $totalActPrice = bcsub((string)$totalActPrice, (string)$amt, 2);
             $totalTkPrice = bcadd((string)$totalTkPrice, (string)$amt, 2);
         }
+        // 隔天仅退款并入「仅退款」合计(与小程序供货业绩扣减口径一致)
+        $totalOnlyTkPrice = bcadd(
+            (string)$totalOnlyTkPrice,
+            CgPurchaseNextDayClass::sumMoneyOnlyAmountByMainAndTime($mainId, $currentStartTime, $currentEndTime),
+            2
+        );
 
         // 有入库单时补齐本主账号下全部供货商行(与旧逻辑一致)
         if (!empty($orderList)) {

+ 12 - 4
app-ghs/controllers/StatItemController.php

@@ -147,6 +147,7 @@ class StatItemController extends BaseController
         }
 
         // 通过日:退货扣数量+金额;仅退款只扣金额;无当日销量的花材也建负行
+        $nextDayDeduct = '0.00';
         $deductMaps = [
             NextDayRefundClass::sumItemByProduct($this->mainId, $currentStartTime, $currentEndTime),
             NextDayRefundClass::sumMoneyOnlyAmountByProduct($this->mainId, $currentStartTime, $currentEndTime),
@@ -177,14 +178,15 @@ class StatItemController extends BaseController
                 $totalNum = bcsub((string)$totalNum, $subNum, 2);
                 $totalAmount = bcsub((string)$totalAmount, $subAmt, 2);
                 $totalMl = bcsub((string)$totalMl, $subAmt, 2);
+                $nextDayDeduct = bcadd($nextDayDeduct, $subAmt, 2);
             }
         }
 
-        //增加毛利率
+        //增加毛利率(金额为负时不计算毛利率,避免除零/误导)
         foreach ($stat as $key => $val) {
             $profit = $val['gross'] ?? 0;
             $price = $val['amount'] ?? 0;
-            if ($price > 0) {
+            if (bccomp((string)$price, '0', 2) > 0) {
                 $mll = bcdiv($profit, $price, 3);
                 $mll = bcmul($mll, 100);
                 $mll = round($mll, 1);
@@ -203,7 +205,7 @@ class StatItemController extends BaseController
         if ($sort == 'mll') {
             $rank = 'mll';
         }
-        $stat = arrayUtil::arraySort($stat, $rank);
+        $stat = array_values(arrayUtil::arraySort($stat, $rank));
 
         $export = $get['export'] ?? 0;
         if ($export == 1) {
@@ -211,7 +213,13 @@ class StatItemController extends BaseController
             StatSaleClass::exportItemSale($stat, $mainId);
         }
 
-        util::success(['list' => $stat, 'totalAmount' => floatval($totalAmount), 'totalNum' => floatval($totalNum), 'totalMl' => $totalMl,]);
+        util::success([
+            'list' => $stat,
+            'totalAmount' => floatval($totalAmount),
+            'totalNum' => floatval($totalNum),
+            'totalMl' => floatval($totalMl),
+            'nextDayDeduct' => floatval($nextDayDeduct),
+        ]);
 
     }
 

+ 19 - 20
biz-ghs/order/classes/OrderClass.php

@@ -2895,36 +2895,35 @@ XL;
 
         $objPHPExcel->getActiveSheet()->setCellValue('A1', 'ID');
         $objPHPExcel->getActiveSheet()->setCellValue('B1', '名称');
-        $objPHPExcel->getActiveSheet()->setCellValue('C1', '金额');
-        $objPHPExcel->getActiveSheet()->setCellValue('D1', '订单数');
+        $objPHPExcel->getActiveSheet()->setCellValue('C1', '未扣隔天金额');
+        $objPHPExcel->getActiveSheet()->setCellValue('D1', '隔天售后金额');
+        $objPHPExcel->getActiveSheet()->setCellValue('E1', '已扣隔天金额');
+        $objPHPExcel->getActiveSheet()->setCellValue('F1', '订单数');
 
         //设置宽度
         $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(25);
-        $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(20);
-        $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(20);
+        $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(18);
+        $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(18);
+        $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(18);
+        $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(15);
         //加粗
-        $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setSize(9)->setBold(true);
-        $objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setSize(9)->setBold(true);
-        $objPHPExcel->getActiveSheet()->getStyle('C1')->getFont()->setSize(9)->setBold(true);
-        $objPHPExcel->getActiveSheet()->getStyle('D1')->getFont()->setSize(9)->setBold(true);
-
-        $objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
-        $objPHPExcel->getActiveSheet()->getStyle('B1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
-        $objPHPExcel->getActiveSheet()->getStyle('C1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
-        $objPHPExcel->getActiveSheet()->getStyle('D1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
+        foreach (['A1', 'B1', 'C1', 'D1', 'E1', 'F1'] as $cell) {
+            $objPHPExcel->getActiveSheet()->getStyle($cell)->getFont()->setSize(9)->setBold(true);
+            $objPHPExcel->getActiveSheet()->getStyle($cell)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
+        }
 
         $baseRow = 2;
         foreach ($list as $key => $custom) {
             $i = $baseRow + $key;
             $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, $custom['id']);
             $objPHPExcel->getActiveSheet()->setCellValue('B' . $i, $custom['name']);
-            $objPHPExcel->getActiveSheet()->setCellValue('C' . $i, $custom['amount']);
-            $objPHPExcel->getActiveSheet()->setCellValue('D' . $i, $custom['num']);
-            //居左
-            $objPHPExcel->getActiveSheet()->getStyle('A' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
-            $objPHPExcel->getActiveSheet()->getStyle('B' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
-            $objPHPExcel->getActiveSheet()->getStyle('C' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
-            $objPHPExcel->getActiveSheet()->getStyle('D' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
+            $objPHPExcel->getActiveSheet()->setCellValue('C' . $i, $custom['originAmount'] ?? $custom['amount']);
+            $objPHPExcel->getActiveSheet()->setCellValue('D' . $i, $custom['nextDayAmount'] ?? 0);
+            $objPHPExcel->getActiveSheet()->setCellValue('E' . $i, $custom['amount']);
+            $objPHPExcel->getActiveSheet()->setCellValue('F' . $i, $custom['num']);
+            foreach (['A', 'B', 'C', 'D', 'E', 'F'] as $col) {
+                $objPHPExcel->getActiveSheet()->getStyle($col . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
+            }
         }
         $fileName = '应收统计-' . date("m-d");
         $objPHPExcel->getActiveSheet()->setTitle($fileName);

+ 19 - 14
biz-ghs/order/classes/PurchaseOrderClass.php

@@ -1919,30 +1919,35 @@ class PurchaseOrderClass extends BaseClass
 
         $objPHPExcel->getActiveSheet()->setCellValue('A1', 'ID');
         $objPHPExcel->getActiveSheet()->setCellValue('B1', '名称');
-        $objPHPExcel->getActiveSheet()->setCellValue('C1', '金额');
+        $objPHPExcel->getActiveSheet()->setCellValue('C1', '未扣隔天金额');
+        $objPHPExcel->getActiveSheet()->setCellValue('D1', '隔天售后金额');
+        $objPHPExcel->getActiveSheet()->setCellValue('E1', '已扣隔天金额');
+        $objPHPExcel->getActiveSheet()->setCellValue('F1', '订单数');
 
         //设置宽度
         $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(25);
-        $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(20);
+        $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(18);
+        $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(18);
+        $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(18);
+        $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(15);
         //加粗
-        $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setSize(9)->setBold(true);
-        $objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setSize(9)->setBold(true);
-        $objPHPExcel->getActiveSheet()->getStyle('C1')->getFont()->setSize(9)->setBold(true);
-
-        $objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
-        $objPHPExcel->getActiveSheet()->getStyle('B1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
-        $objPHPExcel->getActiveSheet()->getStyle('C1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
+        foreach (['A1', 'B1', 'C1', 'D1', 'E1', 'F1'] as $cell) {
+            $objPHPExcel->getActiveSheet()->getStyle($cell)->getFont()->setSize(9)->setBold(true);
+            $objPHPExcel->getActiveSheet()->getStyle($cell)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
+        }
 
         $baseRow = 2;
         foreach ($list as $key => $custom) {
             $i = $baseRow + $key;
             $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, $custom['id']);
             $objPHPExcel->getActiveSheet()->setCellValue('B' . $i, $custom['name']);
-            $objPHPExcel->getActiveSheet()->setCellValue('C' . $i, $custom['amount']);
-            //居左
-            $objPHPExcel->getActiveSheet()->getStyle('A' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
-            $objPHPExcel->getActiveSheet()->getStyle('B' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
-            $objPHPExcel->getActiveSheet()->getStyle('C' . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
+            $objPHPExcel->getActiveSheet()->setCellValue('C' . $i, $custom['originAmount'] ?? $custom['amount']);
+            $objPHPExcel->getActiveSheet()->setCellValue('D' . $i, $custom['nextDayAmount'] ?? 0);
+            $objPHPExcel->getActiveSheet()->setCellValue('E' . $i, $custom['amount']);
+            $objPHPExcel->getActiveSheet()->setCellValue('F' . $i, $custom['num'] ?? 0);
+            foreach (['A', 'B', 'C', 'D', 'E', 'F'] as $col) {
+                $objPHPExcel->getActiveSheet()->getStyle($col . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
+            }
         }
         $fileName = '应付统计-' . date("m-d");
         $objPHPExcel->getActiveSheet()->setTitle($fileName);

+ 87 - 3
biz-ghs/stat/classes/StatSaleClass.php

@@ -207,6 +207,8 @@ class StatSaleClass extends BaseClass
         $fwdMap = NextDayRefundClass::sumAmountGroupByCustom($mainId, $currentStartTime, $currentEndTime);
         $qtyMap = NextDayRefundClass::sumItemQtyByCustom($mainId, $currentStartTime, $currentEndTime);
         $cidKeys = array_unique(array_merge(array_keys($fwdMap), array_keys($qtyMap)));
+        // 与按客户扣减同一套数据汇总,避免 passTime 空值导致合计为 0
+        $nextDayDeduct = '0.00';
         foreach ($cidKeys as $cid) {
             $amt = $fwdMap[$cid] ?? '0';
             $qty = $qtyMap[$cid] ?? '0';
@@ -233,12 +235,20 @@ class StatSaleClass extends BaseClass
             $arr[$cid]['count'] = bcsub((string)($arr[$cid]['count'] ?? 0), (string)$qty, 2);
             $totalAmount = bcsub((string)$totalAmount, (string)$amt, 2);
             $totalProfit = bcsub((string)$totalProfit, (string)$amt, 2);
+            $nextDayDeduct = bcadd($nextDayDeduct, (string)$amt, 2);
         }
         if (!empty($arr)) {
-            $arr = arrayUtil::arraySort($arr, 'profit');
+            $arr = array_values(arrayUtil::arraySort($arr, 'profit'));
         }
         $totalAmount = floatval($totalAmount);
-        return ['list' => $arr, 'totalAmount' => $totalAmount, 'totalNum' => $totalNum, 'totalCost' => $totalCost, 'totalProfit' => $totalProfit];
+        return [
+            'list' => $arr,
+            'totalAmount' => $totalAmount,
+            'totalNum' => $totalNum,
+            'totalCost' => $totalCost,
+            'totalProfit' => $totalProfit,
+            'nextDayDeduct' => floatval($nextDayDeduct),
+        ];
     }
 
     /**
@@ -488,6 +498,9 @@ class StatSaleClass extends BaseClass
     }
 
     //按花材统计收入 ssh 20231111
+    /**
+     * 花材收支明细:销售侧已按隔天通过日扣收入;采购侧入库日净量 + 通过日扣成本。
+     */
     public static function incomeOutItem($mainId)
     {
         $get = Yii::$app->request->get();
@@ -556,7 +569,12 @@ class StatSaleClass extends BaseClass
                         $itemNum = $cgData->itemNum ?? 0;
                         $productId = $cgData->productId ?? 0;
                         $refundNum = $cgData->refundNum ?? 0;
-                        $remainNum = bcsub($itemNum, $refundNum);
+                        // 入库日净量:隔天退货记 nextRefundNum,通过日再扣成本
+                        $remainNum = CgPurchaseNextDayClass::payDayRemainNum(
+                            $itemNum,
+                            $refundNum,
+                            $cgData->nextRefundNum ?? 0
+                        );
                         $bigPrice = $cgData->bigPrice ?? 0;
                         $amount = bcmul($remainNum, $bigPrice, 2);
                         $itemName = $productList[$productId]['name'] ?? '已删除';
@@ -577,6 +595,11 @@ class StatSaleClass extends BaseClass
                         if (!empty($cgRefundOrderList)) {
                             foreach ($cgRefundOrderList as $cgRefundOrder) {
                                 if ($cgRefundOrder->refundType == 2) {
+                                    // 隔天仅退款记在通过日,避免与下方汇总重复
+                                    if (intval($cgRefundOrder->sameDay ?? CgPurchaseNextDayClass::SAME_DAY_YES)
+                                        === CgPurchaseNextDayClass::SAME_DAY_NO) {
+                                        continue;
+                                    }
                                     $onlyRefundCg = bcadd($cgRefundOrder->refundPrice, $onlyRefundCg, 2);
                                 }
                             }
@@ -586,6 +609,19 @@ class StatSaleClass extends BaseClass
             }
         }
 
+        // 采购隔天售后:入库日已用 nextRefundNum;通过日再扣花材成本/数量;仅退款进「采购仅退款」
+        $onlyRefundCg = bcadd(
+            (string)$onlyRefundCg,
+            self::applyNextDayAdjustToProductExpendRows(
+                $arr,
+                $productList,
+                $mainId,
+                $currentStartTime,
+                $currentEndTime
+            ),
+            2
+        );
+
         //批发开单
         $pfIncome = 0;
         $tbSaleIncome = [];
@@ -1698,6 +1734,54 @@ class StatSaleClass extends BaseClass
         return ['list' => $arr, 'totalAmount' => $totalAmount, 'totalNum' => $totalNum, 'totalCost' => $totalCost, 'totalProfit' => $totalProfit];
     }
 
+    /**
+     * 花材收支明细-采购侧:入库日已用 nextRefundNum;通过日扣退货数量/金额,返回隔天仅退款合计。
+     *
+     * @param array $arr 产品收支行(引用修改 expend/outNum)
+     * @param array $productList 花材字典
+     * @param int $mainId
+     * @param string $startTime
+     * @param string $endTime
+     * @return string 通过日隔天「采购仅退款」合计
+     */
+    private static function applyNextDayAdjustToProductExpendRows(
+        &$arr,
+        $productList,
+        $mainId,
+        $startTime,
+        $endTime
+    ) {
+        $applyDelta = function ($pidMap, $sign) use (&$arr, $productList) {
+            foreach ($pidMap as $pid => $row) {
+                $deltaNum = bcmul((string)($row['num'] ?? '0'), (string)$sign, 2);
+                $deltaAmt = bcmul((string)($row['amount'] ?? '0'), (string)$sign, 2);
+                if (bccomp($deltaAmt, '0', 2) == 0 && bccomp($deltaNum, '0', 2) == 0) {
+                    continue;
+                }
+                // 通过日无该花材入库也建负成本行
+                if (!isset($arr[$pid])) {
+                    $arr[$pid] = [
+                        'name' => $productList[$pid]['name'] ?? '已删除',
+                        'id' => $pid,
+                        'expend' => '0.00',
+                        'outNum' => '0.00',
+                        'inNum' => 0,
+                        'income' => 0,
+                    ];
+                }
+                $arr[$pid]['expend'] = bcadd((string)($arr[$pid]['expend'] ?? 0), $deltaAmt, 2);
+                $arr[$pid]['outNum'] = bcadd((string)($arr[$pid]['outNum'] ?? 0), $deltaNum, 2);
+            }
+        };
+
+        $applyDelta(
+            CgPurchaseNextDayClass::sumItemByProduct($mainId, $startTime, $endTime),
+            -1
+        );
+
+        return CgPurchaseNextDayClass::sumMoneyOnlyAmountByMainAndTime($mainId, $startTime, $endTime);
+    }
+
     /**
      * 花材收支明细:支付日已用 nextRefundNum;此处按通过日扣退货数量/金额,并返回隔天仅退款合计。
      *