CaiWuXiTong/modules/EcommerceFinance/Repositories/SupplierManagementMirrorRepository.php

154 lines
7.0 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\Repositories;
use Illuminate\Database\Query\Builder;
use Modules\EcommerceFinance\Services\BusinessMirrorDatasetRegistry;
use RuntimeException;
/** 工作平台供应商主档案,HTTP 请求仅访问共享镜像。 */
class SupplierManagementMirrorRepository
{
public const DATASET = 'jiansun.dbo.js_supplier_View';
public const RELATED = [
'contracts' => 'jiansun.dbo.js_supplier_contract_View',
'contacts' => 'jiansun.dbo.js_supplier_linkers',
'payments' => 'jiansun.dbo.js_supplier_payinfo',
];
public const COLUMNS = [
'sourcefrom' => '数据来源', 'coopersgn' => '是否合作', 'scmcode' => '供应商代码',
'scmname' => '供应商名称', 'scmtype' => '供应商类型', 'tradebody' => '合同主体',
'company' => '签订公司', 'enterpriseType' => '企业类型', 'creditcode' => '社会信用代码',
'handlePerson' => '电子合同经办人姓名', 'accountbankno' => '电子合同经办人账号',
'legalPerson' => '法人姓名', 'corpmobile' => '法人电话', 'paycyclesgn' => '结算周期',
'tradebtime' => '合同开始时间', 'tradeetime' => '合同截止时间',
'endTimeA' => '罚款终止日期', 'endTimeB' => '赔付终止日期',
'finishTimeA' => '终止合作日期', 'finishTimeB' => '重启合作日期',
'undefined2' => '板材提供方', 'dsper' => '分配人', 'reconciliter' => '对账会计',
'levelname' => '级别', 'linkerprovience' => '联系人省', 'linkercity' => '联系人市',
'linkerarea' => '联系人区', 'linkeradd' => '联系人详细地址', 'memo' => '备注',
'buyer' => '采购', 'craftType' => '工艺类型', 'outline' => '生产线',
'capacity' => '工厂产能', 'freereason' => '免罚原因', 'region' => '所属区域',
'sindou' => '叫货周期',
];
public function __construct(
private readonly BusinessMirrorDatasetRegistry $datasets,
private readonly GenericBusinessMirrorRepository $mirror,
) {
}
public function ready(): bool
{
return $this->mirror->ready($this->datasets->get(self::DATASET));
}
public function state(): ?array
{
return $this->mirror->state($this->datasets->get(self::DATASET));
}
/** 正式供应商签署资料;accountbankno 是上游电子合同账号,handlePerson 是实名姓名。 */
public function signingOptions(): array
{
if (! $this->signingReady()) return [];
return $this->mirror->connection()->table($this->datasets->get(self::DATASET)->targetTable())
->orderBy('scmname')->orderBy('Id')
->get(['Id', 'scmname', 'scmcode', 'tradebody', 'accountbankno', 'handlePerson'])
->map(static fn (object $row): array => [
'id' => (int) $row->Id, 'value' => trim((string) $row->scmname),
'code' => trim((string) $row->scmcode), 'company' => trim((string) $row->tradebody),
'account' => trim((string) $row->accountbankno), 'operator' => trim((string) $row->handlePerson),
])->all();
}
public function signingSupplier(int $id): ?object
{
if (! $this->signingReady()) return null;
return $this->mirror->connection()->table($this->datasets->get(self::DATASET)->targetTable())
->where('Id', $id)->first(['Id', 'scmname', 'tradebody', 'accountbankno', 'handlePerson']);
}
private function signingReady(): bool
{
return $this->ready() && $this->mirror->connection()->getSchemaBuilder()
->hasColumn($this->datasets->get(self::DATASET)->targetTable(), 'accountbankno');
}
public function paginate(array $filters, int $page, int $limit): array
{
$query = $this->query($filters);
return [
'total' => (clone $query)->count(),
'rows' => $query->orderBy('scmname')->orderBy('Id')
->forPage(max($page, 1), min(max($limit, 1), 100))->get()->all(),
];
}
/** 全部筛选结果,按上游稳定键小批读取,保留编码/账号文本。 */
public function exportRows(array $filters): \Generator
{
$lastId = 0;
do {
$rows = $this->query($filters)->where('Id', '>', $lastId)->orderBy('Id')->limit(500)->get();
foreach ($rows as $row) {
$lastId = (int) $row->Id;
yield $row;
}
} while ($rows->count() === 500);
}
/** 详情以已选供应商关联,不能在未选择时显示全体账户或合同。 */
public function details(object $supplier, string $tab, int $page, int $limit): array
{
if (! array_key_exists($tab, self::RELATED)) {
return ['ready' => false, 'rows' => [], 'total' => 0,
'message' => '工作平台操作日志的供应商关联尚未确认,暂不展示。'];
}
$dataset = $this->datasets->get(self::RELATED[$tab]);
if (! $this->mirror->ready($dataset)) {
return ['ready' => false, 'rows' => [], 'total' => 0, 'message' => '该详情资料尚未完成首次同步。'];
}
$query = $this->mirror->connection()->table($dataset->targetTable());
if ($tab === 'contracts') {
if (trim((string) $supplier->tradebody) === '' || trim((string) $supplier->company) === '') {
return ['ready' => true, 'rows' => [], 'total' => 0,
'message' => '该供应商未维护合同主体或签订公司,无法准确匹配合同。'];
}
$query->where('tradebody', $supplier->tradebody)->where('company', $supplier->company);
$query->orderByDesc('sendTime')->orderBy('id');
} else {
if (trim((string) $supplier->scmname) === '') {
return ['ready' => true, 'rows' => [], 'total' => 0, 'message' => '该供应商未维护名称,无法准确匹配详情。'];
}
$query->where('scmname', $supplier->scmname)->orderBy('Id');
}
return ['ready' => true, 'total' => (clone $query)->count(),
'rows' => $query->forPage(max($page, 1), min(max($limit, 1), 100))->get()->all(),
'message' => null];
}
private function query(array $filters): Builder
{
if (! $this->ready()) {
throw new RuntimeException('supplier_management_mirror_not_ready');
}
$query = $this->mirror->connection()->table($this->datasets->get(self::DATASET)->targetTable());
foreach (['supplier_name' => 'scmname', 'buyer' => 'buyer'] as $key => $column) {
if (($filters[$key] ?? '') !== '') {
$value = '%' . str_replace(['!', '%', '_'], ['!!', '!%', '!_'], $filters[$key]) . '%';
$query->whereRaw($column . " LIKE ? ESCAPE '!'", [$value]);
}
}
if (in_array($filters['cooperation_status'] ?? '', ['1', '2'], true)) {
$query->where('coopersgn', (int) $filters['cooperation_status']);
}
return $query;
}
}