1use serde::{Deserialize, Serialize};
4
5use crate::enums::Currency;
6use crate::traits::{Bo4eMeta, Bo4eObject};
7
8#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
24#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
25#[cfg_attr(feature = "json-schema", schemars(rename = "Bonus"))]
26#[serde(rename_all = "camelCase")]
27pub struct Bonus {
28 #[serde(flatten)]
30 pub meta: Bo4eMeta,
31
32 #[serde(skip_serializing_if = "Option::is_none")]
34 #[cfg_attr(feature = "json-schema", schemars(rename = "bezeichnung"))]
35 pub description: Option<String>,
36
37 #[serde(skip_serializing_if = "Option::is_none")]
39 #[cfg_attr(feature = "json-schema", schemars(rename = "wert"))]
40 pub value: Option<f64>,
41
42 #[serde(skip_serializing_if = "Option::is_none")]
44 #[cfg_attr(feature = "json-schema", schemars(rename = "waehrung"))]
45 pub currency: Option<Currency>,
46
47 #[serde(skip_serializing_if = "Option::is_none")]
49 #[cfg_attr(feature = "json-schema", schemars(rename = "bedingungen"))]
50 pub conditions: Option<String>,
51
52 #[serde(skip_serializing_if = "Option::is_none")]
54 #[cfg_attr(feature = "json-schema", schemars(rename = "einmalig"))]
55 pub is_one_time: Option<bool>,
56}
57
58impl Bo4eObject for Bonus {
59 fn type_name_german() -> &'static str {
60 "Bonus"
61 }
62
63 fn type_name_english() -> &'static str {
64 "Bonus"
65 }
66
67 fn meta(&self) -> &Bo4eMeta {
68 &self.meta
69 }
70
71 fn meta_mut(&mut self) -> &mut Bo4eMeta {
72 &mut self.meta
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn test_new_customer_bonus() {
82 let bonus = Bonus {
83 description: Some("Neukundenbonus".to_string()),
84 value: Some(100.0),
85 currency: Some(Currency::Eur),
86 is_one_time: Some(true),
87 conditions: Some("Bei Vertragsabschluss".to_string()),
88 ..Default::default()
89 };
90
91 assert_eq!(bonus.value, Some(100.0));
92 assert_eq!(bonus.is_one_time, Some(true));
93 }
94
95 #[test]
96 fn test_loyalty_bonus() {
97 let bonus = Bonus {
98 description: Some("Treuebonus".to_string()),
99 value: Some(25.0),
100 currency: Some(Currency::Eur),
101 is_one_time: Some(false),
102 ..Default::default()
103 };
104
105 assert_eq!(bonus.is_one_time, Some(false));
106 }
107
108 #[test]
109 fn test_default() {
110 let bonus = Bonus::default();
111 assert!(bonus.description.is_none());
112 assert!(bonus.value.is_none());
113 }
114
115 #[test]
116 fn test_roundtrip() {
117 let bonus = Bonus {
118 description: Some("Online-Bonus".to_string()),
119 value: Some(50.0),
120 currency: Some(Currency::Eur),
121 conditions: Some("Bei Online-Abschluss".to_string()),
122 is_one_time: Some(true),
123 ..Default::default()
124 };
125
126 let json = serde_json::to_string(&bonus).unwrap();
127 let parsed: Bonus = serde_json::from_str(&json).unwrap();
128 assert_eq!(bonus, parsed);
129 }
130
131 #[test]
132 fn test_bo4e_object_impl() {
133 assert_eq!(Bonus::type_name_german(), "Bonus");
134 assert_eq!(Bonus::type_name_english(), "Bonus");
135 }
136}