From 4ecd34e767a339878de65390a03cf4f1d3fc04a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Wed, 4 Mar 2026 10:23:14 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[ecard]=20=EB=B3=80=EA=B2=BD=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=A0=80=EC=9E=A5=20=EC=8B=9C=20=EA=B8=B0=EC=A1=B4?= =?UTF-8?q?=20=EB=B6=84=EA=B0=9C=20=EA=B8=88=EC=95=A1=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=20=EA=B0=B1=EC=8B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 카드 금액 수정 후 저장 시 기존 분개의 차변/대변 금액도 연동 갱신 - 공제/불공제 유형별 라인 구조 보존하면서 금액만 업데이트 - 기존 계정과목, 적요, 거래처 정보 유지 --- .../Controllers/Barobill/EcardController.php | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/app/Http/Controllers/Barobill/EcardController.php b/app/Http/Controllers/Barobill/EcardController.php index 7d064b74..5be49334 100644 --- a/app/Http/Controllers/Barobill/EcardController.php +++ b/app/Http/Controllers/Barobill/EcardController.php @@ -1006,6 +1006,12 @@ public function save(Request $request): JsonResponse 'modified_supply_amount' => $data['modified_supply_amount'], 'modified_tax' => $data['modified_tax'], ]); + + // 금액 변경 시 기존 분개 자료의 차변/대변 금액도 자동 갱신 + if ($amountChanged) { + $this->syncJournalAmounts($tenantId, $uniqueKey, $newSupply, $newTax, $data['deduction_type']); + } + $updated++; } else { CardTransaction::create($data); @@ -1846,6 +1852,132 @@ public function hiddenTransactions(Request $request): JsonResponse } } + /** + * 카드 금액 변경 시 기존 분개 자료의 차변/대변 금액 자동 갱신 + */ + private function syncJournalAmounts(int $tenantId, string $uniqueKey, float $newSupply, float $newTax, ?string $deductionType): void + { + $journal = JournalEntry::getJournalBySourceKey($tenantId, 'ecard_transaction', $uniqueKey); + if (! $journal) { + return; + } + + $lines = $journal->lines()->get(); + if ($lines->isEmpty()) { + return; + } + + $isDeductible = ($deductionType ?? 'non_deductible') === 'deductible'; + $totalAmount = (int) round($newSupply + $newTax); + $supplyInt = (int) round($newSupply); + $taxInt = (int) round($newTax); + + // 기존 라인의 계정과목/적요를 보존하면서 금액만 갱신 + $debitLines = $lines->where('dc_type', 'debit')->values(); + $creditLines = $lines->where('dc_type', 'credit')->values(); + + // 기존 라인 삭제 후 재생성 (금액 갱신) + $journal->lines()->delete(); + $lineNo = 1; + + if ($isDeductible && $debitLines->count() >= 2) { + // 공제: 비용 계정(공급가액) + 부가세대급금(세액) + $expenseLine = $debitLines->first(fn ($l) => $l->account_code !== '135') ?? $debitLines[0]; + $taxLine = $debitLines->first(fn ($l) => $l->account_code === '135') ?? $debitLines[1]; + + JournalEntryLine::create([ + 'tenant_id' => $tenantId, + 'journal_entry_id' => $journal->id, + 'line_no' => $lineNo++, + 'dc_type' => 'debit', + 'account_code' => $expenseLine->account_code, + 'account_name' => $expenseLine->account_name, + 'debit_amount' => $supplyInt, + 'credit_amount' => 0, + 'trading_partner_id' => $expenseLine->trading_partner_id, + 'trading_partner_name' => $expenseLine->trading_partner_name, + 'description' => $expenseLine->description, + ]); + JournalEntryLine::create([ + 'tenant_id' => $tenantId, + 'journal_entry_id' => $journal->id, + 'line_no' => $lineNo++, + 'dc_type' => 'debit', + 'account_code' => $taxLine->account_code, + 'account_name' => $taxLine->account_name, + 'debit_amount' => $taxInt, + 'credit_amount' => 0, + 'trading_partner_id' => $taxLine->trading_partner_id, + 'trading_partner_name' => $taxLine->trading_partner_name, + 'description' => $taxLine->description, + ]); + } elseif ($isDeductible) { + // 공제인데 기존 라인이 1개뿐이면 기본 구조로 생성 + $expenseAccount = $debitLines->first(); + JournalEntryLine::create([ + 'tenant_id' => $tenantId, + 'journal_entry_id' => $journal->id, + 'line_no' => $lineNo++, + 'dc_type' => 'debit', + 'account_code' => $expenseAccount?->account_code ?? '826', + 'account_name' => $expenseAccount?->account_name ?? '잡비', + 'debit_amount' => $supplyInt, + 'credit_amount' => 0, + 'trading_partner_id' => $expenseAccount?->trading_partner_id, + 'trading_partner_name' => $expenseAccount?->trading_partner_name, + 'description' => $expenseAccount?->description, + ]); + JournalEntryLine::create([ + 'tenant_id' => $tenantId, + 'journal_entry_id' => $journal->id, + 'line_no' => $lineNo++, + 'dc_type' => 'debit', + 'account_code' => '135', + 'account_name' => '부가세대급금', + 'debit_amount' => $taxInt, + 'credit_amount' => 0, + ]); + } else { + // 불공제: 비용 계정 = 공급가액 + 세액 + $expenseAccount = $debitLines->first(); + JournalEntryLine::create([ + 'tenant_id' => $tenantId, + 'journal_entry_id' => $journal->id, + 'line_no' => $lineNo++, + 'dc_type' => 'debit', + 'account_code' => $expenseAccount?->account_code ?? '826', + 'account_name' => $expenseAccount?->account_name ?? '잡비', + 'debit_amount' => $totalAmount, + 'credit_amount' => 0, + 'trading_partner_id' => $expenseAccount?->trading_partner_id, + 'trading_partner_name' => $expenseAccount?->trading_partner_name, + 'description' => $expenseAccount?->description, + ]); + } + + // 대변: 미지급비용 (기존 대변 라인의 계정 보존) + $creditAccount = $creditLines->first(); + JournalEntryLine::create([ + 'tenant_id' => $tenantId, + 'journal_entry_id' => $journal->id, + 'line_no' => $lineNo, + 'dc_type' => 'credit', + 'account_code' => $creditAccount?->account_code ?? '205', + 'account_name' => $creditAccount?->account_name ?? '미지급비용', + 'debit_amount' => 0, + 'credit_amount' => $totalAmount, + 'trading_partner_id' => $creditAccount?->trading_partner_id, + 'trading_partner_name' => $creditAccount?->trading_partner_name, + 'description' => $creditAccount?->description, + ]); + + // 분개 헤더 합계 갱신 + $journal->update([ + 'total_debit' => $totalAmount, + 'total_credit' => $totalAmount, + ]); + } + // ================================================================ // 카드거래 복식부기 분개 API (journal_entries 통합) // ================================================================