bo4e_core/com/
offer_variant.rs1use serde::{Deserialize, Serialize};
4
5use crate::enums::OfferStatus;
6use crate::traits::{Bo4eMeta, Bo4eObject};
7
8#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
25#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
26#[cfg_attr(feature = "json-schema", schemars(rename = "Angebotsvariante"))]
27#[serde(rename_all = "camelCase")]
28pub struct OfferVariant {
29 #[serde(flatten)]
31 pub meta: Bo4eMeta,
32
33 #[serde(skip_serializing_if = "Option::is_none")]
35 #[cfg_attr(feature = "json-schema", schemars(rename = "angebotsstatus"))]
36 pub offer_status: Option<OfferStatus>,
37
38 #[serde(skip_serializing_if = "Option::is_none")]
40 #[cfg_attr(feature = "json-schema", schemars(rename = "erstellungsdatum"))]
41 pub creation_date: Option<String>,
42
43 #[serde(skip_serializing_if = "Option::is_none")]
45 #[cfg_attr(feature = "json-schema", schemars(rename = "bindefrist"))]
46 pub binding_deadline: Option<String>,
47
48 #[serde(skip_serializing_if = "Option::is_none")]
52 #[cfg_attr(feature = "json-schema", schemars(rename = "anzahlTeile"))]
53 pub parts_count: Option<i32>,
54
55 #[serde(skip_serializing_if = "Option::is_none")]
57 #[cfg_attr(feature = "json-schema", schemars(rename = "gesamtmenge"))]
58 pub total_quantity_value: Option<f64>,
59
60 #[serde(skip_serializing_if = "Option::is_none")]
62 #[cfg_attr(feature = "json-schema", schemars(rename = "gesamtkosten"))]
63 pub total_cost_value: Option<f64>,
64}
65
66impl Bo4eObject for OfferVariant {
67 fn type_name_german() -> &'static str {
68 "Angebotsvariante"
69 }
70
71 fn type_name_english() -> &'static str {
72 "OfferVariant"
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_offer_variant_default() {
90 let variant = OfferVariant::default();
91 assert!(variant.offer_status.is_none());
92 assert!(variant.creation_date.is_none());
93 }
94
95 #[test]
96 fn test_offer_variant_serialize() {
97 let variant = OfferVariant {
98 offer_status: Some(OfferStatus::Binding),
99 creation_date: Some("2024-03-01T09:00:00+01:00".to_string()),
100 binding_deadline: Some("2024-04-01T23:59:59+02:00".to_string()),
101 ..Default::default()
102 };
103
104 let json = serde_json::to_string(&variant).unwrap();
105 assert!(json.contains(r#""offerStatus":"VERBINDLICH""#));
106 assert!(json.contains(r#""creationDate":"#));
107 assert!(json.contains(r#""bindingDeadline":"#));
108 }
109
110 #[test]
111 fn test_offer_variant_roundtrip() {
112 let variant = OfferVariant {
113 meta: Bo4eMeta::with_type("Angebotsvariante"),
114 offer_status: Some(OfferStatus::NonBinding),
115 creation_date: Some("2024-02-15T10:30:00+01:00".to_string()),
116 binding_deadline: Some("2024-03-15T23:59:59+01:00".to_string()),
117 parts_count: Some(2),
118 total_quantity_value: Some(100000.0),
119 total_cost_value: Some(25000.0),
120 };
121
122 let json = serde_json::to_string(&variant).unwrap();
123 let parsed: OfferVariant = serde_json::from_str(&json).unwrap();
124 assert_eq!(variant, parsed);
125 }
126
127 #[test]
128 fn test_bo4e_object_impl() {
129 assert_eq!(OfferVariant::type_name_german(), "Angebotsvariante");
130 assert_eq!(OfferVariant::type_name_english(), "OfferVariant");
131 }
132}