From 0a9831bfffdea7ace7d1bbe6421c24aaa1f7759f Mon Sep 17 00:00:00 2001 From: Samuel Shuert Date: Mon, 29 Jun 2026 19:12:03 +0000 Subject: [PATCH] feat(backend): Connect Batches to database fix(backend): correct ingredient type --- .../20260623204328_ingredients.up.sql | 2 +- .../20260623210026_customers.up.sql | 2 +- backend/src/models/batch.rs | 81 +++++++++++++++++-- backend/src/models/customer.rs | 18 +++-- backend/src/models/ingredient.rs | 49 +++++++---- 5 files changed, 124 insertions(+), 28 deletions(-) diff --git a/backend/migrations/20260623204328_ingredients.up.sql b/backend/migrations/20260623204328_ingredients.up.sql index 40e3a5b..8906ef5 100644 --- a/backend/migrations/20260623204328_ingredients.up.sql +++ b/backend/migrations/20260623204328_ingredients.up.sql @@ -17,6 +17,6 @@ CREATE TABLE ingredients ( date_recieved TIMESTAMPTZ NOT NULL DEFAULT now(), date_opened TIMESTAMPTZ, date_last_used TIMESTAMPTZ, - finished BOOLEAN DEFAULT false, + finished BOOLEAN NOT NULL DEFAULT false, lot VARCHAR NOT NULL ); diff --git a/backend/migrations/20260623210026_customers.up.sql b/backend/migrations/20260623210026_customers.up.sql index 7ce1f0a..2acf356 100644 --- a/backend/migrations/20260623210026_customers.up.sql +++ b/backend/migrations/20260623210026_customers.up.sql @@ -2,5 +2,5 @@ CREATE TABLE customers ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR NOT NULL, - code VARCHAR + code VARCHAR NOT NULL ); diff --git a/backend/src/models/batch.rs b/backend/src/models/batch.rs index 305acc9..16fd789 100644 --- a/backend/src/models/batch.rs +++ b/backend/src/models/batch.rs @@ -26,6 +26,7 @@ pub struct BatchUpdate { pub struct BatchCreate { flavor: Uuid, lot_number: String, + ingredients: Vec, } impl Update for BatchUpdate { @@ -58,22 +59,59 @@ impl CrudBackend for Batch { } async fn create_inner(conn: &mut PgConnection, create: Self::Create) -> Result { - todo!() + let batch = sqlx::query_as!( + Batch, + r#"INSERT INTO batches (flavor, lot_number) VALUES ($1, $2) RETURNING *"#, + create.flavor, + create.lot_number + ) + .fetch_one(&mut *conn) + .await?; + + for ingredient in &create.ingredients { + sqlx::query!( + r#" + INSERT INTO batch_ingredients (batch_id, ingredient_id) VALUES ($1, $2)"#, + batch.id, + ingredient.id + ) + .execute(&mut *conn) + .await?; + } + + Ok(batch) } async fn read_inner<'a>( conn: impl sqlx::prelude::Executor<'a, Database = sqlx::Postgres>, id: Self::Identifier, ) -> Result { - todo!() + let batch = sqlx::query_as!(Batch, r#"SELECT * FROM batches WHERE id = $1"#, id) + .fetch_one(conn) + .await?; + + Ok(batch) } async fn update_inner(&mut self, conn: &mut PgConnection) -> Result<()> { - todo!() + sqlx::query!( + r#"UPDATE batches SET flavor = $1, lot_number = $2 WHERE id = $3"#, + self.flavor, + self.lot_number, + self.id + ) + .execute(conn) + .await?; + + Ok(()) } async fn delete_inner(&self, conn: &mut PgConnection) -> Result<()> { - todo!() + sqlx::query!(r#"DELETE FROM batches WHERE id = $1"#, self.id) + .execute(conn) + .await?; + + Ok(()) } } @@ -83,7 +121,15 @@ impl Batch { conn: &mut PgConnection, ingredient_id: Uuid, ) -> Result<()> { - todo!() + sqlx::query!( + r#"DELETE FROM batch_ingredients WHERE batch_id = $1 AND ingredient_id = $2"#, + self.id, + ingredient_id + ) + .execute(conn) + .await?; + + Ok(()) } pub async fn add_ingredient( @@ -91,13 +137,34 @@ impl Batch { conn: &mut PgConnection, ingredient_id: Uuid, ) -> Result<()> { - todo!() + sqlx::query!( + r#"INSERT INTO batch_ingredients (batch_id, ingredient_id) VALUES ($1, $2)"#, + self.id, + ingredient_id + ) + .execute(conn) + .await?; + + Ok(()) } pub async fn get_ingredients<'a>( &self, conn: impl sqlx::prelude::Executor<'a, Database = sqlx::Postgres>, ) -> Result> { - todo!() + let ingredients = sqlx::query_as!( + Ingredient, + r#" + SELECT ingredients.* + FROM ingredients + INNER JOIN batch_ingredients ON ingredients.id = batch_ingredients.ingredient_id + WHERE batch_ingredients.batch_id = $1 + "#, + self.id + ) + .fetch_all(conn) + .await?; + + Ok(ingredients) } } diff --git a/backend/src/models/customer.rs b/backend/src/models/customer.rs index cf9a648..f41bd69 100644 --- a/backend/src/models/customer.rs +++ b/backend/src/models/customer.rs @@ -14,14 +14,14 @@ pub struct Customer { #[derive(Debug, Deserialize, Serialize)] pub struct CustomerUpdate { - pub name: Option, - pub code: Option, + name: Option, + code: Option, } #[derive(Debug, Deserialize, Serialize)] pub struct CustomerCreate { - flavor: Uuid, - lot_number: String, + name: String, + code: String, } impl Update for CustomerUpdate { @@ -48,7 +48,15 @@ impl CrudBackend for Customer { } async fn create_inner(conn: &mut PgConnection, create: Self::Create) -> Result { - todo!() + sqlx::query_as!( + Customer, + r#"INSERT INTO customers (name, code) VALUES ($1, $2) RETURNING *"#, + create.name, + create.code + ) + .fetch_one(&mut *conn) + .await + .map_err(Into::into) } async fn read_inner<'a>( diff --git a/backend/src/models/ingredient.rs b/backend/src/models/ingredient.rs index c84f00d..cb4a75d 100644 --- a/backend/src/models/ingredient.rs +++ b/backend/src/models/ingredient.rs @@ -72,34 +72,55 @@ impl CrudBackend for IngredientType { #[derive(Debug, Deserialize, Serialize, Clone, FromRow)] pub struct Ingredient { pub id: Uuid, - pub created_at: DateTime, - pub flavor: Uuid, - pub lot_number: String, + pub ingredient_type: Uuid, + pub supplier: Uuid, + pub date_recieved: DateTime, + pub date_opened: Option>, + pub date_last_used: Option>, + pub finished: bool, + pub lot: String, } #[derive(Debug, Deserialize, Serialize)] pub struct IngredientUpdate { - created_at: Option>, - flavor: Option, - lot_number: Option, + ingredient_type: Option, + supplier: Option, + date_recieved: Option>, + date_opened: Option>>, + date_last_used: Option>>, + finished: Option, + lot: Option, } #[derive(Debug, Deserialize, Serialize)] pub struct IngredientCreate { - flavor: Uuid, - lot_number: String, + ingredient_type: Uuid, + supplier: Uuid, + date_recieved: DateTime, + date_opened: Option>, + date_last_used: Option>, + finished: bool, + lot: String, } impl Update for IngredientUpdate { fn apply(self, other: &mut Ingredient) -> bool { let Self { - flavor, - created_at, - lot_number, + ingredient_type, + supplier, + date_recieved, + date_opened, + date_last_used, + finished, + lot, } = self; - flavor.apply_to(&mut other.flavor) - | created_at.apply_to(&mut other.created_at) - | lot_number.apply_to(&mut other.lot_number) + ingredient_type.apply_to(&mut other.ingredient_type) + | supplier.apply_to(&mut other.supplier) + | date_recieved.apply_to(&mut other.date_recieved) + | date_opened.apply_to(&mut other.date_opened) + | date_last_used.apply_to(&mut other.date_last_used) + | finished.apply_to(&mut other.finished) + | lot.apply_to(&mut other.lot) } } -- 2.51.2