Files
paperlessmanager/paperless-frontend/src/api/email-import.ts
T
bjoernpoettkerandClaude Opus 5.5 534b313054
Build and Push Multi-Platform Images / build-and-push (push) Successful in 39s
fix(mail): Duplikate auch bei gerade laufenden Importen erkennen
Wurde dieselbe Mail zweimal weitergeleitet, erkannte der Import-Assistent
das Duplikat nicht, solange Paperless das erste Dokument noch verarbeitete –
geprüft wurde nur die Checksumme in Paperless.

- checkDuplicate() berücksichtigt zusätzlich offene Paperless-Tasks von
  Anhängen mit gleicher Checksumme (gleicher Seitenbereich)
- Assistent prüft erneut vor dem Abrufen der Belegnummern und vor dem
  Import; Duplikate werden ignoriert, reservierte Nummern freigegeben
- executeImport prüft serverseitig vor Upload und Festlegen der Nummer,
  sperrt laufende Importe gegen parallele Doppelimporte und meldet 409

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 10:29:43 +02:00

89 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import api from './client';
export interface CorrespondentMapping {
Id: number;
EmailAddress: string;
PaperlessCorrespondentId: number;
}
export interface AttachmentImportData {
attachmentId: number;
virtualId: string;
fileName: string;
pages?: { start: number; end: number };
type: 'MAIN' | 'ATTACHMENT' | 'IGNORE';
paperlessCorrespondentId?: number | null;
parentDocumentId?: number | null;
parentVirtualId?: string | null;
splitRanges?: { start: number; end: number }[];
barcode?: { x: number; y: number; nummer: string; datum: string; jahr: string };
belegnummer?: string;
isDuplicate?: boolean;
}
export const emailImportApi = {
getMappings: async (): Promise<CorrespondentMapping[]> => {
const res = await api.get('/api/email-import/mappings');
return res.data;
},
addMapping: async (emailAddress: string, paperlessCorrespondentId: number): Promise<CorrespondentMapping> => {
const res = await api.post('/api/email-import/mappings', { emailAddress, paperlessCorrespondentId });
return res.data;
},
deleteMapping: async (id: number): Promise<void> => {
await api.delete(`/api/email-import/mappings/${id}`);
},
getCorrespondentByEmail: async (emailAddress: string): Promise<{ paperlessCorrespondentId: number | null }> => {
const res = await api.get('/api/email-import/correspondent', { params: { email: emailAddress } });
return res.data;
},
getBelegnummer: async (dateStr: string): Promise<{ nummer: string }> => {
const res = await api.get('/api/email-import/belegnummer', { params: { date: dateStr } });
return res.data;
},
releaseBelegnummer: async (dateStr: string, number: string): Promise<void> => {
await api.post('/api/email-import/belegnummer/release', { date: dateStr, number });
},
printPreview: async (attachmentId: number, barcodeData: any, pages?: { start: number; end: number }): Promise<Blob> => {
const res = await api.post(`/api/email-import/attachments/${attachmentId}/print-preview`, { ...barcodeData, _pages: pages }, {
responseType: 'blob',
});
return res.data;
},
// Prüft auf Duplikate – in Paperless und bei Importen, die dort noch verarbeitet werden.
checkDuplicate: async (attachmentId: number): Promise<boolean> => {
const res = await api.post<{ isDuplicate: boolean }>(`/api/email-import/attachments/${attachmentId}/check-duplicate`);
return res.data.isDuplicate;
},
checkSplitChecksum: async (attachmentId: number, pages: { start: number; end: number }): Promise<boolean> => {
const res = await api.post<{ isDuplicate: boolean }>(`/api/email-import/attachments/${attachmentId}/check-split-checksum`, { pages });
return res.data.isDuplicate;
},
executeImport: async (emailDate: string, attachments: AttachmentImportData[], jobId?: string): Promise<{ success: boolean; results: any[] }> => {
const res = await api.post('/api/email-import/execute', { emailDate, attachments, jobId }, { timeout: 300_000 });
return res.data;
},
getJobStatus: async (jobId: string): Promise<{ message: string; done: boolean } | null> => {
try {
const res = await api.get(`/api/email-import/jobs/${jobId}/status`);
return res.data;
} catch {
return null;
}
},
ensurePreviews: async (emailId: number): Promise<void> => {
await api.post(`/api/email-import/emails/${emailId}/ensure-previews`);
},
};