createMock(UpstreamReadOnlyQuery::class); $query->expects($this->once())->method('select')->willReturnCallback( function (string $sql, array $bindings): array { UpstreamReadOnlyQuery::assertReadOnlySql($sql); $this->assertStringContainsString('[dbo].[finance_boardDeduction]', $sql); $this->assertStringContainsString('OFFSET 2 ROWS FETCH NEXT 3 ROWS ONLY', $sql); $this->assertSame([ '2026-07-01', '2026-07-02', '%Factory\\%\\_%', '%Press%', '%Normal%', '%Board%', '%AP-1%', ], $bindings); return [[ 'received_quantity' => '2', 'unit_price' => '10.50', 'amount' => '', ]]; }, ); $result = $this->repository($query)->boardDeductions([ 'stock_in_date' => '2026-07-01', 'stock_out_date' => '2026-07-02', 'furniture_factory' => 'Factory%_', 'lamination_factory' => 'Press', 'deduction_type' => 'Normal', 'material_name' => 'Board', 'claim_number' => 'AP-1', ], 2, 2); $this->assertSame(2.0, $result['rows'][0]['received_quantity']); $this->assertSame(10.5, $result['rows'][0]['unit_price']); $this->assertNull($result['rows'][0]['amount']); } public function test_supplier_payables_use_fixed_fields_and_parameterized_filters(): void { $query = $this->createMock(UpstreamReadOnlyQuery::class); $query->expects($this->once())->method('select')->willReturnCallback( function (string $sql, array $bindings): array { UpstreamReadOnlyQuery::assertReadOnlySql($sql); $this->assertStringContainsString('[dbo].[fys_supplierPaymentSummary]', $sql); $this->assertStringContainsString('[billRemaining] AS supplier_balance', $sql); $this->assertStringContainsString('OFFSET 2 ROWS FETCH NEXT 3 ROWS ONLY', $sql); $this->assertSame(['2026-07', '%Supplier%', '%Checker%', '%Monthly%'], $bindings); return [[ 'should_pay' => '100.00', 'supplier_balance' => null, 'is_payment' => 1, ]]; }, ); $result = $this->repository($query)->supplierPayables([ 'month' => '2026-07', 'supplier' => 'Supplier', 'checker' => 'Checker', 'settlement_method' => 'Monthly', ], 2, 2); $this->assertSame(100.0, $result['rows'][0]['should_pay']); $this->assertNull($result['rows'][0]['supplier_balance']); $this->assertTrue($result['rows'][0]['is_payment']); } private function repository(UpstreamReadOnlyQuery $query): SupplierPayableReportRepository { $factory = $this->createMock(UpstreamReadOnlyQueryFactory::class); $factory->expects($this->once())->method('forSource')->with('jiansun')->willReturn($query); return new SupplierPayableReportRepository($factory); } }