feat:휴일관리 중복 방지 및 년도별 삭제 기능 추가
- store/bulkStore 메소드에 중복 휴일 등록 방지 로직 추가 - 년도별 일괄 삭제 기능 (destroyByYear) 추가 - 휴일관리 UI에 년도 전체 삭제 버튼 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -61,6 +61,20 @@ public function store(Request $request): JsonResponse
|
||||
|
||||
$tenantId = session('selected_tenant_id', 1);
|
||||
|
||||
// 중복 체크: 같은 날짜 + 같은 이름
|
||||
$exists = Holiday::forTenant($tenantId)
|
||||
->where('start_date', $request->input('startDate'))
|
||||
->where('end_date', $request->input('endDate'))
|
||||
->where('name', $request->input('name'))
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '동일한 휴일이 이미 등록되어 있습니다.',
|
||||
], 422);
|
||||
}
|
||||
|
||||
$holiday = Holiday::create([
|
||||
'tenant_id' => $tenantId,
|
||||
'start_date' => $request->input('startDate'),
|
||||
@@ -132,8 +146,21 @@ public function bulkStore(Request $request): JsonResponse
|
||||
|
||||
$tenantId = session('selected_tenant_id', 1);
|
||||
$count = 0;
|
||||
$skipped = 0;
|
||||
|
||||
foreach ($request->input('holidays') as $item) {
|
||||
// 중복 체크
|
||||
$exists = Holiday::forTenant($tenantId)
|
||||
->where('start_date', $item['startDate'])
|
||||
->where('end_date', $item['endDate'])
|
||||
->where('name', $item['name'])
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
$skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
Holiday::create([
|
||||
'tenant_id' => $tenantId,
|
||||
'start_date' => $item['startDate'],
|
||||
@@ -146,9 +173,37 @@ public function bulkStore(Request $request): JsonResponse
|
||||
$count++;
|
||||
}
|
||||
|
||||
$message = "{$count}건의 휴일이 등록되었습니다.";
|
||||
if ($skipped > 0) {
|
||||
$message .= " (중복 {$skipped}건 제외)";
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => "{$count}건의 휴일이 등록되었습니다.",
|
||||
'message' => $message,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 해당 연도의 모든 휴일 삭제
|
||||
*/
|
||||
public function destroyByYear(Request $request): JsonResponse
|
||||
{
|
||||
$request->validate([
|
||||
'year' => 'required|integer|min:2000|max:2100',
|
||||
]);
|
||||
|
||||
$tenantId = session('selected_tenant_id', 1);
|
||||
$year = $request->input('year');
|
||||
|
||||
$count = Holiday::forTenant($tenantId)
|
||||
->forYear($year)
|
||||
->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => "{$year}년도 휴일 {$count}건이 삭제되었습니다.",
|
||||
'data' => ['deleted' => $count],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +180,26 @@ function HolidayManagement() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteYear = async () => {
|
||||
if (!confirm(`${selectedYear}년도의 모든 휴일(${totalHolidays}건)을 삭제하시겠습니까?\n\n이 작업은 되돌릴 수 없습니다.`)) return;
|
||||
try {
|
||||
const res = await fetch(`/system/holidays/year/${selectedYear}`, {
|
||||
method: 'DELETE',
|
||||
headers: { 'X-CSRF-TOKEN': csrfToken },
|
||||
});
|
||||
const data = await res.json();
|
||||
if (res.ok) {
|
||||
alert(data.message);
|
||||
fetchHolidays(selectedYear);
|
||||
} else {
|
||||
alert(data.message || '삭제에 실패했습니다.');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('연도별 삭제 실패:', err);
|
||||
alert('삭제에 실패했습니다.');
|
||||
}
|
||||
};
|
||||
|
||||
// 대량 등록 파싱
|
||||
const parseBulkText = (text) => {
|
||||
const lines = text.trim().split('\n').filter(l => l.trim());
|
||||
@@ -420,6 +440,14 @@ className={`relative h-9 flex flex-col items-center justify-center rounded curso
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{totalHolidays > 0 && (
|
||||
<button
|
||||
onClick={handleDeleteYear}
|
||||
className="ml-auto px-3 py-1.5 text-sm text-red-600 hover:text-white hover:bg-red-600 border border-red-300 rounded-lg transition-colors"
|
||||
>
|
||||
{selectedYear}년 전체 삭제
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -401,6 +401,7 @@
|
||||
Route::put('/{id}', [HolidayController::class, 'update'])->name('update');
|
||||
Route::delete('/{id}', [HolidayController::class, 'destroy'])->name('destroy');
|
||||
Route::post('/bulk', [HolidayController::class, 'bulkStore'])->name('bulk');
|
||||
Route::delete('/year/{year}', [HolidayController::class, 'destroyByYear'])->name('destroy-year');
|
||||
});
|
||||
|
||||
// 명함 OCR API
|
||||
|
||||
Reference in New Issue
Block a user