Skip to main content

bo4e_core/bo/
tariff_info.rs

1//! Tariff info (Tarifinfo) business object.
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use crate::com::{EnergyMix, PriceGuarantee, TariffRestriction, TimePeriod};
7use crate::enums::{CustomerType, Division};
8use crate::traits::{Bo4eMeta, Bo4eObject};
9
10/// Tariff information/overview.
11///
12/// Provides summary information about a tariff without the full details.
13///
14/// German: Tarifinfo
15///
16/// # Example
17///
18/// ```rust
19/// use bo4e_core::bo::TariffInfo;
20/// use bo4e_core::enums::{CustomerType, Division};
21///
22/// let tariff_info = TariffInfo {
23///     tariff_name: Some("Oekostrom Basis".to_string()),
24///     division: Some(Division::Electricity),
25///     customer_type: Some(CustomerType::Household),
26///     ..Default::default()
27/// };
28/// ```
29#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
30#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
31#[cfg_attr(feature = "json-schema", schemars(rename = "Tarifinfo"))]
32#[serde(rename_all = "camelCase")]
33pub struct TariffInfo {
34    /// BO4E metadata
35    #[serde(flatten)]
36    pub meta: Bo4eMeta,
37
38    /// Tariff name (Tarifname)
39    #[serde(skip_serializing_if = "Option::is_none")]
40    #[cfg_attr(feature = "json-schema", schemars(rename = "tarifname"))]
41    pub tariff_name: Option<String>,
42
43    /// Tariff description (Tarifbeschreibung)
44    #[serde(skip_serializing_if = "Option::is_none")]
45    #[cfg_attr(feature = "json-schema", schemars(rename = "tarifbeschreibung"))]
46    pub description: Option<String>,
47
48    /// Energy division (Sparte)
49    #[serde(skip_serializing_if = "Option::is_none")]
50    #[cfg_attr(feature = "json-schema", schemars(rename = "sparte"))]
51    pub division: Option<Division>,
52
53    /// Target customer type (Kundentyp)
54    #[serde(skip_serializing_if = "Option::is_none")]
55    #[cfg_attr(feature = "json-schema", schemars(rename = "kundentyp"))]
56    pub customer_type: Option<CustomerType>,
57
58    /// Website URL for tariff information (Website)
59    #[serde(skip_serializing_if = "Option::is_none")]
60    #[cfg_attr(feature = "json-schema", schemars(rename = "website"))]
61    pub website: Option<String>,
62
63    /// Validity period (Gueltigkeitszeitraum)
64    #[serde(skip_serializing_if = "Option::is_none")]
65    #[cfg_attr(feature = "json-schema", schemars(rename = "gueltigkeitszeitraum"))]
66    pub validity_period: Option<TimePeriod>,
67
68    /// Start date of tariff availability (Angebotsdatum)
69    #[serde(skip_serializing_if = "Option::is_none")]
70    #[cfg_attr(feature = "json-schema", schemars(rename = "angebotsdatum"))]
71    pub available_from: Option<DateTime<Utc>>,
72
73    /// End date of tariff availability (Enddatum)
74    #[serde(skip_serializing_if = "Option::is_none")]
75    #[cfg_attr(feature = "json-schema", schemars(rename = "enddatum"))]
76    pub available_until: Option<DateTime<Utc>>,
77
78    /// Energy mix composition (Energiemix)
79    #[serde(skip_serializing_if = "Option::is_none")]
80    #[cfg_attr(feature = "json-schema", schemars(rename = "energiemix"))]
81    pub energy_mix: Option<EnergyMix>,
82
83    /// Price guarantee (Preisgarantie)
84    #[serde(skip_serializing_if = "Option::is_none")]
85    #[cfg_attr(feature = "json-schema", schemars(rename = "preisgarantie"))]
86    pub price_guarantee: Option<PriceGuarantee>,
87
88    /// Tariff restrictions (Tarifeinschraenkungen)
89    #[serde(default, skip_serializing_if = "Vec::is_empty")]
90    #[cfg_attr(feature = "json-schema", schemars(rename = "tarifeinschraenkungen"))]
91    pub restrictions: Vec<TariffRestriction>,
92
93    /// Provider/supplier
94    #[serde(skip_serializing_if = "Option::is_none")]
95    #[cfg_attr(feature = "json-schema", schemars(rename = "anbieter"))]
96    pub supplier: Option<Box<super::BusinessPartner>>,
97}
98
99impl Bo4eObject for TariffInfo {
100    fn type_name_german() -> &'static str {
101        "Tarifinfo"
102    }
103
104    fn type_name_english() -> &'static str {
105        "TariffInfo"
106    }
107
108    fn meta(&self) -> &Bo4eMeta {
109        &self.meta
110    }
111
112    fn meta_mut(&mut self) -> &mut Bo4eMeta {
113        &mut self.meta
114    }
115}
116
117#[cfg(test)]
118mod tests {
119    use super::*;
120
121    #[test]
122    fn test_tariff_info_creation() {
123        let tariff_info = TariffInfo {
124            tariff_name: Some("Oekostrom Basis".to_string()),
125            division: Some(Division::Electricity),
126            customer_type: Some(CustomerType::Household),
127            website: Some("https://example.com/tariff".to_string()),
128            ..Default::default()
129        };
130
131        assert_eq!(tariff_info.tariff_name, Some("Oekostrom Basis".to_string()));
132        assert_eq!(tariff_info.customer_type, Some(CustomerType::Household));
133    }
134
135    #[test]
136    fn test_serialize() {
137        let tariff_info = TariffInfo {
138            meta: Bo4eMeta::with_type("Tarifinfo"),
139            tariff_name: Some("Green Energy".to_string()),
140            division: Some(Division::Electricity),
141            ..Default::default()
142        };
143
144        let json = serde_json::to_string(&tariff_info).unwrap();
145        assert!(json.contains(r#""tariffName":"Green Energy""#));
146        assert!(json.contains(r#""_typ":"Tarifinfo""#));
147    }
148
149    #[test]
150    fn test_roundtrip() {
151        let tariff_info = TariffInfo {
152            meta: Bo4eMeta::with_type("Tarifinfo"),
153            tariff_name: Some("Test Tariff".to_string()),
154            description: Some("A test tariff info".to_string()),
155            division: Some(Division::Gas),
156            customer_type: Some(CustomerType::Commercial),
157            website: Some("https://test.com".to_string()),
158            ..Default::default()
159        };
160
161        let json = serde_json::to_string(&tariff_info).unwrap();
162        let parsed: TariffInfo = serde_json::from_str(&json).unwrap();
163        assert_eq!(tariff_info, parsed);
164    }
165
166    #[test]
167    fn test_bo4e_object_impl() {
168        assert_eq!(TariffInfo::type_name_german(), "Tarifinfo");
169        assert_eq!(TariffInfo::type_name_english(), "TariffInfo");
170    }
171}