供应商应付(终版)页签 */ private const SUPPLIER_TITLES = [ 'product-prices' => '商品价格', 'payment-reconciliation' => '货款对账', 'return-reconciliation' => '退货对账', 'invoice-deductions' => '发票扣款', 'board-deductions' => '板材扣款', 'compensation-details' => '赔偿明细', 'advance-details' => '借支明细', 'sample-deductions' => '样品扣款', 'other-adjustments' => '其他扣款补款', 'delivery-unpriced' => '送货未定价', 'return-unpriced' => '退货未定价', 'dropshipping-express' => '代发快递', 'supplier-payables-report' => '供应商应付表', ]; /** 所有终版导入模板都带“月份”列,方便按月导入和查看。 */ private const MONTH_FIELD = ['summary_month' => ['label' => '月份', 'type' => 'month']]; /** * 供应商应付(终版)在基础字段上做的增删(只影响终版目录,基础目录对应列另有口径): * - prepend:紧跟在「月份」后的列; * - remove:去掉的列; * - insert:锚点列之后插入的列(锚点列名 => 列定义); * - append:追加到末尾的列。 * 货款对账在「月份」后补入库单号、采购单号、日期,末尾补未发出、对账人; * 退货对账去掉「快递名称」,在「标题」后插入 wms 配货单号,在「标记多标签」后补创建人。 */ private const SUPPLIER_FIELD_PATCHES = [ 'payment-reconciliation' => [ 'prepend' => [ 'stockNo' => ['label' => '入库单号', 'type' => 'text'], 'purchaseNo' => ['label' => '采购单号', 'type' => 'text'], 'date' => ['label' => '日期', 'type' => 'date'], ], 'append' => [ 'unsent' => ['label' => '未发出', 'type' => 'text'], 'reconciler' => ['label' => '对账人', 'type' => 'text'], ], ], 'return-reconciliation' => [ 'remove' => ['express_name'], 'insert' => [ 'title' => ['wms_pick_no' => ['label' => 'wms配货单号', 'type' => 'text']], 'labels' => ['creator' => ['label' => '创建人', 'type' => 'text']], ], ], ]; public function __construct( private readonly SupplierPayableMaintenanceRegistry $supplier, private readonly ProductPriceWorkbookImporter $productPrices, private readonly CourierPayableFinalRegistry $courier, ) { } public function supports(string $section, string $dataset): bool { return array_key_exists($dataset, $this->titles($section)); } /** @return array */ public function titles(string $section): array { return match ($section) { self::SECTION_SUPPLIER => self::SUPPLIER_TITLES, self::SECTION_COURIER => $this->courier->titles(), default => [], }; } public function title(string $section, string $dataset): string { $titles = $this->titles($section); if (! array_key_exists($dataset, $titles)) { throw ValidationException::withMessages(['dataset' => '不支持该终版目录页面。']); } return $titles[$dataset]; } /** @return array */ public function fields(string $section, string $dataset): array { $this->title($section, $dataset); if ($section === self::SECTION_COURIER) { return self::MONTH_FIELD + $this->courier->fields($dataset); } $fields = $dataset === 'product-prices' ? $this->productPrices->templateFields() : $this->supplier->fields($dataset); return self::MONTH_FIELD + $this->patchSupplierFields($dataset, $fields); } /** * @param array $fields * @return array */ private function patchSupplierFields(string $dataset, array $fields): array { $patch = self::SUPPLIER_FIELD_PATCHES[$dataset] ?? []; foreach ($patch['remove'] ?? [] as $key) { unset($fields[$key]); } $inserts = $patch['insert'] ?? []; if ($inserts !== []) { $ordered = []; foreach ($fields as $key => $definition) { $ordered[$key] = $definition; foreach ($inserts[$key] ?? [] as $insertedKey => $insertedDefinition) { $ordered[$insertedKey] = $insertedDefinition; } } $fields = $ordered; } return ($patch['prepend'] ?? []) + $fields + ($patch['append'] ?? []); } }