Files
KanzlAI-mGMT/docs/kostenrechner-plan.md
m 7c70649494 docs: add Patentprozesskostenrechner implementation plan
Comprehensive analysis of the Excel-based patent litigation cost calculator
with implementation plan for the web version:

- Fee calculation logic (GKG/RVG step-based accumulator, all multipliers)
- Exact fee schedule data for all 5 versions (extracted from Excel)
- UPC fee structure research (fixed fees, value-based brackets, recoverable costs)
- Architecture: new page at /kosten/rechner within KanzlAI-mGMT (pure frontend)
- Complete input/output specifications
- 3 bugs to fix from the Excel (VAT formula, wrong fee type, missing expert fees)
- Side-by-side DE vs UPC cost comparison data
2026-03-31 17:28:39 +02:00

20 KiB
Raw Blame History

Patentprozesskostenrechner — Implementation Plan

Date: 2026-03-31 Source: Analysis of Patentprozesskostenrechner.xlsm (c) 2021 M. Siebels Status: Research complete, ready for implementation


1. Fee Calculation Logic Summary

The calculator computes costs for German patent litigation using two fee systems:

GKG (Gerichtskostengesetz) — Court Fees

A step-based accumulator. The Streitwert is divided into brackets, each with a step size and per-step increment. The algorithm:

  1. Start with the minimum fee (first row of the fee table)
  2. For each bracket: compute steps = ceil(portion_in_bracket / step_size)
  3. Accumulate: fee += steps * increment
  4. Result = "einfache Gebühr" (1.0x base fee)
  5. Multiply by the instance-specific factor (e.g., 3.0x for LG, 4.0x for OLG)

For Streitwert > EUR 500,000 (post-2025 schedule): base = 4,138 + ceil((Streitwert - 500,000) / 50,000) * 210

RVG (Rechtsanwaltsvergütungsgesetz) — Attorney Fees

Same step-based lookup but with its own column in the fee table. Per attorney, the formula is:

attorney_cost = (VG_factor * base_RVG + increase_fee + TG_factor * base_RVG + Pauschale) * (1 + VAT)

Where:

  • VG = Verfahrensgebühr (procedural fee): 1.3x (LG/BPatG), 1.6x (OLG/BGH nullity), 2.3x (BGH NZB/Rev for RA)
  • TG = Terminsgebühr (hearing fee): 1.2x or 1.5x (BGH), only if hearing held
  • Increase fee (Nr. 1008 VV RVG): MIN((clients - 1) * 0.3, 2.0) * base_RVG for multiple clients
  • Pauschale = EUR 20 (Auslagenpauschale Nr. 7002 VV RVG)

PatKostG — Patent Court Fees

BPatG nullity uses PatKostG instead of GKG for court fees (but same step-based lookup from the same table). DPMA/BPatG cancellation uses fixed fees (EUR 300 / EUR 500).

Instance Multipliers (Complete Reference)

Instance Court Fee Factor Source Fee Basis
LG (infringement 1st) 3.0x GKG Nr. 1210 Anl. 1 GKG GKG
OLG (infringement appeal) 4.0x GKG Nr. 1420 KV GKG GKG
BGH NZB (leave to appeal) 2.0x GKG Nr. 1242 KV GKG GKG
BGH Revision 5.0x GKG Nr. 1230 KV GKG GKG
BPatG (nullity 1st) 4.5x Nr. 402 100 Anl. PatKostG PatKostG
BGH (nullity appeal) 6.0x GKG Nr. 1250 KV GKG GKG
DPMA (cancellation) EUR 300 flat Nr. 323 100 Anl. PatKostG Fixed
BPatG (cancellation appeal) EUR 500 flat Nr. 401 100 Anl. PatKostG Fixed
Instance RA VG Factor RA TG Factor PA VG Factor PA TG Factor
LG 1.3x 1.2x 1.3x 1.2x
OLG 1.6x 1.2x 1.6x 1.2x
BGH NZB 2.3x 1.2x 1.6x 1.2x
BGH Revision 2.3x 1.5x 1.6x 1.5x
BPatG (nullity) 1.3x 1.2x 1.3x 1.2x
BGH (nullity appeal) 1.6x 1.5x 1.6x 1.5x
DPMA 1.3x 1.2x
BPatG (cancellation) 1.3x 1.2x

2. Fee Schedule Data (JSON)

Five historical versions of the fee table. Each row: [upperBound, stepSize, gkgIncrement, rvgIncrement].

Each row: [upperBound, stepSize, gkgIncrement, rvgIncrement]. Values extracted directly from the Excel ListObjects. Note: increments are decimal (e.g., 51.5 EUR per step). The last bracket uses a very large upper bound (effectively infinity).

{
  "feeSchedules": {
    "2005": {
      "label": "GKG/RVG 2006-09-01",
      "validFrom": "2006-09-01",
      "brackets": [
        [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],
        [Infinity, 50000, 150, 150]
      ]
    },
    "2013": {
      "label": "GKG/RVG 2013-08-01",
      "validFrom": "2013-08-01",
      "brackets": [
        [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],
        [Infinity, 50000, 180, 150]
      ]
    },
    "2021": {
      "label": "GKG/RVG 2021-01-01",
      "validFrom": "2021-01-01",
      "brackets": [
        [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],
        [Infinity, 50000, 198, 165]
      ]
    },
    "2025": {
      "label": "GKG/RVG 2025-06-01",
      "validFrom": "2025-06-01",
      "brackets": [
        [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],
        [Infinity, 50000, 210, 175]
      ]
    },
    "Aktuell": {
      "label": "Aktuell (= 2025-06-01)",
      "validFrom": "2025-06-01",
      "aliasOf": "2025"
    }
  },
  "constants": {
    "erhoehungsfaktor": 0.3,
    "erhoehungsfaktorMax": 2.0,
    "auslagenpauschale": 20
  }
}

Notes on the data:

  • The 2005 version has 9 brackets (starts at 300, not 500). Older versions differ more than expected.
  • Increments are not integers in the 2025 version (e.g., 51.5, 41.5, 59.5) — the implementation must handle decimal arithmetic.
  • The last bracket upper bound is 1e+20 in the Excel (effectively infinity). Use Infinity in TypeScript or a sentinel value.
  • "Aktuell" is currently identical to "2025" — implement as an alias that can diverge when fees are next updated.

UPC Fee Data (New — Not in Excel)

{
  "upcFees": {
    "pre2026": {
      "label": "UPC (vor 2026)",
      "validFrom": "2023-06-01",
      "fixedFees": {
        "infringement": 11000,
        "counterclaim_infringement": 11000,
        "non_infringement": 11000,
        "license_compensation": 11000,
        "determine_damages": 3000,
        "revocation_standalone": 20000,
        "counterclaim_revocation": 20000,
        "provisional_measures": 11000
      },
      "valueBased": [
        { "maxValue": 500000, "fee": 0 },
        { "maxValue": 750000, "fee": 2500 },
        { "maxValue": 1000000, "fee": 4000 },
        { "maxValue": 1500000, "fee": 8000 },
        { "maxValue": 2000000, "fee": 13000 },
        { "maxValue": 3000000, "fee": 20000 },
        { "maxValue": 4000000, "fee": 26000 },
        { "maxValue": 5000000, "fee": 32000 },
        { "maxValue": 6000000, "fee": 39000 },
        { "maxValue": 7000000, "fee": 46000 },
        { "maxValue": 8000000, "fee": 52000 },
        { "maxValue": 9000000, "fee": 58000 },
        { "maxValue": 10000000, "fee": 65000 },
        { "maxValue": 15000000, "fee": 75000 },
        { "maxValue": 20000000, "fee": 100000 },
        { "maxValue": 25000000, "fee": 125000 },
        { "maxValue": 30000000, "fee": 150000 },
        { "maxValue": 50000000, "fee": 250000 },
        { "maxValue": null, "fee": 325000 }
      ],
      "recoverableCosts": [
        { "maxValue": 250000, "ceiling": 38000 },
        { "maxValue": 500000, "ceiling": 56000 },
        { "maxValue": 1000000, "ceiling": 112000 },
        { "maxValue": 2000000, "ceiling": 200000 },
        { "maxValue": 4000000, "ceiling": 400000 },
        { "maxValue": 8000000, "ceiling": 600000 },
        { "maxValue": 16000000, "ceiling": 800000 },
        { "maxValue": 30000000, "ceiling": 1200000 },
        { "maxValue": 50000000, "ceiling": 1500000 },
        { "maxValue": null, "ceiling": 2000000 }
      ],
      "smReduction": 0.40
    },
    "2026": {
      "label": "UPC (ab 2026)",
      "validFrom": "2026-01-01",
      "fixedFees": {
        "infringement": 14600,
        "counterclaim_infringement": 14600,
        "non_infringement": 14600,
        "license_compensation": 14600,
        "determine_damages": 4000,
        "revocation_standalone": 26500,
        "counterclaim_revocation": 26500,
        "provisional_measures": 14600
      },
      "valueBased": "TODO: exact 2026 table not yet published in extractable form. Estimated ~32% increase on pre-2026 values. Replace with official data when available.",
      "smReduction": 0.50
    }
  }
}

3. Architecture Decision

Recommendation: New page within KanzlAI-mGMT at /kosten/rechner

Reasons:

  1. Existing infrastructure: KanzlAI already has billing/cost infrastructure (time tracking, invoices, RVG rates). The Kostenrechner is a natural extension.
  2. Shared UI patterns: Sidebar nav, card layout, Tailwind styling, Recharts for any comparison charts — all already established.
  3. Future integration: Cost calculations can link to cases (attach estimated costs to a case), feed into Prozesskostensicherheit calculations, and inform billing.
  4. No auth required for core calculator: The page can work without login (public tool for marketing), but logged-in users get case-linking and save functionality.
  5. No backend needed initially: All fee calculations are deterministic lookups + arithmetic — pure frontend. Data lives as static JSON/TypeScript constants.

Against standalone deployment:

  • Maintaining a separate deploy adds operational overhead for zero benefit
  • Can't integrate with cases or billing later without cross-origin complexity
  • Duplicates styling/build tooling

Proposed Route Structure

/kosten/                        — Overview page (links to sub-calculators)
/kosten/rechner                 — Patentprozesskostenrechner (main calculator)
/kosten/rechner/vergleich       — (future) Venue comparison tool (DE vs UPC)

Frontend Architecture

frontend/src/
  app/(app)/kosten/
    page.tsx                    — Overview
    rechner/
      page.tsx                  — Calculator page (client component)
  lib/
    costs/
      fee-tables.ts             — All fee schedule data (GKG, RVG, UPC)
      calculator.ts             — Pure calculation functions
      types.ts                  — TypeScript types for inputs/outputs
  components/
    costs/
      CostCalculator.tsx        — Main calculator component
      InstanceCard.tsx           — Per-instance input card (LG, OLG, etc.)
      CostSummary.tsx           — Results display with breakdown
      CostComparison.tsx        — (future) Side-by-side venue comparison

No backend changes needed. All calculation logic is client-side. If we later want to save calculations to a case, we add one API endpoint.


4. All Inputs

Global Inputs

Input Type Range Default Description
vatRate enum 0%, 16%, 19% 0% Umsatzsteuer
streitwert number 50030,000,000 100,000 Amount in dispute (EUR)
erhoehungsStreitwert number >= streitwert = streitwert Increased amount (for Erhoehungsgebuehr)
proceedingType enum infringement, nullity, cancellation, security infringement Which proceeding to calculate

Per-Instance Inputs (Infringement: LG, OLG, BGH-NZB, BGH-Rev)

Input Type Default Description
enabled boolean true (LG), false (others) Include this instance
feeVersion enum "Aktuell" Fee schedule version (2005/2013/2021/2025/Aktuell)
numAttorneys integer >= 0 1 Rechtsanwälte
numPatentAttorneys integer >= 0 1 Patentanwälte
oralHearing boolean true Mündliche Verhandlung held?
expertFees number >= 0 0 Sachverständigenvergütung (EUR)
terminationType enum "Urteil" How case ended (Urteil/Vergleich/Klagerücknahme/etc.)
numClients integer >= 1 1 Mandanten (for Erhöhungsgebühr)

Per-Instance Inputs (Nullity: BPatG, BGH)

Same structure as infringement instances.

Per-Instance Inputs (Cancellation: DPMA, BPatG)

Same structure but no patent attorneys at DPMA level, fixed court fees.

UPC-Specific Inputs (New)

Input Type Default Description
actionType enum "infringement" UPC action type (affects fixed fee + value-based applicability)
feeVersion enum "2026" pre-2026 or 2026
isSME boolean false Small/micro enterprise (40%/50% court fee reduction)
includeAppeal boolean false Include Court of Appeal
includeRevocation boolean false Include counterclaim for revocation

5. All Outputs

Per-Instance Breakdown

Output Description
Court fee (base) e.g., "3.0x GKG = EUR 18,714"
Expert fees If applicable
Court subtotal Court fee + expert fees
Per-attorney cost VG + Erhöhung + TG + Pauschale, before VAT
Per-attorney cost (incl. VAT) × (1 + VAT)
Attorney subtotal Per-attorney × num_attorneys
Patent attorney subtotal Same calculation × num_patent_attorneys
Instance total Court subtotal + attorney subtotal + patent attorney subtotal

Summary Totals (Infringement)

Output Description
Gesamtkosten bei Nichtzulassung LG + OLG + BGH-NZB
Gesamtkosten bei Revision LG + OLG + BGH-Rev

Summary Totals (Nullity)

Output Description
Gesamtkosten Nichtigkeitsverfahren BPatG + BGH

Summary Totals (Cancellation)

Output Description
Gesamtkosten Löschungsverfahren DPMA + BPatG

Security for Costs (Prozesskostensicherheit)

Output Description
1. Instanz 2.5x RA + increase + 2.5x PA + increase + EUR 5,000
2. Instanz 2.8x RA + increase + 2.8x PA + increase + 4.0x court + EUR 5,000
NZB 2.3x RA + increase + 2.3x PA + increase
Total (incl. VAT) Sum × (1 + VAT)

UPC Outputs (New)

Output Description
Fixed court fee Per action type
Value-based fee Per Streitwert bracket
Total court fees Fixed + value-based
Court fees (SME) With 40%/50% reduction
Recoverable costs ceiling Per Streitwert bracket
Appeal court fees If appeal enabled
Total cost risk All court fees + recoverable costs ceiling

Fee Schedule Reference (Quick Lookup)

Output Description
Base 1.0x GKG fee For each fee version at given Streitwert
Base 1.0x RVG fee For each fee version at given Streitwert

6. Bugs to Fix (from Excel)

Bug 1: Prozesskostensicherheit VAT Formula (CRITICAL)

  • Location: Excel cell C31 on Prozesskostensicherheit sheet
  • Problem: Formula =C30*(1-Umsatzsteuer) subtracts VAT instead of adding it
  • Label says: "inkl. Umsatzsteuer" (including VAT)
  • Fix: =C30*(1+Umsatzsteuer) → in web version: total * (1 + vatRate)
  • Impact: 32% error when VAT = 19% (EUR 35,394 vs correct EUR 51,998)
  • Why hidden: Default VAT is 0%, so 1-0 = 1+0 = 1 — bug only manifests with non-zero VAT

Bug 2: Prozesskostensicherheit Uses Wrong Fee Type

  • Location: Excel cell C22 on Prozesskostensicherheit sheet
  • Problem: mGebuehrensatz(Streitwert, 1, SelectedVersion) — parameter 1 selects RVG (attorney) fees
  • Should be: mGebuehrensatz(Streitwert, 0, SelectedVersion) — parameter 0 selects GKG (court) fees
  • Context: This cell calculates "4-fache Gerichts-Verfahrensgebühr (Nr. 1420 KV)" — clearly a court fee
  • Fix: Use GKG fee schedule for court fee calculations
  • Impact: GKG and RVG fees differ, so the result is always wrong

Bug 3: Nichtigkeitsverfahren Missing Expert Fees in Total

  • Location: Excel cell D24 on Nichtigkeitsverfahren sheet
  • Problem: =C23+C13 adds attorney total (C23) + bare court fee (C13), but C13 is only the 4.5x fee line item
  • Should be: =C23+C15 where C15 is the Zwischensumme (court fees + expert fees)
  • Fix: Include expert fees subtotal in instance total
  • Impact: Expert fees are silently dropped from the BPatG total. Consistent with Verletzungsverfahren pattern where D26 = C25 + C17 (uses Zwischensumme)

7. UPC Fee Structure (New Feature)

How UPC Fees Differ from German Courts

Aspect German Courts (GKG/RVG) UPC
Court fee model Step-based accumulator Fixed fee + bracket lookup
Attorney fees RVG statutory table Contractual (market rates)
Recoverable costs RVG-based (predictable) Ceiling table (much higher)
Scope Single country Pan-European
Nullity Separate BPatG proceeding Counterclaim in same action

UPC Court Fees: Two Components

  1. Fixed fee — always due, depends on action type:

    • Infringement: EUR 14,600 (2026) / EUR 11,000 (pre-2026)
    • Revocation: EUR 26,500 (2026) / EUR 20,000 (pre-2026) — flat, no value-based component
    • Appeal: same fixed fees as first instance
  2. Value-based fee — only for infringement-type actions when Streitwert > EUR 500,000:

    • 19 brackets from EUR 0 (≤500k) to EUR 325,000 (>50M) — pre-2026
    • ~32% increase in 2026 (exact table pending official publication)
    • Revocation actions have NO value-based fee
  3. SME reduction: 50% (2026) / 40% (pre-2026) on all court fees

Recoverable Costs Ceilings (Attorney Fee Caps)

Per instance, the losing party reimburses up to:

Streitwert Ceiling
≤ EUR 250,000 EUR 38,000
≤ EUR 500,000 EUR 56,000
≤ EUR 1,000,000 EUR 112,000
≤ EUR 2,000,000 EUR 200,000
≤ EUR 4,000,000 EUR 400,000
≤ EUR 8,000,000 EUR 600,000
≤ EUR 16,000,000 EUR 800,000
≤ EUR 30,000,000 EUR 1,200,000
≤ EUR 50,000,000 EUR 1,500,000
> EUR 50,000,000 EUR 2,000,000

Court can raise ceiling by 50% (cases ≤1M) or 25% (150M). Expert/translator fees recoverable separately on top.

Cost Comparison (Key Insight)

At EUR 3M Streitwert (infringement, 1st instance):

UPC (2026) German LG
Court fees ~EUR 41,000 EUR 43,914
Recoverable attorney costs up to EUR 400,000 ~EUR 100,388
Total cost risk ~EUR 441,000 ~EUR 144,302

Key takeaway: UPC court fees are comparable to or lower than German courts. But recoverable attorney costs are 35x higher, making total cost risk at UPC roughly 23x German courts. This is the critical information patent litigators need.

UPC Sources

  • Rule 370 RoP (court fees), Rule 152 RoP (recoverable costs), Art. 69 UPCA
  • UPC Administrative Committee fee table AC/05/08072022 (pre-2026)
  • UPC Administrative Committee amendment, 4 Nov 2025 (2026 changes)
  • Scale of Ceilings for Recoverable Costs: D-AC/10/24042023
  • Maiwald MAIinsight April 2025 (practitioner analysis with verified figures)

8. Implementation Recommendations

Phase 1: Core Calculator (MVP)

  • Implement fee-tables.ts with all 5 GKG/RVG schedule versions as typed constants
  • Implement calculator.ts with pure functions: computeBaseFee(streitwert, isRVG, version), per-instance calculations, totals
  • Build the UI as a single "use client" page at /kosten/rechner
  • Card-based layout: global inputs at top, collapsible instance cards, results summary at bottom
  • Fix all 3 bugs in the implementation (don't port them from Excel)
  • German language UI throughout

Phase 2: UPC Extension

  • Add UPC fee data and calculation functions (bracket lookup, not step-based)
  • Add UPC section to the calculator (separate card or tab)
  • Add venue comparison view: side-by-side DE vs UPC for the same Streitwert

Phase 3: Integration

  • Allow saving calculations to a case (requires one backend endpoint)
  • PDF export of cost breakdown
  • Wire up Verfahrensbeendigung (termination type affects fee multipliers)

Data Extraction TODO

Before implementation begins, the exact fee table values must be extracted from the Excel file. The analysis doc describes the structure but doesn't list every cell value. The implementer should either:

  1. Open the Excel and manually read the Hebesaetze sheet values, or
  2. Use a Python script with openpyxl to extract the ListObject data programmatically

This is critical — the older fee versions (2005, 2013, 2021) have different step sizes and increments.