use serde::{Deserialize, Serialize};
use crate::common::contact::ContactMedium;
use crate::common::price::Price;
use crate::common::related_party::RelatedParty;
use crate::common::tmf_error::TMFError;
use crate::{HasId, HasRelatedParty, HasValidity, TimePeriod};
use tmflib_derive::{HasId, HasRelatedParty, HasValidity};
use super::cart_item::CartItem;
use super::MOD_PATH;
const CLASS_PATH: &str = "shoppingCart";
const CART_DEFAULT_VALID: u8 = 7;
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
pub struct CartPrice {
description: String,
name: String,
price_type: String,
recurring_charge_period: String,
unit_of_measure: String,
price: Option<Price>,
}
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
pub struct ShoppingCartRef {
id: String,
href: String,
}
impl From<ShoppingCart> for ShoppingCartRef {
fn from(value: ShoppingCart) -> Self {
ShoppingCartRef {
id: value.get_id(),
href: value.get_href(),
}
}
}
#[derive(Clone, Debug, Default, Deserialize, HasId, HasValidity, HasRelatedParty, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ShoppingCart {
#[serde(skip_serializing_if = "Option::is_none")]
pub contact_medium: Option<Vec<ContactMedium>>,
#[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 valid_for: Option<TimePeriod>,
cart_total_price: Option<Vec<CartPrice>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cart_item: Option<Vec<CartItem>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub related_party: Option<Vec<RelatedParty>>,
}
impl ShoppingCart {
pub fn new() -> ShoppingCart {
ShoppingCart {
valid_for: Some(TimePeriod::period_days(CART_DEFAULT_VALID.into())),
..Default::default()
}
}
pub fn add_item(&mut self, item: CartItem) {
match self.cart_item.as_mut() {
Some(v) => v.push(item),
None => self.cart_item = Some(vec![item]),
}
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::common::related_party::RelatedParty;
#[cfg(all(feature = "tmf632", feature = "build-V4"))]
use crate::tmf632::organization_v4::Organization;
#[cfg(all(feature = "tmf632", feature = "build-V5"))]
use crate::tmf632::organization_v5::Organization;
const ORG: &str = "AnOrganization";
#[test]
fn test_cart_add_item() {
let mut cart = ShoppingCart::new();
let org1 = Organization::new(ORG);
let org2 = org1.clone();
cart.add_party(RelatedParty::from(org1));
assert_eq!(cart.related_party.is_some(), true);
assert_eq!(cart.related_party.as_ref().unwrap().len(), 1);
assert_eq!(
cart.related_party.as_ref().unwrap().first(),
Some(&RelatedParty::from(org2))
);
}
#[test]
fn test_cart_add_party() {
let mut cart = ShoppingCart::new();
let item1 = CartItem::default();
let item2 = item1.clone();
cart.add_item(item1);
assert_eq!(cart.cart_item.is_some(), true);
assert_eq!(cart.cart_item.as_ref().unwrap().len(), 1);
assert_eq!(cart.cart_item.as_ref().unwrap().first(), Some(&item2));
}
#[test]
fn test_cart_valid_for() {
let cart = ShoppingCart::new();
assert_eq!(cart.valid_for.is_some(), true);
}
}