feat: kot add service
This commit is contained in:
parent
ddd0716380
commit
6115a9adde
7 changed files with 248 additions and 6 deletions
129
src/ordering/application/services/add_kot_service.rs
Normal file
129
src/ordering/application/services/add_kot_service.rs
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use derive_builder::Builder;
|
||||||
|
use mockall::predicate::*;
|
||||||
|
use mockall::*;
|
||||||
|
use time::OffsetDateTime;
|
||||||
|
|
||||||
|
use super::errors::*;
|
||||||
|
use crate::ordering::{
|
||||||
|
application::port::output::db::kot_id_exists::*,
|
||||||
|
application::port::output::db::order_id_exists::*,
|
||||||
|
domain::{add_kot_command::*, kot_added_event::*, kot_aggregate::*},
|
||||||
|
};
|
||||||
|
use crate::utils::uuid::*;
|
||||||
|
|
||||||
|
#[automock]
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
pub trait AddKotUseCase: Send + Sync {
|
||||||
|
async fn add_kot(&self, cmd: AddKotCommand) -> OrderingResult<KotAddedEvent>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type AddKotServiceObj = Arc<dyn AddKotUseCase>;
|
||||||
|
|
||||||
|
#[derive(Clone, Builder)]
|
||||||
|
pub struct AddKotService {
|
||||||
|
db_kot_id_exists: KotIDExistsDBPortObj,
|
||||||
|
db_order_id_exists: OrderIDExistsDBPortObj,
|
||||||
|
get_uuid: GetUUIDInterfaceObj,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl AddKotUseCase for AddKotService {
|
||||||
|
async fn add_kot(&self, cmd: AddKotCommand) -> OrderingResult<KotAddedEvent> {
|
||||||
|
if !self
|
||||||
|
.db_order_id_exists
|
||||||
|
.order_id_exists(cmd.order_id())
|
||||||
|
.await?
|
||||||
|
{
|
||||||
|
return Err(OrderingError::OrderIDNotFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut kot_id = self.get_uuid.get_uuid();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if self.db_kot_id_exists.kot_id_exists(&kot_id).await? {
|
||||||
|
kot_id = self.get_uuid.get_uuid();
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let kot = KotBuilder::default()
|
||||||
|
.created_time(OffsetDateTime::now_utc())
|
||||||
|
.order_id(*cmd.order_id())
|
||||||
|
.kot_id(kot_id)
|
||||||
|
.deleted(false)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Ok(KotAddedEventBuilder::default()
|
||||||
|
.added_by_user(*cmd.adding_by())
|
||||||
|
.kot(kot)
|
||||||
|
.build()
|
||||||
|
.unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use crate::ordering::domain::kot_added_event::tests::get_added_kot_event_from_command;
|
||||||
|
use crate::utils::uuid::tests::UUID;
|
||||||
|
use crate::{tests::bdd::*, utils::uuid::tests::mock_get_uuid};
|
||||||
|
|
||||||
|
pub fn mock_add_kot_service(times: Option<usize>, cmd: AddKotCommand) -> AddKotServiceObj {
|
||||||
|
let mut m = MockAddKotUseCase::new();
|
||||||
|
|
||||||
|
let res = get_added_kot_event_from_command(&cmd);
|
||||||
|
if let Some(times) = times {
|
||||||
|
m.expect_add_kot()
|
||||||
|
.times(times)
|
||||||
|
.returning(move |_| Ok(res.clone()));
|
||||||
|
} else {
|
||||||
|
m.expect_add_kot().returning(move |_| Ok(res.clone()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Arc::new(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_service() {
|
||||||
|
let cmd = AddKotCommand::get_cmd();
|
||||||
|
|
||||||
|
let s = AddKotServiceBuilder::default()
|
||||||
|
.db_kot_id_exists(mock_kot_id_exists_db_port_false(IS_CALLED_ONLY_ONCE))
|
||||||
|
.db_order_id_exists(mock_order_id_exists_db_port_true(IS_CALLED_ONLY_ONCE))
|
||||||
|
.get_uuid(mock_get_uuid(IS_CALLED_ONLY_ONCE))
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let res = s.add_kot(cmd.clone()).await.unwrap();
|
||||||
|
assert_eq!(res.kot().order_id(), cmd.order_id());
|
||||||
|
assert!(!res.kot().deleted());
|
||||||
|
assert_eq!(res.added_by_user(), cmd.adding_by());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_service_order_id_doesnt_exist() {
|
||||||
|
let cmd = AddKotCommand::get_cmd();
|
||||||
|
|
||||||
|
let s = AddKotServiceBuilder::default()
|
||||||
|
.db_kot_id_exists(mock_kot_id_exists_db_port_false(IS_NEVER_CALLED))
|
||||||
|
.db_order_id_exists(mock_order_id_exists_db_port_false(IS_CALLED_ONLY_ONCE))
|
||||||
|
.get_uuid(mock_get_uuid(IS_NEVER_CALLED))
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
s.add_kot(cmd.clone()).await,
|
||||||
|
Err(OrderingError::OrderIDNotFound)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ use mockall::*;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
|
|
||||||
//services
|
//services
|
||||||
|
pub mod add_kot_service;
|
||||||
pub mod add_line_item_service;
|
pub mod add_line_item_service;
|
||||||
pub mod add_order_service;
|
pub mod add_order_service;
|
||||||
pub mod delete_line_item_service;
|
pub mod delete_line_item_service;
|
||||||
|
@ -24,6 +25,7 @@ pub trait OrderingServicesInterface: Send + Sync {
|
||||||
fn add_order(&self) -> add_order_service::AddOrderServiceObj;
|
fn add_order(&self) -> add_order_service::AddOrderServiceObj;
|
||||||
fn update_order(&self) -> update_order_service::UpdateOrderServiceObj;
|
fn update_order(&self) -> update_order_service::UpdateOrderServiceObj;
|
||||||
fn delete_order(&self) -> delete_order_service::DeleteOrderServiceObj;
|
fn delete_order(&self) -> delete_order_service::DeleteOrderServiceObj;
|
||||||
|
fn add_kot(&self) -> add_kot_service::AddKotServiceObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Builder)]
|
#[derive(Clone, Builder)]
|
||||||
|
@ -34,6 +36,7 @@ pub struct OrderingServices {
|
||||||
add_order: add_order_service::AddOrderServiceObj,
|
add_order: add_order_service::AddOrderServiceObj,
|
||||||
update_order: update_order_service::UpdateOrderServiceObj,
|
update_order: update_order_service::UpdateOrderServiceObj,
|
||||||
delete_order: delete_order_service::DeleteOrderServiceObj,
|
delete_order: delete_order_service::DeleteOrderServiceObj,
|
||||||
|
add_kot: add_kot_service::AddKotServiceObj,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OrderingServicesInterface for OrderingServices {
|
impl OrderingServicesInterface for OrderingServices {
|
||||||
|
@ -59,4 +62,8 @@ impl OrderingServicesInterface for OrderingServices {
|
||||||
fn delete_order(&self) -> delete_order_service::DeleteOrderServiceObj {
|
fn delete_order(&self) -> delete_order_service::DeleteOrderServiceObj {
|
||||||
self.delete_order.clone()
|
self.delete_order.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_kot(&self) -> add_kot_service::AddKotServiceObj {
|
||||||
|
self.add_kot.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
58
src/ordering/domain/add_kot_command.rs
Normal file
58
src/ordering/domain/add_kot_command.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// 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 serde::{Deserialize, Serialize};
|
||||||
|
use time::OffsetDateTime;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters, Builder,
|
||||||
|
)]
|
||||||
|
pub struct AddKotCommand {
|
||||||
|
adding_by: Uuid,
|
||||||
|
|
||||||
|
#[builder(default = "OffsetDateTime::now_utc()")]
|
||||||
|
created_time: OffsetDateTime,
|
||||||
|
order_id: Uuid,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use time::macros::datetime;
|
||||||
|
|
||||||
|
use crate::utils::uuid::tests::UUID;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl AddKotCommand {
|
||||||
|
pub fn get_cmd() -> Self {
|
||||||
|
let order_id = UUID;
|
||||||
|
let adding_by = UUID;
|
||||||
|
|
||||||
|
AddKotCommandBuilder::default()
|
||||||
|
.adding_by(adding_by)
|
||||||
|
.created_time(datetime!(1970-01-01 0:00 UTC))
|
||||||
|
.order_id(order_id)
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cmd() {
|
||||||
|
let order_id = UUID;
|
||||||
|
let adding_by = UUID;
|
||||||
|
|
||||||
|
let cmd = AddKotCommandBuilder::default()
|
||||||
|
.adding_by(adding_by)
|
||||||
|
.order_id(order_id)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(*cmd.order_id(), order_id);
|
||||||
|
assert_eq!(*cmd.adding_by(), adding_by);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,9 +6,10 @@ use mockall::predicate::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
add_line_item_command::AddLineItemCommand, add_order_command::AddOrderCommand,
|
add_kot_command::AddKotCommand, add_line_item_command::AddLineItemCommand,
|
||||||
delete_line_item_command::DeleteLineItemCommand, delete_order_command::DeleteOrderCommand,
|
add_order_command::AddOrderCommand, delete_line_item_command::DeleteLineItemCommand,
|
||||||
update_line_item_command::UpdateLineItemCommand, update_order_command::UpdateOrderCommand,
|
delete_order_command::DeleteOrderCommand, update_line_item_command::UpdateLineItemCommand,
|
||||||
|
update_order_command::UpdateOrderCommand,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
|
@ -19,4 +20,5 @@ pub enum OrderingCommand {
|
||||||
AddOrder(AddOrderCommand),
|
AddOrder(AddOrderCommand),
|
||||||
UpdateOrder(UpdateOrderCommand),
|
UpdateOrder(UpdateOrderCommand),
|
||||||
DeleteOrder(DeleteOrderCommand),
|
DeleteOrder(DeleteOrderCommand),
|
||||||
|
AddKot(AddKotCommand),
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,10 @@ use cqrs_es::DomainEvent;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
line_item_added_event::LineItemAddedEvent, line_item_deleted_event::LineItemDeletedEvent,
|
kot_added_event::KotAddedEvent, line_item_added_event::LineItemAddedEvent,
|
||||||
line_item_updated_event::LineItemUpdatedEvent, order_added_event::OrderAddedEvent,
|
line_item_deleted_event::LineItemDeletedEvent, line_item_updated_event::LineItemUpdatedEvent,
|
||||||
order_deleted_event::OrderDeletedEvent, order_updated_event::OrderUpdatedEvent,
|
order_added_event::OrderAddedEvent, order_deleted_event::OrderDeletedEvent,
|
||||||
|
order_updated_event::OrderUpdatedEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
|
@ -19,6 +20,7 @@ pub enum OrderingEvent {
|
||||||
OrderAdded(OrderAddedEvent),
|
OrderAdded(OrderAddedEvent),
|
||||||
OrderUpdated(OrderUpdatedEvent),
|
OrderUpdated(OrderUpdatedEvent),
|
||||||
OrderDeleted(OrderDeletedEvent),
|
OrderDeleted(OrderDeletedEvent),
|
||||||
|
KotAdded(KotAddedEvent),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DomainEvent for OrderingEvent {
|
impl DomainEvent for OrderingEvent {
|
||||||
|
@ -34,6 +36,7 @@ impl DomainEvent for OrderingEvent {
|
||||||
OrderingEvent::OrderAdded { .. } => "OrderingOrderAdded",
|
OrderingEvent::OrderAdded { .. } => "OrderingOrderAdded",
|
||||||
OrderingEvent::OrderUpdated { .. } => "OrderingOrderUpdated",
|
OrderingEvent::OrderUpdated { .. } => "OrderingOrderUpdated",
|
||||||
OrderingEvent::OrderDeleted { .. } => "OrderingOrderDeleted",
|
OrderingEvent::OrderDeleted { .. } => "OrderingOrderDeleted",
|
||||||
|
OrderingEvent::KotAdded { .. } => "OrderingKotAdded",
|
||||||
};
|
};
|
||||||
|
|
||||||
e.to_string()
|
e.to_string()
|
||||||
|
|
41
src/ordering/domain/kot_added_event.rs
Normal file
41
src/ordering/domain/kot_added_event.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// 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 serde::{Deserialize, Serialize};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use super::kot_aggregate::Kot;
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Clone, Debug, Builder, Serialize, Deserialize, Getters, Eq, PartialEq, Ord, PartialOrd,
|
||||||
|
)]
|
||||||
|
pub struct KotAddedEvent {
|
||||||
|
added_by_user: Uuid,
|
||||||
|
|
||||||
|
kot: Kot,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub mod tests {
|
||||||
|
use crate::ordering::domain::add_kot_command::AddKotCommand;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub fn get_added_kot_event_from_command(cmd: &AddKotCommand) -> KotAddedEvent {
|
||||||
|
let kot = Kot::get_kot();
|
||||||
|
|
||||||
|
KotAddedEventBuilder::default()
|
||||||
|
.added_by_user(cmd.adding_by().clone())
|
||||||
|
.kot(kot)
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_event() {
|
||||||
|
get_added_kot_event_from_command(&AddKotCommand::get_cmd());
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ pub mod line_item_aggregate;
|
||||||
pub mod order_aggregate;
|
pub mod order_aggregate;
|
||||||
|
|
||||||
// commands
|
// commands
|
||||||
|
pub mod add_kot_command;
|
||||||
pub mod add_line_item_command;
|
pub mod add_line_item_command;
|
||||||
pub mod add_order_command;
|
pub mod add_order_command;
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
|
@ -18,6 +19,7 @@ pub mod update_order_command;
|
||||||
|
|
||||||
// events
|
// events
|
||||||
pub mod events;
|
pub mod events;
|
||||||
|
pub mod kot_added_event;
|
||||||
pub mod line_item_added_event;
|
pub mod line_item_added_event;
|
||||||
pub mod line_item_deleted_event;
|
pub mod line_item_deleted_event;
|
||||||
pub mod line_item_updated_event;
|
pub mod line_item_updated_event;
|
||||||
|
|
Loading…
Reference in a new issue