CaiWuXiTong/tests/Unit/EcommerceFinance/ProductMaterialBarcodeMappingRepositoryTest.php
chenxi 16ff4dcfaa 91 料号按启用状态和最新条码映射 (#671)
91 料号仅匹配销售状态商品,并按条码档案创建时间选择最新唯一候选。
2026-10-27 10:43:46 +08:00

129 lines
5.2 KiB
PHP

<?php
namespace Tests\Unit\EcommerceFinance;
use Modules\EcommerceFinance\Repositories\ProductMaterialBarcodeMappingRepository;
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery;
use PHPUnit\Framework\TestCase;
class ProductMaterialBarcodeMappingRepositoryTest extends TestCase
{
public function test_only_91_material_codes_are_normalized_and_suffixes_are_removed(): void
{
$this->assertSame(
'91.C46324.01',
ProductMaterialBarcodeMappingRepository::normalizeMaterialCode(' 91.c46324.01-N1280 '),
);
$this->assertSame(
'91.C45340.01',
ProductMaterialBarcodeMappingRepository::normalizeMaterialCode('91.C45340.01-N09'),
);
$this->assertSame(
'91.C49784.01',
ProductMaterialBarcodeMappingRepository::normalizeMaterialCode('91.C49784.01-N1280-1'),
);
$this->assertNull(ProductMaterialBarcodeMappingRepository::normalizeMaterialCode('GBGJ-SJ025102'));
$this->assertNull(ProductMaterialBarcodeMappingRepository::normalizeMaterialCode('91.OTHER'));
}
public function test_latest_enabled_barcode_is_selected_and_missing_or_tied_mapping_is_not_guessed(): void
{
$query = $this->createMock(UpstreamReadOnlyQuery::class);
$query->expects($this->once())
->method('select')
->with(
$this->callback(static fn (string $sql): bool => str_contains(
$sql,
'FROM public."BarcodePrintImportRecord"',
) && str_contains($sql, "updates->>'barcode'")
&& str_contains($sql, 'JOIN public."SupplyChainProductArchive"')
&& str_contains($sql, "archive.\"productStatus\" = '销售'")
&& str_contains($sql, 'archive."createdAt"')
&& substr_count($sql, '?') === 5),
[
'91.C45340.01',
'91.C45438.01',
'91.C45492.01',
'91.C45493.01',
'91.C49784.01',
],
)
->willReturn([
[
'material_no' => '91.C45340.01',
'mapped_sku' => 'GBGJ-SJ025102N09V01',
'product_status' => '销售',
'candidate_created_at' => '2026-08-07 05:08:00',
],
[
'material_no' => '91.C45340.01',
'mapped_sku' => 'GBGJ-SJ025102N09V01',
'product_status' => '销售',
'candidate_created_at' => '2026-08-07 05:09:00',
],
[
'material_no' => '91.C45438.01',
'mapped_sku' => 'GBGJ-DNZ036601N09V01',
'product_status' => '销售',
'candidate_created_at' => '2026-08-07 05:08:56',
],
[
'material_no' => '91.C45438.01',
'mapped_sku' => 'MKHDNZ0409260601235',
'product_status' => '销售',
'candidate_created_at' => '2026-08-07 05:11:13',
],
[
'material_no' => '91.C45438.01',
'mapped_sku' => 'GBGJ-DNZ036601N08V01',
'product_status' => '停产',
'candidate_created_at' => '2026-08-07 05:12:00',
],
[
'material_no' => '91.C45492.01',
'mapped_sku' => 'GBGJ-CYJ005701N1282V01',
'product_status' => '停产',
'candidate_created_at' => '2026-08-07 05:12:00',
],
[
'material_no' => '91.C45492.01',
'mapped_sku' => 'GBGJ-CYJ005701N1411V01',
'product_status' => '销售',
'candidate_created_at' => '2026-08-07 05:09:31',
],
[
'material_no' => '91.C45493.01',
'mapped_sku' => 'SKU-TIE-A',
'product_status' => '销售',
'candidate_created_at' => '2026-08-07 05:10:00',
],
[
'material_no' => '91.C45493.01',
'mapped_sku' => 'SKU-TIE-B',
'product_status' => '销售',
'candidate_created_at' => '2026-08-07 05:10:00',
],
]);
$result = (new ProductMaterialBarcodeMappingRepository())->resolve([
'91.C45340.01-N09',
'91.C45438.01-N09',
'91.C45492.01-N1411',
'91.C45493.01-N01',
'91.C49784.01-N1280-1',
'GBGJ-SJ025102',
], $query);
$this->assertSame([
'91.C45340.01' => 'GBGJ-SJ025102N09V01',
'91.C45438.01' => 'MKHDNZ0409260601235',
'91.C45492.01' => 'GBGJ-CYJ005701N1411V01',
], $result['unique']);
$this->assertSame([
'91.C45493.01' => ['SKU-TIE-A', 'SKU-TIE-B'],
], $result['ambiguous']);
$this->assertSame(['91.C49784.01'], $result['missing']);
$this->assertSame(9, $result['source_rows']);
}
}