CaiWuXiTong/modules/EcommerceFinance/Repositories/AlibabaAccountBalanceRepository.php

105 lines
3.9 KiB
PHP

<?php
namespace Modules\EcommerceFinance\Repositories;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Database\DatabaseManager;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\Schema;
class AlibabaAccountBalanceRepository
{
public const TABLE = 'alibaba_account_balance_snapshots';
private readonly ConnectionInterface $connection;
public function __construct(DatabaseManager $database)
{
$this->connection = $database->connection(
(string) config('upstream_mirrors.connection', 'business_mirror')
);
}
public function usesBusinessMirror(): bool
{
return Schema::connection($this->connection->getName())->hasTable(self::TABLE);
}
/** @return string[] */
public function storeOptions(): array
{
if (! $this->usesBusinessMirror()) {
return [];
}
return $this->connection->table(self::TABLE)
->whereNotNull('store_name')
->where('store_name', '<>', '')
->distinct()
->orderBy('store_name')
->pluck('store_name')
->map(static fn (mixed $value): string => (string) $value)
->all();
}
/** @return array{rows:array<int,array<string,mixed>>,total:int} */
public function paginateMonthlyBalances(
?string $storeName = null,
?string $month = null,
int $page = 1,
int $pageSize = 25,
): array {
if (! $this->usesBusinessMirror()) {
return ['rows' => [], 'total' => 0];
}
$page = max($page, 1);
$pageSize = min(max($pageSize, 1), 5000);
$query = $this->connection->table(self::TABLE);
$this->applyFilters($query, $storeName, $month);
$total = (clone $query)->count();
if ($total === 0) {
return ['rows' => [], 'total' => 0];
}
$rows = $query
->orderByDesc('balance_date')
->orderBy('store_name')
->forPage($page, $pageSize)
->get([
'balance_date', 'store_name', 'opening_balance', 'income_total',
'expense_total', 'closing_balance', 'system_closing_balance',
'balance_difference', 'difference_reason', 'verification_status', 'notes',
])
->map(static fn (object $row): array => [
'date' => (string) $row->balance_date,
'store_name' => (string) $row->store_name,
'opening_balance' => $row->opening_balance === null ? null : (float) $row->opening_balance,
'income_total' => $row->income_total === null ? null : (float) $row->income_total,
'expense_total' => $row->expense_total === null ? null : (float) $row->expense_total,
'closing_balance' => $row->closing_balance === null ? null : (float) $row->closing_balance,
'system_closing_balance' => $row->system_closing_balance === null ? null : (float) $row->system_closing_balance,
'balance_difference' => $row->balance_difference === null ? null : (float) $row->balance_difference,
'difference_reason' => (string) ($row->difference_reason ?? ''),
'verification_status' => (string) ($row->verification_status ?? ''),
'notes' => (string) ($row->notes ?? ''),
])
->all();
return ['rows' => $rows, 'total' => $total];
}
private function applyFilters(Builder $query, ?string $storeName, ?string $month): void
{
if ($storeName !== null && $storeName !== '') {
$query->where('store_name', $storeName);
}
if ($month !== null && preg_match('/^\d{4}-\d{2}$/', $month) === 1) {
$query->where('balance_date', '>=', $month . '-01')
->where('balance_date', '<', date('Y-m-d', strtotime($month . '-01 +1 month')));
}
}
}