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();
|
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) {
|
function openDetailModal(id) {
|
||||||
document.getElementById('detailModal').classList.remove('hidden');
|
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>
|
</span>
|
||||||
</div>
|
</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"
|
<button type="button"
|
||||||
onclick="openDetailModal({{ $item->id }})"
|
onclick="openDetailModal({{ $item->id }})"
|
||||||
class="px-2 py-1 bg-gray-400 hover:bg-gray-500 text-white text-xs font-medium rounded transition">
|
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');
|
->name('approvals.reject');
|
||||||
Route::post('/approvals/{id}/status', [\App\Http\Controllers\Sales\SalesDevelopmentApprovalController::class, 'updateStatus'])
|
Route::post('/approvals/{id}/status', [\App\Http\Controllers\Sales\SalesDevelopmentApprovalController::class, 'updateStatus'])
|
||||||
->name('approvals.status');
|
->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'])
|
Route::get('/approvals/{id}/detail', [\App\Http\Controllers\Sales\SalesDevelopmentApprovalController::class, 'detail'])
|
||||||
->name('approvals.detail');
|
->name('approvals.detail');
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user