feat: [esign] 전자계약 수정 기능 추가

- draft 상태 계약의 제목, 설명, 서명자 정보, 파일 수정 가능
- 계약 상세 페이지에 '계약 정보 수정' 버튼 추가
- create.blade.php를 생성/수정 겸용으로 확장
This commit is contained in:
김보곤
2026-03-11 11:55:46 +09:00
parent d7428e1785
commit edc69040ab
5 changed files with 186 additions and 18 deletions

View File

@@ -572,6 +572,97 @@ public function store(Request $request): JsonResponse
]);
}
/**
* 계약 수정 (draft 상태만)
*/
public function update(Request $request, int $id): JsonResponse
{
$tenantId = session('selected_tenant_id', 1);
$contract = EsignContract::forTenant($tenantId)->findOrFail($id);
if ($contract->status !== 'draft') {
return response()->json(['success' => false, 'message' => '초안 상태의 계약만 수정할 수 있습니다.'], 422);
}
$request->validate([
'title' => 'required|string|max:200',
'description' => 'nullable|string',
'sign_order_type' => 'required|in:counterpart_first,creator_first',
'expires_at' => 'nullable|date',
'signers' => 'required|array|size:2',
'signers.*.name' => 'required|string|max:100',
'signers.*.email' => 'required|email|max:200',
'signers.*.phone' => 'nullable|string|max:20',
'signers.*.role' => 'required|in:creator,counterpart',
'file' => 'nullable|file|mimes:pdf,doc,docx|max:20480',
]);
$userId = auth()->id();
// PDF 파일 교체
if ($request->hasFile('file')) {
// 기존 파일 삭제
if ($contract->original_file_path && Storage::disk('local')->exists($contract->original_file_path)) {
Storage::disk('local')->delete($contract->original_file_path);
}
$file = $request->file('file');
$converter = new DocxToPdfConverter;
$result = $converter->convertAndStore($file, "esign/{$tenantId}/contracts");
$contract->original_file_path = $result['path'];
$contract->original_file_name = $result['name'];
$contract->original_file_hash = $result['hash'];
$contract->original_file_size = $result['size'];
}
$contract->title = $request->input('title');
$contract->description = $request->input('description');
$contract->sign_order_type = $request->input('sign_order_type');
$contract->expires_at = $request->input('expires_at')
? \Carbon\Carbon::parse($request->input('expires_at'))
: $contract->expires_at;
$contract->updated_by = $userId;
$contract->save();
// 서명자 정보 업데이트
$signers = $request->input('signers');
foreach ($signers as $signerData) {
$existingSigner = EsignSigner::withoutGlobalScopes()
->where('contract_id', $contract->id)
->where('role', $signerData['role'])
->first();
if ($existingSigner) {
$existingSigner->update([
'name' => $signerData['name'],
'email' => $signerData['email'],
'phone' => $signerData['phone'] ?? null,
'sign_order' => $signerData['role'] === 'creator'
? ($request->input('sign_order_type') === 'creator_first' ? 1 : 2)
: ($request->input('sign_order_type') === 'counterpart_first' ? 1 : 2),
]);
}
}
// 감사 로그
EsignAuditLog::create([
'tenant_id' => $tenantId,
'contract_id' => $contract->id,
'action' => 'contract_updated',
'ip_address' => $request->ip(),
'user_agent' => $request->userAgent(),
'metadata' => ['updated_by' => $userId],
'created_at' => now(),
]);
return response()->json([
'success' => true,
'message' => '계약이 수정되었습니다.',
'data' => $contract->load('signers'),
]);
}
/**
* 계약 취소
*/