CaiWuXiTong/tests/Unit/EcommerceFinance/SupplierPayableReportRepositoryTest.php
苏木 87845baa01 fix: 最晚出账时间改为按供应商简称匹配 (#1128)
Co-authored-by: 苏木 <594326199@qq.com>
Co-committed-by: 苏木 <594326199@qq.com>
2026-11-11 21:15:59 +08:00

121 lines
4.9 KiB
PHP

<?php
namespace Tests\Unit\EcommerceFinance;
use Modules\EcommerceFinance\Repositories\SupplierPayableReportRepository;
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery;
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQueryFactory;
use PHPUnit\Framework\TestCase;
class SupplierPayableReportRepositoryTest extends TestCase
{
public function test_board_deductions_use_parameterized_filters_and_overfetch_pagination(): 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].[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']);
}
public function test_latest_modified_times_are_grouped_by_supplier_only(): 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('MAX([modifiedTime])', $sql);
$this->assertStringContainsString('GROUP BY [supplier]', $sql);
$this->assertSame(['供应商甲', '供应商乙'], $bindings);
return [[
'supplier' => '供应商甲',
'modified_at' => '2026-11-09 09:30:00',
]];
},
);
$result = $this->repository($query)->latestModifiedTimesBySupplier([
'供应商甲',
'供应商乙',
'供应商甲',
'',
]);
$this->assertSame('供应商甲', $result[0]['supplier']);
$this->assertSame('2026-11-09 09:30:00', $result[0]['modified_at']);
}
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);
}
}