Erweiterungen
This commit is contained in:
@@ -9,11 +9,16 @@ import com.vaadin.flow.router.PageTitle;
|
|||||||
import com.vaadin.flow.router.Route;
|
import com.vaadin.flow.router.Route;
|
||||||
import com.vaadin.flow.component.UI;
|
import com.vaadin.flow.component.UI;
|
||||||
import de.assecutor.votianlt.model.invoices.SystemInvoice;
|
import de.assecutor.votianlt.model.invoices.SystemInvoice;
|
||||||
|
import de.assecutor.votianlt.model.invoices.CustomerInvoiceData;
|
||||||
|
import de.assecutor.votianlt.model.invoices.CustomerInvoiceItem;
|
||||||
|
import de.assecutor.votianlt.security.SecurityService;
|
||||||
|
import de.assecutor.votianlt.service.CustomerInvoiceService;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.vaadin.flow.server.StreamResource;
|
import com.vaadin.flow.server.StreamResource;
|
||||||
@@ -24,10 +29,15 @@ import com.vaadin.flow.server.StreamRegistration;
|
|||||||
@RolesAllowed({ "USER", "ADMIN" })
|
@RolesAllowed({ "USER", "ADMIN" })
|
||||||
public class InvoicesView extends VerticalLayout {
|
public class InvoicesView extends VerticalLayout {
|
||||||
|
|
||||||
|
|
||||||
private final Grid<SystemInvoice> invoiceGrid;
|
private final Grid<SystemInvoice> invoiceGrid;
|
||||||
|
|
||||||
public InvoicesView() {
|
private final CustomerInvoiceService customerInvoiceService;
|
||||||
|
private final SecurityService securityService;
|
||||||
|
|
||||||
|
public InvoicesView(CustomerInvoiceService customerInvoiceService, SecurityService securityService) {
|
||||||
|
this.customerInvoiceService = customerInvoiceService;
|
||||||
|
this.securityService = securityService;
|
||||||
|
|
||||||
setSizeFull();
|
setSizeFull();
|
||||||
setPadding(true);
|
setPadding(true);
|
||||||
setSpacing(true);
|
setSpacing(true);
|
||||||
@@ -67,8 +77,8 @@ public class InvoicesView extends VerticalLayout {
|
|||||||
|
|
||||||
private void downloadInvoicePdf(SystemInvoice systemInvoice) {
|
private void downloadInvoicePdf(SystemInvoice systemInvoice) {
|
||||||
try {
|
try {
|
||||||
// PDF generieren
|
// PDF generieren mit CustomerInvoice (HTML Template)
|
||||||
byte[] pdfBytes = generatePdf(systemInvoice);
|
byte[] pdfBytes = generateCustomerInvoicePdf(systemInvoice);
|
||||||
StreamResource resource = new StreamResource(systemInvoice.getId() + ".pdf",
|
StreamResource resource = new StreamResource(systemInvoice.getId() + ".pdf",
|
||||||
() -> new ByteArrayInputStream(pdfBytes));
|
() -> new ByteArrayInputStream(pdfBytes));
|
||||||
resource.setContentType("application/pdf");
|
resource.setContentType("application/pdf");
|
||||||
@@ -84,21 +94,72 @@ public class InvoicesView extends VerticalLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] generatePdf(SystemInvoice systemInvoice) {
|
private byte[] generateCustomerInvoicePdf(SystemInvoice systemInvoice) throws Exception {
|
||||||
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
// Aktuellen Benutzer als Rechnungssteller ermitteln
|
||||||
// Einfache PDF mit iText (oder OpenPDF, falls iText nicht verfügbar)
|
de.assecutor.votianlt.model.User user = securityService.getCurrentDatabaseUser();
|
||||||
com.lowagie.text.Document document = new com.lowagie.text.Document();
|
|
||||||
com.lowagie.text.pdf.PdfWriter.getInstance(document, out);
|
CustomerInvoiceData data = new CustomerInvoiceData();
|
||||||
document.open();
|
// Kopf
|
||||||
document.add(new com.lowagie.text.Paragraph("Rechnung: " + systemInvoice.getId()));
|
data.setInvoiceNumber(systemInvoice.getId());
|
||||||
document.add(new com.lowagie.text.Paragraph("Kunde: " + systemInvoice.getKunde()));
|
data.setInvoiceDate(systemInvoice.getDatum());
|
||||||
document.add(new com.lowagie.text.Paragraph("Datum: " + systemInvoice.getDatum()));
|
data.setDeliveryDate(systemInvoice.getDatum());
|
||||||
document.add(new com.lowagie.text.Paragraph("Betrag: " + systemInvoice.getBetrag() + " EUR"));
|
data.setDescription(systemInvoice.getBeschreibung());
|
||||||
document.add(new com.lowagie.text.Paragraph("Beschreibung: " + systemInvoice.getBeschreibung()));
|
|
||||||
document.close();
|
// Rechnungssteller = eingeloggter Benutzer
|
||||||
return out.toByteArray();
|
String senderName = (nullToEmpty(user.getFirstname()) + " " + nullToEmpty(user.getName())).trim();
|
||||||
} catch (Exception e) {
|
if (senderName.isBlank() && user.getEmail() != null)
|
||||||
throw new RuntimeException("PDF-Generierung fehlgeschlagen: " + e.getMessage(), e);
|
senderName = user.getEmail();
|
||||||
|
data.setSenderName(user.getCompany() != null && !user.getCompany().isBlank() ? user.getCompany() : senderName);
|
||||||
|
data.setSenderAddress((nullToEmpty(user.getStreet()) + " " + nullToEmpty(user.getHouseNumber())).trim());
|
||||||
|
data.setSenderPostcode(nullToEmpty(user.getZip()));
|
||||||
|
data.setSenderCity(nullToEmpty(user.getCity()));
|
||||||
|
data.setSenderCountry("Deutschland");
|
||||||
|
data.setSenderTaxNumber("");
|
||||||
|
data.setSenderVatId("");
|
||||||
|
data.setSenderPhone(nullToEmpty(user.getPhone()));
|
||||||
|
data.setSenderEmail(nullToEmpty(user.getEmail()));
|
||||||
|
data.setSenderWebsite("");
|
||||||
|
|
||||||
|
// Empfänger = Kunde aus der Zeile (nur Name vorhanden in Testdaten)
|
||||||
|
data.setRecipientCompany("");
|
||||||
|
data.setRecipientName(systemInvoice.getKunde());
|
||||||
|
data.setRecipientAddress("");
|
||||||
|
data.setRecipientPostcode("");
|
||||||
|
data.setRecipientCity("");
|
||||||
|
data.setRecipientCountry("Deutschland");
|
||||||
|
data.setRecipientVatId("");
|
||||||
|
|
||||||
|
// Positionen (eine einfache Position aus Betrag/Beschreibung)
|
||||||
|
List<CustomerInvoiceItem> items = new ArrayList<>();
|
||||||
|
BigDecimal vatRate = new BigDecimal("0.19");
|
||||||
|
BigDecimal unitPrice = BigDecimal.valueOf(systemInvoice.getBetrag());
|
||||||
|
items.add(new CustomerInvoiceItem(BigDecimal.ONE, "Stk.", systemInvoice.getBeschreibung(), unitPrice, vatRate));
|
||||||
|
data.setItems(items);
|
||||||
|
|
||||||
|
// Summen berechnen
|
||||||
|
BigDecimal netAmount = items.stream().map(CustomerInvoiceItem::getNetTotal).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
|
BigDecimal vatAmount = netAmount.multiply(vatRate);
|
||||||
|
BigDecimal totalAmount = netAmount.add(vatAmount);
|
||||||
|
data.setNetAmount(netAmount);
|
||||||
|
data.setVatRate(vatRate);
|
||||||
|
data.setVatAmount(vatAmount);
|
||||||
|
data.setTotalAmount(totalAmount);
|
||||||
|
|
||||||
|
// Zahlung
|
||||||
|
data.setPaymentTerms("Zahlbar innerhalb von 14 Tagen netto ohne Abzug.");
|
||||||
|
data.setPaymentDueDate(systemInvoice.getDatum().plusDays(14));
|
||||||
|
data.setBankAccount(data.getSenderName());
|
||||||
|
data.setIban("");
|
||||||
|
data.setBic("");
|
||||||
|
|
||||||
|
// Rechtliches
|
||||||
|
data.setLegalNotes("");
|
||||||
|
data.setReverseChargeNote("");
|
||||||
|
|
||||||
|
return customerInvoiceService.generateCustomerInvoicePdf(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String nullToEmpty(String s) {
|
||||||
|
return s == null ? "" : s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,12 +128,20 @@ public class CustomerInvoiceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public byte[] generateCustomerInvoicePdf() throws Exception {
|
public byte[] generateCustomerInvoicePdf() throws Exception {
|
||||||
|
// Backward-compatible sample generation
|
||||||
|
CustomerInvoiceData sampleData = createCustomerInvoiceData("customerId", "jobId");
|
||||||
|
return generateCustomerInvoicePdf(sampleData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a Customer Invoice PDF from provided data using the HTML template.
|
||||||
|
*/
|
||||||
|
public byte[] generateCustomerInvoicePdf(CustomerInvoiceData data) throws Exception {
|
||||||
// Read the HTML template
|
// Read the HTML template
|
||||||
String htmlContent = readCustomerInvoiceHtmlTemplate();
|
String htmlContent = readCustomerInvoiceHtmlTemplate();
|
||||||
|
|
||||||
// Fill HTML with sample data
|
// Fill HTML with provided data
|
||||||
CustomerInvoiceData sampleData = createCustomerInvoiceData("customerId", "jobId");
|
String filledHtml = fillCustomerInvoiceHtmlWithInvoiceData(htmlContent, data);
|
||||||
String filledHtml = fillCustomerInvoiceHtmlWithInvoiceData(htmlContent, sampleData);
|
|
||||||
|
|
||||||
// Generate PDF from HTML
|
// Generate PDF from HTML
|
||||||
return generatePdfFromHtmlString(filledHtml);
|
return generatePdfFromHtmlString(filledHtml);
|
||||||
|
|||||||
Reference in New Issue
Block a user