feat: intégration Microsoft Graph pour export SharePoint - helper uploadToSharePoint, champs Azure AD en DB et UI
This commit is contained in:
@@ -470,6 +470,7 @@ export const appRouter = router({
|
||||
const importSettings = await getImportSettingsByUser(ctx.user.id);
|
||||
const bapExportMode = importSettings?.bapExportMode || 'browser';
|
||||
const exportFolder = importSettings?.exportFolder || null;
|
||||
const exportFolderType = (importSettings as any)?.exportFolderType || 'local';
|
||||
const STORAGE_BASE_PATH = process.env.STORAGE_BASE_PATH || path.join(process.cwd(), 'storage');
|
||||
|
||||
let pdfUrl: string | null = null;
|
||||
@@ -550,12 +551,37 @@ export const appRouter = router({
|
||||
const filename = path.basename(invoice.fileKey);
|
||||
const bapFilename = `BAP_${Date.now()}_${filename}`;
|
||||
|
||||
if (bapExportMode === 'folder' && exportFolder) {
|
||||
// Mode dossier : enregistrer sur le disque
|
||||
await fs.mkdir(exportFolder, { recursive: true });
|
||||
exportPath = path.join(exportFolder, bapFilename);
|
||||
await fs.writeFile(exportPath, signedPdfBytes);
|
||||
} else {
|
||||
if ((bapExportMode === 'folder' || bapExportMode === 'both') && exportFolder) {
|
||||
if (exportFolderType === 'sharepoint') {
|
||||
// Mode SharePoint : upload via Microsoft Graph
|
||||
const { uploadToSharePoint } = await import('./sharepoint');
|
||||
const spResult = await uploadToSharePoint(
|
||||
{
|
||||
tenantId: (importSettings as any)?.azureTenantId || '',
|
||||
clientId: (importSettings as any)?.azureClientId || '',
|
||||
clientSecret: (importSettings as any)?.azureClientSecret || '',
|
||||
sharepointUrl: exportFolder,
|
||||
},
|
||||
Buffer.from(signedPdfBytes),
|
||||
bapFilename
|
||||
);
|
||||
if (spResult.success) {
|
||||
exportPath = spResult.webUrl || exportFolder;
|
||||
} else {
|
||||
console.warn('[BAP] Erreur upload SharePoint:', spResult.error);
|
||||
// Fallback : stocker localement
|
||||
const bapKey = generateStorageKey(ctx.user.id, bapFilename);
|
||||
const { url } = await localStoragePut(bapKey, Buffer.from(signedPdfBytes), 'application/pdf');
|
||||
pdfUrl = url;
|
||||
}
|
||||
} else {
|
||||
// Mode dossier local : enregistrer sur le disque
|
||||
await fs.mkdir(exportFolder, { recursive: true });
|
||||
exportPath = path.join(exportFolder, bapFilename);
|
||||
await fs.writeFile(exportPath, signedPdfBytes);
|
||||
}
|
||||
}
|
||||
if (bapExportMode === 'browser' || bapExportMode === 'both' || !exportFolder) {
|
||||
// Mode navigateur : stocker localement et retourner l'URL relative
|
||||
const bapKey = generateStorageKey(ctx.user.id, bapFilename);
|
||||
const { url } = await localStoragePut(bapKey, Buffer.from(signedPdfBytes), 'application/pdf');
|
||||
@@ -625,6 +651,7 @@ export const appRouter = router({
|
||||
const importSettings = await getImportSettingsByUser(ctx.user.id);
|
||||
const bapExportMode = importSettings?.bapExportMode || 'browser';
|
||||
const exportFolder = importSettings?.exportFolder || null;
|
||||
const exportFolderType = (importSettings as any)?.exportFolderType || 'local';
|
||||
const STORAGE_BASE_PATH = process.env.STORAGE_BASE_PATH || path.join(process.cwd(), 'storage');
|
||||
const serviceSignaturesList = await getServiceSignaturesByUser(ctx.user.id);
|
||||
const results: Array<{ id: number; success: boolean; pdfUrl?: string | null; exportPath?: string | null; error?: string }> = [];
|
||||
@@ -702,11 +729,34 @@ export const appRouter = router({
|
||||
const signedPdfBytes = await pdfDoc.save();
|
||||
const filename = path.basename(invoice.fileKey);
|
||||
const bapFilename = `BAP_${Date.now()}_${filename}`;
|
||||
if (bapExportMode === 'folder' && exportFolder) {
|
||||
await fs.mkdir(exportFolder, { recursive: true });
|
||||
exportPath = path.join(exportFolder, bapFilename);
|
||||
await fs.writeFile(exportPath, signedPdfBytes);
|
||||
} else {
|
||||
if ((bapExportMode === 'folder' || bapExportMode === 'both') && exportFolder) {
|
||||
if (exportFolderType === 'sharepoint') {
|
||||
const { uploadToSharePoint } = await import('./sharepoint');
|
||||
const spResult = await uploadToSharePoint(
|
||||
{
|
||||
tenantId: (importSettings as any)?.azureTenantId || '',
|
||||
clientId: (importSettings as any)?.azureClientId || '',
|
||||
clientSecret: (importSettings as any)?.azureClientSecret || '',
|
||||
sharepointUrl: exportFolder,
|
||||
},
|
||||
Buffer.from(signedPdfBytes),
|
||||
bapFilename
|
||||
);
|
||||
if (spResult.success) {
|
||||
exportPath = spResult.webUrl || exportFolder;
|
||||
} else {
|
||||
console.warn('[BAP Bulk] Erreur upload SharePoint:', spResult.error);
|
||||
const bapKey = generateStorageKey(ctx.user.id, bapFilename);
|
||||
const { url } = await localStoragePut(bapKey, Buffer.from(signedPdfBytes), 'application/pdf');
|
||||
pdfUrl = url;
|
||||
}
|
||||
} else {
|
||||
await fs.mkdir(exportFolder, { recursive: true });
|
||||
exportPath = path.join(exportFolder, bapFilename);
|
||||
await fs.writeFile(exportPath, signedPdfBytes);
|
||||
}
|
||||
}
|
||||
if (bapExportMode === 'browser' || bapExportMode === 'both' || !exportFolder) {
|
||||
const bapKey = generateStorageKey(ctx.user.id, bapFilename);
|
||||
const { url } = await localStoragePut(bapKey, Buffer.from(signedPdfBytes), 'application/pdf');
|
||||
pdfUrl = url;
|
||||
@@ -1410,7 +1460,11 @@ export const appRouter = router({
|
||||
emailImportPort: 993,
|
||||
emailImportFrequency: 30,
|
||||
exportFolder: null,
|
||||
exportFolderType: "local" as const,
|
||||
bapExportMode: "browser" as const,
|
||||
azureTenantId: null,
|
||||
azureClientId: null,
|
||||
azureClientSecret: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1430,7 +1484,11 @@ export const appRouter = router({
|
||||
emailImportPort: z.number().min(1).max(65535).optional(),
|
||||
emailImportFrequency: z.number().min(1).optional(),
|
||||
exportFolder: z.string().nullable().optional(),
|
||||
exportFolderType: z.enum(["local", "teams", "sharepoint"]).optional(),
|
||||
bapExportMode: z.enum(["browser", "folder", "both"]).optional(),
|
||||
azureTenantId: z.string().nullable().optional(),
|
||||
azureClientId: z.string().nullable().optional(),
|
||||
azureClientSecret: z.string().nullable().optional(),
|
||||
}))
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const settings = await upsertImportSettings({
|
||||
|
||||
Reference in New Issue
Block a user