197 lines
11 KiB
PHP
197 lines
11 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\GenericBusinessMirrorRepository;
|
|
use Modules\EcommerceFinance\Repositories\WorkOrderMirrorRepository;
|
|
use Modules\EcommerceFinance\Services\BusinessMirrorDatasetRegistry;
|
|
use Tests\TestCase;
|
|
|
|
class WorkOrderMirrorRepositoryTest extends TestCase
|
|
{
|
|
private WorkOrderMirrorRepository $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' => [
|
|
WorkOrderMirrorRepository::MAIN_DATASET => $this->definition('work_order_main', 'fixture_work_order_main', ['id'], 'update_time'),
|
|
WorkOrderMirrorRepository::SUB_DATASET => $this->definition('work_order_sub', 'fixture_work_order_sub', ['id'], 'update_time'),
|
|
WorkOrderMirrorRepository::CONFIG_DATASET => $this->definition('work_order_form_config', 'fixture_work_order_config', ['id'], 'update_time'),
|
|
WorkOrderMirrorRepository::VALUE_DATASET => $this->definition('work_order_form_value', 'fixture_work_order_values', ['id'], 'create_time'),
|
|
],
|
|
]);
|
|
DB::purge('business_mirror');
|
|
|
|
$schema = Schema::connection('business_mirror');
|
|
$schema->create('business_mirror_table_states', function (Blueprint $table): void {
|
|
$table->string('dataset_key')->primary();
|
|
$table->string('status')->nullable();
|
|
$table->dateTime('initial_completed_at')->nullable();
|
|
$table->dateTime('last_succeeded_at')->nullable();
|
|
});
|
|
$this->createTables($schema);
|
|
|
|
foreach (array_keys(config('upstream_mirrors.datasets')) as $key) {
|
|
DB::connection('business_mirror')->table('business_mirror_table_states')->insert([
|
|
'dataset_key' => $key,
|
|
'status' => 'succeeded',
|
|
'initial_completed_at' => '2026-08-01 00:00:00',
|
|
'last_succeeded_at' => '2026-08-31 12:00:00',
|
|
]);
|
|
}
|
|
|
|
DB::connection('business_mirror')->table('fixture_work_order_config')->insert([
|
|
['id' => 1, 'work_type' => 'WAREHOUSE', 'work_type_name' => '仓内未发', 'group_name' => '协同工单', 'is_enabled' => 1],
|
|
['id' => 2, 'work_type' => 'OTHER', 'work_type_name' => '其他', 'group_name' => '其他', 'is_enabled' => 1],
|
|
]);
|
|
DB::connection('business_mirror')->table('fixture_work_order_main')->insert([
|
|
['id' => 1, 'work_type' => 'WAREHOUSE', 'order_no' => 'WO-001', 'title' => '仓内未发一', 'status' => '待处理', 'create_user' => '张三', 'create_time' => '2026-08-20 10:00:00', 'update_time' => '2026-08-20 10:00:00', 'is_deleted' => 0],
|
|
['id' => 2, 'work_type' => 'WAREHOUSE', 'order_no' => 'WO-002', 'title' => '仓内未发二', 'status' => '处理中', 'create_user' => '李四', 'create_time' => '2026-08-21 10:00:00', 'update_time' => '2026-08-21 10:00:00', 'is_deleted' => 0],
|
|
['id' => 3, 'work_type' => 'OTHER', 'order_no' => 'WO-003', 'title' => '其他类型', 'status' => '待处理', 'create_user' => '张三', 'create_time' => '2026-08-22 10:00:00', 'update_time' => '2026-08-22 10:00:00', 'is_deleted' => 0],
|
|
['id' => 4, 'work_type' => 'WAREHOUSE', 'order_no' => 'WO-004', 'title' => '已删除', 'status' => '待处理', 'create_user' => '张三', 'create_time' => '2026-08-23 10:00:00', 'update_time' => '2026-08-23 10:00:00', 'is_deleted' => 1],
|
|
]);
|
|
DB::connection('business_mirror')->table('fixture_work_order_sub')->insert([
|
|
['id' => 1, 'sub_order_no' => 'SUB-001', 'main_order_no' => 'WO-002', 'title' => '拣货任务', 'assign_user' => '王五', 'status' => '执行中', 'is_deleted' => 0],
|
|
['id' => 2, 'sub_order_no' => 'SUB-002', 'main_order_no' => 'WO-002', 'title' => '已删除任务', 'assign_user' => '赵六', 'status' => '已取消', 'is_deleted' => 1],
|
|
]);
|
|
DB::connection('business_mirror')->table('fixture_work_order_values')->insert([
|
|
['id' => 1, 'main_order_no' => 'WO-002', 'field_code' => 'reason', 'field_name' => '未发原因', 'field_value' => '缺货', 'field_type' => 'text', 'sort' => 1, 'is_deleted' => 0],
|
|
['id' => 2, 'main_order_no' => 'WO-002', 'field_code' => 'secret', 'field_name' => '删除字段', 'field_value' => '不应显示', 'field_type' => 'text', 'sort' => 2, 'is_deleted' => 1],
|
|
]);
|
|
|
|
$this->repository = new WorkOrderMirrorRepository(
|
|
new BusinessMirrorDatasetRegistry(),
|
|
new GenericBusinessMirrorRepository(app('db')),
|
|
);
|
|
}
|
|
|
|
public function test_default_type_delete_filter_pagination_and_related_rows(): void
|
|
{
|
|
$page = $this->repository->paginate(1, 1);
|
|
|
|
$this->assertTrue($page['ready']);
|
|
$this->assertSame(2, $page['total']);
|
|
$this->assertSame('WO-002', $page['data'][0]['order_no']);
|
|
$this->assertCount(1, $page['data'][0]['sub_orders']);
|
|
$this->assertSame('SUB-001', $page['data'][0]['sub_orders'][0]['sub_order_no']);
|
|
$this->assertCount(1, $page['data'][0]['form_values']);
|
|
$this->assertSame('缺货', $page['data'][0]['form_values'][0]['field_value']);
|
|
|
|
$filtered = $this->repository->paginate(1, 50, ['assign_user' => '王五']);
|
|
$this->assertSame(1, $filtered['total']);
|
|
$this->assertSame('WO-002', $filtered['data'][0]['order_no']);
|
|
|
|
$secondPage = $this->repository->paginate(2, 1);
|
|
$this->assertSame('WO-001', $secondPage['data'][0]['order_no']);
|
|
}
|
|
|
|
public function test_after_sales_alerts_are_filtered_by_type_and_form_values(): void
|
|
{
|
|
DB::connection('business_mirror')->table('fixture_work_order_config')->insert([
|
|
'id' => 3,
|
|
'work_type' => 'ORDER_AFSALES',
|
|
'work_type_name' => '天猫_售后超标',
|
|
'group_name' => '运营',
|
|
'is_enabled' => 1,
|
|
]);
|
|
DB::connection('business_mirror')->table('fixture_work_order_main')->insert([
|
|
'id' => 5,
|
|
'work_type' => 'ORDER_AFSALES',
|
|
'order_no' => 'WO-005-AF',
|
|
'title' => '售后超标提醒',
|
|
'status' => '待处理',
|
|
'create_user' => '运营一组',
|
|
'create_time' => '2026-08-24 10:00:00',
|
|
'update_time' => '2026-08-24 10:00:00',
|
|
'is_deleted' => 0,
|
|
]);
|
|
DB::connection('business_mirror')->table('fixture_work_order_values')->insert([
|
|
['id' => 3, 'main_order_no' => 'WO-005-AF', 'field_code' => 'shop_name', 'field_name' => '店铺名称', 'field_value' => '天猫旗舰店', 'field_type' => 'text', 'sort' => 1, 'is_deleted' => 0],
|
|
['id' => 4, 'main_order_no' => 'WO-005-AF', 'field_code' => 'id', 'field_name' => '商品ID', 'field_value' => 'SKU-AF-1', 'field_type' => 'text', 'sort' => 2, 'is_deleted' => 0],
|
|
]);
|
|
|
|
$result = $this->repository->paginateAfterSales(1, 10, [
|
|
'from' => '2026-08-24',
|
|
'to' => '2026-08-24',
|
|
'shop_name' => '旗舰店',
|
|
'sku_id' => 'SKU-AF',
|
|
]);
|
|
|
|
$this->assertTrue($result['ready']);
|
|
$this->assertSame(1, $result['total']);
|
|
$this->assertSame('WO-005-AF', $result['data'][0]['order_no']);
|
|
$this->assertSame('天猫_售后超标', $result['data'][0]['work_type_name']);
|
|
$this->assertSame('天猫旗舰店', $result['data'][0]['form_values'][0]['field_value']);
|
|
}
|
|
|
|
public function test_unready_state_is_explicit_and_never_looks_like_empty_data(): void
|
|
{
|
|
DB::connection('business_mirror')->table('business_mirror_table_states')
|
|
->where('dataset_key', WorkOrderMirrorRepository::SUB_DATASET)
|
|
->update(['initial_completed_at' => null, 'status' => 'running']);
|
|
|
|
$result = $this->repository->paginate(1, 25);
|
|
|
|
$this->assertFalse($result['ready']);
|
|
$this->assertSame([], $result['data']);
|
|
$this->assertSame('initial_sync_pending', $result['sync_status']['code']);
|
|
$this->assertFalse($result['sync_status']['datasets']['sub']['ready']);
|
|
}
|
|
|
|
private function definition(string $object, string $target, array $keys, ?string $watermark): array
|
|
{
|
|
return [
|
|
'source_key' => 'operations_replica',
|
|
'schema' => 'rpt',
|
|
'object' => $object,
|
|
'target' => $target,
|
|
'keys' => $keys,
|
|
'watermark' => $watermark,
|
|
];
|
|
}
|
|
|
|
private function createTables($schema): void
|
|
{
|
|
$schema->create('fixture_work_order_main', function (Blueprint $table): void {
|
|
$table->integer('id');
|
|
foreach (['work_type', 'order_no', 'title', 'status', 'create_user', 'expect_minute', 'submit_time', 'expect_end_time', 'end_time', 'score', 'update_user', 'description', 'create_time', 'update_time'] as $column) {
|
|
$table->string($column)->nullable();
|
|
}
|
|
$table->integer('is_deleted')->nullable();
|
|
});
|
|
$schema->create('fixture_work_order_sub', function (Blueprint $table): void {
|
|
$table->integer('id');
|
|
foreach (['sub_order_no', 'main_order_no', 'title', 'assign_user', 'status', 'expect_minute', 'submit_time', 'expect_end_time', 'finish_time', 'content', 'notify_submit', 'notify_soon', 'notify_overdue', 'overdue_notify_count', 'create_time', 'update_time', 'taskid'] as $column) {
|
|
$table->string($column)->nullable();
|
|
}
|
|
$table->integer('is_deleted')->nullable();
|
|
});
|
|
$schema->create('fixture_work_order_config', function (Blueprint $table): void {
|
|
$table->integer('id');
|
|
foreach (['work_type', 'work_type_name', 'group_name', 'icon', 'icon_color', 'time_limit_options', 'form_fields', 'sort', 'remark', 'create_time', 'update_time', 'timeout_reminder_count'] as $column) {
|
|
$table->string($column)->nullable();
|
|
}
|
|
$table->integer('is_enabled')->nullable();
|
|
});
|
|
$schema->create('fixture_work_order_values', function (Blueprint $table): void {
|
|
$table->integer('id');
|
|
foreach (['main_order_no', 'field_code', 'field_name', 'field_value', 'field_type', 'sort', 'create_time'] as $column) {
|
|
$table->string($column)->nullable();
|
|
}
|
|
$table->integer('is_deleted')->nullable();
|
|
});
|
|
}
|
|
}
|