diff --git a/app/Http/Controllers/Api/Admin/HR/PayrollController.php b/app/Http/Controllers/Api/Admin/HR/PayrollController.php index ed018f0f..cab2e4b9 100644 --- a/app/Http/Controllers/Api/Admin/HR/PayrollController.php +++ b/app/Http/Controllers/Api/Admin/HR/PayrollController.php @@ -842,11 +842,11 @@ public function generateJournalEntry(Request $request): JsonResponse } // 계정과목 조회 - $accountCodes = AccountCode::whereIn('code', ['80100', '20700', '20500']) + $accountCodes = AccountCode::whereIn('code', ['80100', '80200', '25400', '26200']) ->where('is_active', true) ->pluck('name', 'code'); - $missingCodes = array_diff(['80100', '20700', '20500'], $accountCodes->keys()->toArray()); + $missingCodes = array_diff(['80100', '80200', '25400', '26200'], $accountCodes->keys()->toArray()); if (! empty($missingCodes)) { return response()->json([ 'success' => false, @@ -885,12 +885,14 @@ public function generateJournalEntry(Request $request): JsonResponse } } - // 1. 차변: 80100 급여 / 임직원 — 총지급액 + // 1. 차변: 80100 임원급여(대표이사) / 80200 직원급여(나머지) if ($grossAmount > 0) { + // 대표이사 여부에 따라 계정코드 분기 + $salaryCode = $this->isCeoPayroll($year, $month) ? '80100' : '80200'; $lines[] = [ 'dc_type' => 'debit', - 'account_code' => '80100', - 'account_name' => $accountCodes['80100'], + 'account_code' => $salaryCode, + 'account_name' => $accountCodes[$salaryCode], 'trading_partner_id' => $partners['임직원'], 'trading_partner_name' => '임직원', 'debit_amount' => $grossAmount, @@ -916,8 +918,8 @@ public function generateJournalEntry(Request $request): JsonResponse } else { $creditLines[$mergeKey] = [ 'dc_type' => 'credit', - 'account_code' => '20700', - 'account_name' => $accountCodes['20700'], + 'account_code' => '25400', + 'account_name' => $accountCodes['25400'], 'trading_partner_id' => $partners[$partnerName], 'trading_partner_name' => $partnerName, 'debit_amount' => 0, @@ -935,12 +937,12 @@ public function generateJournalEntry(Request $request): JsonResponse $lines[] = $creditLine; } - // 최종: 대변 20500 미지급비용 / 임직원 — 실수령액 (DB 값) + // 최종: 대변 26200 미지급비용 / 임직원 — 실수령액 (DB 값) if ($netSalary > 0) { $lines[] = [ 'dc_type' => 'credit', - 'account_code' => '20500', - 'account_name' => $accountCodes['20500'], + 'account_code' => '26200', + 'account_name' => $accountCodes['26200'], 'trading_partner_id' => $partners['임직원'], 'trading_partner_name' => '임직원', 'debit_amount' => 0, @@ -1087,4 +1089,25 @@ public function calculate(Request $request): JsonResponse 'data' => array_merge($result, ['family_count' => $familyCount]), ]); } + + /** + * 해당 월 급여가 대표이사 전용인지 판별 + * 대표이사만 있으면 80100(임원급여), 그 외 80200(직원급여) + */ + private function isCeoPayroll(int $year, int $month): bool + { + // 해당 월 급여 대상자 중 대표이사만 있는지 확인 + $tenantId = session('selected_tenant_id', 1); + + return \App\Models\HR\Payroll::where('tenant_id', $tenantId) + ->where('year', $year) + ->where('month', $month) + ->whereHas('employee', fn ($q) => $q->where('position', '대표이사')) + ->exists() + && ! \App\Models\HR\Payroll::where('tenant_id', $tenantId) + ->where('year', $year) + ->where('month', $month) + ->whereHas('employee', fn ($q) => $q->where('position', '!=', '대표이사')) + ->exists(); + } } diff --git a/app/Http/Controllers/Barobill/EcardController.php b/app/Http/Controllers/Barobill/EcardController.php index 8b072867..08d525a7 100644 --- a/app/Http/Controllers/Barobill/EcardController.php +++ b/app/Http/Controllers/Barobill/EcardController.php @@ -1919,7 +1919,7 @@ private function syncJournalAmounts(int $tenantId, string $uniqueKey, float $new 'journal_entry_id' => $journal->id, 'line_no' => $lineNo++, 'dc_type' => 'debit', - 'account_code' => $expenseAccount?->account_code ?? '82600', + 'account_code' => $expenseAccount?->account_code ?? '83700', 'account_name' => $expenseAccount?->account_name ?? '잡비', 'debit_amount' => $supplyInt, 'credit_amount' => 0, @@ -1945,7 +1945,7 @@ private function syncJournalAmounts(int $tenantId, string $uniqueKey, float $new 'journal_entry_id' => $journal->id, 'line_no' => $lineNo++, 'dc_type' => 'debit', - 'account_code' => $expenseAccount?->account_code ?? '82600', + 'account_code' => $expenseAccount?->account_code ?? '83700', 'account_name' => $expenseAccount?->account_name ?? '잡비', 'debit_amount' => $totalAmount, 'credit_amount' => 0, @@ -1962,7 +1962,7 @@ private function syncJournalAmounts(int $tenantId, string $uniqueKey, float $new 'journal_entry_id' => $journal->id, 'line_no' => $lineNo, 'dc_type' => 'credit', - 'account_code' => $creditAccount?->account_code ?? '20500', + 'account_code' => $creditAccount?->account_code ?? '26200', 'account_name' => $creditAccount?->account_name ?? '미지급비용', 'debit_amount' => 0, 'credit_amount' => $totalAmount, diff --git a/app/Http/Controllers/Finance/PayableController.php b/app/Http/Controllers/Finance/PayableController.php index a3734ce2..9464b51d 100644 --- a/app/Http/Controllers/Finance/PayableController.php +++ b/app/Http/Controllers/Finance/PayableController.php @@ -196,7 +196,7 @@ public function integrated(Request $request): JsonResponse $account = $request->input('account', 'all'); $vendor = $request->input('vendor', ''); - $accountCodes = $account === 'all' ? ['20400', '20500'] : [$account]; + $accountCodes = $account === 'all' ? ['25300', '26200'] : [$account]; // 0. 이월 잔액 계산 (startDate 이전의 누적 잔액) $priorBalanceMap = []; @@ -431,7 +431,7 @@ public function hometaxPayables(Request $request): JsonResponse $endDate = $request->input('endDate', date('Y-12-31')); $account = $request->input('account', 'all'); - $accountCodes = $account === 'all' ? ['20400', '20500'] : [$account]; + $accountCodes = $account === 'all' ? ['25300', '26200'] : [$account]; $items = HometaxInvoiceJournal::where('tenant_id', $tenantId) ->whereIn('account_code', $accountCodes) @@ -465,7 +465,7 @@ public function journalPayables(Request $request): JsonResponse $account = $request->input('account', 'all'); $dcType = $request->input('dcType', 'all'); - $accountCodes = $account === 'all' ? ['20400', '20500'] : [$account]; + $accountCodes = $account === 'all' ? ['25300', '26200'] : [$account]; $query = JournalEntryLine::where('journal_entry_lines.tenant_id', $tenantId) ->whereIn('journal_entry_lines.account_code', $accountCodes) diff --git a/database/migrations/2026_03_13_100000_fix_duplicate_journal_entry_lines.php b/database/migrations/2026_03_13_100000_fix_duplicate_journal_entry_lines.php index 3d0d8629..b70a02b6 100644 --- a/database/migrations/2026_03_13_100000_fix_duplicate_journal_entry_lines.php +++ b/database/migrations/2026_03_13_100000_fix_duplicate_journal_entry_lines.php @@ -22,7 +22,7 @@ public function up(): void debit_amount, credit_amount, COUNT(*) as cnt, MIN(id) as keep_id, GROUP_CONCAT(id ORDER BY id) as all_ids FROM journal_entry_lines - WHERE account_code IN ('20400', '20500') + WHERE account_code IN ('25300', '26200') GROUP BY journal_entry_id, account_code, dc_type, trading_partner_name, debit_amount, credit_amount HAVING cnt > 1 diff --git a/resources/views/barobill/ecard/index.blade.php b/resources/views/barobill/ecard/index.blade.php index d0b68430..de25d9fc 100644 --- a/resources/views/barobill/ecard/index.blade.php +++ b/resources/views/barobill/ecard/index.blade.php @@ -716,7 +716,7 @@ className={`px-3 py-1.5 text-sm cursor-pointer ${index === highlightIndex ? 'bg- const splitSupply = Math.round(parseFloat(singleSplit.split_supply_amount ?? singleSplit.supplyAmount ?? singleSplit.split_amount ?? singleSplit.amount ?? 0)); const splitTax = Math.round(parseFloat(singleSplit.split_tax ?? singleSplit.tax ?? 0)); const splitDeductionType = singleSplit.deduction_type || singleSplit.deductionType || 'non_deductible'; - const splitAccountCode = singleSplit.account_code || singleSplit.accountCode || '82600'; + const splitAccountCode = singleSplit.account_code || singleSplit.accountCode || '83700'; const splitAccountName = singleSplit.account_name || singleSplit.accountName || '잡비'; const lines = []; @@ -751,7 +751,7 @@ className={`px-3 py-1.5 text-sm cursor-pointer ${index === highlightIndex ? 'bg- // 대변: 미지급비용 = 합계 lines.push({ - dc_type: 'credit', account_code: '20500', account_name: '미지급비용', + dc_type: 'credit', account_code: '26200', account_name: '미지급비용', debit_amount: 0, credit_amount: totalDebitSum, trading_partner_id: null, trading_partner_name: '', description: '' }); @@ -760,19 +760,19 @@ className={`px-3 py-1.5 text-sm cursor-pointer ${index === highlightIndex ? 'bg- } // splits가 없으면 기존 로직 (원본 금액 기반, 분리 없는 거래용) - const expenseCode = log.accountCode || '82600'; + const expenseCode = log.accountCode || '83700'; const expenseName = log.accountName || '잡비'; if (isDeductible) { return [ { dc_type: 'debit', account_code: expenseCode, account_name: expenseName, debit_amount: supplyAmount, credit_amount: 0, trading_partner_id: null, trading_partner_name: '', description: '' }, { dc_type: 'debit', account_code: '13500', account_name: '부가세대급금', debit_amount: taxAmount, credit_amount: 0, trading_partner_id: null, trading_partner_name: '', description: '' }, - { dc_type: 'credit', account_code: '20500', account_name: '미지급비용', debit_amount: 0, credit_amount: totalAmount, trading_partner_id: null, trading_partner_name: '', description: '' }, + { dc_type: 'credit', account_code: '26200', account_name: '미지급비용', debit_amount: 0, credit_amount: totalAmount, trading_partner_id: null, trading_partner_name: '', description: '' }, ]; } else { return [ { dc_type: 'debit', account_code: expenseCode, account_name: expenseName, debit_amount: totalAmount, credit_amount: 0, trading_partner_id: null, trading_partner_name: '', description: '' }, - { dc_type: 'credit', account_code: '20500', account_name: '미지급비용', debit_amount: 0, credit_amount: totalAmount, trading_partner_id: null, trading_partner_name: '', description: '' }, + { dc_type: 'credit', account_code: '26200', account_name: '미지급비용', debit_amount: 0, credit_amount: totalAmount, trading_partner_id: null, trading_partner_name: '', description: '' }, ]; } }; diff --git a/resources/views/barobill/hometax/index.blade.php b/resources/views/barobill/hometax/index.blade.php index 11c3b0bc..2a20b7a4 100644 --- a/resources/views/barobill/hometax/index.blade.php +++ b/resources/views/barobill/hometax/index.blade.php @@ -2292,13 +2292,13 @@ className={`px-3 py-1.5 text-xs cursor-pointer ${ return [ { dc_type: 'debit', account_code: '10800', account_name: '외상매출금', debit_amount: totalAmount, credit_amount: 0, description: '' }, { dc_type: 'credit', account_code: '40100', account_name: '상품매출', debit_amount: 0, credit_amount: supplyAmount, description: '' }, - { dc_type: 'credit', account_code: '20800', account_name: '부가세예수금', debit_amount: 0, credit_amount: taxAmount, description: '' }, + { dc_type: 'credit', account_code: '25500', account_name: '부가세예수금', debit_amount: 0, credit_amount: taxAmount, description: '' }, ]; } else { return [ - { dc_type: 'debit', account_code: '50100', account_name: '상품매출원가', debit_amount: supplyAmount, credit_amount: 0, description: '' }, - { dc_type: 'debit', account_code: '11700', account_name: '부가세대급금', debit_amount: taxAmount, credit_amount: 0, description: '' }, - { dc_type: 'credit', account_code: '20100', account_name: '외상매입금', debit_amount: 0, credit_amount: totalAmount, description: '' }, + { dc_type: 'debit', account_code: '45100', account_name: '상품매출원가', debit_amount: supplyAmount, credit_amount: 0, description: '' }, + { dc_type: 'debit', account_code: '13500', account_name: '부가세대급금', debit_amount: taxAmount, credit_amount: 0, description: '' }, + { dc_type: 'credit', account_code: '25100', account_name: '외상매입금', debit_amount: 0, credit_amount: totalAmount, description: '' }, ]; } }; diff --git a/resources/views/finance/journal-entries.blade.php b/resources/views/finance/journal-entries.blade.php index d79dd9ad..c6e724c1 100644 --- a/resources/views/finance/journal-entries.blade.php +++ b/resources/views/finance/journal-entries.blade.php @@ -1968,13 +1968,13 @@ className="px-4 py-2 text-sm font-medium bg-blue-600 text-white rounded-lg hover return [ { key: 1, dc_type: 'debit', account_code: expenseCode, account_name: expenseName, trading_partner_id: null, trading_partner_name: '', debit_amount: supplyAmount, credit_amount: 0, description: '' }, { key: 2, dc_type: 'debit', account_code: '13500', account_name: '부가세대급금', trading_partner_id: null, trading_partner_name: '', debit_amount: taxAmount, credit_amount: 0, description: '' }, - { key: 3, dc_type: 'credit', account_code: '25300', account_name: '미지급금', trading_partner_id: null, trading_partner_name: '', debit_amount: 0, credit_amount: amount, description: '' }, + { key: 3, dc_type: 'credit', account_code: '30800', account_name: '미지급금', trading_partner_id: null, trading_partner_name: '', debit_amount: 0, credit_amount: amount, description: '' }, ]; } else { // 불공제: 차변(비용=합계) / 대변(미지급금=합계) return [ { key: 1, dc_type: 'debit', account_code: expenseCode, account_name: expenseName, trading_partner_id: null, trading_partner_name: '', debit_amount: amount, credit_amount: 0, description: '' }, - { key: 2, dc_type: 'credit', account_code: '25300', account_name: '미지급금', trading_partner_id: null, trading_partner_name: '', debit_amount: 0, credit_amount: amount, description: '' }, + { key: 2, dc_type: 'credit', account_code: '30800', account_name: '미지급금', trading_partner_id: null, trading_partner_name: '', debit_amount: 0, credit_amount: amount, description: '' }, ]; } }; diff --git a/resources/views/finance/payables.blade.php b/resources/views/finance/payables.blade.php index 1eeb222d..78af38fb 100644 --- a/resources/views/finance/payables.blade.php +++ b/resources/views/finance/payables.blade.php @@ -187,8 +187,8 @@ function IntegratedTab({ startDate, endDate, account, vendorSearch }) {
{v.vendorName || '(거래처 미지정)'}