Skip to content

Commit

Permalink
Setup basic fields for credit note
Browse files Browse the repository at this point in the history
We want to be able to correct invoices send into the KSeF API.
To correct the invoices we need to prepare a credit note.
There are a few differences between a regular VAT invoice and
a polish credit note. The first is the InvoiceType that changes
from VAT to KOR. The second is a CorrectionType it is used to
define when the correction should take legal effect, with values
1-3 meaning:
1 - Changes take effect in the date of the invoice. This is mostly used
if you made a mistake in the original invoice.
2 - Changes take effect in the date of the correction. This is used for
example when giving a discount or returning items.
3 - Changes take effect in a different date than any of the invoices or
the date is different for different elements.
There is also a optional field CorrectionReason where you can give a reason
for the correction.
The last element is data of the Invoice you are correcting. You need to give
the SequentialNumber and IssueDate of the original invoice. If the invoice
has a KSeF number you need to provide it and set the KsefNumberPresent flag
to 1. If the original invoice didn't have a KSeF number you need to set the
NoKsefNumberPresent flag to 1.
  • Loading branch information
noplisu committed Feb 12, 2024
1 parent 3150a4b commit 69bf1ba
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions invoice.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ksef
/**/
import (
"github.com/invopop/gobl/bill"
"github.com/invopop/gobl/head"
"github.com/invopop/gobl/regimes/pl"
"github.com/invopop/gobl/tax"
)
Expand Down Expand Up @@ -41,10 +42,21 @@ type Inv struct {
TotalAmountReceivable string `xml:"P_15"`
Annotations *Annotations `xml:"Adnotacje"`
InvoiceType string `xml:"RodzajFaktury"`
CorrectionReason string `xml:"PrzyczynaKorekty,omitempty"`
CorrectionType int `xml:"TypKorekty,omitempty"`
CorrectedFa *CorrectedFa `xml:"DaneFaKorygowanej,omitempty"`
Lines []*Line `xml:"FaWiersz"`
Payment *Payment `xml:"Platnosc"`
}

type CorrectedFa struct {
IssueDate string `xml:"DataWystFaKorygowanej,omitempty"`
SequentialNumber string `xml:"NrFaKorygowanej,omitempty"`
KsefNumberPresent int `xml:"NrKSeF,omitempty"`
NoKsefNumberPresent int `xml:"NrKSeFN,omitempty"`
KsefNumber string `xml:"NrKSeFFaKorygowanej,omitempty"`
}

// Annotations defines the XML structure for KSeF annotations
type Annotations struct {
CashAccounting int `xml:"P_16"`
Expand Down Expand Up @@ -86,6 +98,13 @@ func NewInv(inv *bill.Invoice) *Inv {
TotalAmountReceivable: inv.Totals.Payable.Rescale(cu).String(),
Lines: NewLines(inv.Lines),
Payment: NewPayment(inv.Payment, inv.Totals),
CorrectionReason: inv.Preceding[0].Reason,
// CorrectionType defines when the correction should have legal consequences
// 1 - in the date of the original invoice
// 2 - in the date of the correction invoice
// 3 - other date or the dates are different for different position on the invoice
CorrectionType: 2,
CorrectedFa: NewCorrectedFa(inv.Preceding[0]),
}

ss := inv.ScenarioSummary()
Expand Down Expand Up @@ -116,3 +135,28 @@ func NewInv(inv *bill.Invoice) *Inv {

return Inv
}

func NewCorrectedFa(prc *bill.Preceding) *CorrectedFa {
fa := &CorrectedFa{
IssueDate: prc.IssueDate.String(),
SequentialNumber: prc.Series + prc.Code,
}

if id := findStamp(prc.Stamps, "KSEF"); id != -1 {
fa.KsefNumberPresent = 1
fa.KsefNumber = prc.Stamps[id].Value
} else {
fa.NoKsefNumberPresent = 1
}

return fa
}

func findStamp(a []*head.Stamp, x string) int {
for i, n := range a {
if x == string(n.Provider) {
return i
}
}
return -1
}

0 comments on commit 69bf1ba

Please sign in to comment.