CaiWuXiTong/tests/Unit/EcommerceFinance/TaobaoWechatOpeningBalanceRepositoryTest.php

131 lines
4.8 KiB
PHP

<?php
namespace Tests\Unit\EcommerceFinance;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Modules\EcommerceFinance\Repositories\TaobaoWechatOpeningBalanceRepository;
use Tests\TestCase;
class TaobaoWechatOpeningBalanceRepositoryTest extends TestCase
{
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->createTables();
}
public function test_july_opening_uses_the_june_ending_balance(): void
{
$this->insertOpening('淘系微信一店', '669385.40');
$result = app(TaobaoWechatOpeningBalanceRepository::class)
->openingBalance('淘系微信一店', '2026-07-01');
$this->assertSame(669385.4, $result['balance']);
$this->assertSame('2026-06-30', $result['date']);
$this->assertSame('data_cube_june_ending', $result['source']);
$this->assertSame(1, $result['store_count']);
}
public function test_later_periods_carry_the_opening_balance_forward(): void
{
$this->insertOpening('淘系微信一店', '100.00');
$this->insertBill('淘系微信一店', '2026-07-05 10:00:00', '50.00', '20.00');
$this->insertBill('淘系微信一店', '2026-08-02 10:00:00', '10.00', '5.00');
$result = app(TaobaoWechatOpeningBalanceRepository::class)
->openingBalance('淘系微信一店', '2026-08-01');
$this->assertSame(130.0, $result['balance']);
$this->assertSame('2026-07-31', $result['date']);
$this->assertSame('data_cube_june_ending_carried_forward', $result['source']);
}
public function test_all_store_openings_are_summed_when_no_store_is_selected(): void
{
$this->insertOpening('淘系微信一店', '100.00');
$this->insertOpening('淘系微信二店', '200.25');
$result = app(TaobaoWechatOpeningBalanceRepository::class)
->openingBalance(null, '2026-07-01');
$this->assertSame(300.25, $result['balance']);
$this->assertSame(2, $result['store_count']);
}
public function test_missing_opening_balance_is_unavailable(): void
{
$result = app(TaobaoWechatOpeningBalanceRepository::class)
->openingBalance('未录入店铺', '2026-07-01');
$this->assertNull($result['balance']);
$this->assertNull($result['date']);
$this->assertSame('unavailable', $result['source']);
$this->assertSame(0, $result['store_count']);
}
private function createTables(): void
{
$schema = Schema::connection('business_mirror');
$schema->create(TaobaoWechatOpeningBalanceRepository::TABLE, function (Blueprint $table): void {
$table->id();
$table->date('balance_date');
$table->string('store_name', 191);
$table->decimal('balance', 20, 2);
$table->string('source', 191);
$table->text('source_note')->nullable();
$table->timestamp('imported_at');
$table->timestamps();
$table->unique(['balance_date', 'store_name']);
});
$schema->create('taobao_wechat_bill_rows', function (Blueprint $table): void {
$table->string('record_code', 191)->primary();
$table->string('store_name')->nullable();
$table->dateTime('occurred_at');
$table->decimal('income_amount', 20, 2);
$table->decimal('expense_amount', 20, 2);
});
}
private function insertOpening(string $storeName, string $balance): void
{
DB::connection('business_mirror')->table(TaobaoWechatOpeningBalanceRepository::TABLE)->insert([
'balance_date' => '2026-06-30',
'store_name' => $storeName,
'balance' => $balance,
'source' => 'DataCube淘系微信7月首笔余额倒推',
'source_note' => '用7月第一笔交易后的账户余额减去第一笔交易金额',
'imported_at' => '2026-11-09 10:00:00',
]);
}
private function insertBill(
string $storeName,
string $occurredAt,
string $income,
string $expense,
): void {
static $sequence = 0;
$sequence++;
DB::connection('business_mirror')->table('taobao_wechat_bill_rows')->insert([
'record_code' => 'TEST-' . $sequence,
'store_name' => $storeName,
'occurred_at' => $occurredAt,
'income_amount' => $income,
'expense_amount' => $expense,
]);
}
}