CaiWuXiTong/tests/Unit/StoreReceiptProductCostLineTest.php
chenxi ab308fe388 商品成本:口径不一致行全部计算成本 (#492)
所有匹配到单价的行统一按数量 × 单价计算成本,缺单价行继续待核验。
2026-10-24 14:34:08 +08:00

148 lines
5.1 KiB
PHP

<?php
namespace Tests\Unit;
use App\Business\StoreReceiptPlatformSkuMapper;
use App\Console\Commands\SyncStoreReceiptProductCost;
use PHPUnit\Framework\TestCase;
use ReflectionMethod;
class StoreReceiptProductCostLineTest extends TestCase
{
public function test_platform_placeholder_is_removed_when_internal_sku_exists(): void
{
[$lines, $placeholders, $bundles] = $this->costLines([
$this->row('platform', '955859844397', '3767501840732782900', 20, 2800),
$this->row('internal', 'DSG005016N11V01', '3767501840732782900', 20, 2800),
]);
$this->assertSame(1, $placeholders);
$this->assertSame(0, $bundles);
$this->assertSame('DSG005016N11V01', $lines[0]['sku']);
$this->assertSame(20.0, $lines[0]['qty']);
}
public function test_bundle_parent_is_removed_but_component_remains(): void
{
[$lines, $placeholders, $bundles] = $this->costLines([
$this->row('bundle-parent', '运营组合套装12994', '3832980288011632985', 2, 696),
$this->row(
'bundle-child',
'SJ038017N1410V02',
'3832980288011632985',
2,
625.26,
'运营组合套装12994',
),
]);
$this->assertSame(0, $placeholders);
$this->assertSame(1, $bundles);
$this->assertSame('SJ038017N1410V02', $lines[0]['sku']);
$this->assertSame(2.0, $lines[0]['qty']);
}
public function test_unique_platform_sku_is_replaced_after_line_filtering(): void
{
[$lines] = $this->costLines([
$this->row(
'platform',
'958530694526',
'3768947181063635112',
1,
93.25,
),
]);
$mapper = new StoreReceiptPlatformSkuMapper([
[
'shop_sku_id' => '3533103677164802',
'shop_i_id' => '3768947181063635112',
'sku_id' => 'SG006367N1028V01',
'i_id' => 'SG0063',
'properties_value' => '经典北美黑胡桃色',
],
]);
$command = new SyncStoreReceiptProductCost();
$method = new ReflectionMethod($command, 'mapPlatformSkus');
$method->setAccessible(true);
$result = $method->invoke($command, $lines, $mapper);
$this->assertSame(1, $result['auto_replaced_rows']);
$this->assertSame('SG006367N1028V01', $result['lines'][0]['sku']);
$this->assertSame('958530694526', $result['lines'][0]['original_platform_sku']);
$this->assertSame('unique', $result['lines'][0]['platform_mapping_status']);
}
public function test_yunfei_and_bcj_are_excluded_globally_and_from_bundle_components(): void
{
$command = new SyncStoreReceiptProductCost();
$constant = (new \ReflectionClass($command))->getReflectionConstant('EXCLUDED_SKUS');
$excludedSkus = $constant->getValue();
$this->assertContains('YUNFEI', $excludedSkus);
$this->assertContains('BCJ', $excludedSkus);
$method = new ReflectionMethod($command, 'expandComboSku');
$method->setAccessible(true);
$components = $method->invoke(
null,
'MKH-YUNFEI-1-BCJ-1-SG006367N1028V01-2',
3.0,
);
$this->assertSame([['SG006367N1028V01', 6.0, true]], $components);
}
public function test_priced_line_always_calculates_cost_without_unit_mismatch_override(): void
{
$command = new SyncStoreReceiptProductCost();
$method = new ReflectionMethod($command, 'calculateLineCost');
$method->setAccessible(true);
$result = $method->invoke($command, 9524.0, 58.0);
$this->assertSame(9524.0, $result['quantity']);
$this->assertSame(58.0, $result['unit_price']);
$this->assertSame(552392.0, $result['cost']);
}
/** @return array{0:list<array<string,mixed>>,1:int,2:int} */
private function costLines(array $rows): array
{
$command = new SyncStoreReceiptProductCost();
$method = new ReflectionMethod($command, 'costLines');
$method->setAccessible(true);
$placeholders = 0;
$bundles = 0;
$lines = $method->invokeArgs($command, [$rows, &$placeholders, &$bundles]);
return [$lines, $placeholders, $bundles];
}
/** @return array<string,mixed> */
private function row(
string $rowKey,
string $sku,
string $shopItemId,
float $quantity,
float $amount,
string $bundleParent = '',
): array {
return [
'source' => 'jst',
'sku' => $sku,
'qty' => $quantity,
'amount' => $amount,
'warehouse' => '简尚-新苏北仓',
'o_id' => '8986587',
'parent_o_id' => '',
'row_key' => $rowKey,
'status' => 'Sent',
'shop_i_id' => $shopItemId,
'shop_sku_id' => '3533103677164802',
'properties_value' => '颜色分类:六格-90*30*75cm-木纹胡桃色?赠送后背板',
'src_combine_sku_id' => $bundleParent,
];
}
}