CaiWuXiTong/tests/Unit/EcommerceFinance/CourierSurchargeSettlementMirrorRepositoryTest.php
zhoushengchen 1fbb924924 feat: 附加费结算接入超长费/退回费/拦截费拉取、导入核验与模板导出
- 超长费按报价规则从销售出库单拉取;退回费/拦截费从查件扣单拉取,并补出库时间、平台商品ID、线上订单号等字段
- 页面新增导入核验(单号+附加费类型+快递名称+可选金额),返回正常结/不结原因与差异金额,并提供导入模板下载
2026-10-12 09:16:05 +08:00

201 lines
10 KiB
PHP

<?php
namespace Tests\Unit\EcommerceFinance;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Modules\EcommerceFinance\Repositories\CourierSurchargeSettlementMirrorRepository;
use Tests\TestCase;
class CourierSurchargeSettlementMirrorRepositoryTest extends TestCase
{
private CourierSurchargeSettlementMirrorRepository $repository;
protected function setUp(): void
{
parent::setUp();
config([
'database.connections.business_mirror' => [
'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '',
],
'upstream_mirrors.connection' => 'business_mirror',
]);
DB::purge('business_mirror');
$this->repository = new CourierSurchargeSettlementMirrorRepository(app('db'));
}
public function test_it_reports_unavailable_until_the_settlement_table_exists(): void
{
$this->assertFalse($this->repository->available());
$this->assertFalse($this->repository->ready());
$this->assertSame('pending', $this->repository->state()['code']);
}
public function test_it_filters_maps_and_summarises_settlement_rows(): void
{
$this->createTable();
DB::connection('business_mirror')->table(CourierSurchargeSettlementMirrorRepository::TABLE)->insert([
[
'rule_id' => 6, 'surcharge_type' => '超长费', 'courier_name' => '曹县德邦',
'waybill' => 'DPK1', 'outbound_io_id' => 1001, 'product_code' => 'DNZ032912N887V01',
'shop_name' => '拼多多-满富油家具旗舰店', 'online_order_no' => '261009-325069063762746',
'length' => 194, 'width' => 83, 'height' => 12.5, 'volume' => 201305,
'settlement_amount' => 8, 'settlement_status' => '已计算',
'shipped_at' => '2026-10-09 08:41:48', 'pulled_at' => '2026-10-09 12:00:00',
'evidence' => '最长边 194cm > 160cm',
'created_at' => '2026-10-09 12:00:00', 'updated_at' => '2026-10-09 12:00:00',
],
[
'rule_id' => 42, 'surcharge_type' => '超长费', 'courier_name' => '常州德邦',
'waybill' => 'DPK2', 'outbound_io_id' => 1002, 'product_code' => 'GBGJ-ZWJ024903A',
'shop_name' => '京东-HX旗舰店104', 'online_order_no' => null,
'length' => 244, 'width' => 7.5, 'height' => 8, 'volume' => 14640,
'settlement_amount' => 7, 'settlement_status' => '已计算',
'shipped_at' => '2026-10-08 10:00:00', 'pulled_at' => '2026-10-09 12:00:00',
'evidence' => '最长边 244cm > 160cm',
'created_at' => '2026-10-09 12:00:00', 'updated_at' => '2026-10-09 12:00:00',
],
]);
$this->assertTrue($this->repository->available());
$this->assertTrue($this->repository->ready());
$result = $this->repository->paginate([], 1, 25);
$this->assertSame(2, $result['total']);
$this->assertSame(15.0, $result['summary']['settlement_amount']);
$this->assertSame('曹县德邦', $result['data'][0]['courier_name']);
$this->assertSame('DPK1', $result['data'][0]['waybill']);
$this->assertSame('2026-10-09 08:41:48', $result['data'][0]['shipped_at']);
$this->assertSame('超长费', $result['data'][0]['surcharge_type']);
$this->assertSame(194.0, (float) $result['data'][0]['length']);
$this->assertSame(8.0, (float) $result['data'][0]['settlement_amount']);
$this->assertSame('fresh', $result['sync']['code']);
}
public function test_it_applies_page_filters(): void
{
$this->createTable();
DB::connection('business_mirror')->table(CourierSurchargeSettlementMirrorRepository::TABLE)->insert([
[
'rule_id' => 6, 'surcharge_type' => '超长费', 'courier_name' => '曹县德邦',
'waybill' => 'DPK1', 'outbound_io_id' => 1001, 'product_code' => 'DNZ032912N887V01',
'settlement_amount' => 8, 'settlement_status' => '已计算',
'shipped_at' => '2026-10-09 08:41:48', 'pulled_at' => '2026-10-09 12:00:00',
'created_at' => '2026-10-09 12:00:00', 'updated_at' => '2026-10-09 12:00:00',
],
[
'rule_id' => 42, 'surcharge_type' => '超长费', 'courier_name' => '常州德邦',
'waybill' => 'DPK2', 'outbound_io_id' => 1002, 'product_code' => 'GBGJ-ZWJ024903A',
'settlement_amount' => 7, 'settlement_status' => '待核价',
'shipped_at' => '2026-09-01 10:00:00', 'pulled_at' => '2026-10-09 12:00:00',
'created_at' => '2026-10-09 12:00:00', 'updated_at' => '2026-10-09 12:00:00',
],
]);
$byCourier = $this->repository->paginate(['courier_name' => '常州', 'status' => '待核价'], 1, 25);
$this->assertSame(1, $byCourier['total']);
$this->assertSame('常州德邦', $byCourier['data'][0]['courier_name']);
$this->assertSame(7.0, $byCourier['summary']['settlement_amount']);
$byDate = $this->repository->paginate(['created_from' => '2026-10-01', 'created_to' => '2026-10-09'], 1, 25);
$this->assertSame(1, $byDate['total']);
$this->assertSame('DPK1', $byDate['data'][0]['waybill']);
$byWaybill = $this->repository->paginate(['waybill' => 'DPK2'], 1, 25);
$this->assertSame(1, $byWaybill['total']);
$this->assertSame('常州德邦', $byWaybill['data'][0]['courier_name']);
}
public function test_import_decisions_report_settlement_and_reasons(): void
{
$this->createTable();
DB::connection('business_mirror')->table(CourierSurchargeSettlementMirrorRepository::TABLE)->insert([
[
'rule_id' => 6, 'surcharge_type' => '超长费', 'courier_name' => '曹县德邦',
'waybill' => 'DPK1', 'outbound_io_id' => 1001, 'product_code' => 'SKU-1',
'settlement_amount' => 8, 'settlement_status' => '已计算',
'shipped_at' => '2026-10-09 08:41:48', 'pulled_at' => '2026-10-09 12:00:00',
'evidence' => '最长边 194cm > 160cm',
'created_at' => '2026-10-09 12:00:00', 'updated_at' => '2026-10-09 12:00:00',
],
[
'rule_id' => 7, 'surcharge_type' => '退回费', 'courier_name' => '曹县德邦小件',
'waybill' => 'DPK2', 'outbound_io_id' => null, 'product_code' => 'SKU-2',
'settlement_amount' => 0, 'settlement_status' => '已计算',
'shipped_at' => '2026-09-01 10:00:00', 'pulled_at' => '2026-10-09 12:00:00',
'evidence' => '查件扣单/买家-不想要;售后退货退款无进仓/实退记录;结算金额 0.00',
'created_at' => '2026-10-09 12:00:00', 'updated_at' => '2026-10-09 12:00:00',
],
]);
$result = $this->repository->decideImportRows([
['row_number' => 2, 'waybill' => 'DPK1', 'surcharge_type' => '超长费'],
['row_number' => 3, 'waybill' => 'DPK2', 'surcharge_type' => '退回件'],
['row_number' => 4, 'waybill' => 'DPK3', 'surcharge_type' => '退回费'],
['row_number' => 5, 'waybill' => 'DPK4', 'surcharge_type' => '退回费', 'courier_name' => '恒思德邦'],
['row_number' => 6, 'waybill' => 'DPK1', 'surcharge_type' => '超长费', 'courier_name' => '常州德邦'],
]);
$this->assertSame('正常结', $result[0]['decision']);
$this->assertSame('', $result[0]['reason']);
$this->assertSame('曹县德邦', $result[0]['courier_name']);
$this->assertSame(8.0, (float) $result[0]['settlement_amount']);
$this->assertSame('不结', $result[1]['decision']);
$this->assertSame('退回费', $result[1]['surcharge_type']);
$this->assertStringContainsString('无进仓', $result[1]['reason']);
$this->assertSame('不结', $result[2]['decision']);
$this->assertNotSame('', $result[2]['reason']);
$this->assertNull($result[2]['settlement_amount']);
$this->assertSame('不结', $result[3]['decision']);
$this->assertStringContainsString('恒思德邦', $result[3]['reason']);
$this->assertSame('恒思德邦', $result[3]['courier_name']);
$this->assertSame('不结', $result[4]['decision']);
$this->assertStringContainsString('不一致', $result[4]['reason']);
}
private function createTable(): void
{
Schema::connection('business_mirror')->create(
CourierSurchargeSettlementMirrorRepository::TABLE,
function (Blueprint $table): void {
$table->bigIncrements('id');
$table->unsignedInteger('rule_id');
$table->string('surcharge_type', 40);
$table->string('courier_name', 191);
$table->string('waybill', 191)->nullable();
$table->unsignedBigInteger('outbound_io_id')->nullable();
$table->string('platform_product_id', 191)->nullable();
$table->string('product_code', 191)->nullable();
$table->string('shop_name', 191)->nullable();
$table->string('online_order_no', 191)->nullable();
$table->decimal('length', 12, 2)->nullable();
$table->decimal('width', 12, 2)->nullable();
$table->decimal('height', 12, 2)->nullable();
$table->decimal('volume', 16, 2)->nullable();
$table->string('inspection_type', 60)->nullable();
$table->string('inspection_reason', 120)->nullable();
$table->string('return_waybill_no', 191)->nullable();
$table->decimal('settlement_weight', 12, 2)->nullable();
$table->decimal('settlement_amount', 12, 2)->default(0);
$table->string('settlement_status', 40)->default('已计算');
$table->string('evidence', 500)->nullable();
$table->dateTime('shipped_at')->nullable();
$table->dateTime('pulled_at');
$table->timestamps();
},
);
}
}