CaiWuXiTong/tests/Feature/Business/SupplierBookkeepingPageTest.php
limeng ed58e8ef43 供应商应付:新增厂家记账,接入聚工单记账工单(2026-09-01 起)
- 复用已登记镜像 jiansun.dbo.jst_workOrderInfo,不新增上游链路
- 口径与聚工单「记账」视图一致:工单类型“记账”,状态待审核/已拒绝/待处理/处理中/已完成,
  记账原因为厂家记账 12 项 + 仓库记账 5 项二级原因,发起时间 >= 2026-09-01;同一工单只取最新一版
- 新页面 供应商应付 → 厂家记账:筛选、记账金额合计、列设置、CSV 导出;首次同步未完成时明确提示
- 镜像索引迁移 (woTypeId, created, Id)

涉及:金额展示(只读)、镜像索引迁移;不涉及权限模型和上游写入。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N5KQeRJaLrbJY9iKNC5veV
2026-10-18 22:27:16 +08:00

91 lines
4.0 KiB
PHP

<?php
namespace Tests\Feature\Business;
use App\Models\Auth\Permission;
use Modules\EcommerceFinance\Repositories\SupplierBookkeepingWorkOrderRepository;
use Tests\Feature\FeatureTestCase;
class SupplierBookkeepingPageTest extends FeatureTestCase
{
private function row(array $patch = []): array
{
$row = array_fill_keys(array_keys(\Modules\EcommerceFinance\View\SupplierBookkeepingPageData::COLUMNS), '');
return array_replace($row, [
'started_at' => '2026-09-05 10:00:00', 'work_order_no' => 'GD614939067', 'initiator' => '梦得',
'bookkeeping_reason' => '厂家记账/孔位错误', 'reason_level_1' => '厂家记账', 'reason_level_2' => '孔位错误',
'bookkeeping_type' => '补偿款项', 'amount' => '382.15', 'actual_paid_amount' => '399.41',
'online_order_no' => '5127787476014026744', 'shop_name' => '淘宝-亿家达家居', 'status' => '待处理',
'supplier' => '彩虹', 'product_code' => "DNZ0134101N24V01\nDNZ0134102N24V01",
'attachment' => 'https://jgd-static.example/a.png', 'work_order_type' => '记账',
], $patch);
}
private function mockRepository(array $rows, string $code = 'ready'): void
{
$repository = \Mockery::mock(SupplierBookkeepingWorkOrderRepository::class);
$repository->shouldReceive('syncStatus')->andReturn(['code' => $code, 'last_succeeded_at' => '2026-10-18 21:00:00']);
$repository->shouldReceive('rows')->andReturn($rows);
$this->app->instance(SupplierBookkeepingWorkOrderRepository::class, $repository);
$this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
}
private function url(array $query = []): string
{
return route('business.pages.show', [
'company_id' => $this->company->id, 'section' => 'supplier-payables', 'page' => 'manufacturer-bookkeeping',
]) . ($query ? '?' . http_build_query($query) : '');
}
public function test_page_renders_rows_totals_and_filters(): void
{
$this->mockRepository([
$this->row(),
$this->row(['work_order_no' => 'GD-WAREHOUSE', 'bookkeeping_reason' => '仓库记账/退货运费', 'reason_level_1' => '仓库记账', 'amount' => '10.05', 'bookkeeping_type' => '运费损耗']),
]);
$this->loginAs()->get($this->url())
->assertOk()
->assertSee('厂家记账')
->assertSee('GD614939067')
->assertSee('GD-WAREHOUSE')
->assertSee('392.20')
->assertSee('运费损耗')
->assertSee('附件1');
$this->loginAs()->get($this->url(['reason' => '仓库记账']))
->assertOk()
->assertSee('GD-WAREHOUSE')
->assertDontSee('GD614939067')
->assertSee('10.05');
$this->withExceptionHandling()->loginAs()->get($this->url(['reason' => 'DROP TABLE']))->assertStatus(422);
}
public function test_page_explains_pending_initial_sync(): void
{
$this->mockRepository([], 'initializing');
$this->loginAs()->get($this->url())
->assertOk()
->assertSee('尚未完成首次同步')
->assertSee('当前为空不代表没有记账工单');
}
public function test_export_uses_same_filters_and_selected_columns(): void
{
$this->mockRepository([$this->row(), $this->row(['work_order_no' => 'GD-2', 'status' => '已完成'])]);
$response = $this->loginAs()->get(route('business.supplier-bookkeeping.export', [
'company_id' => $this->company->id, 'status' => '待处理', 'columns' => 'work_order_no,online_order_no,amount',
]));
$response->assertOk();
$csv = $response->streamedContent();
$this->assertStringContainsString("工单编号,线上订单号,记账金额", $csv);
$this->assertStringContainsString("GD614939067,'5127787476014026744,382.15", $csv);
$this->assertStringNotContainsString('GD-2', $csv);
}
}