diff --git a/app/Console/Commands/SyncStoreReceiptProductCost.php b/app/Console/Commands/SyncStoreReceiptProductCost.php index d100f584..351cdfbd 100644 --- a/app/Console/Commands/SyncStoreReceiptProductCost.php +++ b/app/Console/Commands/SyncStoreReceiptProductCost.php @@ -210,13 +210,19 @@ class SyncStoreReceiptProductCost extends Command $warehouse = ''; } } - $lines[$core][] = [ - // 月加权平均单价表里的商品编码统一大写,订单侧可能小写,统一成大写再比。 - 'sku' => mb_strtoupper($sku), - 'qty' => $qty, - 'amount' => $amount, - 'warehouse' => $warehouse, - ]; + // 组合装条码(ZH-条码-数量-条码-数量)按子订单拆成组件行: + // 一个订单有几个发货仓库、商品编码、数量就分开列,组件数量 = 明细数量 × 组件倍数。 + // 解析不了的组合条码(条码被截断等)保持原样,避免丢行。 + foreach (self::expandComboSku($sku, $qty) as [$code, $codeQty, $isComponent]) { + $lines[$core][] = [ + // 月加权平均单价表里的商品编码统一大写,订单侧可能小写,统一成大写再比。 + 'sku' => mb_strtoupper($code), + 'qty' => $codeQty, + // 组合装明细金额对应整包,拆到组件后不再参与「数量×单价 vs 明细金额」校验。 + 'amount' => $isComponent ? 0.0 : $amount, + 'warehouse' => $warehouse, + ]; + } } } $this->info('订单侧命中核心单号:' . count($lines)); @@ -391,6 +397,50 @@ class SyncStoreReceiptProductCost extends Command return array_values($aggregated); } + /** + * 组合装条码拆组件:聚水潭的组合装 sku 形如 + * ZH-<条码>-<数量>[-<条码>-<数量>...] + * 条码本身含横杠,所以按「纯数字段」识别数量,再按组件展开。 + * + * 返回 [条码, 数量, 是否组件];非组合装或解析失败时返回原条码 / 原数量。 + * + * @return list + */ + private static function expandComboSku(string $sku, float $quantity): array + { + if (! str_starts_with(mb_strtoupper($sku), 'ZH-')) { + return [[$sku, $quantity, false]]; + } + + $parts = explode('-', substr($sku, 3)); + $components = []; + $buffer = []; + foreach ($parts as $part) { + if ($part === '') { + return [[$sku, $quantity, false]]; + } + if (preg_match('/^\d+(\.\d+)?$/', $part) === 1) { + if ($buffer === []) { + return [[$sku, $quantity, false]]; + } + $components[] = [implode('-', $buffer), (float) $part]; + $buffer = []; + continue; + } + $buffer[] = $part; + } + if ($buffer !== [] || $components === []) { + return [[$sku, $quantity, false]]; + } + + $expanded = []; + foreach ($components as [$code, $multiplier]) { + $expanded[] = [$code, $quantity * $multiplier, true]; + } + + return $expanded; + } + /** * 仓库映射表:发货仓库 → 仓库简称。 *