bo4e_core/com/
contract_part.rs1use serde::{Deserialize, Serialize};
4
5use crate::traits::{Bo4eMeta, Bo4eObject};
6
7#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
28#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
29#[cfg_attr(feature = "json-schema", schemars(rename = "Vertragsteil"))]
30#[serde(rename_all = "camelCase")]
31pub struct ContractPart {
32 #[serde(flatten)]
34 pub meta: Bo4eMeta,
35
36 #[serde(skip_serializing_if = "Option::is_none")]
38 #[cfg_attr(feature = "json-schema", schemars(rename = "vertragsteilbeginn"))]
39 pub contract_part_start: Option<String>,
40
41 #[serde(skip_serializing_if = "Option::is_none")]
43 #[cfg_attr(feature = "json-schema", schemars(rename = "vertragsteilende"))]
44 pub contract_part_end: Option<String>,
45
46 #[serde(skip_serializing_if = "Option::is_none")]
48 #[cfg_attr(feature = "json-schema", schemars(rename = "lokation"))]
49 pub location_id: Option<String>,
50
51 #[serde(skip_serializing_if = "Option::is_none")]
55 #[cfg_attr(feature = "json-schema", schemars(rename = "vertraglichFixierteMenge"))]
56 pub fixed_quantity_value: Option<f64>,
57
58 #[serde(skip_serializing_if = "Option::is_none")]
60 #[cfg_attr(feature = "json-schema", schemars(rename = "minimaleAbnahmemenge"))]
61 pub minimum_quantity_value: Option<f64>,
62
63 #[serde(skip_serializing_if = "Option::is_none")]
65 #[cfg_attr(feature = "json-schema", schemars(rename = "maximaleAbnahmemenge"))]
66 pub maximum_quantity_value: Option<f64>,
67}
68
69impl Bo4eObject for ContractPart {
70 fn type_name_german() -> &'static str {
71 "Vertragsteil"
72 }
73
74 fn type_name_english() -> &'static str {
75 "ContractPart"
76 }
77
78 fn meta(&self) -> &Bo4eMeta {
79 &self.meta
80 }
81
82 fn meta_mut(&mut self) -> &mut Bo4eMeta {
83 &mut self.meta
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn test_contract_part_default() {
93 let part = ContractPart::default();
94 assert!(part.location_id.is_none());
95 assert!(part.contract_part_start.is_none());
96 }
97
98 #[test]
99 fn test_contract_part_serialize() {
100 let part = ContractPart {
101 location_id: Some("DE00012345678901234567890123456".to_string()),
102 contract_part_start: Some("2024-01-01T00:00:00+01:00".to_string()),
103 contract_part_end: Some("2024-12-31T23:59:59+01:00".to_string()),
104 fixed_quantity_value: Some(50000.0),
105 ..Default::default()
106 };
107
108 let json = serde_json::to_string(&part).unwrap();
109 assert!(json.contains(r#""locationId":"DE00012345678901234567890123456""#));
110 assert!(json.contains(r#""contractPartStart":"#));
111 assert!(json.contains(r#""fixedQuantityValue":50000"#));
112 }
113
114 #[test]
115 fn test_contract_part_roundtrip() {
116 let part = ContractPart {
117 meta: Bo4eMeta::with_type("Vertragsteil"),
118 contract_part_start: Some("2024-06-01T00:00:00+02:00".to_string()),
119 contract_part_end: Some("2025-05-31T23:59:59+02:00".to_string()),
120 location_id: Some("MALO-12345".to_string()),
121 fixed_quantity_value: Some(100000.0),
122 minimum_quantity_value: Some(80000.0),
123 maximum_quantity_value: Some(120000.0),
124 };
125
126 let json = serde_json::to_string(&part).unwrap();
127 let parsed: ContractPart = serde_json::from_str(&json).unwrap();
128 assert_eq!(part, parsed);
129 }
130
131 #[test]
132 fn test_bo4e_object_impl() {
133 assert_eq!(ContractPart::type_name_german(), "Vertragsteil");
134 assert_eq!(ContractPart::type_name_english(), "ContractPart");
135 }
136}