- BankTransaction 모델: getUniqueKeyAttribute, generateUniqueKey에 summary 추가 - EaccountController: API 응답 및 DB upsert 시 summary 포함 매칭 - JournalEntry, JournalEntryController: 레거시(5필드) 키 호환 처리 - BankTransactionOverride: 레거시 키 호환 조회
130 lines
3.7 KiB
PHP
130 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Models\Finance;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class JournalEntry extends Model
|
|
{
|
|
use SoftDeletes;
|
|
|
|
protected $table = 'journal_entries';
|
|
|
|
protected $fillable = [
|
|
'tenant_id',
|
|
'entry_no',
|
|
'entry_date',
|
|
'entry_type',
|
|
'description',
|
|
'total_debit',
|
|
'total_credit',
|
|
'status',
|
|
'source_type',
|
|
'source_key',
|
|
'created_by_name',
|
|
'attachment_note',
|
|
];
|
|
|
|
protected $casts = [
|
|
'entry_date' => 'date',
|
|
'total_debit' => 'integer',
|
|
'total_credit' => 'integer',
|
|
];
|
|
|
|
public function lines()
|
|
{
|
|
return $this->hasMany(JournalEntryLine::class)->orderBy('line_no');
|
|
}
|
|
|
|
public function scopeForTenant($query, $tenantId)
|
|
{
|
|
return $query->where('tenant_id', $tenantId);
|
|
}
|
|
|
|
/**
|
|
* 분개 완료된 source_key 일괄 조회
|
|
* 레거시(summary 미포함) 형식과 신규(summary 포함) 형식 모두 매칭
|
|
*/
|
|
public static function getJournaledSourceKeys(int $tenantId, string $sourceType, array $sourceKeys): array
|
|
{
|
|
if (empty($sourceKeys)) {
|
|
return [];
|
|
}
|
|
|
|
// 레거시 키도 함께 검색 (새 키에서 마지막 |summary 부분 제거)
|
|
$allKeys = $sourceKeys;
|
|
$legacyToNewMap = [];
|
|
foreach ($sourceKeys as $key) {
|
|
$parts = explode('|', $key);
|
|
if (count($parts) === 6) {
|
|
$legacyKey = implode('|', array_slice($parts, 0, 5));
|
|
$allKeys[] = $legacyKey;
|
|
$legacyToNewMap[$legacyKey] = $key;
|
|
}
|
|
}
|
|
|
|
$found = static::where('tenant_id', $tenantId)
|
|
->where('source_type', $sourceType)
|
|
->whereIn('source_key', array_unique($allKeys))
|
|
->pluck('source_key')
|
|
->toArray();
|
|
|
|
// 레거시 키로 매칭된 것을 새 키 형식으로 변환하여 반환
|
|
$result = [];
|
|
foreach ($found as $key) {
|
|
if (in_array($key, $sourceKeys)) {
|
|
$result[] = $key;
|
|
} elseif (isset($legacyToNewMap[$key])) {
|
|
$result[] = $legacyToNewMap[$key];
|
|
}
|
|
}
|
|
|
|
return array_unique($result);
|
|
}
|
|
|
|
/**
|
|
* source_key로 분개 전표 조회 (ID 포함)
|
|
* 레거시(summary 미포함) 형식과 신규(summary 포함) 형식 모두 매칭
|
|
*/
|
|
public static function getJournalBySourceKey(int $tenantId, string $sourceType, string $sourceKey)
|
|
{
|
|
$keys = [$sourceKey];
|
|
$parts = explode('|', $sourceKey);
|
|
if (count($parts) === 6) {
|
|
$keys[] = implode('|', array_slice($parts, 0, 5));
|
|
}
|
|
|
|
return static::where('tenant_id', $tenantId)
|
|
->where('source_type', $sourceType)
|
|
->whereIn('source_key', $keys)
|
|
->first();
|
|
}
|
|
|
|
/**
|
|
* 전표번호 자동채번: JE-YYYYMMDD-NNN
|
|
*/
|
|
public static function generateEntryNo($tenantId, $date)
|
|
{
|
|
$dateStr = date('Ymd', strtotime($date));
|
|
$prefix = "JE-{$dateStr}-";
|
|
|
|
// withTrashed: soft-deleted 레코드도 포함하여 채번 (DB unique 제약 충돌 방지)
|
|
$last = static::withTrashed()
|
|
->where('tenant_id', $tenantId)
|
|
->where('entry_no', 'like', $prefix.'%')
|
|
->lockForUpdate()
|
|
->orderByDesc('entry_no')
|
|
->value('entry_no');
|
|
|
|
if ($last) {
|
|
$seq = (int) substr($last, -3) + 1;
|
|
} else {
|
|
$seq = 1;
|
|
}
|
|
|
|
return $prefix.str_pad($seq, 3, '0', STR_PAD_LEFT);
|
|
}
|
|
}
|