diff --git a/app/Services/BendingItemService.php b/app/Services/BendingItemService.php index 99c7dca4..f9674df2 100644 --- a/app/Services/BendingItemService.php +++ b/app/Services/BendingItemService.php @@ -47,16 +47,9 @@ public function create(array $data): BendingItem { $code = $data['code'] ?? ''; - // BD-XX 접두사가 있으면 순번 자동 채번 + // BD-XX 접두사 → 자동 채번 (BD-XX 또는 BD-XX.nn) if (preg_match('/^BD-([A-Z]{2})$/i', $code, $m)) { $code = $this->generateCode($m[1]); - } elseif (preg_match('/^BD-([A-Z]{2})-\d+$/i', $code)) { - // BD-XX-nn 완전한 코드 — 그대로 사용 (중복 검증) - $exists = BendingItem::withoutGlobalScopes()->where('code', $code)->exists(); - if ($exists) { - $prefix = substr($code, 3, 2); - $code = $this->generateCode($prefix); - } } return BendingItem::create([ @@ -151,25 +144,48 @@ private function buildOptions(array $data): ?array ]; /** - * BD-{prefix}-{순번} 코드 자동 채번 + * 기초자료 코드 자동 채번 + * + * 해당 분류에 기존 항목이 없으면: BD-XX (순번 없음) + * 기존 1건(BD-XX)이면: 기존을 BD-XX.01로 변경 후 BD-XX.02 반환 + * 기존 다수(BD-XX.nn)면: 마지막 순번 +1 반환 */ private function generateCode(string $prefix): string { $prefix = strtoupper($prefix); - $lastCode = BendingItem::withoutGlobalScopes() - ->where('code', 'like', "BD-{$prefix}-%") - ->orderByRaw('CAST(SUBSTRING(code, ?) AS UNSIGNED) DESC', [strlen("BD-{$prefix}-") + 1]) + // BD-XX.nn 형태 중 가장 큰 순번 조회 + $lastDotCode = BendingItem::withoutGlobalScopes() + ->where('code', 'like', "BD-{$prefix}.%") + ->orderByRaw('CAST(SUBSTRING(code, ?) AS UNSIGNED) DESC', [strlen("BD-{$prefix}.") + 1]) ->value('code'); - $nextSeq = 1; - if ($lastCode && preg_match('/BD-[A-Z]{2}-(\d+)$/', $lastCode, $m)) { - $nextSeq = (int) $m[1] + 1; + // BD-XX (순번 없음) 존재 여부 + $plainExists = BendingItem::withoutGlobalScopes() + ->where('code', "BD-{$prefix}") + ->exists(); + + if (! $lastDotCode && ! $plainExists) { + // 해당 분류 첫 등록 → BD-XX + return "BD-{$prefix}"; } + if ($plainExists && ! $lastDotCode) { + // 기존 1건(BD-XX)만 있음 → BD-XX를 BD-XX.01로 변경하고, 신규는 BD-XX.02 + $existing = BendingItem::withoutGlobalScopes()->where('code', "BD-{$prefix}")->first(); + $existing->code = "BD-{$prefix}.01"; + $existing->timestamps = false; + $existing->saveQuietly(); + + return "BD-{$prefix}.02"; + } + + // BD-XX.nn이 이미 있음 → 마지막 +1 + preg_match('/\.(\d+)$/', $lastDotCode, $m); + $nextSeq = (int) ($m[1] ?? 0) + 1; $pad = $nextSeq >= 100 ? 3 : 2; - return 'BD-'.$prefix.'-'.str_pad($nextSeq, $pad, '0', STR_PAD_LEFT); + return "BD-{$prefix}.".str_pad($nextSeq, $pad, '0', STR_PAD_LEFT); } /** @@ -179,7 +195,7 @@ public function prefixes(): array { return BendingItem::withoutGlobalScopes() ->where('code', 'like', 'BD-%') - ->selectRaw('SUBSTRING(code, 4, 2) as prefix, COUNT(*) as cnt') + ->selectRaw("CASE WHEN code LIKE 'BD-__.%' THEN SUBSTRING(code, 4, 2) ELSE SUBSTRING(code, 4, 2) END as prefix, COUNT(*) as cnt") ->groupBy('prefix') ->orderBy('prefix') ->pluck('cnt', 'prefix')