feat: [ecard] 변경사항 저장 시 기존 분개 금액 자동 갱신

- 카드 금액 수정 후 저장 시 기존 분개의 차변/대변 금액도 연동 갱신
- 공제/불공제 유형별 라인 구조 보존하면서 금액만 업데이트
- 기존 계정과목, 적요, 거래처 정보 유지
This commit is contained in:
김보곤
2026-03-04 10:23:14 +09:00
parent d149af95b7
commit 4ecd34e767

View File

@@ -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 통합)
// ================================================================