use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RelationshipType {
Ratio,
Trend,
Correlation,
Reasonableness,
}
impl std::fmt::Display for RelationshipType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Self::Ratio => "Ratio",
Self::Trend => "Trend",
Self::Correlation => "Correlation",
Self::Reasonableness => "Reasonableness",
};
write!(f, "{s}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum DataReliability {
High,
Medium,
Low,
}
impl std::fmt::Display for DataReliability {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Self::High => "High",
Self::Medium => "Medium",
Self::Low => "Low",
};
write!(f, "{s}")
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PeriodDataPoint {
pub period: String,
#[serde(with = "crate::serde_decimal")]
pub value: Decimal,
pub is_current: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SupportingMetric {
pub metric_name: String,
#[serde(with = "crate::serde_decimal")]
pub value: Decimal,
pub source: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnalyticalRelationship {
pub id: String,
pub entity_code: String,
pub relationship_name: String,
pub account_area: String,
pub relationship_type: RelationshipType,
pub formula: String,
pub periods: Vec<PeriodDataPoint>,
pub expected_range: (String, String),
pub variance_explanation: Option<String>,
pub supporting_metrics: Vec<SupportingMetric>,
pub reliability: DataReliability,
pub within_expected_range: bool,
}
impl AnalyticalRelationship {
pub fn current_period(&self) -> Option<&PeriodDataPoint> {
self.periods.iter().find(|p| p.is_current)
}
}