Skip to content

Commit

Permalink
Merge pull request #7 from MarlinKuhn/main
Browse files Browse the repository at this point in the history
Due Dates added to XRechnung
  • Loading branch information
samlown authored Jan 10, 2025
2 parents 2488794 + 2597709 commit 50fa135
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 57 deletions.
2 changes: 1 addition & 1 deletion document/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type Tax struct {

// Summary defines the structure of SpecifiedTradeSettlementHeaderMonetarySummation of the CII standard
type Summary struct {
TotalAmount string `xml:"ram:LineTotalAmount"`
LineTotalAmount string `xml:"ram:LineTotalAmount"`
Charges string `xml:"ram:ChargeTotalAmount,omitempty"`
Discounts string `xml:"ram:AllowanceTotalAmount,omitempty"`
TaxBasisTotalAmount string `xml:"ram:TaxBasisTotalAmount"`
Expand Down
63 changes: 34 additions & 29 deletions internal/ctog/charges.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,23 +76,25 @@ func newCharge(ac *document.AllowanceCharge) (*bill.Charge, error) {
}
c.Percent = &p
}
if ac.Tax.TypeCode != "" {
c.Taxes = tax.Set{
{
Category: cbc.Code(ac.Tax.TypeCode),
},
}
}
// Format percentages
if ac.Tax.RateApplicablePercent != "" {
if !strings.HasSuffix(ac.Tax.RateApplicablePercent, "%") {
ac.Tax.RateApplicablePercent += "%"
if ac.Tax != nil {
if ac.Tax.TypeCode != "" {
c.Taxes = tax.Set{
{
Category: cbc.Code(ac.Tax.TypeCode),
},
}
}
p, err := num.PercentageFromString(ac.Tax.RateApplicablePercent)
if err != nil {
return nil, err
// Format percentages
if ac.Tax.RateApplicablePercent != "" {
if !strings.HasSuffix(ac.Tax.RateApplicablePercent, "%") {
ac.Tax.RateApplicablePercent += "%"
}
p, err := num.PercentageFromString(ac.Tax.RateApplicablePercent)
if err != nil {
return nil, err
}
c.Taxes[0].Percent = &p
}
c.Taxes[0].Percent = &p
}
return c, nil
}
Expand Down Expand Up @@ -127,23 +129,26 @@ func newDiscount(ac *document.AllowanceCharge) (*bill.Discount, error) {
}
d.Percent = &p
}
if ac.Tax.TypeCode != "" {
d.Taxes = tax.Set{
{
Category: cbc.Code(ac.Tax.TypeCode),
},
}
}
if ac.Tax.RateApplicablePercent != "" {
if !strings.HasSuffix(ac.Tax.RateApplicablePercent, "%") {
ac.Tax.RateApplicablePercent += "%"
if ac.Tax != nil {
if ac.Tax.TypeCode != "" {
d.Taxes = tax.Set{
{
Category: cbc.Code(ac.Tax.TypeCode),
},
}
}
p, err := num.PercentageFromString(ac.Tax.RateApplicablePercent)
if err != nil {
return nil, err
if ac.Tax.RateApplicablePercent != "" {
if !strings.HasSuffix(ac.Tax.RateApplicablePercent, "%") {
ac.Tax.RateApplicablePercent += "%"
}
p, err := num.PercentageFromString(ac.Tax.RateApplicablePercent)
if err != nil {
return nil, err
}
d.Taxes[0].Percent = &p
}
d.Taxes[0].Percent = &p
}

return d, nil
}

Expand Down
14 changes: 10 additions & 4 deletions internal/ctog/party.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,17 @@ func (c *Converter) getParty(party *document.Party) *org.Party {
for _, taxReg := range party.SpecifiedTaxRegistration {
if taxReg.ID != nil && taxReg.ID.Value != "" {
switch taxReg.ID.SchemeID {
//Source (XML Document) https://ec.europa.eu/digital-building-blocks/sites/download/attachments/467108974/EN16931%20code%20lists%20values%20v13%20-%20used%20from%202024-05-15.xlsx?version=2&modificationDate=1712937109681&api=v2
// Source (XML Document) https://ec.europa.eu/digital-building-blocks/sites/download/attachments/467108974/EN16931%20code%20lists%20values%20v13%20-%20used%20from%202024-05-15.xlsx?version=2&modificationDate=1712937109681&api=v2
case "VA":
p.TaxID = &tax.Identity{
Country: l10n.TaxCountryCode(party.PostalTradeAddress.CountryID),
Code: cbc.Code(taxReg.ID.Value),
// Parse the country code from the vat
if identity, err := tax.ParseIdentity(taxReg.ID.Value); err == nil {
p.TaxID = identity
} else {
// Fallback to preserve the tax id
p.TaxID = &tax.Identity{
Country: l10n.TaxCountryCode(party.PostalTradeAddress.CountryID),
Code: cbc.Code(taxReg.ID.Value),
}
}
case "FC":
identity := &org.Identity{
Expand Down
12 changes: 6 additions & 6 deletions internal/gtoc/charges.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ func newLineAllowanceCharges(line *bill.Line) []*document.AllowanceCharge {
func newCharge(c *bill.Charge) *document.AllowanceCharge {
ac := &document.AllowanceCharge{
ChargeIndicator: document.Indicator{Value: true},
Amount: c.Amount.String(),
Amount: c.Amount.Rescale(2).String(),
}
if c.Reason != "" {
ac.Reason = c.Reason
}
ac.ReasonCode = c.Ext.Get(untdid.ExtKeyCharge).String()
if c.Percent != nil {
p := c.Percent.String()
p := c.Percent.StringWithoutSymbol()
ac.Percent = p
}
if c.Taxes != nil {
Expand All @@ -57,14 +57,14 @@ func newCharge(c *bill.Charge) *document.AllowanceCharge {
func newDiscount(d *bill.Discount) *document.AllowanceCharge {
ac := &document.AllowanceCharge{
ChargeIndicator: document.Indicator{Value: false},
Amount: d.Amount.String(),
Amount: d.Amount.Rescale(2).String(),
}
if d.Reason != "" {
ac.Reason = d.Reason
}
ac.ReasonCode = d.Ext.Get(untdid.ExtKeyAllowance).String()
if d.Percent != nil {
p := d.Percent.String()
p := d.Percent.StringWithoutSymbol()
ac.Percent = p
}
if d.Taxes != nil {
Expand All @@ -76,7 +76,7 @@ func newDiscount(d *bill.Discount) *document.AllowanceCharge {
func makeLineCharge(c *bill.LineCharge) *document.AllowanceCharge {
ac := &document.AllowanceCharge{
ChargeIndicator: document.Indicator{Value: true},
Amount: c.Amount.String(),
Amount: c.Amount.Rescale(2).String(),
}
if c.Reason != "" {
ac.Reason = c.Reason
Expand All @@ -92,7 +92,7 @@ func makeLineCharge(c *bill.LineCharge) *document.AllowanceCharge {
func makeLineDiscount(d *bill.LineDiscount) *document.AllowanceCharge {
ac := &document.AllowanceCharge{
ChargeIndicator: document.Indicator{Value: false},
Amount: d.Amount.String(),
Amount: d.Amount.Rescale(2).String(),
}
if d.Reason != "" {
ac.Reason = d.Reason
Expand Down
4 changes: 2 additions & 2 deletions internal/gtoc/lines.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func newLine(l *bill.Line) *document.Line {
},
Agreement: &document.LineAgreement{
NetPrice: &document.NetPrice{
Amount: it.Price.String(),
Amount: it.Price.Rescale(2).String(),
},
},
Quantity: &document.LineDelivery{
Expand Down Expand Up @@ -90,7 +90,7 @@ func newTradeSettlement(l *bill.Line) *document.TradeSettlement {
stlm := &document.TradeSettlement{
ApplicableTradeTax: taxes,
Sum: &document.Summation{
Amount: l.Total.String(),
Amount: l.Total.Rescale(2).String(),
},
}

Expand Down
53 changes: 40 additions & 13 deletions internal/gtoc/settlement.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,36 @@ func (c *Converter) prepareSettlement(inv *bill.Invoice) error {
}
stlm := c.doc.Transaction.Settlement
if inv.Payment != nil && inv.Payment.Terms != nil {
stlm.PaymentTerms = []*document.Terms{
{
Description: inv.Payment.Terms.Detail,
},
description := inv.Payment.Terms.Detail
if len(inv.Payment.Terms.DueDates) == 0 {
stlm.PaymentTerms = []*document.Terms{
{
Description: description,
},
}
} else {
for _, dueDate := range inv.Payment.Terms.DueDates {
term := &document.Terms{
Description: description,
}

if !dueDate.Amount.Equals(inv.Totals.Payable) {
term.PartialPayment = dueDate.Amount.Rescale(2).String()
}

if dueDate.Date != nil {
term.DueDate = &document.IssueDate{
DateFormat: &document.Date{
Value: formatIssueDate(*dueDate.Date),
Format: issueDateFormat,
},
}
}

stlm.PaymentTerms = append(stlm.PaymentTerms, term)
}
}

}

if inv.Totals != nil {
Expand Down Expand Up @@ -111,7 +136,9 @@ func (c *Converter) prepareSettlement(inv *bill.Invoice) error {
},
}
} else {
stlm.PaymentTerms[0].Mandate = instr.DirectDebit.Ref
for _, term := range stlm.PaymentTerms {
term.Mandate = instr.DirectDebit.Ref
}
}

stlm.CreditorRefID = instr.DirectDebit.Creditor
Expand Down Expand Up @@ -141,22 +168,22 @@ func (c *Converter) prepareSettlement(inv *bill.Invoice) error {

func newSummary(totals *bill.Totals, currency string) *document.Summary {
s := &document.Summary{
TotalAmount: totals.Total.String(),
TaxBasisTotalAmount: totals.Total.String(),
GrandTotalAmount: totals.TotalWithTax.String(),
DuePayableAmount: totals.Payable.String(),
LineTotalAmount: totals.Sum.Rescale(2).String(),
TaxBasisTotalAmount: totals.Total.Rescale(2).String(),
GrandTotalAmount: totals.TotalWithTax.Rescale(2).String(),
DuePayableAmount: totals.Payable.Rescale(2).String(),
TaxTotalAmount: &document.TaxTotalAmount{
Amount: totals.Tax.String(),
Amount: totals.Tax.Rescale(2).String(),
Currency: currency,
},
}

if totals.Charge != nil {
s.Charges = totals.Charge.String()
s.Charges = totals.Charge.Rescale(2).String()
}

if totals.Discount != nil {
s.Discounts = totals.Discount.String()
s.Discounts = totals.Discount.Rescale(2).String()
}

return s
Expand Down Expand Up @@ -186,7 +213,7 @@ func newTax(rate *tax.RateTotal, category *tax.CategoryTotal) *document.Tax {
}

tax := &document.Tax{
CalculatedAmount: rate.Amount.String(),
CalculatedAmount: rate.Amount.Rescale(2).String(),
TypeCode: category.Code.String(),
BasisAmount: rate.Base.String(),
CategoryCode: rate.Ext[untdid.ExtKeyTaxCategory].String(),
Expand Down
4 changes: 3 additions & 1 deletion internal/gtoc/settlement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ func TestNewSettlement(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, "EUR", doc.Transaction.Settlement.Currency)
assert.Equal(t, "lorem ipsum", doc.Transaction.Settlement.PaymentTerms[0].Description)
assert.Equal(t, "1800.00", doc.Transaction.Settlement.Summary.TotalAmount)
assert.Equal(t, "20240227", doc.Transaction.Settlement.PaymentTerms[0].DueDate.DateFormat.Value)
assert.Equal(t, "2000.00", doc.Transaction.Settlement.PaymentTerms[0].PartialPayment)
assert.Equal(t, "1800.00", doc.Transaction.Settlement.Summary.LineTotalAmount)
assert.Equal(t, "1800.00", doc.Transaction.Settlement.Summary.TaxBasisTotalAmount)
assert.Equal(t, "2142.00", doc.Transaction.Settlement.Summary.GrandTotalAmount)
assert.Equal(t, "2142.00", doc.Transaction.Settlement.Summary.DuePayableAmount)
Expand Down
9 changes: 8 additions & 1 deletion test/data/gtoc/invoice-de-de.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,14 @@
},
"payment": {
"terms": {
"detail": "lorem ipsum"
"detail": "lorem ipsum",
"due_dates": [
{
"date": "2024-02-27",
"amount": "2000.00",
"currency": "EUR"
}
]
}
},
"tax": {
Expand Down
3 changes: 3 additions & 0 deletions test/data/gtoc/out/invoice-complete.xml
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@
</ram:CategoryTradeTax>
</ram:SpecifiedTradeAllowanceCharge>
<ram:SpecifiedTradePaymentTerms>
<ram:DueDateDateTime>
<udt:DateTimeString format="102">20130720</udt:DateTimeString>
</ram:DueDateDateTime>
<ram:DirectDebitMandateID>1234567890</ram:DirectDebitMandateID>
</ram:SpecifiedTradePaymentTerms>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
Expand Down
4 changes: 4 additions & 0 deletions test/data/gtoc/out/invoice-de-de.xml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@
</ram:ApplicableTradeTax>
<ram:SpecifiedTradePaymentTerms>
<ram:Description>lorem ipsum</ram:Description>
<ram:DueDateDateTime>
<udt:DateTimeString format="102">20240227</udt:DateTimeString>
</ram:DueDateDateTime>
<ram:PartialPaymentAmount>2000.00</ram:PartialPaymentAmount>
</ram:SpecifiedTradePaymentTerms>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount>1800.00</ram:LineTotalAmount>
Expand Down

0 comments on commit 50fa135

Please sign in to comment.