Compare commits

..

No commits in common. "41e4bcb2d60859117109ff505914639d54718b18" and "dba801f34f65130155acd7dfe9849ea543083281" have entirely different histories.

7 changed files with 137 additions and 194 deletions

View File

@ -10,9 +10,8 @@ use crate::{
material_tab::MaterialTabViewer, material_tab::MaterialTabViewer,
misc, misc,
models::{ models::{
Equipment, EquipmentFilter, EquipmentModalState, LoginModalState, LoginStatus, Material, Equipment, EquipmentModalState, LoginModalState, LoginStatus, Material, MaterialCategory,
MaterialCategory, MaterialRow, ModalStatus, ModalWinState, Position, Salary, MaterialRow, ModalStatus, ModalWinState, Position, Salary, SalaryModalState, Worker,
SalaryModalState, Worker,
}, },
recipe_tab::RecipeTabViewer, recipe_tab::RecipeTabViewer,
reports::Reporter, reports::Reporter,
@ -185,22 +184,16 @@ struct MainTabViewer {
salaries: Arc<RwLock<Vec<Salary>>>, salaries: Arc<RwLock<Vec<Salary>>>,
db_oper: DBOperator, db_oper: DBOperator,
rt: tokio::runtime::Runtime,
worker_tabs: WorkerTabViewer, worker_tabs: WorkerTabViewer,
worker_tree: egui_dock::DockState<Tab>, worker_tree: egui_dock::DockState<Tab>,
material_tabs: MaterialTabViewer, material_tabs: MaterialTabViewer,
material_tree: egui_dock::DockState<Tab>, material_tree: egui_dock::DockState<Tab>,
recipe_tab: RecipeTabViewer, recipe_tab: RecipeTabViewer,
rt: tokio::runtime::Runtime,
equipment_modal_state: EquipmentModalState, equipment_modal_state: EquipmentModalState,
salary_modal_state: SalaryModalState, salary_modal_state: SalaryModalState,
is_dark_theme: bool, is_dark_theme: bool,
interface_scale_ratio: f32, interface_scale_ratio: f32,
page: i32,
elements_per_page: i32,
is_admin: bool, is_admin: bool,
reporter: Reporter, reporter: Reporter,
} }
@ -208,14 +201,13 @@ impl Default for MainTabViewer {
fn default() -> Self { fn default() -> Self {
let rt = tokio::runtime::Runtime::new().unwrap(); let rt = tokio::runtime::Runtime::new().unwrap();
let db_oper = rt.block_on(async { DBOperator::new().await }); let db_oper = rt.block_on(async { DBOperator::new().await });
let elements_per_page = 5;
Self { Self {
workers: Arc::new(RwLock::new( workers: Arc::new(RwLock::new(
rt.block_on(async { db_oper.get_workers().await.unwrap() }), rt.block_on(async { db_oper.get_workers().await.unwrap() }),
)), )),
equipment: Arc::new(RwLock::new(rt.block_on(async { equipment: Arc::new(RwLock::new(
db_oper.get_equipment(0, elements_per_page).await.unwrap() rt.block_on(async { db_oper.get_equipment().await.unwrap() }),
}))), )),
salaries: Arc::new(RwLock::new( salaries: Arc::new(RwLock::new(
rt.block_on(async { db_oper.get_salaries().await.unwrap() }), rt.block_on(async { db_oper.get_salaries().await.unwrap() }),
)), )),
@ -230,10 +222,6 @@ impl Default for MainTabViewer {
title: "Должности".to_owned(), title: "Должности".to_owned(),
tab_type: TabTypes::WorkerPosition, tab_type: TabTypes::WorkerPosition,
}, },
Tab {
title: "Повышения".to_owned(),
tab_type: TabTypes::WorkerPromotion,
},
]), ]),
material_tabs: MaterialTabViewer::default(), material_tabs: MaterialTabViewer::default(),
material_tree: egui_dock::DockState::new(vec![ material_tree: egui_dock::DockState::new(vec![
@ -256,7 +244,6 @@ impl Default for MainTabViewer {
can_finish: false, can_finish: false,
equipment: Equipment::default(), equipment: Equipment::default(),
status: ModalStatus::Add, status: ModalStatus::Add,
filters: EquipmentFilter::default(),
}, },
salary_modal_state: SalaryModalState { salary_modal_state: SalaryModalState {
is_open: false, is_open: false,
@ -272,9 +259,6 @@ impl Default for MainTabViewer {
}, },
is_admin: false, is_admin: false,
reporter: Reporter {}, reporter: Reporter {},
elements_per_page,
page: 0,
} }
} }
} }
@ -286,12 +270,10 @@ impl MainTabViewer {
)); ));
} }
fn update_equipment(&mut self) { fn update_equipment(&mut self) {
self.equipment = Arc::new(RwLock::new(self.rt.block_on(async { self.equipment = Arc::new(RwLock::new(
self.db_oper self.rt
.get_equipment(self.page, self.elements_per_page) .block_on(async { self.db_oper.get_equipment().await.unwrap() }),
.await ));
.unwrap()
})));
} }
fn get_salary(&self) -> Salary { fn get_salary(&self) -> Salary {
Salary { Salary {
@ -345,11 +327,7 @@ impl MainTabViewer {
} }
}); });
} }
ui.add(egui::Checkbox::new( let mut table = TableBuilder::new(ui)
&mut self.equipment_modal_state.filters.without_written_offs,
"Без списанных",
));
TableBuilder::new(ui)
.striped(true) .striped(true)
.resizable(false) .resizable(false)
.vscroll(false) .vscroll(false)
@ -381,10 +359,6 @@ impl MainTabViewer {
.body(|mut body| { .body(|mut body| {
body.ui_mut().style_mut().interaction.selectable_labels = false; body.ui_mut().style_mut().interaction.selectable_labels = false;
for eq in self.equipment.read().clone().iter() { for eq in self.equipment.read().clone().iter() {
if (self.equipment_modal_state.filters.without_written_offs
&& !eq.is_written_off)
|| !self.equipment_modal_state.filters.without_written_offs
{
body.row(20.0, |mut row| { body.row(20.0, |mut row| {
row.col(|ui| { row.col(|ui| {
ui.label(&eq.name); ui.label(&eq.name);
@ -417,7 +391,6 @@ impl MainTabViewer {
} }
}); });
} }
}
}); });
if self.equipment_modal_state.is_open { if self.equipment_modal_state.is_open {
egui::Modal::new(egui::Id::new("process_equipment_modal")).show(ui.ctx(), |ui| { egui::Modal::new(egui::Id::new("process_equipment_modal")).show(ui.ctx(), |ui| {
@ -468,6 +441,13 @@ impl MainTabViewer {
ui.end_row(); ui.end_row();
ui.label("Дата последнего\nтехобслуживания"); ui.label("Дата последнего\nтехобслуживания");
// let mut date = self
// .equipment_modal_state
// .equipment
// .maintenance_date
// .date_naive()
// .to_string();
// let bdate = date.clone();
let ndate = self let ndate = self
.equipment_modal_state .equipment_modal_state
.equipment .equipment
@ -489,6 +469,25 @@ impl MainTabViewer {
.and_local_timezone(chrono::Local) .and_local_timezone(chrono::Local)
.unwrap(); .unwrap();
} }
// if date != bdate {
// self.equipment_modal_state.equipment.maintenance_date =
// match NaiveDate::parse_from_str(&date, "%Y-%m-%d") {
// Ok(o) => {date_okay = true;
// o
// .and_hms_opt(0, 0, 0)
// .unwrap()
// .and_local_timezone(chrono::Local)
// .unwrap()},
// Err(e) => {
// date_okay = false;
// NaiveDate::default()
// .and_hms_opt(0, 0, 0)
// .unwrap()
// .and_local_timezone(chrono::Local)
// .unwrap()
// }
// };
// }
}); });
} else { } else {
ui.label("Вы уверены, что хотите удалить:"); ui.label("Вы уверены, что хотите удалить:");
@ -509,9 +508,7 @@ impl MainTabViewer {
} }
_ => { _ => {
self.equipment_modal_state.can_finish = self.equipment_modal_state.can_finish =
self.equipment_modal_state.equipment.name.len() > 0 self.equipment_modal_state.equipment.name.len() > 0 && date_okay
&& self.equipment_modal_state.equipment.inv_number.len() > 0
&& self.equipment_modal_state.equipment.worker.id != 0;
} }
} }
let resp = ui.add_enabled( let resp = ui.add_enabled(

View File

@ -29,12 +29,6 @@ impl DBOperator {
.await?; .await?;
Ok(rets) Ok(rets)
} }
pub async fn get_position_by_id(&self, id: i32) -> Result<Position, sqlx::Error> {
sqlx::query_as::<_, Position>("SELECT * FROM `position` WHERE id = ?")
.bind(id)
.fetch_one(&self.pool)
.await
}
pub async fn get_workers(&self) -> Result<Vec<Worker>, sqlx::Error> { pub async fn get_workers(&self) -> Result<Vec<Worker>, sqlx::Error> {
let pre_rets: Vec<WorkerRow> = sqlx::query_as::<_, WorkerRow>("SELECT * FROM `worker`") let pre_rets: Vec<WorkerRow> = sqlx::query_as::<_, WorkerRow>("SELECT * FROM `worker`")
.fetch_all(&self.pool) .fetch_all(&self.pool)
@ -55,40 +49,12 @@ impl DBOperator {
hire_date: worker.hire_date, hire_date: worker.hire_date,
position: ppos, position: ppos,
is_fired: worker.is_fired, is_fired: worker.is_fired,
fire_date: worker.fire_date,
}); });
} }
Ok(rets) Ok(rets)
} }
pub async fn get_worker_by_id(&self, id: i32) -> Result<Worker, sqlx::Error> { pub async fn get_equipment(&self) -> Result<Vec<Equipment>, sqlx::Error> {
match sqlx::query_as::<_, WorkerRow>("SELECT * FROM `worker` WHERE id = ?") let pre_rets = sqlx::query_as::<_, EquipmentRow>("SELECT * FROM `equipment`")
.bind(id)
.fetch_one(&self.pool)
.await
{
Ok(n) => Ok(Worker {
id: n.id,
full_name: n.full_name,
position: self
.get_position_by_id(n.position_id)
.await
.unwrap_or(Position::default()),
is_fired: n.is_fired,
hire_date: n.hire_date,
fire_date: n.fire_date,
}),
Err(e) => Err(e),
}
}
pub async fn get_equipment(
&self,
start: i32,
count: i32,
) -> Result<Vec<Equipment>, sqlx::Error> {
let pre_rets =
sqlx::query_as::<_, EquipmentRow>("SELECT * FROM `equipment` LIMIT ? OFFSET ?")
.bind(count)
.bind(start)
.fetch_all(&self.pool) .fetch_all(&self.pool)
.await?; .await?;
let mut rets: Vec<Equipment> = Vec::new(); let mut rets: Vec<Equipment> = Vec::new();
@ -112,26 +78,6 @@ impl DBOperator {
} }
Ok(rets) Ok(rets)
} }
pub async fn get_equipment_by_id(&self, id: i32) -> Result<Equipment, sqlx::Error> {
match sqlx::query_as::<_, EquipmentRow>("SELECT * FROM `equipment` WHERE id = ?")
.bind(id)
.fetch_one(&self.pool)
.await
{
Ok(n) => Ok(Equipment {
id,
name: n.name,
inv_number: n.inv_number,
maintenance_date: n.maintenance_date,
worker: self
.get_worker_by_id(n.worker_id)
.await
.unwrap_or(Worker::default()),
is_written_off: n.is_written_off,
}),
Err(e) => Err(e),
}
}
pub async fn add_equipment(&self, equipment: Equipment) -> Result<bool, sqlx::Error> { pub async fn add_equipment(&self, equipment: Equipment) -> Result<bool, sqlx::Error> {
match sqlx::query("INSERT INTO `equipment` (id, inv_number, maintenance_date, worker_id, name, is_written_off) VALUES(0, ?, ?, ?, ?, 0);") match sqlx::query("INSERT INTO `equipment` (id, inv_number, maintenance_date, worker_id, name, is_written_off) VALUES(0, ?, ?, ?, ?, 0);")
.bind(equipment.inv_number) .bind(equipment.inv_number)
@ -186,21 +132,19 @@ impl DBOperator {
} }
Ok(rets) Ok(rets)
} }
pub async fn promote_worker( pub async fn check_worker(&self, worker: Worker) -> Result<bool, sqlx::Error> {
&self, let ret = sqlx::query(&format!(
worker: Worker, "SELECT * FROM `worker` WHERE full_name = {}, position_id = {}, hire_date = {}",
position_to: Position, worker.full_name,
date: DateTime<chrono::Local>, worker.position.id,
) -> Result<(), sqlx::Error> { worker.hire_date.to_string()
let mut tx = self.pool.begin().await?; ))
sqlx::query("INSERT INTO promotion (worker_id, from_position_id, to_position_id, `date`) VALUES(?, ?, ?, ?);").bind(worker.id).bind(worker.position.id).bind(position_to.id).bind(date).execute(&mut *tx).await?; .fetch_all(&self.pool)
sqlx::query("UPDATE worker SET position_id=? WHERE id=?;")
.bind(position_to.id)
.bind(worker.id)
.execute(&mut *tx)
.await?; .await?;
if ret.len() > 0 {
tx.commit().await return Ok(true);
}
Ok(false)
} }
pub async fn add_worker(&self, worker: WorkerRow) -> Result<bool, sqlx::Error> { pub async fn add_worker(&self, worker: WorkerRow) -> Result<bool, sqlx::Error> {
// sqlx::query!("INSERT INTO Brewery.worker (id, position_id, hire_date, is_fired, full_name) VALUES(0, ?, ?, ?, ?);",worker.position.id, worker.hire_date ,worker.is_fired,worker.full_name) // sqlx::query!("INSERT INTO Brewery.worker (id, position_id, hire_date, is_fired, full_name) VALUES(0, ?, ?, ?, ?);",worker.position.id, worker.hire_date ,worker.is_fired,worker.full_name)
@ -292,19 +236,20 @@ impl DBOperator {
} }
pub async fn update_worker(&self, worker: WorkerRow) -> Result<bool, sqlx::Error> { pub async fn update_worker(&self, worker: WorkerRow) -> Result<bool, sqlx::Error> {
match sqlx::query( match sqlx::query("UPDATE `worker` SET position_id=?, hire_date=?, is_fired=?, full_name=? WHERE id=?;")
"UPDATE `worker` SET position_id=?, hire_date=?, is_fired=?, full_name=? WHERE id=?;",
)
.bind(worker.position_id) .bind(worker.position_id)
.bind(worker.hire_date) .bind(worker.hire_date)
.bind(worker.is_fired) .bind(worker.is_fired)
.bind(worker.full_name) .bind(worker.full_name)
.bind(worker.id) .bind(worker.id)
.execute(&self.pool) .execute(&self.pool)
.await .await{
{ Ok(_) =>{
Ok(_) => Ok(true), Ok(true)
Err(_) => Ok(false), },
Err(_)=>{
Ok(false)
}
} }
} }
pub async fn update_material_category( pub async fn update_material_category(
@ -322,7 +267,9 @@ impl DBOperator {
} }
} }
pub async fn update_material(&self, mat: MaterialRow) -> Result<bool, sqlx::Error> { pub async fn update_material(&self, mat: MaterialRow) -> Result<bool, sqlx::Error> {
match sqlx::query("UPDATE `material` SET name=?, quantity=?, category_id=? WHERE id=?;") match sqlx::query(
"UPDATE `material` SET name=?, quantity=?, category_id=? WHERE id=?;",
)
.bind(mat.name) .bind(mat.name)
.bind(mat.quantity) .bind(mat.quantity)
.bind(mat.category_id) .bind(mat.category_id)
@ -334,6 +281,26 @@ impl DBOperator {
Err(_) => Ok(false), Err(_) => Ok(false),
} }
} }
pub async fn get_worker_by_id(&self, worker_id: i32) -> Result<Worker, sqlx::Error> {
let preret = sqlx::query_as::<_, WorkerRow>("SELECT * FROM `worker` WHERE id = ?;")
.bind(worker_id)
.fetch_all(&self.pool)
.await?;
let poses = self.get_position().await?;
let ret = Ok(Worker {
id: preret[0].id,
full_name: preret[0].full_name.clone(),
hire_date: preret[0].hire_date,
is_fired: preret[0].is_fired,
position: poses
.iter()
.find(|&pos| &pos.id == &preret[0].position_id)
.unwrap()
.clone(),
});
ret
}
pub async fn update_position(&self, pos: Position) -> Result<bool, sqlx::Error> { pub async fn update_position(&self, pos: Position) -> Result<bool, sqlx::Error> {
match sqlx::query("UPDATE `position`SET name=?, wage=? WHERE id=?") match sqlx::query("UPDATE `position`SET name=?, wage=? WHERE id=?")
.bind(pos.name) .bind(pos.name)
@ -441,19 +408,16 @@ impl DBOperator {
} }
} }
pub async fn update_salary(&self, salary: Salary) -> Result<bool, sqlx::Error> { pub async fn update_salary(&self, salary: Salary) -> Result<bool, sqlx::Error> {
match sqlx::query( match sqlx::query("UPDATE `salary` SET worker_id=?, salary_size=?, salary_date=?, comment=? WHERE id=?;")
"UPDATE `salary` SET worker_id=?, salary_size=?, salary_date=?, comment=? WHERE id=?;",
)
.bind(salary.worker.id) .bind(salary.worker.id)
.bind(salary.salary_size) .bind(salary.salary_size)
.bind(salary.salary_date) .bind(salary.salary_date)
.bind(salary.comment) .bind(salary.comment)
.bind(salary.id) .bind(salary.id)
.execute(&self.pool) .execute(&self.pool)
.await .await{
{
Ok(_) => Ok(true), Ok(_) => Ok(true),
Err(_) => Ok(false), Err(_) => Ok(false)
} }
} }
pub async fn remove_salary(&self, id: i32) -> Result<bool, sqlx::Error> { pub async fn remove_salary(&self, id: i32) -> Result<bool, sqlx::Error> {
@ -526,17 +490,14 @@ impl DBOperator {
} }
} }
pub async fn get_recipe_elements(&self) -> Result<Vec<RecipeElement>, sqlx::Error> { pub async fn get_recipe_elements(&self) -> Result<Vec<RecipeElement>, sqlx::Error> {
let pre_ret = sqlx::query_as::<_, RecipeElementRow>( let pre_ret = sqlx::query_as::<_, RecipeElementRow>("SELECT id, recipe_id, material_id, equipment_id, quantity FROM `recipe_element`;").fetch_all(&self.pool).await;
"SELECT id, recipe_id, material_id, equipment_id, quantity FROM `recipe_element`;",
)
.fetch_all(&self.pool)
.await;
let mats = self.get_materials().await.unwrap(); let mats = self.get_materials().await.unwrap();
let eqs = self.get_equipment().await.unwrap();
let mut ret: Vec<RecipeElement> = Vec::new(); let mut ret: Vec<RecipeElement> = Vec::new();
for re in pre_ret.unwrap().iter() { for re in pre_ret.unwrap().iter() {
let mat = mats.iter().find(|m| m.id == re.material_id); let mat = mats.iter().find(|m| m.id == re.material_id);
let eq = self.get_equipment_by_id(re.equipment_id).await.ok(); let eq = eqs.iter().find(|e| e.id == re.equipment_id);
match (mat, eq) { match (mat, eq) {
(Some(m), Some(e)) => { (Some(m), Some(e)) => {
ret.push(RecipeElement { ret.push(RecipeElement {

View File

@ -16,8 +16,8 @@ fn main() {
database::estabilish_connection(); database::estabilish_connection();
let mut native_opts = eframe::NativeOptions { let mut native_opts = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default() viewport: egui::ViewportBuilder::default()
.with_inner_size([815.0, 300.0]) .with_inner_size([700.0, 300.0])
.with_min_inner_size([750.0, 200.0]), .with_min_inner_size([650.0, 200.0]),
..Default::default() ..Default::default()
}; };
native_opts.renderer = eframe::Renderer::Glow; native_opts.renderer = eframe::Renderer::Glow;

View File

@ -1,5 +1,3 @@
use std::str::FromStr;
use bigdecimal::ToPrimitive; use bigdecimal::ToPrimitive;
use chrono::Datelike; use chrono::Datelike;
@ -19,9 +17,3 @@ pub fn jiff_to_naivedate(date: jiff::civil::Date) -> chrono::NaiveDate {
) )
.unwrap() .unwrap()
} }
pub fn is_date_okay(date: String) -> bool {
match chrono::NaiveDate::from_str(&date) {
Ok(_) => true,
Err(_) => false,
}
}

View File

@ -29,7 +29,6 @@ pub struct Worker {
pub hire_date: DateTime<chrono::Local>, pub hire_date: DateTime<chrono::Local>,
pub position: Position, pub position: Position,
pub is_fired: bool, pub is_fired: bool,
pub fire_date: Option<DateTime<chrono::Local>>,
} }
#[derive(sqlx::FromRow, sqlx::Decode)] #[derive(sqlx::FromRow, sqlx::Decode)]
pub struct WorkerRow { pub struct WorkerRow {
@ -38,7 +37,6 @@ pub struct WorkerRow {
pub hire_date: DateTime<chrono::Local>, pub hire_date: DateTime<chrono::Local>,
pub position_id: i32, pub position_id: i32,
pub is_fired: bool, pub is_fired: bool,
pub fire_date: Option<DateTime<chrono::Local>>,
} }
#[derive(sqlx::FromRow, sqlx::Decode)] #[derive(sqlx::FromRow, sqlx::Decode)]
pub struct SalaryRow { pub struct SalaryRow {
@ -158,12 +156,11 @@ pub struct Promotion {
} }
#[derive(Default)] #[derive(Default)]
pub struct EquipmentModalState { pub struct EquipmentModalState{
pub is_open: bool, pub is_open: bool,
pub can_finish: bool, pub can_finish: bool,
pub equipment: Equipment, pub equipment: Equipment,
pub status: ModalStatus, pub status: ModalStatus,
pub filters: EquipmentFilter,
} }
#[derive(Default)] #[derive(Default)]
@ -223,7 +220,3 @@ pub enum LoginStatus {
Login, Login,
Finished, Finished,
} }
#[derive(Default)]
pub struct EquipmentFilter {
pub without_written_offs: bool,
}

View File

@ -302,7 +302,7 @@ impl Default for RecipeTabViewer {
rt.block_on(async { db_oper.get_materials().await.unwrap_or(Vec::new()) }), rt.block_on(async { db_oper.get_materials().await.unwrap_or(Vec::new()) }),
)), )),
equipment: Arc::new(RwLock::new( equipment: Arc::new(RwLock::new(
rt.block_on(async { db_oper.get_equipment(0,5).await.unwrap_or(Vec::new()) }), rt.block_on(async { db_oper.get_equipment().await.unwrap_or(Vec::new()) }),
)), )),
process_recipe_status: RecipeModalState { process_recipe_status: RecipeModalState {

View File

@ -3,6 +3,7 @@ pub static TABS_CAN_BE_WINDOWS: bool = false;
pub enum TabTypes { pub enum TabTypes {
Equipment, Equipment,
Worker, Worker,
Position,
Salary, Salary,
Material, Material,
Recipe, Recipe,
@ -12,7 +13,6 @@ pub enum TabTypes {
Settings, Settings,
WorkerList, WorkerList,
WorkerPosition, WorkerPosition,
WorkerPromotion,
MaterialList, MaterialList,
MaterialTypeList, MaterialTypeList,
RecipeList, RecipeList,