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.component.UI;
|
||||
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 java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.vaadin.flow.server.StreamResource;
|
||||
@@ -24,10 +29,15 @@ import com.vaadin.flow.server.StreamRegistration;
|
||||
@RolesAllowed({ "USER", "ADMIN" })
|
||||
public class InvoicesView extends VerticalLayout {
|
||||
|
||||
|
||||
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();
|
||||
setPadding(true);
|
||||
setSpacing(true);
|
||||
@@ -67,8 +77,8 @@ public class InvoicesView extends VerticalLayout {
|
||||
|
||||
private void downloadInvoicePdf(SystemInvoice systemInvoice) {
|
||||
try {
|
||||
// PDF generieren
|
||||
byte[] pdfBytes = generatePdf(systemInvoice);
|
||||
// PDF generieren mit CustomerInvoice (HTML Template)
|
||||
byte[] pdfBytes = generateCustomerInvoicePdf(systemInvoice);
|
||||
StreamResource resource = new StreamResource(systemInvoice.getId() + ".pdf",
|
||||
() -> new ByteArrayInputStream(pdfBytes));
|
||||
resource.setContentType("application/pdf");
|
||||
@@ -84,21 +94,72 @@ public class InvoicesView extends VerticalLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] generatePdf(SystemInvoice systemInvoice) {
|
||||
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
||||
// Einfache PDF mit iText (oder OpenPDF, falls iText nicht verfügbar)
|
||||
com.lowagie.text.Document document = new com.lowagie.text.Document();
|
||||
com.lowagie.text.pdf.PdfWriter.getInstance(document, out);
|
||||
document.open();
|
||||
document.add(new com.lowagie.text.Paragraph("Rechnung: " + systemInvoice.getId()));
|
||||
document.add(new com.lowagie.text.Paragraph("Kunde: " + systemInvoice.getKunde()));
|
||||
document.add(new com.lowagie.text.Paragraph("Datum: " + systemInvoice.getDatum()));
|
||||
document.add(new com.lowagie.text.Paragraph("Betrag: " + systemInvoice.getBetrag() + " EUR"));
|
||||
document.add(new com.lowagie.text.Paragraph("Beschreibung: " + systemInvoice.getBeschreibung()));
|
||||
document.close();
|
||||
return out.toByteArray();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("PDF-Generierung fehlgeschlagen: " + e.getMessage(), e);
|
||||
private byte[] generateCustomerInvoicePdf(SystemInvoice systemInvoice) throws Exception {
|
||||
// Aktuellen Benutzer als Rechnungssteller ermitteln
|
||||
de.assecutor.votianlt.model.User user = securityService.getCurrentDatabaseUser();
|
||||
|
||||
CustomerInvoiceData data = new CustomerInvoiceData();
|
||||
// Kopf
|
||||
data.setInvoiceNumber(systemInvoice.getId());
|
||||
data.setInvoiceDate(systemInvoice.getDatum());
|
||||
data.setDeliveryDate(systemInvoice.getDatum());
|
||||
data.setDescription(systemInvoice.getBeschreibung());
|
||||
|
||||
// Rechnungssteller = eingeloggter Benutzer
|
||||
String senderName = (nullToEmpty(user.getFirstname()) + " " + nullToEmpty(user.getName())).trim();
|
||||
if (senderName.isBlank() && user.getEmail() != null)
|
||||
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 {
|
||||
// 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
|
||||
String htmlContent = readCustomerInvoiceHtmlTemplate();
|
||||
|
||||
// Fill HTML with sample data
|
||||
CustomerInvoiceData sampleData = createCustomerInvoiceData("customerId", "jobId");
|
||||
String filledHtml = fillCustomerInvoiceHtmlWithInvoiceData(htmlContent, sampleData);
|
||||
// Fill HTML with provided data
|
||||
String filledHtml = fillCustomerInvoiceHtmlWithInvoiceData(htmlContent, data);
|
||||
|
||||
// Generate PDF from HTML
|
||||
return generatePdfFromHtmlString(filledHtml);
|
||||
|
||||
Reference in New Issue
Block a user