406 lines
11 KiB
Markdown
406 lines
11 KiB
Markdown
use actix_web::web::Data;
|
|
use chrono::{Datelike, DateTime, Utc};
|
|
use futures::executor::block_on;
|
|
use sqlx::{Arguments, Pool, Row, Sqlite};
|
|
use sqlx::sqlite::{SqliteArguments, SqliteRow};
|
|
|
|
use common::models::entry::Entry;
|
|
use common::models::production::Production;
|
|
|
|
use crate::traits::database::{Database, DatabaseSub};
|
|
use crate::traits::query::QuerySub;
|
|
use crate::traits::standard::{Standard, StandardSub};
|
|
|
|
impl Standard for Entry {
|
|
fn table_name() -> String {
|
|
"entry".to_string()
|
|
}
|
|
}
|
|
|
|
impl StandardSub for Entry {
|
|
fn parent_table() -> String {
|
|
"variant".to_string()
|
|
}
|
|
}
|
|
|
|
impl QuerySub<Entry> for Entry {
|
|
fn from_sqlite_row(row: SqliteRow, _parent_id: i64, pool: &Data<Pool<Sqlite>>) -> Entry {
|
|
let production: Option<Production> = match Production::get_by_id(row.get(7), pool).first() {
|
|
Some(prod) => {
|
|
Some(prod.clone())
|
|
}
|
|
None => {
|
|
None
|
|
}
|
|
};
|
|
|
|
Entry {
|
|
id: row.get(0),
|
|
charge: row.get(1),
|
|
amount_created: row.get(2),
|
|
amount_left: row.get(3),
|
|
date: row.get(4),
|
|
variant_id: row.get(5),
|
|
origin: row.get(6),
|
|
production,
|
|
}
|
|
}
|
|
|
|
fn from_sqlite_row_small(row: SqliteRow, _parent_id: i64, pool: &Data<Pool<Sqlite>>) -> Entry {
|
|
Entry {
|
|
id: row.get(0),
|
|
charge: row.get(1),
|
|
amount_created: row.get(2),
|
|
amount_left: row.get(3),
|
|
date: row.get(4),
|
|
variant_id: row.get(5),
|
|
origin: row.get(6),
|
|
production: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl DatabaseSub<Entry> for Entry {
|
|
|
|
}
|
|
|
|
impl Database<Entry> for Entry {
|
|
fn insert(&self, pool: &Data<Pool<Sqlite>>) -> i64 {
|
|
let production_id = match &self.production {
|
|
Some(production) => {
|
|
Some(production.insert(pool))
|
|
}
|
|
None => {
|
|
None
|
|
}
|
|
};
|
|
|
|
let statement = format!(
|
|
"INSERT INTO {} (charge, amount_created, amount_left, date, variant, origin_id, production_id) VALUES ($1, $2, $2, $3, $4, $5, $6)",
|
|
Entry::table_name(),
|
|
);
|
|
|
|
let charge = self.charge.as_str();
|
|
|
|
let charge = if charge.eq("000_TO_GENERATE") {
|
|
let new_charge = next_charge(pool);
|
|
insert_charge(new_charge.clone(), pool);
|
|
|
|
new_charge
|
|
} else {
|
|
self.charge.clone()
|
|
};
|
|
|
|
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(charge);
|
|
args.add(&self.amount_created);
|
|
args.add(date_time);
|
|
args.add(&self.variant_id);
|
|
args.add(&self.origin);
|
|
args.add(production_id);
|
|
|
|
let mut conn = block_on(pool.acquire()).unwrap();
|
|
let temp = block_on(
|
|
sqlx::query_with(
|
|
statement.as_str(),
|
|
args)
|
|
.execute(&mut *conn)
|
|
);
|
|
|
|
println!("Entry result:\n {:#?}", temp);
|
|
temp.unwrap().last_insert_rowid()
|
|
}
|
|
|
|
fn update(&self, pool: &Data<Pool<Sqlite>>) {
|
|
let statement = format!(
|
|
"UPDATE {} SET amount_left = $2 WHERE id = $1",
|
|
Entry::table_name(),
|
|
);
|
|
|
|
let mut args = SqliteArguments::default();
|
|
args.add(&self.id);
|
|
args.add(&self.amount_left);
|
|
|
|
println!("Updating");
|
|
|
|
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 mut conn = block_on(pool.acquire()).unwrap();
|
|
let temp = block_on(
|
|
sqlx::query(
|
|
format!("DELETE FROM {} WHERE id = {}",
|
|
Entry::table_name(),
|
|
self.id
|
|
).as_str()
|
|
).execute(&mut *conn)
|
|
);
|
|
|
|
println!("Result:\n {:#?}", temp);
|
|
}
|
|
|
|
fn get_all(pool: &Data<Pool<Sqlite>>) -> Vec<Entry> {
|
|
let mut conn = block_on(pool.acquire()).unwrap();
|
|
let res = block_on(
|
|
sqlx::query(format!("SELECT * FROM {}", Entry::table_name()).as_str())
|
|
.fetch_all(&mut *conn)
|
|
);
|
|
|
|
let mut entry: Vec<Entry> = Vec::new();
|
|
|
|
match res {
|
|
Ok(records) => {
|
|
for record in records {
|
|
entry.push(
|
|
// TODO: Parent_id
|
|
Entry::from_sqlite_row_small(record, -1, pool)
|
|
);
|
|
}
|
|
}
|
|
Err(err) => {
|
|
println!("Error while loading all entry entries:");
|
|
println!("{:#?}", err);
|
|
}
|
|
}
|
|
|
|
entry
|
|
}
|
|
|
|
fn get_by_id(id: i64, pool: &Data<Pool<Sqlite>>) -> Vec<Entry> {
|
|
let statement = format!(
|
|
"SELECT * FROM {} WHERE id = $1",
|
|
Entry::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)
|
|
);
|
|
|
|
let mut entry: Vec<Entry> = Vec::new();
|
|
|
|
match res {
|
|
Ok(records) => {
|
|
for record in records {
|
|
entry.push(
|
|
// TODO: Parent_id
|
|
Entry::from_sqlite_row(record, -1, pool)
|
|
);
|
|
}
|
|
}
|
|
Err(err) => {
|
|
println!("Error while loading all entry entries:");
|
|
println!("{:#?}", err);
|
|
}
|
|
}
|
|
|
|
entry
|
|
}
|
|
|
|
fn get_by_search(search_term: String, pool: &Data<Pool<Sqlite>>) -> Vec<Entry> {
|
|
let statement = format!(
|
|
"SELECT * FROM {} WHERE variant = {}",
|
|
Entry::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)
|
|
);
|
|
|
|
let mut entry: Vec<Entry> = Vec::new();
|
|
|
|
match res {
|
|
Ok(records) => {
|
|
for record in records {
|
|
entry.push(
|
|
// TODO: Parent_id
|
|
Entry::from_sqlite_row(record, -1, pool)
|
|
);
|
|
}
|
|
}
|
|
Err(err) => {
|
|
println!("Error while loading all entry entries:");
|
|
println!("{:#?}", err);
|
|
}
|
|
}
|
|
|
|
entry
|
|
}
|
|
}
|
|
|
|
pub fn get_entry_by_variant_and_date(variant_id: i64, date_start: String, date_end: String, pool: &Data<Pool<Sqlite>>) -> Vec<Entry> {
|
|
let statement = format!(
|
|
"SELECT entry.*
|
|
FROM entry WHERE entry.variant = $1 AND entry.date > date($2) AND entry.date < date($3)",
|
|
);
|
|
|
|
let mut args = SqliteArguments::default();
|
|
args.add(variant_id);
|
|
args.add(date_start);
|
|
args.add(date_end);
|
|
|
|
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 entries: Vec<Entry> = Vec::new();
|
|
|
|
match res {
|
|
Ok(records) => {
|
|
for record in records {
|
|
entries.push(
|
|
// TODO: Parent_id
|
|
Entry::from_sqlite_row_small(record, -1, pool)
|
|
);
|
|
}
|
|
}
|
|
Err(err) => {
|
|
println!("Error while loading entries by variant and dates:");
|
|
println!("{:#?}", err);
|
|
}
|
|
}
|
|
|
|
entries
|
|
}
|
|
|
|
pub fn get_entry_with_used_via_production(production_id: i64, pool: &Data<Pool<Sqlite>>) -> Option<Entry> {
|
|
let statement = format!(
|
|
"SELECT entry.*
|
|
FROM entry WHERE entry.production_id = $1",
|
|
);
|
|
|
|
let mut args = SqliteArguments::default();
|
|
args.add(production_id);
|
|
|
|
let mut conn = block_on(pool.acquire()).unwrap();
|
|
let res = block_on(
|
|
sqlx::query_with(
|
|
statement.as_str(),
|
|
args)
|
|
.fetch_one(&mut *conn)
|
|
);
|
|
conn.detach();
|
|
|
|
let entry: Option<Entry>;
|
|
|
|
match res {
|
|
Ok(record) => {
|
|
entry = Some(Entry::from_sqlite_row_small(record, -1, pool));
|
|
}
|
|
Err(err) => {
|
|
entry = None;
|
|
println!("Error while loading parent entry by used:");
|
|
println!("{:#?}", err);
|
|
}
|
|
}
|
|
|
|
entry
|
|
}
|
|
|
|
const CHARGE_TABLE: &str = "used_charge";
|
|
|
|
fn insert_charge(charge: String, pool: &Data<Pool<Sqlite>>) {
|
|
let statement = format!(
|
|
"INSERT INTO {} (charge) VALUES ($1)",
|
|
CHARGE_TABLE,
|
|
);
|
|
|
|
let mut args = SqliteArguments::default();
|
|
args.add(charge);
|
|
|
|
let mut conn = block_on(pool.acquire()).unwrap();
|
|
let temp = block_on(
|
|
sqlx::query_with(
|
|
statement.as_str(),
|
|
args)
|
|
.execute(&mut *conn)
|
|
);
|
|
conn.detach();
|
|
|
|
println!("Charge result:\n {:#?}", temp);
|
|
}
|
|
|
|
fn next_charge(pool: &Data<Pool<Sqlite>>) -> String {
|
|
let statement = format!(
|
|
"SELECT charge FROM {}",
|
|
CHARGE_TABLE,
|
|
);
|
|
|
|
let mut conn = block_on(pool.acquire()).unwrap();
|
|
let temp = block_on(
|
|
sqlx::query(
|
|
statement.as_str())
|
|
.fetch_all(&mut *conn)
|
|
);
|
|
conn.detach();
|
|
|
|
match temp {
|
|
Ok(charges) => {
|
|
if charges.last().is_some() {
|
|
increment_charge(charges.last().unwrap().get(0))
|
|
} else {
|
|
"A".to_string()
|
|
}
|
|
},
|
|
Err(_) => {
|
|
"A".to_string()
|
|
}
|
|
}
|
|
}
|
|
|
|
fn increment_charge(charge: String) -> String {
|
|
let mut charge: Vec<char> = charge.chars().collect();
|
|
|
|
charge.reverse();
|
|
let mut over = false;
|
|
|
|
for ch in charge.iter_mut() {
|
|
if *ch == 'Z' {
|
|
over = true;
|
|
*ch = 'A';
|
|
} else if over {
|
|
*ch = std::char::from_u32(*ch as u32 + 1).unwrap_or(*ch);
|
|
over = false;
|
|
} else {
|
|
*ch = std::char::from_u32(*ch as u32 + 1).unwrap_or(*ch);
|
|
break;
|
|
}
|
|
}
|
|
|
|
charge.reverse();
|
|
|
|
if over {
|
|
charge.push('A');
|
|
}
|
|
|
|
charge.iter().collect()
|
|
} |