bo4e_core/com/
external_reference.rs

1//! External reference (ExterneReferenz) component.
2
3use serde::{Deserialize, Serialize};
4
5use crate::traits::{Bo4eMeta, Bo4eObject};
6
7/// Reference to an external system.
8///
9/// Used to link BO4E objects to identifiers in other systems (e.g., SAP, CRM).
10///
11/// German: ExterneReferenz
12///
13/// # Example
14///
15/// ```rust
16/// use bo4e_core::com::ExternalReference;
17///
18/// let ext_ref = ExternalReference::new("SAP", "4711");
19/// assert_eq!(ext_ref.external_ref_name, Some("SAP".to_string()));
20/// assert_eq!(ext_ref.external_ref_value, Some("4711".to_string()));
21/// ```
22#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
23#[serde(rename_all = "camelCase")]
24pub struct ExternalReference {
25    /// BO4E metadata
26    #[serde(flatten)]
27    pub meta: Bo4eMeta,
28
29    /// Name of the external system (ExRefName)
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub external_ref_name: Option<String>,
32
33    /// Value/ID in the external system (ExRefWert)
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub external_ref_value: Option<String>,
36}
37
38impl Bo4eObject for ExternalReference {
39    fn type_name_german() -> &'static str {
40        "ExterneReferenz"
41    }
42
43    fn type_name_english() -> &'static str {
44        "ExternalReference"
45    }
46
47    fn meta(&self) -> &Bo4eMeta {
48        &self.meta
49    }
50
51    fn meta_mut(&mut self) -> &mut Bo4eMeta {
52        &mut self.meta
53    }
54}
55
56impl ExternalReference {
57    /// Create a new external reference.
58    ///
59    /// # Arguments
60    ///
61    /// * `system` - Name of the external system
62    /// * `value` - The identifier/value in that system
63    pub fn new(system: impl Into<String>, value: impl Into<String>) -> Self {
64        Self {
65            external_ref_name: Some(system.into()),
66            external_ref_value: Some(value.into()),
67            ..Default::default()
68        }
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75
76    #[test]
77    fn test_external_reference_default() {
78        let ext_ref = ExternalReference::default();
79        assert!(ext_ref.external_ref_name.is_none());
80        assert!(ext_ref.external_ref_value.is_none());
81    }
82
83    #[test]
84    fn test_sap_reference() {
85        let ext_ref = ExternalReference::new("SAP", "4711");
86        assert_eq!(ext_ref.external_ref_name, Some("SAP".to_string()));
87        assert_eq!(ext_ref.external_ref_value, Some("4711".to_string()));
88    }
89
90    #[test]
91    fn test_serialize() {
92        let ext_ref = ExternalReference::new("CRM", "CUST-12345");
93        let json = serde_json::to_string(&ext_ref).unwrap();
94        assert!(json.contains(r#""externalRefName":"CRM""#));
95        assert!(json.contains(r#""externalRefValue":"CUST-12345""#));
96    }
97
98    #[test]
99    fn test_external_reference_roundtrip() {
100        let ext_ref = ExternalReference {
101            meta: Bo4eMeta::with_type("ExterneReferenz"),
102            external_ref_name: Some("ERP".to_string()),
103            external_ref_value: Some("ORDER-2024-001".to_string()),
104        };
105
106        let json = serde_json::to_string(&ext_ref).unwrap();
107        let parsed: ExternalReference = serde_json::from_str(&json).unwrap();
108        assert_eq!(ext_ref, parsed);
109    }
110
111    #[test]
112    fn test_bo4e_object_impl() {
113        assert_eq!(ExternalReference::type_name_german(), "ExterneReferenz");
114        assert_eq!(ExternalReference::type_name_english(), "ExternalReference");
115    }
116}