220 lines
8.1 KiB
TypeScript
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 }
|
|
);
|
|
}
|
|
}
|