espace-paie-odentas/app/api/staff/contracts/bulk-esign/route.ts

220 lines
8.1 KiB
TypeScript

// app/api/staff/contracts/bulk-esign/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { createSbServiceRole } from '@/lib/supabaseServer';
export async function POST(request: NextRequest) {
console.log('=== Bulk E-Sign API ===');
try {
const supabase = createSbServiceRole();
const { contractIds } = await request.json();
if (!Array.isArray(contractIds) || contractIds.length === 0) {
return NextResponse.json(
{ error: 'contractIds doit être un tableau non vide' },
{ status: 400 }
);
}
console.log(`📝 Traitement de ${contractIds.length} contrats pour signature électronique`);
// Déterminer l'URL de base pour les appels API internes
// En production, utiliser toujours l'URL de production principale
const baseUrl = process.env.NEXT_PUBLIC_APP_URL ||
(process.env.VERCEL_ENV === 'production' ? 'https://paie.odentas.fr' :
process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` :
'http://localhost:3000');
console.log(`🌐 Base URL utilisée: ${baseUrl}`);
// Récupérer les informations des contrats
const { data: contracts, error: contractsError } = await supabase
.from('cddu_contracts')
.select('*')
.in('id', contractIds);
if (contractsError) {
console.error('❌ Erreur lors de la récupération des contrats:', contractsError);
return NextResponse.json(
{ error: 'Erreur lors de la récupération des contrats' },
{ status: 500 }
);
}
const results = [];
for (const contract of contracts || []) {
try {
console.log(`\n🔄 Traitement du contrat ${contract.contract_number || contract.id}`);
// Vérifier que le contrat a un PDF généré
if (!contract.contract_pdf_filename) {
results.push({
contractId: contract.id,
contractNumber: contract.contract_number,
success: false,
error: 'PDF du contrat non généré'
});
continue;
}
// Récupérer l'email du salarié UNIQUEMENT par matricule
let employeeEmail = null;
if (!contract.employee_matricule) {
console.log(`❌ Matricule manquant pour le contrat ${contract.contract_number}`);
results.push({
contractId: contract.id,
contractNumber: contract.contract_number,
employeeName: contract.employee_name,
success: false,
error: `Matricule salarié manquant dans le contrat`
});
continue;
}
console.log(`🔍 Recherche email pour matricule: ${contract.employee_matricule}`);
const { data: salarie } = await supabase
.from('salaries')
.select('adresse_mail, nom, prenom')
.eq('code_salarie', contract.employee_matricule)
.maybeSingle();
employeeEmail = salarie?.adresse_mail;
if (!employeeEmail) {
console.log(`❌ Salarié non trouvé ou email manquant pour matricule: ${contract.employee_matricule}`);
results.push({
contractId: contract.id,
contractNumber: contract.contract_number,
employeeName: contract.employee_name,
success: false,
error: `Email du salarié non trouvé pour le matricule ${contract.employee_matricule}. Vérifiez que le salarié existe et a un email renseigné.`
});
continue;
}
console.log(`✅ Email trouvé: ${employeeEmail} (${salarie?.prenom || ''} ${salarie?.nom || ''})`);
// Récupérer les informations de l'organisation
let employerEmail = "paie@odentas.fr";
let signerName = "Responsable";
let organizationName = contract.production_name || "Organisation";
let employerCode = "DEMO";
if (contract.org_id) {
const { data: orgDetails } = await supabase
.from('organization_details')
.select('*')
.eq('org_id', contract.org_id)
.maybeSingle();
if (orgDetails) {
employerEmail = orgDetails.email_signature || orgDetails.email_contact || employerEmail;
signerName = `${orgDetails.prenom_signataire || ""} ${orgDetails.nom_signataire || ""}`.trim() || signerName;
organizationName = orgDetails.structure || organizationName;
employerCode = orgDetails.code_employeur || employerCode;
console.log(`✅ Organisation trouvée: ${organizationName}, email: ${employerEmail}`);
} else {
console.log(`⚠️ Aucun orgDetails trouvé pour org_id: ${contract.org_id}`);
}
}
// Construire la clé S3 du PDF
const pdfS3Key = `unsigned-contracts/${contract.contract_pdf_filename}`;
// Préparer les données pour l'API DocuSeal
const signatureData = {
contractId: contract.id,
pdfS3Key: pdfS3Key,
employerEmail: employerEmail,
employeeEmail: employeeEmail,
reference: contract.reference || contract.contract_number,
employeeName: contract.employee_name,
startDate: contract.start_date,
role: contract.profession || contract.role,
analytique: contract.analytique || contract.production_name,
structure: organizationName,
signerFirstName: signerName,
employerCode: employerCode,
employeeFirstName: contract.employee_name?.split(' ')[0],
matricule: contract.employee_matricule,
contractType: 'CDDU',
skipEmployerEmail: true, // Ne pas envoyer d'email à l'employeur individuellement
orgId: contract.org_id // Passer l'org_id pour récupérer la signature
};
console.log(`📤 Appel API DocuSeal pour contrat ${contract.contract_number}`);
// Appeler l'API DocuSeal
const docusealResponse = await fetch(`${baseUrl}/api/docuseal-signature`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(signatureData),
});
if (!docusealResponse.ok) {
const errorData = await docusealResponse.json();
results.push({
contractId: contract.id,
contractNumber: contract.contract_number,
success: false,
error: errorData.error || `Erreur ${docusealResponse.status}`
});
continue;
}
const docusealResult = await docusealResponse.json();
results.push({
contractId: contract.id,
contractNumber: contract.contract_number,
employeeName: contract.employee_name,
success: true,
submissionId: docusealResult.data?.submissionId,
org_id: contract.org_id // Ajouter l'org_id pour l'envoi d'email
});
console.log(`✅ Signature créée pour contrat ${contract.contract_number}`);
} catch (error) {
console.error(`❌ Erreur pour contrat ${contract.id}:`, error);
results.push({
contractId: contract.id,
contractNumber: contract.contract_number,
success: false,
error: error instanceof Error ? error.message : 'Erreur inconnue'
});
}
}
const successCount = results.filter(r => r.success).length;
const errorCount = results.filter(r => !r.success).length;
console.log(`\n✅ Traitement terminé: ${successCount} succès, ${errorCount} erreurs`);
return NextResponse.json({
success: true,
message: `Signatures électroniques créées: ${successCount} succès, ${errorCount} erreurs`,
results: results,
summary: {
total: results.length,
success: successCount,
errors: errorCount
}
});
} catch (error) {
console.error('Erreur lors du traitement bulk e-sign:', error);
return NextResponse.json(
{
error: 'Erreur lors du traitement des signatures électroniques',
details: error instanceof Error ? error.message : 'Erreur inconnue'
},
{ status: 500 }
);
}
}