|
@@ -1,14 +1,17 @@
|
|
|
<?php
|
|
<?php
|
|
|
/**
|
|
/**
|
|
|
* 上游采购隔天售后业务类(biz-ghs/cg/classes)
|
|
* 上游采购隔天售后业务类(biz-ghs/cg/classes)
|
|
|
- * 用途:按入库日/结清状态判定当天 vs 隔天;写支付快照;隔天累加 nextDayTkPrice 并买方加余额。
|
|
|
|
|
- * 调用方:CgRefundService、CgRefundController;与销售 NextDayRefundClass 语义对齐,时间基准用 entryTime。
|
|
|
|
|
|
|
+ * 用途:按入库日/结清状态判定当天 vs 隔天;写支付快照;隔天累加 nextDayTkPrice 并买方加余额;
|
|
|
|
|
+ * 统计辅助:入库日净量、通过日按供货商/采购人/花材扣减。
|
|
|
|
|
+ * 调用方:CgRefundService、CgRefundController、StatCgClass、StatCgGhsController。
|
|
|
*/
|
|
*/
|
|
|
namespace bizGhs\cg\classes;
|
|
namespace bizGhs\cg\classes;
|
|
|
|
|
|
|
|
use bizGhs\order\classes\PurchaseOrderClass;
|
|
use bizGhs\order\classes\PurchaseOrderClass;
|
|
|
|
|
+use bizGhs\order\classes\PurchaseOrderItemClass;
|
|
|
use common\components\dict;
|
|
use common\components\dict;
|
|
|
use common\components\util;
|
|
use common\components\util;
|
|
|
|
|
+use Yii;
|
|
|
|
|
|
|
|
class CgPurchaseNextDayClass
|
|
class CgPurchaseNextDayClass
|
|
|
{
|
|
{
|
|
@@ -166,4 +169,227 @@ class CgPurchaseNextDayClass
|
|
|
$refund->hasReturn = self::FLAG_YES;
|
|
$refund->hasReturn = self::FLAG_YES;
|
|
|
$refund->save(false, ['hasReturn']);
|
|
$refund->save(false, ['hasReturn']);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 入库日净采购量:当天已退 = refundNum - nextRefundNum,净量 = itemNum - 当天已退。
|
|
|
|
|
+ * 隔天退货记在 nextRefundNum,不在入库日扣掉(通过日再扣)。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param mixed $itemNum 采购数量
|
|
|
|
|
+ * @param mixed $refundNum 总已退
|
|
|
|
|
+ * @param mixed $nextRefundNum 隔天已退
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function payDayRemainNum($itemNum, $refundNum, $nextRefundNum = 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ $sameDayRefund = bcsub((string)$refundNum, (string)($nextRefundNum ?? 0), 2);
|
|
|
|
|
+ if (bccomp($sameDayRefund, '0', 2) < 0) {
|
|
|
|
|
+ $sameDayRefund = '0';
|
|
|
|
|
+ }
|
|
|
|
|
+ return bcsub((string)$itemNum, $sameDayRefund, 2);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 通过日有效时间:passTime 为空时回退 addTime(与销售统计一致)
|
|
|
|
|
+ */
|
|
|
|
|
+ private static function passTimeSqlExpr($alias = 'r')
|
|
|
|
|
+ {
|
|
|
|
|
+ return "IFNULL(NULLIF({$alias}.passTime,'0000-00-00 00:00:00'), {$alias}.addTime)";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 按供货商汇总隔天售后金额(供货业绩 cgStat 通过日扣减)
|
|
|
|
|
+ * @return array ghsId => amount
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function sumAmountGroupByGhs($mainId, $startTime, $endTime)
|
|
|
|
|
+ {
|
|
|
|
|
+ $passExpr = self::passTimeSqlExpr('r');
|
|
|
|
|
+ $sql = "SELECT r.ghsId, COALESCE(SUM(r.refundPrice),0) AS total
|
|
|
|
|
+ FROM xhGhsCgRefund r
|
|
|
|
|
+ WHERE r.mainId=:mainId AND r.status=:status AND r.sameDay=:sameDay
|
|
|
|
|
+ AND {$passExpr} BETWEEN :start AND :end
|
|
|
|
|
+ GROUP BY r.ghsId";
|
|
|
|
|
+ $rows = Yii::$app->db->createCommand($sql, [
|
|
|
|
|
+ ':mainId' => intval($mainId),
|
|
|
|
|
+ ':status' => 1,
|
|
|
|
|
+ ':sameDay' => self::SAME_DAY_NO,
|
|
|
|
|
+ ':start' => $startTime,
|
|
|
|
|
+ ':end' => $endTime,
|
|
|
|
|
+ ])->queryAll();
|
|
|
|
|
+ $map = [];
|
|
|
|
|
+ foreach ($rows as $row) {
|
|
|
|
|
+ $map[intval($row['ghsId'] ?? 0)] = bcadd($row['total'] ?? '0', '0', 2);
|
|
|
|
|
+ }
|
|
|
|
|
+ return $map;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 按原采购单采购人汇总隔天售后金额(采购人业绩 cgYj 通过日扣减,笔数不减)
|
|
|
|
|
+ * @return array cgStaffId => [amount, cgStaffName]
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function sumAmountGroupByCgStaff($mainId, $startTime, $endTime)
|
|
|
|
|
+ {
|
|
|
|
|
+ $passExpr = self::passTimeSqlExpr('r');
|
|
|
|
|
+ $sql = "SELECT IFNULL(o.cgStaffId,0) AS cgStaffId,
|
|
|
|
|
+ MAX(IFNULL(o.cgStaffName,'')) AS cgStaffName,
|
|
|
|
|
+ COALESCE(SUM(r.refundPrice),0) AS total
|
|
|
|
|
+ FROM xhGhsCgRefund r
|
|
|
|
|
+ INNER JOIN xhGhsCgOrder o ON o.orderSn = r.relateOrderSn
|
|
|
|
|
+ WHERE r.mainId=:mainId AND r.status=:status AND r.sameDay=:sameDay
|
|
|
|
|
+ AND {$passExpr} BETWEEN :start AND :end
|
|
|
|
|
+ GROUP BY o.cgStaffId";
|
|
|
|
|
+ $rows = Yii::$app->db->createCommand($sql, [
|
|
|
|
|
+ ':mainId' => intval($mainId),
|
|
|
|
|
+ ':status' => 1,
|
|
|
|
|
+ ':sameDay' => self::SAME_DAY_NO,
|
|
|
|
|
+ ':start' => $startTime,
|
|
|
|
|
+ ':end' => $endTime,
|
|
|
|
|
+ ])->queryAll();
|
|
|
|
|
+ $map = [];
|
|
|
|
|
+ foreach ($rows as $row) {
|
|
|
|
|
+ $sid = intval($row['cgStaffId'] ?? 0);
|
|
|
|
|
+ $map[$sid] = [
|
|
|
|
|
+ 'amount' => bcadd($row['total'] ?? '0', '0', 2),
|
|
|
|
|
+ 'cgStaffName' => (string)($row['cgStaffName'] ?? ''),
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+ return $map;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 按花材汇总隔天退货数量与金额(退货退款明细;itemId=productId)
|
|
|
|
|
+ * @return array productId => [num, amount]
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function sumItemByProduct($mainId, $startTime, $endTime)
|
|
|
|
|
+ {
|
|
|
|
|
+ $passExpr = self::passTimeSqlExpr('r');
|
|
|
|
|
+ $sql = "SELECT i.itemId AS productId,
|
|
|
|
|
+ COALESCE(SUM(i.num),0) AS num,
|
|
|
|
|
+ COALESCE(SUM(i.price),0) AS amount
|
|
|
|
|
+ FROM xhGhsCgRefundItem i
|
|
|
|
|
+ INNER JOIN xhGhsCgRefund r ON r.refundSn = i.refundSn
|
|
|
|
|
+ WHERE r.mainId=:mainId AND r.status=:status AND r.sameDay=:sameDay
|
|
|
|
|
+ AND r.refundType=:rtype
|
|
|
|
|
+ AND {$passExpr} BETWEEN :start AND :end
|
|
|
|
|
+ GROUP BY i.itemId";
|
|
|
|
|
+ $rows = Yii::$app->db->createCommand($sql, [
|
|
|
|
|
+ ':mainId' => intval($mainId),
|
|
|
|
|
+ ':status' => 1,
|
|
|
|
|
+ ':sameDay' => self::SAME_DAY_NO,
|
|
|
|
|
+ ':rtype' => CgRefundClass::REFUND_TYPE_MONEY_GOOD,
|
|
|
|
|
+ ':start' => $startTime,
|
|
|
|
|
+ ':end' => $endTime,
|
|
|
|
|
+ ])->queryAll();
|
|
|
|
|
+ $map = [];
|
|
|
|
|
+ foreach ($rows as $row) {
|
|
|
|
|
+ $pid = intval($row['productId'] ?? 0);
|
|
|
|
|
+ if ($pid <= 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $map[$pid] = [
|
|
|
|
|
+ 'num' => bcadd($row['num'] ?? '0', '0', 2),
|
|
|
|
|
+ 'amount' => bcadd($row['amount'] ?? '0', '0', 2),
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+ return $map;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 隔天「仅退款」按原采购明细金额占比分摊到花材(通过日只扣金额不扣数量)
|
|
|
|
|
+ * @return array productId => [num=>0, amount=>...]
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function sumMoneyOnlyAmountByProduct($mainId, $startTime, $endTime)
|
|
|
|
|
+ {
|
|
|
|
|
+ $passExpr = self::passTimeSqlExpr('r');
|
|
|
|
|
+ $sql = "SELECT r.id, r.refundPrice, r.relateOrderSn
|
|
|
|
|
+ FROM xhGhsCgRefund r
|
|
|
|
|
+ WHERE r.mainId=:mainId AND r.status=:status AND r.sameDay=:sameDay
|
|
|
|
|
+ AND r.refundType=:rtype
|
|
|
|
|
+ AND IFNULL(NULLIF(r.relateOrderSn,''), '') <> ''
|
|
|
|
|
+ AND {$passExpr} BETWEEN :start AND :end";
|
|
|
|
|
+ $rows = Yii::$app->db->createCommand($sql, [
|
|
|
|
|
+ ':mainId' => intval($mainId),
|
|
|
|
|
+ ':status' => 1,
|
|
|
|
|
+ ':sameDay' => self::SAME_DAY_NO,
|
|
|
|
|
+ ':rtype' => CgRefundClass::REFUND_TYPE_MONEY,
|
|
|
|
|
+ ':start' => $startTime,
|
|
|
|
|
+ ':end' => $endTime,
|
|
|
|
|
+ ])->queryAll();
|
|
|
|
|
+ if (empty($rows)) {
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
+ $map = [];
|
|
|
|
|
+ foreach ($rows as $row) {
|
|
|
|
|
+ $refundPrice = bcadd((string)($row['refundPrice'] ?? '0'), '0', 2);
|
|
|
|
|
+ if (bccomp($refundPrice, '0', 2) <= 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $relateSn = $row['relateOrderSn'] ?? '';
|
|
|
|
|
+ $items = PurchaseOrderItemClass::getAllByCondition(
|
|
|
|
|
+ ['orderSn' => $relateSn],
|
|
|
|
|
+ null,
|
|
|
|
|
+ 'productId,itemNum,bigPrice',
|
|
|
|
|
+ null,
|
|
|
|
|
+ true
|
|
|
|
|
+ );
|
|
|
|
|
+ if (empty($items)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $weights = [];
|
|
|
|
|
+ $weightSum = '0.00';
|
|
|
|
|
+ foreach ($items as $item) {
|
|
|
|
|
+ $pid = intval($item->productId ?? 0);
|
|
|
|
|
+ if ($pid <= 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $line = bcmul((string)($item->itemNum ?? '0'), (string)($item->bigPrice ?? '0'), 2);
|
|
|
|
|
+ if (bccomp($line, '0', 2) <= 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $weights[$pid] = bcadd($weights[$pid] ?? '0', $line, 2);
|
|
|
|
|
+ $weightSum = bcadd($weightSum, $line, 2);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (bccomp($weightSum, '0', 2) <= 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $allocated = '0.00';
|
|
|
|
|
+ $pids = array_keys($weights);
|
|
|
|
|
+ $last = count($pids) - 1;
|
|
|
|
|
+ foreach ($pids as $idx => $pid) {
|
|
|
|
|
+ if ($idx === $last) {
|
|
|
|
|
+ $part = bcsub($refundPrice, $allocated, 2);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $part = bcdiv(bcmul($refundPrice, $weights[$pid], 4), $weightSum, 2);
|
|
|
|
|
+ $allocated = bcadd($allocated, $part, 2);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!isset($map[$pid])) {
|
|
|
|
|
+ $map[$pid] = ['num' => '0.00', 'amount' => '0.00'];
|
|
|
|
|
+ }
|
|
|
|
|
+ $map[$pid]['amount'] = bcadd($map[$pid]['amount'], $part, 2);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return $map;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 隔天「仅退款」按通过日汇总金额(收支分类「采购仅退款」)
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function sumMoneyOnlyAmountByMainAndTime($mainId, $startTime, $endTime)
|
|
|
|
|
+ {
|
|
|
|
|
+ $passExpr = self::passTimeSqlExpr('r');
|
|
|
|
|
+ $sql = "SELECT COALESCE(SUM(r.refundPrice),0) AS total
|
|
|
|
|
+ FROM xhGhsCgRefund r
|
|
|
|
|
+ WHERE r.mainId=:mainId AND r.status=:status AND r.sameDay=:sameDay
|
|
|
|
|
+ AND r.refundType=:rtype
|
|
|
|
|
+ AND {$passExpr} BETWEEN :start AND :end";
|
|
|
|
|
+ $row = Yii::$app->db->createCommand($sql, [
|
|
|
|
|
+ ':mainId' => intval($mainId),
|
|
|
|
|
+ ':status' => 1,
|
|
|
|
|
+ ':sameDay' => self::SAME_DAY_NO,
|
|
|
|
|
+ ':rtype' => CgRefundClass::REFUND_TYPE_MONEY,
|
|
|
|
|
+ ':start' => $startTime,
|
|
|
|
|
+ ':end' => $endTime,
|
|
|
|
|
+ ])->queryOne();
|
|
|
|
|
+ return bcadd($row['total'] ?? '0', '0', 2);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|