CaiWuXiTong/tests/Feature/Business/AccessoryReshipDeductionsTest.php

85 lines
4.2 KiB
PHP

<?php
namespace Tests\Feature\Business;
use App\Models\Auth\Permission;
use Modules\EcommerceFinance\Repositories\ShippingOrderRepository;
use Modules\EcommerceFinance\Services\AccessoryReshipCourierStore;
use Modules\EcommerceFinance\Services\AccessoryReshipSelectionStore;
use Tests\Feature\FeatureTestCase;
class AccessoryReshipDeductionsTest extends FeatureTestCase
{
protected function mockShipments(): void
{
$accessories = [];
foreach (['祥和中通', '柏卡顺丰干配配件', '正常补发快递'] as $i => $courier) {
$accessories[] = [
'trade_no' => 'T001', 'express_no' => 'BF-TEST-' . $i,
'express_name1' => $courier, 'express_name2' => '',
'ship_time' => '2026-11-10', 'barcode' => 'SKU-1', 'freight' => '10.00',
];
}
$original = [
'trade_no' => 'T001', 'express_no' => 'FIRST001', 'express_name1' => '首发快递',
'ship_time' => '2026-10-01', 'barcode' => 'SKU', 'warehouse_name' => '成品仓',
];
$shipping = \Mockery::mock(ShippingOrderRepository::class);
$shipping->shouldReceive('accessoryReshipBatches')->with('2026-11-01', '2026-12-01', '2026-09-01')
->andReturnUsing(static function () use ($accessories, $original) {
yield ['accessories' => $accessories, 'originals' => [$original]];
});
$configs = \Mockery::mock(AccessoryReshipCourierStore::class);
$configs->shouldReceive('activeRates')->andReturn(['首发快递' => ['courier_code' => 'TEST', 'rate_basis_points' => 5000]]);
$selections = \Mockery::mock(AccessoryReshipSelectionStore::class);
$selections->shouldReceive('forMonth')->andReturn([]);
$this->app->instance(ShippingOrderRepository::class, $shipping);
$this->app->instance(AccessoryReshipCourierStore::class, $configs);
$this->app->instance(AccessoryReshipSelectionStore::class, $selections);
$this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
}
protected function pageUrl(array $filters = []): string
{
return route('business.pages.show', [
'company_id' => $this->company->id, 'section' => 'courier-payables',
'page' => 'accessory-reship-deductions', 'month' => '2026-11',
] + $filters);
}
public function test_page_totals_and_export_exclude_both_couriers_from_deductions(): void
{
$this->mockShipments();
$this->loginAs()->get($this->pageUrl(['match_status' => 'all']))->assertOk()
->assertSee('BF-TEST-0')->assertSee('BF-TEST-1')->assertSee('BF-TEST-2')
->assertSee('补发快递为祥和中通,不参与扣款')
->assertSee('补发快递为柏卡顺丰干配配件,不参与扣款')
->assertSee('¥ 5.00');
$csv = $this->get(route('business.accessory-reship-deductions.export', [
'company_id' => $this->company->id, 'month' => '2026-11', 'match_status' => 'all',
]))->assertOk()->streamedContent();
$records = array_map('str_getcsv', explode("\n", trim($csv)));
$this->assertCount(4, $records);
foreach ([1, 2] as $i) {
$this->assertSame('不扣款', $records[$i][7]);
$this->assertSame('0.00', $records[$i][12]);
}
$this->assertSame('可扣款', $records[3][7]);
$this->assertSame('5.00', $records[3][12]);
$this->get($this->pageUrl())->assertOk()->assertSee('BF-TEST-2')
->assertDontSee('BF-TEST-0')->assertDontSee('BF-TEST-1')->assertSee('¥ 5.00');
$readyCsv = $this->get(route('business.accessory-reship-deductions.export', [
'company_id' => $this->company->id, 'month' => '2026-11',
]))->assertOk()->streamedContent();
$this->assertStringContainsString('BF-TEST-2', $readyCsv);
$this->assertStringNotContainsString('BF-TEST-0', $readyCsv);
$this->assertStringNotContainsString('BF-TEST-1', $readyCsv);
$this->get($this->pageUrl(['match_status' => 'all', 'deduction_state' => 'excluded_courier']))
->assertOk()->assertSee('BF-TEST-0')->assertSee('BF-TEST-1')
->assertDontSee('BF-TEST-2')->assertSee('¥ 0.00');
}
}