Skip to content

Commit 6263f0a

Browse files
authored
add rounding amount BT-114 (#6)
1 parent e9a731c commit 6263f0a

8 files changed

Lines changed: 304 additions & 5 deletions

File tree

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Add Gallop to your project via [Maven Central](https://central.sonatype.com/arti
4242

4343
```groovy
4444
dependencies {
45-
implementation 'de.codebarista:gallop:2.1.0'
45+
implementation 'de.codebarista:gallop:2.2.0'
4646
}
4747
```
4848

@@ -53,7 +53,7 @@ dependencies {
5353
<dependency>
5454
<groupId>de.codebarista</groupId>
5555
<artifactId>gallop</artifactId>
56-
<version>2.1.0</version>
56+
<version>2.2.0</version>
5757
</dependency>
5858
```
5959

@@ -154,7 +154,8 @@ public class InvoiceGenerator {
154154
.taxTotalAmount(new BigDecimal("100.60")) // Total VAT amount
155155
.grandTotalAmount(new BigDecimal("630.08")) // Invoice total with VAT
156156
.paidAmount(new BigDecimal("100.00")) // Already paid amount
157-
.duePayableAmount(new BigDecimal("530.08")) // Amount due for payment
157+
.roundingAmount(new BigDecimal("0.02")) // Rounding amount
158+
.duePayableAmount(new BigDecimal("530.10")) // Amount due for payment
158159

159160
// Sales order reference
160161
.salesOrderReference("SO-98765");
@@ -168,6 +169,7 @@ public class InvoiceGenerator {
168169

169170
### Changelog
170171

172+
- 2.2.0: Add BT-114 (Rounding amount)
171173
- 2.1.0: Add BT-30/BT-47 (Seller/Buyer legal registration identifier),
172174
BT-32 (Seller tax registration identifier),
173175
BT-33 (Seller additional legal information),

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ plugins {
77
}
88

99
group = 'de.codebarista'
10-
version = '2.1.0'
10+
version = '2.2.0'
1111

1212
java {
1313
toolchain {

src/main/java/de/codebarista/gallop/xrechnung/XRechnungWriter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,11 @@ private Element createTradeSettlement(XmlDocumentBuilder builder) {
360360
taxTotal.setTextContent(invoice.getTaxTotalAmount().toString());
361361
sum.appendChild(taxTotal);
362362
}
363+
if (invoice.getRoundingAmount() != null) {
364+
Element roundingAmount = builder.createElement(NS_RAM, "RoundingAmount"); // BT-114
365+
roundingAmount.setTextContent(invoice.getRoundingAmount().toString());
366+
sum.appendChild(roundingAmount);
367+
}
363368
Element grandTotal = builder.createElement(NS_RAM, "GrandTotalAmount"); // BT-112
364369
if (invoice.getGrandTotalAmount() != null) {
365370
grandTotal.setTextContent(invoice.getGrandTotalAmount().toString());

src/main/java/de/codebarista/gallop/xrechnung/model/Invoice.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ public class Invoice {
109109
*/
110110
private BigDecimal paidAmount;
111111

112+
/**
113+
* The amount by which the grand total amount was rounded (BT-114)
114+
*/
115+
private BigDecimal roundingAmount;
116+
112117
/**
113118
* Amount due for payment (BT-115)
114119
*/
@@ -346,6 +351,14 @@ public Invoice paidAmount(BigDecimal paidAmount) {
346351
return this;
347352
}
348353

354+
/**
355+
* Sets the {@link #roundingAmount}
356+
*/
357+
public Invoice roundingAmount(BigDecimal roundingAmount) {
358+
this.roundingAmount = roundingAmount;
359+
return this;
360+
}
361+
349362
/**
350363
* Sets the {@link #duePayableAmount}
351364
*/
@@ -564,6 +577,13 @@ public BigDecimal getPaidAmount() {
564577
return paidAmount;
565578
}
566579

580+
/**
581+
* Gets the {@link #roundingAmount}.
582+
*/
583+
public BigDecimal getRoundingAmount() {
584+
return roundingAmount;
585+
}
586+
567587
/**
568588
* Gets the {@link #duePayableAmount}.
569589
*/

src/test/java/de/codebarista/gallop/xrechnung/BuildInvoiceTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ public void buildInvoice() {
117117
.taxTotalAmount(new BigDecimal("100.60")) // Total VAT amount
118118
.grandTotalAmount(new BigDecimal("630.08")) // Invoice total with VAT
119119
.paidAmount(new BigDecimal("100.00")) // Already paid amount
120-
.duePayableAmount(new BigDecimal("530.08")) // Amount due for payment
120+
.roundingAmount(new BigDecimal("0.02")) // Rounding amount
121+
.duePayableAmount(new BigDecimal("530.10")) // Amount due for payment
121122

122123
// Sales order reference
123124
.salesOrderReference("SO-98765");

src/test/java/de/codebarista/gallop/xrechnung/XRechnungWriterScenariosTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public class XRechnungWriterScenariosTest {
5050
"order_with_shipping_costs_with_multiple_taxes",
5151
"order_with_tax_free_product",
5252
"order_with_already_paid_amount",
53+
"order_with_rounding_amount",
5354
"order_without_vatid",
5455
"order_with_legal_registration_identifiers"
5556
})
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
{
2+
"documentTypeCode": "380",
3+
"documentId": "1012",
4+
"leitwegId": null,
5+
"currency": "EUR",
6+
"paymentInstructions": {
7+
"meansType": "10",
8+
"meansText": "Cash on delivery",
9+
"remittanceInfo": null,
10+
"paymentTerms": "Die Ware bleibt, bis zur vollständigen Bezahlung, unser Eigentum.\nLeistungsdatum entspricht Rechnungsdatum",
11+
"creditTransfers": [],
12+
"paymentCardInformation": null,
13+
"directDebit": null
14+
},
15+
"issueDate": "2024-11-30T13:12:11.781+00:00",
16+
"seller": {
17+
"name": "Example Company",
18+
"tradingName": "Examply Company Doing Things",
19+
"vatId": "DE987654321",
20+
"electronicAddress": "mail@company.com",
21+
"electronicAddressScheme": "EM",
22+
"address": {
23+
"addressLineOne": "Tribute Avenue 777",
24+
"addressLineTwo": null,
25+
"addressLineThree": null,
26+
"city": "Taxora",
27+
"zipCode": "12345",
28+
"countryIsoCode": "DE"
29+
},
30+
"contact": {
31+
"name": "Kim Elliot",
32+
"phone": "123456789",
33+
"email": "mail@company.com"
34+
}
35+
},
36+
"buyer": {
37+
"name": "Test Test",
38+
"tradingName": null,
39+
"vatId": null,
40+
"electronicAddress": "test@test.test",
41+
"electronicAddressScheme": null,
42+
"address": {
43+
"addressLineOne": "Test",
44+
"addressLineTwo": null,
45+
"addressLineThree": null,
46+
"city": "Foo",
47+
"zipCode": "11223",
48+
"countryIsoCode": "BH"
49+
},
50+
"contact": null
51+
},
52+
"deliveryInfo": {
53+
"name": "Test Test",
54+
"deliveryAddress": {
55+
"addressLineOne": "Test",
56+
"addressLineTwo": null,
57+
"addressLineThree": null,
58+
"city": "Foo",
59+
"zipCode": "11223",
60+
"countryIsoCode": "BH"
61+
},
62+
"actualDeliveryDate": null
63+
},
64+
"items": [
65+
{
66+
"id": 1,
67+
"quantity": 1,
68+
"unitCode": "XPP",
69+
"itemTotalNetAmount": 16.80,
70+
"name": "Main product with properties",
71+
"description": null,
72+
"unitPrice": 16.8000,
73+
"vat": {
74+
"rate": 19,
75+
"category": "S",
76+
"taxableAmount": null,
77+
"taxAmount": null,
78+
"vatExemptionReasonText": null,
79+
"vatExemptionReasonCode": null
80+
},
81+
"sellerAssignedId": "10007.1",
82+
"itemAttributes": [
83+
{
84+
"name": "Size",
85+
"value": "S"
86+
}
87+
],
88+
"netAmount": 16.80
89+
}
90+
],
91+
"vatTotals": [
92+
{
93+
"rate": 19,
94+
"category": "S",
95+
"taxableAmount": 16.80,
96+
"taxAmount": 3.19,
97+
"vatExemptionReasonText": null,
98+
"vatExemptionReasonCode": null
99+
}
100+
],
101+
"precedingInvoiceReferences": [],
102+
"lineTotalAmount": 16.80,
103+
"allowanceTotalAmount": 0.00,
104+
"chargeTotalAmount": 0.00,
105+
"taxBasisTotalAmount": 16.80,
106+
"taxTotalAmount": 3.19,
107+
"grandTotalAmount": 19.99,
108+
"roundingAmount": 0.01,
109+
"paidAmount": 10.00,
110+
"duePayableAmount": 10.00,
111+
"salesOrderReference": "10000",
112+
"invoiceNotes": [],
113+
"allowances": [],
114+
"charges": [
115+
{
116+
"netAmount": 0.00,
117+
"vatCategory": "S",
118+
"vatRate": 19,
119+
"reason": "Shipping costs"
120+
}
121+
]
122+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<rsm:CrossIndustryInvoice xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
3+
xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
4+
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
5+
<rsm:ExchangedDocumentContext>
6+
<ram:BusinessProcessSpecifiedDocumentContextParameter>
7+
<ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID>
8+
</ram:BusinessProcessSpecifiedDocumentContextParameter>
9+
<ram:GuidelineSpecifiedDocumentContextParameter>
10+
<ram:ID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</ram:ID>
11+
</ram:GuidelineSpecifiedDocumentContextParameter>
12+
</rsm:ExchangedDocumentContext>
13+
<rsm:ExchangedDocument>
14+
<ram:ID>1012</ram:ID>
15+
<ram:TypeCode>380</ram:TypeCode>
16+
<ram:IssueDateTime>
17+
<udt:DateTimeString format="102">20241130</udt:DateTimeString>
18+
</ram:IssueDateTime>
19+
</rsm:ExchangedDocument>
20+
<rsm:SupplyChainTradeTransaction>
21+
<ram:IncludedSupplyChainTradeLineItem>
22+
<ram:AssociatedDocumentLineDocument>
23+
<ram:LineID>1</ram:LineID>
24+
</ram:AssociatedDocumentLineDocument>
25+
<ram:SpecifiedTradeProduct>
26+
<ram:SellerAssignedID>10007.1</ram:SellerAssignedID>
27+
<ram:Name>Main product with properties</ram:Name>
28+
<ram:ApplicableProductCharacteristic>
29+
<ram:Description>Size</ram:Description>
30+
<ram:Value>S</ram:Value>
31+
</ram:ApplicableProductCharacteristic>
32+
</ram:SpecifiedTradeProduct>
33+
<ram:SpecifiedLineTradeAgreement>
34+
<ram:NetPriceProductTradePrice>
35+
<ram:ChargeAmount>16.8000</ram:ChargeAmount>
36+
<ram:BasisQuantity unitCode="XPP">1</ram:BasisQuantity>
37+
</ram:NetPriceProductTradePrice>
38+
</ram:SpecifiedLineTradeAgreement>
39+
<ram:SpecifiedLineTradeDelivery>
40+
<ram:BilledQuantity unitCode="XPP">1</ram:BilledQuantity>
41+
</ram:SpecifiedLineTradeDelivery>
42+
<ram:SpecifiedLineTradeSettlement>
43+
<ram:ApplicableTradeTax>
44+
<ram:TypeCode>VAT</ram:TypeCode>
45+
<ram:CategoryCode>S</ram:CategoryCode>
46+
<ram:RateApplicablePercent>19</ram:RateApplicablePercent>
47+
</ram:ApplicableTradeTax>
48+
<ram:SpecifiedTradeSettlementLineMonetarySummation>
49+
<ram:LineTotalAmount>16.80</ram:LineTotalAmount>
50+
</ram:SpecifiedTradeSettlementLineMonetarySummation>
51+
</ram:SpecifiedLineTradeSettlement>
52+
</ram:IncludedSupplyChainTradeLineItem>
53+
<ram:ApplicableHeaderTradeAgreement>
54+
<ram:BuyerReference>N/A</ram:BuyerReference>
55+
<ram:SellerTradeParty>
56+
<ram:Name>Example Company</ram:Name>
57+
<ram:DefinedTradeContact>
58+
<ram:PersonName>Kim Elliot</ram:PersonName>
59+
<ram:TelephoneUniversalCommunication>
60+
<ram:CompleteNumber>123456789</ram:CompleteNumber>
61+
</ram:TelephoneUniversalCommunication>
62+
<ram:EmailURIUniversalCommunication>
63+
<ram:URIID>mail@company.com</ram:URIID>
64+
</ram:EmailURIUniversalCommunication>
65+
</ram:DefinedTradeContact>
66+
<ram:PostalTradeAddress>
67+
<ram:PostcodeCode>12345</ram:PostcodeCode>
68+
<ram:LineOne>Tribute Avenue 777</ram:LineOne>
69+
<ram:CityName>Taxora</ram:CityName>
70+
<ram:CountryID>DE</ram:CountryID>
71+
</ram:PostalTradeAddress>
72+
<ram:URIUniversalCommunication>
73+
<ram:URIID schemeID="EM">mail@company.com</ram:URIID>
74+
</ram:URIUniversalCommunication>
75+
<ram:SpecifiedTaxRegistration>
76+
<ram:ID schemeID="VA">DE987654321</ram:ID>
77+
</ram:SpecifiedTaxRegistration>
78+
</ram:SellerTradeParty>
79+
<ram:BuyerTradeParty>
80+
<ram:Name>Test Test</ram:Name>
81+
<ram:PostalTradeAddress>
82+
<ram:PostcodeCode>11223</ram:PostcodeCode>
83+
<ram:LineOne>Test</ram:LineOne>
84+
<ram:CityName>Foo</ram:CityName>
85+
<ram:CountryID>BH</ram:CountryID>
86+
</ram:PostalTradeAddress>
87+
<ram:URIUniversalCommunication>
88+
<ram:URIID schemeID="EM">test@test.test</ram:URIID>
89+
</ram:URIUniversalCommunication>
90+
</ram:BuyerTradeParty>
91+
<ram:SellerOrderReferencedDocument>
92+
<ram:IssuerAssignedID>10000</ram:IssuerAssignedID>
93+
</ram:SellerOrderReferencedDocument>
94+
</ram:ApplicableHeaderTradeAgreement>
95+
<ram:ApplicableHeaderTradeDelivery>
96+
<ram:ShipToTradeParty>
97+
<ram:Name>Test Test</ram:Name>
98+
<ram:PostalTradeAddress>
99+
<ram:PostcodeCode>11223</ram:PostcodeCode>
100+
<ram:LineOne>Test</ram:LineOne>
101+
<ram:CityName>Foo</ram:CityName>
102+
<ram:CountryID>BH</ram:CountryID>
103+
</ram:PostalTradeAddress>
104+
</ram:ShipToTradeParty>
105+
</ram:ApplicableHeaderTradeDelivery>
106+
<ram:ApplicableHeaderTradeSettlement>
107+
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
108+
<ram:SpecifiedTradeSettlementPaymentMeans>
109+
<ram:TypeCode>10</ram:TypeCode>
110+
<ram:Information>Cash on delivery</ram:Information>
111+
</ram:SpecifiedTradeSettlementPaymentMeans>
112+
<ram:ApplicableTradeTax>
113+
<ram:CalculatedAmount>3.19</ram:CalculatedAmount>
114+
<ram:TypeCode>VAT</ram:TypeCode>
115+
<ram:BasisAmount>16.80</ram:BasisAmount>
116+
<ram:CategoryCode>S</ram:CategoryCode>
117+
<ram:RateApplicablePercent>19</ram:RateApplicablePercent>
118+
</ram:ApplicableTradeTax>
119+
<ram:SpecifiedTradeAllowanceCharge>
120+
<ram:ChargeIndicator>
121+
<udt:Indicator>true</udt:Indicator>
122+
</ram:ChargeIndicator>
123+
<ram:ActualAmount>0.00</ram:ActualAmount>
124+
<ram:Reason>Shipping costs</ram:Reason>
125+
<ram:CategoryTradeTax>
126+
<ram:TypeCode>VAT</ram:TypeCode>
127+
<ram:CategoryCode>S</ram:CategoryCode>
128+
<ram:RateApplicablePercent>19</ram:RateApplicablePercent>
129+
</ram:CategoryTradeTax>
130+
</ram:SpecifiedTradeAllowanceCharge>
131+
<ram:SpecifiedTradePaymentTerms>
132+
<ram:Description>Die Ware bleibt, bis zur vollständigen Bezahlung, unser Eigentum.
133+
Leistungsdatum entspricht Rechnungsdatum</ram:Description>
134+
</ram:SpecifiedTradePaymentTerms>
135+
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
136+
<ram:LineTotalAmount>16.80</ram:LineTotalAmount>
137+
<ram:ChargeTotalAmount>0.00</ram:ChargeTotalAmount>
138+
<ram:AllowanceTotalAmount>0.00</ram:AllowanceTotalAmount>
139+
<ram:TaxBasisTotalAmount>16.80</ram:TaxBasisTotalAmount>
140+
<ram:TaxTotalAmount currencyID="EUR">3.19</ram:TaxTotalAmount>
141+
<ram:RoundingAmount>0.01</ram:RoundingAmount>
142+
<ram:GrandTotalAmount>19.99</ram:GrandTotalAmount>
143+
<ram:TotalPrepaidAmount>10.00</ram:TotalPrepaidAmount>
144+
<ram:DuePayableAmount>10.00</ram:DuePayableAmount>
145+
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
146+
</ram:ApplicableHeaderTradeSettlement>
147+
</rsm:SupplyChainTradeTransaction>
148+
</rsm:CrossIndustryInvoice>

0 commit comments

Comments
 (0)