bo4e_core/com/
offer_position.rs1use serde::{Deserialize, Serialize};
4
5use crate::traits::{Bo4eMeta, Bo4eObject};
6
7#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
27#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
28#[cfg_attr(feature = "json-schema", schemars(rename = "Angebotsposition"))]
29#[serde(rename_all = "camelCase")]
30pub struct OfferPosition {
31 #[serde(flatten)]
33 pub meta: Bo4eMeta,
34
35 #[serde(skip_serializing_if = "Option::is_none")]
37 #[cfg_attr(feature = "json-schema", schemars(rename = "positionsbezeichnung"))]
38 pub position_description: Option<String>,
39
40 #[serde(skip_serializing_if = "Option::is_none")]
45 #[cfg_attr(feature = "json-schema", schemars(rename = "positionspreis"))]
46 pub position_price_value: Option<f64>,
47
48 #[serde(skip_serializing_if = "Option::is_none")]
50 #[cfg_attr(feature = "json-schema", schemars(rename = "positionsmenge"))]
51 pub position_quantity_value: Option<f64>,
52
53 #[serde(skip_serializing_if = "Option::is_none")]
55 #[cfg_attr(feature = "json-schema", schemars(rename = "positionskosten"))]
56 pub position_cost_value: Option<f64>,
57}
58
59impl Bo4eObject for OfferPosition {
60 fn type_name_german() -> &'static str {
61 "Angebotsposition"
62 }
63
64 fn type_name_english() -> &'static str {
65 "OfferPosition"
66 }
67
68 fn meta(&self) -> &Bo4eMeta {
69 &self.meta
70 }
71
72 fn meta_mut(&mut self) -> &mut Bo4eMeta {
73 &mut self.meta
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_offer_position_default() {
83 let pos = OfferPosition::default();
84 assert!(pos.position_description.is_none());
85 assert!(pos.position_price_value.is_none());
86 }
87
88 #[test]
89 fn test_offer_position_serialize() {
90 let pos = OfferPosition {
91 position_description: Some("Electricity delivery".to_string()),
92 position_price_value: Some(24.56),
93 position_quantity_value: Some(4000.0),
94 position_cost_value: Some(982.40),
95 ..Default::default()
96 };
97
98 let json = serde_json::to_string(&pos).unwrap();
99 assert!(json.contains(r#""positionDescription":"Electricity delivery""#));
100 assert!(json.contains("24.56"));
101 assert!(json.contains("4000"));
102 }
103
104 #[test]
105 fn test_offer_position_roundtrip() {
106 let pos = OfferPosition {
107 meta: Bo4eMeta::with_type("Angebotsposition"),
108 position_description: Some("Gas supply".to_string()),
109 position_price_value: Some(0.08),
110 position_quantity_value: Some(10000.0),
111 position_cost_value: Some(800.0),
112 };
113
114 let json = serde_json::to_string(&pos).unwrap();
115 let parsed: OfferPosition = serde_json::from_str(&json).unwrap();
116 assert_eq!(pos, parsed);
117 }
118
119 #[test]
120 fn test_bo4e_object_impl() {
121 assert_eq!(OfferPosition::type_name_german(), "Angebotsposition");
122 assert_eq!(OfferPosition::type_name_english(), "OfferPosition");
123 }
124}