query = $queries->forSource(self::SOURCE); } /** @return array{rows:array>} */ 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>} */ 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} */ 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} */ 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 $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 $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; } }