use crate::common::related_entity::RelatedEntity;
use crate::common::related_party::RelatedParty;
use crate::common::tmf_error::TMFError;
use crate::vec_insert;
use crate::{
common::attachment::AttachmentRefOrValue, DateTime, HasDescription, HasId, HasLastUpdate,
HasName, HasRelatedParty, Uri,
};
use serde::{Deserialize, Serialize};
use tmflib_derive::{HasDescription, HasId, HasLastUpdate, HasName, HasRelatedParty};
const CLASS_PATH: &str = "document";
use super::MOD_PATH;
const DOC_VERSION: &str = "1.0";
#[derive(Clone, Default, Debug, Deserialize, PartialEq, Serialize)]
pub enum DocumentStatusType {
#[default]
Created,
Reviewed,
Approved,
Published,
Archived,
Deleted,
}
#[derive(
Clone,
Default,
Debug,
Deserialize,
HasId,
HasName,
HasLastUpdate,
HasRelatedParty,
HasDescription,
Serialize,
)]
#[serde(rename_all = "camelCase")]
pub struct Document {
#[serde(skip_serializing_if = "Option::is_none")]
id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
href: Option<Uri>,
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_update: Option<DateTime>,
#[serde(skip_serializing_if = "Option::is_none")]
status: Option<DocumentStatusType>,
#[serde(skip_serializing_if = "Option::is_none")]
version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
document_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
creation_date: Option<DateTime>,
related_party: Option<Vec<RelatedParty>>,
related_entity: Option<Vec<RelatedEntity>>,
attachment: AttachmentRefOrValue,
}
impl Document {
pub fn new(name: impl Into<String>) -> Document {
let mut doc = Document::create_with_time();
doc.name = Some(name.into());
doc.creation_date = Some(Document::get_timestamp());
doc.status = Some(DocumentStatusType::Created);
doc.version = Some(DOC_VERSION.into());
doc
}
pub fn attachment(mut self, attachment: AttachmentRefOrValue) -> Document {
self.attachment = attachment;
self
}
pub fn doc_type(mut self, r#type: impl Into<String>) -> Document {
self.document_type = Some(r#type.into());
self
}
pub fn link<T: HasName>(mut self, entity: T) -> Document {
self.link_entity(entity);
self
}
pub fn link_entity<T: HasName>(&mut self, entity: T) {
vec_insert(&mut self.related_entity, RelatedEntity::from(entity));
}
}
impl From<AttachmentRefOrValue> for Document {
fn from(value: AttachmentRefOrValue) -> Self {
let mut document = Document::create_with_time();
document.set_name(value.get_name());
document.description.clone_from(&value.description);
document.status = Some(DocumentStatusType::Created);
document.attachment = value.clone();
document
}
}
#[cfg(test)]
mod test {
use super::DocumentStatusType;
use super::DOC_VERSION;
use crate::common::attachment::AttachmentRefOrValue;
use crate::tmf651::agreement::Agreement;
use super::Document;
use crate::HasName;
const DOC_NAME: &str = "A Document";
const DOC_TYPE: &str = "PDF";
const DOC_STATE: &str = "\"Created\"";
const AGREEMENT_NAME: &str = "AnAgreement";
#[test]
fn test_document_new() {
let doc = Document::new(DOC_NAME);
assert_eq!(doc.name, Some(DOC_NAME.into()));
}
#[test]
fn test_document_new_type() {
let doc = Document::new(DOC_NAME).doc_type(DOC_TYPE);
assert_eq!(doc.document_type, Some(DOC_TYPE.into()));
}
#[test]
fn test_document_new_version() {
let doc = Document::new(DOC_NAME);
assert_eq!(doc.version, Some(DOC_VERSION.into()));
}
#[test]
fn test_document_new_status() {
let doc = Document::new(DOC_NAME);
assert_eq!(doc.status.unwrap(), DocumentStatusType::Created);
}
#[test]
fn test_docstatustype_deserialize() {
let docstatustype: DocumentStatusType = serde_json::from_str(DOC_STATE).unwrap();
assert_eq!(docstatustype, DocumentStatusType::Created);
}
#[test]
fn test_document_from_attachref() {
let attachref = AttachmentRefOrValue::new();
let doc = Document::from(attachref.clone());
assert_eq!(doc.get_name(), attachref.get_name());
}
#[test]
fn test_document_link() {
let agreement = Agreement::new(AGREEMENT_NAME);
let document = Document::new(AGREEMENT_NAME).link(agreement);
assert_eq!(document.related_entity.is_some(), true);
assert_eq!(document.related_entity.unwrap().first().is_some(), true);
}
}