财务更正口径:厂家记账配置表中没有的供应商(含配置不在生效期内)视同正常记账,作为厂家扣款项; 取消“待配置”判定。工单未带供应商、或多供应商判定不一致的仍为“待确认”,不计入扣款。 涉及:扣款金额汇总口径;无数据库变更。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JouFR6TJ7vGscRJanYScEo
132 lines
6.6 KiB
PHP
132 lines
6.6 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);
|
|
}
|
|
|
|
public function test_seeded_configs_drive_deduction_judgement_totals_and_filter(): void
|
|
{
|
|
$this->mockRepository([
|
|
$this->row(),
|
|
$this->row(['work_order_no' => 'GD-NORMAL', 'supplier' => '鑫呈', 'amount' => '100.00']),
|
|
$this->row(['work_order_no' => 'GD-NONE', 'supplier' => '尊享', 'amount' => '50.00']),
|
|
$this->row(['work_order_no' => 'GD-DROP-OTHER', 'supplier' => '曹县洪耀', 'amount' => '30.00']),
|
|
$this->row(['work_order_no' => 'GD-DROP-WRONG', 'supplier' => '曹县洪耀', 'amount' => '20.50', 'reason_level_1' => '仓库记账',
|
|
'reason_level_2' => '仓库发错货(面单照片,实物照片,条形码照片)', 'bookkeeping_reason' => '仓库记账/仓库发错货(面单照片,实物照片,条形码照片)', 'shipping_warehouse' => '曹县洪耀代发仓']),
|
|
$this->row(['work_order_no' => 'GD-MAIN-WRONG', 'supplier' => '曹县洪耀', 'amount' => '8.00', 'reason_level_1' => '仓库记账',
|
|
'reason_level_2' => '仓库发错货(面单照片,实物照片,条形码照片)', 'bookkeeping_reason' => '仓库记账/仓库发错货(面单照片,实物照片,条形码照片)', 'shipping_warehouse' => '常州主仓']),
|
|
]);
|
|
|
|
$this->loginAs()->get($this->url())
|
|
->assertOk()
|
|
->assertSee('厂家扣款判定')
|
|
->assertSee('仅代发仓发错货记账')
|
|
->assertSee('502.65')
|
|
->assertSee('供应商不在配置表,按正常记账扣款');
|
|
|
|
$this->loginAs()->get($this->url(['deduction' => '扣款']))
|
|
->assertOk()
|
|
->assertSee('GD-NORMAL')
|
|
->assertSee('GD-DROP-WRONG')
|
|
->assertSee('GD614939067')
|
|
->assertDontSee('GD-NONE')
|
|
->assertDontSee('GD-DROP-OTHER')
|
|
->assertDontSee('GD-MAIN-WRONG');
|
|
|
|
$this->loginAs()->get($this->url(['deduction' => '不扣款']))->assertOk()->assertSee('GD-NONE')->assertDontSee('GD614939067');
|
|
|
|
$csv = $this->loginAs()->get(route('business.supplier-bookkeeping.export', [
|
|
'company_id' => $this->company->id, 'deduction' => '扣款', 'columns' => 'work_order_no,deduction_status,deduction_basis',
|
|
]))->assertOk()->streamedContent();
|
|
$this->assertStringContainsString('工单编号,厂家扣款判定,判定说明', $csv);
|
|
$this->assertStringContainsString('GD-DROP-WRONG,扣款,代发仓发错货,记厂家扣款', $csv);
|
|
$this->assertStringNotContainsString('GD-NONE', $csv);
|
|
|
|
$this->withExceptionHandling()->loginAs()->get($this->url(['deduction' => 'x']))->assertStatus(422);
|
|
}
|
|
}
|