diff --git a/app/Http/Controllers/Barobill/EcardController.php b/app/Http/Controllers/Barobill/EcardController.php index 34408ac5..8299d64c 100644 --- a/app/Http/Controllers/Barobill/EcardController.php +++ b/app/Http/Controllers/Barobill/EcardController.php @@ -1076,7 +1076,11 @@ public function exportExcel(Request $request): StreamedResponse|JsonResponse foreach ($splits as $index => $split) { $splitDeductionType = $split['deduction_type'] ?? $split['deductionType'] ?? 'deductible'; $splitDeductionText = ($splitDeductionType === 'non_deductible') ? '불공' : '공제'; - $splitAmount = $split['split_amount'] ?? $split['amount'] ?? 0; + $splitSupplyAmount = $split['split_supply_amount'] ?? $split['supplyAmount'] ?? null; + $splitTax = $split['split_tax'] ?? $split['tax'] ?? null; + $splitAmount = ($splitSupplyAmount !== null && $splitTax !== null) + ? floatval($splitSupplyAmount) + floatval($splitTax) + : ($split['split_amount'] ?? $split['amount'] ?? 0); $splitEvidenceName = $split['evidence_name'] ?? $split['evidenceName'] ?? ''; $splitDescription = $split['description'] ?? ''; $splitAccountCode = $split['account_code'] ?? $split['accountCode'] ?? ''; @@ -1092,7 +1096,7 @@ public function exportExcel(Request $request): StreamedResponse|JsonResponse $splitEvidenceName, $splitDescription, number_format($splitAmount), - '', // 부가세 (분개에서는 생략) + $splitTax !== null ? number_format(floatval($splitTax)) : '', '', // 승인번호 $splitAccountCode, $splitAccountName, @@ -1176,9 +1180,14 @@ public function saveSplits(Request $request): JsonResponse ]); } - // 분개 금액 합계 검증 + // 분개 금액 합계 검증 (공급가액 + 부가세 합계) $originalAmount = floatval($originalData['originalAmount'] ?? 0); - $splitTotal = array_sum(array_map(fn($s) => floatval($s['amount'] ?? 0), $splits)); + $splitTotal = array_sum(array_map(function ($s) { + if (isset($s['supplyAmount']) && isset($s['tax'])) { + return floatval($s['supplyAmount']) + floatval($s['tax']); + } + return floatval($s['amount'] ?? 0); + }, $splits)); if (abs($originalAmount - $splitTotal) > 0.01) { return response()->json([ diff --git a/app/Models/Barobill/CardTransactionSplit.php b/app/Models/Barobill/CardTransactionSplit.php index 78d0b971..0e4654a2 100644 --- a/app/Models/Barobill/CardTransactionSplit.php +++ b/app/Models/Barobill/CardTransactionSplit.php @@ -18,6 +18,8 @@ class CardTransactionSplit extends Model 'tenant_id', 'original_unique_key', 'split_amount', + 'split_supply_amount', + 'split_tax', 'account_code', 'account_name', 'deduction_type', @@ -35,6 +37,8 @@ class CardTransactionSplit extends Model protected $casts = [ 'split_amount' => 'decimal:2', + 'split_supply_amount' => 'decimal:2', + 'split_tax' => 'decimal:2', 'original_amount' => 'decimal:2', 'sort_order' => 'integer', ]; @@ -95,10 +99,18 @@ public static function saveSplits(int $tenantId, string $uniqueKey, array $origi // 새 분개 저장 foreach ($splits as $index => $split) { + $supplyAmount = $split['supplyAmount'] ?? null; + $tax = $split['tax'] ?? null; + $splitAmount = ($supplyAmount !== null && $tax !== null) + ? (float) $supplyAmount + (float) $tax + : ($split['amount'] ?? 0); + self::create([ 'tenant_id' => $tenantId, 'original_unique_key' => $uniqueKey, - 'split_amount' => $split['amount'] ?? 0, + 'split_amount' => $splitAmount, + 'split_supply_amount' => $supplyAmount, + 'split_tax' => $tax, 'account_code' => $split['accountCode'] ?? null, 'account_name' => $split['accountName'] ?? null, 'deduction_type' => $split['deductionType'] ?? null, diff --git a/resources/views/barobill/ecard/index.blade.php b/resources/views/barobill/ecard/index.blade.php index b725dbd0..97c9a231 100644 --- a/resources/views/barobill/ecard/index.blade.php +++ b/resources/views/barobill/ecard/index.blade.php @@ -347,19 +347,26 @@ className={`px-3 py-1.5 text-xs cursor-pointer ${ const defaultDeductionType = log.deductionType || (log.merchantBizNum ? 'deductible' : 'non_deductible'); if (existingSplits && existingSplits.length > 0) { // 기존 분개 로드 - setSplits(existingSplits.map(s => ({ - amount: parseFloat(s.split_amount || s.amount || 0), - accountCode: s.account_code || s.accountCode || '', - accountName: s.account_name || s.accountName || '', - deductionType: s.deduction_type || s.deductionType || defaultDeductionType, - evidenceName: s.evidence_name || s.evidenceName || log.evidenceName || log.merchantName || '', - description: s.description || log.description || log.merchantBizType || log.memo || '', - memo: s.memo || '' - }))); + setSplits(existingSplits.map(s => { + const hasSupplyTax = s.split_supply_amount !== null && s.split_supply_amount !== undefined; + return { + supplyAmount: hasSupplyTax ? parseFloat(s.split_supply_amount) : parseFloat(s.split_amount || s.amount || 0), + tax: hasSupplyTax ? parseFloat(s.split_tax || 0) : 0, + accountCode: s.account_code || s.accountCode || '', + accountName: s.account_name || s.accountName || '', + deductionType: s.deduction_type || s.deductionType || defaultDeductionType, + evidenceName: s.evidence_name || s.evidenceName || log.evidenceName || log.merchantName || '', + description: s.description || log.description || log.merchantBizType || log.memo || '', + memo: s.memo || '' + }; + })); } else { - // 새 분개: 원본 금액으로 1개 행 생성 + // 새 분개: 원본의 공급가액/부가세로 1개 행 생성 + const origSupply = log.effectiveSupplyAmount ?? ((log.approvalAmount || 0) - (log.tax || 0)); + const origTax = log.effectiveTax ?? (log.tax || 0); setSplits([{ - amount: log.approvalAmount || 0, + supplyAmount: origSupply, + tax: origTax, accountCode: log.accountCode || '', accountName: log.accountName || '', deductionType: defaultDeductionType, @@ -374,14 +381,16 @@ className={`px-3 py-1.5 text-xs cursor-pointer ${ if (!isOpen || !log) return null; const originalAmount = log.approvalAmount || 0; - const splitTotal = splits.reduce((sum, s) => sum + (parseFloat(s.amount) || 0), 0); + // 합계금액 = sum(공급가액 + 부가세) + const splitTotal = splits.reduce((sum, s) => sum + (parseFloat(s.supplyAmount) || 0) + (parseFloat(s.tax) || 0), 0); const isValid = Math.abs(originalAmount - splitTotal) < 0.01; const addSplit = () => { const remaining = originalAmount - splitTotal; const defaultDeductionType = log.deductionType || (log.merchantBizNum ? 'deductible' : 'non_deductible'); setSplits([...splits, { - amount: remaining > 0 ? remaining : 0, + supplyAmount: remaining > 0 ? remaining : 0, + tax: 0, accountCode: '', accountName: '', deductionType: defaultDeductionType, @@ -404,7 +413,7 @@ className={`px-3 py-1.5 text-xs cursor-pointer ${ const handleSave = async () => { if (!isValid) { - notify('분개 금액 합계가 원본 금액과 일치하지 않습니다.', 'error'); + notify('분개 합계금액이 원본 금액과 일치하지 않습니다.', 'error'); return; } setSaving(true); @@ -458,8 +467,16 @@ className={`px-3 py-1.5 text-xs cursor-pointer ${ 사용일시 {log.useDateTime} +