Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds support for exporting selected GOBL invoice notes into the KSeF FA(3) XML footer (Stopka) by introducing a dedicated note source key and mapping logic during invoice build.
Changes:
- Introduces
NoteSourceFooterand maps matching invoice notes toStopka/Informacje/StopkaFaktury. - Extends the root
InvoiceXML model to include an optionalStopkaelement and populates it inBuildFavat. - Prevents footer-sourced notes from also being exported as
Fa/DodatkowyOpis.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| ksef.go | Adds a footer note source constant and includes Stopka in the root invoice XML plus wiring in BuildFavat. |
| invoice.go | Defines Stopka XML structs, implements NewFavatFooter, and skips footer notes from AdditionalDescription. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
invoice.go:186
Stopka/Informacjeis limited to maxOccurs=3 in the FA(3) schema (docs/ksef-docs-en/schema/FA3.xsd:3740), but this loop appends one entry per matching note without enforcing the limit. This can generate XML that fails schema validation when more than 3 footer notes are present.
var informacje []*StopkaInformacje
for _, note := range inv.Notes {
if note.Src == NoteSourceFooter {
informacje = append(informacje, &StopkaInformacje{StopkaFaktury: note.Text})
}
invoice.go:259
- New behavior is introduced here (skipping
NoteSourceFooternotes fromDodatkowyOpisand mapping them intoStopkaviaNewFavatFooter), but there is no test asserting the generated XML/struct output. Sinceinvoice_test.goalready has coverage for notes →AdditionalDescription, please add a test case for footer notes (including the max 3 entries constraint).
if len(invoice.Notes) > 0 {
for _, note := range invoice.Notes {
if note.Src == NoteSourceFooter {
continue
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (2)
ksef.go:40
- Stopka is now produced in GOBL → KSeF (Footer field + NewFavatFooter), but KSeF → GOBL conversion ignores it (ToGOBL only parses AdditionalDescription notes). This breaks round-tripping for footer content generated by this library; consider parsing Stopka/Informacje/StopkaFaktury back into invoice notes (e.g., code/key "footer") during ToGOBL.
Seller *Seller `xml:"Podmiot1"`
Buyer *Buyer `xml:"Podmiot2"`
ThirdParties []*ThirdParty `xml:"Podmiot3,omitempty"` // third party (up to 100)
Inv *Inv `xml:"Fa"`
Footer *Stopka `xml:"Stopka,omitempty"`
}
invoice.go:192
- New footer behavior (mapping notes into Stopka and excluding them from AdditionalDescription) isn’t covered by tests. There are existing tests for note → AdditionalDescription behavior in invoice_test.go; add a test that creates an invoice with a "footer" note and asserts it appears under Stopka (and not in AdditionalDescription).
// NewFavatFooter builds a Stopka from GOBL invoice notes with src == NoteSourceFooter.
func NewFavatFooter(inv *bill.Invoice) *Stopka {
var informacje []*StopkaInformacje
for _, note := range inv.Notes {
if note.Src == NoteSourceFooter {
informacje = append(informacje, &StopkaInformacje{StopkaFaktury: note.Text})
}
}
if len(informacje) == 0 {
return nil
}
return &Stopka{Informacje: informacje}
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
invoice.go:187
- FA(3) schema limits
Stopka/InformacjetomaxOccurs=3(seetest/data/schema/FA3.xsd:3740).NewFavatFootercurrently appends one<Informacje>per footer note without enforcing this limit, which can generate schema-invalid XML when more than 3 footer notes are present.
func NewFavatFooter(inv *bill.Invoice) *Stopka {
var informacje []*StopkaInformacje
for _, note := range inv.Notes {
if note.Src == NoteSourceFooter {
informacje = append(informacje, &StopkaInformacje{StopkaFaktury: note.Text})
}
}
No description provided.