57 lines
1.5 KiB
Go
57 lines
1.5 KiB
Go
package tax
|
|
|
|
// nordicStandardRates maps country code -> default standard VAT rate in basis
|
|
// points of a percent (2500 = 25%).
|
|
var nordicStandardRates = map[string]int{
|
|
"SE": 2500,
|
|
"NO": 2500,
|
|
"DK": 2500,
|
|
"FI": 2550, // 25.5% as of 2024 — exact in basis points, no truncation
|
|
}
|
|
|
|
// Nordic implements Provider for the Nordic countries (SE, NO, DK, FI).
|
|
// It encodes the standard statutory VAT rates (basis points):
|
|
//
|
|
// SE: 25 % (2500)
|
|
// NO: 25 % (2500)
|
|
// DK: 25 % (2500)
|
|
// FI: 25.5 % (2550)
|
|
//
|
|
// Rates are integer basis points, so fractional rates (FI 25.5) are represented
|
|
// exactly — no float, no truncation.
|
|
//
|
|
// Nordic does not make network calls — all logic is local math. An external
|
|
// provider (Avalara, TaxJar) can be added by implementing Provider and
|
|
// switching on TAX_PROVIDER.
|
|
type Nordic struct {
|
|
defaultCountry string
|
|
}
|
|
|
|
// NewNordic returns a Nordic provider. defaultCountry is used when
|
|
// DefaultTaxRate is called with an empty country code; it defaults to "SE"
|
|
// if empty.
|
|
func NewNordic(defaultCountry string) *Nordic {
|
|
if defaultCountry == "" {
|
|
defaultCountry = "SE"
|
|
}
|
|
return &Nordic{defaultCountry: defaultCountry}
|
|
}
|
|
|
|
var _ Provider = (*Nordic)(nil)
|
|
|
|
func (p *Nordic) Name() string { return "nordic" }
|
|
|
|
func (p *Nordic) Compute(total int64, taxRate int) int64 {
|
|
return Compute(total, taxRate)
|
|
}
|
|
|
|
func (p *Nordic) DefaultTaxRate(country string) int {
|
|
if country == "" {
|
|
country = p.defaultCountry
|
|
}
|
|
if rate, ok := nordicStandardRates[country]; ok {
|
|
return rate
|
|
}
|
|
return nordicStandardRates[p.defaultCountry]
|
|
}
|