155 lines
6.4 KiB
PHP
155 lines
6.4 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\TaobaoWechatSettlementBillRepository;
|
|
use RuntimeException;
|
|
use Tests\TestCase;
|
|
|
|
class TaobaoWechatSettlementAccountBillsRepositoryTest 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_account_bill_page_reads_authoritative_rows_with_filters_and_totals(): void
|
|
{
|
|
$this->insertSucceededImport();
|
|
$this->insertRow('REC-INCOME', '淘系微信一店', '交易收款', '2026-08-01 00:00:00', '100.00', '0.00', '100.00', 'M-100', 'O-100');
|
|
$this->insertRow('REC-EXPENSE', '淘系微信一店', '退款', '2026-08-31 23:59:59', '0.00', '20.00', '-20.00', 'M-200', 'O-200');
|
|
$this->insertRow('REC-OTHER', '淘系微信二店', '交易收款', '2026-08-15 12:00:00', '50.00', '0.00', '50.00', 'M-300', 'O-300');
|
|
|
|
$result = app(TaobaoWechatSettlementBillRepository::class)->paginateAccountBills([
|
|
'store_name' => '淘系微信一店',
|
|
'start' => '2026-08-01',
|
|
'end' => '2026-08-31',
|
|
], 'occurred_at', 'desc', 1, 10);
|
|
|
|
$this->assertSame(2, $result['total']);
|
|
$this->assertSame(100.0, $result['summary']['income']);
|
|
$this->assertSame(20.0, $result['summary']['expense']);
|
|
$this->assertSame(80.0, $result['summary']['balance']);
|
|
$this->assertSame('REC-EXPENSE', $result['data'][0]['record_code']);
|
|
$this->assertSame('M-200', $result['data'][0]['order_no']);
|
|
$this->assertSame('O-200', $result['data'][0]['payload']['online_order_no']);
|
|
$this->assertSame('退款', $result['data'][0]['payload']['entry_type']);
|
|
$this->assertSame('M-200', $result['data'][0]['payload']['taobao_order_no']);
|
|
$this->assertSame('2026-09-01 08:00:00', $result['data'][0]['payload']['jst_pulled_at']);
|
|
$this->assertSame(20.0, $result['data'][0]['amount']);
|
|
$this->assertSame(-20.0, $result['data'][0]['balance']);
|
|
|
|
$filtered = app(TaobaoWechatSettlementBillRepository::class)->paginateAccountBills([
|
|
'bill_item' => '退款',
|
|
'keyword' => 'O-200',
|
|
], 'record_code', 'asc', 1, 10);
|
|
|
|
$this->assertSame(1, $filtered['total']);
|
|
$this->assertSame('REC-EXPENSE', $filtered['data'][0]['record_code']);
|
|
|
|
$options = app(TaobaoWechatSettlementBillRepository::class)->accountBillFilterOptions();
|
|
$this->assertSame(['淘系微信一店', '淘系微信二店'], $options['shops']);
|
|
$this->assertSame(['交易收款', '退款'], $options['bill_items']);
|
|
|
|
$export = iterator_to_array(app(TaobaoWechatSettlementBillRepository::class)->exportAccountBills([
|
|
'bill_item' => '退款',
|
|
], 'record_code', 'asc'));
|
|
$this->assertCount(1, $export);
|
|
$this->assertSame('REC-EXPENSE', $export[0]['record_code']);
|
|
}
|
|
|
|
public function test_account_bill_page_fails_closed_until_a_successful_import_exists(): void
|
|
{
|
|
$this->expectException(RuntimeException::class);
|
|
$this->expectExceptionMessage('taobao_wechat_authoritative_bills_not_ready');
|
|
|
|
app(TaobaoWechatSettlementBillRepository::class)->paginateAccountBills(
|
|
[],
|
|
'occurred_at',
|
|
'desc',
|
|
1,
|
|
10,
|
|
);
|
|
}
|
|
|
|
private function createTables(): void
|
|
{
|
|
$schema = Schema::connection('business_mirror');
|
|
$schema->create('taobao_wechat_bill_imports', function (Blueprint $table): void {
|
|
$table->uuid('generation')->primary();
|
|
$table->string('status', 32);
|
|
});
|
|
$schema->create('taobao_wechat_bill_rows', function (Blueprint $table): void {
|
|
$table->string('record_code', 191)->primary();
|
|
$table->string('store_name')->nullable();
|
|
$table->string('custom_remark')->nullable();
|
|
$table->string('bill_item')->nullable();
|
|
$table->string('taobao_order_no', 191)->nullable();
|
|
$table->string('online_order_no', 191)->nullable();
|
|
$table->string('pay_serial_no')->nullable();
|
|
$table->string('business_description', 1000)->nullable();
|
|
$table->string('entry_type')->nullable();
|
|
$table->dateTime('occurred_at');
|
|
$table->decimal('income_amount', 20, 2);
|
|
$table->decimal('expense_amount', 20, 2);
|
|
$table->decimal('signed_amount', 20, 2);
|
|
$table->string('remark', 1000)->nullable();
|
|
$table->dateTime('jst_pulled_at')->nullable();
|
|
$table->string('source_modified_by')->nullable();
|
|
});
|
|
}
|
|
|
|
private function insertSucceededImport(): void
|
|
{
|
|
DB::connection('business_mirror')->table('taobao_wechat_bill_imports')->insert([
|
|
'generation' => '11111111-1111-1111-1111-111111111111',
|
|
'status' => 'succeeded',
|
|
]);
|
|
}
|
|
|
|
private function insertRow(
|
|
string $recordCode,
|
|
string $storeName,
|
|
string $billItem,
|
|
string $occurredAt,
|
|
string $income,
|
|
string $expense,
|
|
string $signed,
|
|
string $taobaoOrderNo,
|
|
string $onlineOrderNo,
|
|
): void {
|
|
DB::connection('business_mirror')->table('taobao_wechat_bill_rows')->insert([
|
|
'record_code' => $recordCode,
|
|
'store_name' => $storeName,
|
|
'custom_remark' => '自定义备注',
|
|
'bill_item' => $billItem,
|
|
'taobao_order_no' => $taobaoOrderNo,
|
|
'online_order_no' => $onlineOrderNo,
|
|
'pay_serial_no' => 'PAY-' . $recordCode,
|
|
'business_description' => '业务描述',
|
|
'entry_type' => $billItem,
|
|
'occurred_at' => $occurredAt,
|
|
'income_amount' => $income,
|
|
'expense_amount' => $expense,
|
|
'signed_amount' => $signed,
|
|
'remark' => '账单备注',
|
|
'jst_pulled_at' => '2026-09-01 08:00:00',
|
|
'source_modified_by' => '聚胜算',
|
|
]);
|
|
}
|
|
}
|