225 lines
6.3 KiB
Rust
225 lines
6.3 KiB
Rust
|
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||
|
//
|
||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||
|
|
||
|
use derive_builder::Builder;
|
||
|
use derive_getters::Getters;
|
||
|
use derive_more::{Display, Error};
|
||
|
use serde::{Deserialize, Serialize};
|
||
|
use uuid::Uuid;
|
||
|
|
||
|
use super::product_aggregate::Price;
|
||
|
|
||
|
#[derive(Debug, Error, Display, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
||
|
pub enum AddProductCommandError {
|
||
|
NameIsEmpty,
|
||
|
}
|
||
|
|
||
|
#[derive(
|
||
|
Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters, Builder,
|
||
|
)]
|
||
|
pub struct UnvalidatedAddProductCommand {
|
||
|
name: String,
|
||
|
description: Option<String>,
|
||
|
image: Option<String>,
|
||
|
category_id: Uuid,
|
||
|
sku_able: bool,
|
||
|
price: Price,
|
||
|
adding_by: Uuid,
|
||
|
}
|
||
|
|
||
|
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters)]
|
||
|
pub struct AddProductCommand {
|
||
|
name: String,
|
||
|
description: Option<String>,
|
||
|
image: Option<String>,
|
||
|
category_id: Uuid,
|
||
|
sku_able: bool,
|
||
|
price: Price,
|
||
|
adding_by: Uuid,
|
||
|
}
|
||
|
|
||
|
impl UnvalidatedAddProductCommand {
|
||
|
pub fn validate(self) -> Result<AddProductCommand, AddProductCommandError> {
|
||
|
let description: Option<String> = if let Some(description) = self.description {
|
||
|
let description = description.trim();
|
||
|
if description.is_empty() {
|
||
|
None
|
||
|
} else {
|
||
|
Some(description.to_owned())
|
||
|
}
|
||
|
} else {
|
||
|
None
|
||
|
};
|
||
|
|
||
|
let image: Option<String> = if let Some(image) = self.image {
|
||
|
let image = image.trim();
|
||
|
if image.is_empty() {
|
||
|
None
|
||
|
} else {
|
||
|
Some(image.to_owned())
|
||
|
}
|
||
|
} else {
|
||
|
None
|
||
|
};
|
||
|
|
||
|
let name = self.name.trim().to_owned();
|
||
|
if name.is_empty() {
|
||
|
return Err(AddProductCommandError::NameIsEmpty);
|
||
|
}
|
||
|
|
||
|
Ok(AddProductCommand {
|
||
|
name,
|
||
|
description,
|
||
|
image,
|
||
|
category_id: self.category_id,
|
||
|
sku_able: self.sku_able,
|
||
|
price: self.price,
|
||
|
adding_by: self.adding_by,
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[cfg(test)]
|
||
|
pub mod tests {
|
||
|
use super::*;
|
||
|
|
||
|
use crate::{
|
||
|
inventory::domain::product_aggregate::{Currency, PriceBuilder},
|
||
|
utils::uuid::tests::UUID,
|
||
|
};
|
||
|
|
||
|
pub fn get_command() -> AddProductCommand {
|
||
|
let name = "foo";
|
||
|
let adding_by = UUID;
|
||
|
let category_id = Uuid::new_v4();
|
||
|
let sku_able = false;
|
||
|
let image = Some("image".to_string());
|
||
|
let description = Some("description".to_string());
|
||
|
|
||
|
let price = PriceBuilder::default()
|
||
|
.minor(0)
|
||
|
.major(100)
|
||
|
.currency(Currency::INR)
|
||
|
.build()
|
||
|
.unwrap();
|
||
|
|
||
|
let cmd = UnvalidatedAddProductCommandBuilder::default()
|
||
|
.name(name.into())
|
||
|
.description(description.clone())
|
||
|
.image(image.clone())
|
||
|
.category_id(category_id.clone())
|
||
|
.adding_by(adding_by.clone())
|
||
|
.sku_able(sku_able)
|
||
|
.price(price.clone())
|
||
|
.build()
|
||
|
.unwrap();
|
||
|
|
||
|
cmd.validate().unwrap()
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_description_and_image_none() {
|
||
|
let name = "foo";
|
||
|
let adding_by = UUID;
|
||
|
let category_id = Uuid::new_v4();
|
||
|
let sku_able = false;
|
||
|
|
||
|
let price = PriceBuilder::default()
|
||
|
.minor(0)
|
||
|
.major(100)
|
||
|
.currency(Currency::INR)
|
||
|
.build()
|
||
|
.unwrap();
|
||
|
|
||
|
// description = None
|
||
|
let cmd = UnvalidatedAddProductCommandBuilder::default()
|
||
|
.name(name.into())
|
||
|
.description(None)
|
||
|
.image(None)
|
||
|
.category_id(category_id.clone())
|
||
|
.adding_by(adding_by.clone())
|
||
|
.sku_able(sku_able)
|
||
|
.price(price.clone())
|
||
|
.build()
|
||
|
.unwrap();
|
||
|
|
||
|
let cmd = cmd.validate().unwrap();
|
||
|
|
||
|
assert_eq!(cmd.name(), name);
|
||
|
assert_eq!(cmd.description(), &None);
|
||
|
assert_eq!(cmd.adding_by(), &adding_by);
|
||
|
assert_eq!(cmd.category_id(), &category_id);
|
||
|
assert_eq!(cmd.image(), &None);
|
||
|
assert_eq!(cmd.sku_able(), &sku_able);
|
||
|
assert_eq!(cmd.price(), &price);
|
||
|
}
|
||
|
#[test]
|
||
|
fn test_description_some() {
|
||
|
let name = "foo";
|
||
|
let adding_by = UUID;
|
||
|
let category_id = Uuid::new_v4();
|
||
|
let sku_able = false;
|
||
|
let image = Some("image".to_string());
|
||
|
let description = Some("description".to_string());
|
||
|
|
||
|
let price = PriceBuilder::default()
|
||
|
.minor(0)
|
||
|
.major(100)
|
||
|
.currency(Currency::INR)
|
||
|
.build()
|
||
|
.unwrap();
|
||
|
|
||
|
let cmd = UnvalidatedAddProductCommandBuilder::default()
|
||
|
.name(name.into())
|
||
|
.description(description.clone())
|
||
|
.image(image.clone())
|
||
|
.category_id(category_id.clone())
|
||
|
.adding_by(adding_by.clone())
|
||
|
.sku_able(sku_able)
|
||
|
.price(price.clone())
|
||
|
.build()
|
||
|
.unwrap();
|
||
|
|
||
|
let cmd = cmd.validate().unwrap();
|
||
|
|
||
|
assert_eq!(cmd.name(), name);
|
||
|
assert_eq!(cmd.description(), &description);
|
||
|
assert_eq!(cmd.adding_by(), &adding_by);
|
||
|
assert_eq!(cmd.category_id(), &category_id);
|
||
|
assert_eq!(cmd.image(), &image);
|
||
|
assert_eq!(cmd.sku_able(), &sku_able);
|
||
|
assert_eq!(cmd.price(), &price);
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_name_is_empty() {
|
||
|
let adding_by = UUID;
|
||
|
let category_id = Uuid::new_v4();
|
||
|
let sku_able = false;
|
||
|
let image = Some("image".to_string());
|
||
|
let description = Some("description".to_string());
|
||
|
|
||
|
let price = PriceBuilder::default()
|
||
|
.minor(0)
|
||
|
.major(100)
|
||
|
.currency(Currency::INR)
|
||
|
.build()
|
||
|
.unwrap();
|
||
|
|
||
|
let cmd = UnvalidatedAddProductCommandBuilder::default()
|
||
|
.name("".into())
|
||
|
.description(description.clone())
|
||
|
.image(image.clone())
|
||
|
.category_id(category_id.clone())
|
||
|
.adding_by(adding_by.clone())
|
||
|
.sku_able(sku_able)
|
||
|
.price(price.clone())
|
||
|
.build()
|
||
|
.unwrap();
|
||
|
|
||
|
// AddProductCommandError::NameIsEmpty
|
||
|
assert_eq!(cmd.validate(), Err(AddProductCommandError::NameIsEmpty))
|
||
|
}
|
||
|
}
|