8.9 KiB
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<Pool>) -> 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<Pool<Sqlite>>) -> 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<Pool>) -> i64 {
let statement = format!(
"INSERT INTO {} (creation_date, description) VALUES ($1, $2)",
Delivery::table_name(),
);
let mut date_time: DateTime<Utc> = 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<Pool<Sqlite>>) {
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> = 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<DateTime<Utc>> = 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<Pool<Sqlite>>) {
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<Pool<Sqlite>>) -> Vec<Delivery> {
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<Delivery> = 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<Pool<Sqlite>>) -> Vec<Delivery> {
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<Delivery> = 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<Pool<Sqlite>>) -> Vec<Delivery> {
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<Delivery> = 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
}
}