feat: export manuel (exportToPdf) supporte maintenant SharePoint en plus du dossier local
This commit is contained in:
@@ -1136,6 +1136,8 @@ export const appRouter = router({
|
|||||||
// Get export folder from settings
|
// Get export folder from settings
|
||||||
const settings = await getImportSettingsByUser(ctx.user.id);
|
const settings = await getImportSettingsByUser(ctx.user.id);
|
||||||
const exportFolder = settings?.exportFolder;
|
const exportFolder = settings?.exportFolder;
|
||||||
|
const exportFolderType = (settings as any)?.exportFolderType || 'local';
|
||||||
|
const isSharePoint = exportFolderType === 'sharepoint';
|
||||||
|
|
||||||
// Load service→signature associations
|
// Load service→signature associations
|
||||||
const serviceAssociations = await getServiceSignaturesByUser(ctx.user.id);
|
const serviceAssociations = await getServiceSignaturesByUser(ctx.user.id);
|
||||||
@@ -1163,18 +1165,22 @@ export const appRouter = router({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create export folder if it doesn't exist
|
// Create export folder if not SharePoint
|
||||||
try {
|
if (!isSharePoint) {
|
||||||
await fs.mkdir(exportFolder, { recursive: true });
|
try {
|
||||||
} catch (error) {
|
await fs.mkdir(exportFolder, { recursive: true });
|
||||||
console.error('Error creating export folder:', error);
|
} catch (error) {
|
||||||
throw new TRPCError({
|
console.error('Error creating export folder:', error);
|
||||||
code: "INTERNAL_SERVER_ERROR",
|
throw new TRPCError({
|
||||||
message: `Impossible de créer le dossier d'export: ${exportFolder}`
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
});
|
message: `Impossible de créer le dossier d'export: ${exportFolder}`
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy PDFs to export folder
|
console.log(`[exportToPdf] Mode: ${exportFolderType}, dossier: ${exportFolder}, ${invoices.length} facture(s)`);
|
||||||
|
|
||||||
|
// Copy/upload PDFs to export folder
|
||||||
const copiedFiles: string[] = [];
|
const copiedFiles: string[] = [];
|
||||||
const errors: string[] = [];
|
const errors: string[] = [];
|
||||||
const STORAGE_BASE_PATH = process.env.STORAGE_BASE_PATH || path.join(process.cwd(), "storage");
|
const STORAGE_BASE_PATH = process.env.STORAGE_BASE_PATH || path.join(process.cwd(), "storage");
|
||||||
@@ -1261,38 +1267,88 @@ export const appRouter = router({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const signedPdfBytes = await pdfDoc.save();
|
const signedPdfBytes = await pdfDoc.save();
|
||||||
await fs.writeFile(destPath, signedPdfBytes);
|
|
||||||
copiedFiles.push(destPath);
|
|
||||||
console.log(`[Export] Signature apposée pour ${serviceName} sur ${filename}`);
|
console.log(`[Export] Signature apposée pour ${serviceName} sur ${filename}`);
|
||||||
|
if (isSharePoint) {
|
||||||
|
const { uploadToSharePoint } = await import('./sharepoint');
|
||||||
|
console.log(`[exportToPdf] Upload SharePoint: ${filename}`);
|
||||||
|
const spResult = await uploadToSharePoint(
|
||||||
|
{ tenantId: (settings as any)?.azureTenantId || '', clientId: (settings as any)?.azureClientId || '', clientSecret: (settings as any)?.azureClientSecret || '', sharepointUrl: exportFolder },
|
||||||
|
Buffer.from(signedPdfBytes), filename
|
||||||
|
);
|
||||||
|
if (!spResult.success) throw new Error(`SharePoint: ${spResult.error}`);
|
||||||
|
console.log(`[exportToPdf] Upload SharePoint réussi: ${spResult.webUrl}`);
|
||||||
|
copiedFiles.push(spResult.webUrl || filename);
|
||||||
|
} else {
|
||||||
|
await fs.writeFile(destPath, signedPdfBytes);
|
||||||
|
copiedFiles.push(destPath);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Signature not found, copy without signature
|
// Signature not found, upload/copy without signature
|
||||||
try { await fs.copyFile(sourcePath, destPath); } catch (_) {
|
let pdfBuf: Buffer;
|
||||||
|
try { pdfBuf = await fs.readFile(sourcePath); } catch (_) {
|
||||||
const fu = invoice!.fileUrl; if (!fu) throw new Error('PDF introuvable');
|
const fu = invoice!.fileUrl; if (!fu) throw new Error('PDF introuvable');
|
||||||
const au = fu.startsWith('/') ? `${process.env.APP_BASE_URL||`http://localhost:${process.env.PORT||3000}`}${fu}` : fu;
|
const au = fu.startsWith('/') ? `${process.env.APP_BASE_URL||`http://localhost:${process.env.PORT||3000}`}${fu}` : fu;
|
||||||
const rb = await fetch(au); if (!rb.ok) throw new Error(`HTTP ${rb.status}`);
|
const rb = await fetch(au); if (!rb.ok) throw new Error(`HTTP ${rb.status}`);
|
||||||
await fs.writeFile(destPath, Buffer.from(await rb.arrayBuffer()));
|
pdfBuf = Buffer.from(await rb.arrayBuffer());
|
||||||
|
}
|
||||||
|
if (isSharePoint) {
|
||||||
|
const { uploadToSharePoint } = await import('./sharepoint');
|
||||||
|
const spResult = await uploadToSharePoint(
|
||||||
|
{ tenantId: (settings as any)?.azureTenantId || '', clientId: (settings as any)?.azureClientId || '', clientSecret: (settings as any)?.azureClientSecret || '', sharepointUrl: exportFolder },
|
||||||
|
pdfBuf, filename
|
||||||
|
);
|
||||||
|
if (!spResult.success) throw new Error(`SharePoint: ${spResult.error}`);
|
||||||
|
copiedFiles.push(spResult.webUrl || filename);
|
||||||
|
} else {
|
||||||
|
try { await fs.copyFile(sourcePath, destPath); } catch (_) { await fs.writeFile(destPath, pdfBuf); }
|
||||||
|
copiedFiles.push(destPath);
|
||||||
}
|
}
|
||||||
copiedFiles.push(destPath);
|
|
||||||
}
|
}
|
||||||
} catch (sigError: any) {
|
} catch (sigError: any) {
|
||||||
console.warn(`[Export] Impossible d'apposer la signature: ${sigError.message}. Copie sans signature.`);
|
console.warn(`[Export] Impossible d'apposer la signature: ${sigError.message}. Copie sans signature.`);
|
||||||
try { await fs.copyFile(sourcePath, destPath); } catch (_) {
|
let pdfBuf: Buffer;
|
||||||
|
try { pdfBuf = await fs.readFile(sourcePath); } catch (_) {
|
||||||
const fu = invoice!.fileUrl; if (!fu) throw new Error('PDF introuvable');
|
const fu = invoice!.fileUrl; if (!fu) throw new Error('PDF introuvable');
|
||||||
const au = fu.startsWith('/') ? `${process.env.APP_BASE_URL||`http://localhost:${process.env.PORT||3000}`}${fu}` : fu;
|
const au = fu.startsWith('/') ? `${process.env.APP_BASE_URL||`http://localhost:${process.env.PORT||3000}`}${fu}` : fu;
|
||||||
const rb = await fetch(au); if (!rb.ok) throw new Error(`HTTP ${rb.status}`);
|
const rb = await fetch(au); if (!rb.ok) throw new Error(`HTTP ${rb.status}`);
|
||||||
await fs.writeFile(destPath, Buffer.from(await rb.arrayBuffer()));
|
pdfBuf = Buffer.from(await rb.arrayBuffer());
|
||||||
|
}
|
||||||
|
if (isSharePoint) {
|
||||||
|
const { uploadToSharePoint } = await import('./sharepoint');
|
||||||
|
const spResult = await uploadToSharePoint(
|
||||||
|
{ tenantId: (settings as any)?.azureTenantId || '', clientId: (settings as any)?.azureClientId || '', clientSecret: (settings as any)?.azureClientSecret || '', sharepointUrl: exportFolder },
|
||||||
|
pdfBuf, filename
|
||||||
|
);
|
||||||
|
if (!spResult.success) throw new Error(`SharePoint: ${spResult.error}`);
|
||||||
|
copiedFiles.push(spResult.webUrl || filename);
|
||||||
|
} else {
|
||||||
|
try { await fs.copyFile(sourcePath, destPath); } catch (_) { await fs.writeFile(destPath, pdfBuf); }
|
||||||
|
copiedFiles.push(destPath);
|
||||||
}
|
}
|
||||||
copiedFiles.push(destPath);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No signature association, copy as-is
|
// No signature association, upload/copy as-is
|
||||||
try { await fs.copyFile(sourcePath, destPath); } catch (_) {
|
let pdfBuf: Buffer;
|
||||||
|
try { pdfBuf = await fs.readFile(sourcePath); } catch (_) {
|
||||||
const fu = invoice!.fileUrl; if (!fu) throw new Error('PDF introuvable');
|
const fu = invoice!.fileUrl; if (!fu) throw new Error('PDF introuvable');
|
||||||
const au = fu.startsWith('/') ? `${process.env.APP_BASE_URL||`http://localhost:${process.env.PORT||3000}`}${fu}` : fu;
|
const au = fu.startsWith('/') ? `${process.env.APP_BASE_URL||`http://localhost:${process.env.PORT||3000}`}${fu}` : fu;
|
||||||
const rb = await fetch(au); if (!rb.ok) throw new Error(`HTTP ${rb.status}`);
|
const rb = await fetch(au); if (!rb.ok) throw new Error(`HTTP ${rb.status}`);
|
||||||
await fs.writeFile(destPath, Buffer.from(await rb.arrayBuffer()));
|
pdfBuf = Buffer.from(await rb.arrayBuffer());
|
||||||
|
}
|
||||||
|
if (isSharePoint) {
|
||||||
|
const { uploadToSharePoint } = await import('./sharepoint');
|
||||||
|
console.log(`[exportToPdf] Upload SharePoint sans signature: ${filename}`);
|
||||||
|
const spResult = await uploadToSharePoint(
|
||||||
|
{ tenantId: (settings as any)?.azureTenantId || '', clientId: (settings as any)?.azureClientId || '', clientSecret: (settings as any)?.azureClientSecret || '', sharepointUrl: exportFolder },
|
||||||
|
pdfBuf, filename
|
||||||
|
);
|
||||||
|
if (!spResult.success) throw new Error(`SharePoint: ${spResult.error}`);
|
||||||
|
console.log(`[exportToPdf] Upload SharePoint réussi: ${spResult.webUrl}`);
|
||||||
|
copiedFiles.push(spResult.webUrl || filename);
|
||||||
|
} else {
|
||||||
|
try { await fs.copyFile(sourcePath, destPath); } catch (_) { await fs.writeFile(destPath, pdfBuf); }
|
||||||
|
copiedFiles.push(destPath);
|
||||||
}
|
}
|
||||||
copiedFiles.push(destPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update export status
|
// Update export status
|
||||||
|
|||||||
Reference in New Issue
Block a user