166 lines
9.3 KiB
PHP
166 lines
9.3 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\EcommerceFinance;
|
|
|
|
use Illuminate\Database\Schema\Blueprint;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Mockery;
|
|
use Modules\EcommerceFinance\Repositories\GenericBusinessMirrorRepository;
|
|
use Modules\EcommerceFinance\Repositories\OrderDataMirrorRepository;
|
|
use Modules\EcommerceFinance\Services\BusinessMirrorDatasetRegistry;
|
|
use Tests\TestCase;
|
|
|
|
class OrderDataMirrorRepositoryTest extends TestCase
|
|
{
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
config(['database.connections.business_mirror' => [
|
|
'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '',
|
|
]]);
|
|
DB::purge('business_mirror');
|
|
$this->createTables();
|
|
}
|
|
|
|
public function test_after_sales_reads_complete_rows_from_shared_mirror(): void
|
|
{
|
|
$db = DB::connection('business_mirror');
|
|
$db->table('ops_jst_orders')->insert([
|
|
'o_id' => 1, 'so_id' => 'SO-1', 'pay_date' => '2026-08-01 08:00:00',
|
|
'end_time' => '2026-08-02 12:00:00', 'send_date' => '2026-08-02 10:00:00',
|
|
'order_date' => '2026-08-01 09:00:00', 'shop_name' => '京东店铺',
|
|
'shop_id' => 'SHOP-1', 'shop_site' => 'jd', 'type' => '普通订单',
|
|
'labels' => '正常', 'wms_co_id' => 'WH-1', 'l_id' => 'EXP-1',
|
|
'logistics_company' => '物流', 'receiver_state' => '江苏', 'receiver_city' => '常州',
|
|
'creator_name' => '销售员', 'free_amount' => 2, 'freight' => 5,
|
|
]);
|
|
$db->table('ops_jst_order_item')->insert([
|
|
'oi_id' => 11, 'o_id' => 1, 'outer_oi_id' => 'SUB-1', 'sku_id' => 'SKU-1',
|
|
'i_id' => 'STYLE-1', 'shop_sku_id' => 'SHOP-SKU-1', 'shop_i_id' => '1001',
|
|
'properties_value' => '黑色', 'name' => '线上商品', 'qty' => 2,
|
|
'amount' => 100, 'buyer_paid_amount' => 95, 'seller_income_amount' => 98,
|
|
'is_gift' => 0, 'src_combine_sku_id' => null, 'send_warehouse' => 'WH-1',
|
|
]);
|
|
$db->table('ops_jst_sku')->insert([
|
|
'autoid' => 1, 'sku_type' => 'normal', 'sku_id' => 'SKU-1', 'brand' => '品牌A', 'category' => '家具', 'vc_name' => '桌子',
|
|
'cost_price' => 20, 'name' => '镜像商品', 'supplier_id' => 'SUP-1', 'supplier_name' => '供应商A',
|
|
]);
|
|
$db->table('ops_jst_warehouse_info')->insert([
|
|
'wms_co_id' => 'WH-1', 'name' => '主仓', 'remark1' => '运营云仓',
|
|
]);
|
|
$db->table('ops_jst_return_refund_info')->insert([
|
|
'as_id' => 21, 'outer_as_id' => 'AF-1', 'o_id' => 1,
|
|
'as_date' => '2026-08-02 12:00:00', 'type' => '退货退款',
|
|
'question_type' => '质量问题', 'labels' => '售后', 'refund' => 50, 'free_amount' => 3,
|
|
]);
|
|
$db->table('ops_jst_return_refund_item')->insert([
|
|
'as_id' => 21, 'outer_oi_id' => 'SUB-1', 'sku_id' => 'SKU-1', 'type' => '退货',
|
|
'qty' => 1, 'amount' => 50, 'r_qty' => 1, 'shop_amount' => 50, 'defective_qty' => 1,
|
|
]);
|
|
$mirror = Mockery::mock(GenericBusinessMirrorRepository::class);
|
|
$mirror->shouldReceive('connection')->andReturn($db);
|
|
$repository = new OrderDataMirrorRepository(
|
|
Mockery::mock(BusinessMirrorDatasetRegistry::class), $mirror,
|
|
);
|
|
|
|
$result = $repository->afterSales([
|
|
'from' => '2026-08-01', 'to' => '2026-08-02',
|
|
'order_no' => '', 'shop_name' => '', 'sku_id' => '',
|
|
], 1, 25);
|
|
|
|
$this->assertCount(1, $result['rows']);
|
|
$row = $result['rows'][0];
|
|
$this->assertSame('SO-1', $row['online_order_no']);
|
|
$this->assertSame('AF-1', $row['after_sales_no']);
|
|
$this->assertSame(40.0, $row['product_cost']);
|
|
$this->assertSame(1.0, $row['post_return_quantity']);
|
|
$this->assertSame('https://item.jd.com/1001.html', $row['product_link']);
|
|
$this->assertNull($row['account_8001201']);
|
|
}
|
|
|
|
public function test_promotion_expenses_use_the_bill_item_without_scanning_the_large_sku_map(): void
|
|
{
|
|
$db = DB::connection('business_mirror');
|
|
$db->table('ops_item_sales_cost_ratio')->insert([
|
|
'stat_date' => '2026-08-09 00:00:00', 'shop_name' => '京东店铺',
|
|
'item_id' => 'ITEM-1', 'push_fee' => 9.05,
|
|
]);
|
|
$mirror = Mockery::mock(GenericBusinessMirrorRepository::class);
|
|
$mirror->shouldReceive('connection')->andReturn($db);
|
|
$repository = new OrderDataMirrorRepository(
|
|
Mockery::mock(BusinessMirrorDatasetRegistry::class), $mirror,
|
|
);
|
|
|
|
$result = $repository->promotionExpenses([
|
|
'date' => '2026-08-09', 'shop_name' => '', 'sku_id' => '',
|
|
], 1, 25);
|
|
|
|
$this->assertSame('2026-08-09', $result['date']);
|
|
$this->assertNull($result['rows'][0]['product_code']);
|
|
$this->assertSame('ITEM-1', $result['rows'][0]['shop_product_code']);
|
|
$this->assertSame(9.05, $result['rows'][0]['promotion_fee']);
|
|
}
|
|
|
|
public function test_promotion_readiness_does_not_wait_for_the_unused_sku_map(): void
|
|
{
|
|
$datasets = app(BusinessMirrorDatasetRegistry::class);
|
|
$mirror = Mockery::mock(GenericBusinessMirrorRepository::class);
|
|
$mirror->shouldReceive('connection')->andReturn(DB::connection('business_mirror'));
|
|
$mirror->shouldReceive('ready')->once()->andReturnTrue();
|
|
|
|
$this->assertTrue((new OrderDataMirrorRepository($datasets, $mirror))->promotionReady());
|
|
}
|
|
|
|
private function createTables(): void
|
|
{
|
|
$schema = Schema::connection('business_mirror');
|
|
$schema->create('ops_jst_orders', function (Blueprint $t): void {
|
|
$t->integer('o_id'); $t->string('so_id')->nullable(); $t->dateTime('pay_date')->nullable();
|
|
$t->dateTime('end_time')->nullable(); $t->dateTime('send_date')->nullable(); $t->dateTime('order_date');
|
|
$t->string('shop_name'); $t->string('shop_id')->nullable(); $t->string('shop_site')->nullable();
|
|
$t->string('type')->nullable(); $t->string('labels')->nullable(); $t->string('wms_co_id')->nullable();
|
|
$t->string('l_id')->nullable(); $t->string('logistics_company')->nullable();
|
|
$t->string('receiver_state')->nullable(); $t->string('receiver_city')->nullable();
|
|
$t->string('creator_name')->nullable(); $t->decimal('free_amount')->nullable(); $t->decimal('freight')->nullable();
|
|
});
|
|
$schema->create('ops_jst_order_item', function (Blueprint $t): void {
|
|
$t->integer('oi_id'); $t->integer('o_id'); $t->string('outer_oi_id')->nullable();
|
|
$t->string('sku_id'); $t->string('i_id')->nullable(); $t->string('shop_sku_id')->nullable();
|
|
$t->string('shop_i_id')->nullable(); $t->string('properties_value')->nullable(); $t->string('name')->nullable();
|
|
$t->decimal('qty')->nullable(); $t->decimal('amount')->nullable(); $t->decimal('buyer_paid_amount')->nullable();
|
|
$t->decimal('seller_income_amount')->nullable(); $t->integer('is_gift')->nullable();
|
|
$t->string('src_combine_sku_id')->nullable(); $t->string('send_warehouse')->nullable();
|
|
});
|
|
$schema->create('ops_jst_sku', function (Blueprint $t): void {
|
|
$t->integer('autoid'); $t->string('sku_type'); $t->string('sku_id'); $t->string('brand')->nullable(); $t->string('category')->nullable();
|
|
$t->string('vc_name')->nullable(); $t->decimal('cost_price')->nullable(); $t->string('name')->nullable();
|
|
$t->string('supplier_id')->nullable(); $t->string('supplier_name')->nullable();
|
|
});
|
|
$schema->create('ops_jst_warehouse_info', function (Blueprint $t): void {
|
|
$t->string('wms_co_id'); $t->string('name')->nullable(); $t->string('remark1')->nullable();
|
|
});
|
|
$schema->create('ops_jst_return_refund_info', function (Blueprint $t): void {
|
|
$t->integer('as_id'); $t->string('outer_as_id')->nullable(); $t->integer('o_id');
|
|
$t->dateTime('as_date'); $t->string('type')->nullable(); $t->string('question_type')->nullable();
|
|
$t->string('labels')->nullable(); $t->decimal('refund')->nullable(); $t->decimal('free_amount')->nullable();
|
|
});
|
|
$schema->create('ops_jst_return_refund_item', function (Blueprint $t): void {
|
|
$t->integer('as_id'); $t->string('outer_oi_id')->nullable(); $t->string('sku_id')->nullable();
|
|
$t->string('type')->nullable(); $t->decimal('qty')->nullable(); $t->decimal('amount')->nullable();
|
|
$t->decimal('r_qty')->nullable(); $t->decimal('shop_amount')->nullable(); $t->decimal('defective_qty')->nullable();
|
|
});
|
|
$schema->create('ops_item_sales_cost_ratio', function (Blueprint $t): void {
|
|
$t->dateTime('stat_date'); $t->string('shop_name'); $t->string('item_id'); $t->decimal('push_fee');
|
|
});
|
|
$schema->create('ops_jst_sku_map', function (Blueprint $t): void {
|
|
$t->string('shop_i_id'); $t->integer('shop_id'); $t->string('sku_id')->nullable();
|
|
$t->string('i_id')->nullable(); $t->string('shop_sku_id')->nullable();
|
|
$t->string('properties_value')->nullable(); $t->dateTime('modified')->nullable();
|
|
});
|
|
$schema->create('ops_jst_shop_info', function (Blueprint $t): void {
|
|
$t->integer('shop_id'); $t->string('shop_name');
|
|
});
|
|
}
|
|
}
|