feat:개발 진행중 → 승인대기로 이동 기능 추가
- revertToPending 서비스 메서드 추가
- revertToPending 컨트롤러 액션 추가
- /approvals/{id}/revert-pending 라우트 추가
- progress-list에 "승인대기로" 버튼 추가
- JavaScript revertToPending 함수 추가
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -170,6 +170,41 @@ public function updateStatus(Request $request, int $id)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 승인대기로 되돌리기
|
||||
*/
|
||||
public function revertToPending(Request $request, int $id)
|
||||
{
|
||||
// 권한 체크
|
||||
if (!auth()->user()->isAdmin()) {
|
||||
abort(403, '접근 권한이 없습니다.');
|
||||
}
|
||||
|
||||
try {
|
||||
$management = $this->service->revertToPending($id);
|
||||
$tenantName = $management->tenant?->company_name ?? '알 수 없음';
|
||||
|
||||
if ($request->header('HX-Request')) {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => "{$tenantName}이(가) 승인대기로 이동되었습니다.",
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect()->route('sales.development.approvals.index')
|
||||
->with('success', "{$tenantName}이(가) 승인대기로 이동되었습니다.");
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
if ($request->header('HX-Request')) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => $e->getMessage(),
|
||||
], 400);
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 상세 정보 모달
|
||||
*/
|
||||
|
||||
@@ -202,6 +202,30 @@ public function updateHqStatus(int $id, string $status): SalesTenantManagement
|
||||
return $management->fresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* 승인대기로 되돌리기 (진행중 → pending)
|
||||
*/
|
||||
public function revertToPending(int $id): SalesTenantManagement
|
||||
{
|
||||
$management = SalesTenantManagement::findOrFail($id);
|
||||
|
||||
// 이미 pending 상태인 경우
|
||||
if ($management->hq_status === SalesTenantManagement::HQ_STATUS_PENDING) {
|
||||
throw new \InvalidArgumentException('이미 승인대기 상태입니다.');
|
||||
}
|
||||
|
||||
// handover(인계) 상태에서는 되돌리기 불가
|
||||
if ($management->hq_status === SalesTenantManagement::HQ_STATUS_HANDOVER) {
|
||||
throw new \InvalidArgumentException('인계 완료된 항목은 되돌릴 수 없습니다.');
|
||||
}
|
||||
|
||||
$management->update([
|
||||
'hq_status' => SalesTenantManagement::HQ_STATUS_PENDING,
|
||||
]);
|
||||
|
||||
return $management->fresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* 상세 정보 조회
|
||||
*/
|
||||
|
||||
@@ -198,6 +198,38 @@ function updateStatus(id, name) {
|
||||
);
|
||||
}
|
||||
|
||||
// 승인대기로 되돌리기
|
||||
function revertToPending(id, name) {
|
||||
showConfirm(
|
||||
`<strong>${name}</strong>을(를) 승인대기 상태로 되돌리시겠습니까?<br><small class="text-gray-500">개발 진행 상태가 초기화됩니다.</small>`,
|
||||
() => {
|
||||
fetch(`/sales/development/approvals/${id}/revert-pending`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
||||
'Accept': 'application/json',
|
||||
'HX-Request': 'true'
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
showToast(data.message, 'success');
|
||||
window.location.reload();
|
||||
} else {
|
||||
showToast(data.message || '되돌리기에 실패했습니다.', 'error');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
showToast('서버 오류가 발생했습니다.', 'error');
|
||||
console.error(error);
|
||||
});
|
||||
},
|
||||
{ title: '승인대기로 이동', icon: 'warning', confirmText: '이동' }
|
||||
);
|
||||
}
|
||||
|
||||
// 상세 모달 열기
|
||||
function openDetailModal(id) {
|
||||
document.getElementById('detailModal').classList.remove('hidden');
|
||||
|
||||
@@ -81,8 +81,13 @@ class="px-2 py-1 bg-purple-500 hover:bg-purple-600 text-white text-xs font-mediu
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{{-- 상세 버튼 --}}
|
||||
<div class="flex items-center justify-end">
|
||||
{{-- 버튼 --}}
|
||||
<div class="flex items-center justify-end gap-1">
|
||||
<button type="button"
|
||||
onclick="revertToPending({{ $item->id }}, '{{ addslashes($companyName) }}')"
|
||||
class="px-2 py-1 bg-yellow-500 hover:bg-yellow-600 text-white text-xs font-medium rounded transition">
|
||||
승인대기로
|
||||
</button>
|
||||
<button type="button"
|
||||
onclick="openDetailModal({{ $item->id }})"
|
||||
class="px-2 py-1 bg-gray-400 hover:bg-gray-500 text-white text-xs font-medium rounded transition">
|
||||
|
||||
@@ -897,6 +897,8 @@
|
||||
->name('approvals.reject');
|
||||
Route::post('/approvals/{id}/status', [\App\Http\Controllers\Sales\SalesDevelopmentApprovalController::class, 'updateStatus'])
|
||||
->name('approvals.status');
|
||||
Route::post('/approvals/{id}/revert-pending', [\App\Http\Controllers\Sales\SalesDevelopmentApprovalController::class, 'revertToPending'])
|
||||
->name('approvals.revert-pending');
|
||||
Route::get('/approvals/{id}/detail', [\App\Http\Controllers\Sales\SalesDevelopmentApprovalController::class, 'detail'])
|
||||
->name('approvals.detail');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user