CaiWuXiTong/tests/Unit/EcommerceFinance/TmallTaobaoSpreadBillRepositoryTest.php
chenxi 5511dfb221 恢复店铺营销账户余额页面 (#40)
恢复淘系与拼多多营销账户月度余额汇总、筛选、分页和导出。
2026-08-13 11:41:42 +08:00

135 lines
5.4 KiB
PHP

<?php
namespace Tests\Unit\EcommerceFinance;
use Modules\EcommerceFinance\Repositories\TmallTaobaoSpreadBillRepository;
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery;
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQueryFactory;
use PHPUnit\Framework\TestCase;
class TmallTaobaoSpreadBillRepositoryTest extends TestCase
{
public function test_monthly_balances_convert_cents_and_reconcile_by_store_and_month(): void
{
$query = new class('jiansun') extends UpstreamReadOnlyQuery {
public array $calls = [];
public function scalar(string $sql, array $bindings = []): mixed
{
$this->calls[] = compact('sql', 'bindings') + ['method' => 'scalar'];
return 1;
}
public function select(string $sql, array $bindings = []): array
{
$this->calls[] = compact('sql', 'bindings') + ['method' => 'select'];
return [[
'shopName' => '淘系_测试店铺',
'balance_date' => '2026-06-30',
'opening_balance_raw' => 100000,
'income_total_raw' => 50000,
'expense_total_raw' => 20000,
'system_closing_balance_raw' => 130000,
]];
}
};
$factory = new class($query) extends UpstreamReadOnlyQueryFactory {
public function __construct(private readonly UpstreamReadOnlyQuery $query) {}
public function forSource(string $source): UpstreamReadOnlyQuery { return $this->query; }
};
$result = (new TmallTaobaoSpreadBillRepository($factory))->paginateMonthlyBalances(
'淘系_测试店铺', '2026-06', 2, 25,
);
$row = $result['rows'][0];
$this->assertSame(1000.0, $row['opening_balance']);
$this->assertSame(500.0, $row['income_total']);
$this->assertSame(200.0, $row['expense_total']);
$this->assertSame(1300.0, $row['closing_balance']);
$this->assertSame(0.0, $row['balance_difference']);
$this->assertSame('已核对', $row['verification_status']);
$this->assertStringContainsString("finType = 'DEBIT'", $query->calls[1]['sql']);
$this->assertStringContainsString("finType = 'CREDIT'", $query->calls[1]['sql']);
$this->assertSame(['淘系_测试店铺', '2026-06-01', '2026-06-01', 26, 50], $query->calls[1]['bindings']);
}
public function test_filters_and_cent_amounts_are_normalized_consistently(): void
{
$query = new class('jiansun') extends UpstreamReadOnlyQuery {
/** @var array<int,array{method:string,sql:string,bindings:array}> */
public array $calls = [];
public function scalar(string $sql, array $bindings = []): mixed
{
$this->calls[] = compact('sql', 'bindings') + ['method' => 'scalar'];
return 1;
}
public function select(string $sql, array $bindings = []): array
{
$this->calls[] = compact('sql', 'bindings') + ['method' => 'select'];
return [[
'shopName' => '测试店铺',
'uniTransTime' => '2026-07-23 12:00:00',
'transTime' => '2026-07-23',
'amount' => 15050,
'balance' => 990050,
'comment' => '测试流水',
'finType' => 'DEBIT',
'bizType' => 'INTEL_CHARGE_POST',
'tradeType' => '',
]];
}
public function first(string $sql, array $bindings = []): ?array
{
$this->calls[] = compact('sql', 'bindings') + ['method' => 'first'];
return [
'income_total_raw' => 15050,
'expense_total_raw' => 0,
'cnt' => 1,
];
}
};
$factory = new class($query) extends UpstreamReadOnlyQueryFactory {
public function __construct(private readonly UpstreamReadOnlyQuery $query)
{
}
public function forSource(string $source): UpstreamReadOnlyQuery
{
TestCase::assertSame('jiansun', $source);
return $this->query;
}
};
$repository = new TmallTaobaoSpreadBillRepository($factory);
$page = $repository->paginate('测试店铺', '2026-07-01', '2026-07-23', 'income', 1, 25);
$summary = $repository->summary('测试店铺', '2026-07-01', '2026-07-23', 'income');
$this->assertSame(1, $page['total']);
$this->assertSame(150.5, $page['rows'][0]['amount']);
$this->assertSame(9900.5, $page['rows'][0]['balance']);
$this->assertSame('收入', $page['rows'][0]['income_expense_type']);
$this->assertSame('充值', $page['rows'][0]['transaction_type']);
$this->assertSame(150.5, $summary['income_total']);
$this->assertSame(150.5, $summary['net']);
$this->assertStringContainsString('finType = \'DEBIT\'', $query->calls[0]['sql']);
$this->assertSame(
['测试店铺', '2026-07-01', '2026-07-23'],
$query->calls[0]['bindings']
);
$this->assertStringContainsString('finType = \'DEBIT\'', $query->calls[1]['sql']);
$this->assertStringContainsString('finType = \'DEBIT\'', $query->calls[2]['sql']);
}
}