Pure Go implementation of patent litigation cost calculator with: - Step-based GKG/RVG fee accumulator across 4 historical schedules (2005/2013/2021/2025 + Aktuell alias) - Instance multiplier tables for 8 court types (LG, OLG, BGH NZB/Rev, BPatG, BGH Null, DPMA, BPatG Canc) - Full attorney fee calculation (VG, TG, Erhöhungsgebühr Nr. 1008 VV RVG, Auslagenpauschale) - Prozesskostensicherheit computation - UPC fee data (pre-2026 and 2026 schedules with value-based brackets, recoverable costs ceilings) - Public API: POST /api/fees/calculate, GET /api/fees/schedules (no auth required) - 22 unit tests covering all calculation paths Fixes 3 Excel bugs: - Bug 1: Prozesskostensicherheit VAT formula (subtract → add) - Bug 2: Security for costs uses GKG base for court fee, not RVG - Bug 3: Expert fees included in BPatG instance total
126 lines
4.7 KiB
Go
126 lines
4.7 KiB
Go
package models
|
|
|
|
// FeeScheduleVersion identifies a fee schedule version.
|
|
type FeeScheduleVersion string
|
|
|
|
const (
|
|
FeeVersion2005 FeeScheduleVersion = "2005"
|
|
FeeVersion2013 FeeScheduleVersion = "2013"
|
|
FeeVersion2021 FeeScheduleVersion = "2021"
|
|
FeeVersion2025 FeeScheduleVersion = "2025"
|
|
FeeVersionAktuell FeeScheduleVersion = "Aktuell"
|
|
)
|
|
|
|
// InstanceType identifies a court instance.
|
|
type InstanceType string
|
|
|
|
const (
|
|
InstanceLG InstanceType = "LG"
|
|
InstanceOLG InstanceType = "OLG"
|
|
InstanceBGHNZB InstanceType = "BGH_NZB"
|
|
InstanceBGHRev InstanceType = "BGH_Rev"
|
|
InstanceBPatG InstanceType = "BPatG"
|
|
InstanceBGHNull InstanceType = "BGH_Null"
|
|
InstanceDPMA InstanceType = "DPMA"
|
|
InstanceBPatGCanc InstanceType = "BPatG_Canc"
|
|
)
|
|
|
|
// ProceedingPath identifies the type of patent litigation proceeding.
|
|
type ProceedingPath string
|
|
|
|
const (
|
|
PathInfringement ProceedingPath = "infringement"
|
|
PathNullity ProceedingPath = "nullity"
|
|
PathCancellation ProceedingPath = "cancellation"
|
|
)
|
|
|
|
// --- Request ---
|
|
|
|
// FeeCalculateRequest is the request body for POST /api/fees/calculate.
|
|
type FeeCalculateRequest struct {
|
|
Streitwert float64 `json:"streitwert"`
|
|
VATRate float64 `json:"vat_rate"`
|
|
ProceedingPath ProceedingPath `json:"proceeding_path"`
|
|
Instances []InstanceInput `json:"instances"`
|
|
IncludeSecurityCosts bool `json:"include_security_costs"`
|
|
}
|
|
|
|
// InstanceInput configures one court instance in the calculation request.
|
|
type InstanceInput struct {
|
|
Type InstanceType `json:"type"`
|
|
Enabled bool `json:"enabled"`
|
|
FeeVersion FeeScheduleVersion `json:"fee_version"`
|
|
NumAttorneys int `json:"num_attorneys"`
|
|
NumPatentAttorneys int `json:"num_patent_attorneys"`
|
|
NumClients int `json:"num_clients"`
|
|
OralHearing bool `json:"oral_hearing"`
|
|
ExpertFees float64 `json:"expert_fees"`
|
|
}
|
|
|
|
// --- Response ---
|
|
|
|
// FeeCalculateResponse is the response for POST /api/fees/calculate.
|
|
type FeeCalculateResponse struct {
|
|
Instances []InstanceResult `json:"instances"`
|
|
Totals []FeeTotal `json:"totals"`
|
|
SecurityForCosts *SecurityForCosts `json:"security_for_costs,omitempty"`
|
|
}
|
|
|
|
// InstanceResult contains the cost breakdown for one court instance.
|
|
type InstanceResult struct {
|
|
Type InstanceType `json:"type"`
|
|
Label string `json:"label"`
|
|
CourtFeeBase float64 `json:"court_fee_base"`
|
|
CourtFeeMultiplier float64 `json:"court_fee_multiplier"`
|
|
CourtFeeSource string `json:"court_fee_source"`
|
|
CourtFee float64 `json:"court_fee"`
|
|
ExpertFees float64 `json:"expert_fees"`
|
|
CourtSubtotal float64 `json:"court_subtotal"`
|
|
AttorneyBreakdown *AttorneyBreakdown `json:"attorney_breakdown,omitempty"`
|
|
PatentAttorneyBreakdown *AttorneyBreakdown `json:"patent_attorney_breakdown,omitempty"`
|
|
AttorneySubtotal float64 `json:"attorney_subtotal"`
|
|
PatentAttorneySubtotal float64 `json:"patent_attorney_subtotal"`
|
|
InstanceTotal float64 `json:"instance_total"`
|
|
}
|
|
|
|
// AttorneyBreakdown details the fee computation for one attorney type.
|
|
type AttorneyBreakdown struct {
|
|
BaseFee float64 `json:"base_fee"`
|
|
VGFactor float64 `json:"vg_factor"`
|
|
VGFee float64 `json:"vg_fee"`
|
|
IncreaseFee float64 `json:"increase_fee"`
|
|
TGFactor float64 `json:"tg_factor"`
|
|
TGFee float64 `json:"tg_fee"`
|
|
Pauschale float64 `json:"pauschale"`
|
|
SubtotalNet float64 `json:"subtotal_net"`
|
|
VAT float64 `json:"vat"`
|
|
SubtotalGross float64 `json:"subtotal_gross"`
|
|
Count int `json:"count"`
|
|
TotalGross float64 `json:"total_gross"`
|
|
}
|
|
|
|
// FeeTotal is a labeled total amount.
|
|
type FeeTotal struct {
|
|
Label string `json:"label"`
|
|
Total float64 `json:"total"`
|
|
}
|
|
|
|
// SecurityForCosts is the Prozesskostensicherheit calculation result.
|
|
type SecurityForCosts struct {
|
|
Instance1 float64 `json:"instance_1"`
|
|
Instance2 float64 `json:"instance_2"`
|
|
NZB float64 `json:"nzb"`
|
|
SubtotalNet float64 `json:"subtotal_net"`
|
|
VAT float64 `json:"vat"`
|
|
TotalGross float64 `json:"total_gross"`
|
|
}
|
|
|
|
// FeeScheduleInfo describes a fee schedule version for the schedules endpoint.
|
|
type FeeScheduleInfo struct {
|
|
Key string `json:"key"`
|
|
Label string `json:"label"`
|
|
ValidFrom string `json:"valid_from"`
|
|
IsAlias bool `json:"is_alias,omitempty"`
|
|
AliasOf string `json:"alias_of,omitempty"`
|
|
}
|