CaiWuXiTong/modules/EcommerceFinance/View/AccessoryReshipPageData.php

56 lines
2.8 KiB
PHP

<?php
namespace Modules\EcommerceFinance\View;
use Illuminate\Pagination\LengthAwarePaginator;
use Modules\EcommerceFinance\Repositories\ShippingOrderRepository;
use Modules\EcommerceFinance\Services\AccessoryReshipMatcher;
class AccessoryReshipPageData
{
public function __construct(private ShippingOrderRepository $shipping, private AccessoryReshipMatcher $matcher) {}
public function filters(): array
{
$month = request()->query('month', now()->format('Y-m'));
abort_unless(is_string($month) && preg_match('/^\d{4}-(0[1-9]|1[0-2])$/', $month) && (int) substr($month, 0, 4) >= 2000, 422, '请选择有效业务月份。');
$status = request()->query('match_status', 'matched');
return ['month' => $month, 'match_status' => in_array($status, ['matched', 'unmatched', 'all'], true) ? $status : 'matched'];
}
public function rows(array $filters): \Generator
{
$start = \Carbon\Carbon::createFromFormat('!Y-m', $filters['month']);
foreach ($this->shipping->accessoryReshipBatches($start->format('Y-m-d'), $start->copy()->addMonth()->format('Y-m-d'), $start->copy()->subMonths(2)->format('Y-m-d')) as $batch) {
foreach ($this->matcher->match($batch['accessories'], $batch['originals']) as $row) yield $row;
}
}
public function page(): array
{
$filters = $this->filters();
$page = max(1, (int) request('page', 1));
$summary = ['all' => 0, 'matched' => 0, 'unmatched' => 0, 'amount' => 0, 'invalid_amount' => 0, 'ambiguous' => 0];
$items = []; $total = 0; $error = null;
try {
foreach ($this->rows($filters) as $row) {
$summary['all']++; $summary[$row['status']]++;
if ($row['status'] === 'matched') {
$summary['amount'] += $row['deduction_cents'] ?? 0;
if ($row['deduction_cents'] === null) $summary['invalid_amount']++;
if (count($row['matches']) > 1) $summary['ambiguous']++;
}
if ($filters['match_status'] !== 'all' && $filters['match_status'] !== $row['status']) continue;
if ($total >= ($page - 1) * 50 && count($items) < 50) $items[] = $row;
$total++;
}
} catch (\Throwable $exception) {
report($exception); $error = '发货数据暂时无法读取,请检查数据连接或同步状态后重试。';
$items = []; $total = 0;
$summary = array_fill_keys(array_keys($summary), 0);
}
return ['view' => 'business.pages.courier-payables.accessory-reship-deductions', 'reshipFilters' => $filters, 'reshipSummary' => $summary, 'reshipError' => $error,
'reshipRows' => new LengthAwarePaginator($items, $total, 50, $page, ['path' => request()->url(), 'query' => request()->except('page')])];
}
}