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;
|
||||
|
||||
//services
|
||||
pub mod add_kot_service;
|
||||
pub mod add_line_item_service;
|
||||
pub mod add_order_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 update_order(&self) -> update_order_service::UpdateOrderServiceObj;
|
||||
fn delete_order(&self) -> delete_order_service::DeleteOrderServiceObj;
|
||||
fn add_kot(&self) -> add_kot_service::AddKotServiceObj;
|
||||
}
|
||||
|
||||
#[derive(Clone, Builder)]
|
||||
|
@ -34,6 +36,7 @@ pub struct OrderingServices {
|
|||
add_order: add_order_service::AddOrderServiceObj,
|
||||
update_order: update_order_service::UpdateOrderServiceObj,
|
||||
delete_order: delete_order_service::DeleteOrderServiceObj,
|
||||
add_kot: add_kot_service::AddKotServiceObj,
|
||||
}
|
||||
|
||||
impl OrderingServicesInterface for OrderingServices {
|
||||
|
@ -59,4 +62,8 @@ impl OrderingServicesInterface for OrderingServices {
|
|||
fn delete_order(&self) -> delete_order_service::DeleteOrderServiceObj {
|
||||
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 super::{
|
||||
add_line_item_command::AddLineItemCommand, add_order_command::AddOrderCommand,
|
||||
delete_line_item_command::DeleteLineItemCommand, delete_order_command::DeleteOrderCommand,
|
||||
update_line_item_command::UpdateLineItemCommand, update_order_command::UpdateOrderCommand,
|
||||
add_kot_command::AddKotCommand, add_line_item_command::AddLineItemCommand,
|
||||
add_order_command::AddOrderCommand, delete_line_item_command::DeleteLineItemCommand,
|
||||
delete_order_command::DeleteOrderCommand, update_line_item_command::UpdateLineItemCommand,
|
||||
update_order_command::UpdateOrderCommand,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
|
||||
|
@ -19,4 +20,5 @@ pub enum OrderingCommand {
|
|||
AddOrder(AddOrderCommand),
|
||||
UpdateOrder(UpdateOrderCommand),
|
||||
DeleteOrder(DeleteOrderCommand),
|
||||
AddKot(AddKotCommand),
|
||||
}
|
||||
|
|
|
@ -6,9 +6,10 @@ use cqrs_es::DomainEvent;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{
|
||||
line_item_added_event::LineItemAddedEvent, line_item_deleted_event::LineItemDeletedEvent,
|
||||
line_item_updated_event::LineItemUpdatedEvent, order_added_event::OrderAddedEvent,
|
||||
order_deleted_event::OrderDeletedEvent, order_updated_event::OrderUpdatedEvent,
|
||||
kot_added_event::KotAddedEvent, line_item_added_event::LineItemAddedEvent,
|
||||
line_item_deleted_event::LineItemDeletedEvent, line_item_updated_event::LineItemUpdatedEvent,
|
||||
order_added_event::OrderAddedEvent, order_deleted_event::OrderDeletedEvent,
|
||||
order_updated_event::OrderUpdatedEvent,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
|
||||
|
@ -19,6 +20,7 @@ pub enum OrderingEvent {
|
|||
OrderAdded(OrderAddedEvent),
|
||||
OrderUpdated(OrderUpdatedEvent),
|
||||
OrderDeleted(OrderDeletedEvent),
|
||||
KotAdded(KotAddedEvent),
|
||||
}
|
||||
|
||||
impl DomainEvent for OrderingEvent {
|
||||
|
@ -34,6 +36,7 @@ impl DomainEvent for OrderingEvent {
|
|||
OrderingEvent::OrderAdded { .. } => "OrderingOrderAdded",
|
||||
OrderingEvent::OrderUpdated { .. } => "OrderingOrderUpdated",
|
||||
OrderingEvent::OrderDeleted { .. } => "OrderingOrderDeleted",
|
||||
OrderingEvent::KotAdded { .. } => "OrderingKotAdded",
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
// commands
|
||||
pub mod add_kot_command;
|
||||
pub mod add_line_item_command;
|
||||
pub mod add_order_command;
|
||||
pub mod commands;
|
||||
|
@ -18,6 +19,7 @@ pub mod update_order_command;
|
|||
|
||||
// events
|
||||
pub mod events;
|
||||
pub mod kot_added_event;
|
||||
pub mod line_item_added_event;
|
||||
pub mod line_item_deleted_event;
|
||||
pub mod line_item_updated_event;
|
||||
|
|
Loading…
Reference in a new issue