CaiWuXiTong/modules/EcommerceFinance/Services/PayablesFinalRegistry.php
renshen 8429ad0642 应付款终版货款对账:采购单号后新增「日期」列 (#358)
「月份」后依次为入库单号、采购单号、日期;导入模板/表格/导入/编辑/导出同一套字段,只作用于终版目录。
2026-10-16 22:34:01 +08:00

142 lines
5.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Modules\EcommerceFinance\Services;
use Illuminate\Validation\ValidationException;
/**
* 「终版」目录的按表数据登记:确定每个页签的字段(决定导入模板与表格列)
* 以及数据标题;数据本身独立存放,与基础目录互不影响。
*/
class PayablesFinalRegistry
{
public const SECTION_SUPPLIER = 'supplier-payables-final';
public const SECTION_COURIER = 'courier-payables-final';
/** @var array<string,string> 供应商应付(终版)页签 */
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<string,string> */
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<string,array{label:string,type:string}> */
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<string,array{label:string,type:string}> $fields
* @return array<string,array{label:string,type:string}>
*/
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'] ?? []);
}
}