CaiWuXiTong/tests/Feature/Console/ImportWangshangBankBillsTest.php
92451 67c85678e6 feat: 接入网商银行每日动账明细 (#831)
Co-authored-by: 92451 <924518135@qq.com>
Co-committed-by: 92451 <924518135@qq.com>
2026-11-02 20:58:42 +08:00

193 lines
7.7 KiB
PHP

<?php
namespace Tests\Feature\Console;
use Illuminate\Support\Facades\DB;
use Modules\EcommerceFinance\Services\WangshangBankBillImporter;
use Tests\Feature\FeatureTestCase;
use ZipArchive;
class ImportWangshangBankBillsTest extends FeatureTestCase
{
public function test_imports_a_batch_and_replaces_the_same_account_date(): void
{
$connection = DB::connection('business_mirror');
$connection->table('fin_accounts')->insert([
'company_name' => '测试网商公司',
'account_short' => '测试网商银行',
'account_no' => '8888000012345678',
'account_type' => '网商银行',
'current_balance' => 1000,
]);
$connection->table('fin_account_opening')->insert([
'account_short' => '测试网商银行',
'opening_date' => '2026-10-01',
'opening_balance' => 1000,
]);
$connection->table('fin_transactions')->insert([
'txn_date' => '2026-11-01',
'account_short' => '测试网商银行',
'detail' => '旧版本',
'income' => 999,
'expense' => 0,
'source' => WangshangBankBillImporter::SOURCE,
'source_value' => '8888000012345678',
'process_type' => WangshangBankBillImporter::PROCESS_TYPE,
'row_key' => hash('sha256', 'old-wangshang-row'),
]);
$bundle = $this->bundle([
['交易时间', '账务流水号', '交易名称', '对方户名', '借方金额(收)', '贷方金额(支)', '交易状态'],
['2026-11-01 09:10:00', '202611010001', '他行转入', '甲公司', '100.00', '-', '成功'],
['2026-11-01 10:20:00', '202611010002', '转账汇款', '乙公司', '-', '20.00', '成功'],
['2026-10-31 10:20:00', '202610310001', '非目标日期', '丙公司', '999.00', '-', '成功'],
], expectedIncome: 100, expectedExpense: 20);
$this->artisan('finance-ledger:import-wangshang-bank', [
'path' => $bundle,
'--date' => '2026-11-01',
])->assertExitCode(0);
$this->assertDatabaseCount('fin_transactions', 2, 'business_mirror');
$this->assertDatabaseHas('fin_transactions', [
'account_short' => '测试网商银行',
'approval_no' => '202611010001',
'income' => 100,
'expense' => 0,
'source' => WangshangBankBillImporter::SOURCE,
'source_value' => '8888000012345678',
], 'business_mirror');
$this->assertDatabaseHas('fin_transactions', [
'approval_no' => '202611010002',
'income' => 0,
'expense' => 20,
], 'business_mirror');
$this->assertDatabaseMissing('fin_transactions', ['detail' => '旧版本'], 'business_mirror');
$this->assertDatabaseHas('fin_account_map', [
'source' => WangshangBankBillImporter::SOURCE,
'source_value' => '8888000012345678',
'account_short' => '测试网商银行',
'txn_count' => 2,
'income_sum' => 100,
'expense_sum' => 20,
], 'business_mirror');
$this->assertDatabaseHas('fin_daily_flows', [
'flow_date' => '2026-11-01',
'account_short' => '测试网商银行',
'opening_balance' => 1000,
'inflow' => 100,
'outflow' => 20,
'closing_balance' => 1080,
], 'business_mirror');
}
public function test_row_count_mismatch_keeps_existing_transactions(): void
{
$connection = DB::connection('business_mirror');
$connection->table('fin_accounts')->insert([
'company_name' => '测试网商公司',
'account_short' => '测试网商银行',
'account_no' => '8888000012345678',
'account_type' => '网商银行',
]);
$connection->table('fin_transactions')->insert([
'txn_date' => '2026-11-01',
'account_short' => '测试网商银行',
'detail' => '应保留',
'income' => 1,
'expense' => 0,
'source' => WangshangBankBillImporter::SOURCE,
'source_value' => '8888000012345678',
'process_type' => WangshangBankBillImporter::PROCESS_TYPE,
'row_key' => hash('sha256', 'keep-wangshang-row'),
]);
$bundle = $this->bundle([
['交易时间', '账务流水号', '交易名称', '借方金额(收)', '贷方金额(支)'],
['2026-11-01 09:10:00', '202611010001', '他行转入', '100.00', '-'],
], expectedRows: 2);
$this->withExceptionHandling()->artisan('finance-ledger:import-wangshang-bank', [
'path' => $bundle,
'--date' => '2026-11-01',
])->assertExitCode(1);
$this->assertDatabaseHas('fin_transactions', ['detail' => '应保留'], 'business_mirror');
}
public function test_imports_transactions_when_the_account_master_has_not_been_extended(): void
{
$bundle = $this->bundle([
['交易时间', '账务流水号', '交易名称', '借方金额(收)', '贷方金额(支)'],
['2026-11-01 09:10:00', '202611010003', '他行转入', '100.00', '-'],
], expectedRows: 1, expectedIncome: 100, expectedExpense: 0);
$this->artisan('finance-ledger:import-wangshang-bank', [
'path' => $bundle,
'--date' => '2026-11-01',
'--dry-run' => true,
])->assertExitCode(0);
$this->assertDatabaseCount('fin_transactions', 0, 'business_mirror');
$this->artisan('finance-ledger:import-wangshang-bank', [
'path' => $bundle,
'--date' => '2026-11-01',
])->assertExitCode(0);
$this->assertDatabaseHas('fin_transactions', [
'account_short' => '测试网商银行',
'approval_no' => '202611010003',
'income' => 100,
], 'business_mirror');
$this->assertDatabaseHas('fin_account_map', [
'source' => WangshangBankBillImporter::SOURCE,
'source_value' => '8888000012345678',
'account_short' => '测试网商银行',
], 'business_mirror');
}
/**
* @param list<list<string>> $rows
*/
private function bundle(
array $rows,
int $expectedRows = 2,
?float $expectedIncome = null,
?float $expectedExpense = null,
): string
{
$directory = sys_get_temp_dir() . '/wangshang-test-' . bin2hex(random_bytes(6));
mkdir($directory, 0700, true);
$csv = $directory . '/bills.csv';
$stream = fopen($csv, 'wb');
foreach ($rows as $row) {
fputcsv($stream, $row);
}
fclose($stream);
file_put_contents($directory . '/manifest.json', json_encode([
'date' => '2026-11-01',
'accounts' => [[
'company' => '测试网商公司',
'account' => '8888000012345678',
'account_short' => '测试网商银行',
'expected_rows' => $expectedRows,
'expected_income' => $expectedIncome,
'expected_expense' => $expectedExpense,
'file' => 'bills.csv',
]],
], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR));
$zipPath = sys_get_temp_dir() . '/wangshang-test-' . bin2hex(random_bytes(6)) . '.zip';
$zip = new ZipArchive();
$this->assertTrue($zip->open($zipPath, ZipArchive::CREATE) === true);
$zip->addFile($directory . '/manifest.json', 'manifest.json');
$zip->addFile($csv, 'bills.csv');
$zip->close();
unlink($csv);
unlink($directory . '/manifest.json');
rmdir($directory);
return $zipPath;
}
}