From 9b2edfe1defd01c2e96346c24bb689507b4fef48 Mon Sep 17 00:00:00 2001 From: chenxi Date: Mon, 19 Oct 2026 14:06:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=95=86=E5=93=81=E6=88=90=E6=9C=AC=EF=BC=9A?= =?UTF-8?q?=E7=BB=84=E5=90=88=E8=A3=85=E6=8C=89=E5=AD=90=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E6=8B=86=E6=88=90=E7=BB=84=E4=BB=B6=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 聚水潭组合装 sku 形如 ZH-<条码>-<数量>-<条码>-<数量>,之前整包按一个商品行列出, 月加权/代发价都匹配不到。现在按组件拆分:一个订单有几个发货仓库、商品编码、数量就分开列, 组件数量 = 明细数量 × 组件倍数;解析不了的(条码被截断等)保持原样。 组件行的明细金额按整包处理,不参与「数量×单价 vs 明细金额」校验。 --- .../Commands/SyncStoreReceiptProductCost.php | 64 +++++++++++++++++-- 1 file changed, 57 insertions(+), 7 deletions(-) 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; + } + /** * 仓库映射表:发货仓库 → 仓库简称。 *