Files
paliad/internal/calc/fee_tables.go
m 2f44461275 fix(t-paliad-114): EPA Beschwerdegebühr 2.255€ → 2.925€ (2024-04-01 EPO restructure)
Standard appeal fee per Rule 6 EPC-Gebühren v2024-04-01 was raised from
2.255€ to 2.925€; reduced fee per Rule 7a(2)(a-d) was raised from 1.880€
to 2.015€. Both stale in calc.EPAFees, surfaced wrong amount on
/tools/kostenrechner and /tools/gebuehrentabellen EPA tab.

Reduced-fee tier is updated for data accuracy; UI surfacing of that tier
is deferred per m's call (out of scope for this task).
2026-05-04 16:57:58 +02:00

327 lines
8.3 KiB
Go

package calc
import "math"
// FeeBracket defines one bracket in a fee schedule.
// [upperBound, stepSize, gkgIncrement, rvgIncrement]
type FeeBracket struct {
UpperBound float64
StepSize float64
GKGIncrement float64
RVGIncrement float64
}
// FeeSchedule defines a versioned fee schedule.
type FeeSchedule struct {
Label string
ValidFrom string
Brackets []FeeBracket
}
// InstanceMeta defines the fee factors for a court instance.
type InstanceMeta struct {
Key string
Label string
LabelEN string
CourtFeeFactor float64
FeeBasis string // "GKG", "PatKostG", "fixed"
FixedCourtFee float64
RAVGFactor float64
RATGFactor float64
PAVGFactor float64
PATGFactor float64
HasPatentAttorneys bool
}
// UPCFeeBracket maps a max dispute value to a court fee.
type UPCFeeBracket struct {
MaxValue *float64 // nil = unlimited
Fee float64
}
// UPCRecoverableCost maps a max dispute value to a recoverable cost ceiling.
type UPCRecoverableCost struct {
MaxValue *float64 // nil = unlimited
Ceiling float64
}
// UPCFeeSchedule defines UPC court fees for a version.
type UPCFeeSchedule struct {
Label string
FixedInfringement float64
FixedRevocation float64
ValueBased []UPCFeeBracket
RecoverableCosts []UPCRecoverableCost
SMEReduction float64 // 0.4 = 40% reduction
}
// EPAFee defines a fixed EPA proceeding fee.
type EPAFee struct {
Key string
Label string
LabelEN string
Fee float64
SMEFee float64 // 0 if no SME discount
}
// FeeSchedules contains all GKG/RVG bracket tables by version.
var FeeSchedules = map[string]FeeSchedule{
"2005": {
Label: "GKG/RVG 2006-09-01",
ValidFrom: "2006-09-01",
Brackets: []FeeBracket{
{300, 300, 25, 25},
{1500, 300, 10, 20},
{5000, 500, 8, 28},
{10000, 1000, 15, 37},
{25000, 3000, 23, 40},
{50000, 5000, 29, 72},
{200000, 15000, 100, 77},
{500000, 30000, 150, 118},
{math.Inf(1), 50000, 150, 150},
},
},
"2013": {
Label: "GKG/RVG 2013-08-01",
ValidFrom: "2013-08-01",
Brackets: []FeeBracket{
{500, 300, 35, 45},
{2000, 500, 18, 35},
{10000, 1000, 19, 51},
{25000, 3000, 26, 46},
{50000, 5000, 35, 75},
{200000, 15000, 120, 85},
{500000, 30000, 179, 120},
{math.Inf(1), 50000, 180, 150},
},
},
"2021": {
Label: "GKG/RVG 2021-01-01",
ValidFrom: "2021-01-01",
Brackets: []FeeBracket{
{500, 300, 38, 49},
{2000, 500, 20, 39},
{10000, 1000, 21, 56},
{25000, 3000, 29, 52},
{50000, 5000, 38, 81},
{200000, 15000, 132, 94},
{500000, 30000, 198, 132},
{math.Inf(1), 50000, 198, 165},
},
},
"2025": {
Label: "GKG/RVG 2025-06-01",
ValidFrom: "2025-06-01",
Brackets: []FeeBracket{
{500, 300, 40, 51.5},
{2000, 500, 21, 41.5},
{10000, 1000, 22.5, 59.5},
{25000, 3000, 30.5, 55},
{50000, 5000, 40.5, 86},
{200000, 15000, 140, 99.5},
{500000, 30000, 210, 140},
{math.Inf(1), 50000, 210, 175},
},
},
}
// FeeScheduleAliases maps alias names to actual schedule versions.
var FeeScheduleAliases = map[string]string{
"Aktuell": "2025",
}
// DEInfringementInstances lists the court instances for DE patent infringement.
var DEInfringementInstances = []InstanceMeta{
{
Key: "LG",
Label: "LG (Verletzung 1. Instanz)",
LabelEN: "Regional Court (Infringement 1st Instance)",
CourtFeeFactor: 3.0,
FeeBasis: "GKG",
RAVGFactor: 1.3,
RATGFactor: 1.2,
PAVGFactor: 1.3,
PATGFactor: 1.2,
HasPatentAttorneys: true,
},
{
Key: "OLG",
Label: "OLG (Berufung)",
LabelEN: "Higher Regional Court (Appeal)",
CourtFeeFactor: 4.0,
FeeBasis: "GKG",
RAVGFactor: 1.6,
RATGFactor: 1.2,
PAVGFactor: 1.6,
PATGFactor: 1.2,
HasPatentAttorneys: true,
},
{
Key: "BGH_NZB",
Label: "BGH (Nichtzulassungsbeschwerde)",
LabelEN: "Federal Court of Justice (Leave to Appeal)",
CourtFeeFactor: 2.0,
FeeBasis: "GKG",
RAVGFactor: 2.3,
RATGFactor: 1.2,
PAVGFactor: 1.6,
PATGFactor: 1.2,
HasPatentAttorneys: true,
},
{
Key: "BGH_REV",
Label: "BGH (Revision)",
LabelEN: "Federal Court of Justice (Revision)",
CourtFeeFactor: 5.0,
FeeBasis: "GKG",
RAVGFactor: 2.3,
RATGFactor: 1.5,
PAVGFactor: 1.6,
PATGFactor: 1.5,
HasPatentAttorneys: true,
},
}
// DENullityInstances lists the court instances for DE patent nullity.
var DENullityInstances = []InstanceMeta{
{
Key: "BPatG",
Label: "BPatG (Nichtigkeitsverfahren)",
LabelEN: "Federal Patent Court (Nullity)",
CourtFeeFactor: 4.5,
FeeBasis: "PatKostG",
RAVGFactor: 1.3,
RATGFactor: 1.2,
PAVGFactor: 1.3,
PATGFactor: 1.2,
HasPatentAttorneys: true,
},
{
Key: "BGH_NULLITY",
Label: "BGH (Nichtigkeitsberufung)",
LabelEN: "Federal Court of Justice (Nullity Appeal)",
CourtFeeFactor: 6.0,
FeeBasis: "GKG",
RAVGFactor: 1.6,
RATGFactor: 1.5,
PAVGFactor: 1.6,
PATGFactor: 1.5,
HasPatentAttorneys: true,
},
}
// AllDEInstances returns all DE instance metadata in order.
func AllDEInstances() []InstanceMeta {
all := make([]InstanceMeta, 0, len(DEInfringementInstances)+len(DENullityInstances))
all = append(all, DEInfringementInstances...)
all = append(all, DENullityInstances...)
return all
}
// UPCFeeSchedules contains UPC court fee data by version.
var UPCFeeSchedules = map[string]UPCFeeSchedule{
"pre2026": {
Label: "UPC (vor 2026)",
FixedInfringement: 11000,
FixedRevocation: 20000,
ValueBased: []UPCFeeBracket{
{ptr(500000), 0},
{ptr(750000), 2500},
{ptr(1000000), 4000},
{ptr(1500000), 8000},
{ptr(2000000), 13000},
{ptr(3000000), 20000},
{ptr(4000000), 26000},
{ptr(5000000), 32000},
{ptr(6000000), 39000},
{ptr(7000000), 46000},
{ptr(8000000), 52000},
{ptr(9000000), 58000},
{ptr(10000000), 65000},
{ptr(15000000), 75000},
{ptr(20000000), 100000},
{ptr(25000000), 125000},
{ptr(30000000), 150000},
{ptr(50000000), 250000},
{nil, 325000},
},
RecoverableCosts: []UPCRecoverableCost{
{ptr(250000), 38000},
{ptr(500000), 56000},
{ptr(1000000), 112000},
{ptr(2000000), 200000},
{ptr(4000000), 400000},
{ptr(8000000), 600000},
{ptr(16000000), 800000},
{ptr(30000000), 1200000},
{ptr(50000000), 1500000},
{nil, 2000000},
},
SMEReduction: 0.4,
},
"2026": {
Label: "UPC (ab 2026)",
FixedInfringement: 14600,
FixedRevocation: 26500,
ValueBased: []UPCFeeBracket{
{ptr(500000), 0},
{ptr(750000), 3300},
{ptr(1000000), 5300},
{ptr(1500000), 10600},
{ptr(2000000), 17200},
{ptr(3000000), 26400},
{ptr(4000000), 34300},
{ptr(5000000), 42200},
{ptr(6000000), 51500},
{ptr(7000000), 60700},
{ptr(8000000), 68600},
{ptr(9000000), 76600},
{ptr(10000000), 85800},
{ptr(15000000), 99000},
{ptr(20000000), 132000},
{ptr(25000000), 165000},
{ptr(30000000), 198000},
{ptr(50000000), 330000},
{nil, 429000},
},
RecoverableCosts: []UPCRecoverableCost{
{ptr(250000), 38000},
{ptr(500000), 56000},
{ptr(1000000), 112000},
{ptr(2000000), 200000},
{ptr(4000000), 400000},
{ptr(8000000), 600000},
{ptr(16000000), 800000},
{ptr(30000000), 1200000},
{ptr(50000000), 1500000},
{nil, 2000000},
},
SMEReduction: 0.5,
},
}
// EPAFees contains fixed fees for EPA proceedings.
var EPAFees = map[string]EPAFee{
"EPA_OPPOSITION": {
Key: "EPA_OPPOSITION",
Label: "Einspruch",
LabelEN: "Opposition",
Fee: 880,
SMEFee: 880,
},
// EPO appeal fee per Rule 6 EPC-Gebühren, version 2024-04-01. Standard fee
// only; reduced fee for natural persons / SMEs (Rule 7a(2)(a-d)) is 2.015€ —
// surface that separately if/when m signals.
"EPA_APPEAL": {
Key: "EPA_APPEAL",
Label: "Einspruchsbeschwerde",
LabelEN: "Appeal from Opposition",
Fee: 2925,
SMEFee: 2015,
},
}
func ptr(v float64) *float64 {
return &v
}