Skip to main content

bo4e_core/com/
tariff_calculation_parameter.rs

1//! Tariff calculation parameter (Tarifberechnungsparameter) component.
2
3use serde::{Deserialize, Serialize};
4
5use crate::enums::{TariffCalculationMethod, TariffTime};
6use crate::traits::{Bo4eMeta, Bo4eObject};
7
8/// Parameters for tariff calculation.
9///
10/// German: Tarifberechnungsparameter
11///
12/// # Example
13///
14/// ```rust
15/// use bo4e_core::com::TariffCalculationParameter;
16/// use bo4e_core::enums::TariffCalculationMethod;
17///
18/// let param = TariffCalculationParameter {
19///     calculation_method: Some(TariffCalculationMethod::Tiers),
20///     ..Default::default()
21/// };
22/// ```
23#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
24#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
25#[cfg_attr(
26    feature = "json-schema",
27    schemars(rename = "Tarifberechnungsparameter")
28)]
29#[serde(rename_all = "camelCase")]
30pub struct TariffCalculationParameter {
31    /// BO4E metadata
32    #[serde(flatten)]
33    pub meta: Bo4eMeta,
34
35    /// Method for tariff calculation (Berechnungsmethode)
36    #[serde(skip_serializing_if = "Option::is_none")]
37    #[cfg_attr(feature = "json-schema", schemars(rename = "berechnungsmethode"))]
38    pub calculation_method: Option<TariffCalculationMethod>,
39
40    /// Tariff time (day/night, etc.) (Tarifzeit)
41    #[serde(skip_serializing_if = "Option::is_none")]
42    #[cfg_attr(feature = "json-schema", schemars(rename = "tarifzeit"))]
43    pub tariff_time: Option<TariffTime>,
44
45    /// Whether this applies to peak demand (Ist Leistungsabhängig)
46    #[serde(skip_serializing_if = "Option::is_none")]
47    #[cfg_attr(feature = "json-schema", schemars(rename = "istLeistungsabhaengig"))]
48    pub is_demand_based: Option<bool>,
49
50    /// Minimum annual consumption for this tariff (Mindestjahresverbrauch)
51    #[serde(skip_serializing_if = "Option::is_none")]
52    #[cfg_attr(feature = "json-schema", schemars(rename = "mindestjahresverbrauch"))]
53    pub min_annual_consumption: Option<f64>,
54
55    /// Maximum annual consumption for this tariff (Höchstjahresverbrauch)
56    #[serde(skip_serializing_if = "Option::is_none")]
57    #[cfg_attr(feature = "json-schema", schemars(rename = "hoechstjahresverbrauch"))]
58    pub max_annual_consumption: Option<f64>,
59
60    /// Description (Beschreibung)
61    #[serde(skip_serializing_if = "Option::is_none")]
62    #[cfg_attr(feature = "json-schema", schemars(rename = "beschreibung"))]
63    pub description: Option<String>,
64}
65
66impl Bo4eObject for TariffCalculationParameter {
67    fn type_name_german() -> &'static str {
68        "Tarifberechnungsparameter"
69    }
70
71    fn type_name_english() -> &'static str {
72        "TariffCalculationParameter"
73    }
74
75    fn meta(&self) -> &Bo4eMeta {
76        &self.meta
77    }
78
79    fn meta_mut(&mut self) -> &mut Bo4eMeta {
80        &mut self.meta
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use super::*;
87
88    #[test]
89    fn test_tiered_tariff() {
90        let param = TariffCalculationParameter {
91            calculation_method: Some(TariffCalculationMethod::Tiers),
92            min_annual_consumption: Some(0.0),
93            max_annual_consumption: Some(10000.0),
94            ..Default::default()
95        };
96
97        assert_eq!(
98            param.calculation_method,
99            Some(TariffCalculationMethod::Tiers)
100        );
101    }
102
103    #[test]
104    fn test_time_based_tariff() {
105        let param = TariffCalculationParameter {
106            calculation_method: Some(TariffCalculationMethod::None),
107            tariff_time: Some(TariffTime::HighTariff),
108            ..Default::default()
109        };
110
111        assert_eq!(param.tariff_time, Some(TariffTime::HighTariff));
112    }
113
114    #[test]
115    fn test_default() {
116        let param = TariffCalculationParameter::default();
117        assert!(param.calculation_method.is_none());
118        assert!(param.min_annual_consumption.is_none());
119    }
120
121    #[test]
122    fn test_roundtrip() {
123        let param = TariffCalculationParameter {
124            calculation_method: Some(TariffCalculationMethod::None),
125            tariff_time: Some(TariffTime::LowTariff),
126            is_demand_based: Some(false),
127            description: Some("Night rate tariff".to_string()),
128            ..Default::default()
129        };
130
131        let json = serde_json::to_string(&param).unwrap();
132        let parsed: TariffCalculationParameter = serde_json::from_str(&json).unwrap();
133        assert_eq!(param, parsed);
134    }
135
136    #[test]
137    fn test_bo4e_object_impl() {
138        assert_eq!(
139            TariffCalculationParameter::type_name_german(),
140            "Tarifberechnungsparameter"
141        );
142        assert_eq!(
143            TariffCalculationParameter::type_name_english(),
144            "TariffCalculationParameter"
145        );
146    }
147}