|
|
@@ -27,6 +27,13 @@ use common\components\util;
|
|
|
* 冲销凭证服务(方案A)
|
|
|
* 职责:同事务创建双侧凭证/明细,处理资金三分支、库存回退、原单汇总缓存、售后转凭证取消;
|
|
|
* 不插入负销售单/负采购单。ssh 冲销单功能
|
|
|
+ *
|
|
|
+ * —— 原单明细数量设计(xhGhsOrderItem,冲销必须遵守)——
|
|
|
+ * 花材有大小单位(如扎/支),但每一行明细「只会使用其中一个单位」,不会同时有两个单位数量。
|
|
|
+ * - xhUnitType:0=当前为大单位,1=当前为小单位(dict unitType)
|
|
|
+ * - xhNum:当前单位下的数量(唯一规范数量字段)
|
|
|
+ * - num / bigNum / smallNum:历史/非规范字段,冲销校验与累计不要使用
|
|
|
+ * 冲销明细 num、原单 forwardNum 均按 xhNum 同口径累计;回库存时再按 xhUnitType+ratio 换算。
|
|
|
*/
|
|
|
class ForwardService extends BaseService
|
|
|
{
|
|
|
@@ -436,7 +443,7 @@ class ForwardService extends BaseService
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 从售后明细生成冲销明细
|
|
|
+ * 从售后明细生成冲销明细(数量只用 xhNum + xhUnitType)
|
|
|
*/
|
|
|
protected static function buildItemsFromRefund($refund)
|
|
|
{
|
|
|
@@ -447,21 +454,17 @@ class ForwardService extends BaseService
|
|
|
return [];
|
|
|
}
|
|
|
$items = [];
|
|
|
- $unitSmall = dict::getDict('unitType', 'small');
|
|
|
foreach ($list as $row) {
|
|
|
- $unitType = intval($row->xhUnitType ?? 0);
|
|
|
$xhNum = bcadd((string)($row->xhNum ?? '0'), '0', 2);
|
|
|
- $itemNum = bcadd((string)($row->itemNum ?? '0'), '0', 2);
|
|
|
- $bigNum = $unitType === $unitSmall ? '0' : $xhNum;
|
|
|
- $smallNum = $unitType === $unitSmall ? $xhNum : '0';
|
|
|
$items[] = [
|
|
|
'productId' => intval($row->productId ?? 0),
|
|
|
'orderItemId' => intval($row->orderItemId ?? 0),
|
|
|
'itemId' => intval($row->itemId ?? 0),
|
|
|
'name' => (string)($row->name ?? ''),
|
|
|
- 'num' => $itemNum,
|
|
|
- 'bigNum' => $bigNum,
|
|
|
- 'smallNum' => $smallNum,
|
|
|
+ 'num' => $xhNum,
|
|
|
+ 'xhNum' => $xhNum,
|
|
|
+ 'xhUnitType' => intval($row->xhUnitType ?? 0),
|
|
|
+ 'ratio' => bcadd((string)($row->ratio ?? '1'), '0', 2),
|
|
|
'unitPrice' => bcadd((string)($row->xhUnitPrice ?? '0'), '0', 2),
|
|
|
'price' => bcadd((string)($row->xhUnitPrice ?? '0'), '0', 2),
|
|
|
'amount' => bcadd((string)($row->xhPrice ?? '0'), '0', 2),
|
|
|
@@ -471,7 +474,8 @@ class ForwardService extends BaseService
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 规范化明细:补全名称/数量/金额,并校验原单明细上限
|
|
|
+ * 规范化明细:数量只认当前单位 xhNum,不用 num/bigNum/smallNum。
|
|
|
+ * 入参优先 raw.xhNum / raw.num(前端当前单位数量);有原单时单位类型以原单 xhUnitType 为准。
|
|
|
*/
|
|
|
protected static function normalizeItems($items, $order)
|
|
|
{
|
|
|
@@ -485,6 +489,7 @@ class ForwardService extends BaseService
|
|
|
$orderItemMap[intval($oi->id)] = $oi;
|
|
|
}
|
|
|
}
|
|
|
+ $unitSmall = dict::getDict('unitType', 'small');
|
|
|
$result = [];
|
|
|
foreach ($items as $raw) {
|
|
|
$productId = intval($raw['productId'] ?? 0);
|
|
|
@@ -501,31 +506,44 @@ class ForwardService extends BaseService
|
|
|
$product = ProductClass::getById($productId, true);
|
|
|
$name = $product->name ?? '';
|
|
|
}
|
|
|
- $bigNum = bcadd((string)($raw['bigNum'] ?? '0'), '0', 2);
|
|
|
- $smallNum = bcadd((string)($raw['smallNum'] ?? '0'), '0', 2);
|
|
|
+
|
|
|
+ // 当前单位类型:有原单跟原单;自由冲销用入参
|
|
|
+ $xhUnitType = !empty($orderItem)
|
|
|
+ ? intval($orderItem->xhUnitType ?? 0)
|
|
|
+ : intval($raw['xhUnitType'] ?? 0);
|
|
|
$ratio = bcadd((string)($orderItem->ratio ?? ($raw['ratio'] ?? '1')), '0', 2);
|
|
|
if (bccomp($ratio, '0', 2) <= 0) {
|
|
|
$ratio = '1';
|
|
|
}
|
|
|
- // 有大小单位时按售后口径换算 itemNum;否则用入参 num
|
|
|
- if (bccomp($bigNum, '0', 2) > 0 || bccomp($smallNum, '0', 2) > 0) {
|
|
|
- $num = ProductClass::mergeItemNum($bigNum, $smallNum, $ratio);
|
|
|
- } else {
|
|
|
- $num = bcadd((string)($raw['num'] ?? '0'), '0', 2);
|
|
|
- }
|
|
|
- if (bccomp($num, '0', 2) <= 0) {
|
|
|
+
|
|
|
+ // 规范数量:只取当前单位数量(xhNum),忽略 bigNum/smallNum/num 等非规范字段
|
|
|
+ $xhNum = bcadd((string)($raw['xhNum'] ?? ($raw['num'] ?? '0')), '0', 2);
|
|
|
+ if (bccomp($xhNum, '0', 2) <= 0) {
|
|
|
util::fail('冲销数量必须大于0');
|
|
|
}
|
|
|
+
|
|
|
+ // 回库存:大单位直接加 xhNum;小单位按 ratio 换算成库存小数
|
|
|
+ if ($xhUnitType === $unitSmall) {
|
|
|
+ $stockNum = ProductClass::mergeItemNum(0, $xhNum, $ratio);
|
|
|
+ $bigNum = '0';
|
|
|
+ $smallNum = $xhNum;
|
|
|
+ } else {
|
|
|
+ $stockNum = ProductClass::mergeItemNum($xhNum, 0, $ratio);
|
|
|
+ $bigNum = $xhNum;
|
|
|
+ $smallNum = '0';
|
|
|
+ }
|
|
|
+
|
|
|
$unitPrice = bcadd((string)($raw['unitPrice'] ?? ($raw['price'] ?? '0')), '0', 2);
|
|
|
$price = bcadd((string)($raw['price'] ?? $unitPrice), '0', 2);
|
|
|
$amount = bcadd((string)($raw['amount'] ?? '0'), '0', 2);
|
|
|
if (bccomp($amount, '0', 2) <= 0) {
|
|
|
- $baseNum = bccomp($bigNum, '0', 2) > 0 ? $bigNum : $num;
|
|
|
- $amount = bcmul($baseNum, $price, 2);
|
|
|
+ $amount = bcmul($xhNum, $price, 2);
|
|
|
}
|
|
|
if (!empty($orderItem)) {
|
|
|
- $remain = bcsub((string)($orderItem->itemNum ?? '0'), (string)($orderItem->forwardNum ?? '0'), 2);
|
|
|
- if (bccomp($num, $remain, 2) === 1) {
|
|
|
+ // 可冲销量 = 原单 xhNum − 已冲销 forwardNum(forwardNum 也按 xhNum 累计)
|
|
|
+ $originNum = bcadd((string)($orderItem->xhNum ?? '0'), '0', 2);
|
|
|
+ $remain = bcsub($originNum, (string)($orderItem->forwardNum ?? '0'), 2);
|
|
|
+ if (bccomp($xhNum, $remain, 2) === 1) {
|
|
|
util::fail(($name ?: '花材') . '冲销数量超过可冲销量');
|
|
|
}
|
|
|
}
|
|
|
@@ -534,7 +552,10 @@ class ForwardService extends BaseService
|
|
|
'orderItemId' => $orderItemId,
|
|
|
'itemId' => intval($raw['itemId'] ?? ($orderItem->itemId ?? 0)),
|
|
|
'name' => $name,
|
|
|
- 'num' => $num,
|
|
|
+ 'num' => $xhNum,
|
|
|
+ 'xhNum' => $xhNum,
|
|
|
+ 'xhUnitType' => $xhUnitType,
|
|
|
+ 'stockNum' => $stockNum,
|
|
|
'bigNum' => $bigNum,
|
|
|
'smallNum' => $smallNum,
|
|
|
'unitPrice' => $unitPrice,
|
|
|
@@ -561,7 +582,8 @@ class ForwardService extends BaseService
|
|
|
}
|
|
|
$customName = $custom->name ?? '';
|
|
|
foreach ($items as $it) {
|
|
|
- $itemNum = $it['num'];
|
|
|
+ // 回库存必须用换算后的库存数量,不能直接用 xhNum 展示数量
|
|
|
+ $itemNum = $it['stockNum'] ?? $it['num'];
|
|
|
if (bccomp($itemNum, '0', 2) <= 0) {
|
|
|
continue;
|
|
|
}
|
|
|
@@ -585,7 +607,7 @@ class ForwardService extends BaseService
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 累加原销售明细 forwardNum
|
|
|
+ * 累加原销售明细 forwardNum(与 xhNum 同单位:当前下单单位数量)
|
|
|
*/
|
|
|
protected static function increaseOrderItemForwardNum($items)
|
|
|
{
|
|
|
@@ -598,13 +620,14 @@ class ForwardService extends BaseService
|
|
|
if (empty($oi)) {
|
|
|
continue;
|
|
|
}
|
|
|
- $oi->forwardNum = bcadd((string)($oi->forwardNum ?? '0'), $it['num'], 2);
|
|
|
+ $addNum = $it['xhNum'] ?? $it['num'];
|
|
|
+ $oi->forwardNum = bcadd((string)($oi->forwardNum ?? '0'), (string)$addNum, 2);
|
|
|
$oi->save(false, ['forwardNum']);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 累加采购明细 forwardNum(按平台 itemId 对齐)
|
|
|
+ * 累加采购明细 forwardNum(按平台 itemId 对齐;数量同 xhNum 口径)
|
|
|
*/
|
|
|
protected static function increaseCgItemForwardNum($items, $cgItemMap)
|
|
|
{
|
|
|
@@ -618,7 +641,8 @@ class ForwardService extends BaseService
|
|
|
if (empty($ci)) {
|
|
|
continue;
|
|
|
}
|
|
|
- $ci->forwardNum = bcadd((string)($ci->forwardNum ?? '0'), $it['num'], 2);
|
|
|
+ $addNum = $it['xhNum'] ?? $it['num'];
|
|
|
+ $ci->forwardNum = bcadd((string)($ci->forwardNum ?? '0'), (string)$addNum, 2);
|
|
|
$ci->save(false, ['forwardNum']);
|
|
|
}
|
|
|
}
|