175 lines
7.2 KiB
PHP
175 lines
7.2 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\EcommerceFinance;
|
|
|
|
use Modules\EcommerceFinance\Repositories\OrderDataRepository;
|
|
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery;
|
|
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQueryFactory;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class OrderDataRepositoryTest extends TestCase
|
|
{
|
|
public function test_after_sales_uses_fixed_joins_parameterized_filters_and_overfetch_pagination(): void
|
|
{
|
|
$query = $this->createMock(UpstreamReadOnlyQuery::class);
|
|
$call = 0;
|
|
$query->expects($this->exactly(2))->method('select')->willReturnCallback(
|
|
function (string $sql, array $bindings) use (&$call): array {
|
|
$call++;
|
|
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
|
|
|
|
if ($call === 2) {
|
|
$this->assertStringContainsString('[rpt].[jst_returnAndRefundInfo]', $sql);
|
|
$this->assertSame(['1'], $bindings);
|
|
|
|
return [[
|
|
'internal_order_no' => '1',
|
|
'after_sales_id' => 'AF-1',
|
|
'after_sales_time' => '2026-08-02 12:00:00',
|
|
'sub_order_no' => 'SUB-1',
|
|
'product_code' => 'SKU-1',
|
|
'application_quantity' => '1',
|
|
'application_amount' => '6.00',
|
|
'return_quantity' => '1',
|
|
'return_amount' => '6.00',
|
|
]];
|
|
}
|
|
|
|
$this->assertStringContainsString('[rpt].[jst_Orders]', $sql);
|
|
$this->assertStringContainsString('[rpt].[jst_OrderItem]', $sql);
|
|
$this->assertStringContainsString('OFFSET 2 ROWS FETCH NEXT 3 ROWS ONLY', $sql);
|
|
$this->assertStringNotContainsString('COUNT(*) OVER', $sql);
|
|
$this->assertSame([
|
|
'2026-08-01',
|
|
'2026-08-02',
|
|
'%SO\%\_%',
|
|
'%SO\%\_%',
|
|
'%SO\%\_%',
|
|
'%JD%',
|
|
'%SKU%',
|
|
'%SKU%',
|
|
'%SKU%',
|
|
], $bindings);
|
|
|
|
return [[
|
|
'internal_order_no' => '1',
|
|
'sub_order_no' => 'SUB-1',
|
|
'product_code' => 'SKU-1',
|
|
'shop_site' => 'jd',
|
|
'shop_style_code' => '1001',
|
|
'send_time' => '2026-08-02 10:00:00',
|
|
'unit_cost' => '3.00',
|
|
'product_amount' => '12.34',
|
|
'product_quantity' => '2',
|
|
'actual_shipped_amount' => '12.34',
|
|
'actual_shipped_quantity' => '2',
|
|
'actual_shipped_cost' => '6.00',
|
|
'pre_application_quantity' => '0',
|
|
'pre_application_amount' => '0',
|
|
'pre_application_cost' => '0',
|
|
'pre_return_quantity' => '0',
|
|
'pre_return_amount' => '0',
|
|
'pre_return_cost' => '0',
|
|
'pre_refund_amount' => '0',
|
|
'pre_refund_cost' => '0',
|
|
'pre_platform_subsidy' => '0',
|
|
'post_application_quantity' => '0',
|
|
'post_application_amount' => '0',
|
|
'post_application_cost' => '0',
|
|
'post_return_quantity' => '0',
|
|
'post_return_amount' => '0',
|
|
'post_return_cost' => '0',
|
|
'post_refund_amount' => '0',
|
|
'post_refund_cost' => '0',
|
|
'post_platform_subsidy' => '0',
|
|
'defective_quantity' => '0',
|
|
]];
|
|
},
|
|
);
|
|
|
|
$result = (new OrderDataRepository($this->factory($query)))->afterSales([
|
|
'from' => '2026-08-01',
|
|
'to' => '2026-08-02',
|
|
'order_no' => 'SO%_',
|
|
'shop_name' => 'JD',
|
|
'sku_id' => 'SKU',
|
|
], 2, 2);
|
|
|
|
$this->assertCount(1, $result['rows']);
|
|
$this->assertSame(12.34, $result['rows'][0]['product_amount']);
|
|
$this->assertSame(2.0, $result['rows'][0]['product_quantity']);
|
|
$this->assertSame('https://item.jd.com/1001.html', $result['rows'][0]['product_link']);
|
|
$this->assertSame('AF-1', $result['rows'][0]['after_sales_no']);
|
|
$this->assertSame(1.0, $result['rows'][0]['post_return_quantity']);
|
|
$this->assertNull($result['rows'][0]['account_500112']);
|
|
$this->assertNull($result['rows'][0]['account_8001201']);
|
|
}
|
|
|
|
public function test_promotion_expenses_use_one_statistics_date_and_map_only_the_page_rows(): void
|
|
{
|
|
$query = $this->createMock(UpstreamReadOnlyQuery::class);
|
|
$call = 0;
|
|
$query->expects($this->exactly(2))->method('select')->willReturnCallback(
|
|
function (string $sql, array $bindings) use (&$call): array {
|
|
$call++;
|
|
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
|
|
|
|
if ($call === 2) {
|
|
$this->assertStringContainsString('[rpt].[jst_skumap]', $sql);
|
|
$this->assertSame(['ITEM-1'], $bindings);
|
|
|
|
return [[
|
|
'shop_style_code' => 'ITEM-1',
|
|
'shop_name' => 'JD',
|
|
'product_code' => 'SKU-1',
|
|
'style_code' => 'STYLE-1',
|
|
'shop_product_code' => 'SHOP-SKU-1',
|
|
'online_color_spec' => '黑色',
|
|
]];
|
|
}
|
|
|
|
$this->assertStringContainsString('[rpt].[ads_itemid_sales_cost_ratio_v2_di]', $sql);
|
|
$this->assertStringContainsString('OFFSET 3 ROWS FETCH NEXT 4 ROWS ONLY', $sql);
|
|
$this->assertStringContainsString('FROM paged p', $sql);
|
|
$this->assertStringNotContainsString('SUM(c.[push_fee])', $sql);
|
|
$this->assertStringNotContainsString('COUNT(*) OVER', $sql);
|
|
$this->assertSame([
|
|
'2026-08-09',
|
|
'%JD%',
|
|
'%SKU\_%',
|
|
'%SKU\_%',
|
|
'%SKU\_%',
|
|
'%SKU\_%',
|
|
], $bindings);
|
|
|
|
return [[
|
|
'shop_name' => 'JD',
|
|
'shop_style_code' => 'ITEM-1',
|
|
'promotion_fee' => '9.05',
|
|
]];
|
|
},
|
|
);
|
|
|
|
$result = (new OrderDataRepository($this->factory($query)))->promotionExpenses([
|
|
'date' => '2026-08-09',
|
|
'shop_name' => 'JD',
|
|
'sku_id' => 'SKU_',
|
|
], 2, 3);
|
|
|
|
$this->assertSame('2026-08-09', $result['date']);
|
|
$this->assertSame(9.05, $result['rows'][0]['promotion_fee']);
|
|
$this->assertSame('SKU-1', $result['rows'][0]['product_code']);
|
|
}
|
|
|
|
private function factory(UpstreamReadOnlyQuery $query): UpstreamReadOnlyQueryFactory
|
|
{
|
|
$factory = $this->createMock(UpstreamReadOnlyQueryFactory::class);
|
|
$factory->expects($this->once())
|
|
->method('forSource')
|
|
->with('operations_replica')
|
|
->willReturn($query);
|
|
|
|
return $factory;
|
|
}
|
|
}
|