CaiWuXiTong/modules/EcommerceFinance/Repositories/SupplierManagementMirrorRepository.php

144 lines
6.1 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' => '社会信用代码',
'accountbankno' => '电子合同经办人', 'buyer' => '采购人员',
];
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;
}
}