193 lines
7.7 KiB
PHP
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;
|
|
}
|
|
}
|