125 lines
5.4 KiB
PHP
125 lines
5.4 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\CourierFreightReconciliationMirrorRepository;
|
|
use Modules\EcommerceFinance\Repositories\GenericBusinessMirrorRepository;
|
|
use Modules\EcommerceFinance\Services\BusinessMirrorDatasetRegistry;
|
|
use RuntimeException;
|
|
use Tests\TestCase;
|
|
|
|
class CourierFreightReconciliationMirrorRepositoryTest extends TestCase
|
|
{
|
|
private CourierFreightReconciliationMirrorRepository $repository;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
config([
|
|
'database.connections.business_mirror' => [
|
|
'driver' => 'sqlite',
|
|
'database' => ':memory:',
|
|
'prefix' => '',
|
|
],
|
|
'upstream_mirrors.connection' => 'business_mirror',
|
|
'upstream_mirrors.datasets' => [
|
|
CourierFreightReconciliationMirrorRepository::DATASET => [
|
|
'source_key' => 'jiansun',
|
|
'schema' => 'dbo',
|
|
'object' => 'fys_express_courier_settlement',
|
|
'target' => 'js_express_courier_settlement',
|
|
'keys' => ['Id'],
|
|
'watermark' => 'modify_time',
|
|
],
|
|
],
|
|
]);
|
|
DB::purge('business_mirror');
|
|
|
|
Schema::connection('business_mirror')->create('business_mirror_table_states', function (Blueprint $table): void {
|
|
$table->string('dataset_key')->primary();
|
|
$table->dateTime('initial_completed_at')->nullable();
|
|
$table->string('status')->nullable();
|
|
$table->dateTime('last_succeeded_at')->nullable();
|
|
$table->string('run_mode')->nullable();
|
|
});
|
|
Schema::connection('business_mirror')->create('js_express_courier_settlement', function (Blueprint $table): void {
|
|
$table->integer('Id');
|
|
foreach (['month', 'status', 'courier_company_name', 'expresscode', 'expressname', 'replenish_courier', 'reconciliation_person', 'file_status', 'taskid', 'guid', 'creator'] as $column) {
|
|
$table->string($column)->nullable();
|
|
}
|
|
foreach (['opening_balance', 'courier_provided_amount', 'reconciliation_difference', 'confirmed_amount', 'advance_payment', 'payable_amount', 'actual_payment', 'compensation_amount', 'other_replenishment', 'corporate_payment_amount', 'personal_payment_amount'] as $column) {
|
|
$table->decimal($column, 20, 6)->nullable();
|
|
}
|
|
$table->string('waybill')->nullable();
|
|
$table->dateTime('create_time')->nullable();
|
|
$table->dateTime('modify_time')->nullable();
|
|
$table->boolean('is_delete')->nullable();
|
|
});
|
|
|
|
$this->repository = new CourierFreightReconciliationMirrorRepository(
|
|
new BusinessMirrorDatasetRegistry(),
|
|
new GenericBusinessMirrorRepository(app('db')),
|
|
);
|
|
}
|
|
|
|
public function test_it_rejects_an_unready_mirror(): void
|
|
{
|
|
$this->expectException(RuntimeException::class);
|
|
$this->expectExceptionMessage('courier_freight_reconciliation_mirror_not_ready');
|
|
|
|
$this->repository->paginate([], 1, 25);
|
|
}
|
|
|
|
public function test_it_filters_sorts_and_summarizes_only_approved_mirror_fields(): void
|
|
{
|
|
DB::connection('business_mirror')->table('business_mirror_table_states')->insert([
|
|
'dataset_key' => CourierFreightReconciliationMirrorRepository::DATASET,
|
|
'initial_completed_at' => '2026-09-01 09:00:00',
|
|
'status' => 'succeeded',
|
|
'last_succeeded_at' => now()->toDateTimeString(),
|
|
]);
|
|
DB::connection('business_mirror')->table('js_express_courier_settlement')->insert([
|
|
$this->row(1, 'YT-001', '圆通速递', 100, 80, 20, '2026-08'),
|
|
$this->row(2, 'YT-002', '圆通速递', 50, 50, 0, '2026-08'),
|
|
$this->row(3, 'ZT-003', '中通礼品单', 30, 25, 5, '2026-09'),
|
|
]);
|
|
|
|
$result = $this->repository->paginate([
|
|
'express_no' => 'YT',
|
|
'express_name' => '圆通',
|
|
'month' => '2026-08',
|
|
], 1, 1);
|
|
|
|
$this->assertSame(2, $result['total']);
|
|
$this->assertSame('YT-002', $result['data'][0]['waybill']);
|
|
$this->assertSame(150.0, $result['summary']['payable_amount']);
|
|
$this->assertSame(130.0, $result['summary']['actual_payment']);
|
|
$this->assertSame(20.0, $result['summary']['reconciliation_difference']);
|
|
$this->assertSame('fresh', $result['sync']['code']);
|
|
$this->assertArrayNotHasKey('password', $result['data'][0]);
|
|
}
|
|
|
|
/** @return array<string,mixed> */
|
|
private function row(int $id, string $waybill, string $express, float $payable, float $actual, float $difference, string $month): array
|
|
{
|
|
return [
|
|
'Id' => $id,
|
|
'waybill' => $waybill,
|
|
'expressname' => $express,
|
|
'courier_company_name' => $express,
|
|
'month' => $month,
|
|
'status' => '已确认',
|
|
'payable_amount' => $payable,
|
|
'actual_payment' => $actual,
|
|
'confirmed_amount' => $payable,
|
|
'reconciliation_difference' => $difference,
|
|
'create_time' => '2026-09-07 09:00:00',
|
|
'modify_time' => '2026-09-07 10:00:00',
|
|
];
|
|
}
|
|
}
|