CaiWuXiTong/tests/Unit/EcommerceFinance/TaobaoAlipaySettlementBillRepositoryTest.php
qiuxiang 40d3ce162a feat: 淘系微信账单增加淘系支付宝账户余额 (#898)
淘系微信账户新增期初余额与淘系支付宝期末余额。

测试:7 tests / 41 assertions;前端生产构建通过。
2026-11-05 18:36:23 +08:00

204 lines
8.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Tests\Unit\EcommerceFinance;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Contracts\Console\Kernel;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Modules\EcommerceFinance\Repositories\TaobaoAlipaySettlementBillRepository;
use PHPUnit\Framework\TestCase;
class TaobaoAlipaySettlementBillRepositoryTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
$app = require dirname(__DIR__, 3) . '/bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
config([
'database.connections.business_mirror' => [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
],
'upstream_mirrors.connection' => 'business_mirror',
]);
DB::purge('business_mirror');
Cache::flush();
$this->createTables();
}
public function test_month_balance_uses_previous_account_balances_plus_month_flow(): void
{
$rows = DB::connection('business_mirror')->table('taobao_alipay_bill_rows');
$rows->insert([
$this->row('A-SEP-1', '天猫-A店', '20880001', '2026-09-30 23:58:00', '0', '0', '100', 10),
$this->row('A-SEP-2', '天猫-A店', '20880001', '2026-09-30 23:59:59', '0', '0', '150', 20),
// 同一时间的两笔按源表行号取后一笔。
$this->row('A-SEP-3', '天猫-A店', '20880001', '2026-09-30 23:59:59', '0', '0', '180', 30),
$this->row('B-SEP', '淘宝-B店', '20880002', '2026-09-29 18:00:00', '0', '0', '50', 40),
$this->row('A-OCT', '天猫-A店', '20880001', '2026-10-15 10:00:00', '40', '10', '210', 50),
$this->row('B-OCT', '淘宝-B店', '20880002', '2026-10-20 10:00:00', '20', '5', '65', 60),
]);
$result = app(TaobaoAlipaySettlementBillRepository::class)->paginate(
['start' => '2026-10-01', 'end' => '2026-10-31'],
'occurred_at',
'desc',
1,
20,
);
$this->assertSame(2, $result['summary']['count']);
$this->assertSame(60.0, $result['summary']['income']);
$this->assertSame(15.0, $result['summary']['expense']);
$this->assertSame(230.0, $result['summary']['opening_balance']);
$this->assertSame('2026-09-30', $result['summary']['opening_balance_date']);
$this->assertSame('previous_period', $result['summary']['opening_balance_source']);
$this->assertSame(275.0, $result['summary']['balance']);
$this->assertSame(
$result['summary'],
app(TaobaoAlipaySettlementBillRepository::class)->summary([
'start' => '2026-10-01',
'end' => '2026-10-31',
]),
);
}
public function test_month_balance_respects_store_filter(): void
{
$rows = DB::connection('business_mirror')->table('taobao_alipay_bill_rows');
$rows->insert([
$this->row('A-SEP', '天猫-A店', '20880001', '2026-09-30 23:59:59', '0', '0', '150', 10),
$this->row('B-SEP', '淘宝-B店', '20880002', '2026-09-30 23:59:59', '0', '0', '50', 20),
$this->row('A-OCT', '天猫-A店', '20880001', '2026-10-15 10:00:00', '40', '10', '180', 30),
$this->row('B-OCT', '淘宝-B店', '20880002', '2026-10-20 10:00:00', '20', '5', '65', 40),
]);
$result = app(TaobaoAlipaySettlementBillRepository::class)->paginate(
['store_name' => '天猫-A店', 'start' => '2026-10-01', 'end' => '2026-10-31'],
'occurred_at',
'desc',
1,
20,
);
$this->assertSame(1, $result['summary']['count']);
$this->assertSame(40.0, $result['summary']['income']);
$this->assertSame(10.0, $result['summary']['expense']);
$this->assertSame(150.0, $result['summary']['opening_balance']);
$this->assertSame(180.0, $result['summary']['balance']);
}
public function test_first_imported_month_infers_opening_balance_from_first_account_rows(): void
{
$rows = DB::connection('business_mirror')->table('taobao_alipay_bill_rows');
$rows->insert([
$this->row('A-JUL-1', '天猫-A店', 'account-a', '2026-07-01 09:00:00', 10, 0, 210, 10),
$this->row('A-JUL-2', '天猫-A店', 'account-a', '2026-07-02 09:00:00', 20, 5, 225, 20),
$this->row('B-JUL-1', '淘宝-B店', 'account-b', '2026-07-01 10:00:00', 0, 10, 90, 30),
$this->row('B-JUL-2', '淘宝-B店', 'account-b', '2026-07-03 10:00:00', 5, 0, 95, 40),
]);
$result = app(TaobaoAlipaySettlementBillRepository::class)->paginate(
['start' => '2026-07-01', 'end' => '2026-07-31'],
'occurred_at',
'desc',
1,
20,
);
// A 首笔倒推期初 200,B 首笔倒推期初 100。
$this->assertSame(300.0, $result['summary']['opening_balance']);
$this->assertSame('first_row_estimate', $result['summary']['opening_balance_source']);
$this->assertSame(35.0, $result['summary']['income']);
$this->assertSame(15.0, $result['summary']['expense']);
$this->assertSame(320.0, $result['summary']['balance']);
}
private function createTables(): void
{
$schema = Schema::connection('business_mirror');
$schema->create('taobao_alipay_bill_imports', function (Blueprint $table): void {
$table->uuid('generation');
$table->string('status');
$table->timestamp('completed_at')->nullable();
});
$schema->create('taobao_alipay_bill_rows', function (Blueprint $table): void {
$table->string('record_code')->primary();
$table->string('store_name')->nullable();
$table->string('custom_remark')->nullable();
$table->string('bill_item')->nullable();
$table->string('alipay_account')->nullable();
$table->string('account_order_no')->nullable();
$table->string('business_serial_no')->nullable();
$table->string('merchant_order_no')->nullable();
$table->string('business_base_order_no')->nullable();
$table->string('goods_name')->nullable();
$table->string('counterparty_account')->nullable();
$table->dateTime('occurred_at');
$table->decimal('income_amount', 20, 6)->default(0);
$table->decimal('expense_amount', 20, 6)->default(0);
$table->decimal('balance_amount', 20, 6)->default(0);
$table->string('business_type')->nullable();
$table->string('remark')->nullable();
$table->string('online_order_no')->nullable();
$table->string('online_real_store')->nullable();
$table->string('business_description')->nullable();
$table->string('business_bill_source')->nullable();
$table->string('business_order_no')->nullable();
$table->dateTime('source_created_at')->nullable();
$table->dateTime('source_updated_at')->nullable();
$table->string('source_modified_by')->nullable();
$table->unsignedBigInteger('source_row_number');
});
DB::connection('business_mirror')->table('taobao_alipay_bill_imports')->insert([
'generation' => 'test-generation',
'status' => 'succeeded',
'completed_at' => '2026-11-01 09:00:00',
]);
}
private function row(
string $recordCode,
string $storeName,
string $account,
string $occurredAt,
string $income,
string $expense,
string $balance,
int $sourceRowNumber,
): array {
return [
'record_code' => $recordCode,
'store_name' => $storeName,
'custom_remark' => null,
'bill_item' => '交易收款',
'alipay_account' => $account,
'account_order_no' => null,
'business_serial_no' => null,
'merchant_order_no' => null,
'business_base_order_no' => null,
'goods_name' => null,
'counterparty_account' => null,
'occurred_at' => $occurredAt,
'income_amount' => $income,
'expense_amount' => $expense,
'balance_amount' => $balance,
'business_type' => '交易付款',
'remark' => null,
'online_order_no' => null,
'online_real_store' => null,
'business_description' => null,
'business_bill_source' => '支付宝',
'business_order_no' => null,
'source_created_at' => null,
'source_updated_at' => null,
'source_modified_by' => null,
'source_row_number' => $sourceRowNumber,
];
}
}