use std::convert::TryFrom;
use crate::error::ClientError;
use crate::protocol::purchase_order::state::{
PurchaseOrderAlternateId, PurchaseOrderAlternateIdBuilder,
};
use crate::purchase_order::store::{ListPOFilters, ListVersionFilters};
use super::Client;
#[derive(Debug, Clone, PartialEq)]
pub struct PurchaseOrder {
pub purchase_order_uid: String,
pub workflow_state: String,
pub buyer_org_id: String,
pub seller_org_id: String,
pub is_closed: bool,
pub alternate_ids: Vec<AlternateId>,
pub accepted_version_id: Option<String>,
pub versions: Vec<PurchaseOrderVersion>,
pub created_at: i64,
pub workflow_id: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct PurchaseOrderVersion {
pub version_id: String,
pub workflow_state: String,
pub is_draft: bool,
pub current_revision_id: u64,
pub revisions: Vec<PurchaseOrderRevision>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct PurchaseOrderRevision {
pub revision_id: u64,
pub order_xml_v3_4: String,
pub submitter: String,
pub created_at: i64,
}
#[derive(Debug, Clone, PartialEq)]
pub struct AlternateId {
pub purchase_order_uid: String,
pub alternate_id_type: String,
pub alternate_id: String,
}
impl AlternateId {
pub fn new(purchase_order_uid: &str, alternate_id_type: &str, alternate_id: &str) -> Self {
Self {
purchase_order_uid: purchase_order_uid.to_string(),
alternate_id_type: alternate_id_type.to_string(),
alternate_id: alternate_id.to_string(),
}
}
}
impl TryFrom<AlternateId> for PurchaseOrderAlternateId {
type Error = ClientError;
fn try_from(id: AlternateId) -> Result<PurchaseOrderAlternateId, Self::Error> {
let po = PurchaseOrderAlternateIdBuilder::new()
.with_id_type(id.alternate_id_type.to_string())
.with_id(id.alternate_id.to_string())
.with_purchase_order_uid(id.purchase_order_uid)
.build()
.map_err(|err| {
Self::Error::InternalError(format!("Could not convert Alternate ID: {}", err))
})?;
Ok(po)
}
}
impl TryFrom<&AlternateId> for PurchaseOrderAlternateId {
type Error = ClientError;
fn try_from(id: &AlternateId) -> Result<PurchaseOrderAlternateId, Self::Error> {
let po = PurchaseOrderAlternateIdBuilder::new()
.with_id_type(id.alternate_id_type.to_string())
.with_id(id.alternate_id.to_string())
.with_purchase_order_uid(id.purchase_order_uid.to_string())
.build()
.map_err(|err| {
Self::Error::InternalError(format!("Could not convert Alternate ID: {}", err))
})?;
Ok(po)
}
}
pub trait PurchaseOrderClient: Client {
fn get_purchase_order(
&self,
id: String,
service_id: Option<&str>,
) -> Result<Option<PurchaseOrder>, ClientError>;
fn get_purchase_order_version(
&self,
id: String,
version_id: String,
service_id: Option<&str>,
) -> Result<Option<PurchaseOrderVersion>, ClientError>;
fn get_purchase_order_revision(
&self,
id: String,
version_id: String,
revision_id: u64,
service_id: Option<&str>,
) -> Result<Option<PurchaseOrderRevision>, ClientError>;
fn list_purchase_orders(
&self,
filters: Option<ListPOFilters>,
service_id: Option<&str>,
) -> Result<Box<dyn Iterator<Item = Result<PurchaseOrder, ClientError>>>, ClientError>;
fn list_purchase_order_versions(
&self,
id: String,
filters: Option<ListVersionFilters>,
service_id: Option<&str>,
) -> Result<Box<dyn Iterator<Item = Result<PurchaseOrderVersion, ClientError>>>, ClientError>;
fn list_purchase_order_revisions(
&self,
id: String,
version_id: String,
service_id: Option<&str>,
) -> Result<Box<dyn Iterator<Item = Result<PurchaseOrderRevision, ClientError>>>, ClientError>;
fn get_latest_revision_id(
&self,
purchase_order_uid: String,
version_id: String,
service_id: Option<&str>,
) -> Result<Option<i64>, ClientError>;
}