1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//! Pure EEG/KWKG feed-in settlement calculation for German energy markets.
//!
//! Implements all settlement models defined in **EEG** (multiple versions 2000–2024)
//! and **KWKG 2023**. Zero I/O, zero async — every function is deterministic
//! and synchronous. No floating-point money: all monetary arithmetic uses
//! [`billing::EuroAmount`] (`i64 × 10⁻⁵ EUR`) internally.
//!
//! # Settlement schemes (9)
//!
//! | `SettlementScheme` | Formula | Legal basis |
//! |---|---|---|
//! | `FeedInTariff` | `kwh × verguetungssatz_ct / 100` | §21 EEG |
//! | `TenantElectricity` | Vergütung + `kwh × mieter_zuschlag_ct / 100` | §38a EEG 2023 |
//! | `MarketPremium` | `max(0, (AW+Mgmt) − EPEX) × kwh / 100` (§20 Abs. 3) | §20 EEG |
//! | `MarketPremium` + `TariffSource::Auction` | same formula, AW from BNetzA tender | §§22a,28 EEG 2023 |
//! | `PostEeg` | `kwh × EPEX / 100` (§23b cap: 10 ct; configurable floor) | §21 EEG (post-Förderung) |
//! | `Eigenverbrauch` | EUR 0 (no feed-in remuneration) | §38a EEG |
//! | `KwkSurcharge` | `eligible_kwh × rate / 100` (hour-limit cap) | §7 KWKG 2023 |
//! | `FlexibilityPremium` | Vergütung + `kwh × flex_praemie_ct / 100` | §50b EEG 2023 (bestehende Anlagen) |
//! | `FlexibilitySurcharge` | `kw × rate / 12` (monthly capacity payment) | §50a EEG 2023 (neue Anlagen) |
//!
//! # One formula — all EEG versions (2000–2024)
//!
//! **No separate tariff per EEG version is needed.** The settlement formula is
//! identical across all EEG versions. What differs between versions:
//!
//! 1. **Vergütungssatz (rate)** — fixed at commissioning for 20 years; caller provides it.
//! Use [`rates::solar_pv_ueberschuss_lookup`] or `einsd`'s `lookup_verguetungssatz`.
//!
//! 2. **§51 Negativpreisregel** — guard applied automatically from `inbetriebnahme`.
//! EEG 2023: any negative hour. Pre-2023 EEG 2017–2021: ≥6 consecutive hours.
//!
//! 3. **§100 EEG 2023 Übergangsregelung** — old plants continue under their EEG version's
//! rules (§100 Abs. 1). The rate is the only thing that changes per plant.
//!
//! # Umsatzsteuer (not Mehrwertsteuer)
//!
//! "Umsatzsteuer" (USt) is the legal term; "Mehrwertsteuer" (MwSt) is colloquial.
//! Three distinct situations — see [`ust`]:
//! - **§12 Abs. 3 UStG**: Solar PV ≤30 kWp, after 01.01.2023 → **no USt**
//! - **§19 UStG Kleinunternehmer**: turnover ≤€25 000/yr → **no USt**
//! - **Regelbesteuerung**: all others → **19 % USt**
//!
//! Use [`ust::ust_tax_layers`] to get the right `billing::TaxLayer` for a document.
//!
//! # Multi-EEG-version support
//!
//! Supply `inbetriebnahme` and `leistung_kwp` in [`SettleInput`] for automatic
//! version-specific rule enforcement:
//! - §51 Negativpreisregel guard (≥100 kWp, after 2016-01-01)
//! - Automatic `FoerderungBeendet` when `billing_date > foerderendedatum`
//!
//! # §24 EEG Anlagenerweiterung
//!
//! Plants extended with additional capacity blocks use [`CapacityBlock`].
//! Settlement is proportionally allocated across all blocks by installed kWp.
//!
//! # Quick start
//!
//! ```rust
//! use eeg_billing::{SettleInput, SettlementScheme, calculate_settlement, SettlementStatus};
//! use rust_decimal::Decimal;
//! use std::str::FromStr;
//!
//! fn d(s: &str) -> Decimal { Decimal::from_str(s).unwrap() }
//!
//! // §21 EEG 2023 — 100 kWh × 8.51 ct/kWh (Solarpaket I, ≤10 kWp Überschuss) = 8.51 EUR
//! let out = calculate_settlement(&SettleInput {
//! scheme: eeg_billing::SettlementScheme::FeedInTariff { verguetungssatz_ct: d("8.51") },
//! einspeisemenge_kwh: Some(d("100")),
//! ..SettleInput::default()
//! });
//! assert_eq!(out.status, SettlementStatus::Calculated);
//! assert_eq!(out.settlement_eur, Some(d("8.51")));
//! ```
pub use SettlementError;
pub use ;
pub use calculate_settlement;
pub use ;
pub use ;
pub use ;
pub use ;
// Domain module guide:
// degression: §23a quarterly solar PV tariff degression — Quarter, DegressionTier, apply_degression
// direktverm: §§20–22 Direktvermarktung — mandatory threshold, Ausschreibungspflicht, period model
// metering: Multi-meter Messkonzept — MeterConfiguration, compute_einspeisemenge, §42b GGV, §14a
// reductions: §§52–54 reduction pipeline — Sect52Netting, Sect53c, Sect54, ReductionPipeline
// settlement_state: Monthly lifecycle state machine — SettlementPeriodState, derive_settlement_state
// solar: §48 EEG PV subtypes, Volleinspeisung/Überschuss, §12 Abs. 3 UStG, Agri-PV
// wind: §36k Korrekturfaktor, Standortklasse, reference yield model
// biomasse: §43/§44 fuel classes, Güllekleinanlage (≤75 kW, ≥80% Gülle)
// foerderungsende: FoerderendeGrund enum, SanktionStatus lifecycle
// scheme: SettlementScheme, TariffSource, Paragraph100Rule, SettlementType