fix:홈택스 분개 차/대 토글 기능 추가 및 저장 오류 수정

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
김보곤
2026-02-09 16:25:16 +09:00
parent b2b07bffbe
commit 943648169a
2 changed files with 43 additions and 6 deletions

View File

@@ -1677,13 +1677,22 @@ public function createJournalEntry(Request $request): JsonResponse
'message' => "전표 {$result->entry_no}가 생성되었습니다.",
'data' => $result->load('lines'),
]);
} catch (\Illuminate\Validation\ValidationException $e) {
$errors = $e->errors();
$firstError = collect($errors)->flatten()->first() ?? '입력 데이터가 올바르지 않습니다.';
Log::error('분개 생성 검증 오류', ['errors' => $errors]);
return response()->json([
'success' => false,
'error' => $firstError,
'errors' => $errors,
], 422);
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
return response()->json([
'success' => false,
'error' => '해당 세금계산서를 찾을 수 없습니다.',
], 404);
} catch (\Throwable $e) {
Log::error('분개 생성 오류: ' . $e->getMessage());
Log::error('분개 생성 오류: ' . $e->getMessage(), ['trace' => $e->getTraceAsString()]);
return response()->json([
'success' => false,
'error' => '분개 생성 오류: ' . $e->getMessage(),

View File

@@ -791,12 +791,16 @@ className="px-2 py-1 bg-red-50 text-red-700 rounded text-xs hover:bg-red-100 tra
});
const data = await res.json();
if (data.success) {
notify(data.message, 'success');
notify(data.message || '전표가 생성되었습니다.', 'success');
setShowJournalModal(false);
setJournalInvoice(null);
} else {
notify(data.error || '분개 생성 실패', 'error');
const errorMsg = data.error || '분개 생성 실패';
console.error('분개 생성 실패:', data);
notify(errorMsg, 'error');
}
} catch (err) {
console.error('분개 생성 오류:', err);
notify('분개 생성 오류: ' + err.message, 'error');
}
};
@@ -1190,7 +1194,7 @@ className="ml-auto px-4 py-3 text-sm font-medium rounded-lg bg-violet-600 text-w
onRequestCollect={handleRequestCollect}
summary={currentInvoiceSummary}
onJournalEntry={(inv) => {
setJournalInvoice(inv);
setJournalInvoice({...inv, invoiceType: activeTab});
setShowJournalModal(true);
}}
onEditManual={(inv) => {
@@ -2064,7 +2068,26 @@ className={`px-3 py-1.5 text-xs cursor-pointer ${
const totalCredit = lines.reduce((sum, l) => sum + (parseFloat(l.credit_amount) || 0), 0);
const isBalanced = Math.abs(totalDebit - totalCredit) < 1;
const toggleDcType = (idx) => {
setLines(prev => prev.map((l, i) => {
if (i !== idx) return l;
const newType = l.dc_type === 'debit' ? 'credit' : 'debit';
return {
...l,
dc_type: newType,
debit_amount: l.credit_amount,
credit_amount: l.debit_amount,
};
}));
};
const handleSubmit = async () => {
// 계정과목 검증
const emptyLine = lines.find(l => !l.account_code || !l.account_name);
if (emptyLine) {
notify('모든 분개 라인의 계정과목을 선택해주세요.', 'warning');
return;
}
if (!isBalanced) {
notify('차변과 대변의 합계가 일치하지 않습니다.', 'warning');
return;
@@ -2117,9 +2140,14 @@ className={`px-3 py-1.5 text-xs cursor-pointer ${
{lines.map((line, idx) => (
<tr key={idx} className="border-b border-stone-100">
<td className="px-3 py-2 text-center">
<span className={`px-2 py-0.5 rounded text-xs font-medium ${line.dc_type === 'debit' ? 'bg-blue-100 text-blue-700' : 'bg-red-100 text-red-700'}`}>
<button
type="button"
onClick={() => toggleDcType(idx)}
className={`px-2 py-0.5 rounded text-xs font-medium cursor-pointer hover:opacity-80 transition-opacity ${line.dc_type === 'debit' ? 'bg-blue-100 text-blue-700' : 'bg-red-100 text-red-700'}`}
title="클릭하여 차변/대변 전환"
>
{line.dc_type === 'debit' ? '차변' : '대변'}
</span>
</button>
</td>
<td className="px-3 py-2" colSpan="2">
<AccountCodeSelect