From efd6fade36f20a6b620c8f7bb314d33931a0f960 Mon Sep 17 00:00:00 2001 From: shanshi <3316401569@qq.com> Date: Mon, 26 Oct 2026 14:25:48 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B4=A2=E5=8A=A1=E5=8F=B0=E8=B4=A6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E7=BB=B4=E6=8A=A4=E5=85=AC=E5=8F=B8=E8=B5=84=E6=96=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Business/FinanceLedger.php | 15 ++++- docs/财务台账开发说明.md | 2 +- .../Services/FinanceLedgerAccountCreator.php | 27 ++++++++ .../pages/financial-ledger/ledger.blade.php | 51 +++++++++++++-- .../FinanceLedgerAccountStatusTest.php | 64 +++++++++++++++++++ 5 files changed, 151 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/Business/FinanceLedger.php b/app/Http/Controllers/Business/FinanceLedger.php index 76b08226..2769a3de 100644 --- a/app/Http/Controllers/Business/FinanceLedger.php +++ b/app/Http/Controllers/Business/FinanceLedger.php @@ -48,6 +48,13 @@ class FinanceLedger extends Controller $openingDate = (string) config('finance_ledger.opening_date', '2026-10-17'); $data = $request->validate([ 'company_name' => ['required', 'string', 'max:100'], + 'company_register_place' => ['nullable', 'string', 'max:200'], + 'company_business_type' => ['nullable', 'string', 'max:50'], + 'company_tax_type' => ['nullable', 'string', 'max:50'], + 'company_status' => ['nullable', 'string', 'max:20'], + 'company_basic_bank' => ['nullable', 'string', 'max:200'], + 'company_basic_account_last4' => ['nullable', 'string', 'max:50'], + 'company_remark' => ['nullable', 'string', 'max:500'], 'account_short' => ['required', 'string', 'max:100'], 'account_type' => ['nullable', 'string', 'max:50'], 'status' => ['required', 'string', Rule::in(array_keys(FinanceLedgerAccountStatus::OPTIONS))], @@ -90,9 +97,11 @@ class FinanceLedger extends Controller $result = $creator->create($data); $connection = DB::connection((string) config('upstream_mirrors.connection', 'business_mirror')); - $message = $result['company_created'] - ? '已新增公司并建立首个账户。' - : '已新增账户并关联现有公司。'; + $message = match (true) { + $result['company_created'] => '已新增公司并建立首个账户。', + $result['company_updated'] => '已新增账户并更新公司资料。', + default => '已新增账户并关联现有公司。', + }; return response()->json([ 'ok' => true, diff --git a/docs/财务台账开发说明.md b/docs/财务台账开发说明.md index 7d12dcea..c5ac60c2 100644 --- a/docs/财务台账开发说明.md +++ b/docs/财务台账开发说明.md @@ -64,7 +64,7 @@ docker compose -f docker-compose.local.yml exec -u www-data app \ - 路由:`/workspace/financial-operations/ledger`(旧地址会自动跳转) - 页面:账户总表、店铺台账、每日资金流水、动账明细、账户映射、数据来源 - 账户总表支持导出空白 Excel 录入模板,包含页面列、状态和账户类型选项及填写说明 -- 账户总表编辑模式支持直接新增公司和首个账户:公司不存在时同步写入公司台账,账户简称必须唯一,可同时登记期初日期与期初余额 +- 账户总表编辑模式支持直接新增公司和首个账户:公司不存在时同步写入公司台账,可维护注册地、企业类型、税务类型、公司状态、基本户信息和备注;账户简称必须唯一,可同时登记期初日期与期初余额 - 写权限:账户映射、账户状态和账户类型修改仅系统管理员及配置的财务台账管理员角色;其他账号只读 - 调度:`finance-ledger:sync-rpt --days=7 --merge` 每天 02:30(Asia/Shanghai) diff --git a/modules/EcommerceFinance/Services/FinanceLedgerAccountCreator.php b/modules/EcommerceFinance/Services/FinanceLedgerAccountCreator.php index 64fa93fc..84b0c368 100644 --- a/modules/EcommerceFinance/Services/FinanceLedgerAccountCreator.php +++ b/modules/EcommerceFinance/Services/FinanceLedgerAccountCreator.php @@ -21,6 +21,15 @@ class FinanceLedgerAccountCreator $accountNo = $this->text($data['account_no'] ?? ''); $accountType = $this->text($data['account_type'] ?? ''); $companyPlan = $this->text($data['company_plan'] ?? ''); + $companyFields = [ + 'register_place' => $this->nullableText($data['company_register_place'] ?? null), + 'business_type' => $this->nullableText($data['company_business_type'] ?? null), + 'tax_type' => $this->nullableText($data['company_tax_type'] ?? null), + 'status' => $this->nullableText($data['company_status'] ?? null), + 'basic_bank' => $this->nullableText($data['company_basic_bank'] ?? null), + 'basic_account_last4' => $this->nullableText($data['company_basic_account_last4'] ?? null), + 'remark' => $this->nullableText($data['company_remark'] ?? null), + ]; $openingDate = (string) ($data['opening_date'] ?? now()->toDateString()); $openingBalance = round((float) ($data['opening_balance'] ?? 0), 2); $status = FinanceLedgerAccountStatus::normalize((string) ($data['status'] ?? '')); @@ -38,6 +47,7 @@ class FinanceLedgerAccountCreator $accountNo, $accountType, $companyPlan, + $companyFields, $openingDate, $openingBalance, $status, @@ -55,12 +65,28 @@ class FinanceLedgerAccountCreator $company = $connection->table('fin_companies')->where('name', $companyName)->first(['id']); $companyCreated = $company === null; + $companyUpdated = false; if ($companyCreated) { $connection->table('fin_companies')->insert([ 'name' => $companyName, + ...$companyFields, 'created_at' => $now, 'updated_at' => $now, ]); + } else { + $providedCompanyFields = array_filter( + $companyFields, + static fn (?string $value): bool => $value !== null, + ); + if ($providedCompanyFields !== []) { + $connection->table('fin_companies') + ->where('id', $company->id) + ->update([ + ...$providedCompanyFields, + 'updated_at' => $now, + ]); + $companyUpdated = true; + } } $accountId = $connection->table('fin_accounts')->insertGetId([ @@ -118,6 +144,7 @@ class FinanceLedgerAccountCreator 'company_name' => $companyName, 'account_short' => $accountShort, 'company_created' => $companyCreated, + 'company_updated' => $companyUpdated, 'status' => $status, 'opening_date' => $openingDate, 'opening_balance' => $openingBalance, diff --git a/resources/views/business/pages/financial-ledger/ledger.blade.php b/resources/views/business/pages/financial-ledger/ledger.blade.php index 6dbbda1d..62c8603a 100644 --- a/resources/views/business/pages/financial-ledger/ledger.blade.php +++ b/resources/views/business/pages/financial-ledger/ledger.blade.php @@ -211,13 +211,20 @@ .ledger-company-form__close { display:inline-grid; flex:0 0 auto; place-items:center; width:1.8rem; height:1.8rem; padding:0; border:1px solid transparent; border-radius:.35rem; background:transparent; color:var(--vip-content-muted, #595959); cursor:pointer; } .ledger-company-form__close:hover { border-color:var(--vip-border, #D8D2C7); color:var(--vip-content-accent-dark, #856632); } .ledger-company-form__body { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:.8rem; padding:1rem 1.1rem; } + .ledger-company-form__section { grid-column:1 / -1; display:flex; align-items:baseline; gap:.55rem; padding-top:.75rem; border-top:1px solid #e8e3da; color:var(--vip-content-ink, #171717); font-size:.76rem; font-weight:700; } + .ledger-company-form__section:first-child { padding-top:0; border-top:0; } + .ledger-company-form__section span:last-child { color:var(--vip-content-muted, #595959); font-size:.65rem; font-weight:400; } .ledger-company-field { display:grid; min-width:0; gap:.3rem; } .ledger-company-field--wide { grid-column:span 2; } + .ledger-company-field--full { grid-column:1 / -1; } .ledger-company-field label { color:var(--vip-content-muted, #595959); font-size:.7rem; font-weight:600; } .ledger-company-field input, - .ledger-company-field select { width:100%; min-width:0; height:2.15rem; padding:0 .58rem; border:1px solid var(--vip-border, #D8D2C7); border-radius:.45rem; background:#fff; color:var(--vip-content-ink, #171717); font:inherit; } + .ledger-company-field select, + .ledger-company-field textarea { width:100%; min-width:0; min-height:2.15rem; padding:0 .58rem; border:1px solid var(--vip-border, #D8D2C7); border-radius:.45rem; background:#fff; color:var(--vip-content-ink, #171717); font:inherit; } + .ledger-company-field textarea { min-height:3.4rem; padding-top:.45rem; padding-bottom:.45rem; resize:vertical; } .ledger-company-field input:focus, - .ledger-company-field select:focus { border-color:var(--vip-content-accent-dark, #856632); outline:none; box-shadow:0 0 0 3px rgba(133,102,50,.16); } + .ledger-company-field select:focus, + .ledger-company-field textarea:focus { border-color:var(--vip-content-accent-dark, #856632); outline:none; box-shadow:0 0 0 3px rgba(133,102,50,.16); } .ledger-company-field__hint { color:var(--vip-content-muted, #595959); font-size:.65rem; line-height:1.45; } .ledger-company-form__message { grid-column:1 / -1; margin:0; padding:.55rem .65rem; border:1px solid rgba(184,0,0,.28); border-radius:.4rem; background:#fff5f5; color:var(--vip-danger, #B80000); font-size:.7rem; line-height:1.5; } .ledger-company-form__message[hidden] { display:none !important; } @@ -479,18 +486,54 @@

新增公司/账户

-

公司不存在时自动加入公司台账;账户简称必须唯一。期初余额会作为该账户的起始资金并进入每日流水。

+

公司不存在时自动加入公司台账,也可补充已有公司的资料。账户简称必须唯一,期初余额会作为该账户的起始资金并进入每日流水。

+
+ 公司资料 + 除公司名称外均可留空;已有公司只会更新本次填写的字段。 +
输入公司台账中不存在的名称时会自动新增公司。
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ 账户资料 + 首个账户会自动关联上方公司。 +
@@ -555,7 +598,7 @@ diff --git a/tests/Feature/Business/FinanceLedgerAccountStatusTest.php b/tests/Feature/Business/FinanceLedgerAccountStatusTest.php index 1c28e9c6..daaf9622 100644 --- a/tests/Feature/Business/FinanceLedgerAccountStatusTest.php +++ b/tests/Feature/Business/FinanceLedgerAccountStatusTest.php @@ -141,6 +141,13 @@ class FinanceLedgerAccountStatusTest extends FeatureTestCase ->assertSee('data-ledger-company-dialog', false) ->assertSee('新增公司/账户') ->assertSee('name="company_name"', false) + ->assertSee('name="company_register_place"', false) + ->assertSee('name="company_business_type"', false) + ->assertSee('name="company_tax_type"', false) + ->assertSee('name="company_status"', false) + ->assertSee('name="company_basic_bank"', false) + ->assertSee('name="company_basic_account_last4"', false) + ->assertSee('name="company_remark"', false) ->assertSee('name="opening_balance"', false) ->assertSee('id="ledger-company-options"', false) ->assertSee('aria-checked="false"', false) @@ -753,6 +760,13 @@ class FinanceLedgerAccountStatusTest extends FeatureTestCase { $this->loginAs()->postJson($this->createAccountUrl(), [ 'company_name' => '新设财务公司', + 'company_register_place' => '上海市浦东新区', + 'company_business_type' => '有限责任公司', + 'company_tax_type' => '一般纳税人', + 'company_status' => '正常', + 'company_basic_bank' => '中国农业银行上海浦东支行', + 'company_basic_account_last4' => '1234', + 'company_remark' => '新设公司财务备注', 'account_short' => '新设财务公司农行', 'account_type' => '公户', 'status' => 'limited', @@ -774,6 +788,13 @@ class FinanceLedgerAccountStatusTest extends FeatureTestCase $this->assertDatabaseHas('fin_companies', [ 'name' => '新设财务公司', + 'register_place' => '上海市浦东新区', + 'business_type' => '有限责任公司', + 'tax_type' => '一般纳税人', + 'status' => '正常', + 'basic_bank' => '中国农业银行上海浦东支行', + 'basic_account_last4' => '1234', + 'remark' => '新设公司财务备注', ], 'business_mirror'); $this->assertDatabaseHas('fin_accounts', [ 'company_name' => '新设财务公司', @@ -823,6 +844,49 @@ class FinanceLedgerAccountStatusTest extends FeatureTestCase $this->assertDatabaseCount('fin_companies', 1, 'business_mirror'); } + public function test_existing_company_profile_can_be_updated_with_a_new_account(): void + { + DB::connection('business_mirror')->table('fin_companies')->insert([ + 'name' => '已有资料公司', + 'register_place' => '江苏省苏州市', + 'business_type' => '个体工商户', + 'tax_type' => '小规模纳税人', + 'status' => '存续', + 'remark' => '原公司备注', + ]); + + $this->loginAs()->postJson($this->createAccountUrl(), [ + 'company_name' => '已有资料公司', + 'company_business_type' => '有限责任公司', + 'company_tax_type' => '一般纳税人', + 'company_status' => '正常', + 'company_basic_bank' => '中国工商银行苏州分行', + 'company_basic_account_last4' => '8899', + 'company_remark' => '更新后的公司备注', + 'account_short' => '已有资料公司工行', + 'account_type' => '公户', + 'status' => 'normal', + 'account_no' => '1102000000008899', + 'opening_date' => '2026-10-20', + 'opening_balance' => 0, + ]) + ->assertCreated() + ->assertJsonPath('account.company_created', false) + ->assertJsonPath('account.company_updated', true) + ->assertJsonPath('message', '已新增账户并更新公司资料。'); + + $this->assertDatabaseHas('fin_companies', [ + 'name' => '已有资料公司', + 'register_place' => '江苏省苏州市', + 'business_type' => '有限责任公司', + 'tax_type' => '一般纳税人', + 'status' => '正常', + 'basic_bank' => '中国工商银行苏州分行', + 'basic_account_last4' => '8899', + 'remark' => '更新后的公司备注', + ], 'business_mirror'); + } + public function test_invalid_status_or_account_is_rejected(): void { $this->withExceptionHandling()->loginAs()->postJson($this->statusUrl(), [ -- 2.47.2