CaiWuXiTong/tests/Feature/Business/SupplierBookkeepingPageTest.php

176 lines
9.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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', 'actual_paid_amount' => '40.00', '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);
}
public function test_small_compensation_zeroes_page_totals_and_exports_with_original_amount_and_note(): void
{
$this->mockRepository([
$this->row(['work_order_no' => 'GD-SMALL', 'amount' => '30.00', 'buyer_paid_amount' => '100', 'remark' => '原备注']),
$this->row(['work_order_no' => 'GD-EQUAL-RATIO', 'amount' => '40.00', 'buyer_paid_amount' => '100', 'actual_paid_amount' => '100.00']),
$this->row(['work_order_no' => 'GD-EQUAL-LIMIT', 'amount' => '50.00', 'buyer_paid_amount' => '200']),
]);
$response = $this->loginAs()->get($this->url())->assertOk();
$data = app(\Modules\EcommerceFinance\View\SupplierBookkeepingPageData::class)->page();
$summary = $data['bookkeepingSummary'];
$this->assertSame(9000, $summary['amount_cents']);
$this->assertSame(9000, $summary['deduction_cents']);
$this->assertSame(2, $summary['deduction_count']);
$row = $data['bookkeepingRows']->getCollection()->firstWhere('work_order_no', 'GD-SMALL');
$this->assertSame('0.00', $row['amount']);
$this->assertSame('30.00', $row['original_amount']);
$this->assertSame("原备注\n小于50且小于0.4,记账改0", $row['remark']);
$response->assertSee('原记账金额')->assertSee('小于50且小于0.4,记账改0');
$this->get($this->url(['deduction' => '扣款']))->assertOk()->assertDontSee('GD-SMALL')->assertSee('GD-EQUAL-RATIO');
$this->get($this->url(['deduction' => '不扣款']))->assertOk()->assertSee('GD-SMALL')->assertDontSee('GD-EQUAL-RATIO');
$csv = $this->get(route('business.supplier-bookkeeping.export', [
'company_id' => $this->company->id, 'columns' => 'work_order_no,amount,original_amount,remark',
]))->assertOk()->streamedContent();
$this->assertStringContainsString('GD-SMALL,0.00,30.00,', $csv);
$this->assertStringContainsString('小于50且小于0.4,记账改0', $csv);
}
public function test_second_round_zeroes_by_order_paid_when_buyer_paid_ratio_does_not_hit(): void
{
$this->mockRepository([
$this->row(['work_order_no' => 'GD-ROUND-TWO', 'amount' => '30.00', 'buyer_paid_amount' => '50.00', 'actual_paid_amount' => '100.00']),
]);
$this->loginAs()->get($this->url())->assertOk()->assertSee('GD-ROUND-TWO')->assertSee('小于50且小于0.4,记账改0');
$data = app(\Modules\EcommerceFinance\View\SupplierBookkeepingPageData::class)->page();
$this->assertSame(0, $data['bookkeepingSummary']['deduction_cents']);
$this->assertSame(0, $data['bookkeepingSummary']['amount_cents']);
$this->get($this->url(['deduction' => '扣款']))->assertOk()->assertDontSee('GD-ROUND-TWO');
$csv = $this->get(route('business.supplier-bookkeeping.export', [
'company_id' => $this->company->id, 'deduction' => '不扣款',
'columns' => 'work_order_no,amount,original_amount,remark',
]))->assertOk()->streamedContent();
$this->assertStringContainsString('GD-ROUND-TWO,0.00,30.00,', $csv);
}
}