47 lines
2.7 KiB
PHP
47 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace Modules\EcommerceFinance\Repositories;
|
|
|
|
use Modules\EcommerceFinance\Services\AccessoryReshipMatcher;
|
|
use Modules\EcommerceFinance\Services\BusinessMirrorDatasetRegistry;
|
|
use Modules\EcommerceFinance\Services\SupplierAccessoryFreightMatcher;
|
|
use RuntimeException;
|
|
|
|
/** 只读现有共享镜像,不使用发货行的历史供应商字段代替商品资料。 */
|
|
class SupplierAccessoryFreightRepository
|
|
{
|
|
public function __construct(
|
|
private readonly ShippingOrderRepository $shipping,
|
|
private readonly BusinessMirrorDatasetRegistry $datasets,
|
|
private readonly GenericBusinessMirrorRepository $mirror,
|
|
private readonly SupplierAccessoryFreightMatcher $matcher,
|
|
) {}
|
|
|
|
public function rows(string $month): \Generator
|
|
{
|
|
$productDataset = $this->datasets->get(ProductCatalogMirrorRepository::DATASET_KEY);
|
|
$supplierDataset = $this->datasets->get(SupplierManagementMirrorRepository::DATASET);
|
|
if (!$this->mirror->ready($productDataset) || !$this->mirror->ready($supplierDataset)) {
|
|
throw new RuntimeException('商品或供应商资料尚未完成首次同步');
|
|
}
|
|
$db = $this->mirror->connection();
|
|
// 供应商档案数量较小,一次读取,批量商品查询避免逐单访问数据库。
|
|
$suppliers = $db->table($supplierDataset->targetTable())->get(['scmname', 'linkerprovience'])
|
|
->groupBy(static fn ($row) => trim((string) $row->scmname))
|
|
->map(static fn ($group) => $group->map(static fn ($row) => (array) $row)->all());
|
|
$start = \Carbon\Carbon::createFromFormat('!Y-m', $month);
|
|
foreach ($this->shipping->accessoryFreightBatches($start->format('Y-m-d'), $start->copy()->addMonth()->format('Y-m-d')) as $batch) {
|
|
$barcodes = array_values(array_unique(array_filter(array_map(static fn ($row) => AccessoryReshipMatcher::barcode((string) ($row['barcode'] ?? '')), $batch), static fn ($value) => $value !== '')));
|
|
$products = $db->table($productDataset->targetTable())->where('sku_type', 'normal')->whereIn('sku_id', $barcodes)
|
|
->get(['sku_id', 'name', 'supplier_name'])->groupBy(static fn ($row) => trim((string) $row->sku_id))
|
|
->map(static fn ($group) => $group->map(static fn ($row) => (array) $row)->all());
|
|
foreach ($batch as $row) {
|
|
$barcode = AccessoryReshipMatcher::barcode((string) ($row['barcode'] ?? ''));
|
|
$candidates = $products->get($barcode, []);
|
|
$supplierName = trim((string) ($candidates[0]['supplier_name'] ?? ''));
|
|
yield $this->matcher->match($row, $candidates, $suppliers->get($supplierName, []));
|
|
}
|
|
}
|
|
}
|
|
}
|