feat:거래 분개 모달에 공제/불공 선택 필드 추가
- SplitModal에 공제/불공 선택 드롭다운 추가 - 공제: 녹색 배경, 불공: 붉은색 배경 - CardTransactionSplit 모델에 deduction_type 필드 추가 - 마이그레이션으로 splits 테이블에 deduction_type 컬럼 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,7 @@ class CardTransactionSplit extends Model
|
||||
'split_amount',
|
||||
'account_code',
|
||||
'account_name',
|
||||
'deduction_type',
|
||||
'evidence_name',
|
||||
'description',
|
||||
'memo',
|
||||
@@ -100,6 +101,7 @@ public static function saveSplits(int $tenantId, string $uniqueKey, array $origi
|
||||
'split_amount' => $split['amount'] ?? 0,
|
||||
'account_code' => $split['accountCode'] ?? null,
|
||||
'account_name' => $split['accountName'] ?? null,
|
||||
'deduction_type' => $split['deductionType'] ?? null,
|
||||
'evidence_name' => $split['evidenceName'] ?? null,
|
||||
'description' => $split['description'] ?? null,
|
||||
'memo' => $split['memo'] ?? null,
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
* 카드 거래 분개에 공제유형 필드 추가
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('barobill_card_transaction_splits', function (Blueprint $table) {
|
||||
$table->string('deduction_type', 20)->nullable()->after('account_name')->comment('공제유형: deductible/non_deductible');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('barobill_card_transaction_splits', function (Blueprint $table) {
|
||||
$table->dropColumn('deduction_type');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -284,12 +284,14 @@ className={`px-3 py-1.5 text-xs cursor-pointer hover:bg-purple-50 ${
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen && log) {
|
||||
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 || ''
|
||||
@@ -300,6 +302,7 @@ className={`px-3 py-1.5 text-xs cursor-pointer hover:bg-purple-50 ${
|
||||
amount: log.approvalAmount || 0,
|
||||
accountCode: log.accountCode || '',
|
||||
accountName: log.accountName || '',
|
||||
deductionType: defaultDeductionType,
|
||||
evidenceName: log.evidenceName || log.merchantName || '',
|
||||
description: log.description || log.merchantBizType || log.memo || '',
|
||||
memo: ''
|
||||
@@ -316,10 +319,12 @@ className={`px-3 py-1.5 text-xs cursor-pointer hover:bg-purple-50 ${
|
||||
|
||||
const addSplit = () => {
|
||||
const remaining = originalAmount - splitTotal;
|
||||
const defaultDeductionType = log.deductionType || (log.merchantBizNum ? 'deductible' : 'non_deductible');
|
||||
setSplits([...splits, {
|
||||
amount: remaining > 0 ? remaining : 0,
|
||||
accountCode: '',
|
||||
accountName: '',
|
||||
deductionType: defaultDeductionType,
|
||||
evidenceName: log.evidenceName || log.merchantName || '',
|
||||
description: log.description || log.merchantBizType || log.memo || '',
|
||||
memo: ''
|
||||
@@ -400,6 +405,21 @@ className="w-full px-3 py-2 border border-stone-200 rounded-lg text-sm focus:rin
|
||||
accountCodes={accountCodes}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-xs text-stone-500 mb-1">공제</label>
|
||||
<select
|
||||
value={split.deductionType || 'deductible'}
|
||||
onChange={(e) => updateSplit(index, { deductionType: e.target.value })}
|
||||
className={`w-full px-3 py-2 border border-stone-200 rounded-lg text-sm font-bold focus:ring-2 focus:ring-purple-500 outline-none ${
|
||||
split.deductionType === 'non_deductible'
|
||||
? 'bg-red-500 text-white'
|
||||
: 'bg-green-100 text-green-700'
|
||||
}`}
|
||||
>
|
||||
<option value="deductible">공제</option>
|
||||
<option value="non_deductible">불공</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-xs text-stone-500 mb-1">증빙/판매자상호</label>
|
||||
<input
|
||||
|
||||
Reference in New Issue
Block a user