Skip to content

Commit 93d0102

Browse files
authored
Merge pull request #1 from ipax77/dev
v0.1.0
2 parents cefead0 + 56107ca commit 93d0102

23 files changed

+412
-222
lines changed

README.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,17 @@ InvoiceDto invoiceDto = new()
3131
Note = "Test Note",
3232
DocumentCurrencyCode = "EUR",
3333
BuyerReference = "123",
34-
AdditionalDocumentReference = new()
34+
AdditionalDocumentReferences = [new()
3535
{
3636
Id = "invoice 123",
3737
DocumentDescription = "human readable pdf invoice",
3838
MimeCode = "application/pdf",
3939
FileName = "invoice.pdf",
4040
Content = "ZWYNCjE0OTk0Nw0KJSVFT0Y=",
41-
},
41+
}],
4242
Seller = new()
4343
{
44+
Website = "www.example.com",
4445
Email = "seller@email.com",
4546
Name = "Seller",
4647
StreetName = "TestStreet",
@@ -50,7 +51,8 @@ InvoiceDto invoiceDto = new()
5051
ContactTelephone = "12345",
5152
ContactEmail = "contact@email.com",
5253
TaxCompanyId = "DE1234567",
53-
TaxSchemeId = "VAT",
54+
TaxSchemeId = "S",
55+
TaxId = "000/0000/000",
5456
RegistrationName = "Seller Name",
5557
},
5658
Buyer = new()
@@ -153,7 +155,16 @@ catch (Exception ex)
153155
* **Incomplete XML Validation**: Not all XML element names or attributes are verified for strict compliance with XRechnung standards.
154156
# ChangeLog
155157

156-
<details open="open"><summary>v0.0.1</summary>
158+
<details open="open"><summary>v0.1.0</summary>
159+
160+
>- **Breaking Changes**
161+
>- Added FinancialInstitutionBranch to FinancialAccountType (XmlPaymentInstructions)
162+
>- Seller/Buyer cleanup and reference XmlParty
163+
>- Changed XmlAdditionalDocumentReference to XmlAdditionalDocumentReferences as list
164+
165+
</details>
166+
167+
<details><summary>v0.0.1</summary>
157168

158169
>- Initial release
159170
>- Support for invoice validation and serialization
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
2+
using pax.XRechnung.NET.Dtos;
3+
4+
namespace pax.XRechnung.NET.tests;
5+
[TestClass]
6+
public class CalculateSummaryTests
7+
{
8+
[TestMethod]
9+
public void CanCalculteSummry()
10+
{
11+
var invoice = DtoValidationTests.GetStandardInvoiceDto();
12+
invoice.InvoiceLines.Clear();
13+
var line = new InvoiceLineDto()
14+
{
15+
Id = "1",
16+
Note = "Test Note",
17+
Name = "Test",
18+
Description = "Test Desc",
19+
TaxId = "S",
20+
TaxPercent = 19.0M,
21+
TaxScheme = "VAT",
22+
InvoicedQuantity = 1,
23+
InvoicedQuantityCode = "HUR",
24+
LineExtensionAmount = 100M,
25+
PriceAmount = 100M,
26+
};
27+
invoice.InvoiceLines.Add(line);
28+
29+
invoice.CalculateTotals();
30+
31+
Assert.AreEqual(100M, invoice.TaxTotal.TaxableAmount);
32+
Assert.AreEqual(19M, invoice.TaxTotal.TaxAmount);
33+
Assert.AreEqual(100M, invoice.LegalMonetaryTotal.LineExtensionAmount);
34+
Assert.AreEqual(100M, invoice.LegalMonetaryTotal.TaxExclusiveAmount);
35+
Assert.AreEqual(119M, invoice.LegalMonetaryTotal.TaxInclusiveAmount);
36+
Assert.AreEqual(119M, invoice.LegalMonetaryTotal.PayableAmount);
37+
}
38+
39+
[TestMethod]
40+
public void CanCalculteComplexSummry()
41+
{
42+
var invoice = DtoValidationTests.GetStandardInvoiceDto();
43+
invoice.InvoiceLines.Clear();
44+
var line1 = new InvoiceLineDto()
45+
{
46+
Id = "1",
47+
Note = "Test Note",
48+
Name = "Test",
49+
Description = "Test Desc",
50+
TaxId = "S",
51+
TaxPercent = 19.0M,
52+
TaxScheme = "VAT",
53+
InvoicedQuantity = 1,
54+
InvoicedQuantityCode = "HUR",
55+
LineExtensionAmount = 100M,
56+
PriceAmount = 100M,
57+
};
58+
var line2 = new InvoiceLineDto()
59+
{
60+
Id = "2",
61+
Note = "Test Note",
62+
Name = "Test",
63+
Description = "Test Desc",
64+
TaxId = "S",
65+
TaxPercent = 19.0M,
66+
TaxScheme = "VAT",
67+
InvoicedQuantity = 2,
68+
InvoicedQuantityCode = "HUR",
69+
LineExtensionAmount = 100M,
70+
PriceAmount = 50M,
71+
};
72+
invoice.InvoiceLines.Add(line1);
73+
invoice.InvoiceLines.Add(line2);
74+
75+
invoice.CalculateTotals();
76+
77+
Assert.AreEqual(200M, invoice.TaxTotal.TaxableAmount);
78+
Assert.AreEqual(38M, invoice.TaxTotal.TaxAmount);
79+
Assert.AreEqual(200M, invoice.LegalMonetaryTotal.LineExtensionAmount);
80+
Assert.AreEqual(200M, invoice.LegalMonetaryTotal.TaxExclusiveAmount);
81+
Assert.AreEqual(238M, invoice.LegalMonetaryTotal.TaxInclusiveAmount);
82+
Assert.AreEqual(238M, invoice.LegalMonetaryTotal.PayableAmount);
83+
}
84+
}

src/pax.XRechnung.NET.tests/DtoValidationTests.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace pax.XRechnung.NET.tests;
66
[TestClass]
77
public class DtoValidationTests
88
{
9-
private static InvoiceDto GetStandardInvoiceDto()
9+
public static InvoiceDto GetStandardInvoiceDto()
1010
{
1111
InvoiceDto invoiceDto = new()
1212
{
@@ -17,16 +17,17 @@ private static InvoiceDto GetStandardInvoiceDto()
1717
Note = "Test Note",
1818
DocumentCurrencyCode = "EUR",
1919
BuyerReference = "123",
20-
AdditionalDocumentReference = new()
20+
AdditionalDocumentReferences = [new()
2121
{
2222
Id = "invoice 123",
2323
DocumentDescription = "human readable pdf invoice",
2424
MimeCode = "application/pdf",
2525
FileName = "invoice.pdf",
2626
Content = "ZWYNCjE0OTk0Nw0KJSVFT0Y=",
27-
},
27+
}],
2828
Seller = new()
2929
{
30+
Website = "www.example.com",
3031
Email = "seller@email.com",
3132
Name = "Seller",
3233
StreetName = "TestStreet",
@@ -36,7 +37,8 @@ private static InvoiceDto GetStandardInvoiceDto()
3637
ContactTelephone = "12345",
3738
ContactEmail = "contact@email.com",
3839
TaxCompanyId = "DE1234567",
39-
TaxSchemeId = "VAT",
40+
TaxSchemeId = "S",
41+
TaxId = "000/0000/000",
4042
RegistrationName = "Seller Name",
4143
},
4244
Buyer = new()
@@ -107,7 +109,7 @@ public void CanValidateStandardDto()
107109
public void CanValidateDtoWithTaxRegistrationName()
108110
{
109111
var invoiceDto = GetStandardInvoiceDto();
110-
invoiceDto.Seller.TaxRegistrationName = "000/000/00000";
112+
invoiceDto.Seller.TaxRegistrationName = "Test";
111113
var xmlInvoice = XmlInvoiceMapper.MapToXmlInvoice(invoiceDto);
112114
var validationResult = XmlInvoiceValidator.Validate(xmlInvoice);
113115

src/pax.XRechnung.NET.tests/MapTests.cs

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ public void CanMap2Xml()
1515
InvoiceDto invoiceDto = new()
1616
{
1717
Id = "1",
18-
IssueDate = DateTime.UtcNow,
19-
DueDate = DateTime.UtcNow.AddDays(14),
18+
IssueDate = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc),
19+
DueDate = new DateTime(2025, 1, 14, 0, 0, 0, DateTimeKind.Utc),
2020
InvoiceTypeCode = "380",
2121
Note = "Test Note",
2222
DocumentCurrencyCode = "EUR",
@@ -42,7 +42,7 @@ public void CanMap2Xml_NullableFields()
4242
InvoiceDto invoiceDto = new()
4343
{
4444
Id = "1",
45-
IssueDate = DateTime.UtcNow,
45+
IssueDate = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc),
4646
DueDate = null,
4747
InvoiceTypeCode = "380",
4848
DocumentCurrencyCode = "EUR",
@@ -70,8 +70,8 @@ public void CanMap2Dto()
7070
XmlInvoice xmlInvoice = new()
7171
{
7272
Id = new() { Content = "1" },
73-
IssueDate = DateTime.UtcNow,
74-
DueDate = DateTime.UtcNow.AddDays(14),
73+
IssueDate = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc),
74+
DueDate = new DateTime(2025, 1, 14, 0, 0, 0, DateTimeKind.Utc),
7575
InvoiceTypeCode = "380",
7676
Note = "Test Note",
7777
DocumentCurrencyCode = "EUR",
@@ -96,8 +96,8 @@ public void CanMapTwiceBase()
9696
InvoiceDto invoiceDto = new()
9797
{
9898
Id = "1",
99-
IssueDate = DateTime.UtcNow,
100-
DueDate = DateTime.UtcNow.AddDays(14),
99+
IssueDate = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc),
100+
DueDate = new DateTime(2025, 1, 14, 0, 0, 0, DateTimeKind.Utc),
101101
InvoiceTypeCode = "380",
102102
Note = "Test Note",
103103
DocumentCurrencyCode = "EUR",
@@ -106,7 +106,7 @@ public void CanMapTwiceBase()
106106

107107
XmlInvoice xmlInvoice = XmlInvoiceMapper.MapToXmlInvoice(invoiceDto);
108108
InvoiceDto invoiceDto2 = XmlInvoiceMapper.MapToInvoiceDto(xmlInvoice);
109-
109+
110110
var json1 = JsonSerializer.Serialize(invoiceDto, jsonOptions);
111111
var json2 = JsonSerializer.Serialize(invoiceDto2, jsonOptions);
112112

@@ -119,20 +119,20 @@ public void CanMapTwiceWithDocContent()
119119
InvoiceDto invoiceDto = new()
120120
{
121121
Id = "1",
122-
IssueDate = DateTime.UtcNow,
123-
DueDate = DateTime.UtcNow.AddDays(14),
122+
IssueDate = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc),
123+
DueDate = new DateTime(2025, 1, 14, 0, 0, 0, DateTimeKind.Utc),
124124
InvoiceTypeCode = "380",
125125
Note = "Test Note",
126126
DocumentCurrencyCode = "EUR",
127127
BuyerReference = "123",
128-
AdditionalDocumentReference = new()
128+
AdditionalDocumentReferences = [new()
129129
{
130130
Id = "invoice 123",
131131
DocumentDescription = "human readable pdf invoice",
132132
MimeCode = "application/pdf",
133133
FileName = "invoice.pdf",
134134
Content = "ZWYNCjE0OTk0Nw0KJSVFT0Y=",
135-
}
135+
}]
136136
};
137137

138138
XmlInvoice xmlInvoice = XmlInvoiceMapper.MapToXmlInvoice(invoiceDto);
@@ -150,8 +150,8 @@ public void CanMapTwiceWithParticipants()
150150
InvoiceDto invoiceDto = new()
151151
{
152152
Id = "1",
153-
IssueDate = DateTime.UtcNow,
154-
DueDate = DateTime.UtcNow.AddDays(14),
153+
IssueDate = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc),
154+
DueDate = new DateTime(2025, 1, 14, 0, 0, 0, DateTimeKind.Utc),
155155
InvoiceTypeCode = "380",
156156
Note = "Test Note",
157157
DocumentCurrencyCode = "EUR",
@@ -198,8 +198,8 @@ public void CanMapTwiceWithPaymentInstructions()
198198
InvoiceDto invoiceDto = new()
199199
{
200200
Id = "1",
201-
IssueDate = DateTime.UtcNow,
202-
DueDate = DateTime.UtcNow.AddDays(14),
201+
IssueDate = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc),
202+
DueDate = new DateTime(2025, 1, 14, 0, 0, 0, DateTimeKind.Utc),
203203
InvoiceTypeCode = "380",
204204
Note = "Test Note",
205205
DocumentCurrencyCode = "EUR",
@@ -208,6 +208,7 @@ public void CanMapTwiceWithPaymentInstructions()
208208
{
209209
PaymentMeansTypeCode = "30",
210210
IBAN = "DE21081508151234123412",
211+
BIC = "BIC12345",
211212
BankName = "Test Bank"
212213
}
213214
};
@@ -227,8 +228,8 @@ public void CanMapTwiceWithTaxTotal()
227228
InvoiceDto invoiceDto = new()
228229
{
229230
Id = "1",
230-
IssueDate = DateTime.UtcNow,
231-
DueDate = DateTime.UtcNow.AddDays(14),
231+
IssueDate = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc),
232+
DueDate = new DateTime(2025, 1, 14, 0, 0, 0, DateTimeKind.Utc),
232233
InvoiceTypeCode = "380",
233234
Note = "Test Note",
234235
DocumentCurrencyCode = "EUR",
@@ -258,8 +259,8 @@ public void CanMapTwiceWithMonetaryTotal()
258259
InvoiceDto invoiceDto = new()
259260
{
260261
Id = "1",
261-
IssueDate = DateTime.UtcNow,
262-
DueDate = DateTime.UtcNow.AddDays(14),
262+
IssueDate = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc),
263+
DueDate = new DateTime(2025, 1, 14, 0, 0, 0, DateTimeKind.Utc),
263264
InvoiceTypeCode = "380",
264265
Note = "Test Note",
265266
DocumentCurrencyCode = "EUR",
@@ -288,8 +289,8 @@ public void CanMapTwiceWithInvoiceLine()
288289
InvoiceDto invoiceDto = new()
289290
{
290291
Id = "1",
291-
IssueDate = DateTime.UtcNow,
292-
DueDate = DateTime.UtcNow.AddDays(14),
292+
IssueDate = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc),
293+
DueDate = new DateTime(2025, 1, 14, 0, 0, 0, DateTimeKind.Utc),
293294
InvoiceTypeCode = "380",
294295
Note = "Test Note",
295296
DocumentCurrencyCode = "EUR",

src/pax.XRechnung.NET.tests/XmlInvoiceTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public static XmlInvoice GetTestInvoice()
2121
{
2222
Party = new()
2323
{
24+
Website = "https://www.einvoicetest.com",
2425
EndpointId = new() { Content = "buyer@email.com" },
2526
PartyName = new() { Name = "Verkäufer" },
2627
PostalAddress = new()

src/pax.XRechnung.NET/Dtos/InvoiceDto.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace pax.XRechnung.NET.Dtos;
44

55
/// <summary>
6-
/// Das Wurzelelement INVOICE
6+
/// Simplified Invoice DTO for all items have the same sales tax
77
/// </summary>
88
public record InvoiceDto
99
{
@@ -64,7 +64,7 @@ public record InvoiceDto
6464
/// Eine Gruppe von Informationselementen mit Informationen über rechnungsbegründende Unterlagen,
6565
/// die Belege für die in der Rechnung gestellten Ansprüche enthalten.
6666
/// </summary>
67-
public AdditionalDocumentReferenceDto? AdditionalDocumentReference { get; set; }
67+
public List<AdditionalDocumentReferenceDto> AdditionalDocumentReferences { get; set; } = [];
6868
/// <summary>
6969
/// AccountingSupplierParty
7070
/// </summary>

0 commit comments

Comments
 (0)