129 lines
5.2 KiB
PHP
129 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\Business;
|
|
|
|
use App\Business\KukaPostingBase\KukaPostingMaterialMapSynchronizer;
|
|
use Illuminate\Database\Schema\Blueprint;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Mockery;
|
|
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery;
|
|
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQueryFactory;
|
|
use Tests\TestCase;
|
|
|
|
class KukaPostingMaterialMapSynchronizerTest extends TestCase
|
|
{
|
|
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');
|
|
|
|
$schema = Schema::connection('business_mirror');
|
|
$schema->create('kuka_posting_base_rows', function (Blueprint $table): void {
|
|
$table->bigIncrements('id');
|
|
$table->unsignedBigInteger('company_id');
|
|
$table->string('period', 7);
|
|
$table->longText('source_values');
|
|
});
|
|
$schema->create('kuka_posting_quotation_rows', function (Blueprint $table): void {
|
|
$table->bigIncrements('id');
|
|
$table->unsignedBigInteger('company_id');
|
|
$table->string('material_number', 191);
|
|
$table->string('record_status', 64)->nullable();
|
|
});
|
|
$schema->create('kuka_posting_material_map_rows', function (Blueprint $table): void {
|
|
$table->bigIncrements('id');
|
|
$table->unsignedBigInteger('company_id');
|
|
$table->string('item_number', 191);
|
|
$table->string('material_number', 191)->nullable();
|
|
$table->string('match_status', 24);
|
|
$table->string('match_source', 24)->nullable();
|
|
$table->unsignedInteger('candidate_count')->default(0);
|
|
$table->longText('candidate_materials')->nullable();
|
|
$table->timestamp('synced_at');
|
|
});
|
|
}
|
|
|
|
public function test_only_a_unique_active_quotation_match_is_selected(): void
|
|
{
|
|
$connection = DB::connection('business_mirror');
|
|
foreach (['A', 'B', 'C', 'D', 'E'] as $itemNumber) {
|
|
$connection->table('kuka_posting_base_rows')->insert([
|
|
'company_id' => 1,
|
|
'period' => '2026-10',
|
|
'source_values' => json_encode(['货号' => 'ITEM-'.$itemNumber], JSON_THROW_ON_ERROR),
|
|
]);
|
|
}
|
|
foreach (['Q-A', 'Q-B', 'Q-C1', 'Q-C2', 'Q-E'] as $materialNumber) {
|
|
$connection->table('kuka_posting_quotation_rows')->insert([
|
|
'company_id' => 1,
|
|
'material_number' => $materialNumber,
|
|
'record_status' => '生效',
|
|
]);
|
|
}
|
|
|
|
$query = Mockery::mock(UpstreamReadOnlyQuery::class);
|
|
$query->shouldReceive('select')
|
|
->twice()
|
|
->andReturnUsing(static function (string $sql): array {
|
|
if (str_contains($sql, 'BarcodePrintImportRecord')) {
|
|
return [
|
|
['item_number' => 'ITEM-A', 'material_number' => 'Q-A'],
|
|
['item_number' => 'ITEM-B', 'material_number' => 'Q-B'],
|
|
['item_number' => 'ITEM-C', 'material_number' => 'Q-C-OLD'],
|
|
['item_number' => 'ITEM-E', 'material_number' => 'Q-E-OLD'],
|
|
];
|
|
}
|
|
|
|
return [
|
|
['item_number' => 'ITEM-A', 'material_number' => 'Q-A'],
|
|
['item_number' => 'ITEM-B', 'material_number' => 'Q-B-ARCHIVE'],
|
|
['item_number' => 'ITEM-C', 'material_number' => 'Q-C1'],
|
|
['item_number' => 'ITEM-C', 'material_number' => 'Q-C2'],
|
|
['item_number' => 'ITEM-E', 'material_number' => 'Q-E'],
|
|
];
|
|
});
|
|
$factory = Mockery::mock(UpstreamReadOnlyQueryFactory::class);
|
|
$factory->shouldReceive('forSourceWithTimeout')
|
|
->once()
|
|
->with(KukaPostingMaterialMapSynchronizer::SOURCE_KEY, 15)
|
|
->andReturn($query);
|
|
|
|
$result = (new KukaPostingMaterialMapSynchronizer(app('db'), $factory))
|
|
->sync(1, '2026-10');
|
|
|
|
$this->assertSame([
|
|
'dry_run' => false,
|
|
'items' => 5,
|
|
'matched' => 3,
|
|
'unmatched' => 1,
|
|
'ambiguous' => 1,
|
|
'direct' => 2,
|
|
'archive' => 1,
|
|
], $result);
|
|
|
|
$rows = $connection->table('kuka_posting_material_map_rows')
|
|
->orderBy('item_number')
|
|
->get()
|
|
->keyBy('item_number');
|
|
|
|
$this->assertSame('Q-A', $rows['ITEM-A']->material_number);
|
|
$this->assertSame('barcode_material_no', $rows['ITEM-A']->match_source);
|
|
$this->assertSame('Q-B', $rows['ITEM-B']->material_number);
|
|
$this->assertSame('Q-E', $rows['ITEM-E']->material_number);
|
|
$this->assertSame('archive_barcode', $rows['ITEM-E']->match_source);
|
|
$this->assertSame('ambiguous', $rows['ITEM-C']->match_status);
|
|
$this->assertNull($rows['ITEM-C']->material_number);
|
|
$this->assertSame('unmatched', $rows['ITEM-D']->match_status);
|
|
}
|
|
}
|