- SplitModal: 금액 단일필드 → 공급가액+부가세 2필드로 변경 - 행별 합계금액 자동계산 표시 - 분개 리스트 행에 공급가액/부가세 개별 표시 - 분개 기반 요약 재계산 로직 추가 (recalculateSummary) - 모델: split_supply_amount, split_tax 필드 추가 - 컨트롤러: 분개 합계 검증 및 CSV 내보내기 반영 - 레거시 데이터(supply/tax 없는 기존 분개) 호환성 유지 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
141 lines
4.4 KiB
PHP
141 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace App\Models\Barobill;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use App\Models\Tenants\Tenant;
|
|
|
|
/**
|
|
* 카드 거래 분개 모델
|
|
* 하나의 카드 거래를 여러 계정과목으로 분개하여 저장
|
|
*/
|
|
class CardTransactionSplit extends Model
|
|
{
|
|
protected $table = 'barobill_card_transaction_splits';
|
|
|
|
protected $fillable = [
|
|
'tenant_id',
|
|
'original_unique_key',
|
|
'split_amount',
|
|
'split_supply_amount',
|
|
'split_tax',
|
|
'account_code',
|
|
'account_name',
|
|
'deduction_type',
|
|
'evidence_name',
|
|
'description',
|
|
'memo',
|
|
'sort_order',
|
|
'card_num',
|
|
'use_dt',
|
|
'use_date',
|
|
'approval_num',
|
|
'original_amount',
|
|
'merchant_name',
|
|
];
|
|
|
|
protected $casts = [
|
|
'split_amount' => 'decimal:2',
|
|
'split_supply_amount' => 'decimal:2',
|
|
'split_tax' => 'decimal:2',
|
|
'original_amount' => 'decimal:2',
|
|
'sort_order' => 'integer',
|
|
];
|
|
|
|
/**
|
|
* 테넌트 관계
|
|
*/
|
|
public function tenant(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Tenant::class);
|
|
}
|
|
|
|
/**
|
|
* 테넌트별 분개 내역 조회 (기간별)
|
|
* 고유키를 기준으로 그룹핑하여 반환
|
|
*/
|
|
public static function getByDateRange(int $tenantId, string $startDate, string $endDate): array
|
|
{
|
|
$splits = self::where('tenant_id', $tenantId)
|
|
->whereBetween('use_date', [$startDate, $endDate])
|
|
->orderBy('original_unique_key')
|
|
->orderBy('sort_order')
|
|
->get();
|
|
|
|
// 고유키별로 그룹핑
|
|
$grouped = [];
|
|
foreach ($splits as $split) {
|
|
$key = $split->original_unique_key;
|
|
if (!isset($grouped[$key])) {
|
|
$grouped[$key] = [];
|
|
}
|
|
$grouped[$key][] = $split;
|
|
}
|
|
|
|
return $grouped;
|
|
}
|
|
|
|
/**
|
|
* 특정 거래의 분개 내역 조회
|
|
*/
|
|
public static function getByUniqueKey(int $tenantId, string $uniqueKey): \Illuminate\Database\Eloquent\Collection
|
|
{
|
|
return self::where('tenant_id', $tenantId)
|
|
->where('original_unique_key', $uniqueKey)
|
|
->orderBy('sort_order')
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* 특정 거래의 분개 내역 저장 (기존 분개 삭제 후 재생성)
|
|
*/
|
|
public static function saveSplits(int $tenantId, string $uniqueKey, array $originalData, array $splits): void
|
|
{
|
|
// 기존 분개 삭제
|
|
self::where('tenant_id', $tenantId)
|
|
->where('original_unique_key', $uniqueKey)
|
|
->delete();
|
|
|
|
// 새 분개 저장
|
|
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' => $splitAmount,
|
|
'split_supply_amount' => $supplyAmount,
|
|
'split_tax' => $tax,
|
|
'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,
|
|
'sort_order' => $index,
|
|
'card_num' => $originalData['cardNum'] ?? '',
|
|
'use_dt' => $originalData['useDt'] ?? '',
|
|
'use_date' => $originalData['useDate'] ?? '',
|
|
'approval_num' => $originalData['approvalNum'] ?? '',
|
|
'original_amount' => $originalData['originalAmount'] ?? 0,
|
|
'merchant_name' => $originalData['merchantName'] ?? '',
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 분개 내역 삭제 (원본으로 복원)
|
|
*/
|
|
public static function deleteSplits(int $tenantId, string $uniqueKey): int
|
|
{
|
|
return self::where('tenant_id', $tenantId)
|
|
->where('original_unique_key', $uniqueKey)
|
|
->delete();
|
|
}
|
|
}
|