接入公司非店铺支付宝账单、受限批处理导入,并为账户总表及每日资金流水增加管理员手动编辑与审计。 Co-authored-by: 92451 <924518135@qq.com> Co-committed-by: 92451 <924518135@qq.com>
278 lines
11 KiB
PHP
278 lines
11 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Business;
|
|
|
|
use App\Models\Auth\Permission;
|
|
use App\Models\Auth\Role;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Modules\EcommerceFinance\Services\FinanceLedgerCalculator;
|
|
use Tests\Feature\FeatureTestCase;
|
|
|
|
class FinanceLedgerManualEditTest extends FeatureTestCase
|
|
{
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail(),
|
|
);
|
|
|
|
$connection = DB::connection('business_mirror');
|
|
$accountId = $connection->table('fin_accounts')->insertGetId([
|
|
'company_name' => '手动编辑测试公司',
|
|
'account_short' => '手动编辑测试账户',
|
|
'account_type' => '公户',
|
|
'account_no' => '6222000000008899',
|
|
'current_balance' => 100,
|
|
'daily_available' => 100,
|
|
]);
|
|
$this->accountId = (int) $accountId;
|
|
$connection->table('fin_account_opening')->insert([
|
|
'account_short' => '手动编辑测试账户',
|
|
'opening_date' => '2026-10-17',
|
|
'opening_balance' => 100,
|
|
]);
|
|
$connection->table('fin_transactions')->insert([
|
|
[
|
|
'txn_date' => '2026-10-18',
|
|
'account_short' => '手动编辑测试账户',
|
|
'detail' => '自动入账',
|
|
'income' => 25,
|
|
'expense' => 0,
|
|
'source' => 'manual',
|
|
'process_type' => '手工录入',
|
|
'row_key' => hash('sha256', 'manual-edit-income'),
|
|
],
|
|
[
|
|
'txn_date' => '2026-10-19',
|
|
'account_short' => '手动编辑测试账户',
|
|
'detail' => '自动出账',
|
|
'income' => 0,
|
|
'expense' => 30,
|
|
'source' => 'manual',
|
|
'process_type' => '手工录入',
|
|
'row_key' => hash('sha256', 'manual-edit-expense'),
|
|
],
|
|
]);
|
|
app(FinanceLedgerCalculator::class)->recalculate();
|
|
}
|
|
|
|
private int $accountId;
|
|
|
|
public function test_account_and_daily_flow_edit_controls_are_visible(): void
|
|
{
|
|
$html = $this->loginAs()->get($this->pageUrl())->assertOk()->getContent();
|
|
|
|
$this->assertStringContainsString('data-ledger-account-edit', $html);
|
|
$this->assertStringContainsString('data-ledger-account-dialog', $html);
|
|
$this->assertStringContainsString('data-ledger-flow-edit', $html);
|
|
$this->assertStringContainsString('data-ledger-flow-dialog', $html);
|
|
}
|
|
|
|
public function test_account_editor_updates_fields_renames_references_and_writes_audit(): void
|
|
{
|
|
$this->loginAs()->get($this->accountEditUrl())
|
|
->assertOk()
|
|
->assertJsonPath('account.id', $this->accountId)
|
|
->assertJsonPath('account.account_short', '手动编辑测试账户');
|
|
|
|
$this->loginAs()->postJson($this->accountUpdateUrl(), [
|
|
'company_name' => '手动编辑测试公司',
|
|
'account_short' => '手动编辑测试账户新',
|
|
'account_type' => '公户',
|
|
'status' => 'limited',
|
|
'region' => '苏州',
|
|
'account_no' => '6222000000008899',
|
|
'bank_name' => '测试银行',
|
|
'bank_city_branch' => '苏州分行',
|
|
'company_plan' => '待注销',
|
|
'account_should_keep' => '否',
|
|
'single_limit' => '100000',
|
|
'daily_limit' => '200000',
|
|
'monthly_limit' => '300000',
|
|
'yearly_limit' => '400000',
|
|
'clearing_days' => 2.5,
|
|
'raise_target' => '500000',
|
|
'raise_status' => '处理中',
|
|
'raise_actions' => '提升限额',
|
|
'done_actions' => '提交资料',
|
|
'next_action' => '等待审核',
|
|
'remark' => '账户手动修改',
|
|
'owner' => '财务负责人',
|
|
])->assertOk()->assertJsonPath('account.account_short', '手动编辑测试账户新');
|
|
|
|
$connection = DB::connection('business_mirror');
|
|
$this->assertDatabaseHas('fin_accounts', [
|
|
'id' => $this->accountId,
|
|
'account_short' => '手动编辑测试账户新',
|
|
'region' => '苏州',
|
|
'bank_name' => '测试银行',
|
|
'owner' => '财务负责人',
|
|
], 'business_mirror');
|
|
foreach (['fin_account_opening', 'fin_daily_flows', 'fin_transactions', 'fin_shops'] as $table) {
|
|
$this->assertSame(
|
|
0,
|
|
$connection->table($table)->where('account_short', '手动编辑测试账户')->count(),
|
|
$table . ' 仍保留旧账户简称',
|
|
);
|
|
}
|
|
$this->assertDatabaseHas('fin_account_statuses', [
|
|
'account_short' => '手动编辑测试账户新',
|
|
'status' => 'limited',
|
|
], 'business_mirror');
|
|
$this->assertDatabaseHas('fin_ledger_edit_events', [
|
|
'entity_type' => 'account',
|
|
'entity_key' => (string) $this->accountId,
|
|
'user_name' => 'Test User',
|
|
], 'business_mirror');
|
|
}
|
|
|
|
public function test_daily_flow_override_cascades_and_can_reset_to_automatic(): void
|
|
{
|
|
$this->loginAs()->get($this->flowEditUrl('2026-10-18'))
|
|
->assertOk()
|
|
->assertJsonPath('flow.opening_balance', 100)
|
|
->assertJsonPath('flow.inflow', 25)
|
|
->assertJsonPath('flow.closing_balance', 125);
|
|
|
|
$this->loginAs()->postJson($this->flowUpdateUrl(), [
|
|
'flow_date' => '2026-10-18',
|
|
'account_short' => '手动编辑测试账户',
|
|
'opening_balance' => 100,
|
|
'inflow' => 50,
|
|
'outflow' => 10,
|
|
'closing_balance' => 140,
|
|
'remark' => '银行流水手工校正',
|
|
])->assertOk()
|
|
->assertJsonPath('flow.manual_override', true)
|
|
->assertJsonPath('flow.closing_balance', 140);
|
|
|
|
$connection = DB::connection('business_mirror');
|
|
$this->assertDatabaseHas('fin_daily_flows', [
|
|
'flow_date' => '2026-10-18',
|
|
'account_short' => '手动编辑测试账户',
|
|
'inflow' => 50,
|
|
'outflow' => 10,
|
|
'closing_balance' => 140,
|
|
'manual_override' => 1,
|
|
'updated_by' => 'Test User',
|
|
], 'business_mirror');
|
|
$this->assertDatabaseHas('fin_daily_flows', [
|
|
'flow_date' => '2026-10-19',
|
|
'account_short' => '手动编辑测试账户',
|
|
'opening_balance' => 140,
|
|
'outflow' => 30,
|
|
'closing_balance' => 110,
|
|
], 'business_mirror');
|
|
$this->assertSame(110.0, (float) $connection->table('fin_accounts')
|
|
->where('id', $this->accountId)
|
|
->value('current_balance'));
|
|
|
|
$this->loginAs()->postJson($this->flowResetUrl(), [
|
|
'flow_date' => '2026-10-18',
|
|
'account_short' => '手动编辑测试账户',
|
|
])->assertOk()->assertJsonPath('flow.manual_override', false);
|
|
|
|
$this->assertDatabaseMissing('fin_daily_flow_overrides', [
|
|
'flow_date' => '2026-10-18',
|
|
'account_short' => '手动编辑测试账户',
|
|
], 'business_mirror');
|
|
$this->assertDatabaseHas('fin_daily_flows', [
|
|
'flow_date' => '2026-10-19',
|
|
'account_short' => '手动编辑测试账户',
|
|
'opening_balance' => 125,
|
|
'closing_balance' => 95,
|
|
], 'business_mirror');
|
|
}
|
|
|
|
public function test_manual_edit_validates_equation_duplicate_short_and_permission(): void
|
|
{
|
|
$this->withExceptionHandling()->loginAs()->postJson($this->flowUpdateUrl(), [
|
|
'flow_date' => '2026-10-18',
|
|
'account_short' => '手动编辑测试账户',
|
|
'opening_balance' => 100,
|
|
'inflow' => 10,
|
|
'outflow' => 5,
|
|
'closing_balance' => 120,
|
|
])->assertUnprocessable()->assertJsonValidationErrors('closing_balance');
|
|
|
|
$connection = DB::connection('business_mirror');
|
|
$connection->table('fin_accounts')->insert([
|
|
'company_name' => '重名公司',
|
|
'account_short' => '已存在账户简称',
|
|
]);
|
|
$this->withExceptionHandling()->loginAs()->postJson($this->accountUpdateUrl(), [
|
|
'company_name' => '手动编辑测试公司',
|
|
'account_short' => '已存在账户简称',
|
|
'status' => 'normal',
|
|
])->assertUnprocessable()->assertJsonValidationErrors('account_short');
|
|
|
|
$viewer = user_model_class()::create([
|
|
'name' => '台账只读用户',
|
|
'email' => 'ledger-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)->postJson($this->flowUpdateUrl(), [
|
|
'flow_date' => '2026-10-18',
|
|
'account_short' => '手动编辑测试账户',
|
|
'opening_balance' => 100,
|
|
'inflow' => 10,
|
|
'outflow' => 5,
|
|
'closing_balance' => 105,
|
|
])->assertForbidden();
|
|
}
|
|
|
|
private function pageUrl(): string
|
|
{
|
|
return route('business.pages.show', [
|
|
'company_id' => $this->company->id,
|
|
'section' => 'financial-operations',
|
|
'page' => 'ledger',
|
|
]) . '?tab=flows';
|
|
}
|
|
|
|
private function accountEditUrl(): string
|
|
{
|
|
return route('business.financial-ledger.accounts.edit', [
|
|
'company_id' => $this->company->id,
|
|
'id' => $this->accountId,
|
|
]);
|
|
}
|
|
|
|
private function accountUpdateUrl(): string
|
|
{
|
|
return route('business.financial-ledger.accounts.update', [
|
|
'company_id' => $this->company->id,
|
|
'id' => $this->accountId,
|
|
]);
|
|
}
|
|
|
|
private function flowEditUrl(string $date): string
|
|
{
|
|
return route('business.financial-ledger.flows.edit', [
|
|
'company_id' => $this->company->id,
|
|
'flow_date' => $date,
|
|
'account_short' => '手动编辑测试账户',
|
|
]);
|
|
}
|
|
|
|
private function flowUpdateUrl(): string
|
|
{
|
|
return route('business.financial-ledger.flows.update', ['company_id' => $this->company->id]);
|
|
}
|
|
|
|
private function flowResetUrl(): string
|
|
{
|
|
return route('business.financial-ledger.flows.reset', ['company_id' => $this->company->id]);
|
|
}
|
|
}
|