bo4e_core/enums/
calculation_method.rs

1//! Calculation method (Kalkulationsmethode) enumeration.
2
3use serde::{Deserialize, Serialize};
4
5/// Calculation method for price sheets.
6///
7/// List of different calculation methods for a price sheet.
8///
9/// German: Kalkulationsmethode
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
11#[non_exhaustive]
12pub enum CalculationMethod {
13    /// Step model - total quantity is assigned to one step and the price applies to entire quantity
14    #[serde(rename = "STUFEN")]
15    Steps,
16
17    /// Zone model - total quantity is distributed across zones with respective prices
18    #[serde(rename = "ZONEN")]
19    Zones,
20
21    /// Pre-zone base price (Vorzonengrundpreis)
22    #[serde(rename = "VORZONEN_GP")]
23    PreZoneBasePrice,
24
25    /// Sigmoid function (Sigmoidfunktion)
26    #[serde(rename = "SIGMOID")]
27    Sigmoid,
28
29    /// Reactive power above 50% of active power
30    #[serde(rename = "BLINDARBEIT_GT_50_PROZENT")]
31    ReactivePowerAbove50Percent,
32
33    /// Reactive power above 40% of active power
34    #[serde(rename = "BLINDARBEIT_GT_40_PROZENT")]
35    ReactivePowerAbove40Percent,
36
37    /// Reactive power with free allowance (defined by cos phi or percentage)
38    #[serde(rename = "BLINDARBEIT_MIT_FREIMENGE")]
39    ReactivePowerWithFreeAllowance,
40
41    /// Working and base price zoned
42    #[serde(rename = "AP_GP_ZONEN")]
43    WorkingAndBasePriceZoned,
44
45    /// Capacity charge based on installed capacity
46    #[serde(rename = "LP_INSTALL_LEISTUNG")]
47    CapacityChargeInstalledCapacity,
48
49    /// Working price based on transport or distribution network
50    #[serde(rename = "AP_TRANSPORT_ODER_VERTEILNETZ")]
51    WorkingPriceTransportOrDistribution,
52
53    /// Working price based on transport/distribution network, local network via sigmoid
54    #[serde(rename = "AP_TRANSPORT_ODER_VERTEILNETZ_ORTSVERTEILNETZ_SIGMOID")]
55    WorkingPriceTransportOrDistributionLocalSigmoid,
56
57    /// Capacity charge based on annual consumption
58    #[serde(rename = "LP_JAHRESVERBRAUCH")]
59    CapacityChargeAnnualConsumption,
60
61    /// Capacity price based on transport or distribution network
62    #[serde(rename = "LP_TRANSPORT_ODER_VERTEILNETZ")]
63    CapacityPriceTransportOrDistribution,
64
65    /// Capacity price based on transport/distribution network, local network via sigmoid
66    #[serde(rename = "LP_TRANSPORT_ODER_VERTEILNETZ_ORTSVERTEILNETZ_SIGMOID")]
67    CapacityPriceTransportOrDistributionLocalSigmoid,
68
69    /// Function-based capacity determination for consumption above SLP threshold
70    #[serde(rename = "FUNKTIONEN")]
71    Functions,
72
73    /// Above SLP threshold, function-based calculation as LGK
74    #[serde(rename = "VERBRAUCH_UEBER_SLP_GRENZE_FUNKTIONSBEZOGEN_WEITERE_BERECHNUNG_ALS_LGK")]
75    ConsumptionAboveSLPThresholdFunctionBasedLGK,
76}
77
78impl CalculationMethod {
79    /// Returns the German name.
80    pub fn german_name(&self) -> &'static str {
81        match self {
82            Self::Steps => "Stufen",
83            Self::Zones => "Zonen",
84            Self::PreZoneBasePrice => "Vorzonengrundpreis",
85            Self::Sigmoid => "Sigmoid",
86            Self::ReactivePowerAbove50Percent => "Blindarbeit oberhalb 50% der Wirkarbeit",
87            Self::ReactivePowerAbove40Percent => "Blindarbeit oberhalb 40% der Wirkarbeit",
88            Self::ReactivePowerWithFreeAllowance => "Blindarbeit mit Freimenge",
89            Self::WorkingAndBasePriceZoned => "Arbeits- und Grundpreis gezont",
90            Self::CapacityChargeInstalledCapacity => {
91                "Leistungsentgelt auf Grundlage der installierten Leistung"
92            }
93            Self::WorkingPriceTransportOrDistribution => {
94                "AP auf Grundlage Transport- oder Verteilnetz"
95            }
96            Self::WorkingPriceTransportOrDistributionLocalSigmoid => {
97                "AP auf Grundlage Transport- oder Verteilnetz, Ortsverteilnetz über Sigmoid"
98            }
99            Self::CapacityChargeAnnualConsumption => {
100                "Leistungsentgelt auf Grundlage des Jahresverbrauchs"
101            }
102            Self::CapacityPriceTransportOrDistribution => {
103                "LP auf Grundlage Transport- oder Verteilnetz"
104            }
105            Self::CapacityPriceTransportOrDistributionLocalSigmoid => {
106                "LP auf Grundlage Transport- oder Verteilnetz, Ortsverteilnetz über Sigmoid"
107            }
108            Self::Functions => "Funktionen",
109            Self::ConsumptionAboveSLPThresholdFunctionBasedLGK => {
110                "Verbrauch über SLP-Grenze funktionsbezogen als LGK"
111            }
112        }
113    }
114}
115
116#[cfg(test)]
117mod tests {
118    use super::*;
119
120    #[test]
121    fn test_serialize() {
122        assert_eq!(
123            serde_json::to_string(&CalculationMethod::Steps).unwrap(),
124            r#""STUFEN""#
125        );
126        assert_eq!(
127            serde_json::to_string(&CalculationMethod::Zones).unwrap(),
128            r#""ZONEN""#
129        );
130    }
131
132    #[test]
133    fn test_deserialize() {
134        assert_eq!(
135            serde_json::from_str::<CalculationMethod>(r#""SIGMOID""#).unwrap(),
136            CalculationMethod::Sigmoid
137        );
138    }
139
140    #[test]
141    fn test_roundtrip() {
142        for method in [
143            CalculationMethod::Steps,
144            CalculationMethod::Zones,
145            CalculationMethod::PreZoneBasePrice,
146            CalculationMethod::Sigmoid,
147            CalculationMethod::ReactivePowerAbove50Percent,
148            CalculationMethod::ReactivePowerAbove40Percent,
149            CalculationMethod::ReactivePowerWithFreeAllowance,
150            CalculationMethod::WorkingAndBasePriceZoned,
151            CalculationMethod::CapacityChargeInstalledCapacity,
152            CalculationMethod::WorkingPriceTransportOrDistribution,
153            CalculationMethod::WorkingPriceTransportOrDistributionLocalSigmoid,
154            CalculationMethod::CapacityChargeAnnualConsumption,
155            CalculationMethod::CapacityPriceTransportOrDistribution,
156            CalculationMethod::CapacityPriceTransportOrDistributionLocalSigmoid,
157            CalculationMethod::Functions,
158            CalculationMethod::ConsumptionAboveSLPThresholdFunctionBasedLGK,
159        ] {
160            let json = serde_json::to_string(&method).unwrap();
161            let parsed: CalculationMethod = serde_json::from_str(&json).unwrap();
162            assert_eq!(method, parsed);
163        }
164    }
165}