2024-07-15 17:47:50 +05:30
|
|
|
// 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;
|
|
|
|
|
2024-07-15 19:50:39 +05:30
|
|
|
use super::product_aggregate::{Price, Quantity};
|
2024-07-15 17:47:50 +05:30
|
|
|
|
|
|
|
#[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,
|
2024-07-15 19:50:39 +05:30
|
|
|
quantity: Quantity,
|
2024-07-15 17:47:50 +05:30
|
|
|
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,
|
2024-07-15 19:50:39 +05:30
|
|
|
quantity: Quantity,
|
2024-07-15 17:47:50 +05:30
|
|
|
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,
|
2024-07-15 19:50:39 +05:30
|
|
|
quantity: self.quantity,
|
2024-07-15 17:47:50 +05:30
|
|
|
adding_by: self.adding_by,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
pub mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
use crate::{
|
2024-07-15 19:50:39 +05:30
|
|
|
inventory::domain::product_aggregate::{
|
|
|
|
Currency, PriceBuilder, QuantityBuilder, QuantityUnit,
|
|
|
|
},
|
2024-07-15 17:47:50 +05:30
|
|
|
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();
|
|
|
|
|
2024-07-15 19:50:39 +05:30
|
|
|
let quantity = QuantityBuilder::default()
|
|
|
|
.number(1)
|
|
|
|
.unit(QuantityUnit::DiscreteNumber)
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
|
|
|
|
2024-07-15 17:47:50 +05:30
|
|
|
let cmd = UnvalidatedAddProductCommandBuilder::default()
|
|
|
|
.name(name.into())
|
|
|
|
.description(description.clone())
|
|
|
|
.image(image.clone())
|
|
|
|
.category_id(category_id.clone())
|
|
|
|
.adding_by(adding_by.clone())
|
2024-07-15 19:50:39 +05:30
|
|
|
.quantity(quantity)
|
2024-07-15 17:47:50 +05:30
|
|
|
.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();
|
2024-07-15 19:50:39 +05:30
|
|
|
let quantity = QuantityBuilder::default()
|
|
|
|
.number(1)
|
|
|
|
.unit(QuantityUnit::DiscreteNumber)
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
2024-07-15 17:47:50 +05:30
|
|
|
|
|
|
|
// description = None
|
|
|
|
let cmd = UnvalidatedAddProductCommandBuilder::default()
|
|
|
|
.name(name.into())
|
|
|
|
.description(None)
|
|
|
|
.image(None)
|
|
|
|
.category_id(category_id.clone())
|
|
|
|
.adding_by(adding_by.clone())
|
2024-07-15 19:50:39 +05:30
|
|
|
.quantity(quantity.clone())
|
2024-07-15 17:47:50 +05:30
|
|
|
.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);
|
2024-07-15 19:50:39 +05:30
|
|
|
assert_eq!(cmd.quantity(), &quantity);
|
2024-07-15 17:47:50 +05:30
|
|
|
}
|
|
|
|
#[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();
|
2024-07-15 19:50:39 +05:30
|
|
|
let quantity = QuantityBuilder::default()
|
|
|
|
.number(1)
|
|
|
|
.unit(QuantityUnit::DiscreteNumber)
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
2024-07-15 17:47:50 +05:30
|
|
|
|
|
|
|
let cmd = UnvalidatedAddProductCommandBuilder::default()
|
|
|
|
.name(name.into())
|
|
|
|
.description(description.clone())
|
|
|
|
.image(image.clone())
|
|
|
|
.category_id(category_id.clone())
|
2024-07-15 19:50:39 +05:30
|
|
|
.quantity(quantity.clone())
|
2024-07-15 17:47:50 +05:30
|
|
|
.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);
|
2024-07-15 19:50:39 +05:30
|
|
|
assert_eq!(cmd.quantity(), &quantity);
|
2024-07-15 17:47:50 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
#[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();
|
2024-07-15 19:50:39 +05:30
|
|
|
let quantity = QuantityBuilder::default()
|
|
|
|
.number(1)
|
|
|
|
.unit(QuantityUnit::DiscreteNumber)
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
2024-07-15 17:47:50 +05:30
|
|
|
|
|
|
|
let cmd = UnvalidatedAddProductCommandBuilder::default()
|
|
|
|
.name("".into())
|
|
|
|
.description(description.clone())
|
|
|
|
.image(image.clone())
|
|
|
|
.category_id(category_id.clone())
|
|
|
|
.adding_by(adding_by.clone())
|
2024-07-15 19:50:39 +05:30
|
|
|
.quantity(quantity)
|
2024-07-15 17:47:50 +05:30
|
|
|
.sku_able(sku_able)
|
|
|
|
.price(price.clone())
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// AddProductCommandError::NameIsEmpty
|
|
|
|
assert_eq!(cmd.validate(), Err(AddProductCommandError::NameIsEmpty))
|
|
|
|
}
|
|
|
|
}
|