|
|
@@ -611,4 +611,145 @@ class NextDayRefundService
|
|
|
}
|
|
|
return $map;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 关联原单上「已发生」的隔天退货(不限通过日):用于销量按 payTime 统计时加回 refundNum 中的隔天部分,
|
|
|
+ * 避免与按 passTime 扣减重复;口径对齐客户业绩(支付日先全额,通过日再扣)。
|
|
|
+ *
|
|
|
+ * @param int $mainId
|
|
|
+ * @param string[] $relateOrderSns 原销售单号列表
|
|
|
+ * @return array productId => [num, amount]
|
|
|
+ */
|
|
|
+ public static function sumItemByProductForRelateOrderSns($mainId, $relateOrderSns)
|
|
|
+ {
|
|
|
+ $relateOrderSns = array_values(array_unique(array_filter($relateOrderSns)));
|
|
|
+ if (empty($relateOrderSns)) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ $snParams = [];
|
|
|
+ foreach ($relateOrderSns as $i => $sn) {
|
|
|
+ $snParams[':sn' . $i] = $sn;
|
|
|
+ }
|
|
|
+ $in = implode(',', array_keys($snParams));
|
|
|
+ $sql = "SELECT i.productId, COALESCE(SUM(i.xhNum),0) AS num, COALESCE(SUM(i.xhPrice),0) AS amount
|
|
|
+ FROM xhRefundItem i
|
|
|
+ INNER JOIN xhRefund r ON r.orderSn = i.orderSn
|
|
|
+ WHERE r.mainId=:mainId AND r.status=:status AND r.sameDay=:sameDay
|
|
|
+ AND r.refundType=:rtype
|
|
|
+ AND r.relateOrderSn IN ($in)
|
|
|
+ GROUP BY i.productId";
|
|
|
+ $params = array_merge([
|
|
|
+ ':mainId' => $mainId,
|
|
|
+ ':status' => RefundOrderClass::STATUS_COMPLETE,
|
|
|
+ ':sameDay' => self::SAME_DAY_NO,
|
|
|
+ ':rtype' => RefundOrderClass::REFUND_TYPE_MONEY_GOOD,
|
|
|
+ ], $snParams);
|
|
|
+ $rows = Yii::$app->db->createCommand($sql, $params)->queryAll();
|
|
|
+ $map = [];
|
|
|
+ foreach ($rows as $row) {
|
|
|
+ $map[$row['productId']] = [
|
|
|
+ 'num' => bcadd($row['num'] ?? '0', '0', 2),
|
|
|
+ 'amount' => bcadd($row['amount'] ?? '0', '0', 2),
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ return $map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 隔天「仅退款」按通过日汇总金额(无花材明细,进收支分类「销售仅退款」等)
|
|
|
+ */
|
|
|
+ public static function sumMoneyOnlyAmountByMainAndTime($mainId, $startTime, $endTime)
|
|
|
+ {
|
|
|
+ $sql = "SELECT COALESCE(SUM(refundPrice),0) AS total FROM xhRefund
|
|
|
+ WHERE mainId=:mainId AND status=:status AND sameDay=:sameDay
|
|
|
+ AND refundType=:rtype
|
|
|
+ AND IFNULL(NULLIF(passTime,'0000-00-00 00:00:00'), addTime) BETWEEN :start AND :end";
|
|
|
+ $row = Yii::$app->db->createCommand($sql, [
|
|
|
+ ':mainId' => $mainId,
|
|
|
+ ':status' => RefundOrderClass::STATUS_COMPLETE,
|
|
|
+ ':sameDay' => self::SAME_DAY_NO,
|
|
|
+ ':rtype' => RefundOrderClass::REFUND_TYPE_MONEY,
|
|
|
+ ':start' => $startTime,
|
|
|
+ ':end' => $endTime,
|
|
|
+ ])->queryOne();
|
|
|
+ return bcadd($row['total'] ?? '0', '0', 2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 隔天「仅退款」按通过日分摊到原单花材(无明细时按原单行金额占比分摊 refundPrice)
|
|
|
+ * 花材销量页用:通过日扣金额,数量不扣。
|
|
|
+ *
|
|
|
+ * @return array productId => [num=>0, amount=>...]
|
|
|
+ */
|
|
|
+ public static function sumMoneyOnlyAmountByProduct($mainId, $startTime, $endTime)
|
|
|
+ {
|
|
|
+ $sql = "SELECT r.id, r.refundPrice, r.relateOrderSn
|
|
|
+ FROM xhRefund r
|
|
|
+ WHERE r.mainId=:mainId AND r.status=:status AND r.sameDay=:sameDay
|
|
|
+ AND r.refundType=:rtype
|
|
|
+ AND IFNULL(NULLIF(r.relateOrderSn,''), '') <> ''
|
|
|
+ AND IFNULL(NULLIF(r.passTime,'0000-00-00 00:00:00'), r.addTime) BETWEEN :start AND :end";
|
|
|
+ $rows = Yii::$app->db->createCommand($sql, [
|
|
|
+ ':mainId' => $mainId,
|
|
|
+ ':status' => RefundOrderClass::STATUS_COMPLETE,
|
|
|
+ ':sameDay' => self::SAME_DAY_NO,
|
|
|
+ ':rtype' => RefundOrderClass::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 = \bizGhs\order\classes\OrderItemClass::getAllByCondition(
|
|
|
+ ['orderSn' => $relateSn],
|
|
|
+ null,
|
|
|
+ 'productId,xhNum,xhUnitPrice',
|
|
|
+ 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->xhNum ?? '0'), (string)($item->xhUnitPrice ?? '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;
|
|
|
+ }
|
|
|
}
|