Merge branch 'master' of https://gitea.suz-ppk.ru/UltraGoose/BreweryControlSystem
commit
cd4c66e5c6
|
|
@ -8,7 +8,7 @@ anyhow = "1.0.102"
|
||||||
bigdecimal = "0.4.10"
|
bigdecimal = "0.4.10"
|
||||||
chrono = { version = "0.4.44", features = ["serde"] }
|
chrono = { version = "0.4.44", features = ["serde"] }
|
||||||
dotenvy = "0.15.7"
|
dotenvy = "0.15.7"
|
||||||
eframe = "0.34.2"
|
eframe = {version = "0.34.2", features = ["glow"]}
|
||||||
egui = "0.34.2"
|
egui = "0.34.2"
|
||||||
egui_dock = "0.19.1"
|
egui_dock = "0.19.1"
|
||||||
egui_extras = {version = "0.34.2", features = ["datepicker"]}
|
egui_extras = {version = "0.34.2", features = ["datepicker"]}
|
||||||
|
|
@ -20,5 +20,3 @@ tokio={version = "1.52.3", features = ["full"]}
|
||||||
|
|
||||||
[target.'cfg(target_os="windows")'.dependencies]
|
[target.'cfg(target_os="windows")'.dependencies]
|
||||||
eframe = {version ="0.34.2",default-features=false, features=["glow"]}
|
eframe = {version ="0.34.2",default-features=false, features=["glow"]}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ use crate::{
|
||||||
database::DBOperator,
|
database::DBOperator,
|
||||||
material_tab::MaterialTabViewer,
|
material_tab::MaterialTabViewer,
|
||||||
models::{
|
models::{
|
||||||
Equipment, LoginModalState, Material, MaterialCategory, MaterialRow, ModalStatus,
|
Equipment, LoginModalState, LoginStatus, Material, MaterialCategory, MaterialRow,
|
||||||
ModalWinState, Position, Worker,
|
ModalStatus, ModalWinState, Position, Worker,
|
||||||
},
|
},
|
||||||
tab::*,
|
tab::*,
|
||||||
worker_tab::{self, *},
|
worker_tab::{self, *},
|
||||||
|
|
@ -82,6 +82,19 @@ impl App<'_> {
|
||||||
|
|
||||||
impl eframe::App for App<'_> {
|
impl eframe::App for App<'_> {
|
||||||
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
|
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
|
||||||
|
if self.login_modal_state.status == LoginStatus::Finished {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label(self.login_modal_state.data.get("login").unwrap());
|
||||||
|
if ui.button("Выйти").clicked() {
|
||||||
|
self.login_modal_state.is_open = true;
|
||||||
|
self.login_modal_state.status = LoginStatus::Login;
|
||||||
|
self.login_modal_state.data.insert("login", String::new());
|
||||||
|
self.login_modal_state
|
||||||
|
.data
|
||||||
|
.insert("password", String::new());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
if self.login_modal_state.is_open {
|
if self.login_modal_state.is_open {
|
||||||
egui::Modal::new(egui::Id::new("login_modal")).show(ui.ctx(), |ui| {
|
egui::Modal::new(egui::Id::new("login_modal")).show(ui.ctx(), |ui| {
|
||||||
ui.label("Пройдите авторизацию:");
|
ui.label("Пройдите авторизацию:");
|
||||||
|
|
@ -152,7 +165,7 @@ impl eframe::App for App<'_> {
|
||||||
|
|
||||||
struct MainTabViewer {
|
struct MainTabViewer {
|
||||||
positions: Arc<RwLock<Option<Vec<Position>>>>,
|
positions: Arc<RwLock<Option<Vec<Position>>>>,
|
||||||
workers: Arc<RwLock<Option<Vec<Worker>>>>,
|
workers: Arc<RwLock<Vec<Worker>>>,
|
||||||
equipment: Arc<RwLock<Option<Vec<Equipment>>>>,
|
equipment: Arc<RwLock<Option<Vec<Equipment>>>>,
|
||||||
db_oper: DBOperator,
|
db_oper: DBOperator,
|
||||||
worker_tabs: WorkerTabViewer,
|
worker_tabs: WorkerTabViewer,
|
||||||
|
|
@ -173,9 +186,9 @@ impl Default for MainTabViewer {
|
||||||
positions: Arc::new(RwLock::new(Option::Some(
|
positions: Arc::new(RwLock::new(Option::Some(
|
||||||
rt.block_on(async { db_oper.get_position().await.unwrap() }),
|
rt.block_on(async { db_oper.get_position().await.unwrap() }),
|
||||||
))),
|
))),
|
||||||
workers: Arc::new(RwLock::new(Option::Some(
|
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(Option::Some(
|
equipment: Arc::new(RwLock::new(Option::Some(
|
||||||
rt.block_on(async { db_oper.get_equipment().await.unwrap() }),
|
rt.block_on(async { db_oper.get_equipment().await.unwrap() }),
|
||||||
))),
|
))),
|
||||||
|
|
@ -343,25 +356,37 @@ impl MainTabViewer {
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Инв. номер");
|
ui.label("Инв. номер");
|
||||||
let mut inv_num = self
|
ui.text_edit_singleline(
|
||||||
.equipment_modal_state
|
self.equipment_modal_state
|
||||||
.data
|
.data
|
||||||
.get_mut("inv_number")
|
.get_mut("inv_number")
|
||||||
.unwrap();
|
.unwrap(),
|
||||||
ui.text_edit_singleline(inv_num);
|
);
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Ответственный");
|
ui.label("Ответственный");
|
||||||
// egui::ComboBox::new("process_equipment_combobox");
|
egui::ComboBox::new("process_equipment_combobox", "").show_ui(ui, |ui| {
|
||||||
|
for wkrk in self.workers.read().clone().iter() {
|
||||||
|
ui.selectable_value(
|
||||||
|
&mut self
|
||||||
|
.equipment_modal_state
|
||||||
|
.data
|
||||||
|
.get_mut("worker_id")
|
||||||
|
.unwrap(),
|
||||||
|
&mut wkrk.id.to_string(),
|
||||||
|
wkrk.full_name.clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Дата последнего\nтехобслуживания");
|
ui.label("Дата последнего\nтехобслуживания");
|
||||||
let mut maintenance = self
|
ui.text_edit_singleline(
|
||||||
.equipment_modal_state
|
self.equipment_modal_state
|
||||||
.data
|
.data
|
||||||
.get_mut("maintenance_date")
|
.get_mut("maintenance_date")
|
||||||
.unwrap();
|
.unwrap(),
|
||||||
ui.text_edit_singleline(maintenance);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -117,10 +117,10 @@ impl DBOperator {
|
||||||
}
|
}
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
pub async fn add_worker(&self, worker: Worker) -> 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)
|
||||||
match sqlx::query("INSERT INTO Brewery.worker (id, position_id, hire_date, is_fired, full_name) VALUES(0, ?, ?, ?, ?);")
|
match sqlx::query("INSERT INTO Brewery.worker (id, position_id, hire_date, is_fired, full_name) VALUES(0, ?, ?, ?, ?);")
|
||||||
.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)
|
||||||
|
|
@ -206,9 +206,9 @@ impl DBOperator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_worker(&self, worker: Worker) -> Result<bool, sqlx::Error> {
|
pub async fn update_worker(&self, worker: WorkerRow) -> Result<bool, sqlx::Error> {
|
||||||
match sqlx::query("UPDATE Brewery.worker SET position_id=?, hire_date=?, is_fired=?, full_name=? WHERE id=?;")
|
match sqlx::query("UPDATE Brewery.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)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ mod app;
|
||||||
mod database;
|
mod database;
|
||||||
mod material_tab;
|
mod material_tab;
|
||||||
mod models;
|
mod models;
|
||||||
|
mod payment_tab;
|
||||||
mod recipe_tab;
|
mod recipe_tab;
|
||||||
mod tab;
|
mod tab;
|
||||||
mod worker_tab;
|
mod worker_tab;
|
||||||
|
|
@ -10,12 +11,13 @@ mod worker_tab;
|
||||||
fn main() {
|
fn main() {
|
||||||
dotenvy::dotenv().ok();
|
dotenvy::dotenv().ok();
|
||||||
database::estabilish_connection();
|
database::estabilish_connection();
|
||||||
let native_opts = eframe::NativeOptions {
|
let mut native_opts = eframe::NativeOptions {
|
||||||
viewport: egui::ViewportBuilder::default()
|
viewport: egui::ViewportBuilder::default()
|
||||||
.with_inner_size([700.0, 300.0])
|
.with_inner_size([700.0, 300.0])
|
||||||
.with_min_inner_size([650.0, 200.0]),
|
.with_min_inner_size([650.0, 200.0]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
native_opts.renderer = eframe::Renderer::Glow;
|
||||||
|
|
||||||
eframe::run_native(
|
eframe::run_native(
|
||||||
"BCS",
|
"BCS",
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ pub struct Product<'a> {
|
||||||
price_per_unit: rust_decimal::Decimal,
|
price_per_unit: rust_decimal::Decimal,
|
||||||
}
|
}
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct User{
|
pub struct User {
|
||||||
login: String,
|
login: String,
|
||||||
is_admin: bool,
|
is_admin: bool,
|
||||||
worker: Worker,
|
worker: Worker,
|
||||||
|
|
@ -142,7 +142,7 @@ pub struct LoginModalState<'a> {
|
||||||
pub fail_message: String,
|
pub fail_message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, PartialEq)]
|
||||||
pub enum LoginStatus {
|
pub enum LoginStatus {
|
||||||
#[default]
|
#[default]
|
||||||
Login,
|
Login,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
use crate::{
|
||||||
|
database::DBOperator,
|
||||||
|
tab::{TABS_CAN_BE_WINDOWS, Tab, TabTypes},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct PaymentTabViewer {
|
||||||
|
db_oper: DBOperator,
|
||||||
|
is_admin: bool,
|
||||||
|
rt: tokio::runtime::Runtime,
|
||||||
|
}
|
||||||
|
impl PaymentTabViewer {
|
||||||
|
pub fn new(is_admin: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
is_admin,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl egui_dock::TabViewer for PaymentTabViewer {
|
||||||
|
type Tab = Tab;
|
||||||
|
fn title(&mut self, tab: &mut Self::Tab) -> egui::WidgetText {
|
||||||
|
(&*tab.title).into()
|
||||||
|
}
|
||||||
|
fn ui(&mut self, ui: &mut egui::Ui, tab: &mut Self::Tab) {
|
||||||
|
match &tab.tab_type {
|
||||||
|
_ => {
|
||||||
|
ui.label("Nope");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn id(&mut self, tab: &mut Self::Tab) -> egui::Id {
|
||||||
|
egui::Id::new(&tab.title)
|
||||||
|
}
|
||||||
|
fn allowed_in_windows(&self, _tab: &mut Self::Tab) -> bool {
|
||||||
|
TABS_CAN_BE_WINDOWS
|
||||||
|
}
|
||||||
|
fn is_closeable(&self, _tab: &Self::Tab) -> bool {
|
||||||
|
!self.is_admin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Default for PaymentTabViewer {
|
||||||
|
fn default() -> Self {
|
||||||
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
let db_oper = rt.block_on(async { DBOperator::new().await });
|
||||||
|
Self {
|
||||||
|
db_oper,
|
||||||
|
rt,
|
||||||
|
is_admin: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,37 +3,20 @@ use egui::mutex::RwLock;
|
||||||
use egui_extras::{Column, TableBuilder};
|
use egui_extras::{Column, TableBuilder};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::database::*;
|
use crate::database::*;
|
||||||
use crate::models::{ModalStatus, ModalWinState, Position, Worker};
|
use crate::models::{ModalStatus, ModalWinState, Position, Worker, WorkerRow};
|
||||||
use crate::tab::*;
|
use crate::tab::*;
|
||||||
pub struct WorkerTabViewer {
|
pub struct WorkerTabViewer {
|
||||||
db_oper: DBOperator,
|
db_oper: DBOperator,
|
||||||
workers: Arc<RwLock<Vec<Worker>>>,
|
workers: Arc<RwLock<Vec<Worker>>>,
|
||||||
positions: Arc<RwLock<Vec<Position>>>,
|
positions: Arc<RwLock<Vec<Position>>>,
|
||||||
show_worker_add_modal: bool,
|
|
||||||
show_worker_edit_modal: bool,
|
|
||||||
show_position_add_modal: bool,
|
|
||||||
fire_worker_id: String,
|
|
||||||
add_worker_name: String,
|
|
||||||
add_worker_hire_date: String,
|
|
||||||
add_worker_position: Position,
|
|
||||||
can_add_worker: bool,
|
|
||||||
can_edit_worker: bool,
|
|
||||||
add_position_name: String,
|
|
||||||
add_position_wage: String,
|
|
||||||
|
|
||||||
edit_worker_id: i32,
|
|
||||||
edit_worker_name: String,
|
|
||||||
edit_worker_hire_date: String,
|
|
||||||
edit_worker_is_fired: bool,
|
|
||||||
edit_worker_position: Position,
|
|
||||||
|
|
||||||
rt: tokio::runtime::Runtime,
|
rt: tokio::runtime::Runtime,
|
||||||
show_position_delete_modal: bool,
|
|
||||||
delete_position: Position,
|
|
||||||
process_worker_state: ModalWinState,
|
process_worker_state: ModalWinState,
|
||||||
process_position_state: ModalWinState,
|
process_position_state: ModalWinState,
|
||||||
is_admin: bool,
|
is_admin: bool,
|
||||||
|
|
@ -63,205 +46,218 @@ impl WorkerTabViewer {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
if ui.button("Добавить").clicked() {
|
if ui.button("Добавить").clicked() {
|
||||||
self.process_worker_state.is_open = true;
|
self.process_worker_state.is_open = true;
|
||||||
self.process_worker_state.data.insert("id".to_string(), "0".to_string());
|
self.process_worker_state
|
||||||
self.process_worker_state.data.insert("full_name".to_string(), String::new());
|
.data
|
||||||
self.process_worker_state.data.insert("hire_date".to_string(), String::new());
|
.insert("id".to_string(), "0".to_string());
|
||||||
|
self.process_worker_state
|
||||||
|
.data
|
||||||
|
.insert("full_name".to_string(), "".to_string());
|
||||||
|
self.process_worker_state.data.insert(
|
||||||
|
"position_id".to_string(),
|
||||||
|
self.positions.read()[0].name.clone(),
|
||||||
|
);
|
||||||
|
self.process_worker_state
|
||||||
|
.data
|
||||||
|
.insert("is_fired".to_string(), false.to_string());
|
||||||
|
self.process_worker_state
|
||||||
|
.data
|
||||||
|
.insert("hire_date".to_string(), "".to_string());
|
||||||
};
|
};
|
||||||
if ui.button("Обновить").clicked() {
|
if ui.button("Обновить").clicked() {
|
||||||
self.update_workers();
|
self.update_workers();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if self.show_worker_add_modal {
|
if self.process_worker_state.is_open {
|
||||||
egui::Modal::new("add_worker".into()).show(ui.ctx(), |ui| {
|
egui::Modal::new(egui::Id::new("process_worker_modal")).show(ui.ctx(), |ui| {
|
||||||
if ui.button("Закрыть").clicked() {
|
if ui.button("Закрыть").clicked() || ui.input(|i| i.key_pressed(egui::Key::Escape))
|
||||||
self.show_worker_add_modal = false;
|
|
||||||
}
|
|
||||||
ui.horizontal(|ui| {
|
|
||||||
ui.vertical(|ui| {
|
|
||||||
ui.label("Имя сотрудника:");
|
|
||||||
ui.label("Дата найма:");
|
|
||||||
ui.label("Должность:");
|
|
||||||
});
|
|
||||||
ui.vertical(|ui| {
|
|
||||||
ui.add(
|
|
||||||
egui::TextEdit::singleline(&mut self.add_worker_name)
|
|
||||||
.hint_text("Напр: Иванов Иван"),
|
|
||||||
);
|
|
||||||
ui.add(
|
|
||||||
egui::TextEdit::singleline(&mut self.add_worker_hire_date)
|
|
||||||
.hint_text("Напр: 12-02-2010"),
|
|
||||||
);
|
|
||||||
egui::ComboBox::from_label("Выбрать!")
|
|
||||||
.selected_text(format!("{}", self.add_worker_position.name))
|
|
||||||
.show_ui(ui, |ui| {
|
|
||||||
self.rt.block_on(async {
|
|
||||||
for pos in self.positions.read().clone().iter() {
|
|
||||||
ui.selectable_value(
|
|
||||||
&mut self.add_worker_position,
|
|
||||||
pos.clone(),
|
|
||||||
&pos.name,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if chrono::NaiveDate::parse_from_str(&self.add_worker_hire_date, "%d-%m-%Y")
|
|
||||||
.is_err()
|
|
||||||
{
|
{
|
||||||
ui.label(egui::RichText::new("ДАТА УКАЗАНА НЕВЕРНО").color(egui::Color32::RED));
|
self.process_worker_state.is_open = false;
|
||||||
self.can_add_worker = false;
|
|
||||||
} else {
|
|
||||||
self.can_add_worker = true;
|
|
||||||
}
|
}
|
||||||
ui.vertical_centered(|ui| {
|
if self.process_worker_state.status != ModalStatus::Remove {
|
||||||
let resp = ui.add_enabled(self.can_add_worker, egui::Button::new("Добавить"));
|
egui::Grid::new("process_worker_grid").show(ui, |ui| {
|
||||||
if resp.clicked() {
|
ui.label("Имя:");
|
||||||
self.rt.block_on(async {
|
ui.add(
|
||||||
let ndate = chrono::NaiveDate::parse_from_str(
|
egui::TextEdit::singleline(
|
||||||
&self.add_worker_hire_date,
|
self.process_worker_state.data.get_mut("full_name").unwrap(),
|
||||||
"%d-%m-%Y",
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.hint_text("Иванов Иван Иванович"),
|
||||||
self.db_oper
|
);
|
||||||
.add_worker(Worker {
|
ui.end_row();
|
||||||
id: 0,
|
|
||||||
full_name: self.add_worker_name.clone(),
|
ui.label("Должность:");
|
||||||
hire_date: ndate
|
let posname = self
|
||||||
|
.positions
|
||||||
|
.read()
|
||||||
|
.clone()
|
||||||
|
.iter()
|
||||||
|
.find(|p| {
|
||||||
|
p.id.to_string()
|
||||||
|
== *self.process_worker_state.data.get("position_id").unwrap()
|
||||||
|
})
|
||||||
|
.map(|m| m.name.clone());
|
||||||
|
egui::ComboBox::new("process_worker_combobox", "")
|
||||||
|
.selected_text(posname.unwrap_or("Выберите".to_string()))
|
||||||
|
.show_ui(ui, |ui| {
|
||||||
|
for pos in self.positions.read().clone().iter() {
|
||||||
|
ui.selectable_value(
|
||||||
|
self.process_worker_state
|
||||||
|
.data
|
||||||
|
.get_mut("position_id")
|
||||||
|
.unwrap(),
|
||||||
|
pos.id.to_string(),
|
||||||
|
pos.name.clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
|
let mut size = ui.spacing().interact_size;
|
||||||
|
size.x = 200.0;
|
||||||
|
ui.label("Дата найма:");
|
||||||
|
ui.add_sized(
|
||||||
|
size,
|
||||||
|
egui::TextEdit::singleline(
|
||||||
|
self.process_worker_state.data.get_mut("hire_date").unwrap(),
|
||||||
|
)
|
||||||
|
.hint_text("1970-01-23"),
|
||||||
|
);
|
||||||
|
ui.end_row();
|
||||||
|
if self.process_worker_state.status == ModalStatus::Edit {
|
||||||
|
ui.label("Уволен:");
|
||||||
|
let data = self.process_worker_state.data.get("is_fired").unwrap();
|
||||||
|
let mut checked = data.parse::<bool>().unwrap();
|
||||||
|
ui.checkbox(&mut checked, "");
|
||||||
|
if checked.to_string() != data.clone() {
|
||||||
|
self.process_worker_state
|
||||||
|
.data
|
||||||
|
.insert("is_fired".to_string(), checked.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self.process_worker_state.can_finish = self.check_date(
|
||||||
|
self.process_worker_state
|
||||||
|
.data
|
||||||
|
.get("hire_date")
|
||||||
|
.unwrap()
|
||||||
|
.clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let btext = match self.process_worker_state.status {
|
||||||
|
ModalStatus::Add => "Добавить",
|
||||||
|
ModalStatus::Edit => "Сохранить",
|
||||||
|
_ => "Подтвердить",
|
||||||
|
};
|
||||||
|
if !self.process_worker_state.can_finish {
|
||||||
|
ui.label("Проверьте правильность всех полей");
|
||||||
|
}
|
||||||
|
let resp = ui.add_enabled(
|
||||||
|
self.process_worker_state.can_finish,
|
||||||
|
egui::Button::new(btext),
|
||||||
|
);
|
||||||
|
if resp.clicked() {
|
||||||
|
match self.process_worker_state.status {
|
||||||
|
ModalStatus::Add => {
|
||||||
|
self.rt.block_on(async {
|
||||||
|
self.db_oper
|
||||||
|
.add_worker(WorkerRow {
|
||||||
|
id: self
|
||||||
|
.process_worker_state
|
||||||
|
.data
|
||||||
|
.get("id")
|
||||||
|
.unwrap()
|
||||||
|
.parse::<i32>()
|
||||||
|
.unwrap(),
|
||||||
|
full_name: self
|
||||||
|
.process_worker_state
|
||||||
|
.data
|
||||||
|
.get("full_name")
|
||||||
|
.unwrap()
|
||||||
|
.clone(),
|
||||||
|
position_id: self
|
||||||
|
.process_worker_state
|
||||||
|
.data
|
||||||
|
.get("position_id")
|
||||||
|
.unwrap()
|
||||||
|
.parse::<i32>()
|
||||||
|
.unwrap(),
|
||||||
|
hire_date: chrono::NaiveDate::parse_from_str(
|
||||||
|
&self
|
||||||
|
.process_worker_state
|
||||||
|
.data
|
||||||
|
.get("hire_date")
|
||||||
|
.unwrap(),
|
||||||
|
"%Y-%m-%d",
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
.and_hms_opt(0, 0, 0)
|
.and_hms_opt(0, 0, 0)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.and_local_timezone(chrono::Local)
|
.and_local_timezone(chrono::Local)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
position: self.add_worker_position.clone(),
|
is_fired: false,
|
||||||
is_fired: false,
|
})
|
||||||
})
|
.await
|
||||||
.await
|
.ok()
|
||||||
.ok();
|
|
||||||
|
|
||||||
self.show_worker_add_modal = false;
|
|
||||||
});
|
|
||||||
self.update_workers();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if self.show_worker_edit_modal {
|
|
||||||
egui::Modal::new("edit_worker".into()).show(ui.ctx(), |ui| {
|
|
||||||
if ui.button("Закрыть").clicked() {
|
|
||||||
self.show_worker_edit_modal = false;
|
|
||||||
}
|
|
||||||
let mut size = ui.spacing().interact_size;
|
|
||||||
size.x = 200.0;
|
|
||||||
|
|
||||||
egui::Grid::new("edit_worker_grid").show(ui, |ui| {
|
|
||||||
ui.label("ID");
|
|
||||||
let old = self.edit_worker_id.clone();
|
|
||||||
egui::ComboBox::from_id_salt("edit_worker_id")
|
|
||||||
.selected_text(format!("#{:08}", &self.edit_worker_id))
|
|
||||||
.show_ui(ui, |ui| {
|
|
||||||
self.rt.block_on(async {
|
|
||||||
for worker in self.workers.read().clone().iter() {
|
|
||||||
ui.selectable_value(
|
|
||||||
&mut self.edit_worker_id,
|
|
||||||
worker.id,
|
|
||||||
format!("#{:08} | {}", worker.id, worker.full_name),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
if self.edit_worker_id != old {
|
ModalStatus::Edit => {
|
||||||
self.rt.block_on(async {
|
|
||||||
let wrkr =
|
|
||||||
match self.db_oper.get_worker_by_id(self.edit_worker_id).await {
|
|
||||||
Ok(worker) => worker,
|
|
||||||
Err(_) => Worker::default(),
|
|
||||||
};
|
|
||||||
self.edit_worker_name = wrkr.full_name;
|
|
||||||
self.edit_worker_hire_date =
|
|
||||||
wrkr.hire_date.format("%Y-%m-%d").to_string();
|
|
||||||
self.edit_worker_position = wrkr.position;
|
|
||||||
self.edit_worker_is_fired = wrkr.is_fired;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ui.end_row();
|
|
||||||
|
|
||||||
ui.label("Имя");
|
|
||||||
ui.add_sized(size, |ui: &mut egui::Ui| {
|
|
||||||
ui.text_edit_singleline(&mut self.edit_worker_name)
|
|
||||||
});
|
|
||||||
ui.end_row();
|
|
||||||
|
|
||||||
ui.label("Должность");
|
|
||||||
egui::ComboBox::from_id_salt("edit_worker_pos")
|
|
||||||
.selected_text(&self.edit_worker_position.name)
|
|
||||||
.show_ui(ui, |ui| {
|
|
||||||
self.rt.block_on(async {
|
self.rt.block_on(async {
|
||||||
for pos in self.positions.read().clone().iter() {
|
self.db_oper
|
||||||
ui.selectable_value(
|
.update_worker(WorkerRow {
|
||||||
&mut self.edit_worker_position,
|
id: self
|
||||||
pos.clone(),
|
.process_worker_state
|
||||||
&pos.name,
|
.data
|
||||||
);
|
.get("id")
|
||||||
}
|
.unwrap()
|
||||||
|
.parse::<i32>()
|
||||||
|
.unwrap(),
|
||||||
|
full_name: self
|
||||||
|
.process_worker_state
|
||||||
|
.data
|
||||||
|
.get("full_name")
|
||||||
|
.unwrap()
|
||||||
|
.clone(),
|
||||||
|
position_id: self
|
||||||
|
.process_worker_state
|
||||||
|
.data
|
||||||
|
.get("position_id")
|
||||||
|
.unwrap()
|
||||||
|
.parse::<i32>()
|
||||||
|
.unwrap(),
|
||||||
|
is_fired: self
|
||||||
|
.process_worker_state
|
||||||
|
.data
|
||||||
|
.get("is_fired")
|
||||||
|
.unwrap()
|
||||||
|
.parse::<bool>()
|
||||||
|
.unwrap(),
|
||||||
|
hire_date: chrono::NaiveDate::parse_from_str(
|
||||||
|
&self
|
||||||
|
.process_worker_state
|
||||||
|
.data
|
||||||
|
.get("hire_date")
|
||||||
|
.unwrap(),
|
||||||
|
"%Y-%m-%d",
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.and_hms_opt(0, 0, 0)
|
||||||
|
.unwrap()
|
||||||
|
.and_local_timezone(chrono::Local)
|
||||||
|
.unwrap(),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
ui.end_row();
|
_ => {}
|
||||||
|
}
|
||||||
ui.label("Дата найма");
|
|
||||||
ui.text_edit_singleline(&mut self.edit_worker_hire_date);
|
|
||||||
ui.end_row();
|
|
||||||
|
|
||||||
ui.checkbox(&mut self.edit_worker_is_fired, "Уволен");
|
|
||||||
ui.end_row();
|
|
||||||
});
|
|
||||||
if chrono::NaiveDate::parse_from_str(&self.edit_worker_hire_date, "%Y-%m-%d")
|
|
||||||
.is_ok()
|
|
||||||
&& self.edit_worker_name.len() > 0
|
|
||||||
{
|
|
||||||
self.can_edit_worker = true;
|
|
||||||
} else {
|
|
||||||
self.can_edit_worker = false;
|
|
||||||
}
|
|
||||||
let resp = ui.add_enabled(self.can_edit_worker, egui::Button::new("Добавить"));
|
|
||||||
if resp.clicked() {
|
|
||||||
self.rt.block_on(async {
|
|
||||||
let ndate = chrono::NaiveDate::parse_from_str(
|
|
||||||
&self.edit_worker_hire_date,
|
|
||||||
"%Y-%m-%d",
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
self.db_oper
|
|
||||||
.update_worker(Worker {
|
|
||||||
id: self.edit_worker_id,
|
|
||||||
full_name: self.edit_worker_name.clone(),
|
|
||||||
hire_date: ndate
|
|
||||||
.and_hms_opt(0, 0, 0)
|
|
||||||
.unwrap()
|
|
||||||
.and_local_timezone(chrono::Local)
|
|
||||||
.unwrap(),
|
|
||||||
position: self.edit_worker_position.clone(),
|
|
||||||
is_fired: self.edit_worker_is_fired,
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
});
|
|
||||||
self.update_workers();
|
self.update_workers();
|
||||||
self.show_worker_edit_modal = false;
|
self.process_worker_state.is_open = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if self.process_worker_state.is_open{
|
|
||||||
egui::Modal::new(egui::Id::new("process_worker_modal")).show(ui.ctx(), |ui|{
|
|
||||||
if ui.button("Закрыть").clicked(){
|
|
||||||
self.process_worker_state.is_open = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
TableBuilder::new(ui)
|
TableBuilder::new(ui)
|
||||||
.column(Column::auto())
|
.vscroll(false)
|
||||||
.column(Column::auto())
|
.column(Column::auto())
|
||||||
.column(Column::auto())
|
.column(Column::auto())
|
||||||
.column(Column::auto())
|
.column(Column::auto())
|
||||||
|
|
@ -298,15 +294,29 @@ impl WorkerTabViewer {
|
||||||
row.col(|ui| {
|
row.col(|ui| {
|
||||||
ui.label(if wk.is_fired { "Да" } else { "Нет" });
|
ui.label(if wk.is_fired { "Да" } else { "Нет" });
|
||||||
});
|
});
|
||||||
row.col(|ui| {
|
if row.response().clicked() {
|
||||||
if ui.button("Уволить").clicked() {
|
self.process_worker_state.is_open = true;
|
||||||
todo!();
|
self.process_worker_state.status = ModalStatus::Edit;
|
||||||
}
|
self.process_worker_state
|
||||||
});
|
.data
|
||||||
|
.insert("id".to_string(), wk.id.to_string());
|
||||||
|
self.process_worker_state
|
||||||
|
.data
|
||||||
|
.insert("full_name".to_string(), wk.full_name.clone());
|
||||||
|
self.process_worker_state.data.insert(
|
||||||
|
"hire_date".to_string(),
|
||||||
|
wk.hire_date.date_naive().to_string(),
|
||||||
|
);
|
||||||
|
self.process_worker_state
|
||||||
|
.data
|
||||||
|
.insert("is_fired".to_string(), wk.is_fired.to_string());
|
||||||
|
self.process_worker_state
|
||||||
|
.data
|
||||||
|
.insert("position_id".to_string(), wk.position.id.to_string());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_position(&mut self, ui: &mut egui::Ui) {
|
fn show_position(&mut self, ui: &mut egui::Ui) {
|
||||||
|
|
@ -387,7 +397,8 @@ impl WorkerTabViewer {
|
||||||
|
|
||||||
if self.process_position_state.is_open {
|
if self.process_position_state.is_open {
|
||||||
egui::Modal::new(egui::Id::new("process_worker_pos_modal")).show(ui.ctx(), |ui| {
|
egui::Modal::new(egui::Id::new("process_worker_pos_modal")).show(ui.ctx(), |ui| {
|
||||||
if ui.button("Закрыть").clicked() {
|
if ui.button("Закрыть").clicked() || ui.input(|i| i.key_pressed(egui::Key::Escape))
|
||||||
|
{
|
||||||
self.process_position_state.is_open = false;
|
self.process_position_state.is_open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -417,6 +428,9 @@ impl WorkerTabViewer {
|
||||||
ModalStatus::Add => {
|
ModalStatus::Add => {
|
||||||
btext = String::from("Добавить");
|
btext = String::from("Добавить");
|
||||||
self.process_position_state.can_finish = true;
|
self.process_position_state.can_finish = true;
|
||||||
|
self.process_position_state
|
||||||
|
.data
|
||||||
|
.insert("id".to_string(), String::new());
|
||||||
}
|
}
|
||||||
ModalStatus::Edit => {
|
ModalStatus::Edit => {
|
||||||
btext = String::from("Сохранить");
|
btext = String::from("Сохранить");
|
||||||
|
|
@ -428,7 +442,10 @@ impl WorkerTabViewer {
|
||||||
.read()
|
.read()
|
||||||
.clone()
|
.clone()
|
||||||
.iter()
|
.iter()
|
||||||
.find(|wrkr| wrkr.position.id == self.delete_position.id)
|
.find(|wrkr| {
|
||||||
|
wrkr.position.id.to_string()
|
||||||
|
== self.process_position_state.data.get("id").unwrap().clone()
|
||||||
|
})
|
||||||
.iter()
|
.iter()
|
||||||
.len()
|
.len()
|
||||||
== 0;
|
== 0;
|
||||||
|
|
@ -446,7 +463,7 @@ impl WorkerTabViewer {
|
||||||
self.rt.block_on(async {
|
self.rt.block_on(async {
|
||||||
self.db_oper
|
self.db_oper
|
||||||
.add_position(Position {
|
.add_position(Position {
|
||||||
id: pos["id"].parse::<i32>().unwrap(),
|
id: 0,
|
||||||
name: pos["name"].clone(),
|
name: pos["name"].clone(),
|
||||||
wage: bigdecimal::BigDecimal::from_str(
|
wage: bigdecimal::BigDecimal::from_str(
|
||||||
pos["wage"].as_str(),
|
pos["wage"].as_str(),
|
||||||
|
|
@ -490,6 +507,10 @@ impl WorkerTabViewer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_date(&self, date: String) -> bool {
|
||||||
|
chrono::NaiveDate::parse_from_str(&date, "%Y-%m-%d").is_ok()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl egui_dock::TabViewer for WorkerTabViewer {
|
impl egui_dock::TabViewer for WorkerTabViewer {
|
||||||
|
|
@ -564,25 +585,6 @@ impl Default for WorkerTabViewer {
|
||||||
},
|
},
|
||||||
workers,
|
workers,
|
||||||
positions: positions,
|
positions: positions,
|
||||||
show_worker_add_modal: false,
|
|
||||||
show_worker_edit_modal: false,
|
|
||||||
show_position_add_modal: false,
|
|
||||||
show_position_delete_modal: false,
|
|
||||||
fire_worker_id: String::new(),
|
|
||||||
add_worker_name: String::new(),
|
|
||||||
add_worker_position: Position::default(),
|
|
||||||
add_worker_hire_date: String::new(),
|
|
||||||
can_add_worker: false,
|
|
||||||
can_edit_worker: false,
|
|
||||||
add_position_name: String::new(),
|
|
||||||
add_position_wage: String::new(),
|
|
||||||
delete_position: Position::default(),
|
|
||||||
|
|
||||||
edit_worker_id: 1,
|
|
||||||
edit_worker_name: String::new(),
|
|
||||||
edit_worker_hire_date: String::new(),
|
|
||||||
edit_worker_position: Position::default(),
|
|
||||||
edit_worker_is_fired: false,
|
|
||||||
|
|
||||||
db_oper,
|
db_oper,
|
||||||
rt,
|
rt,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue