|
|
@@ -20,11 +20,9 @@ use bizGhs\product\classes\ProductClass;
|
|
|
use bizGhs\staff\classes\SalaryClass;
|
|
|
use bizHd\goods\classes\PlantCgClass;
|
|
|
use bizHd\order\classes\OrderClass as HdOrderClass;
|
|
|
-use bizHd\order\classes\OrderItemClass as HdOrderItemClass;
|
|
|
use bizGhs\order\classes\OrderClass;
|
|
|
use bizHd\purchase\classes\PurchaseClass;
|
|
|
use bizHd\refund\classes\HdRefundClass;
|
|
|
-use bizHd\refund\classes\HdNextDayRefundClass;
|
|
|
use common\components\arrayUtil;
|
|
|
use common\components\dateUtil;
|
|
|
use common\components\dict;
|
|
|
@@ -122,10 +120,7 @@ class StatSaleClass extends BaseClass
|
|
|
return ['list' => $ghsOrderList];
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 客户业绩:按客户汇总笔数/扎数/金额/成本/利润,供 ghsApp customSale、/stat-kh-cg/profile 使用。
|
|
|
- * totalCount 为总扎数(含隔天售后扣减),与各行 count 口径一致。
|
|
|
- */
|
|
|
+ //客户下单榜 ssh 20230502
|
|
|
public static function statCustomCg($mainId)
|
|
|
{
|
|
|
$get = Yii::$app->request->get();
|
|
|
@@ -154,7 +149,6 @@ class StatSaleClass extends BaseClass
|
|
|
$ghsOrderList = OrderClass::getAllByCondition($where, null, '*');
|
|
|
$totalAmount = 0;
|
|
|
$totalNum = 0;
|
|
|
- $totalCount = 0;
|
|
|
$totalProfit = 0;
|
|
|
$totalCost = 0;
|
|
|
if (!empty($ghsOrderList)) {
|
|
|
@@ -181,7 +175,6 @@ class StatSaleClass extends BaseClass
|
|
|
$customName = $customList[$customId]['name'] ?? '';
|
|
|
$py = $customList[$customId]['py'] ?? '';
|
|
|
$totalNum++;
|
|
|
- $totalCount = bcadd($totalCount, $count, 2);
|
|
|
$totalAmount = bcadd($totalAmount, $actPrice, 2);
|
|
|
$totalProfit = bcadd($totalProfit, $profit, 2);
|
|
|
$totalCost = bcadd($totalCost, $cost, 2);
|
|
|
@@ -198,7 +191,6 @@ class StatSaleClass extends BaseClass
|
|
|
'customId' => $customId,
|
|
|
'customName' => $customName,
|
|
|
'py' => $py,
|
|
|
- 'source' => 'ghs',
|
|
|
'num' => 1,
|
|
|
'count' => $count,
|
|
|
'amount' => $actPrice,
|
|
|
@@ -211,99 +203,12 @@ class StatSaleClass extends BaseClass
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- // 零售开单:与批发共用客户业绩;key 用 hd_{id},名称加「零售-」前缀
|
|
|
- $productCostMap = ProductClass::getAllByCondition(['mainId' => $mainId], null, 'id,cost,avCost', 'id');
|
|
|
- $hdWhere = [
|
|
|
- 'mainId' => $mainId,
|
|
|
- 'status' => ['in', [HdOrderClass::ORDER_STATUS_UN_SEND, HdOrderClass::ORDER_STATUS_SENDING, HdOrderClass::ORDER_STATUS_COMPLETE]],
|
|
|
- 'payTime' => ['between', [$currentStartTime, $currentEndTime]],
|
|
|
- ];
|
|
|
- $hdOrderList = HdOrderClass::getAllByCondition($hdWhere, null, '*');
|
|
|
- if (!empty($hdOrderList)) {
|
|
|
- foreach ($hdOrderList as $hdOrder) {
|
|
|
- $forward = intval($hdOrder['forward'] ?? 0);
|
|
|
- if ($forward === 1) {
|
|
|
- // 售后付款属支出,不进客户业绩
|
|
|
- continue;
|
|
|
- }
|
|
|
- $status = intval($hdOrder['status'] ?? 0);
|
|
|
- if ($status === HdOrderClass::ORDER_STATUS_UN_PAY || $status === HdOrderClass::ORDER_STATUS_CANCEL) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- $mainPay = bcadd((string)($hdOrder['mainPay'] ?? '0'), '0', 2);
|
|
|
- $tkPrice = bcadd((string)($hdOrder['tkPrice'] ?? '0'), '0', 2);
|
|
|
- $cash = bcadd((string)($hdOrder['cash'] ?? '0'), '0', 2);
|
|
|
- // 当天退款已从 mainPay 口径扣 tkPrice;现金另计(对齐渠道收入)
|
|
|
- $actPrice = bcadd(bcsub($mainPay, $tkPrice, 2), $cash, 2);
|
|
|
- if (bccomp($actPrice, '0', 2) <= 0) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- $customId = intval($hdOrder['customId'] ?? 0);
|
|
|
- $rowKey = HdNextDayRefundClass::customStatKey($customId);
|
|
|
- $rawName = trim((string)($hdOrder['customName'] ?? ''));
|
|
|
- $orderSn = $hdOrder['orderSn'] ?? '';
|
|
|
-
|
|
|
- // 扎数、成本:按支付日净销量(隔天部分 nextRefundNum 留到通过日扣)
|
|
|
- $count = '0.00';
|
|
|
- $cost = '0.00';
|
|
|
- $orderItemList = HdOrderItemClass::getAllByCondition(['orderSn' => $orderSn], null, '*', null, true);
|
|
|
- if (!empty($orderItemList)) {
|
|
|
- foreach ($orderItemList as $orderItem) {
|
|
|
- $remainNum = HdNextDayRefundClass::payDayRemainNum(
|
|
|
- $orderItem->num ?? 0,
|
|
|
- $orderItem->refundNum ?? 0,
|
|
|
- $orderItem->nextRefundNum ?? 0
|
|
|
- );
|
|
|
- $count = bcadd($count, $remainNum, 2);
|
|
|
- $productId = intval($orderItem->itemId ?? 0);
|
|
|
- $unitCost = $orderItem->cost ?? null;
|
|
|
- if ($unitCost === null || $unitCost === '') {
|
|
|
- $unitCost = $productCostMap[$productId]['avCost']
|
|
|
- ?? ($productCostMap[$productId]['cost'] ?? 0);
|
|
|
- }
|
|
|
- $cost = bcadd($cost, bcmul($remainNum, (string)$unitCost, 2), 2);
|
|
|
- }
|
|
|
- }
|
|
|
- $profit = bcsub($actPrice, $cost, 2);
|
|
|
- $totalNum++;
|
|
|
- $totalCount = bcadd($totalCount, $count, 2);
|
|
|
- $totalAmount = bcadd($totalAmount, $actPrice, 2);
|
|
|
- $totalProfit = bcadd($totalProfit, $profit, 2);
|
|
|
- $totalCost = bcadd($totalCost, $cost, 2);
|
|
|
-
|
|
|
- if (isset($arr[$rowKey])) {
|
|
|
- $arr[$rowKey]['num']++;
|
|
|
- $arr[$rowKey]['amount'] = bcadd($arr[$rowKey]['amount'], $actPrice, 2);
|
|
|
- $arr[$rowKey]['count'] = bcadd($arr[$rowKey]['count'], $count, 2);
|
|
|
- $arr[$rowKey]['orderPrice'] = bcadd($arr[$rowKey]['orderPrice'], $mainPay, 2);
|
|
|
- $arr[$rowKey]['tkPrice'] = bcadd($arr[$rowKey]['tkPrice'], $tkPrice, 2);
|
|
|
- $arr[$rowKey]['cost'] = bcadd($arr[$rowKey]['cost'], $cost, 2);
|
|
|
- $arr[$rowKey]['profit'] = bcadd($arr[$rowKey]['profit'], $profit, 2);
|
|
|
- } else {
|
|
|
- $arr[$rowKey] = [
|
|
|
- 'customId' => $customId,
|
|
|
- 'customName' => HdNextDayRefundClass::displayCustomName($rawName, $customId),
|
|
|
- 'py' => '',
|
|
|
- 'source' => 'hd',
|
|
|
- 'num' => 1,
|
|
|
- 'count' => $count,
|
|
|
- 'amount' => $actPrice,
|
|
|
- 'levelName' => '',
|
|
|
- 'orderPrice' => $mainPay,
|
|
|
- 'tkPrice' => $tkPrice,
|
|
|
- 'cost' => $cost,
|
|
|
- 'profit' => $profit,
|
|
|
- ];
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
// 隔天售后:按通过日扣金额/扎数;无当日开单也建负行(笔数不减)
|
|
|
- // ghs 批发客户用原 customId;hd 零售用 hd_{id} 隔离,避免与 xhGhsCustom 撞号
|
|
|
$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';
|
|
|
@@ -315,7 +220,6 @@ class StatSaleClass extends BaseClass
|
|
|
'customId' => $cid,
|
|
|
'customName' => $customList[$cid]['name'] ?? '',
|
|
|
'py' => $customList[$cid]['py'] ?? '',
|
|
|
- 'source' => 'ghs',
|
|
|
'num' => 0,
|
|
|
'count' => '0.00',
|
|
|
'amount' => '0.00',
|
|
|
@@ -331,62 +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);
|
|
|
- $totalCount = bcsub((string)$totalCount, (string)$qty, 2);
|
|
|
- }
|
|
|
-
|
|
|
- // hd 零售隔天:独立 key +「零售-」客户名
|
|
|
- $hdAmtMap = HdNextDayRefundClass::sumAmountGroupByCustom($mainId, $currentStartTime, $currentEndTime);
|
|
|
- $hdQtyMap = HdNextDayRefundClass::sumItemQtyByCustom($mainId, $currentStartTime, $currentEndTime);
|
|
|
- $hdCids = array_unique(array_merge(array_keys($hdAmtMap), array_keys($hdQtyMap)));
|
|
|
- foreach ($hdCids as $cid) {
|
|
|
- $amtInfo = $hdAmtMap[$cid] ?? null;
|
|
|
- $qtyInfo = $hdQtyMap[$cid] ?? null;
|
|
|
- $amt = is_array($amtInfo) ? ($amtInfo['amount'] ?? '0') : '0';
|
|
|
- $qty = is_array($qtyInfo) ? ($qtyInfo['num'] ?? '0') : '0';
|
|
|
- if (bccomp((string)$amt, '0', 2) == 0 && bccomp((string)$qty, '0', 2) == 0) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- $rowKey = HdNextDayRefundClass::customStatKey($cid);
|
|
|
- $rawName = '';
|
|
|
- $py = '';
|
|
|
- if (is_array($amtInfo)) {
|
|
|
- $rawName = $amtInfo['customName'] ?? '';
|
|
|
- $py = $amtInfo['py'] ?? '';
|
|
|
- }
|
|
|
- if ($rawName === '' && is_array($qtyInfo)) {
|
|
|
- $rawName = $qtyInfo['customName'] ?? '';
|
|
|
- if ($py === '') {
|
|
|
- $py = $qtyInfo['py'] ?? '';
|
|
|
- }
|
|
|
- }
|
|
|
- if (!isset($arr[$rowKey])) {
|
|
|
- $arr[$rowKey] = [
|
|
|
- 'customId' => $cid,
|
|
|
- 'customName' => HdNextDayRefundClass::displayCustomName($rawName, $cid),
|
|
|
- 'py' => $py,
|
|
|
- 'source' => 'hd',
|
|
|
- 'num' => 0,
|
|
|
- 'count' => '0.00',
|
|
|
- 'amount' => '0.00',
|
|
|
- 'levelName' => '',
|
|
|
- 'orderPrice' => 0,
|
|
|
- 'tkPrice' => 0,
|
|
|
- 'cost' => 0,
|
|
|
- 'profit' => '0.00',
|
|
|
- ];
|
|
|
- }
|
|
|
- $arr[$rowKey]['amount'] = bcsub((string)$arr[$rowKey]['amount'], (string)$amt, 2);
|
|
|
- $arr[$rowKey]['profit'] = bcsub((string)$arr[$rowKey]['profit'], (string)$amt, 2);
|
|
|
- $arr[$rowKey]['count'] = bcsub((string)($arr[$rowKey]['count'] ?? 0), (string)$qty, 2);
|
|
|
- $totalAmount = bcsub((string)$totalAmount, (string)$amt, 2);
|
|
|
- $totalProfit = bcsub((string)$totalProfit, (string)$amt, 2);
|
|
|
- $totalCount = bcsub((string)$totalCount, (string)$qty, 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, 'totalCount' => floatval($totalCount), 'totalCost' => $totalCost, 'totalProfit' => $totalProfit];
|
|
|
+ return [
|
|
|
+ 'list' => $arr,
|
|
|
+ 'totalAmount' => $totalAmount,
|
|
|
+ 'totalNum' => $totalNum,
|
|
|
+ 'totalCost' => $totalCost,
|
|
|
+ 'totalProfit' => $totalProfit,
|
|
|
+ 'nextDayDeduct' => floatval($nextDayDeduct),
|
|
|
+ ];
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -564,12 +426,6 @@ class StatSaleClass extends BaseClass
|
|
|
$lsGiveBalance = bcadd($lsGiveBalance, $remainGiveBalance, 2);
|
|
|
}
|
|
|
}
|
|
|
- // 隔天售后扣减零售收入(当天退款已在 tkPrice 扣过;隔天记 nextDayTkPrice,按通过日扣)
|
|
|
- $lsIncome = bcsub(
|
|
|
- (string)$lsIncome,
|
|
|
- HdNextDayRefundClass::sumAmountByMainAndTime($mainId, $currentStartTime, $currentEndTime),
|
|
|
- 2
|
|
|
- );
|
|
|
|
|
|
$condition = ['mainId' => $mainId, 'addTime' => ['between', [$currentStartTime, $currentEndTime]],];
|
|
|
|
|
|
@@ -607,7 +463,7 @@ class StatSaleClass extends BaseClass
|
|
|
['name' => '零售', 'id' => 'ls', 'amount' => floatval($lsIncome)],
|
|
|
['name' => '调拨出库', 'id' => 'allot', 'amount' => floatval($stockOut)],
|
|
|
// 采购隔天售后冲回(含退货并退款、仅退款);后续若细分再拆行
|
|
|
- ['name' => '采购隔天退货', 'id' => 'cgNextDay', 'amount' => floatval($cgNextDayRefund)],
|
|
|
+ ['name' => '采购隔天退款', 'id' => 'cgNextDay', 'amount' => floatval($cgNextDayRefund)],
|
|
|
];
|
|
|
$expend = [
|
|
|
['name' => '批发运费', 'id' => 'pfSendCost', 'amount' => floatval($pfSendCost)],
|
|
|
@@ -642,6 +498,9 @@ class StatSaleClass extends BaseClass
|
|
|
}
|
|
|
|
|
|
//按花材统计收入 ssh 20231111
|
|
|
+ /**
|
|
|
+ * 花材收支明细:销售侧已按隔天通过日扣收入;采购侧入库日净量 + 通过日扣成本。
|
|
|
+ */
|
|
|
public static function incomeOutItem($mainId)
|
|
|
{
|
|
|
$get = Yii::$app->request->get();
|
|
|
@@ -710,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'] ?? '已删除';
|
|
|
@@ -731,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);
|
|
|
}
|
|
|
}
|
|
|
@@ -740,6 +609,19 @@ class StatSaleClass extends BaseClass
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 采购隔天售后:入库日已用 nextRefundNum;通过日再扣花材成本/数量;仅退款进「采购仅退款」
|
|
|
+ $onlyRefundCg = bcadd(
|
|
|
+ (string)$onlyRefundCg,
|
|
|
+ self::applyNextDayAdjustToProductExpendRows(
|
|
|
+ $arr,
|
|
|
+ $productList,
|
|
|
+ $mainId,
|
|
|
+ $currentStartTime,
|
|
|
+ $currentEndTime
|
|
|
+ ),
|
|
|
+ 2
|
|
|
+ );
|
|
|
+
|
|
|
//批发开单
|
|
|
$pfIncome = 0;
|
|
|
$tbSaleIncome = [];
|
|
|
@@ -870,12 +752,7 @@ class StatSaleClass extends BaseClass
|
|
|
$refundNum = $orderItem->refundNum ?? 0;
|
|
|
$num = $orderItem->num ?? 0;
|
|
|
$productId = $orderItem->itemId ?? 0;
|
|
|
- // 支付日净销量:隔天部分记 nextRefundNum,通过日再扣
|
|
|
- $remainNum = HdNextDayRefundClass::payDayRemainNum(
|
|
|
- $num,
|
|
|
- $refundNum,
|
|
|
- $orderItem->nextRefundNum ?? 0
|
|
|
- );
|
|
|
+ $remainNum = bcsub($num, $refundNum);
|
|
|
$amount = bcmul($remainNum, $unitPrice, 2);
|
|
|
$itemName = $productList[$productId]['name'] ?? '已删除';
|
|
|
$arr[$productId]['name'] = $itemName;
|
|
|
@@ -891,14 +768,10 @@ class StatSaleClass extends BaseClass
|
|
|
}
|
|
|
}
|
|
|
if ($tkPrice > 0) {
|
|
|
- $refundList = HdRefundClass::getAllByCondition(['orderSn' => $orderSn, 'status' => HdRefundClass::STATUS_COMPLETE], null, '*', null, true);
|
|
|
+ $refundList = HdRefundClass::getAllByCondition(['orderSn' => $orderSn], null, '*', null, true);
|
|
|
if (!empty($refundList)) {
|
|
|
foreach ($refundList as $refund) {
|
|
|
if ($refund->refundType == 2) {
|
|
|
- // 隔天仅退款记在通过日,避免与 applyNextDayAdjust 重复
|
|
|
- if (intval($refund->sameDay ?? HdRefundClass::SAME_DAY_YES) === HdRefundClass::SAME_DAY_NO) {
|
|
|
- continue;
|
|
|
- }
|
|
|
$onlyRefund = bcadd($onlyRefund, $refund->refundPrice, 2);
|
|
|
}
|
|
|
}
|
|
|
@@ -1274,21 +1147,11 @@ class StatSaleClass extends BaseClass
|
|
|
NextDayRefundClass::sumItemByProduct($mainId, $currentStartTime, $currentEndTime),
|
|
|
-1
|
|
|
);
|
|
|
- // hd 零售隔天退货:同样按花材归属分类扣减
|
|
|
- $applyClassDelta(
|
|
|
- HdNextDayRefundClass::sumItemByProduct($mainId, $currentStartTime, $currentEndTime),
|
|
|
- -1
|
|
|
- );
|
|
|
$onlyRefund = bcadd(
|
|
|
(string)$onlyRefund,
|
|
|
NextDayRefundClass::sumMoneyOnlyAmountByMainAndTime($mainId, $currentStartTime, $currentEndTime),
|
|
|
2
|
|
|
);
|
|
|
- $onlyRefund = bcadd(
|
|
|
- (string)$onlyRefund,
|
|
|
- HdNextDayRefundClass::sumMoneyOnlyAmountByMainAndTime($mainId, $currentStartTime, $currentEndTime),
|
|
|
- 2
|
|
|
- );
|
|
|
|
|
|
//零售开单
|
|
|
$lsIncome = 0;
|
|
|
@@ -1314,11 +1177,7 @@ class StatSaleClass extends BaseClass
|
|
|
$num = $orderItem->num ?? 0;
|
|
|
$productId = $orderItem->itemId ?? 0;
|
|
|
$name = $orderItem->name ?? '';
|
|
|
- $remainNum = HdNextDayRefundClass::payDayRemainNum(
|
|
|
- $num,
|
|
|
- $refundNum,
|
|
|
- $orderItem->nextRefundNum ?? 0
|
|
|
- );
|
|
|
+ $remainNum = bcsub($num, $refundNum);
|
|
|
$amount = bcmul($remainNum, $unitPrice, 2);
|
|
|
$className = $classList[$classId]['name'] ?? '已删除';
|
|
|
$arr[$classId]['className'] = $className;
|
|
|
@@ -1343,14 +1202,10 @@ class StatSaleClass extends BaseClass
|
|
|
}
|
|
|
}
|
|
|
if ($tkPrice > 0) {
|
|
|
- $refundList = HdRefundClass::getAllByCondition(['orderSn' => $orderSn, 'status' => HdRefundClass::STATUS_COMPLETE], null, '*', null, true);
|
|
|
+ $refundList = HdRefundClass::getAllByCondition(['orderSn' => $orderSn], null, '*', null, true);
|
|
|
if (!empty($refundList)) {
|
|
|
foreach ($refundList as $refund) {
|
|
|
if ($refund->refundType == 2) {
|
|
|
- // 隔天仅退款记在通过日
|
|
|
- if (intval($refund->sameDay ?? HdRefundClass::SAME_DAY_YES) === HdRefundClass::SAME_DAY_NO) {
|
|
|
- continue;
|
|
|
- }
|
|
|
$onlyRefund = bcadd($onlyRefund, $refund->refundPrice, 2);
|
|
|
}
|
|
|
}
|
|
|
@@ -1756,10 +1611,6 @@ class StatSaleClass extends BaseClass
|
|
|
return $arr;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 片区业绩:按片区汇总笔数/扎数/金额/成本/利润,供 ghsApp distSale、/stat-kh-cg/dist 使用。
|
|
|
- * totalCount 为总扎数(含隔天售后扣减),与各行 count 口径一致。
|
|
|
- */
|
|
|
public static function customDistStat($mainId)
|
|
|
{
|
|
|
$get = Yii::$app->request->get();
|
|
|
@@ -1790,7 +1641,6 @@ class StatSaleClass extends BaseClass
|
|
|
$ghsOrderList = OrderClass::getAllByCondition($where, null, '*');
|
|
|
$totalAmount = 0;
|
|
|
$totalNum = 0;
|
|
|
- $totalCount = 0;
|
|
|
$totalProfit = 0;
|
|
|
$totalCost = 0;
|
|
|
if (!empty($ghsOrderList)) {
|
|
|
@@ -1819,7 +1669,6 @@ class StatSaleClass extends BaseClass
|
|
|
$distName = isset($distMap[$distId]) ? $distMap[$distId]['name'] : '未划片区';
|
|
|
|
|
|
$totalNum++;
|
|
|
- $totalCount = bcadd($totalCount, $count, 2);
|
|
|
$totalAmount = bcadd($totalAmount, $actPrice, 2);
|
|
|
$totalProfit = bcadd($totalProfit, $profit, 2);
|
|
|
$totalCost = bcadd($totalCost, $cost, 2);
|
|
|
@@ -1847,84 +1696,7 @@ class StatSaleClass extends BaseClass
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- // 零售客户无批发片区:全部归入虚拟片区「零售片区」
|
|
|
- $hdDistKey = 'hd_retail';
|
|
|
- $productCostMap = ProductClass::getAllByCondition(['mainId' => $mainId], null, 'id,cost,avCost', 'id');
|
|
|
- $hdWhere = [
|
|
|
- 'mainId' => $mainId,
|
|
|
- 'status' => ['in', [HdOrderClass::ORDER_STATUS_UN_SEND, HdOrderClass::ORDER_STATUS_SENDING, HdOrderClass::ORDER_STATUS_COMPLETE]],
|
|
|
- 'payTime' => ['between', [$currentStartTime, $currentEndTime]],
|
|
|
- ];
|
|
|
- $hdOrderList = HdOrderClass::getAllByCondition($hdWhere, null, '*');
|
|
|
- if (!empty($hdOrderList)) {
|
|
|
- foreach ($hdOrderList as $hdOrder) {
|
|
|
- if (intval($hdOrder['forward'] ?? 0) === 1) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- $status = intval($hdOrder['status'] ?? 0);
|
|
|
- if ($status === HdOrderClass::ORDER_STATUS_UN_PAY || $status === HdOrderClass::ORDER_STATUS_CANCEL) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- $mainPay = bcadd((string)($hdOrder['mainPay'] ?? '0'), '0', 2);
|
|
|
- $tkPrice = bcadd((string)($hdOrder['tkPrice'] ?? '0'), '0', 2);
|
|
|
- $cash = bcadd((string)($hdOrder['cash'] ?? '0'), '0', 2);
|
|
|
- $actPrice = bcadd(bcsub($mainPay, $tkPrice, 2), $cash, 2);
|
|
|
- if (bccomp($actPrice, '0', 2) <= 0) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- $orderSn = $hdOrder['orderSn'] ?? '';
|
|
|
- $count = '0.00';
|
|
|
- $cost = '0.00';
|
|
|
- $orderItemList = HdOrderItemClass::getAllByCondition(['orderSn' => $orderSn], null, '*', null, true);
|
|
|
- if (!empty($orderItemList)) {
|
|
|
- foreach ($orderItemList as $orderItem) {
|
|
|
- $remainNum = HdNextDayRefundClass::payDayRemainNum(
|
|
|
- $orderItem->num ?? 0,
|
|
|
- $orderItem->refundNum ?? 0,
|
|
|
- $orderItem->nextRefundNum ?? 0
|
|
|
- );
|
|
|
- $count = bcadd($count, $remainNum, 2);
|
|
|
- $productId = intval($orderItem->itemId ?? 0);
|
|
|
- $unitCost = $orderItem->cost ?? null;
|
|
|
- if ($unitCost === null || $unitCost === '') {
|
|
|
- $unitCost = $productCostMap[$productId]['avCost']
|
|
|
- ?? ($productCostMap[$productId]['cost'] ?? 0);
|
|
|
- }
|
|
|
- $cost = bcadd($cost, bcmul($remainNum, (string)$unitCost, 2), 2);
|
|
|
- }
|
|
|
- }
|
|
|
- $profit = bcsub($actPrice, $cost, 2);
|
|
|
- $totalNum++;
|
|
|
- $totalCount = bcadd($totalCount, $count, 2);
|
|
|
- $totalAmount = bcadd($totalAmount, $actPrice, 2);
|
|
|
- $totalProfit = bcadd($totalProfit, $profit, 2);
|
|
|
- $totalCost = bcadd($totalCost, $cost, 2);
|
|
|
- if (!isset($arr[$hdDistKey])) {
|
|
|
- $arr[$hdDistKey] = [
|
|
|
- 'distId' => 0,
|
|
|
- 'distName' => '零售片区',
|
|
|
- 'num' => 0,
|
|
|
- 'count' => '0.00',
|
|
|
- 'amount' => '0.00',
|
|
|
- 'levelName' => '',
|
|
|
- 'orderPrice' => 0,
|
|
|
- 'tkPrice' => 0,
|
|
|
- 'cost' => 0,
|
|
|
- 'profit' => '0.00',
|
|
|
- ];
|
|
|
- }
|
|
|
- $arr[$hdDistKey]['num']++;
|
|
|
- $arr[$hdDistKey]['amount'] = bcadd($arr[$hdDistKey]['amount'], $actPrice, 2);
|
|
|
- $arr[$hdDistKey]['orderPrice'] = bcadd($arr[$hdDistKey]['orderPrice'], $mainPay, 2);
|
|
|
- $arr[$hdDistKey]['count'] = bcadd($arr[$hdDistKey]['count'], $count, 2);
|
|
|
- $arr[$hdDistKey]['tkPrice'] = bcadd($arr[$hdDistKey]['tkPrice'], $tkPrice, 2);
|
|
|
- $arr[$hdDistKey]['cost'] = bcadd($arr[$hdDistKey]['cost'], $cost, 2);
|
|
|
- $arr[$hdDistKey]['profit'] = bcadd($arr[$hdDistKey]['profit'], $profit, 2);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 隔天售后按客户归到片区扣金额/扎数(批发走客户片区;零售统一扣「零售片区」)
|
|
|
+ // 隔天售后按客户归到片区扣金额/扎数;无当日开单的片区也建负行
|
|
|
$fwdMap = NextDayRefundClass::sumAmountGroupByCustom($mainId, $currentStartTime, $currentEndTime);
|
|
|
$qtyMap = NextDayRefundClass::sumItemQtyByCustom($mainId, $currentStartTime, $currentEndTime);
|
|
|
$cidKeys = array_unique(array_merge(array_keys($fwdMap), array_keys($qtyMap)));
|
|
|
@@ -1954,46 +1726,60 @@ class StatSaleClass extends BaseClass
|
|
|
$arr[$distId]['count'] = bcsub((string)($arr[$distId]['count'] ?? 0), (string)$qty, 2);
|
|
|
$totalAmount = bcsub((string)$totalAmount, (string)$amt, 2);
|
|
|
$totalProfit = bcsub((string)$totalProfit, (string)$amt, 2);
|
|
|
- $totalCount = bcsub((string)$totalCount, (string)$qty, 2);
|
|
|
- }
|
|
|
-
|
|
|
- $hdAmtMap = HdNextDayRefundClass::sumAmountGroupByCustom($mainId, $currentStartTime, $currentEndTime);
|
|
|
- $hdQtyMap = HdNextDayRefundClass::sumItemQtyByCustom($mainId, $currentStartTime, $currentEndTime);
|
|
|
- $hdAmtTotal = '0.00';
|
|
|
- $hdQtyTotal = '0.00';
|
|
|
- foreach ($hdAmtMap as $row) {
|
|
|
- $hdAmtTotal = bcadd($hdAmtTotal, (string)($row['amount'] ?? '0'), 2);
|
|
|
- }
|
|
|
- foreach ($hdQtyMap as $row) {
|
|
|
- $hdQtyTotal = bcadd($hdQtyTotal, (string)($row['num'] ?? '0'), 2);
|
|
|
- }
|
|
|
- if (bccomp($hdAmtTotal, '0', 2) > 0 || bccomp($hdQtyTotal, '0', 2) > 0) {
|
|
|
- if (!isset($arr[$hdDistKey])) {
|
|
|
- $arr[$hdDistKey] = [
|
|
|
- 'distId' => 0,
|
|
|
- 'distName' => '零售片区',
|
|
|
- 'num' => 0,
|
|
|
- 'count' => '0.00',
|
|
|
- 'amount' => '0.00',
|
|
|
- 'levelName' => '',
|
|
|
- 'orderPrice' => 0,
|
|
|
- 'tkPrice' => 0,
|
|
|
- 'cost' => 0,
|
|
|
- 'profit' => '0.00',
|
|
|
- ];
|
|
|
- }
|
|
|
- $arr[$hdDistKey]['amount'] = bcsub((string)$arr[$hdDistKey]['amount'], $hdAmtTotal, 2);
|
|
|
- $arr[$hdDistKey]['profit'] = bcsub((string)$arr[$hdDistKey]['profit'], $hdAmtTotal, 2);
|
|
|
- $arr[$hdDistKey]['count'] = bcsub((string)($arr[$hdDistKey]['count'] ?? 0), $hdQtyTotal, 2);
|
|
|
- $totalAmount = bcsub((string)$totalAmount, $hdAmtTotal, 2);
|
|
|
- $totalProfit = bcsub((string)$totalProfit, $hdAmtTotal, 2);
|
|
|
- $totalCount = bcsub((string)$totalCount, $hdQtyTotal, 2);
|
|
|
}
|
|
|
if (!empty($arr)) {
|
|
|
$arr = arrayUtil::arraySort($arr, 'profit');
|
|
|
}
|
|
|
$totalAmount = floatval($totalAmount);
|
|
|
- return ['list' => $arr, 'totalAmount' => $totalAmount, 'totalNum' => $totalNum, 'totalCount' => floatval($totalCount), 'totalCost' => $totalCost, 'totalProfit' => $totalProfit];
|
|
|
+ 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);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -2042,22 +1828,13 @@ class StatSaleClass extends BaseClass
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- // 通过日:扣退货数量+金额(ghs 批发 + hd 零售共用花材库存)
|
|
|
+ // 通过日:扣退货数量+金额
|
|
|
$applyDelta(
|
|
|
NextDayRefundClass::sumItemByProduct($mainId, $startTime, $endTime),
|
|
|
-1
|
|
|
);
|
|
|
- $applyDelta(
|
|
|
- HdNextDayRefundClass::sumItemByProduct($mainId, $startTime, $endTime),
|
|
|
- -1
|
|
|
- );
|
|
|
|
|
|
- $onlyRefund = NextDayRefundClass::sumMoneyOnlyAmountByMainAndTime($mainId, $startTime, $endTime);
|
|
|
- return bcadd(
|
|
|
- (string)$onlyRefund,
|
|
|
- HdNextDayRefundClass::sumMoneyOnlyAmountByMainAndTime($mainId, $startTime, $endTime),
|
|
|
- 2
|
|
|
- );
|
|
|
+ return NextDayRefundClass::sumMoneyOnlyAmountByMainAndTime($mainId, $startTime, $endTime);
|
|
|
}
|
|
|
|
|
|
/**
|