CaiWuXiTong/tests/Feature/Business/PerformanceDetailsMetricDetailsTest.php

251 lines
9.0 KiB
PHP

<?php
namespace Tests\Feature\Business;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Tests\Feature\FeatureTestCase;
class PerformanceDetailsMetricDetailsTest extends FeatureTestCase
{
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');
$this->createMirrorTables();
}
public function test_offset_metric_details_group_by_store_and_bill_item_and_reconcile_to_total(): void
{
$mirror = DB::connection('business_mirror');
$mirror->table('store_receipt_order_match_rows')->insert([
$this->row('row-a1', '店铺A', -100),
$this->row('row-a2', '店铺A', -200),
$this->row('row-b1', '店铺B', -50),
]);
$mirror->table('store_receipt_order_match_metric_details')->insert([
$this->detail('detail-a1', 'row-a1', '账单扣款', -60),
$this->detail('detail-a2', 'row-a1', '售后扣减', -40),
$this->detail('detail-a3', 'row-a2', '账单扣款', -200),
$this->detail('detail-b1', 'row-b1', '账单扣款', -50),
]);
$response = $this->loginAs()->getJson(route(
'business.financial-operations.performance-details.metric-details',
[
'metric' => 'offset_amount',
'month' => '2026-09',
'store_name' => ['店铺A'],
],
));
$response
->assertOk()
->assertJsonPath('label', '冲减收入')
->assertJsonPath('total', -300)
->assertJsonPath('detail_total', -300)
->assertJsonPath('balance', 0)
->assertJsonPath('balanced', true);
$rows = $response->json('rows');
$this->assertCount(2, $rows);
$this->assertContains([
'platform' => '京东账单',
'store_name' => '店铺A',
'bill_item' => '账单扣款',
'amount' => -260,
'line_count' => 2,
], $rows);
$this->assertContains([
'platform' => '京东账单',
'store_name' => '店铺A',
'bill_item' => '售后扣减',
'amount' => -40,
'line_count' => 1,
], $rows);
}
public function test_same_bill_item_is_split_by_platform_for_summary(): void
{
$mirror = DB::connection('business_mirror');
$mirror->table('store_receipt_order_match_rows')->insert([
$this->row('row-jd', '京东店铺', -100, '京东账单'),
$this->row('row-pdd', '拼多多店铺', -50, '拼多多'),
]);
$mirror->table('store_receipt_order_match_metric_details')->insert([
$this->detail('detail-jd', 'row-jd', '账单扣款', -100, '京东账单'),
$this->detail('detail-pdd', 'row-pdd', '账单扣款', -50, '拼多多'),
]);
$response = $this->loginAs()->getJson(route(
'business.financial-operations.performance-details.metric-details',
[
'metric' => 'offset_amount',
'month' => '2026-09',
],
));
$response
->assertOk()
->assertJsonPath('total', -150)
->assertJsonPath('detail_total', -150)
->assertJsonPath('balanced', true);
$this->assertContains([
'platform' => '京东账单',
'store_name' => '京东店铺',
'bill_item' => '账单扣款',
'amount' => -100,
'line_count' => 1,
], $response->json('rows'));
$this->assertContains([
'platform' => '拼多多',
'store_name' => '拼多多店铺',
'bill_item' => '账单扣款',
'amount' => -50,
'line_count' => 1,
], $response->json('rows'));
}
public function test_paid_metric_uses_the_amount_used_by_the_matching_basis(): void
{
$mirror = DB::connection('business_mirror');
$mirror->table('store_receipt_order_match_rows')->insert([
array_merge($this->row('row-basis', '店铺A', 0), [
'income_amount' => 10.00,
'paid_amount' => 13079.80,
'difference' => -13069.80,
'remark' => '订单实付按应付/已付核对',
]),
array_merge($this->row('row-normal', '店铺B', 0), [
'income_amount' => 80.00,
'paid_amount' => 100.00,
'difference' => -20.00,
]),
]);
$response = $this->loginAs()->getJson(route(
'business.financial-operations.performance-details.metric-details',
[
'metric' => 'paid_amount',
'month' => '2026-09',
],
));
$response
->assertOk()
->assertJsonPath('label', '订单核对金额')
->assertJsonPath('total', 110)
->assertJsonPath('detail_total', 110)
->assertJsonPath('balanced', true);
$this->assertContains([
'platform' => '京东账单',
'store_name' => '店铺A',
'bill_item' => '订单核对金额',
'amount' => 10,
'line_count' => 1,
], $response->json('rows'));
$this->assertContains([
'platform' => '京东账单',
'store_name' => '店铺B',
'bill_item' => '订单核对金额',
'amount' => 100,
'line_count' => 1,
], $response->json('rows'));
}
private function row(string $rowKey, string $storeName, float $offset, string $platform = '京东账单'): array
{
return [
'report_month' => '2026-09-01',
'platform' => $platform,
'row_key' => $rowKey,
'occurred_date' => '2026-09-01',
'store_name' => $storeName,
'online_order_no' => 'ORDER-' . $rowKey,
'payment_count' => 1,
'income_amount' => 0,
'discount_amount' => 0,
'offset_amount' => $offset,
'default_compensation_amount' => 0,
'refund_amount' => 0,
'planting_amount' => null,
'paid_amount' => 0,
'difference' => 0,
'cross_month_balanced' => false,
'match_status' => '已匹配',
'remark' => null,
'imported_at' => now(),
];
}
private function detail(
string $detailKey,
string $rowKey,
string $billItem,
float $amount,
string $platform = '京东账单'
): array
{
return [
'report_month' => '2026-09-01',
'detail_key' => $detailKey,
'row_key' => $rowKey,
'platform' => $platform,
'metric' => 'offset',
'bill_item' => $billItem,
'amount' => $amount,
'line_count' => 1,
'imported_at' => now(),
];
}
private function createMirrorTables(): void
{
$schema = Schema::connection('business_mirror');
$schema->create('store_receipt_order_match_rows', function (Blueprint $table): void {
$table->date('report_month');
$table->string('platform');
$table->string('row_key');
$table->date('occurred_date')->nullable();
$table->string('store_name')->nullable();
$table->string('online_order_no')->nullable();
$table->unsignedInteger('payment_count')->default(0);
$table->decimal('income_amount', 20, 4)->default(0);
$table->decimal('discount_amount', 20, 4)->nullable();
$table->decimal('offset_amount', 20, 4)->nullable();
$table->decimal('default_compensation_amount', 20, 4)->nullable();
$table->decimal('refund_amount', 20, 4)->nullable();
$table->decimal('planting_amount', 20, 4)->nullable();
$table->decimal('paid_amount', 20, 4)->nullable();
$table->decimal('difference', 20, 4)->nullable();
$table->boolean('cross_month_balanced')->default(false);
$table->string('match_status', 32)->nullable();
$table->string('remark', 191)->nullable();
$table->dateTime('imported_at');
});
$schema->create('store_receipt_order_match_metric_details', function (Blueprint $table): void {
$table->date('report_month');
$table->string('detail_key');
$table->string('row_key');
$table->string('platform');
$table->string('metric');
$table->string('bill_item');
$table->decimal('amount', 20, 4)->default(0);
$table->unsignedInteger('line_count')->default(1);
$table->dateTime('imported_at');
});
}
}