CaiWuXiTong/modules/EcommerceFinance/Services/FinanceLedgerShopDirectory.php
92451 6f0c99c3c0 保留无存续主体店铺 (#639)
Co-authored-by: 92451 <924518135@qq.com>
Co-committed-by: 92451 <924518135@qq.com>
2026-10-26 19:39:01 +08:00

131 lines
4.3 KiB
PHP

<?php
namespace Modules\EcommerceFinance\Services;
use Illuminate\Database\DatabaseManager;
use Illuminate\Support\Facades\Schema;
use Modules\EcommerceFinance\Repositories\BusinessInformationMirrorRepository;
use Throwable;
/**
* 财务台账店铺台账的店铺目录。
*
* 平台和 ERP 店铺名称来自店铺维度报表的店铺资料;店铺主体只取当前
* 失效时间为「存续中」的主体期间。财务台账自己的账户和余额字段按 ERP
* 店铺名称合并,避免把报表销量或其他财务字段混入店铺台账。
*/
class FinanceLedgerShopDirectory
{
public function __construct(
private readonly BusinessInformationMirrorRepository $storeInformation,
private readonly StoreReportPeriodBuilder $periods,
private readonly DatabaseManager $databases,
) {
}
/**
* 返回 null 表示店铺维度报表镜像尚未就绪,调用方应回退到财务台账原表。
*
* @return list<array{
* id:int,
* platform:?string,
* shop_name:string,
* company_name:?string,
* account_short:?string,
* status:string,
* payout_account:?string,
* shop_balance:float,
* shop_balance_date:?string,
* remark:?string
* }>|null
*/
public function rows(): ?array
{
try {
$stores = $this->storeInformation->allStores();
} catch (Throwable $exception) {
report($exception);
return null;
}
$openStores = array_values(array_filter(
$stores,
static fn (array $store): bool => in_array(
(string) ($store['store_status'] ?? ''),
['0', '正常'],
true,
) && trim((string) ($store['erp_store_name'] ?? '')) !== '',
));
if ($openStores === []) {
return [];
}
try {
$periods = $this->periods->build($openStores);
} catch (Throwable $exception) {
report($exception);
return null;
}
$financeShops = $this->financeShops();
$rows = [];
foreach ($openStores as $store) {
$erpStoreName = trim((string) ($store['erp_store_name'] ?? ''));
$companyName = null;
foreach ($periods[$erpStoreName] ?? [] as $period) {
// 报表把失效时间为空的最后一个期间显示为「存续中」。
if (($period['expires_at'] ?? null) === null) {
$companyName = $this->nullableString($period['company_name'] ?? null);
}
}
$financeShop = $financeShops[$erpStoreName] ?? null;
$rows[] = [
'id' => (int) ($store['id'] ?? 0),
'platform' => $this->nullableString($store['platform'] ?? null),
'shop_name' => $erpStoreName,
'company_name' => $companyName,
'account_short' => $this->nullableString($financeShop->account_short ?? null),
'status' => '在营',
'payout_account' => $this->nullableString(
$financeShop->payout_account ?? ($store['withdrawal_account'] ?? null),
),
'shop_balance' => round((float) ($financeShop->shop_balance ?? 0), 2),
'shop_balance_date' => $this->nullableString($financeShop->shop_balance_date ?? null),
'remark' => $this->nullableString($financeShop->remark ?? null),
];
}
return $rows;
}
/** @return array<string,object> */
private function financeShops(): array
{
$connection = $this->databases->connection(
(string) config('upstream_mirrors.connection', 'business_mirror'),
);
if (! Schema::connection($connection->getName())->hasTable('fin_shops')) {
return [];
}
return $connection->table('fin_shops')
->get()
->mapWithKeys(static function (object $row): array {
$name = trim((string) ($row->shop_name ?? ''));
return $name === '' ? [] : [$name => $row];
})
->all();
}
private function nullableString(mixed $value): ?string
{
$value = trim((string) $value);
return $value === '' ? null : $value;
}
}