82 lines
4.3 KiB
PHP
82 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace Modules\EcommerceFinance\View;
|
|
|
|
use Illuminate\Pagination\LengthAwarePaginator;
|
|
use Modules\EcommerceFinance\Repositories\SupplierAccessoryFreightRepository;
|
|
use Modules\EcommerceFinance\Services\SupplierAccessoryFreightMatcher;
|
|
|
|
class SupplierAccessoryFreightPageData
|
|
{
|
|
public const TITLE = '新河北仓、曹县仓配件运费扣除明细';
|
|
public const TEXT_FILTERS = ['trade_no' => '交易单号', 'express_no' => '快递单号', 'supplier_name' => '供应商', 'normalized_barcode' => '处理后条形码', 'province' => '联系人省'];
|
|
public const COLUMNS = ['state' => '扣款状态', 'trade_no' => '交易单号', 'express_no' => '快递单号', 'courier' => '快递名称', 'ship_time' => '发货时间', 'barcode' => '原始条形码', 'normalized_barcode' => '处理后条形码', 'product_name' => '商品名称', 'supplier_name' => '供应商', 'province' => '联系人省', 'freight' => '配件运费(元)', 'deduction' => '扣款金额(元)', 'reason' => '说明'];
|
|
|
|
public function exportColumns(): array
|
|
{
|
|
$requested = request()->query('columns');
|
|
if ($requested === null) return self::COLUMNS;
|
|
abort_unless(is_string($requested) && strlen($requested) <= 500, 422, '导出列无效。');
|
|
$keys = explode(',', $requested);
|
|
abort_unless($keys !== [] && count($keys) === count(array_unique($keys)) && array_diff($keys, array_keys(self::COLUMNS)) === [], 422, '导出列无效。');
|
|
return array_replace(array_flip($keys), array_intersect_key(self::COLUMNS, array_flip($keys)));
|
|
}
|
|
|
|
public function __construct(private readonly SupplierAccessoryFreightRepository $repository) {}
|
|
|
|
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, '请选择有效业务月份。');
|
|
$state = request()->query('state', 'ready');
|
|
abort_unless(is_string($state) && in_array($state, ['all', ...array_keys(SupplierAccessoryFreightMatcher::STATES)], true), 422, '扣款状态无效。');
|
|
$filters = compact('month', 'state');
|
|
foreach (self::TEXT_FILTERS as $key => $label) {
|
|
$value = request()->query($key, '');
|
|
abort_unless(is_string($value) && mb_strlen($value) <= 200, 422, '筛选条件格式无效。');
|
|
$filters[$key] = trim($value);
|
|
}
|
|
$filters['province'] = match ($filters['province']) { '山东省' => '山东', '河北省' => '河北', default => $filters['province'] };
|
|
return $filters;
|
|
}
|
|
|
|
public function rows(array $filters): \Generator
|
|
{
|
|
foreach ($this->repository->rows($filters['month']) as $row) {
|
|
foreach (self::TEXT_FILTERS as $key => $label) {
|
|
if (($filters[$key] ?? '') !== '' && mb_stripos((string) ($row[$key] ?? ''), $filters[$key]) === false) continue 2;
|
|
}
|
|
yield $row;
|
|
}
|
|
}
|
|
|
|
public function page(): array
|
|
{
|
|
$filters = $this->filters();
|
|
$page = max(1, (int) request('page', 1));
|
|
$summary = ['all' => 0, 'ready' => 0, 'excluded' => 0, 'pending' => 0, 'amount' => 0];
|
|
$items = [];
|
|
$total = 0;
|
|
$error = null;
|
|
try {
|
|
foreach ($this->rows($filters) as $row) {
|
|
$summary['all']++;
|
|
$summary[$row['state']]++;
|
|
$summary['amount'] += $row['deduction_cents'];
|
|
if ($filters['state'] !== 'all' && $filters['state'] !== $row['state']) continue;
|
|
if ($total >= ($page - 1) * 50 && count($items) < 50) $items[] = $row;
|
|
$total++;
|
|
}
|
|
} catch (\Throwable $exception) {
|
|
report($exception);
|
|
$error = '发货、商品或供应商资料暂时无法读取,或尚未完成同步,请稍后重试。';
|
|
$summary = array_fill_keys(array_keys($summary), 0);
|
|
$items = [];
|
|
$total = 0;
|
|
}
|
|
return ['view' => 'business.pages.supplier-payables.accessory-freight-deductions',
|
|
'freightFilters' => $filters, 'freightSummary' => $summary, 'freightError' => $error,
|
|
'freightRows' => new LengthAwarePaginator($items, $total, 50, $page, ['path' => request()->url(), 'query' => request()->except('page')])];
|
|
}
|
|
}
|