datasynth_core/models/sourcing/
qualification.rs1use chrono::NaiveDate;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7use super::super::graph_properties::{GraphPropertyValue, ToNodeProperties};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
11#[serde(rename_all = "snake_case")]
12pub enum QualificationStatus {
13 #[default]
15 Pending,
16 InProgress,
18 Qualified,
20 ConditionallyQualified,
22 Disqualified,
24 Expired,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct QualificationCriterion {
31 pub name: String,
33 pub weight: f64,
35 pub min_score: f64,
37 pub is_mandatory: bool,
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct QualificationScore {
44 pub criterion_name: String,
46 pub score: f64,
48 pub passed: bool,
50 pub comments: Option<String>,
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct SupplierCertification {
57 pub certification_id: String,
59 pub vendor_id: String,
61 pub certification_type: String,
63 pub issuing_body: String,
65 pub issue_date: NaiveDate,
67 pub expiry_date: NaiveDate,
69 pub is_valid: bool,
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct SupplierQualification {
76 pub qualification_id: String,
78 pub vendor_id: String,
80 pub sourcing_project_id: Option<String>,
82 pub company_code: String,
84 pub status: QualificationStatus,
86 pub start_date: NaiveDate,
88 pub completion_date: Option<NaiveDate>,
90 pub valid_until: Option<NaiveDate>,
92 pub scores: Vec<QualificationScore>,
94 pub overall_score: f64,
96 pub evaluator_id: String,
98 pub certifications: Vec<String>,
100 pub conditions: Option<String>,
102}
103
104impl ToNodeProperties for SupplierQualification {
105 fn node_type_name(&self) -> &'static str {
106 "supplier_qualification"
107 }
108 fn node_type_code(&self) -> u16 {
109 325
110 }
111 fn to_node_properties(&self) -> HashMap<String, GraphPropertyValue> {
112 let mut p = HashMap::new();
113 p.insert(
114 "qualificationId".into(),
115 GraphPropertyValue::String(self.qualification_id.clone()),
116 );
117 p.insert(
118 "vendorId".into(),
119 GraphPropertyValue::String(self.vendor_id.clone()),
120 );
121 p.insert(
122 "entityCode".into(),
123 GraphPropertyValue::String(self.company_code.clone()),
124 );
125 p.insert(
126 "status".into(),
127 GraphPropertyValue::String(format!("{:?}", self.status)),
128 );
129 p.insert(
130 "startDate".into(),
131 GraphPropertyValue::Date(self.start_date),
132 );
133 p.insert(
134 "overallScore".into(),
135 GraphPropertyValue::Float(self.overall_score),
136 );
137 p.insert(
138 "criterionCount".into(),
139 GraphPropertyValue::Int(self.scores.len() as i64),
140 );
141 p.insert(
142 "certificationCount".into(),
143 GraphPropertyValue::Int(self.certifications.len() as i64),
144 );
145 p.insert(
146 "isQualified".into(),
147 GraphPropertyValue::Bool(matches!(
148 self.status,
149 QualificationStatus::Qualified | QualificationStatus::ConditionallyQualified
150 )),
151 );
152 p
153 }
154}