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
This commit is contained in:
53
backend/internal/handlers/fee_calculator.go
Normal file
53
backend/internal/handlers/fee_calculator.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"mgit.msbls.de/m/KanzlAI-mGMT/internal/models"
|
||||
"mgit.msbls.de/m/KanzlAI-mGMT/internal/services"
|
||||
)
|
||||
|
||||
// FeeCalculatorHandler handles fee calculation API endpoints.
|
||||
type FeeCalculatorHandler struct {
|
||||
calc *services.FeeCalculator
|
||||
}
|
||||
|
||||
func NewFeeCalculatorHandler(calc *services.FeeCalculator) *FeeCalculatorHandler {
|
||||
return &FeeCalculatorHandler{calc: calc}
|
||||
}
|
||||
|
||||
// Calculate handles POST /api/fees/calculate.
|
||||
func (h *FeeCalculatorHandler) Calculate(w http.ResponseWriter, r *http.Request) {
|
||||
var req models.FeeCalculateRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeError(w, http.StatusBadRequest, "invalid request body")
|
||||
return
|
||||
}
|
||||
|
||||
if req.Streitwert <= 0 {
|
||||
writeError(w, http.StatusBadRequest, "streitwert must be positive")
|
||||
return
|
||||
}
|
||||
if req.VATRate < 0 || req.VATRate > 1 {
|
||||
writeError(w, http.StatusBadRequest, "vat_rate must be between 0 and 1")
|
||||
return
|
||||
}
|
||||
if len(req.Instances) == 0 {
|
||||
writeError(w, http.StatusBadRequest, "at least one instance is required")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := h.calc.CalculateFullLitigation(req)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, resp)
|
||||
}
|
||||
|
||||
// Schedules handles GET /api/fees/schedules.
|
||||
func (h *FeeCalculatorHandler) Schedules(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, http.StatusOK, h.calc.GetSchedules())
|
||||
}
|
||||
Reference in New Issue
Block a user