1use serde::{Deserialize, Serialize};
4
5use crate::enums::Currency;
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 = "Betrag"))]
27#[serde(rename_all = "camelCase")]
28pub struct Amount {
29 #[serde(flatten)]
31 pub meta: Bo4eMeta,
32
33 #[serde(skip_serializing_if = "Option::is_none")]
35 #[cfg_attr(feature = "json-schema", schemars(rename = "wert"))]
36 pub value: Option<f64>,
37
38 #[serde(skip_serializing_if = "Option::is_none")]
40 #[cfg_attr(feature = "json-schema", schemars(rename = "waehrung"))]
41 pub currency: Option<Currency>,
42}
43
44impl Bo4eObject for Amount {
45 fn type_name_german() -> &'static str {
46 "Betrag"
47 }
48
49 fn type_name_english() -> &'static str {
50 "Amount"
51 }
52
53 fn meta(&self) -> &Bo4eMeta {
54 &self.meta
55 }
56
57 fn meta_mut(&mut self) -> &mut Bo4eMeta {
58 &mut self.meta
59 }
60}
61
62impl Amount {
63 pub fn eur(value: f64) -> Self {
65 Self {
66 value: Some(value),
67 currency: Some(Currency::Eur),
68 ..Default::default()
69 }
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn test_eur_amount() {
79 let amount = Amount::eur(100.50);
80 assert_eq!(amount.value, Some(100.50));
81 assert_eq!(amount.currency, Some(Currency::Eur));
82 }
83
84 #[test]
85 fn test_default() {
86 let amount = Amount::default();
87 assert!(amount.value.is_none());
88 assert!(amount.currency.is_none());
89 }
90
91 #[test]
92 fn test_serialize() {
93 let amount = Amount::eur(250.75);
94 let json = serde_json::to_string(&amount).unwrap();
95 assert!(json.contains(r#""value":250.75"#));
96 assert!(json.contains(r#""currency":"EUR""#));
97 }
98
99 #[test]
100 fn test_roundtrip() {
101 let amount = Amount::eur(999.99);
102 let json = serde_json::to_string(&amount).unwrap();
103 let parsed: Amount = serde_json::from_str(&json).unwrap();
104 assert_eq!(amount, parsed);
105 }
106
107 #[test]
108 fn test_bo4e_object_impl() {
109 assert_eq!(Amount::type_name_german(), "Betrag");
110 assert_eq!(Amount::type_name_english(), "Amount");
111 }
112}