131 lines
4.3 KiB
PHP
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;
|
|
}
|
|
}
|