Erweiterungen
This commit is contained in:
@@ -5,7 +5,9 @@
|
|||||||
"mcp__ide__getDiagnostics",
|
"mcp__ide__getDiagnostics",
|
||||||
"Bash(find:*)",
|
"Bash(find:*)",
|
||||||
"Bash(./mvnw:*)",
|
"Bash(./mvnw:*)",
|
||||||
"Bash(rm:*)"
|
"Bash(rm:*)",
|
||||||
|
"Bash(lsof:*)",
|
||||||
|
"Bash(xargs kill:*)"
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
|
|||||||
BIN
customer-invoice-test.pdf
Normal file
BIN
customer-invoice-test.pdf
Normal file
Binary file not shown.
@@ -2,6 +2,9 @@ package de.assecutor.votianlt.model.invoices;
|
|||||||
|
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
import org.springframework.data.mongodb.core.mapping.Document;
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Document(collection = "customerInvoices")
|
@Document(collection = "customerInvoices")
|
||||||
public class CustomerInvoice {
|
public class CustomerInvoice {
|
||||||
@@ -9,20 +12,61 @@ public class CustomerInvoice {
|
|||||||
@Id
|
@Id
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
private String invoiceNumber;
|
// Pflichtangaben nach §14 UStG (German VAT law)
|
||||||
private String date;
|
private String invoiceNumber; // Fortlaufende Rechnungsnummer
|
||||||
private String text;
|
private LocalDate invoiceDate; // Rechnungsdatum
|
||||||
|
private LocalDate deliveryDate; // Leistungsdatum
|
||||||
|
|
||||||
// Add other fields as needed
|
// Rechnungssteller (Sender)
|
||||||
|
private String senderName;
|
||||||
|
private String senderAddress;
|
||||||
|
private String senderPostcode;
|
||||||
|
private String senderCity;
|
||||||
|
private String senderCountry;
|
||||||
|
private String senderTaxNumber; // Steuernummer
|
||||||
|
private String senderVatId; // USt-IdNr.
|
||||||
|
private String senderPhone;
|
||||||
|
private String senderEmail;
|
||||||
|
private String senderWebsite;
|
||||||
|
|
||||||
|
// Rechnungsempfänger (Recipient)
|
||||||
|
private String recipientName;
|
||||||
|
private String recipientCompany;
|
||||||
|
private String recipientAddress;
|
||||||
|
private String recipientPostcode;
|
||||||
|
private String recipientCity;
|
||||||
|
private String recipientCountry;
|
||||||
|
private String recipientVatId; // USt-IdNr. des Empfängers (falls vorhanden)
|
||||||
|
|
||||||
|
// Rechnungsdetails
|
||||||
|
private String description; // Beschreibung der Leistung
|
||||||
|
private List<CustomerInvoiceItem> items;
|
||||||
|
|
||||||
|
// Beträge
|
||||||
|
private BigDecimal netAmount; // Nettobetrag
|
||||||
|
private BigDecimal vatRate; // Steuersatz (z.B. 19% = 0.19)
|
||||||
|
private BigDecimal vatAmount; // Steuerbetrag
|
||||||
|
private BigDecimal totalAmount; // Bruttobetrag
|
||||||
|
|
||||||
|
// Zahlungsdetails
|
||||||
|
private String paymentTerms; // Zahlungsbedingungen
|
||||||
|
private LocalDate paymentDueDate; // Fälligkeitsdatum
|
||||||
|
private String bankAccount; // Bankverbindung
|
||||||
|
private String iban;
|
||||||
|
private String bic;
|
||||||
|
|
||||||
|
// Zusätzliche rechtliche Angaben
|
||||||
|
private String legalNotes; // Rechtliche Hinweise
|
||||||
|
private String reverseChargeNote; // Hinweis auf Reverse Charge (falls zutreffend)
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
public CustomerInvoice() {
|
public CustomerInvoice() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomerInvoice(String invoiceNumber, String date, String text) {
|
public CustomerInvoice(String invoiceNumber, LocalDate invoiceDate, String description) {
|
||||||
this.invoiceNumber = invoiceNumber;
|
this.invoiceNumber = invoiceNumber;
|
||||||
this.date = date;
|
this.invoiceDate = invoiceDate;
|
||||||
this.text = text;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getters and Setters
|
// Getters and Setters
|
||||||
@@ -42,19 +86,259 @@ public class CustomerInvoice {
|
|||||||
this.invoiceNumber = invoiceNumber;
|
this.invoiceNumber = invoiceNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDate() {
|
public LocalDate getInvoiceDate() {
|
||||||
return date;
|
return invoiceDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDate(String date) {
|
public void setInvoiceDate(LocalDate invoiceDate) {
|
||||||
this.date = date;
|
this.invoiceDate = invoiceDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText() {
|
public LocalDate getDeliveryDate() {
|
||||||
return text;
|
return deliveryDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setText(String text) {
|
public void setDeliveryDate(LocalDate deliveryDate) {
|
||||||
this.text = text;
|
this.deliveryDate = deliveryDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderName() {
|
||||||
|
return senderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderName(String senderName) {
|
||||||
|
this.senderName = senderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderAddress() {
|
||||||
|
return senderAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderAddress(String senderAddress) {
|
||||||
|
this.senderAddress = senderAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderPostcode() {
|
||||||
|
return senderPostcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderPostcode(String senderPostcode) {
|
||||||
|
this.senderPostcode = senderPostcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderCity() {
|
||||||
|
return senderCity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderCity(String senderCity) {
|
||||||
|
this.senderCity = senderCity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderCountry() {
|
||||||
|
return senderCountry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderCountry(String senderCountry) {
|
||||||
|
this.senderCountry = senderCountry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderTaxNumber() {
|
||||||
|
return senderTaxNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderTaxNumber(String senderTaxNumber) {
|
||||||
|
this.senderTaxNumber = senderTaxNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderVatId() {
|
||||||
|
return senderVatId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderVatId(String senderVatId) {
|
||||||
|
this.senderVatId = senderVatId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderPhone() {
|
||||||
|
return senderPhone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderPhone(String senderPhone) {
|
||||||
|
this.senderPhone = senderPhone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderEmail() {
|
||||||
|
return senderEmail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderEmail(String senderEmail) {
|
||||||
|
this.senderEmail = senderEmail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderWebsite() {
|
||||||
|
return senderWebsite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderWebsite(String senderWebsite) {
|
||||||
|
this.senderWebsite = senderWebsite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientName() {
|
||||||
|
return recipientName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientName(String recipientName) {
|
||||||
|
this.recipientName = recipientName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientCompany() {
|
||||||
|
return recipientCompany;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientCompany(String recipientCompany) {
|
||||||
|
this.recipientCompany = recipientCompany;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientAddress() {
|
||||||
|
return recipientAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientAddress(String recipientAddress) {
|
||||||
|
this.recipientAddress = recipientAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientPostcode() {
|
||||||
|
return recipientPostcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientPostcode(String recipientPostcode) {
|
||||||
|
this.recipientPostcode = recipientPostcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientCity() {
|
||||||
|
return recipientCity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientCity(String recipientCity) {
|
||||||
|
this.recipientCity = recipientCity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientCountry() {
|
||||||
|
return recipientCountry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientCountry(String recipientCountry) {
|
||||||
|
this.recipientCountry = recipientCountry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientVatId() {
|
||||||
|
return recipientVatId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientVatId(String recipientVatId) {
|
||||||
|
this.recipientVatId = recipientVatId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CustomerInvoiceItem> getItems() {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItems(List<CustomerInvoiceItem> items) {
|
||||||
|
this.items = items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getNetAmount() {
|
||||||
|
return netAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNetAmount(BigDecimal netAmount) {
|
||||||
|
this.netAmount = netAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getVatRate() {
|
||||||
|
return vatRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVatRate(BigDecimal vatRate) {
|
||||||
|
this.vatRate = vatRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getVatAmount() {
|
||||||
|
return vatAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVatAmount(BigDecimal vatAmount) {
|
||||||
|
this.vatAmount = vatAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getTotalAmount() {
|
||||||
|
return totalAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalAmount(BigDecimal totalAmount) {
|
||||||
|
this.totalAmount = totalAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPaymentTerms() {
|
||||||
|
return paymentTerms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPaymentTerms(String paymentTerms) {
|
||||||
|
this.paymentTerms = paymentTerms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getPaymentDueDate() {
|
||||||
|
return paymentDueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPaymentDueDate(LocalDate paymentDueDate) {
|
||||||
|
this.paymentDueDate = paymentDueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBankAccount() {
|
||||||
|
return bankAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBankAccount(String bankAccount) {
|
||||||
|
this.bankAccount = bankAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIban() {
|
||||||
|
return iban;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIban(String iban) {
|
||||||
|
this.iban = iban;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBic() {
|
||||||
|
return bic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBic(String bic) {
|
||||||
|
this.bic = bic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLegalNotes() {
|
||||||
|
return legalNotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLegalNotes(String legalNotes) {
|
||||||
|
this.legalNotes = legalNotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReverseChargeNote() {
|
||||||
|
return reverseChargeNote;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReverseChargeNote(String reverseChargeNote) {
|
||||||
|
this.reverseChargeNote = reverseChargeNote;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,70 @@
|
|||||||
package de.assecutor.votianlt.model.invoices;
|
package de.assecutor.votianlt.model.invoices;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.text.NumberFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class CustomerInvoiceData {
|
public class CustomerInvoiceData {
|
||||||
|
|
||||||
private String invoiceNumber;
|
private String invoiceNumber;
|
||||||
private String date;
|
private LocalDate invoiceDate;
|
||||||
private String text;
|
private LocalDate deliveryDate;
|
||||||
|
private String description;
|
||||||
private String recipientName;
|
|
||||||
private String recipientDepartment;
|
|
||||||
private String recipientStreet;
|
|
||||||
private String recipientCity;
|
|
||||||
|
|
||||||
|
// Rechnungssteller
|
||||||
private String senderName;
|
private String senderName;
|
||||||
private String senderAddress;
|
private String senderAddress;
|
||||||
|
private String senderPostcode;
|
||||||
|
private String senderCity;
|
||||||
|
private String senderCountry;
|
||||||
|
private String senderTaxNumber;
|
||||||
|
private String senderVatId;
|
||||||
private String senderPhone;
|
private String senderPhone;
|
||||||
|
private String senderEmail;
|
||||||
private String senderWebsite;
|
private String senderWebsite;
|
||||||
|
|
||||||
|
// Rechnungsempfänger
|
||||||
|
private String recipientName;
|
||||||
|
private String recipientCompany;
|
||||||
|
private String recipientAddress;
|
||||||
|
private String recipientPostcode;
|
||||||
|
private String recipientCity;
|
||||||
|
private String recipientCountry;
|
||||||
|
private String recipientVatId;
|
||||||
|
|
||||||
private List<CustomerInvoiceItem> items;
|
private List<CustomerInvoiceItem> items;
|
||||||
|
|
||||||
private String netAmount;
|
private BigDecimal netAmount;
|
||||||
private String vatAmount;
|
private BigDecimal vatRate;
|
||||||
private String totalAmount;
|
private BigDecimal vatAmount;
|
||||||
|
private BigDecimal totalAmount;
|
||||||
|
|
||||||
|
// Zahlungsdetails
|
||||||
|
private String paymentTerms;
|
||||||
|
private LocalDate paymentDueDate;
|
||||||
|
private String bankAccount;
|
||||||
|
private String iban;
|
||||||
|
private String bic;
|
||||||
|
|
||||||
|
// Rechtliche Angaben
|
||||||
|
private String legalNotes;
|
||||||
|
private String reverseChargeNote;
|
||||||
|
|
||||||
|
// Number formatter for German locale
|
||||||
|
private static final NumberFormat CURRENCY_FORMAT = NumberFormat.getCurrencyInstance(Locale.GERMANY);
|
||||||
|
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("dd.MM.yyyy");
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
public CustomerInvoiceData() {
|
public CustomerInvoiceData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomerInvoiceData(String invoiceNumber, String date, String text) {
|
public CustomerInvoiceData(String invoiceNumber, LocalDate invoiceDate, String description) {
|
||||||
this.invoiceNumber = invoiceNumber;
|
this.invoiceNumber = invoiceNumber;
|
||||||
this.date = date;
|
this.invoiceDate = invoiceDate;
|
||||||
this.text = text;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getters and Setters
|
// Getters and Setters
|
||||||
@@ -43,52 +76,28 @@ public class CustomerInvoiceData {
|
|||||||
this.invoiceNumber = invoiceNumber;
|
this.invoiceNumber = invoiceNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDate() {
|
public LocalDate getInvoiceDate() {
|
||||||
return date;
|
return invoiceDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDate(String date) {
|
public void setInvoiceDate(LocalDate invoiceDate) {
|
||||||
this.date = date;
|
this.invoiceDate = invoiceDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText() {
|
public LocalDate getDeliveryDate() {
|
||||||
return text;
|
return deliveryDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setText(String text) {
|
public void setDeliveryDate(LocalDate deliveryDate) {
|
||||||
this.text = text;
|
this.deliveryDate = deliveryDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRecipientName() {
|
public String getDescription() {
|
||||||
return recipientName;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRecipientName(String recipientName) {
|
public void setDescription(String description) {
|
||||||
this.recipientName = recipientName;
|
this.description = description;
|
||||||
}
|
|
||||||
|
|
||||||
public String getRecipientDepartment() {
|
|
||||||
return recipientDepartment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRecipientDepartment(String recipientDepartment) {
|
|
||||||
this.recipientDepartment = recipientDepartment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRecipientStreet() {
|
|
||||||
return recipientStreet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRecipientStreet(String recipientStreet) {
|
|
||||||
this.recipientStreet = recipientStreet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRecipientCity() {
|
|
||||||
return recipientCity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRecipientCity(String recipientCity) {
|
|
||||||
this.recipientCity = recipientCity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSenderName() {
|
public String getSenderName() {
|
||||||
@@ -107,6 +116,46 @@ public class CustomerInvoiceData {
|
|||||||
this.senderAddress = senderAddress;
|
this.senderAddress = senderAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSenderPostcode() {
|
||||||
|
return senderPostcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderPostcode(String senderPostcode) {
|
||||||
|
this.senderPostcode = senderPostcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderCity() {
|
||||||
|
return senderCity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderCity(String senderCity) {
|
||||||
|
this.senderCity = senderCity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderCountry() {
|
||||||
|
return senderCountry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderCountry(String senderCountry) {
|
||||||
|
this.senderCountry = senderCountry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderTaxNumber() {
|
||||||
|
return senderTaxNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderTaxNumber(String senderTaxNumber) {
|
||||||
|
this.senderTaxNumber = senderTaxNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSenderVatId() {
|
||||||
|
return senderVatId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderVatId(String senderVatId) {
|
||||||
|
this.senderVatId = senderVatId;
|
||||||
|
}
|
||||||
|
|
||||||
public String getSenderPhone() {
|
public String getSenderPhone() {
|
||||||
return senderPhone;
|
return senderPhone;
|
||||||
}
|
}
|
||||||
@@ -115,6 +164,14 @@ public class CustomerInvoiceData {
|
|||||||
this.senderPhone = senderPhone;
|
this.senderPhone = senderPhone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSenderEmail() {
|
||||||
|
return senderEmail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSenderEmail(String senderEmail) {
|
||||||
|
this.senderEmail = senderEmail;
|
||||||
|
}
|
||||||
|
|
||||||
public String getSenderWebsite() {
|
public String getSenderWebsite() {
|
||||||
return senderWebsite;
|
return senderWebsite;
|
||||||
}
|
}
|
||||||
@@ -123,6 +180,62 @@ public class CustomerInvoiceData {
|
|||||||
this.senderWebsite = senderWebsite;
|
this.senderWebsite = senderWebsite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRecipientName() {
|
||||||
|
return recipientName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientName(String recipientName) {
|
||||||
|
this.recipientName = recipientName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientCompany() {
|
||||||
|
return recipientCompany;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientCompany(String recipientCompany) {
|
||||||
|
this.recipientCompany = recipientCompany;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientAddress() {
|
||||||
|
return recipientAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientAddress(String recipientAddress) {
|
||||||
|
this.recipientAddress = recipientAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientPostcode() {
|
||||||
|
return recipientPostcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientPostcode(String recipientPostcode) {
|
||||||
|
this.recipientPostcode = recipientPostcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientCity() {
|
||||||
|
return recipientCity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientCity(String recipientCity) {
|
||||||
|
this.recipientCity = recipientCity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientCountry() {
|
||||||
|
return recipientCountry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientCountry(String recipientCountry) {
|
||||||
|
this.recipientCountry = recipientCountry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientVatId() {
|
||||||
|
return recipientVatId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipientVatId(String recipientVatId) {
|
||||||
|
this.recipientVatId = recipientVatId;
|
||||||
|
}
|
||||||
|
|
||||||
public List<CustomerInvoiceItem> getItems() {
|
public List<CustomerInvoiceItem> getItems() {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
@@ -131,27 +244,140 @@ public class CustomerInvoiceData {
|
|||||||
this.items = items;
|
this.items = items;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNetAmount() {
|
public BigDecimal getNetAmount() {
|
||||||
return netAmount;
|
return netAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNetAmount(String netAmount) {
|
public void setNetAmount(BigDecimal netAmount) {
|
||||||
this.netAmount = netAmount;
|
this.netAmount = netAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getVatAmount() {
|
public BigDecimal getVatRate() {
|
||||||
|
return vatRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVatRate(BigDecimal vatRate) {
|
||||||
|
this.vatRate = vatRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getVatAmount() {
|
||||||
return vatAmount;
|
return vatAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVatAmount(String vatAmount) {
|
public void setVatAmount(BigDecimal vatAmount) {
|
||||||
this.vatAmount = vatAmount;
|
this.vatAmount = vatAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTotalAmount() {
|
public BigDecimal getTotalAmount() {
|
||||||
return totalAmount;
|
return totalAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTotalAmount(String totalAmount) {
|
public void setTotalAmount(BigDecimal totalAmount) {
|
||||||
this.totalAmount = totalAmount;
|
this.totalAmount = totalAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPaymentTerms() {
|
||||||
|
return paymentTerms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPaymentTerms(String paymentTerms) {
|
||||||
|
this.paymentTerms = paymentTerms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getPaymentDueDate() {
|
||||||
|
return paymentDueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPaymentDueDate(LocalDate paymentDueDate) {
|
||||||
|
this.paymentDueDate = paymentDueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBankAccount() {
|
||||||
|
return bankAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBankAccount(String bankAccount) {
|
||||||
|
this.bankAccount = bankAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIban() {
|
||||||
|
return iban;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIban(String iban) {
|
||||||
|
this.iban = iban;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBic() {
|
||||||
|
return bic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBic(String bic) {
|
||||||
|
this.bic = bic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLegalNotes() {
|
||||||
|
return legalNotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLegalNotes(String legalNotes) {
|
||||||
|
this.legalNotes = legalNotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReverseChargeNote() {
|
||||||
|
return reverseChargeNote;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReverseChargeNote(String reverseChargeNote) {
|
||||||
|
this.reverseChargeNote = reverseChargeNote;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formatting methods for PDF generation
|
||||||
|
public String getFormattedInvoiceDate() {
|
||||||
|
return invoiceDate != null ? invoiceDate.format(DATE_FORMAT) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormattedDeliveryDate() {
|
||||||
|
return deliveryDate != null ? deliveryDate.format(DATE_FORMAT) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormattedPaymentDueDate() {
|
||||||
|
return paymentDueDate != null ? paymentDueDate.format(DATE_FORMAT) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormattedNetAmount() {
|
||||||
|
return netAmount != null ? CURRENCY_FORMAT.format(netAmount) : "0,00 €";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormattedVatAmount() {
|
||||||
|
return vatAmount != null ? CURRENCY_FORMAT.format(vatAmount) : "0,00 €";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormattedTotalAmount() {
|
||||||
|
return totalAmount != null ? CURRENCY_FORMAT.format(totalAmount) : "0,00 €";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormattedVatRate() {
|
||||||
|
if (vatRate != null) {
|
||||||
|
return String.format("%.0f%%", vatRate.multiply(new BigDecimal("100")));
|
||||||
|
}
|
||||||
|
return "19%";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy methods for backward compatibility
|
||||||
|
public String getDate() {
|
||||||
|
return getFormattedInvoiceDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientDepartment() {
|
||||||
|
return recipientCompany;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecipientStreet() {
|
||||||
|
return recipientAddress;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,57 @@
|
|||||||
package de.assecutor.votianlt.model.invoices;
|
package de.assecutor.votianlt.model.invoices;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
public class CustomerInvoiceItem {
|
public class CustomerInvoiceItem {
|
||||||
|
|
||||||
private String quantity;
|
private BigDecimal quantity;
|
||||||
|
private String unit; // Einheit (Stk., h, kg, etc.)
|
||||||
private String description;
|
private String description;
|
||||||
private String price;
|
private BigDecimal unitPrice; // Einzelpreis netto
|
||||||
private String total;
|
private BigDecimal netTotal; // Gesamtpreis netto
|
||||||
|
private BigDecimal vatRate; // Steuersatz
|
||||||
|
private BigDecimal vatAmount; // Steuerbetrag
|
||||||
|
private BigDecimal grossTotal; // Gesamtpreis brutto
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
public CustomerInvoiceItem() {
|
public CustomerInvoiceItem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomerInvoiceItem(String quantity, String description, String unitPrice, String total) {
|
public CustomerInvoiceItem(BigDecimal quantity, String unit, String description, BigDecimal unitPrice, BigDecimal vatRate) {
|
||||||
this.quantity = quantity;
|
this.quantity = quantity;
|
||||||
|
this.unit = unit;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.price = unitPrice;
|
this.unitPrice = unitPrice;
|
||||||
this.total = total;
|
this.vatRate = vatRate;
|
||||||
|
calculateTotals();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculateTotals() {
|
||||||
|
if (quantity != null && unitPrice != null) {
|
||||||
|
this.netTotal = quantity.multiply(unitPrice);
|
||||||
|
if (vatRate != null) {
|
||||||
|
this.vatAmount = netTotal.multiply(vatRate);
|
||||||
|
this.grossTotal = netTotal.add(vatAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getters and Setters
|
// Getters and Setters
|
||||||
public String getQuantity() {
|
public BigDecimal getQuantity() {
|
||||||
return quantity;
|
return quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setQuantity(String quantity) {
|
public void setQuantity(BigDecimal quantity) {
|
||||||
this.quantity = quantity;
|
this.quantity = quantity;
|
||||||
|
calculateTotals();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUnit() {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnit(String unit) {
|
||||||
|
this.unit = unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
@@ -35,19 +62,54 @@ public class CustomerInvoiceItem {
|
|||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPrice() {
|
public BigDecimal getUnitPrice() {
|
||||||
return price;
|
return unitPrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrice(String price) {
|
public void setUnitPrice(BigDecimal unitPrice) {
|
||||||
this.price = price;
|
this.unitPrice = unitPrice;
|
||||||
|
calculateTotals();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getNetTotal() {
|
||||||
|
return netTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNetTotal(BigDecimal netTotal) {
|
||||||
|
this.netTotal = netTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getVatRate() {
|
||||||
|
return vatRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVatRate(BigDecimal vatRate) {
|
||||||
|
this.vatRate = vatRate;
|
||||||
|
calculateTotals();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getVatAmount() {
|
||||||
|
return vatAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVatAmount(BigDecimal vatAmount) {
|
||||||
|
this.vatAmount = vatAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getGrossTotal() {
|
||||||
|
return grossTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGrossTotal(BigDecimal grossTotal) {
|
||||||
|
this.grossTotal = grossTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy methods for backward compatibility
|
||||||
|
public String getPrice() {
|
||||||
|
return unitPrice != null ? unitPrice.toString() : "0.00";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTotal() {
|
public String getTotal() {
|
||||||
return total;
|
return grossTotal != null ? grossTotal.toString() : "0.00";
|
||||||
}
|
|
||||||
|
|
||||||
public void setTotal(String total) {
|
|
||||||
this.total = total;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,55 +12,117 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class CustomerInvoiceService {
|
public class CustomerInvoiceService {
|
||||||
|
|
||||||
public CustomerInvoice createCustomerInvoice(String customerId, String jobId) {
|
public CustomerInvoice createCustomerInvoice(String customerId, String jobId) {
|
||||||
// This is a placeholder implementation
|
|
||||||
// In a real application, this would fetch customer and job data and create an invoice
|
|
||||||
|
|
||||||
CustomerInvoice invoice = new CustomerInvoice();
|
CustomerInvoice invoice = new CustomerInvoice();
|
||||||
//invoice.setCustomerId(customerId);
|
|
||||||
//invoice.setJobId(jobId);
|
// Set basic invoice details
|
||||||
|
invoice.setInvoiceNumber("INV-" + System.currentTimeMillis());
|
||||||
|
invoice.setInvoiceDate(LocalDate.now());
|
||||||
|
invoice.setDeliveryDate(LocalDate.now());
|
||||||
|
invoice.setDescription("Logistikdienstleistungen für Auftrag " + jobId);
|
||||||
|
|
||||||
|
// Set sender details (your company)
|
||||||
|
invoice.setSenderName("Assecutor GmbH");
|
||||||
|
invoice.setSenderAddress("Hauptstraße 456");
|
||||||
|
invoice.setSenderPostcode("12345");
|
||||||
|
invoice.setSenderCity("Berlin");
|
||||||
|
invoice.setSenderCountry("Deutschland");
|
||||||
|
invoice.setSenderTaxNumber("12/345/67890");
|
||||||
|
invoice.setSenderVatId("DE123456789");
|
||||||
|
invoice.setSenderPhone("+49 30 12345678");
|
||||||
|
invoice.setSenderEmail("info@assecutor.de");
|
||||||
|
invoice.setSenderWebsite("https://www.assecutor.de");
|
||||||
|
|
||||||
|
// Payment terms
|
||||||
|
invoice.setPaymentTerms("Zahlbar innerhalb von 14 Tagen netto ohne Abzug.");
|
||||||
|
invoice.setPaymentDueDate(LocalDate.now().plusDays(14));
|
||||||
|
invoice.setIban("DE89 3704 0044 0532 0130 00");
|
||||||
|
invoice.setBic("COBADEFFXXX");
|
||||||
|
|
||||||
|
// Legal information
|
||||||
|
invoice.setLegalNotes("Geschäftsführer: Max Mustermann | Registergericht: Berlin | HRB 123456");
|
||||||
|
|
||||||
return invoice;
|
return invoice;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomerInvoiceData createCustomerInvoiceData(String customerId, String jobId) {
|
public CustomerInvoiceData createCustomerInvoiceData(String customerId, String jobId) {
|
||||||
// This is a placeholder implementation
|
|
||||||
// In a real application, this would fetch customer and job data and create invoice data
|
|
||||||
|
|
||||||
CustomerInvoiceData invoiceData = new CustomerInvoiceData();
|
CustomerInvoiceData invoiceData = new CustomerInvoiceData();
|
||||||
|
|
||||||
|
// Rechnungsdetails
|
||||||
invoiceData.setInvoiceNumber("INV-" + System.currentTimeMillis());
|
invoiceData.setInvoiceNumber("INV-" + System.currentTimeMillis());
|
||||||
invoiceData.setDate("2025-09-20");
|
invoiceData.setInvoiceDate(LocalDate.now());
|
||||||
invoiceData.setText("Rechnung für Auftrag " + jobId);
|
invoiceData.setDeliveryDate(LocalDate.now());
|
||||||
|
invoiceData.setDescription("Logistikdienstleistungen für Auftrag " + jobId);
|
||||||
|
|
||||||
// Set recipient details
|
// Rechnungssteller (vollständige Angaben nach deutschem Recht)
|
||||||
invoiceData.setRecipientName("Kunde Name");
|
|
||||||
invoiceData.setRecipientDepartment("Abt. XYZ");
|
|
||||||
invoiceData.setRecipientStreet("Musterstraße 123");
|
|
||||||
invoiceData.setRecipientCity("12345 Musterstadt");
|
|
||||||
|
|
||||||
// Set sender details - Testdaten für den Rechnungssteller
|
|
||||||
invoiceData.setSenderName("Assecutor GmbH");
|
invoiceData.setSenderName("Assecutor GmbH");
|
||||||
invoiceData.setSenderAddress("Hauptstraße 456");
|
invoiceData.setSenderAddress("Hauptstraße 456");
|
||||||
invoiceData.setSenderPhone("+49 123 4567890");
|
invoiceData.setSenderPostcode("12345");
|
||||||
|
invoiceData.setSenderCity("Berlin");
|
||||||
|
invoiceData.setSenderCountry("Deutschland");
|
||||||
|
invoiceData.setSenderTaxNumber("12/345/67890");
|
||||||
|
invoiceData.setSenderVatId("DE123456789");
|
||||||
|
invoiceData.setSenderPhone("+49 30 12345678");
|
||||||
|
invoiceData.setSenderEmail("info@assecutor.de");
|
||||||
invoiceData.setSenderWebsite("https://www.assecutor.de");
|
invoiceData.setSenderWebsite("https://www.assecutor.de");
|
||||||
|
|
||||||
// Create sample items
|
// Rechnungsempfänger
|
||||||
|
invoiceData.setRecipientName("Max Mustermann");
|
||||||
|
invoiceData.setRecipientCompany("Musterfirma GmbH");
|
||||||
|
invoiceData.setRecipientAddress("Musterstraße 123");
|
||||||
|
invoiceData.setRecipientPostcode("54321");
|
||||||
|
invoiceData.setRecipientCity("Hamburg");
|
||||||
|
invoiceData.setRecipientCountry("Deutschland");
|
||||||
|
invoiceData.setRecipientVatId("DE987654321");
|
||||||
|
|
||||||
|
// Rechnungsposten
|
||||||
List<CustomerInvoiceItem> items = new ArrayList<>();
|
List<CustomerInvoiceItem> items = new ArrayList<>();
|
||||||
CustomerInvoiceItem item1 = new CustomerInvoiceItem("1", "Dienstleistung XYZ", "100,00 €", "100,00 €");
|
BigDecimal vatRate = new BigDecimal("0.19"); // 19% MwSt.
|
||||||
CustomerInvoiceItem item2 = new CustomerInvoiceItem("2", "Material ABC", "50,00 €", "100,00 €");
|
|
||||||
|
CustomerInvoiceItem item1 = new CustomerInvoiceItem(
|
||||||
|
new BigDecimal("2"), "Std.", "Transportdienstleistung",
|
||||||
|
new BigDecimal("85.00"), vatRate);
|
||||||
|
CustomerInvoiceItem item2 = new CustomerInvoiceItem(
|
||||||
|
new BigDecimal("1"), "Stk.", "Logistikkoordination",
|
||||||
|
new BigDecimal("120.00"), vatRate);
|
||||||
|
CustomerInvoiceItem item3 = new CustomerInvoiceItem(
|
||||||
|
new BigDecimal("50"), "km", "Kilometergebühr",
|
||||||
|
new BigDecimal("0.60"), vatRate);
|
||||||
|
|
||||||
items.add(item1);
|
items.add(item1);
|
||||||
items.add(item2);
|
items.add(item2);
|
||||||
|
items.add(item3);
|
||||||
invoiceData.setItems(items);
|
invoiceData.setItems(items);
|
||||||
|
|
||||||
// Set amounts
|
// Beträge berechnen
|
||||||
invoiceData.setNetAmount("200,00 €");
|
BigDecimal netAmount = items.stream()
|
||||||
invoiceData.setVatAmount("36,00 €");
|
.map(CustomerInvoiceItem::getNetTotal)
|
||||||
invoiceData.setTotalAmount("236,00 €");
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
|
BigDecimal vatAmount = netAmount.multiply(vatRate);
|
||||||
|
BigDecimal totalAmount = netAmount.add(vatAmount);
|
||||||
|
|
||||||
|
invoiceData.setNetAmount(netAmount);
|
||||||
|
invoiceData.setVatRate(vatRate);
|
||||||
|
invoiceData.setVatAmount(vatAmount);
|
||||||
|
invoiceData.setTotalAmount(totalAmount);
|
||||||
|
|
||||||
|
// Zahlungsdetails
|
||||||
|
invoiceData.setPaymentTerms("Zahlbar innerhalb von 14 Tagen netto ohne Abzug.");
|
||||||
|
invoiceData.setPaymentDueDate(LocalDate.now().plusDays(14));
|
||||||
|
invoiceData.setBankAccount("Assecutor GmbH");
|
||||||
|
invoiceData.setIban("DE89 3704 0044 0532 0130 00");
|
||||||
|
invoiceData.setBic("COBADEFFXXX");
|
||||||
|
|
||||||
|
// Rechtliche Hinweise
|
||||||
|
invoiceData.setLegalNotes("Geschäftsführer: Max Mustermann | Registergericht: Berlin | HRB 123456");
|
||||||
|
|
||||||
return invoiceData;
|
return invoiceData;
|
||||||
}
|
}
|
||||||
@@ -84,48 +146,91 @@ public class CustomerInvoiceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String fillCustomerInvoiceHtmlWithInvoiceData(String html, CustomerInvoiceData data) {
|
private String fillCustomerInvoiceHtmlWithInvoiceData(String html, CustomerInvoiceData data) {
|
||||||
// Replace placeholders in HTML with actual invoice data
|
|
||||||
String filledHtml = html;
|
String filledHtml = html;
|
||||||
|
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.GERMANY);
|
||||||
|
|
||||||
// Replace invoice data placeholders
|
// Replace invoice header data
|
||||||
filledHtml = filledHtml.replace("${invoiceData.invoiceNumber}", data.getInvoiceNumber() != null ? data.getInvoiceNumber() : "");
|
filledHtml = filledHtml.replace("${invoiceData.invoiceNumber}", nvl(data.getInvoiceNumber()));
|
||||||
filledHtml = filledHtml.replace("${invoiceData.date}", data.getDate() != null ? data.getDate() : "");
|
filledHtml = filledHtml.replace("${invoiceData.invoiceDate}", nvl(data.getFormattedInvoiceDate()));
|
||||||
filledHtml = filledHtml.replace("${invoiceData.text}", data.getText() != null ? data.getText() : "");
|
filledHtml = filledHtml.replace("${invoiceData.deliveryDate}", nvl(data.getFormattedDeliveryDate()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.description}", nvl(data.getDescription()));
|
||||||
|
|
||||||
// Replace recipient address
|
// Replace sender details (complete legal information)
|
||||||
filledHtml = filledHtml.replace("${invoiceData.recipientName}", data.getRecipientName() != null ? data.getRecipientName() : "");
|
filledHtml = filledHtml.replace("${invoiceData.senderName}", nvl(data.getSenderName()));
|
||||||
filledHtml = filledHtml.replace("${invoiceData.recipientDepartment}", data.getRecipientDepartment() != null ? data.getRecipientDepartment() : "");
|
filledHtml = filledHtml.replace("${invoiceData.senderAddress}", nvl(data.getSenderAddress()));
|
||||||
filledHtml = filledHtml.replace("${invoiceData.recipientStreet}", data.getRecipientStreet() != null ? data.getRecipientStreet() : "");
|
filledHtml = filledHtml.replace("${invoiceData.senderPostcode}", nvl(data.getSenderPostcode()));
|
||||||
filledHtml = filledHtml.replace("${invoiceData.recipientCity}", data.getRecipientCity() != null ? data.getRecipientCity() : "");
|
filledHtml = filledHtml.replace("${invoiceData.senderCity}", nvl(data.getSenderCity()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.senderCountry}", nvl(data.getSenderCountry()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.senderTaxNumber}", nvl(data.getSenderTaxNumber()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.senderVatId}", nvl(data.getSenderVatId()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.senderPhone}", nvl(data.getSenderPhone()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.senderEmail}", nvl(data.getSenderEmail()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.senderWebsite}", nvl(data.getSenderWebsite()));
|
||||||
|
|
||||||
// Replace sender details
|
// Replace recipient details
|
||||||
filledHtml = filledHtml.replace("${invoiceData.senderName}", data.getSenderName() != null ? data.getSenderName() : "");
|
filledHtml = filledHtml.replace("${invoiceData.recipientName}", nvl(data.getRecipientName()));
|
||||||
filledHtml = filledHtml.replace("${invoiceData.senderAddress}", data.getSenderAddress() != null ? data.getSenderAddress() : "");
|
filledHtml = filledHtml.replace("${invoiceData.recipientCompany}", nvl(data.getRecipientCompany()));
|
||||||
filledHtml = filledHtml.replace("${invoiceData.senderPhone}", data.getSenderPhone() != null ? data.getSenderPhone() : "");
|
filledHtml = filledHtml.replace("${invoiceData.recipientAddress}", nvl(data.getRecipientAddress()));
|
||||||
filledHtml = filledHtml.replace("${invoiceData.senderWebsite}", data.getSenderWebsite() != null ? data.getSenderWebsite() : "");
|
filledHtml = filledHtml.replace("${invoiceData.recipientPostcode}", nvl(data.getRecipientPostcode()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.recipientCity}", nvl(data.getRecipientCity()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.recipientCountry}", nvl(data.getRecipientCountry()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.recipientVatId}", nvl(data.getRecipientVatId()));
|
||||||
|
|
||||||
// Replace invoice items
|
// Replace invoice items
|
||||||
if (data.getItems() != null && !data.getItems().isEmpty()) {
|
if (data.getItems() != null && !data.getItems().isEmpty()) {
|
||||||
StringBuilder itemRows = new StringBuilder();
|
StringBuilder itemRows = new StringBuilder();
|
||||||
for (CustomerInvoiceItem item : data.getItems()) {
|
for (CustomerInvoiceItem item : data.getItems()) {
|
||||||
itemRows.append("<tr>");
|
itemRows.append("<tr>");
|
||||||
itemRows.append("<td>").append(item.getQuantity()).append("</td>");
|
itemRows.append("<td style='text-align: center;'>")
|
||||||
itemRows.append("<td>").append(item.getDescription()).append("</td>");
|
.append(formatDecimal(item.getQuantity()))
|
||||||
itemRows.append("<td>").append(item.getPrice()).append("</td>");
|
.append(" ").append(nvl(item.getUnit()))
|
||||||
itemRows.append("<td>").append(item.getTotal()).append("</td>");
|
.append("</td>");
|
||||||
|
itemRows.append("<td>").append(nvl(item.getDescription())).append("</td>");
|
||||||
|
itemRows.append("<td style='text-align: right;'>")
|
||||||
|
.append(formatCurrency(item.getUnitPrice()))
|
||||||
|
.append("</td>");
|
||||||
|
itemRows.append("<td style='text-align: right;'>")
|
||||||
|
.append(formatCurrency(item.getNetTotal()))
|
||||||
|
.append("</td>");
|
||||||
itemRows.append("</tr>");
|
itemRows.append("</tr>");
|
||||||
}
|
}
|
||||||
filledHtml = filledHtml.replace("<!-- ITEM_ROWS -->", itemRows.toString());
|
filledHtml = filledHtml.replace("<!-- ITEM_ROWS -->", itemRows.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace amounts
|
// Replace amounts
|
||||||
filledHtml = filledHtml.replace("${invoiceData.netAmount}", data.getNetAmount() != null ? data.getNetAmount() : "");
|
filledHtml = filledHtml.replace("${invoiceData.netAmount}", nvl(data.getFormattedNetAmount()));
|
||||||
filledHtml = filledHtml.replace("${invoiceData.vatAmount}", data.getVatAmount() != null ? data.getVatAmount() : "");
|
filledHtml = filledHtml.replace("${invoiceData.vatRate}", nvl(data.getFormattedVatRate()));
|
||||||
filledHtml = filledHtml.replace("${invoiceData.totalAmount}", data.getTotalAmount() != null ? data.getTotalAmount() : "");
|
filledHtml = filledHtml.replace("${invoiceData.vatAmount}", nvl(data.getFormattedVatAmount()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.totalAmount}", nvl(data.getFormattedTotalAmount()));
|
||||||
|
|
||||||
|
// Replace payment details
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.paymentTerms}", nvl(data.getPaymentTerms()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.paymentDueDate}", nvl(data.getFormattedPaymentDueDate()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.bankAccount}", nvl(data.getBankAccount()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.iban}", nvl(data.getIban()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.bic}", nvl(data.getBic()));
|
||||||
|
|
||||||
|
// Replace legal notes
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.legalNotes}", nvl(data.getLegalNotes()));
|
||||||
|
filledHtml = filledHtml.replace("${invoiceData.reverseChargeNote}", nvl(data.getReverseChargeNote()));
|
||||||
|
|
||||||
return filledHtml;
|
return filledHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String nvl(String value) {
|
||||||
|
return value != null ? value : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatCurrency(BigDecimal amount) {
|
||||||
|
if (amount == null) return "0,00 €";
|
||||||
|
return NumberFormat.getCurrencyInstance(Locale.GERMANY).format(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatDecimal(BigDecimal value) {
|
||||||
|
if (value == null) return "0";
|
||||||
|
return NumberFormat.getNumberInstance(Locale.GERMANY).format(value);
|
||||||
|
}
|
||||||
|
|
||||||
private byte[] generatePdfFromHtmlString(String htmlContent) throws Exception {
|
private byte[] generatePdfFromHtmlString(String htmlContent) throws Exception {
|
||||||
// Create PDF using iText library
|
// Create PDF using iText library
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
|||||||
@@ -1,143 +1,467 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org" lang="de">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Rechnung</title>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Rechnung ${invoiceData.invoiceNumber}</title>
|
||||||
<style>
|
<style>
|
||||||
|
@page {
|
||||||
|
size: A4;
|
||||||
|
margin: 2cm 1.5cm 2cm 1.5cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: 'Arial', 'Helvetica', sans-serif;
|
||||||
margin: 0;
|
font-size: 11pt;
|
||||||
padding: 20px;
|
line-height: 1.4;
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
.invoice-container {
|
|
||||||
background-color: white;
|
|
||||||
padding: 30px;
|
|
||||||
max-width: 800px;
|
|
||||||
margin: 0 auto;
|
|
||||||
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
border-bottom: 2px solid #333;
|
|
||||||
padding-bottom: 15px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
.company-info {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.invoice-details {
|
|
||||||
text-align: right;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.invoice-title {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
color: #333;
|
color: #333;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background: white;
|
||||||
}
|
}
|
||||||
.recipient-info {
|
|
||||||
margin-bottom: 30px;
|
.invoice-container {
|
||||||
|
max-width: 21cm;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: white;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Header Section */
|
||||||
|
.header {
|
||||||
|
display: table;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 3em;
|
||||||
|
border-bottom: 2px solid #2c5aa0;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-left {
|
||||||
|
display: table-cell;
|
||||||
|
width: 60%;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-right {
|
||||||
|
display: table-cell;
|
||||||
|
width: 40%;
|
||||||
|
vertical-align: top;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company-logo {
|
||||||
|
font-size: 24pt;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #2c5aa0;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company-details {
|
||||||
|
font-size: 9pt;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoice-title {
|
||||||
|
font-size: 18pt;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #2c5aa0;
|
||||||
|
margin-bottom: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoice-meta {
|
||||||
|
font-size: 10pt;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recipient Section */
|
||||||
|
.recipient-section {
|
||||||
|
margin-bottom: 2.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sender-short {
|
||||||
|
font-size: 8pt;
|
||||||
|
color: #666;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
padding-bottom: 2pt;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recipient-address {
|
||||||
|
font-size: 11pt;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recipient-address .company {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Invoice Details */
|
||||||
|
.invoice-details {
|
||||||
|
display: table;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoice-details-left {
|
||||||
|
display: table-cell;
|
||||||
|
width: 50%;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoice-details-right {
|
||||||
|
display: table-cell;
|
||||||
|
width: 50%;
|
||||||
|
vertical-align: top;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-row {
|
||||||
|
margin-bottom: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-label {
|
||||||
|
font-weight: bold;
|
||||||
|
display: inline-block;
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Items Table */
|
||||||
|
.items-section {
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
.items-table {
|
.items-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
margin-bottom: 20px;
|
font-size: 10pt;
|
||||||
}
|
margin-bottom: 1em;
|
||||||
.items-table th, .items-table td {
|
|
||||||
border: 1px solid #333;
|
|
||||||
padding: 10px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.items-table th {
|
.items-table th {
|
||||||
background-color: #f2f2f2;
|
background-color: #f8f9fa;
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
padding: 8pt;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #2c5aa0;
|
||||||
}
|
}
|
||||||
.totals {
|
|
||||||
width: 100%;
|
.items-table td {
|
||||||
text-align: right;
|
border: 1px solid #dee2e6;
|
||||||
margin-bottom: 30px;
|
padding: 6pt 8pt;
|
||||||
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
.totals td {
|
|
||||||
padding: 5px;
|
.items-table tbody tr:nth-child(even) {
|
||||||
|
background-color: #f8f9fa;
|
||||||
}
|
}
|
||||||
.signature-section {
|
|
||||||
margin-top: 50px;
|
.items-table .qty-col {
|
||||||
}
|
width: 10%;
|
||||||
.signature-line {
|
|
||||||
border-top: 1px solid #333;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding-top: 5px;
|
}
|
||||||
|
|
||||||
|
.items-table .desc-col {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-table .price-col {
|
||||||
|
width: 20%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-table .total-col {
|
||||||
|
width: 20%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Totals Section */
|
||||||
|
.totals-section {
|
||||||
|
display: table;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.totals-left {
|
||||||
|
display: table-cell;
|
||||||
|
width: 60%;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.totals-right {
|
||||||
|
display: table-cell;
|
||||||
|
width: 40%;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.totals-table {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 11pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.totals-table td {
|
||||||
|
padding: 4pt 8pt;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.totals-table .label-col {
|
||||||
|
text-align: right;
|
||||||
|
width: 70%;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.totals-table .amount-col {
|
||||||
|
text-align: right;
|
||||||
|
width: 30%;
|
||||||
|
font-weight: bold;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.totals-table .total-row .label-col,
|
||||||
|
.totals-table .total-row .amount-col {
|
||||||
|
background-color: #2c5aa0;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Payment Section */
|
||||||
|
.payment-section {
|
||||||
|
margin-bottom: 2em;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.payment-terms {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
padding: 1em;
|
||||||
|
border-left: 4px solid #2c5aa0;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bank-details {
|
||||||
|
display: table;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bank-details-left {
|
||||||
|
display: table-cell;
|
||||||
|
width: 50%;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bank-details-right {
|
||||||
|
display: table-cell;
|
||||||
|
width: 50%;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Legal Footer */
|
||||||
|
.legal-footer {
|
||||||
|
border-top: 1px solid #dee2e6;
|
||||||
|
padding-top: 1em;
|
||||||
|
font-size: 8pt;
|
||||||
|
color: #666;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Utility Classes */
|
||||||
|
.text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-1 {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-2 {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print Styles */
|
||||||
|
@media print {
|
||||||
|
body {
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoice-container {
|
||||||
|
max-width: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
page-break-after: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-table {
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.totals-section {
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="invoice-container">
|
<div class="invoice-container">
|
||||||
|
<!-- Header Section -->
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="company-info">
|
<div class="header-left">
|
||||||
<h2>${invoiceData.senderName}</h2>
|
<div class="company-logo">${invoiceData.senderName}</div>
|
||||||
<p>${invoiceData.senderAddress}</p>
|
<div class="company-details">
|
||||||
<p>${invoiceData.senderCity}</p>
|
${invoiceData.senderAddress}<br>
|
||||||
<p>Telefon: ${invoiceData.senderPhone}</p>
|
${invoiceData.senderPostcode} ${invoiceData.senderCity}<br>
|
||||||
<p>Web: ${invoiceData.senderWebsite}</p>
|
${invoiceData.senderCountry}<br>
|
||||||
|
<br>
|
||||||
|
Tel: ${invoiceData.senderPhone}<br>
|
||||||
|
E-Mail: ${invoiceData.senderEmail}<br>
|
||||||
|
Web: ${invoiceData.senderWebsite}<br>
|
||||||
|
<br>
|
||||||
|
Steuernr.: ${invoiceData.senderTaxNumber}<br>
|
||||||
|
USt-IdNr.: ${invoiceData.senderVatId}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="header-right">
|
||||||
|
<div class="invoice-title">RECHNUNG</div>
|
||||||
|
<div class="invoice-meta">
|
||||||
|
<strong>Nr. ${invoiceData.invoiceNumber}</strong><br>
|
||||||
|
vom ${invoiceData.invoiceDate}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Recipient Section -->
|
||||||
|
<div class="recipient-section">
|
||||||
|
<div class="sender-short">
|
||||||
|
${invoiceData.senderName} · ${invoiceData.senderAddress} · ${invoiceData.senderPostcode} ${invoiceData.senderCity}
|
||||||
|
</div>
|
||||||
|
<div class="recipient-address">
|
||||||
|
<div class="company">${invoiceData.recipientCompany}</div>
|
||||||
|
<div>${invoiceData.recipientName}</div>
|
||||||
|
<div>${invoiceData.recipientAddress}</div>
|
||||||
|
<div>${invoiceData.recipientPostcode} ${invoiceData.recipientCity}</div>
|
||||||
|
<div>${invoiceData.recipientCountry}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Invoice Details -->
|
||||||
<div class="invoice-details">
|
<div class="invoice-details">
|
||||||
<h3>Rechnung</h3>
|
<div class="invoice-details-left">
|
||||||
<p>Rechnungsnummer: <span th:text="${invoiceData.invoiceNumber}">INV-123456789</span></p>
|
<div class="detail-row">
|
||||||
<p>Datum: <span th:text="${invoiceData.date}">2025-09-20</span></p>
|
<span class="detail-label">Rechnungsdatum:</span>
|
||||||
|
${invoiceData.invoiceDate}
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Leistungsdatum:</span>
|
||||||
|
${invoiceData.deliveryDate}
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Kundennummer:</span>
|
||||||
|
${invoiceData.recipientVatId}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="invoice-details-right">
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Fälligkeitsdatum:</span>
|
||||||
|
${invoiceData.paymentDueDate}
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Zahlungsziel:</span>
|
||||||
|
14 Tage netto
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 class="invoice-title">Rechnung</h2>
|
<!-- Description -->
|
||||||
|
<div class="mb-2">
|
||||||
<div class="recipient-info">
|
<strong>Leistungsbeschreibung:</strong><br>
|
||||||
<h3>Empfänger:</h3>
|
${invoiceData.description}
|
||||||
<p><span th:text="${invoiceData.recipientName}">Kunde Name</span></p>
|
|
||||||
<p><span th:text="${invoiceData.recipientDepartment}">Abt. XYZ</span></p>
|
|
||||||
<p><span th:text="${invoiceData.recipientStreet}">Musterstraße 123</span></p>
|
|
||||||
<p><span th:text="${invoiceData.recipientCity}">12345 Musterstadt</span></p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Items Table -->
|
||||||
|
<div class="items-section">
|
||||||
<table class="items-table">
|
<table class="items-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Menge</th>
|
<th class="qty-col">Menge</th>
|
||||||
<th>Beschreibung</th>
|
<th class="desc-col">Beschreibung</th>
|
||||||
<th>Einzelpreis</th>
|
<th class="price-col">Einzelpreis<br>(netto)</th>
|
||||||
<th>Gesamt</th>
|
<th class="total-col">Gesamtpreis<br>(netto)</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr th:each="item : ${invoiceData.items}">
|
<!-- ITEM_ROWS -->
|
||||||
<td th:text="${item.quantity}">1</td>
|
|
||||||
<td th:text="${item.description}">Dienstleistung XYZ</td>
|
|
||||||
<td th:text="${item.unitPrice}">100,00 €</td>
|
|
||||||
<td th:text="${item.total}">100,00 €</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="totals">
|
<!-- Totals Section -->
|
||||||
<table>
|
<div class="totals-section">
|
||||||
|
<div class="totals-left">
|
||||||
|
<!-- Space for additional notes if needed -->
|
||||||
|
</div>
|
||||||
|
<div class="totals-right">
|
||||||
|
<table class="totals-table">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Netto:</td>
|
<td class="label-col">Nettobetrag:</td>
|
||||||
<td th:text="${invoiceData.netAmount}">200,00 €</td>
|
<td class="amount-col">${invoiceData.netAmount}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>USt (19%):</td>
|
<td class="label-col">zzgl. ${invoiceData.vatRate} MwSt.:</td>
|
||||||
<td th:text="${invoiceData.vatAmount}">36,00 €</td>
|
<td class="amount-col">${invoiceData.vatAmount}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr class="total-row">
|
||||||
<td><strong>Gesamt:</strong></td>
|
<td class="label-col">Rechnungsbetrag:</td>
|
||||||
<td><strong th:text="${invoiceData.totalAmount}">236,00 €</strong></td>
|
<td class="amount-col">${invoiceData.totalAmount}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="signature-section">
|
|
||||||
<p>Für Assecutor GmbH</p>
|
|
||||||
<div class="signature-line">
|
|
||||||
<p>Unterschrift</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Payment Section -->
|
||||||
|
<div class="payment-section">
|
||||||
|
<div class="payment-terms">
|
||||||
|
<strong>Zahlungsbedingungen:</strong><br>
|
||||||
|
${invoiceData.paymentTerms}
|
||||||
|
Fälligkeitsdatum: ${invoiceData.paymentDueDate}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bank-details">
|
||||||
|
<div class="bank-details-left">
|
||||||
|
<strong>Bankverbindung:</strong><br>
|
||||||
|
${invoiceData.bankAccount}<br>
|
||||||
|
IBAN: ${invoiceData.iban}<br>
|
||||||
|
BIC: ${invoiceData.bic}
|
||||||
|
</div>
|
||||||
|
<div class="bank-details-right">
|
||||||
|
<strong>Verwendungszweck:</strong><br>
|
||||||
|
Rechnung ${invoiceData.invoiceNumber}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Legal Footer -->
|
||||||
|
<div class="legal-footer">
|
||||||
|
${invoiceData.legalNotes}<br>
|
||||||
|
<br>
|
||||||
|
Vielen Dank für Ihr Vertrauen!<br>
|
||||||
|
Bei Fragen zu dieser Rechnung wenden Sie sich bitte an: ${invoiceData.senderEmail}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user