feat:계약 대시보드 선택 삭제 기능 추가
- EsignApiController에 destroy 메서드 추가 (복수 삭제 지원) - 관련 파일(PDF, 서명이미지) 및 레코드(서명자, 필드, 감사로그) 일괄 삭제 - 서명 진행 중(pending, partially_signed) 계약은 삭제 차단 - DELETE /esign/contracts/destroy 라우트 추가 - 대시보드에 체크박스 전체/개별 선택 + 삭제 버튼 UI 추가 - 삭제 전 confirm 확인 다이얼로그 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -219,6 +219,66 @@ public function cancel(Request $request, int $id): JsonResponse
|
||||
return response()->json(['success' => true, 'message' => '계약이 취소되었습니다.']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 계약 삭제 (단건/복수)
|
||||
*/
|
||||
public function destroy(Request $request): JsonResponse
|
||||
{
|
||||
$request->validate([
|
||||
'ids' => 'required|array|min:1',
|
||||
'ids.*' => 'required|integer',
|
||||
]);
|
||||
|
||||
$tenantId = session('selected_tenant_id', 1);
|
||||
$ids = $request->input('ids');
|
||||
|
||||
$contracts = EsignContract::forTenant($tenantId)->whereIn('id', $ids)->get();
|
||||
|
||||
if ($contracts->isEmpty()) {
|
||||
return response()->json(['success' => false, 'message' => '삭제할 계약을 찾을 수 없습니다.'], 404);
|
||||
}
|
||||
|
||||
// 진행 중인 계약(pending, partially_signed) 차단
|
||||
$activeContracts = $contracts->filter(fn ($c) => in_array($c->status, ['pending', 'partially_signed']));
|
||||
if ($activeContracts->isNotEmpty()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '서명 진행 중인 계약은 삭제할 수 없습니다. 먼저 취소해 주세요.',
|
||||
], 422);
|
||||
}
|
||||
|
||||
$deletedCount = 0;
|
||||
foreach ($contracts as $contract) {
|
||||
// 관련 파일 삭제
|
||||
if ($contract->original_file_path && Storage::disk('local')->exists($contract->original_file_path)) {
|
||||
Storage::disk('local')->delete($contract->original_file_path);
|
||||
}
|
||||
if ($contract->signed_file_path && Storage::disk('local')->exists($contract->signed_file_path)) {
|
||||
Storage::disk('local')->delete($contract->signed_file_path);
|
||||
}
|
||||
|
||||
// 서명 이미지 파일 삭제
|
||||
$signers = EsignSigner::withoutGlobalScopes()->where('contract_id', $contract->id)->get();
|
||||
foreach ($signers as $signer) {
|
||||
if ($signer->signature_image_path && Storage::disk('local')->exists($signer->signature_image_path)) {
|
||||
Storage::disk('local')->delete($signer->signature_image_path);
|
||||
}
|
||||
}
|
||||
|
||||
// 관련 레코드 삭제
|
||||
EsignSignField::where('contract_id', $contract->id)->delete();
|
||||
EsignAuditLog::where('contract_id', $contract->id)->delete();
|
||||
EsignSigner::withoutGlobalScopes()->where('contract_id', $contract->id)->delete();
|
||||
$contract->delete();
|
||||
$deletedCount++;
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => "{$deletedCount}건의 계약이 삭제되었습니다.",
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 서명 위치 설정
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user