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
//! Bridge to [`billing`] document types.
//!
//! Since [`SettleOutput`] now carries `positions: Vec<SettlePosition>`, this
//! module is a thin adapter — it calls `SettlePosition::to_line_item` on each
//! position and handles the special cases (`NoData`, `PriceMissing`, `Sanctioned`).
//!
//! # Why not `billing::Tariff`?
//!
//! The `Tariff` trait generates documents from usage data. EEG settlement is a
//! **scalar calculation** with status variants (`NoData`, `PriceMissing`, `Sanctioned`,
//! `FoerderungBeendet`) that cannot be represented as `Err(BillingError)`, and with
//! stateful KWKG hour-limit tracking. The positions are already computed by
//! [`crate::calculate_settlement`] — this module only converts them to `billing::LineItem`.
//!
//! # Example
//!
//! ```rust
//! use eeg_billing::{SettleInput, SettlementScheme, calculate_settlement};
//! use eeg_billing::bridge::settlement_to_line_items;
//! use rust_decimal::Decimal;
//!
//! let output = calculate_settlement(&SettleInput {
//! scheme: eeg_billing::SettlementScheme::FeedInTariff { verguetungssatz_ct: Decimal::from_str_exact("8.11").unwrap() },
//! einspeisemenge_kwh: Some(Decimal::from(500u32)),
//! ..SettleInput::default()
//! });
//! let items = settlement_to_line_items(&output);
//! assert_eq!(items.len(), 1);
//! assert!(items[0].description.contains("EEG"));
//! ```
use ;
use Decimal;
use crate;
/// Convert a settlement result into [`billing::LineItem`] positions.
///
/// Returns an **empty** `Vec` for `NoData` and `PriceMissing` — nothing to bill yet.
///
/// For `Sanctioned`, returns a single EUR 0 line tagged `"§25-sanctioned"` for audit
/// trail.
///
/// For all other statuses, delegates to `SettlePosition::to_line_item` on each
/// position already computed by [`crate::calculate_settlement`].