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.BigDecimalField;
|
||||||
import com.vaadin.flow.component.textfield.EmailField;
|
import com.vaadin.flow.component.textfield.EmailField;
|
||||||
import com.vaadin.flow.component.textfield.TextField;
|
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.data.renderer.ComponentRenderer;
|
||||||
import com.vaadin.flow.router.PageTitle;
|
import com.vaadin.flow.router.PageTitle;
|
||||||
import com.vaadin.flow.router.Route;
|
import com.vaadin.flow.router.Route;
|
||||||
@@ -47,8 +45,6 @@ import de.assecutor.pdftool.zugferd.ZugferdResult;
|
|||||||
import de.assecutor.pdftool.zugferd.ZugferdService;
|
import de.assecutor.pdftool.zugferd.ZugferdService;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.UncheckedIOException;
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
@@ -72,10 +68,7 @@ public class MainView extends VerticalLayout {
|
|||||||
private final InvoiceTemplateService invoiceTemplateService;
|
private final InvoiceTemplateService invoiceTemplateService;
|
||||||
private final TemplatePdfService templatePdfService;
|
private final TemplatePdfService templatePdfService;
|
||||||
|
|
||||||
private final MemoryBuffer uploadBuffer = new MemoryBuffer();
|
/** Grundlage der Rechnung: ein gespeichertes Rechnungstemplate. */
|
||||||
private byte[] uploadedPdf;
|
|
||||||
|
|
||||||
/** Alternative zum PDF-Upload: ein gespeichertes Rechnungstemplate. */
|
|
||||||
private final ComboBox<String> templateSelect = new ComboBox<>("Rechnungstemplate");
|
private final ComboBox<String> templateSelect = new ComboBox<>("Rechnungstemplate");
|
||||||
|
|
||||||
/** Vorbelegung der Rechnungssteller-Felder aus dem Adressbuch. */
|
/** Vorbelegung der Rechnungssteller-Felder aus dem Adressbuch. */
|
||||||
@@ -119,8 +112,8 @@ public class MainView extends VerticalLayout {
|
|||||||
private final Anchor downloadLink = new Anchor();
|
private final Anchor downloadLink = new Anchor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alle Controls unterhalb der Quellenwahl; sie sind erst aktiv, wenn ein PDF
|
* Alle Controls unterhalb der Template-Auswahl; sie sind erst aktiv, wenn
|
||||||
* hochgeladen oder ein Template ausgewählt wurde.
|
* ein Template ausgewählt wurde.
|
||||||
*/
|
*/
|
||||||
private final List<com.vaadin.flow.component.HasEnabled> sourceDependentControls = new ArrayList<>();
|
private final List<com.vaadin.flow.component.HasEnabled> sourceDependentControls = new ArrayList<>();
|
||||||
|
|
||||||
@@ -136,10 +129,9 @@ public class MainView extends VerticalLayout {
|
|||||||
|
|
||||||
setMaxWidth("960px");
|
setMaxWidth("960px");
|
||||||
|
|
||||||
add(new Paragraph("Laden Sie ein Rechnungs-PDF hoch oder wählen Sie ein gespeichertes "
|
add(new Paragraph("Wählen Sie ein gespeichertes Rechnungstemplate und ergänzen Sie die "
|
||||||
+ "Rechnungstemplate und ergänzen Sie die Rechnungsdaten. Die Rechnung wird als "
|
+ "Rechnungsdaten. Die Rechnung wird als rechtskonforme ZUGFeRD-Rechnung "
|
||||||
+ "rechtskonforme ZUGFeRD-Rechnung (PDF/A-3 mit eingebettetem EN16931-XML) erzeugt "
|
+ "(PDF/A-3 mit eingebettetem EN16931-XML) erzeugt und als ZIP-Datei bereitgestellt."));
|
||||||
+ "und als ZIP-Datei bereitgestellt."));
|
|
||||||
|
|
||||||
// Eingaben unter einem Namen speichern bzw. gespeicherte Eingaben laden.
|
// Eingaben unter einem Namen speichern bzw. gespeicherte Eingaben laden.
|
||||||
draftSelect.setPlaceholder("Vorbelegung laden");
|
draftSelect.setPlaceholder("Vorbelegung laden");
|
||||||
@@ -174,34 +166,12 @@ public class MainView extends VerticalLayout {
|
|||||||
});
|
});
|
||||||
add(draftSelect);
|
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.setItems(invoiceTemplateService.templateNames());
|
||||||
templateSelect.setPlaceholder("Template auswählen");
|
templateSelect.setPlaceholder("Template auswählen");
|
||||||
templateSelect.setClearButtonVisible(true);
|
templateSelect.setClearButtonVisible(true);
|
||||||
templateSelect.setWidth("300px");
|
templateSelect.setWidth("300px");
|
||||||
templateSelect.addValueChangeListener(event -> {
|
templateSelect.addValueChangeListener(event -> {
|
||||||
if (event.isFromClient() && event.getValue() != null) {
|
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
|
// Rechnungssteller-Felder nur bei der ersten Template-Auswahl
|
||||||
// leer beginnen lassen; beim Wechsel zwischen Templates bleiben
|
// leer beginnen lassen; beim Wechsel zwischen Templates bleiben
|
||||||
// die Eingaben erhalten (sonst wäre u. a. der Speichern-Button
|
// die Eingaben erhalten (sonst wäre u. a. der Speichern-Button
|
||||||
@@ -213,12 +183,7 @@ public class MainView extends VerticalLayout {
|
|||||||
}
|
}
|
||||||
updateControlsEnabled();
|
updateControlsEnabled();
|
||||||
});
|
});
|
||||||
HorizontalLayout sourceLayout = new HorizontalLayout(upload, templateSelect);
|
add(new H3("1. Template auswählen"), 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);
|
|
||||||
|
|
||||||
invoiceNumber.setRequired(true);
|
invoiceNumber.setRequired(true);
|
||||||
invoiceNumber.setErrorMessage("Rechnungsnummer ist ein Pflichtfeld.");
|
invoiceNumber.setErrorMessage("Rechnungsnummer ist ein Pflichtfeld.");
|
||||||
@@ -368,7 +333,7 @@ public class MainView extends VerticalLayout {
|
|||||||
.addThemeVariants(NotificationVariant.LUMO_SUCCESS);
|
.addThemeVariants(NotificationVariant.LUMO_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sammelt den aktuellen Formularstand; ein hochgeladenes PDF wird nicht mitgespeichert. */
|
/** Sammelt den aktuellen Formularstand. */
|
||||||
private InvoiceDraft buildDraft(String name) {
|
private InvoiceDraft buildDraft(String name) {
|
||||||
return new InvoiceDraft(null, name,
|
return new InvoiceDraft(null, name,
|
||||||
templateSelect.getValue(),
|
templateSelect.getValue(),
|
||||||
@@ -398,8 +363,7 @@ public class MainView extends VerticalLayout {
|
|||||||
|
|
||||||
/** Überträgt gespeicherte Eingaben in das Formular. */
|
/** Überträgt gespeicherte Eingaben in das Formular. */
|
||||||
private void applyDraft(InvoiceDraft draft) {
|
private void applyDraft(InvoiceDraft draft) {
|
||||||
// Die Template-Auswahl wiederherstellen, sofern das Template noch existiert;
|
// Die Template-Auswahl wiederherstellen, sofern das Template noch existiert.
|
||||||
// ein hochgeladenes PDF ist nicht Teil der gespeicherten Eingaben.
|
|
||||||
if (draft.templateName() != null && !draft.templateName().isBlank()
|
if (draft.templateName() != null && !draft.templateName().isBlank()
|
||||||
&& invoiceTemplateService.templateExists(draft.templateName())) {
|
&& invoiceTemplateService.templateExists(draft.templateName())) {
|
||||||
templateSelect.setValue(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
|
* 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() {
|
private void updateControlsEnabled() {
|
||||||
boolean sourceSelected = uploadedPdf != null || templateSelect.getValue() != null;
|
boolean sourceSelected = templateSelect.getValue() != null;
|
||||||
sourceDependentControls.forEach(control -> control.setEnabled(sourceSelected));
|
sourceDependentControls.forEach(control -> control.setEnabled(sourceSelected));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,10 +602,6 @@ public class MainView extends VerticalLayout {
|
|||||||
showErrors(errors);
|
showErrors(errors);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (uploadedPdf != null) {
|
|
||||||
convertAndOfferDownload(uploadedPdf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String templateName = templateSelect.getValue();
|
String templateName = templateSelect.getValue();
|
||||||
Optional<String> templateData = invoiceTemplateService.loadTemplate(templateName);
|
Optional<String> templateData = invoiceTemplateService.loadTemplate(templateName);
|
||||||
if (templateData.isEmpty()) {
|
if (templateData.isEmpty()) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
"noUnusedParameters": false,
|
"noUnusedParameters": false,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"useDefineForClassFields": false,
|
"useDefineForClassFields": false,
|
||||||
|
"ignoreDeprecations": "6.0",
|
||||||
"baseUrl": "src/main/frontend",
|
"baseUrl": "src/main/frontend",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@vaadin/flow-frontend": ["generated/jar-resources"],
|
"@vaadin/flow-frontend": ["generated/jar-resources"],
|
||||||
|
|||||||
Reference in New Issue
Block a user