- 复用已登记镜像 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
91 lines
4.0 KiB
PHP
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);
|
|
}
|
|
}
|