Skip to main content

datasynth_core/models/sourcing/
spend_analysis.rs

1//! Spend analysis models for procurement category management.
2
3use rust_decimal::Decimal;
4use serde::{Deserialize, Serialize};
5
6/// Spend analysis for a procurement category.
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct SpendAnalysis {
9    /// Category identifier (e.g., GL account group or material group)
10    pub category_id: String,
11    /// Category description
12    pub category_name: String,
13    /// Company code
14    pub company_code: String,
15    /// Total spend in the analysis period
16    #[serde(with = "rust_decimal::serde::str")]
17    pub total_spend: Decimal,
18    /// Number of active vendors in this category
19    pub vendor_count: u32,
20    /// Number of transactions in this category
21    pub transaction_count: u32,
22    /// Herfindahl-Hirschman Index (0-10000) measuring vendor concentration
23    pub hhi_index: f64,
24    /// Top vendor spend shares
25    pub vendor_shares: Vec<VendorSpendShare>,
26    /// Percentage of spend under contract
27    pub contract_coverage: f64,
28    /// Percentage of spend through preferred vendors
29    pub preferred_vendor_coverage: f64,
30    /// Average unit price trend (year-over-year change)
31    pub price_trend_pct: f64,
32    /// Analysis period (fiscal year)
33    pub fiscal_year: u16,
34}
35
36/// Vendor's share of category spend.
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct VendorSpendShare {
39    /// Vendor ID
40    pub vendor_id: String,
41    /// Vendor name
42    pub vendor_name: String,
43    /// Spend amount
44    #[serde(with = "rust_decimal::serde::str")]
45    pub spend_amount: Decimal,
46    /// Share of category spend (0.0 to 1.0)
47    pub share: f64,
48    /// Whether this is a preferred/contracted vendor
49    pub is_preferred: bool,
50}