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#[serde(rename_all = "camelCase")]
25pub struct TariffCalculationParameter {
26    /// BO4E metadata
27    #[serde(flatten)]
28    pub meta: Bo4eMeta,
29
30    /// Method for tariff calculation (Berechnungsmethode)
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub calculation_method: Option<TariffCalculationMethod>,
33
34    /// Tariff time (day/night, etc.) (Tarifzeit)
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub tariff_time: Option<TariffTime>,
37
38    /// Whether this applies to peak demand (Ist Leistungsabhängig)
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub is_demand_based: Option<bool>,
41
42    /// Minimum annual consumption for this tariff (Mindestjahresverbrauch)
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub min_annual_consumption: Option<f64>,
45
46    /// Maximum annual consumption for this tariff (Höchstjahresverbrauch)
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub max_annual_consumption: Option<f64>,
49
50    /// Description (Beschreibung)
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub description: Option<String>,
53}
54
55impl Bo4eObject for TariffCalculationParameter {
56    fn type_name_german() -> &'static str {
57        "Tarifberechnungsparameter"
58    }
59
60    fn type_name_english() -> &'static str {
61        "TariffCalculationParameter"
62    }
63
64    fn meta(&self) -> &Bo4eMeta {
65        &self.meta
66    }
67
68    fn meta_mut(&mut self) -> &mut Bo4eMeta {
69        &mut self.meta
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn test_tiered_tariff() {
79        let param = TariffCalculationParameter {
80            calculation_method: Some(TariffCalculationMethod::Tiers),
81            min_annual_consumption: Some(0.0),
82            max_annual_consumption: Some(10000.0),
83            ..Default::default()
84        };
85
86        assert_eq!(
87            param.calculation_method,
88            Some(TariffCalculationMethod::Tiers)
89        );
90    }
91
92    #[test]
93    fn test_time_based_tariff() {
94        let param = TariffCalculationParameter {
95            calculation_method: Some(TariffCalculationMethod::None),
96            tariff_time: Some(TariffTime::HighTariff),
97            ..Default::default()
98        };
99
100        assert_eq!(param.tariff_time, Some(TariffTime::HighTariff));
101    }
102
103    #[test]
104    fn test_default() {
105        let param = TariffCalculationParameter::default();
106        assert!(param.calculation_method.is_none());
107        assert!(param.min_annual_consumption.is_none());
108    }
109
110    #[test]
111    fn test_roundtrip() {
112        let param = TariffCalculationParameter {
113            calculation_method: Some(TariffCalculationMethod::None),
114            tariff_time: Some(TariffTime::LowTariff),
115            is_demand_based: Some(false),
116            description: Some("Night rate tariff".to_string()),
117            ..Default::default()
118        };
119
120        let json = serde_json::to_string(&param).unwrap();
121        let parsed: TariffCalculationParameter = serde_json::from_str(&json).unwrap();
122        assert_eq!(param, parsed);
123    }
124
125    #[test]
126    fn test_bo4e_object_impl() {
127        assert_eq!(
128            TariffCalculationParameter::type_name_german(),
129            "Tarifberechnungsparameter"
130        );
131        assert_eq!(
132            TariffCalculationParameter::type_name_english(),
133            "TariffCalculationParameter"
134        );
135    }
136}