208 lines
7.4 KiB
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;
|
|
}
|
|
}
|