251 lines
9.0 KiB
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');
|
|
});
|
|
}
|
|
}
|