diff --git a/code/src/app.rs b/code/src/app.rs index 4acdc58..e71b48a 100644 --- a/code/src/app.rs +++ b/code/src/app.rs @@ -185,16 +185,22 @@ struct MainTabViewer { salaries: Arc>>, db_oper: DBOperator, + rt: tokio::runtime::Runtime, + worker_tabs: WorkerTabViewer, worker_tree: egui_dock::DockState, material_tabs: MaterialTabViewer, material_tree: egui_dock::DockState, recipe_tab: RecipeTabViewer, - rt: tokio::runtime::Runtime, + equipment_modal_state: EquipmentModalState, salary_modal_state: SalaryModalState, + is_dark_theme: bool, interface_scale_ratio: f32, + page: i32, + elements_per_page: i32, + is_admin: bool, reporter: Reporter, } @@ -202,13 +208,14 @@ impl Default for MainTabViewer { fn default() -> Self { let rt = tokio::runtime::Runtime::new().unwrap(); let db_oper = rt.block_on(async { DBOperator::new().await }); + let elements_per_page = 5; Self { workers: Arc::new(RwLock::new( rt.block_on(async { db_oper.get_workers().await.unwrap() }), )), - equipment: Arc::new(RwLock::new( - rt.block_on(async { db_oper.get_equipment().await.unwrap() }), - )), + equipment: Arc::new(RwLock::new(rt.block_on(async { + db_oper.get_equipment(0, elements_per_page).await.unwrap() + }))), salaries: Arc::new(RwLock::new( rt.block_on(async { db_oper.get_salaries().await.unwrap() }), )), @@ -223,6 +230,10 @@ impl Default for MainTabViewer { title: "Должности".to_owned(), tab_type: TabTypes::WorkerPosition, }, + Tab { + title: "Повышения".to_owned(), + tab_type: TabTypes::WorkerPromotion, + }, ]), material_tabs: MaterialTabViewer::default(), material_tree: egui_dock::DockState::new(vec![ @@ -261,6 +272,9 @@ impl Default for MainTabViewer { }, is_admin: false, reporter: Reporter {}, + + elements_per_page, + page: 0, } } } @@ -272,10 +286,12 @@ impl MainTabViewer { )); } fn update_equipment(&mut self) { - self.equipment = Arc::new(RwLock::new( - self.rt - .block_on(async { self.db_oper.get_equipment().await.unwrap() }), - )); + self.equipment = Arc::new(RwLock::new(self.rt.block_on(async { + self.db_oper + .get_equipment(self.page, self.elements_per_page) + .await + .unwrap() + }))); } fn get_salary(&self) -> Salary { Salary { diff --git a/code/src/database.rs b/code/src/database.rs index e9a5e02..bb89f19 100644 --- a/code/src/database.rs +++ b/code/src/database.rs @@ -29,6 +29,12 @@ impl DBOperator { .await?; Ok(rets) } + pub async fn get_position_by_id(&self, id: i32) -> Result { + sqlx::query_as::<_, Position>("SELECT * FROM `position` WHERE id = ?") + .bind(id) + .fetch_one(&self.pool) + .await + } pub async fn get_workers(&self) -> Result, sqlx::Error> { let pre_rets: Vec = sqlx::query_as::<_, WorkerRow>("SELECT * FROM `worker`") .fetch_all(&self.pool) @@ -49,14 +55,42 @@ impl DBOperator { hire_date: worker.hire_date, position: ppos, is_fired: worker.is_fired, + fire_date: worker.fire_date, }); } Ok(rets) } - pub async fn get_equipment(&self) -> Result, sqlx::Error> { - let pre_rets = sqlx::query_as::<_, EquipmentRow>("SELECT * FROM `equipment`") - .fetch_all(&self.pool) - .await?; + pub async fn get_worker_by_id(&self, id: i32) -> Result { + match sqlx::query_as::<_, WorkerRow>("SELECT * FROM `worker` WHERE id = ?") + .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, sqlx::Error> { + let pre_rets = + sqlx::query_as::<_, EquipmentRow>("SELECT * FROM `equipment` LIMIT ? OFFSET ?") + .bind(count) + .bind(start) + .fetch_all(&self.pool) + .await?; let mut rets: Vec = Vec::new(); let workers = self.get_workers().await?; for eq in pre_rets { @@ -78,6 +112,26 @@ impl DBOperator { } Ok(rets) } + pub async fn get_equipment_by_id(&self, id: i32) -> Result { + 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 { match sqlx::query("INSERT INTO `equipment` (id, inv_number, maintenance_date, worker_id, name, is_written_off) VALUES(0, ?, ?, ?, ?, 0);") .bind(equipment.inv_number) @@ -132,19 +186,21 @@ impl DBOperator { } Ok(rets) } - pub async fn check_worker(&self, worker: Worker) -> Result { - let ret = sqlx::query(&format!( - "SELECT * FROM `worker` WHERE full_name = {}, position_id = {}, hire_date = {}", - worker.full_name, - worker.position.id, - worker.hire_date.to_string() - )) - .fetch_all(&self.pool) - .await?; - if ret.len() > 0 { - return Ok(true); - } - Ok(false) + pub async fn promote_worker( + &self, + worker: Worker, + position_to: Position, + date: DateTime, + ) -> Result<(), sqlx::Error> { + 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?; + sqlx::query("UPDATE worker SET position_id=? WHERE id=?;") + .bind(position_to.id) + .bind(worker.id) + .execute(&mut *tx) + .await?; + + tx.commit().await } pub async fn add_worker(&self, worker: WorkerRow) -> Result { // 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) @@ -236,20 +292,19 @@ impl DBOperator { } pub async fn update_worker(&self, worker: WorkerRow) -> Result { - match sqlx::query("UPDATE `worker` SET position_id=?, hire_date=?, is_fired=?, full_name=? WHERE id=?;") + match sqlx::query( + "UPDATE `worker` SET position_id=?, hire_date=?, is_fired=?, full_name=? WHERE id=?;", + ) .bind(worker.position_id) .bind(worker.hire_date) .bind(worker.is_fired) .bind(worker.full_name) .bind(worker.id) .execute(&self.pool) - .await{ - Ok(_) =>{ - Ok(true) - }, - Err(_)=>{ - Ok(false) - } + .await + { + Ok(_) => Ok(true), + Err(_) => Ok(false), } } pub async fn update_material_category( @@ -267,40 +322,18 @@ impl DBOperator { } } pub async fn update_material(&self, mat: MaterialRow) -> Result { - match sqlx::query( - "UPDATE `material` SET name=?, quantity=?, category_id=? WHERE id=?;", - ) - .bind(mat.name) - .bind(mat.quantity) - .bind(mat.category_id) - .bind(mat.id) - .execute(&self.pool) - .await + match sqlx::query("UPDATE `material` SET name=?, quantity=?, category_id=? WHERE id=?;") + .bind(mat.name) + .bind(mat.quantity) + .bind(mat.category_id) + .bind(mat.id) + .execute(&self.pool) + .await { Ok(_) => Ok(true), Err(_) => Ok(false), } } - pub async fn get_worker_by_id(&self, worker_id: i32) -> Result { - 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 { match sqlx::query("UPDATE `position`SET name=?, wage=? WHERE id=?") .bind(pos.name) @@ -408,16 +441,19 @@ impl DBOperator { } } pub async fn update_salary(&self, salary: Salary) -> Result { - match sqlx::query("UPDATE `salary` SET worker_id=?, salary_size=?, salary_date=?, comment=? WHERE id=?;") - .bind(salary.worker.id) - .bind(salary.salary_size) - .bind(salary.salary_date) - .bind(salary.comment) - .bind(salary.id) - .execute(&self.pool) - .await{ + match sqlx::query( + "UPDATE `salary` SET worker_id=?, salary_size=?, salary_date=?, comment=? WHERE id=?;", + ) + .bind(salary.worker.id) + .bind(salary.salary_size) + .bind(salary.salary_date) + .bind(salary.comment) + .bind(salary.id) + .execute(&self.pool) + .await + { Ok(_) => Ok(true), - Err(_) => Ok(false) + Err(_) => Ok(false), } } pub async fn remove_salary(&self, id: i32) -> Result { @@ -490,14 +526,17 @@ impl DBOperator { } } pub async fn get_recipe_elements(&self) -> Result, sqlx::Error> { - let pre_ret = sqlx::query_as::<_, RecipeElementRow>("SELECT id, recipe_id, material_id, equipment_id, quantity FROM `recipe_element`;").fetch_all(&self.pool).await; + let pre_ret = sqlx::query_as::<_, RecipeElementRow>( + "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 eqs = self.get_equipment().await.unwrap(); let mut ret: Vec = Vec::new(); for re in pre_ret.unwrap().iter() { let mat = mats.iter().find(|m| m.id == re.material_id); - let eq = eqs.iter().find(|e| e.id == re.equipment_id); + let eq = self.get_equipment_by_id(re.equipment_id).await.ok(); match (mat, eq) { (Some(m), Some(e)) => { ret.push(RecipeElement { diff --git a/code/src/main.rs b/code/src/main.rs index a1bc95e..1ed6e06 100644 --- a/code/src/main.rs +++ b/code/src/main.rs @@ -16,8 +16,8 @@ fn main() { database::estabilish_connection(); let mut native_opts = eframe::NativeOptions { viewport: egui::ViewportBuilder::default() - .with_inner_size([700.0, 300.0]) - .with_min_inner_size([650.0, 200.0]), + .with_inner_size([815.0, 300.0]) + .with_min_inner_size([750.0, 200.0]), ..Default::default() }; native_opts.renderer = eframe::Renderer::Glow; diff --git a/code/src/models.rs b/code/src/models.rs index 3053dd5..6aa6040 100644 --- a/code/src/models.rs +++ b/code/src/models.rs @@ -29,6 +29,7 @@ pub struct Worker { pub hire_date: DateTime, pub position: Position, pub is_fired: bool, + pub fire_date: Option>, } #[derive(sqlx::FromRow, sqlx::Decode)] pub struct WorkerRow { @@ -37,6 +38,7 @@ pub struct WorkerRow { pub hire_date: DateTime, pub position_id: i32, pub is_fired: bool, + pub fire_date: Option>, } #[derive(sqlx::FromRow, sqlx::Decode)] pub struct SalaryRow { diff --git a/code/src/recipe_tab.rs b/code/src/recipe_tab.rs index 88cb906..463ffdb 100644 --- a/code/src/recipe_tab.rs +++ b/code/src/recipe_tab.rs @@ -302,7 +302,7 @@ impl Default for RecipeTabViewer { rt.block_on(async { db_oper.get_materials().await.unwrap_or(Vec::new()) }), )), equipment: Arc::new(RwLock::new( - rt.block_on(async { db_oper.get_equipment().await.unwrap_or(Vec::new()) }), + rt.block_on(async { db_oper.get_equipment(0,5).await.unwrap_or(Vec::new()) }), )), process_recipe_status: RecipeModalState { diff --git a/code/src/tab.rs b/code/src/tab.rs index 92579ef..cfaf848 100644 --- a/code/src/tab.rs +++ b/code/src/tab.rs @@ -3,7 +3,6 @@ pub static TABS_CAN_BE_WINDOWS: bool = false; pub enum TabTypes { Equipment, Worker, - Position, Salary, Material, Recipe, @@ -13,6 +12,7 @@ pub enum TabTypes { Settings, WorkerList, WorkerPosition, + WorkerPromotion, MaterialList, MaterialTypeList, RecipeList,