diff --git a/paperless-backend/src/inbox/inbox.controller.ts b/paperless-backend/src/inbox/inbox.controller.ts index 2c51abb..cdacdcf 100644 --- a/paperless-backend/src/inbox/inbox.controller.ts +++ b/paperless-backend/src/inbox/inbox.controller.ts @@ -176,21 +176,18 @@ export class InboxController { await this.inboxService.updateSource(id, body.source, preferredUsername); } - @Post(':id/save-to-paperless') - @HttpCode(204) - async saveToPaperless( + @Get(':id/download') + async download( @Param('id') id: string, - @Body() body: { - title: string; - date?: string; - documentTypeId?: number; - correspondentId?: number; - tagIds?: number[]; - }, @Request() req: any, - ): Promise { + @Res({ passthrough: true }) res: Response, + ): Promise { const preferredUsername: string | null = req.user?.preferredUsername ?? null; - await this.inboxService.saveToPaperless(id, preferredUsername, body); + const { buffer, filename } = await this.inboxService.getEditedPdfBuffer(id, preferredUsername); + const { Readable } = await import('stream'); + res.setHeader('Content-Type', 'application/pdf'); + res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(filename)}"`); + return new StreamableFile(Readable.from(buffer)); } @Post(':id/send-email') diff --git a/paperless-backend/src/inbox/inbox.module.ts b/paperless-backend/src/inbox/inbox.module.ts index ed96b81..edbd62c 100644 --- a/paperless-backend/src/inbox/inbox.module.ts +++ b/paperless-backend/src/inbox/inbox.module.ts @@ -1,4 +1,4 @@ -import { Module, forwardRef } from '@nestjs/common'; +import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { Client } from '../database/entities/client.entity'; import { UserClient } from '../database/entities/user-client.entity'; @@ -9,7 +9,6 @@ import { InboxService } from './inbox.service'; import { InboxMigrationService } from './inbox-migration.service'; import { BarcodeModule } from '../barcode/barcode.module'; import { InboxPostprocessorModule } from '../inbox-postprocessor/inbox-postprocessor.module'; -import { PaperlessModule } from '../paperless/paperless.module'; import { PostprocessingModule } from '../postprocessing/postprocessing.module'; @Module({ @@ -17,7 +16,6 @@ import { PostprocessingModule } from '../postprocessing/postprocessing.module'; TypeOrmModule.forFeature([Client, UserClient, InboxDocument]), BarcodeModule, InboxPostprocessorModule, - forwardRef(() => PaperlessModule), PostprocessingModule, ], controllers: [InboxController, ClientsController], diff --git a/paperless-backend/src/inbox/inbox.service.ts b/paperless-backend/src/inbox/inbox.service.ts index 35b39b2..5c25c88 100644 --- a/paperless-backend/src/inbox/inbox.service.ts +++ b/paperless-backend/src/inbox/inbox.service.ts @@ -14,7 +14,6 @@ import { InboxDocument, type InboxSource, } from '../database/entities/inbox-document.entity'; -import { PaperlessService } from '../paperless/paperless.service'; import { MailService } from '../postprocessing/mail.service'; import { applyEditsToTemp, cleanupTemp } from '../inbox-postprocessor/edit-applier'; @@ -44,7 +43,6 @@ export class InboxService { private readonly pageCache: PageCacheService, @InjectRepository(InboxDocument) private readonly documentRepo: Repository, - private readonly paperlessService: PaperlessService, private readonly mailService: MailService, ) {} @@ -255,28 +253,16 @@ export class InboxService { return this.barcodeScanner.scanRegion(doc, pdfPath, page, x, y, w, h); } - async saveToPaperless( + async getEditedPdfBuffer( id: string, preferredUsername: string | null, - opts: { - title: string; - date?: string; - documentTypeId?: number; - correspondentId?: number; - tagIds?: number[]; - }, - ): Promise { + ): Promise<{ buffer: Buffer; filename: string }> { const { doc, pdfPath } = await this.resolveDocument(id, preferredUsername); let tmpPath: string | null = null; try { tmpPath = await applyEditsToTemp(doc, pdfPath); - await this.paperlessService.uploadDocument(tmpPath, { - title: opts.title, - created: opts.date, - documentType: opts.documentTypeId, - correspondent: opts.correspondentId, - tags: opts.tagIds, - }); + const buffer = await fs.readFile(tmpPath); + return { buffer, filename: doc.OriginalName }; } finally { await cleanupTemp(tmpPath); } diff --git a/paperless-frontend/src/api/inbox.ts b/paperless-frontend/src/api/inbox.ts index f338014..630f2ec 100644 --- a/paperless-frontend/src/api/inbox.ts +++ b/paperless-frontend/src/api/inbox.ts @@ -107,17 +107,8 @@ export const inboxApi = { ) .then((r) => r.data), - saveToPaperless: ( - id: string, - body: { - title: string; - date?: string; - documentTypeId?: number; - correspondentId?: number; - tagIds?: number[]; - }, - ) => - api.post(`/api/inbox/${encodeURIComponent(id)}/save-to-paperless`, body).then(() => {}), + downloadBlob: (id: string) => + api.get(`/api/inbox/${encodeURIComponent(id)}/download`, { responseType: 'blob' }).then((r) => r.data), sendEmail: ( id: string, diff --git a/paperless-frontend/src/pages/InboxDetailPage.tsx b/paperless-frontend/src/pages/InboxDetailPage.tsx index 8615ddc..ebd5aaf 100644 --- a/paperless-frontend/src/pages/InboxDetailPage.tsx +++ b/paperless-frontend/src/pages/InboxDetailPage.tsx @@ -1,6 +1,6 @@ import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; -import { Button, DatePicker, Dropdown, Empty, Form, Input, Modal, Popconfirm, Select, Space, Spin, Steps, Tag, Tooltip, Typography, message } from 'antd'; +import { Button, Dropdown, Empty, Form, Input, Modal, Popconfirm, Space, Spin, Steps, Tag, Tooltip, Typography, message } from 'antd'; import type { MenuProps } from 'antd'; import { ArrowLeftOutlined, @@ -25,7 +25,7 @@ import { useEditor, EditorContent } from '@tiptap/react'; import StarterKit from '@tiptap/starter-kit'; import Underline from '@tiptap/extension-underline'; import { inboxApi, type InboxBarcode, type InboxFile, type PostprocessActionResult } from '../api/inbox'; -import { paperlessApi, type PaperlessDocType, type PaperlessCorrespondent, type PaperlessTag } from '../api/paperless'; +import { paperlessApi } from '../api/paperless'; const ZOOM_MIN = 0.5; const ZOOM_MAX = 3; @@ -528,88 +528,6 @@ function PostprocessWizardModal({ ); } -interface SaveToPaperlessDialogProps { - open: boolean; - fileId: string; - defaultTitle: string; - onClose: () => void; -} - -function SaveToPaperlessDialog({ open, fileId, defaultTitle, onClose }: SaveToPaperlessDialogProps) { - const [form] = Form.useForm(); - const [submitting, setSubmitting] = useState(false); - const [docTypes, setDocTypes] = useState([]); - const [correspondents, setCorrespondents] = useState([]); - const [tags, setTags] = useState([]); - - useEffect(() => { - if (!open) return; - form.resetFields(); - form.setFieldsValue({ title: defaultTitle }); - Promise.all([ - paperlessApi.getDocumentTypes(), - paperlessApi.getCorrespondents(), - paperlessApi.getTags(), - ]).then(([dt, co, tg]) => { - setDocTypes(dt); - setCorrespondents(co); - setTags(tg); - }).catch(() => {}); - }, [open, defaultTitle, form]); - - const handleOk = async () => { - try { - const values = await form.validateFields(); - setSubmitting(true); - await inboxApi.saveToPaperless(fileId, { - title: values.title, - date: values.date ? values.date.format('YYYY-MM-DD') : undefined, - documentTypeId: values.documentTypeId, - correspondentId: values.correspondentId, - tagIds: values.tagIds, - }); - message.success('Dokument wurde an Paperless übertragen'); - onClose(); - } catch (err: any) { - if (err?.errorFields) return; - message.error('Übertragung fehlgeschlagen'); - } finally { - setSubmitting(false); - } - }; - - return ( - -
- - - - - - - - ({ value: c.id, label: c.name }))} /> - - -