'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); } }