接手 sumu 本地任务,复用既有只读 Repository 契约,将赔偿明细切换到 dbo.fys_supplierPaymentSummary,并按附件保留五列表头。
111 lines
4.1 KiB
PHP
111 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\EcommerceFinance;
|
|
|
|
use Modules\EcommerceFinance\Repositories\SupplierPayableRepository;
|
|
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery;
|
|
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQueryFactory;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class SupplierPayableRepositoryTest extends TestCase
|
|
{
|
|
public function test_compensation_queries_use_the_supplier_payment_summary_contract(): void
|
|
{
|
|
$query = $this->createMock(UpstreamReadOnlyQuery::class);
|
|
$bindings = ['%Factory\\%\\_%', '2026-07', '2026-08'];
|
|
|
|
$query->expects($this->once())
|
|
->method('scalar')
|
|
->with(
|
|
$this->callback(function (string $sql): bool {
|
|
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
|
|
$this->assertStringContainsString('[dbo].[fys_supplierPaymentSummary]', $sql);
|
|
$this->assertStringContainsString('[Totalindemnity] <> 0', $sql);
|
|
|
|
return true;
|
|
}),
|
|
$bindings,
|
|
)
|
|
->willReturn(1);
|
|
$query->expects($this->once())
|
|
->method('select')
|
|
->with(
|
|
$this->callback(function (string $sql): bool {
|
|
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
|
|
$this->assertStringContainsString('[Totalindemnity] AS decimal(18,2)', $sql);
|
|
$this->assertStringContainsString('[remarks] AS remark', $sql);
|
|
$this->assertStringContainsString('OFFSET 25 ROWS FETCH NEXT 25 ROWS ONLY', $sql);
|
|
$this->assertStringNotContainsString('fys_paper_factory_compensation_detail', $sql);
|
|
|
|
return true;
|
|
}),
|
|
$bindings,
|
|
)
|
|
->willReturn([[
|
|
'month' => '2026-07',
|
|
'supplier' => 'Factory%_',
|
|
'amount' => '12.50',
|
|
'reason' => 'Reason',
|
|
'remark' => 'Remark',
|
|
]]);
|
|
|
|
$result = $this->repository($query)->compensationDetails([
|
|
'supplier' => 'Factory%_',
|
|
'month_from' => '2026-07',
|
|
'month_to' => '2026-08',
|
|
], 2, 25);
|
|
|
|
$this->assertSame(1, $result['total']);
|
|
$this->assertSame(12.5, $result['data'][0]['amount']);
|
|
$this->assertSame('Remark', $result['data'][0]['remark']);
|
|
}
|
|
|
|
public function test_compensation_summary_and_options_are_bounded_read_only_queries(): void
|
|
{
|
|
$query = $this->createMock(UpstreamReadOnlyQuery::class);
|
|
$query->expects($this->once())
|
|
->method('first')
|
|
->with(
|
|
$this->callback(function (string $sql): bool {
|
|
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
|
|
$this->assertStringContainsString('SUM([Totalindemnity])', $sql);
|
|
|
|
return true;
|
|
}),
|
|
[],
|
|
)
|
|
->willReturn(['total_amount' => '20.25', 'total_count' => '2']);
|
|
$query->expects($this->once())
|
|
->method('select')
|
|
->with($this->callback(function (string $sql): bool {
|
|
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
|
|
$this->assertStringContainsString('DISTINCT TOP 200', $sql);
|
|
|
|
return true;
|
|
}))
|
|
->willReturn([['value' => 'Supplier A']]);
|
|
|
|
$repository = $this->repository($query);
|
|
|
|
$this->assertSame(
|
|
['totalAmount' => 20.25, 'totalCount' => 2],
|
|
$repository->compensationDetailSummary([]),
|
|
);
|
|
$this->assertSame(
|
|
['suppliers' => ['Supplier A']],
|
|
$repository->filterOptionsForCompensation(),
|
|
);
|
|
}
|
|
|
|
private function repository(UpstreamReadOnlyQuery $query): SupplierPayableRepository
|
|
{
|
|
$factory = $this->createMock(UpstreamReadOnlyQueryFactory::class);
|
|
$factory->expects($this->once())
|
|
->method('forSource')
|
|
->with('jiansun')
|
|
->willReturn($query);
|
|
|
|
return new SupplierPayableRepository($factory);
|
|
}
|
|
}
|