CaiWuXiTong/modules/EcommerceFinance/Repositories/SupplierPayableReportRepository.php

208 lines
7.4 KiB
PHP

<?php
namespace Modules\EcommerceFinance\Repositories;
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery;
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQueryFactory;
class SupplierPayableReportRepository
{
private const SOURCE = 'jiansun';
private readonly UpstreamReadOnlyQuery $query;
public function __construct(UpstreamReadOnlyQueryFactory $queries)
{
$this->query = $queries->forSource(self::SOURCE);
}
/** @return array{rows:array<int,array<string,mixed>>} */
public function boardDeductions(array $filters, int $page, int $limit): array
{
[$whereSql, $bindings] = $this->boardWhere($filters);
[$offset, $fetch] = $this->pageWindow($page, $limit);
$sql = 'SELECT '
. '[id] AS id, '
. 'CONVERT(varchar(10), [inDate], 23) AS stock_in_date, '
. 'CONVERT(varchar(10), [deliveryDate], 23) AS stock_out_date, '
. '[giveSupplier] AS furniture_factory, '
. '[arrSupplier] AS lamination_factory, '
. '[name] AS deduction_type, '
. '[number] AS specification, '
. '[plainName] AS material_name, '
. '[inCount] AS received_quantity, '
. '[priceA] AS unit_price, '
. '[moneyA] AS amount, '
. 'CAST(NULL AS varchar(10)) AS unit, '
. 'CONVERT(varchar(10), [date], 23) AS batch_date, '
. '[deliveryNo] AS stock_out_number, '
. '[deliveryRemarks] AS stock_out_remark, '
. '[applyNo] AS claim_number, '
. '[numberType] AS number_type, '
. '[sendNo] AS delivery_number '
. 'FROM [dbo].[finance_boardDeduction]'
. $whereSql
. ' ORDER BY [inDate] DESC, [id] DESC'
. " OFFSET {$offset} ROWS FETCH NEXT {$fetch} ROWS ONLY";
return ['rows' => array_map([$this, 'normalizeBoardRow'], $this->query->select($sql, $bindings))];
}
/** @return array{rows:array<int,array<string,mixed>>} */
public function supplierPayables(array $filters, int $page, int $limit): array
{
[$whereSql, $bindings] = $this->payablesWhere($filters);
[$offset, $fetch] = $this->pageWindow($page, $limit);
$sql = 'SELECT '
. '[id] AS id, '
. '[company] AS company, '
. '[supplier] AS supplier, '
. '[checker] AS checker, '
. '[settleway] AS settlement_method, '
. '[ExpFieght] AS express_freight, '
. '[bginMonthPay] AS beginning_payable, '
. '[unpriced] AS unpriced, '
. '[advloan] AS advance_loan, '
. '[loan] AS loan, '
. '[refund] AS refund, '
. '[procurement] AS procurement, '
. '[invoiceDct] AS invoice_deduction, '
. '[boardDct] AS board_deduction, '
. '[specimenDct] AS sample_deduction, '
. '[Totalindemnity] AS total_compensation, '
. '[other] AS other_adjustment, '
. '[supplySup] AS supplier_supplement, '
. '[billRemaining] AS supplier_balance, '
. '[ShouldPay] AS should_pay, '
. '[guessPrice] AS estimated_price, '
. '[toCorporate] AS to_corporate, '
. '[toPrivate] AS to_private, '
. '[factPay] AS actual_pay, '
. '[remarks] AS remarks, '
. '[reason] AS private_reason, '
. '[mark] AS negative_reason, '
. '[Month] AS month, '
. '[depositMoney] AS deposit, '
. '[cashierbypaid] AS cashier_paid, '
. '[isPayment] AS is_payment, '
. 'CONVERT(varchar(19), [createTime], 120) AS created_at, '
. 'CONVERT(varchar(19), [modifiedTime], 120) AS modified_at '
. 'FROM [dbo].[fys_supplierPaymentSummary]'
. $whereSql
. ' ORDER BY [id] DESC'
. " OFFSET {$offset} ROWS FETCH NEXT {$fetch} ROWS ONLY";
return ['rows' => array_map([$this, 'normalizePayableRow'], $this->query->select($sql, $bindings))];
}
/** @return array{0:string,1:array<int,string>} */
private function boardWhere(array $filters): array
{
$where = [];
$bindings = [];
foreach ([
'stock_in_date' => 'inDate',
'stock_out_date' => 'deliveryDate',
] as $filter => $column) {
if (($filters[$filter] ?? '') === '') {
continue;
}
$where[] = "CAST([{$column}] AS date) = ?";
$bindings[] = (string) $filters[$filter];
}
foreach ([
'furniture_factory' => 'giveSupplier',
'lamination_factory' => 'arrSupplier',
'deduction_type' => 'name',
'material_name' => 'plainName',
'claim_number' => 'applyNo',
] as $filter => $column) {
if (($filters[$filter] ?? '') === '') {
continue;
}
$where[] = "[{$column}] LIKE ? ESCAPE '\\'";
$bindings[] = $this->contains((string) $filters[$filter]);
}
return [$where === [] ? '' : ' WHERE ' . implode(' AND ', $where), $bindings];
}
/** @return array{0:string,1:array<int,string>} */
private function payablesWhere(array $filters): array
{
$where = [];
$bindings = [];
if (($filters['month'] ?? '') !== '') {
$where[] = '[Month] = ?';
$bindings[] = (string) $filters['month'];
}
foreach ([
'supplier' => 'supplier',
'checker' => 'checker',
'settlement_method' => 'settleway',
] as $filter => $column) {
if (($filters[$filter] ?? '') === '') {
continue;
}
$where[] = "[{$column}] LIKE ? ESCAPE '\\'";
$bindings[] = $this->contains((string) $filters[$filter]);
}
return [$where === [] ? '' : ' WHERE ' . implode(' AND ', $where), $bindings];
}
/** @return array{0:int,1:int} */
private function pageWindow(int $page, int $limit): array
{
$page = max($page, 1);
$limit = min(max($limit, 1), 100);
return [($page - 1) * $limit, $limit + 1];
}
private function contains(string $value): string
{
return '%' . str_replace(['\\', '%', '_'], ['\\\\', '\\%', '\\_'], trim($value)) . '%';
}
/** @param array<string,mixed> $row */
private function normalizeBoardRow(array $row): array
{
foreach (['received_quantity', 'unit_price', 'amount'] as $field) {
$row[$field] = $this->number($row[$field] ?? null);
}
return $row;
}
/** @param array<string,mixed> $row */
private function normalizePayableRow(array $row): array
{
foreach ([
'express_freight', 'beginning_payable', 'unpriced', 'advance_loan', 'loan',
'refund', 'procurement', 'invoice_deduction', 'board_deduction',
'sample_deduction', 'total_compensation', 'other_adjustment',
'supplier_supplement', 'supplier_balance', 'should_pay', 'estimated_price',
'to_corporate', 'to_private', 'actual_pay', 'deposit', 'cashier_paid',
] as $field) {
$row[$field] = $this->number($row[$field] ?? null);
}
$row['is_payment'] = (bool) ($row['is_payment'] ?? false);
return $row;
}
private function number(mixed $value): ?float
{
return $value === null || $value === '' ? null : (float) $value;
}
}