use actix_web::web::Data; use chrono::{Datelike, DateTime, Timelike, Utc}; use futures::executor::block_on; use sqlx::{Arguments, Pool, Row, Sqlite}; use sqlx::sqlite::{SqliteArguments, SqliteRow}; use common::models::delivery::Delivery; use common::models::delivery_for::DeliveryFor; use common::models::delivery_item::DeliveryItem; use crate::impls::delivery_items_entry::DeliveryItemEntry; use crate::traits::database::{Database, DatabaseSub}; use crate::traits::query::Query; use crate::traits::standard::Standard; impl Standard for Delivery { fn table_name() -> String { "delivery".to_string() } } impl Query for Delivery { fn from_sqlite_row(row: SqliteRow, pool: &Data>) -> Delivery { let delivery_for: Vec = DeliveryFor::get_by_parent_id(row.get(0), pool); let delivery_items: Vec = DeliveryItem::get_by_parent_id(row.get(0), pool); Delivery { id: row.get(0), description: row.get(3), creation_date: row.get(1), received_all_date: row.get(2), delivery_for, delivery_items } } fn from_sqlite_row_small(row: SqliteRow, _pool: &Data>) -> Delivery { Delivery { id: row.get(0), description: row.get(3), creation_date: row.get(1), received_all_date: row.get(2), delivery_for: vec![], delivery_items: vec![] } } } impl Database for Delivery { fn insert(&self, pool: &Data>) -> i64 { let statement = format!( "INSERT INTO {} (creation_date, description) VALUES ($1, $2)", Delivery::table_name(), ); let mut date_time: DateTime = Utc::now(); date_time = date_time.with_day(21).unwrap(); date_time = date_time.with_month(09).unwrap(); //date_time = date_time.with_hour(10).unwrap(); let mut args = SqliteArguments::default(); args.add(date_time); args.add(&self.description); let mut conn = block_on(pool.acquire()).unwrap(); let temp = block_on( sqlx::query_with( statement.as_str(), args) .execute(&mut *conn) ); println!("Result:\n {:#?}", temp); temp.unwrap().last_insert_rowid() } fn update(&self, pool: &Data>) { let statement = format!( "UPDATE {} SET description = $2, received_all_date = $3 WHERE id = $1", Delivery::table_name(), ); let mut delivered = true; for delivery_item in &self.delivery_items { if delivery_item.total_amount_needed > delivery_item.received_amount { delivered = false; } } let mut date_time: DateTime = Utc::now(); date_time = date_time.with_day(21).unwrap(); date_time = date_time.with_month(09).unwrap(); //date_time = date_time.with_hour(10).unwrap(); let date_time: Option> = match delivered { true => {Some(date_time)} false => {None} }; let mut args = SqliteArguments::default(); args.add(&self.id); args.add(&self.description); args.add(date_time); println!("Updating Delivery"); let mut conn = block_on(pool.acquire()).unwrap(); let temp = block_on( sqlx::query_with( statement.as_str(), args) .execute(&mut *conn) ); println!("Result:\n {:#?}", temp); } fn delete(&self, pool: &Data>) { let received_amounts: f64 = self.delivery_items.iter().map(|x| x.received_amount).sum(); if received_amounts == 0.0 { let mut conn = block_on(pool.acquire()).unwrap(); // Delete delivery for let temp = block_on( sqlx::query( format!("DELETE FROM {} WHERE delivery_id = {}", DeliveryFor::table_name(), self.id ).as_str() ).execute(&mut *conn) ); println!("Result:\n {:#?}", temp); // Delete delivery item entry for delivery_item in &self.delivery_items { let temp = block_on( sqlx::query( format!("DELETE FROM {} WHERE delivery_item_id = {}", DeliveryItemEntry::table_name(), delivery_item.id ).as_str() ).execute(&mut *conn) ); println!("Result:\n {:#?}", temp); } // Delete delivery item let temp = block_on( sqlx::query( format!("DELETE FROM {} WHERE delivery_id = {}", DeliveryItem::table_name(), self.id ).as_str() ).execute(&mut *conn) ); println!("Result:\n {:#?}", temp); // Delete delivery let temp = block_on( sqlx::query( format!("DELETE FROM {} WHERE id = {}", Delivery::table_name(), self.id ).as_str() ).execute(&mut *conn) ); println!("Result:\n {:#?}", temp); } else { println!("Can not delete delivery, already something delivered."); } } fn get_all(pool: &Data>) -> Vec { let mut conn = block_on(pool.acquire()).unwrap(); let res = block_on( sqlx::query(format!("SELECT * FROM {}", Delivery::table_name()).as_str()) .fetch_all(&mut *conn) ); conn.detach(); let mut deliveries: Vec = Vec::new(); match res { Ok(records) => { for record in records { deliveries.push( Delivery::from_sqlite_row_small(record, pool) ); } } Err(err) => { println!("Error while loading all deliveries:"); println!("{:#?}", err); } } deliveries } fn get_by_id(id: i64, pool: &Data>) -> Vec { let statement = format!( "SELECT * FROM {} WHERE id = $1", Delivery::table_name(), ); let mut args = SqliteArguments::default(); args.add(id); let mut conn = block_on(pool.acquire()).unwrap(); let res = block_on( sqlx::query_with( statement.as_str(), args) .fetch_all(&mut *conn) ); conn.detach(); let mut deliveries: Vec = Vec::new(); match res { Ok(records) => { for record in records { deliveries.push( Delivery::from_sqlite_row(record, pool) ); } } Err(err) => { println!("Error while loading deliveries with id: {}:", id); println!("{:#?}", err); } } deliveries } fn get_by_search(search_term: String, pool: &Data>) -> Vec { let statement = format!( "SELECT * FROM {} WHERE creation_date like \"%{}%\"", Delivery::table_name(), search_term, ); let mut conn = block_on(pool.acquire()).unwrap(); let res = block_on( sqlx::query( statement.as_str()) .fetch_all(&mut *conn) ); conn.detach(); let mut deliveries: Vec = Vec::new(); match res { Ok(records) => { for record in records { deliveries.push( Delivery::from_sqlite_row_small(record, pool) ); } } Err(err) => { println!("Error while loading deliveries with search term: {}:", search_term); println!("{:#?}", err); } } deliveries } }