CaiWuXiTong/tests/Feature/Business/FinanceLedgerAlipayBasicImportTest.php
shanshi 10fd8bfdb4 feat: 支持支付宝基本信息导入 (#1164)
支持支付宝基本信息表格合并导入,并保存法人、账户类型、商户号和店铺字段。
2026-11-13 18:38:20 +08:00

234 lines
9.0 KiB
PHP

<?php
namespace Tests\Feature\Business;
use App\Models\Auth\Permission;
use App\Models\Auth\Role;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Tests\Feature\FeatureTestCase;
class FinanceLedgerAlipayBasicImportTest extends FeatureTestCase
{
protected function setUp(): void
{
parent::setUp();
$this->user->attachPermission(
Permission::where('name', 'read-admin-panel')->firstOrFail(),
);
}
private function pageUrl(): string
{
return route('business.financial-ledger.account-basic', [
'company_id' => $this->company->id,
'view' => 'non_store',
]);
}
private function importUrl(): string
{
return route('business.financial-ledger.accounts.alipay.import', [
'company_id' => $this->company->id,
]);
}
public function test_alipay_page_exposes_basic_import_and_columns(): void
{
DB::connection('business_mirror')->table('fin_accounts')->insert([
'company_name' => '页面展示支付宝公司',
'account_short' => '展示支付宝',
'alipay_merchant_no' => '208800000001',
'alipay_account_kind' => '企业',
'alipay_store_name' => '非店铺',
'account_type' => '支付宝',
'account_no' => 'display@example.com',
'bank_name' => '/',
'account_should_keep' => '否',
]);
$this->loginAs()->get($this->pageUrl())
->assertOk()
->assertSee('导入支付宝基本信息')
->assertSee('data-alipay-import-form', false)
->assertSee('商户号')
->assertSee('账户类型')
->assertSee('店铺')
->assertSee('208800000001')
->assertSee('display@example.com');
}
public function test_import_updates_existing_adds_new_and_preserves_other_accounts(): void
{
$connection = DB::connection('business_mirror');
$accounts = [
[
'company_name' => '支付宝导入甲公司',
'account_short' => '导入甲支付宝',
'account_type' => '支付宝',
'account_no' => 'alpha@example.com',
'bank_name' => '/',
'current_balance' => 100,
'remark' => '原备注保留',
'account_should_keep' => '是',
'company_plan' => '保留',
],
[
'company_name' => '支付宝导入乙公司',
'account_short' => '导入乙支付宝',
'account_type' => '支付宝',
'account_no' => 'old-beta@example.com',
'bank_name' => '/',
'current_balance' => 50,
'account_should_keep' => '是',
'company_plan' => '保留',
],
[
'company_name' => '表格外支付宝公司',
'account_short' => '表格外支付宝',
'account_type' => '支付宝',
'account_no' => 'outside@example.com',
'bank_name' => '/',
'current_balance' => 25,
'account_should_keep' => '是',
'company_plan' => '保留',
],
[
'company_name' => '银行账户公司',
'account_short' => '测试银行账户',
'account_type' => '公户',
'account_no' => '888800001',
'bank_name' => '测试银行',
],
];
foreach ($accounts as $account) {
$connection->table('fin_accounts')->insert($account);
}
$this->loginAs()->post($this->importUrl(), [
'file' => $this->workbook(),
])->assertRedirect()->assertSessionHas('success');
$this->assertDatabaseHas('fin_accounts', [
'account_short' => '导入甲支付宝',
'company_name' => '支付宝导入甲公司',
'legal_representative' => '法人甲',
'alipay_merchant_no' => '208800000101',
'alipay_account_kind' => '企业',
'alipay_store_name' => '非店铺',
'account_no' => 'alpha@example.com',
'company_plan' => '待注销',
'account_should_keep' => '否',
'current_balance' => 100,
'remark' => '原备注保留',
], 'business_mirror');
$this->assertDatabaseHas('fin_accounts', [
'account_short' => '导入乙支付宝',
'company_name' => '支付宝导入乙公司',
'legal_representative' => '法人乙',
'alipay_merchant_no' => '208800000102',
'alipay_account_kind' => '个人',
'alipay_store_name' => '天猫-测试店',
'account_no' => 'beta@example.com',
'company_plan' => '保留',
'account_should_keep' => '是',
'current_balance' => 50,
'remark' => '新备注',
], 'business_mirror');
$this->assertDatabaseHas('fin_accounts', [
'company_name' => '支付宝新增丙公司',
'account_short' => '新增丙支付宝',
'legal_representative' => '法人丙',
'alipay_merchant_no' => '208800000103',
'alipay_account_kind' => '企业',
'alipay_store_name' => '非店铺',
'account_no' => 'gamma@example.com',
'account_type' => '支付宝',
'bank_name' => '/',
'company_plan' => '待注销',
'account_should_keep' => '否',
], 'business_mirror');
$this->assertDatabaseHas('fin_accounts', [
'account_short' => '表格外支付宝',
'current_balance' => 25,
], 'business_mirror');
$this->assertDatabaseHas('fin_accounts', [
'account_short' => '测试银行账户',
'account_type' => '公户',
], 'business_mirror');
$this->assertDatabaseMissing('fin_accounts', [
'account_no' => 'old-beta@example.com',
'account_short' => '导入乙支付宝',
], 'business_mirror');
$this->assertDatabaseHas('fin_companies', [
'name' => '支付宝新增丙公司',
], 'business_mirror');
$this->loginAs()->post($this->importUrl(), [
'file' => $this->workbook(),
])->assertRedirect()->assertSessionHas(
'success',
'支付宝基本信息导入完成:共 3 条,新增 0 条,更新 0 条,未变化 3 条,保留表格外现有账户 1 条。',
);
$this->assertDatabaseCount('fin_accounts', 5, 'business_mirror');
}
public function test_import_rejects_duplicate_accounts_and_requires_editor_role(): void
{
$this->withExceptionHandling()->loginAs()->post($this->importUrl(), [
'file' => $this->workbook(true),
])->assertRedirect()->assertSessionHasErrors('file');
$viewer = user_model_class()::create([
'name' => '支付宝只读用户',
'email' => 'alipay-viewer-' . uniqid() . '@example.com',
'password' => 'local-test-password',
'locale' => 'zh-CN',
'enabled' => 1,
'landing_page' => 'dashboard',
'created_from' => 'core::test',
]);
$viewer->companies()->attach($this->company->id);
$viewer->roles()->attach(Role::where('name', 'user')->firstOrFail()->id);
$viewer->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
$this->withExceptionHandling()->loginAs($viewer)->post($this->importUrl(), [
'file' => $this->workbook(),
])->assertForbidden();
}
private function workbook(bool $duplicate = false): UploadedFile
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$rows = [
['公司名称', '账户简称', '法人', '账户类型', '商户号', '支付宝账号', '账户状态', '是否保留', '店铺', '备注'],
['支付宝导入甲公司', null, '法人甲', '企业', '208800000101', 'alpha@example.com', null, '不保留', '非店铺', null],
['支付宝导入乙公司', null, '法人乙', '个人', '208800000102', 'beta@example.com', null, '保留', '天猫-测试店', '新备注'],
['支付宝新增丙公司', null, '法人丙', '企业', '208800000103', 'gamma@example.com', null, '不保留', '非店铺', null],
];
if ($duplicate) {
$rows[2][5] = 'alpha@example.com';
}
$sheet->fromArray($rows, null, 'A1');
$path = tempnam(sys_get_temp_dir(), 'alipay-basic-');
(new Xlsx($spreadsheet))->save($path);
$spreadsheet->disconnectWorksheets();
return new UploadedFile(
$path,
'支付宝基本信息.xlsx',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
null,
true,
);
}
}