176 lines
8.2 KiB
PHP
176 lines
8.2 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\GoodsProfitAfsRepository;
|
|
use Modules\EcommerceFinance\Services\GoodsProfitAfsLookupSchema;
|
|
use Tests\TestCase;
|
|
|
|
class GoodsProfitAfsRepositoryTest 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(GoodsProfitAfsLookupSchema::TABLE, function (Blueprint $table): void {
|
|
$table->integer('id')->primary();
|
|
foreach ([
|
|
'undefined1', 'undefined2', 'undefined7', 'undefined8', 'undefined10',
|
|
'undefined12', 'undefined13', 'undefined20', 'undefined21', 'undefined25',
|
|
'_mirror_afs_order_time',
|
|
] as $column) {
|
|
$table->string($column)->nullable();
|
|
}
|
|
});
|
|
$schema->create('ops_jst_goods_profit_kpi_items_afs_schemas', function (Blueprint $table): void {
|
|
$table->integer('id'); $table->string('column'); $table->string('name');
|
|
});
|
|
$schema->create('business_mirror_table_states', function (Blueprint $table): void {
|
|
$table->string('dataset_key'); $table->dateTime('initial_completed_at')->nullable();
|
|
});
|
|
$db = DB::connection('business_mirror');
|
|
$db->table('business_mirror_table_states')->insert([
|
|
'dataset_key' => GoodsProfitAfsRepository::MAIN_DATASET, 'initial_completed_at' => '2026-10-01 00:00:00',
|
|
]);
|
|
foreach ([
|
|
'undefined1' => '内部订单号', 'undefined2' => '线上订单号', 'undefined7' => '订单时间',
|
|
'undefined8' => '店铺名称', 'undefined10' => '商品编码',
|
|
'undefined12' => '店铺商品编码', 'undefined13' => '店铺款式编码',
|
|
'undefined20' => '商品数量', 'undefined25' => '商品金额',
|
|
] as $column => $name) {
|
|
$db->table('ops_jst_goods_profit_kpi_items_afs_schemas')->insert(['id' => (int) substr($column, 9), 'column' => $column, 'name' => $name]);
|
|
}
|
|
$db->getPdo()->sqliteCreateFunction('STR_TO_DATE', static function (?string $date): ?string {
|
|
return $date === null || trim($date) === '' ? null : date('Y-m-d H:i:s', strtotime($date));
|
|
});
|
|
for ($id = 1; $id <= 60; $id++) {
|
|
$db->table(GoodsProfitAfsLookupSchema::TABLE)->insert([
|
|
'id' => $id, 'undefined1' => 'ORDER-' . $id, 'undefined2' => 'ONLINE-' . $id,
|
|
'undefined7' => sprintf('2026/10/19 1:%d:00', $id - 1),
|
|
'_mirror_afs_order_time' => sprintf('2026-10-19 01:%02d:00', $id - 1),
|
|
'undefined8' => $id % 2 ? '店铺甲' : '店铺乙', 'undefined10' => 'SKU_1', 'undefined25' => '123.45',
|
|
]);
|
|
}
|
|
}
|
|
|
|
public function test_next_page_does_not_skip_the_lookahead_row(): void
|
|
{
|
|
$repo = new GoodsProfitAfsRepository();
|
|
$filters = ['from' => '2026-10-19', 'to' => '2026-10-19'];
|
|
$pages = array_map(fn ($page) => $repo->paginate($filters, $page, 25), [1, 2, 3]);
|
|
$orders = array_merge(...array_map(fn ($page) => array_column($page['rows'], 'internal_order_no'), $pages));
|
|
|
|
$this->assertSame(array_map(fn ($id) => 'ORDER-' . $id, range(60, 1)), $orders);
|
|
$this->assertSame([true, true, false], array_column($pages, 'has_more'));
|
|
$this->assertSame(123.45, $pages[0]['rows'][0]['product_amount']);
|
|
}
|
|
|
|
public function test_dates_before_goods_profit_coverage_skip_mirror_queries(): void
|
|
{
|
|
$db = DB::connection('business_mirror');
|
|
$db->flushQueryLog();
|
|
$db->enableQueryLog();
|
|
|
|
$covered = (new GoodsProfitAfsRepository())->covers([
|
|
'from' => '2026-06-01',
|
|
'to' => '2026-06-30',
|
|
'order_no' => '',
|
|
]);
|
|
|
|
$this->assertFalse($covered);
|
|
$this->assertSame([], $db->getQueryLog());
|
|
}
|
|
|
|
public function test_date_boundaries_and_multi_shop_filters_preserve_values(): void
|
|
{
|
|
$db = DB::connection('business_mirror');
|
|
foreach ([61 => ['2026/10/19 23:59:59', '2026-10-19 23:59:59'],
|
|
62 => ['2026/10/20 0:00:00', '2026-10-20 00:00:00'],
|
|
63 => ['2026/8/23 14:58:51', '2026-08-23 14:58:51']] as $id => [$raw, $parsed]) {
|
|
$db->table(GoodsProfitAfsLookupSchema::TABLE)->insert([
|
|
'id' => $id, 'undefined1' => 'ORDER-' . $id, 'undefined7' => $raw,
|
|
'_mirror_afs_order_time' => $parsed, 'undefined8' => '店铺甲', 'undefined25' => '-31.20',
|
|
]);
|
|
}
|
|
$db->enableQueryLog();
|
|
$result = (new GoodsProfitAfsRepository())->paginate([
|
|
'from' => '2026-10-19', 'to' => '2026-10-19', 'shop_names' => ['店铺甲', '店铺乙'],
|
|
], 1, 100);
|
|
$this->assertCount(61, $result['rows']);
|
|
$this->assertSame('ORDER-61', $result['rows'][0]['internal_order_no']);
|
|
$this->assertSame(-31.2, $result['rows'][0]['product_amount']);
|
|
$this->assertStringNotContainsString('STR_TO_DATE', implode(' ', array_column($db->getQueryLog(), 'query')));
|
|
}
|
|
|
|
public function test_missing_lookup_keeps_the_original_parser(): void
|
|
{
|
|
Schema::connection('business_mirror')->table(GoodsProfitAfsLookupSchema::TABLE, function (Blueprint $table): void {
|
|
$table->dropColumn('_mirror_afs_order_time');
|
|
});
|
|
$result = (new GoodsProfitAfsRepository())->paginate(['from' => '2026-10-19', 'to' => '2026-10-19'], 1, 25);
|
|
$this->assertCount(25, $result['rows']);
|
|
$this->assertSame('ORDER-60', $result['rows'][0]['internal_order_no']);
|
|
}
|
|
|
|
public function test_moved_dynamic_header_does_not_use_the_old_lookup_column(): void
|
|
{
|
|
Schema::connection('business_mirror')->table(GoodsProfitAfsLookupSchema::TABLE, function (Blueprint $table): void {
|
|
$table->string('undefined9')->nullable();
|
|
});
|
|
$db = DB::connection('business_mirror');
|
|
$db->table(GoodsProfitAfsLookupSchema::TABLE)->update(['undefined9' => '2026/8/23 14:58:51']);
|
|
$db->table('ops_jst_goods_profit_kpi_items_afs_schemas')->where('name', '订单时间')->update(['column' => 'undefined9']);
|
|
$result = (new GoodsProfitAfsRepository())->paginate(['from' => '2026-08-23', 'to' => '2026-08-23'], 1, 25);
|
|
$this->assertCount(25, $result['rows']);
|
|
$this->assertSame('2026/8/23 14:58:51', $result['rows'][0]['order_time']);
|
|
}
|
|
|
|
public function test_positive_component_rows_are_returned_for_candidate_orders(): void
|
|
{
|
|
$db = DB::connection('business_mirror');
|
|
$db->table(GoodsProfitAfsLookupSchema::TABLE)->insert([
|
|
'id' => 100,
|
|
'undefined1' => 'ORDER-100',
|
|
'undefined2' => 'ONLINE-100',
|
|
'undefined7' => '2026/9/1 10:00:00',
|
|
'undefined8' => '测试店铺',
|
|
'undefined10' => 'INTERNAL-COMPONENT',
|
|
'undefined12' => 'SHOP-SKU',
|
|
'undefined13' => 'SHOP-ITEM',
|
|
'undefined20' => '2',
|
|
'undefined25' => '199.98',
|
|
]);
|
|
$db->table(GoodsProfitAfsLookupSchema::TABLE)->insert([
|
|
'id' => 101,
|
|
'undefined1' => 'ORDER-100',
|
|
'undefined2' => 'ONLINE-100',
|
|
'undefined7' => '',
|
|
'undefined8' => '测试店铺',
|
|
'undefined10' => 'ZERO-PLACEHOLDER',
|
|
'undefined12' => 'SHOP-SKU',
|
|
'undefined13' => 'SHOP-ITEM',
|
|
'undefined20' => '0',
|
|
'undefined25' => '0',
|
|
]);
|
|
|
|
$rows = (new GoodsProfitAfsRepository())->positiveComponentRowsForOrders(['ONLINE-100']);
|
|
|
|
$this->assertSame([[
|
|
'online_order_no' => 'ONLINE-100',
|
|
'shop_name' => '测试店铺',
|
|
'shop_sku_id' => 'SHOP-SKU',
|
|
'shop_i_id' => 'SHOP-ITEM',
|
|
'product_code' => 'INTERNAL-COMPONENT',
|
|
'product_quantity' => 2.0,
|
|
'product_amount' => 199.98,
|
|
]], $rows);
|
|
}
|
|
}
|