105 lines
3.9 KiB
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')));
|
|
}
|
|
}
|
|
}
|