CaiWuXiTong/tests/Unit/EcommerceFinance/StoreReceivingBalanceOverviewServiceTest.php

174 lines
7.0 KiB
PHP

<?php
namespace Tests\Unit\EcommerceFinance;
use Modules\EcommerceFinance\Services\StoreReceivingBalanceOverviewService;
use PHPUnit\Framework\TestCase;
class StoreReceivingBalanceOverviewServiceTest extends TestCase
{
public function test_overview_sums_all_eight_platforms_for_the_selected_month(): void
{
$seenPeriods = [];
$service = $this->service(function (string $platform, string $start, string $end) use (&$seenPeriods): array {
$seenPeriods[] = [$platform, $start, $end];
$index = array_search($platform, array_column(StoreReceivingBalanceOverviewService::PLATFORMS, 'slug'), true) + 1;
return [
'opening_balance' => 100.10 * $index,
'income' => 10.20 * $index,
'expense' => 1.25 * $index,
];
});
$result = $service->overview('2026-10');
$this->assertSame('2026-10', $result['month']);
$this->assertSame(['start' => '2026-10-01', 'end' => '2026-10-31'], $result['period']);
$this->assertCount(8, $result['platforms']);
$this->assertCount(8, $seenPeriods);
$this->assertSame('taobao-alipay', $seenPeriods[0][0]);
$this->assertSame('xiaohongshu', $seenPeriods[7][0]);
$this->assertSame(3603.60, $result['summary']['opening_balance']);
$this->assertSame(367.20, $result['summary']['income']);
$this->assertSame(45.00, $result['summary']['expense']);
$this->assertSame(3925.80, $result['summary']['balance']);
$this->assertTrue($result['summary']['complete']);
$this->assertSame(8, $result['summary']['available_platform_count']);
}
public function test_overview_does_not_report_a_total_when_an_opening_balance_is_missing(): void
{
$service = $this->service(function (string $platform): array {
return [
'opening_balance' => $platform === 'vipshop-jx' ? null : 25.0,
'income' => 5.0,
'expense' => 2.0,
];
});
$result = $service->overview('2026-09');
$this->assertFalse($result['summary']['complete']);
$this->assertNull($result['summary']['opening_balance']);
$this->assertNull($result['summary']['income']);
$this->assertNull($result['summary']['expense']);
$this->assertNull($result['summary']['balance']);
$this->assertSame(7, $result['summary']['available_platform_count']);
$vipshopJx = array_values(array_filter(
$result['platforms'],
static fn (array $platform): bool => $platform['slug'] === 'vipshop-jx',
))[0];
$this->assertFalse($vipshopJx['available']);
}
public function test_income_detail_groups_platform_store_and_bill_item_rows(): void
{
$service = new class extends StoreReceivingBalanceOverviewService {
public function __construct()
{
}
protected function fetchPlatformIncomeRows(string $platform, string $start, string $end): iterable
{
$index = array_search($platform, array_column(StoreReceivingBalanceOverviewService::PLATFORMS, 'slug'), true) + 1;
yield [
'store_name' => '店铺-' . $index,
'bill_item' => '货款收入',
'income' => 100.10 * $index,
];
yield [
'store_name' => '店铺-' . $index,
'bill_item' => '货款收入',
'income' => 0.20 * $index,
];
yield [
'store_name' => '店铺-' . $index,
'bill_item' => '退款',
'income' => 0,
];
}
};
$result = $service->incomeDetail('2026-10');
$this->assertSame('2026-10', $result['month']);
$this->assertSame(['start' => '2026-10-01', 'end' => '2026-10-31'], $result['period']);
$this->assertCount(8, $result['details']);
$this->assertSame([
'platform_slug' => 'taobao-alipay',
'platform' => '淘系支付宝账户',
'store_name' => '店铺-1',
'bill_item' => '货款收入',
'amount' => 100.30,
], $result['details'][0]);
$this->assertSame('xiaohongshu', $result['details'][7]['platform_slug']);
$this->assertSame(3610.80, $result['summary']['income']);
$this->assertTrue($result['summary']['complete']);
$this->assertSame(8, $result['summary']['available_platform_count']);
}
public function test_expense_detail_groups_platform_store_and_bill_item_rows(): void
{
$service = new class extends StoreReceivingBalanceOverviewService {
public function __construct()
{
}
protected function fetchPlatformExpenseRows(string $platform, string $start, string $end): iterable
{
$index = array_search($platform, array_column(StoreReceivingBalanceOverviewService::PLATFORMS, 'slug'), true) + 1;
yield [
'store_name' => '店铺-' . $index,
'bill_item' => '平台扣费',
'expense' => 20.10 * $index,
];
yield [
'store_name' => '店铺-' . $index,
'bill_item' => '平台扣费',
'expense' => 0.20 * $index,
];
yield [
'store_name' => '店铺-' . $index,
'bill_item' => '退款',
'expense' => 0,
];
}
};
$result = $service->expenseDetail('2026-10');
$this->assertSame('2026-10', $result['month']);
$this->assertSame(['start' => '2026-10-01', 'end' => '2026-10-31'], $result['period']);
$this->assertCount(8, $result['details']);
$this->assertSame([
'platform_slug' => 'taobao-alipay',
'platform' => '淘系支付宝账户',
'store_name' => '店铺-1',
'bill_item' => '平台扣费',
'amount' => 20.30,
], $result['details'][0]);
$this->assertSame('xiaohongshu', $result['details'][7]['platform_slug']);
$this->assertSame(730.80, $result['summary']['expense']);
$this->assertArrayNotHasKey('income', $result['summary']);
$this->assertTrue($result['summary']['complete']);
$this->assertSame(8, $result['summary']['available_platform_count']);
}
private function service(callable $summary): StoreReceivingBalanceOverviewService
{
return new class($summary) extends StoreReceivingBalanceOverviewService {
public function __construct(private $summaryCallback)
{
}
protected function fetchPlatformSummary(string $platform, string $start, string $end): array
{
return ($this->summaryCallback)($platform, $start, $end);
}
};
}
}