diff --git a/README.md b/README.md
index cf8daaa..cdce845 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@ Add Gallop to your project via [Maven Central](https://central.sonatype.com/arti
```groovy
dependencies {
- implementation 'de.codebarista:gallop:2.1.0'
+ implementation 'de.codebarista:gallop:2.2.0'
}
```
@@ -53,7 +53,7 @@ dependencies {
de.codebarista
gallop
- 2.1.0
+ 2.2.0
```
@@ -154,7 +154,8 @@ public class InvoiceGenerator {
.taxTotalAmount(new BigDecimal("100.60")) // Total VAT amount
.grandTotalAmount(new BigDecimal("630.08")) // Invoice total with VAT
.paidAmount(new BigDecimal("100.00")) // Already paid amount
- .duePayableAmount(new BigDecimal("530.08")) // Amount due for payment
+ .roundingAmount(new BigDecimal("0.02")) // Rounding amount
+ .duePayableAmount(new BigDecimal("530.10")) // Amount due for payment
// Sales order reference
.salesOrderReference("SO-98765");
@@ -168,6 +169,7 @@ public class InvoiceGenerator {
### Changelog
+- 2.2.0: Add BT-114 (Rounding amount)
- 2.1.0: Add BT-30/BT-47 (Seller/Buyer legal registration identifier),
BT-32 (Seller tax registration identifier),
BT-33 (Seller additional legal information),
diff --git a/build.gradle b/build.gradle
index ebcc184..bedbe8d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@ plugins {
}
group = 'de.codebarista'
-version = '2.1.0'
+version = '2.2.0'
java {
toolchain {
diff --git a/src/main/java/de/codebarista/gallop/xrechnung/XRechnungWriter.java b/src/main/java/de/codebarista/gallop/xrechnung/XRechnungWriter.java
index 3538bcc..e7dff1d 100644
--- a/src/main/java/de/codebarista/gallop/xrechnung/XRechnungWriter.java
+++ b/src/main/java/de/codebarista/gallop/xrechnung/XRechnungWriter.java
@@ -360,6 +360,11 @@ private Element createTradeSettlement(XmlDocumentBuilder builder) {
taxTotal.setTextContent(invoice.getTaxTotalAmount().toString());
sum.appendChild(taxTotal);
}
+ if (invoice.getRoundingAmount() != null) {
+ Element roundingAmount = builder.createElement(NS_RAM, "RoundingAmount"); // BT-114
+ roundingAmount.setTextContent(invoice.getRoundingAmount().toString());
+ sum.appendChild(roundingAmount);
+ }
Element grandTotal = builder.createElement(NS_RAM, "GrandTotalAmount"); // BT-112
if (invoice.getGrandTotalAmount() != null) {
grandTotal.setTextContent(invoice.getGrandTotalAmount().toString());
diff --git a/src/main/java/de/codebarista/gallop/xrechnung/model/Invoice.java b/src/main/java/de/codebarista/gallop/xrechnung/model/Invoice.java
index de3e47a..ef622b2 100644
--- a/src/main/java/de/codebarista/gallop/xrechnung/model/Invoice.java
+++ b/src/main/java/de/codebarista/gallop/xrechnung/model/Invoice.java
@@ -109,6 +109,11 @@ public class Invoice {
*/
private BigDecimal paidAmount;
+ /**
+ * The amount by which the grand total amount was rounded (BT-114)
+ */
+ private BigDecimal roundingAmount;
+
/**
* Amount due for payment (BT-115)
*/
@@ -346,6 +351,14 @@ public Invoice paidAmount(BigDecimal paidAmount) {
return this;
}
+ /**
+ * Sets the {@link #roundingAmount}
+ */
+ public Invoice roundingAmount(BigDecimal roundingAmount) {
+ this.roundingAmount = roundingAmount;
+ return this;
+ }
+
/**
* Sets the {@link #duePayableAmount}
*/
@@ -564,6 +577,13 @@ public BigDecimal getPaidAmount() {
return paidAmount;
}
+ /**
+ * Gets the {@link #roundingAmount}.
+ */
+ public BigDecimal getRoundingAmount() {
+ return roundingAmount;
+ }
+
/**
* Gets the {@link #duePayableAmount}.
*/
diff --git a/src/test/java/de/codebarista/gallop/xrechnung/BuildInvoiceTest.java b/src/test/java/de/codebarista/gallop/xrechnung/BuildInvoiceTest.java
index 1fd128d..6c2fd3e 100644
--- a/src/test/java/de/codebarista/gallop/xrechnung/BuildInvoiceTest.java
+++ b/src/test/java/de/codebarista/gallop/xrechnung/BuildInvoiceTest.java
@@ -117,7 +117,8 @@ public void buildInvoice() {
.taxTotalAmount(new BigDecimal("100.60")) // Total VAT amount
.grandTotalAmount(new BigDecimal("630.08")) // Invoice total with VAT
.paidAmount(new BigDecimal("100.00")) // Already paid amount
- .duePayableAmount(new BigDecimal("530.08")) // Amount due for payment
+ .roundingAmount(new BigDecimal("0.02")) // Rounding amount
+ .duePayableAmount(new BigDecimal("530.10")) // Amount due for payment
// Sales order reference
.salesOrderReference("SO-98765");
diff --git a/src/test/java/de/codebarista/gallop/xrechnung/XRechnungWriterScenariosTest.java b/src/test/java/de/codebarista/gallop/xrechnung/XRechnungWriterScenariosTest.java
index 6a8c28e..0b6b59a 100644
--- a/src/test/java/de/codebarista/gallop/xrechnung/XRechnungWriterScenariosTest.java
+++ b/src/test/java/de/codebarista/gallop/xrechnung/XRechnungWriterScenariosTest.java
@@ -50,6 +50,7 @@ public class XRechnungWriterScenariosTest {
"order_with_shipping_costs_with_multiple_taxes",
"order_with_tax_free_product",
"order_with_already_paid_amount",
+ "order_with_rounding_amount",
"order_without_vatid",
"order_with_legal_registration_identifiers"
})
diff --git a/src/test/resources/invoice/order_with_rounding_amount/invoice.json b/src/test/resources/invoice/order_with_rounding_amount/invoice.json
new file mode 100644
index 0000000..d6b793e
--- /dev/null
+++ b/src/test/resources/invoice/order_with_rounding_amount/invoice.json
@@ -0,0 +1,122 @@
+{
+ "documentTypeCode": "380",
+ "documentId": "1012",
+ "leitwegId": null,
+ "currency": "EUR",
+ "paymentInstructions": {
+ "meansType": "10",
+ "meansText": "Cash on delivery",
+ "remittanceInfo": null,
+ "paymentTerms": "Die Ware bleibt, bis zur vollständigen Bezahlung, unser Eigentum.\nLeistungsdatum entspricht Rechnungsdatum",
+ "creditTransfers": [],
+ "paymentCardInformation": null,
+ "directDebit": null
+ },
+ "issueDate": "2024-11-30T13:12:11.781+00:00",
+ "seller": {
+ "name": "Example Company",
+ "tradingName": "Examply Company Doing Things",
+ "vatId": "DE987654321",
+ "electronicAddress": "mail@company.com",
+ "electronicAddressScheme": "EM",
+ "address": {
+ "addressLineOne": "Tribute Avenue 777",
+ "addressLineTwo": null,
+ "addressLineThree": null,
+ "city": "Taxora",
+ "zipCode": "12345",
+ "countryIsoCode": "DE"
+ },
+ "contact": {
+ "name": "Kim Elliot",
+ "phone": "123456789",
+ "email": "mail@company.com"
+ }
+ },
+ "buyer": {
+ "name": "Test Test",
+ "tradingName": null,
+ "vatId": null,
+ "electronicAddress": "test@test.test",
+ "electronicAddressScheme": null,
+ "address": {
+ "addressLineOne": "Test",
+ "addressLineTwo": null,
+ "addressLineThree": null,
+ "city": "Foo",
+ "zipCode": "11223",
+ "countryIsoCode": "BH"
+ },
+ "contact": null
+ },
+ "deliveryInfo": {
+ "name": "Test Test",
+ "deliveryAddress": {
+ "addressLineOne": "Test",
+ "addressLineTwo": null,
+ "addressLineThree": null,
+ "city": "Foo",
+ "zipCode": "11223",
+ "countryIsoCode": "BH"
+ },
+ "actualDeliveryDate": null
+ },
+ "items": [
+ {
+ "id": 1,
+ "quantity": 1,
+ "unitCode": "XPP",
+ "itemTotalNetAmount": 16.80,
+ "name": "Main product with properties",
+ "description": null,
+ "unitPrice": 16.8000,
+ "vat": {
+ "rate": 19,
+ "category": "S",
+ "taxableAmount": null,
+ "taxAmount": null,
+ "vatExemptionReasonText": null,
+ "vatExemptionReasonCode": null
+ },
+ "sellerAssignedId": "10007.1",
+ "itemAttributes": [
+ {
+ "name": "Size",
+ "value": "S"
+ }
+ ],
+ "netAmount": 16.80
+ }
+ ],
+ "vatTotals": [
+ {
+ "rate": 19,
+ "category": "S",
+ "taxableAmount": 16.80,
+ "taxAmount": 3.19,
+ "vatExemptionReasonText": null,
+ "vatExemptionReasonCode": null
+ }
+ ],
+ "precedingInvoiceReferences": [],
+ "lineTotalAmount": 16.80,
+ "allowanceTotalAmount": 0.00,
+ "chargeTotalAmount": 0.00,
+ "taxBasisTotalAmount": 16.80,
+ "taxTotalAmount": 3.19,
+ "grandTotalAmount": 19.99,
+ "roundingAmount": 0.01,
+ "paidAmount": 10.00,
+ "duePayableAmount": 10.00,
+ "salesOrderReference": "10000",
+ "invoiceNotes": [],
+ "allowances": [],
+ "charges": [
+ {
+ "netAmount": 0.00,
+ "vatCategory": "S",
+ "vatRate": 19,
+ "reason": "Shipping costs"
+ }
+ ]
+}
diff --git a/src/test/resources/invoice/order_with_rounding_amount/xrechnung.xml b/src/test/resources/invoice/order_with_rounding_amount/xrechnung.xml
new file mode 100644
index 0000000..9bf4f41
--- /dev/null
+++ b/src/test/resources/invoice/order_with_rounding_amount/xrechnung.xml
@@ -0,0 +1,148 @@
+
+
+
+
+ urn:fdc:peppol.eu:2017:poacc:billing:01:1.0
+
+
+ urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0
+
+
+
+ 1012
+ 380
+
+ 20241130
+
+
+
+
+
+ 1
+
+
+ 10007.1
+ Main product with properties
+
+ Size
+ S
+
+
+
+
+ 16.8000
+ 1
+
+
+
+ 1
+
+
+
+ VAT
+ S
+ 19
+
+
+ 16.80
+
+
+
+
+ N/A
+
+ Example Company
+
+ Kim Elliot
+
+ 123456789
+
+
+ mail@company.com
+
+
+
+ 12345
+ Tribute Avenue 777
+ Taxora
+ DE
+
+
+ mail@company.com
+
+
+ DE987654321
+
+
+
+ Test Test
+
+ 11223
+ Test
+ Foo
+ BH
+
+
+ test@test.test
+
+
+
+ 10000
+
+
+
+
+ Test Test
+
+ 11223
+ Test
+ Foo
+ BH
+
+
+
+
+ EUR
+
+ 10
+ Cash on delivery
+
+
+ 3.19
+ VAT
+ 16.80
+ S
+ 19
+
+
+
+ true
+
+ 0.00
+ Shipping costs
+
+ VAT
+ S
+ 19
+
+
+
+ Die Ware bleibt, bis zur vollständigen Bezahlung, unser Eigentum.
+Leistungsdatum entspricht Rechnungsdatum
+
+
+ 16.80
+ 0.00
+ 0.00
+ 16.80
+ 3.19
+ 0.01
+ 19.99
+ 10.00
+ 10.00
+
+
+
+