Compare commits

...

2 commits

Author SHA1 Message Date
3746eb211f Merge pull request 'feat: apply events to ordering Views' (#110) from ordering-view into master
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Reviewed-on: #110
2024-09-18 18:34:22 +05:30
2017ca5e97
feat: apply events to ordering Views
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-18 18:04:36 +05:30
12 changed files with 285 additions and 24 deletions

View file

@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO cqrs_ordering_product_query (\n version,\n name,\n description,\n image,\n product_id,\n category_id,\n price_major,\n price_minor,\n price_currency,\n sku_able,\n quantity_minor_unit,\n quantity_minor_number,\n quantity_major_unit,\n quantity_major_number,\n\n deleted\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15\n );",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int8",
"Text",
"Text",
"Text",
"Uuid",
"Uuid",
"Int4",
"Int4",
"Text",
"Bool",
"Text",
"Int4",
"Text",
"Int4",
"Bool"
]
},
"nullable": []
},
"hash": "3d45cb28b61bac689d137c7415fcd620552e1390a443f4c8907b344a8526ff07"
}

View file

@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "SELECT \n product_id, version\n FROM\n cqrs_ordering_product_query\n WHERE\n product_id = $1;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "product_id",
"type_info": "Uuid"
},
{
"ordinal": 1,
"name": "version",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Uuid"
]
},
"nullable": [
false,
false
]
},
"hash": "9645865fd899d0bb983bb9da43567e172b2c49855971ee58692bed595d347228"
}

View file

@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE\n cqrs_ordering_product_query\n SET\n version = $1,\n name = $2,\n description = $3,\n image = $4,\n product_id = $5,\n category_id = $6,\n price_major = $7,\n price_minor = $8,\n price_currency = $9,\n sku_able = $10,\n quantity_minor_unit = $11,\n quantity_minor_number = $12,\n quantity_major_unit = $13,\n quantity_major_number = $14,\n deleted = $15;",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int8",
"Text",
"Text",
"Text",
"Uuid",
"Uuid",
"Int4",
"Int4",
"Text",
"Bool",
"Text",
"Int4",
"Text",
"Int4",
"Bool"
]
},
"nullable": []
},
"hash": "c3a3348990d0fea3225fd2be2ef883ca1649e21fd28c1a35a0ffffce6035fd75"
}

View file

@ -0,0 +1,100 @@
{
"db_name": "PostgreSQL",
"query": "SELECT \n name,\n description,\n image,\n product_id,\n category_id,\n price_major,\n price_minor,\n price_currency,\n sku_able,\n quantity_minor_unit,\n quantity_minor_number,\n quantity_major_unit,\n quantity_major_number,\n deleted\n FROM\n cqrs_ordering_product_query\n WHERE\n product_id = $1;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "name",
"type_info": "Text"
},
{
"ordinal": 1,
"name": "description",
"type_info": "Text"
},
{
"ordinal": 2,
"name": "image",
"type_info": "Text"
},
{
"ordinal": 3,
"name": "product_id",
"type_info": "Uuid"
},
{
"ordinal": 4,
"name": "category_id",
"type_info": "Uuid"
},
{
"ordinal": 5,
"name": "price_major",
"type_info": "Int4"
},
{
"ordinal": 6,
"name": "price_minor",
"type_info": "Int4"
},
{
"ordinal": 7,
"name": "price_currency",
"type_info": "Text"
},
{
"ordinal": 8,
"name": "sku_able",
"type_info": "Bool"
},
{
"ordinal": 9,
"name": "quantity_minor_unit",
"type_info": "Text"
},
{
"ordinal": 10,
"name": "quantity_minor_number",
"type_info": "Int4"
},
{
"ordinal": 11,
"name": "quantity_major_unit",
"type_info": "Text"
},
{
"ordinal": 12,
"name": "quantity_major_number",
"type_info": "Int4"
},
{
"ordinal": 13,
"name": "deleted",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Uuid"
]
},
"nullable": [
false,
true,
true,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "ddf0a8ae68a2f52e9ae3723d36983dfb42518b07940e620f4b45eb92b8a54a80"
}

View file

@ -32,12 +32,23 @@ pub struct CategoryView {
// design the events to carry the balance information instead. // design the events to carry the balance information instead.
impl View<Category> for CategoryView { impl View<Category> for CategoryView {
fn update(&mut self, event: &EventEnvelope<Category>) { fn update(&mut self, event: &EventEnvelope<Category>) {
if let OrderingEvent::CategoryAdded(val) = &event.payload { match &event.payload {
self.name = val.name().into(); OrderingEvent::CategoryAdded(val) => {
self.description = val.description().clone(); self.name = val.name().into();
self.category_id = *val.category_id(); self.description = val.description().clone();
self.store_id = *val.store_id(); self.category_id = *val.category_id();
self.deleted = false; self.store_id = *val.store_id();
self.deleted = false;
}
OrderingEvent::CategoryUpdated(e) => {
let val = e.new_category();
self.name = val.name().into();
self.description = val.description().clone();
self.category_id = *val.category_id();
self.store_id = *val.store_id();
}
_ => (),
} }
} }
} }

View file

@ -55,6 +55,12 @@ impl View<Customization> for CustomizationView {
self.deleted = false; self.deleted = false;
} }
OrderingEvent::CustomizationUpdated(val) => {
self.name = val.new_customization().name().into();
self.product_id = *val.new_customization().product_id();
self.customization_id = *val.new_customization().customization_id();
}
_ => (), _ => (),
} }
} }

View file

@ -71,6 +71,13 @@ impl View<Kot> for KotView {
self.deleted = false; self.deleted = false;
} }
OrderingEvent::KotUpdated(val) => {
self.order_id = *val.new_kot().order_id();
self.kot_id = *val.new_kot().kot_id();
self.created_time = val.new_kot().created_time().clone();
}
OrderingEvent::KotDeleted(_) => self.deleted = true,
_ => (), _ => (),
} }
} }

View file

@ -112,6 +112,21 @@ impl View<LineItem> for LineItemView {
self.deleted = false; self.deleted = false;
} }
OrderingEvent::LineItemUpdated(val) => {
let new = val.new_line_item();
self.product_name = new.product_name().into();
self.product_id = *new.product_id();
self.line_item_id = *new.line_item_id();
self.quantity_major_number = *new.quantity().major().number() as i32;
self.quantity_minor_number = *new.quantity().minor().number() as i32;
self.quantity_major_unit = new.quantity().major().unit().to_string();
self.quantity_minor_unit = new.quantity().minor().unit().to_string();
self.created_time = new.created_time().clone();
self.kot_id = *new.kot_id();
}
OrderingEvent::LineItemDeleted(_) => self.deleted = true,
_ => (), _ => (),
} }
} }

View file

@ -24,6 +24,7 @@ mod order_id_exists;
mod order_view; mod order_view;
mod product_id_exists; mod product_id_exists;
mod product_name_exists_for_category; mod product_name_exists_for_category;
mod product_view;
mod store_id_exists; mod store_id_exists;
mod store_name_exists; mod store_name_exists;
mod store_view; mod store_view;

View file

@ -66,6 +66,14 @@ impl View<Order> for OrderView {
self.deleted = false; self.deleted = false;
} }
OrderingEvent::OrderUpdated(e) => {
let new = e.new_order();
self.customer_name = new.customer_name().into();
self.order_id = *new.order_id();
self.created_time = new.created_time().clone();
}
OrderingEvent::OrderDeleted(_) => self.deleted = true,
_ => (), _ => (),
} }
} }

View file

@ -11,14 +11,14 @@ use serde::{Deserialize, Serialize};
use uuid::Uuid; use uuid::Uuid;
use super::errors::*; use super::errors::*;
use super::InventoryDBPostgresAdapter; use super::OrderingDBPostgresAdapter;
use crate::inventory::domain::events::InventoryEvent; use crate::ordering::domain::events::OrderingEvent;
use crate::inventory::domain::product_aggregate::{Product, ProductBuilder}; use crate::ordering::domain::product_aggregate::{Product, ProductBuilder};
use crate::types::currency::*; use crate::types::currency::*;
use crate::types::quantity::*; use crate::types::quantity::*;
use crate::utils::parse_aggregate_id::parse_aggregate_id; use crate::utils::parse_aggregate_id::parse_aggregate_id;
pub const NEW_PRODUCT_NON_UUID: &str = "new_product_non_uuid-asdfa"; pub const NEW_PRODUCT_NON_UUID: &str = "new_product_ordering_non_uuid-asdfa";
// The view for a Product query, for a standard http application this should // The view for a Product query, for a standard http application this should
// be designed to reflect the response dto that will be returned to a user. // be designed to reflect the response dto that will be returned to a user.
@ -92,7 +92,7 @@ impl From<ProductView> for Product {
impl View<Product> for ProductView { impl View<Product> for ProductView {
fn update(&mut self, event: &EventEnvelope<Product>) { fn update(&mut self, event: &EventEnvelope<Product>) {
match &event.payload { match &event.payload {
InventoryEvent::ProductAdded(val) => { OrderingEvent::ProductAdded(val) => {
self.name = val.name().into(); self.name = val.name().into();
self.description = val.description().clone(); self.description = val.description().clone();
self.image = val.image().clone(); self.image = val.image().clone();
@ -112,13 +112,32 @@ impl View<Product> for ProductView {
self.deleted = false; self.deleted = false;
} }
OrderingEvent::ProductUpdated(e) => {
let val = e.new_product();
self.name = val.name().into();
self.description = val.description().clone();
self.image = val.image().clone();
self.product_id = *val.product_id();
self.category_id = *val.category_id();
self.sku_able = *val.sku_able();
self.price_minor = *val.price().minor() as i32;
self.price_major = *val.price().major() as i32;
self.price_currency = val.price().currency().to_string();
self.quantity_major_number = *val.quantity().major().number() as i32;
self.quantity_minor_number = *val.quantity().minor().number() as i32;
self.quantity_major_unit = val.quantity().major().unit().to_string();
self.quantity_minor_unit = val.quantity().minor().unit().to_string();
}
_ => (), _ => (),
} }
} }
} }
#[async_trait] #[async_trait]
impl ViewRepository<ProductView, Product> for InventoryDBPostgresAdapter { impl ViewRepository<ProductView, Product> for OrderingDBPostgresAdapter {
async fn load(&self, product_id: &str) -> Result<Option<ProductView>, PersistenceError> { async fn load(&self, product_id: &str) -> Result<Option<ProductView>, PersistenceError> {
let product_id = match parse_aggregate_id(product_id, NEW_PRODUCT_NON_UUID)? { let product_id = match parse_aggregate_id(product_id, NEW_PRODUCT_NON_UUID)? {
Some((val, _)) => return Ok(Some(val)), Some((val, _)) => return Ok(Some(val)),
@ -143,7 +162,7 @@ impl ViewRepository<ProductView, Product> for InventoryDBPostgresAdapter {
quantity_major_number, quantity_major_number,
deleted deleted
FROM FROM
cqrs_inventory_product_query cqrs_ordering_product_query
WHERE WHERE
product_id = $1;", product_id = $1;",
product_id product_id
@ -182,7 +201,7 @@ impl ViewRepository<ProductView, Product> for InventoryDBPostgresAdapter {
quantity_major_number, quantity_major_number,
deleted deleted
FROM FROM
cqrs_inventory_product_query cqrs_ordering_product_query
WHERE WHERE
product_id = $1;", product_id = $1;",
product_id product_id
@ -201,7 +220,7 @@ impl ViewRepository<ProductView, Product> for InventoryDBPostgresAdapter {
"SELECT "SELECT
product_id, version product_id, version
FROM FROM
cqrs_inventory_product_query cqrs_ordering_product_query
WHERE WHERE
product_id = $1;", product_id = $1;",
product_id product_id
@ -223,7 +242,7 @@ impl ViewRepository<ProductView, Product> for InventoryDBPostgresAdapter {
0 => { 0 => {
let version = context.version + 1; let version = context.version + 1;
sqlx::query!( sqlx::query!(
"INSERT INTO cqrs_inventory_product_query ( "INSERT INTO cqrs_ordering_product_query (
version, version,
name, name,
description, description,
@ -268,7 +287,7 @@ impl ViewRepository<ProductView, Product> for InventoryDBPostgresAdapter {
let version = context.version + 1; let version = context.version + 1;
sqlx::query!( sqlx::query!(
"UPDATE "UPDATE
cqrs_inventory_product_query cqrs_ordering_product_query
SET SET
version = $1, version = $1,
name = $2, name = $2,
@ -312,7 +331,7 @@ impl ViewRepository<ProductView, Product> for InventoryDBPostgresAdapter {
} }
#[async_trait] #[async_trait]
impl Query<Product> for InventoryDBPostgresAdapter { impl Query<Product> for OrderingDBPostgresAdapter {
async fn dispatch(&self, product_id: &str, events: &[EventEnvelope<Product>]) { async fn dispatch(&self, product_id: &str, events: &[EventEnvelope<Product>]) {
let res = self let res = self
.load_with_context(product_id) .load_with_context(product_id)

View file

@ -32,12 +32,22 @@ pub struct StoreView {
// design the events to carry the balance information instead. // design the events to carry the balance information instead.
impl View<Store> for StoreView { impl View<Store> for StoreView {
fn update(&mut self, event: &EventEnvelope<Store>) { fn update(&mut self, event: &EventEnvelope<Store>) {
if let OrderingEvent::StoreAdded(val) = &event.payload { match &event.payload {
self.name = val.name().into(); OrderingEvent::StoreAdded(val) => {
self.address = val.address().clone(); self.name = val.name().into();
self.store_id = *val.store_id(); self.address = val.address().clone();
self.owner = *val.owner(); self.store_id = *val.store_id();
self.deleted = false; self.owner = *val.owner();
self.deleted = false;
}
OrderingEvent::StoreUpdated(e) => {
let val = e.new_store();
self.name = val.name().into();
self.address = val.address().clone();
self.store_id = *val.store_id();
self.owner = *val.owner();
}
_ => (),
} }
} }
} }