Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- `cbc.CodeMap`: added `Lookup` method that returns the code matching a given key, falling back hierarchically to less specific keys.
- `pay`: added `MeansKeyCredit` and `MeansKeyDebit` qualifiers, enabling the `card+credit` and `card+debit` payment means. Adapted all addons mapping payment means to extensions to use the two new qualified means.
- `es-tbai-v1`: added `es-tbai-bi-activity` extension for the Bizkaia activity code (epígrafe) required for individual suppliers.
- `pt-saft-v1`: added rule to check that advance payment amounts on invoices are no less than 0 as required by the SAF-T spec.

## [v0.402.0] - 2026-04-30

Expand Down
3 changes: 3 additions & 0 deletions addons/pt/saft/invoices.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ func billInvoiceRules() *rules.Set {
rules.Field("date",
rules.Assert("08", "cannot be blank", is.Present),
),
rules.Field("amount",
rules.Assert("16", "must be no less than 0", num.ZeroOrPositive),
),
),
),
),
Expand Down
14 changes: 14 additions & 0 deletions addons/pt/saft/invoices_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,20 @@ func TestInvoicePaymentValidation(t *testing.T) {
assert.ErrorContains(t, rules.Validate(inv), "cannot be blank")
})

t.Run("advance with negative amount", func(t *testing.T) {
d := cal.NewDate(2024, 1, 1)
inv := calculatedInvoice(t)
inv.Payment = &bill.PaymentDetails{
Advances: []*pay.Record{
{
Date: d,
Amount: num.MakeAmount(-50, 0),
},
},
}
assert.ErrorContains(t, rules.Validate(inv), "must be no less than 0")
})

t.Run("nil advance", func(t *testing.T) {
inv := calculatedInvoice(t)
inv.Payment = &bill.PaymentDetails{
Expand Down
10 changes: 10 additions & 0 deletions data/rules/pt-saft.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@
"tests": "present"
}
]
},
{
"field": "amount",
"assert": [
{
"id": "GOBL-PT-SAFT-BILL-INVOICE-16",
"desc": "must be no less than 0",
"tests": "min 0"
}
]
}
]
}
Expand Down
Loading