use serde::{Deserialize, Serialize};
use crate::{
common::related_party::RelatedParty, vec_insert, DateTime, HasDescription, HasId,
HasRelatedParty, Uri,
};
use crate::common::tmf_error::TMFError;
use crate::tmf633::service_category::ServiceCategoryRef;
use crate::tmf641::service_order_item::ServiceRefOrValue;
use tmflib_derive::{HasDescription, HasId, HasRelatedParty};
const CLASS_PATH: &str = "checkServiceQualification";
use super::{TaskStateType, MOD_PATH};
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct ServiceEligibilityUnavailabilityReason {
code: String,
label: String,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct AlternateServiceProposal {
alternate_service_availability_date: Option<DateTime>,
id: String,
alternate_service: Option<ServiceRefOrValue>,
}
impl From<ServiceRefOrValue> for AlternateServiceProposal {
fn from(value: ServiceRefOrValue) -> Self {
AlternateServiceProposal {
alternate_service_availability_date: value.has_started.clone(),
id: CheckServiceQualification::get_uuid(),
alternate_service: Some(value),
}
}
}
#[derive(Clone, Debug, Default, HasId, HasDescription, HasRelatedParty, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CheckServiceQualificationItem {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub href: Option<Uri>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub related_party: Option<Vec<RelatedParty>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub service: Option<ServiceRefOrValue>,
#[serde(skip_serializing_if = "Option::is_none")]
pub category: Option<ServiceCategoryRef>,
#[serde(skip_serializing_if = "Option::is_none")]
pub eligibility_unavailability_reason: Option<Vec<ServiceEligibilityUnavailabilityReason>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub alternate_service_proposal: Option<Vec<AlternateServiceProposal>>,
}
impl CheckServiceQualificationItem {
pub fn alternate(&mut self, service: ServiceRefOrValue) {
vec_insert(
&mut self.alternate_service_proposal,
AlternateServiceProposal::from(service),
);
}
pub fn reason(&mut self, code: impl Into<String>, label: impl Into<String>) {
vec_insert(
&mut self.eligibility_unavailability_reason,
ServiceEligibilityUnavailabilityReason {
code: code.into(),
label: label.into(),
},
);
}
}
#[derive(Clone, Debug, Default, HasId, HasDescription, HasRelatedParty, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CheckServiceQualification {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub href: Option<Uri>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub state: Option<TaskStateType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub service_qualification_item: Option<Vec<CheckServiceQualificationItem>>,
#[serde(skip_serializing_if = "Option::is_none")]
check_service_qualification_date: Option<DateTime>,
#[serde(skip_serializing_if = "Option::is_none")]
effective_qualification_date: Option<DateTime>,
#[serde(skip_serializing_if = "Option::is_none")]
estimated_response_date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
estimated_qualification_date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
expiration_date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub instant_sync_qualification: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub provide_alternative: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub provide_unavailability_reason: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub related_party: Option<Vec<RelatedParty>>,
}
impl CheckServiceQualification {
pub fn new(desc: impl Into<String>) -> CheckServiceQualification {
CheckServiceQualification {
..CheckServiceQualification::create()
}
.description(desc)
.state(TaskStateType::default())
}
pub fn state(mut self, state: TaskStateType) -> CheckServiceQualification {
self.state = Some(state);
self
}
pub fn item(mut self, item: CheckServiceQualificationItem) -> CheckServiceQualification {
vec_insert(&mut self.service_qualification_item, item);
self
}
}
#[cfg(test)]
mod test {
use super::*;
const SQ_DESC: &str = "SQ Description";
#[test]
fn test_sq_create() {
let sq = CheckServiceQualification::new(SQ_DESC);
assert_eq!(sq.description.is_some(), true);
assert_eq!(sq.description.unwrap(), SQ_DESC.to_string());
}
#[test]
fn test_sq_item() {
let mut item = CheckServiceQualificationItem::default();
item.reason("code", "label");
let sq = CheckServiceQualification::new("Qualification").item(item);
assert_eq!(sq.service_qualification_item.is_some(), true);
assert_eq!(sq.service_qualification_item.unwrap().len(), 1);
}
#[test]
fn test_sq_alternative() {
let mut alternate = ServiceRefOrValue::default();
alternate.description = Some("Alternate Service".to_string());
let mut item = CheckServiceQualificationItem::default();
item.reason("code", "label");
item.alternate(alternate);
assert_eq!(item.alternate_service_proposal.is_some(), true);
assert_eq!(item.alternate_service_proposal.unwrap().len(), 1);
}
#[test]
fn test_sq_state() {
let sq = CheckServiceQualification::new("Qualification").state(TaskStateType::InProgress);
assert_eq!(sq.state.is_some(), true);
assert_eq!(sq.state.unwrap(), TaskStateType::InProgress);
}
}