use crate::common::attachment::AttachmentRefOrValue;
use crate::tmf620::bundled_product_offering::BundledProductOffering;
use crate::tmf620::category::{Category, CategoryRef};
use crate::tmf620::product_specification::{
ProductSpecificationCharacteristicValueUse, ProductSpecificationRef,
};
use super::product_offering_price::ProductOfferingPriceRef;
use crate::tmf633::service_candidate::ServiceCandidateRef;
use crate::tmf634::resource_candidate::ResourceCandidateRef;
use crate::{vec_insert, HasDescription, HasId, HasLastUpdate, HasName, HasReference, TimePeriod};
use serde::{Deserialize, Serialize};
use tmflib_derive::{HasDescription, HasId, HasLastUpdate, HasName};
use super::{ChannelRef, MarketSegmentRef, PlaceRef, SLARef};
use crate::tmf651::agreement::AgreementRef;
use super::MOD_PATH;
use crate::LIB_PATH;
const PO_VERS_INIT: &str = "1.0";
const CLASS_PATH: &str = "productOffering";
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct ProductOfferingRef {
pub id: String,
pub href: String,
pub name: String,
}
impl From<ProductOffering> for ProductOfferingRef {
fn from(po: ProductOffering) -> ProductOfferingRef {
ProductOfferingRef {
id: po.get_id(),
href: po.get_href(),
name: po.get_name(),
}
}
}
impl HasReference for ProductOffering {
type RefType = ProductOfferingRef;
fn as_ref(&self) -> Option<Self::RefType> {
Some(ProductOfferingRef::from(self.clone()))
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ProductOfferingTerm {}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ProductOfferingRelationship {
id: Option<String>,
href: Option<String>,
name: Option<String>,
pub relationship_type: Option<String>,
pub role: Option<String>,
pub valid_for: Option<TimePeriod>,
}
impl From<ProductOffering> for ProductOfferingRelationship {
fn from(po: ProductOffering) -> ProductOfferingRelationship {
ProductOfferingRelationship {
id: po.id.clone(),
href: po.href.clone(),
name: po.name.clone(),
relationship_type: None,
role: None,
valid_for: None,
}
}
}
#[derive(
Clone, Default, Debug, Deserialize, HasId, HasDescription, HasName, HasLastUpdate, Serialize,
)]
#[serde(rename_all = "camelCase")]
pub struct ProductOffering {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub href: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_bundle: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_sellable: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_update: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lifecycle_status: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status_reason: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub valid_for: Option<TimePeriod>,
#[serde(skip_serializing_if = "Option::is_none")]
pub agreement: Option<Vec<AgreementRef>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attachment: Option<Vec<AttachmentRefOrValue>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bundled_product_offering: Option<Vec<BundledProductOffering>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub category: Option<Vec<CategoryRef>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub channel: Option<Vec<ChannelRef>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub market_segment: Option<Vec<MarketSegmentRef>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub place: Option<Vec<PlaceRef>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub product_offering_price: Option<Vec<ProductOfferingPriceRef>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub product_offering_relationship: Option<Vec<ProductOfferingRelationship>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub product_offering_term: Option<Vec<ProductOfferingTerm>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub prod_spec_char_value_use: Option<Vec<ProductSpecificationCharacteristicValueUse>>,
pub product_specification: Option<ProductSpecificationRef>,
#[serde(skip_serializing_if = "Option::is_none")]
pub resource_candidate: Option<ResourceCandidateRef>,
#[serde(skip_serializing_if = "Option::is_none")]
pub service_candidate: Option<ServiceCandidateRef>,
#[serde(skip_serializing_if = "Option::is_none")]
pub service_level_agreement: Option<SLARef>,
}
impl ProductOffering {
pub fn new(name: impl Into<String>) -> ProductOffering {
let mut offer = ProductOffering::create_with_time();
offer.name = Some(name.into());
offer.version = Some(PO_VERS_INIT.to_string());
offer.product_offering_relationship = Some(vec![]);
offer.prod_spec_char_value_use = Some(vec![]);
offer
}
pub fn status(&mut self, status: &str) {
self.lifecycle_status = Some(status.to_owned());
}
pub fn with_category(mut self, category: Category) -> ProductOffering {
vec_insert(&mut self.category, CategoryRef::from(&category));
self
}
pub fn with_char_value_use(
mut self,
char_value_use: ProductSpecificationCharacteristicValueUse,
) -> ProductOffering {
self.prod_spec_char_value_use
.as_mut()
.unwrap()
.push(char_value_use);
self
}
pub fn link_po(&mut self, remote_po: ProductOffering, relationship_type: &str, role: &str) {
let mut offer_rel = ProductOfferingRelationship::from(remote_po);
offer_rel.relationship_type = Some(relationship_type.to_string());
offer_rel.role = Some(role.to_string());
self.product_offering_relationship
.as_mut()
.unwrap()
.push(offer_rel);
}
}
#[cfg(test)]
mod test {
use super::ProductOffering;
use super::PO_VERS_INIT;
#[test]
fn test_po_new_name() {
let po = ProductOffering::new(String::from("MyOffer"));
assert_eq!(po.name, Some(String::from("MyOffer")));
}
#[test]
fn test_po_new_version() {
let po = ProductOffering::new(String::from("MyOffer"));
assert_eq!(po.version, Some(PO_VERS_INIT.to_string()));
}
}