Files
KanzlAI-mGMT/backend/internal/models/fee.go
m 850f3a62c8 feat: add Patentprozesskostenrechner fee calculation engine + API
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
2026-03-31 17:43:17 +02:00

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"`
}