PDF-Upload aus der Rechnungsmaske entfernt; Rechnungen entstehen in der UI nur noch aus Templates
Die REST-API (/api/invoices/sign, /validate) nimmt unverändert PDFs entgegen und bietet weiterhin keinen Template-Zugriff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -23,8 +23,6 @@ import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||
import com.vaadin.flow.component.textfield.BigDecimalField;
|
||||
import com.vaadin.flow.component.textfield.EmailField;
|
||||
import com.vaadin.flow.component.textfield.TextField;
|
||||
import com.vaadin.flow.component.upload.Upload;
|
||||
import com.vaadin.flow.component.upload.receivers.MemoryBuffer;
|
||||
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
||||
import com.vaadin.flow.router.PageTitle;
|
||||
import com.vaadin.flow.router.Route;
|
||||
@@ -47,8 +45,6 @@ import de.assecutor.pdftool.zugferd.ZugferdResult;
|
||||
import de.assecutor.pdftool.zugferd.ZugferdService;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.NumberFormat;
|
||||
import java.time.LocalDate;
|
||||
@@ -72,10 +68,7 @@ public class MainView extends VerticalLayout {
|
||||
private final InvoiceTemplateService invoiceTemplateService;
|
||||
private final TemplatePdfService templatePdfService;
|
||||
|
||||
private final MemoryBuffer uploadBuffer = new MemoryBuffer();
|
||||
private byte[] uploadedPdf;
|
||||
|
||||
/** Alternative zum PDF-Upload: ein gespeichertes Rechnungstemplate. */
|
||||
/** Grundlage der Rechnung: ein gespeichertes Rechnungstemplate. */
|
||||
private final ComboBox<String> templateSelect = new ComboBox<>("Rechnungstemplate");
|
||||
|
||||
/** Vorbelegung der Rechnungssteller-Felder aus dem Adressbuch. */
|
||||
@@ -119,8 +112,8 @@ public class MainView extends VerticalLayout {
|
||||
private final Anchor downloadLink = new Anchor();
|
||||
|
||||
/**
|
||||
* Alle Controls unterhalb der Quellenwahl; sie sind erst aktiv, wenn ein PDF
|
||||
* hochgeladen oder ein Template ausgewählt wurde.
|
||||
* Alle Controls unterhalb der Template-Auswahl; sie sind erst aktiv, wenn
|
||||
* ein Template ausgewählt wurde.
|
||||
*/
|
||||
private final List<com.vaadin.flow.component.HasEnabled> sourceDependentControls = new ArrayList<>();
|
||||
|
||||
@@ -136,10 +129,9 @@ public class MainView extends VerticalLayout {
|
||||
|
||||
setMaxWidth("960px");
|
||||
|
||||
add(new Paragraph("Laden Sie ein Rechnungs-PDF hoch oder wählen Sie ein gespeichertes "
|
||||
+ "Rechnungstemplate und ergänzen Sie die Rechnungsdaten. Die Rechnung wird als "
|
||||
+ "rechtskonforme ZUGFeRD-Rechnung (PDF/A-3 mit eingebettetem EN16931-XML) erzeugt "
|
||||
+ "und als ZIP-Datei bereitgestellt."));
|
||||
add(new Paragraph("Wählen Sie ein gespeichertes Rechnungstemplate und ergänzen Sie die "
|
||||
+ "Rechnungsdaten. Die Rechnung wird als rechtskonforme ZUGFeRD-Rechnung "
|
||||
+ "(PDF/A-3 mit eingebettetem EN16931-XML) erzeugt und als ZIP-Datei bereitgestellt."));
|
||||
|
||||
// Eingaben unter einem Namen speichern bzw. gespeicherte Eingaben laden.
|
||||
draftSelect.setPlaceholder("Vorbelegung laden");
|
||||
@@ -174,34 +166,12 @@ public class MainView extends VerticalLayout {
|
||||
});
|
||||
add(draftSelect);
|
||||
|
||||
Upload upload = new Upload(uploadBuffer);
|
||||
upload.setAcceptedFileTypes("application/pdf", ".pdf");
|
||||
upload.setMaxFiles(1);
|
||||
upload.setMaxFileSize(25 * 1024 * 1024);
|
||||
upload.addSucceededListener(event -> {
|
||||
try {
|
||||
uploadedPdf = uploadBuffer.getInputStream().readAllBytes();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
// Entweder PDF oder Template: hochgeladenes PDF hebt die Template-Auswahl auf.
|
||||
templateSelect.clear();
|
||||
updateControlsEnabled();
|
||||
});
|
||||
upload.addFileRemovedListener(event -> {
|
||||
uploadedPdf = null;
|
||||
updateControlsEnabled();
|
||||
});
|
||||
|
||||
templateSelect.setItems(invoiceTemplateService.templateNames());
|
||||
templateSelect.setPlaceholder("Template auswählen");
|
||||
templateSelect.setClearButtonVisible(true);
|
||||
templateSelect.setWidth("300px");
|
||||
templateSelect.addValueChangeListener(event -> {
|
||||
if (event.isFromClient() && event.getValue() != null) {
|
||||
// Entweder PDF oder Template: Auswahl entfernt ein hochgeladenes PDF.
|
||||
upload.clearFileList();
|
||||
uploadedPdf = null;
|
||||
// Rechnungssteller-Felder nur bei der ersten Template-Auswahl
|
||||
// leer beginnen lassen; beim Wechsel zwischen Templates bleiben
|
||||
// die Eingaben erhalten (sonst wäre u. a. der Speichern-Button
|
||||
@@ -213,12 +183,7 @@ public class MainView extends VerticalLayout {
|
||||
}
|
||||
updateControlsEnabled();
|
||||
});
|
||||
HorizontalLayout sourceLayout = new HorizontalLayout(upload, templateSelect);
|
||||
sourceLayout.setAlignItems(Alignment.CENTER);
|
||||
// Das Label der ComboBox ausgleichen, damit das Eingabefeld selbst
|
||||
// mittig zur Upload-Fläche steht.
|
||||
templateSelect.getStyle().set("margin-top", "-1.25em");
|
||||
add(new H3("1. Rechnungs-PDF hochladen oder Template auswählen"), sourceLayout);
|
||||
add(new H3("1. Template auswählen"), templateSelect);
|
||||
|
||||
invoiceNumber.setRequired(true);
|
||||
invoiceNumber.setErrorMessage("Rechnungsnummer ist ein Pflichtfeld.");
|
||||
@@ -368,7 +333,7 @@ public class MainView extends VerticalLayout {
|
||||
.addThemeVariants(NotificationVariant.LUMO_SUCCESS);
|
||||
}
|
||||
|
||||
/** Sammelt den aktuellen Formularstand; ein hochgeladenes PDF wird nicht mitgespeichert. */
|
||||
/** Sammelt den aktuellen Formularstand. */
|
||||
private InvoiceDraft buildDraft(String name) {
|
||||
return new InvoiceDraft(null, name,
|
||||
templateSelect.getValue(),
|
||||
@@ -398,8 +363,7 @@ public class MainView extends VerticalLayout {
|
||||
|
||||
/** Überträgt gespeicherte Eingaben in das Formular. */
|
||||
private void applyDraft(InvoiceDraft draft) {
|
||||
// Die Template-Auswahl wiederherstellen, sofern das Template noch existiert;
|
||||
// ein hochgeladenes PDF ist nicht Teil der gespeicherten Eingaben.
|
||||
// Die Template-Auswahl wiederherstellen, sofern das Template noch existiert.
|
||||
if (draft.templateName() != null && !draft.templateName().isBlank()
|
||||
&& invoiceTemplateService.templateExists(draft.templateName())) {
|
||||
templateSelect.setValue(draft.templateName());
|
||||
@@ -625,10 +589,10 @@ public class MainView extends VerticalLayout {
|
||||
|
||||
/**
|
||||
* Das Rechnungsformular und der Erzeugen-Button sind nur aktiv, wenn ein
|
||||
* PDF hochgeladen oder ein Template ausgewählt wurde.
|
||||
* Template ausgewählt wurde.
|
||||
*/
|
||||
private void updateControlsEnabled() {
|
||||
boolean sourceSelected = uploadedPdf != null || templateSelect.getValue() != null;
|
||||
boolean sourceSelected = templateSelect.getValue() != null;
|
||||
sourceDependentControls.forEach(control -> control.setEnabled(sourceSelected));
|
||||
}
|
||||
|
||||
@@ -638,10 +602,6 @@ public class MainView extends VerticalLayout {
|
||||
showErrors(errors);
|
||||
return;
|
||||
}
|
||||
if (uploadedPdf != null) {
|
||||
convertAndOfferDownload(uploadedPdf);
|
||||
return;
|
||||
}
|
||||
String templateName = templateSelect.getValue();
|
||||
Optional<String> templateData = invoiceTemplateService.loadTemplate(templateName);
|
||||
if (templateData.isEmpty()) {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"noUnusedParameters": false,
|
||||
"experimentalDecorators": true,
|
||||
"useDefineForClassFields": false,
|
||||
"ignoreDeprecations": "6.0",
|
||||
"baseUrl": "src/main/frontend",
|
||||
"paths": {
|
||||
"@vaadin/flow-frontend": ["generated/jar-resources"],
|
||||
|
||||
Reference in New Issue
Block a user