если есть на свете рай - это не камчатский край
parent
36561fc1bb
commit
0e4cb90023
|
|
@ -5,7 +5,7 @@ use crate::{
|
||||||
material_tab::MaterialTabViewer,
|
material_tab::MaterialTabViewer,
|
||||||
models::{
|
models::{
|
||||||
Equipment, LoginModalState, LoginStatus, Material, MaterialCategory, MaterialRow,
|
Equipment, LoginModalState, LoginStatus, Material, MaterialCategory, MaterialRow,
|
||||||
ModalStatus, ModalWinState, Position, Worker,
|
ModalStatus, ModalWinState, Position, Salary, Worker,
|
||||||
},
|
},
|
||||||
tab::*,
|
tab::*,
|
||||||
worker_tab::{self, *},
|
worker_tab::{self, *},
|
||||||
|
|
@ -166,6 +166,7 @@ impl eframe::App for App<'_> {
|
||||||
struct MainTabViewer {
|
struct MainTabViewer {
|
||||||
workers: Arc<RwLock<Vec<Worker>>>,
|
workers: Arc<RwLock<Vec<Worker>>>,
|
||||||
equipment: Arc<RwLock<Option<Vec<Equipment>>>>,
|
equipment: Arc<RwLock<Option<Vec<Equipment>>>>,
|
||||||
|
salaries: Arc<RwLock<Vec<Salary>>>,
|
||||||
|
|
||||||
db_oper: DBOperator,
|
db_oper: DBOperator,
|
||||||
worker_tabs: WorkerTabViewer,
|
worker_tabs: WorkerTabViewer,
|
||||||
|
|
@ -189,6 +190,9 @@ impl Default for MainTabViewer {
|
||||||
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() }),
|
||||||
))),
|
))),
|
||||||
|
salaries: Arc::new(RwLock::new(
|
||||||
|
rt.block_on(async { db_oper.get_salaries().await.unwrap() }),
|
||||||
|
)),
|
||||||
db_oper,
|
db_oper,
|
||||||
worker_tabs: WorkerTabViewer::default(),
|
worker_tabs: WorkerTabViewer::default(),
|
||||||
worker_tree: egui_dock::DockState::new(vec![
|
worker_tree: egui_dock::DockState::new(vec![
|
||||||
|
|
@ -303,7 +307,7 @@ impl MainTabViewer {
|
||||||
});
|
});
|
||||||
row.col(|ui| {
|
row.col(|ui| {
|
||||||
if self.is_admin {
|
if self.is_admin {
|
||||||
if ui.button("Удалить").clicked() {
|
if ui.button("Списать").clicked() {
|
||||||
self.equipment_modal_state.is_open = true;
|
self.equipment_modal_state.is_open = true;
|
||||||
self.equipment_modal_state.status = ModalStatus::Remove;
|
self.equipment_modal_state.status = ModalStatus::Remove;
|
||||||
self.equipment_modal_state
|
self.equipment_modal_state
|
||||||
|
|
@ -415,6 +419,32 @@ impl MainTabViewer {
|
||||||
self.equipment_modal_state.data.get("inv_number").unwrap()
|
self.equipment_modal_state.data.get("inv_number").unwrap()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
let btext = match self.equipment_modal_state.status {
|
||||||
|
ModalStatus::Add => "Добавить",
|
||||||
|
ModalStatus::Edit => "Сохранить",
|
||||||
|
ModalStatus::Remove => "Списать",
|
||||||
|
};
|
||||||
|
if ui.button(btext).clicked() {
|
||||||
|
match self.equipment_modal_state.status {
|
||||||
|
ModalStatus::Add => {}
|
||||||
|
ModalStatus::Edit => {}
|
||||||
|
ModalStatus::Remove => {
|
||||||
|
self.rt.block_on(async {
|
||||||
|
self.db_oper
|
||||||
|
.write_off_equipment(
|
||||||
|
self.equipment_modal_state
|
||||||
|
.data
|
||||||
|
.get("id")
|
||||||
|
.unwrap()
|
||||||
|
.parse::<i32>()
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -432,7 +462,35 @@ impl MainTabViewer {
|
||||||
.id(id)
|
.id(id)
|
||||||
.show_inside(ui, &mut self.material_tabs);
|
.show_inside(ui, &mut self.material_tabs);
|
||||||
}
|
}
|
||||||
fn show_salary(&mut self, ui: &mut egui::Ui) {}
|
fn show_salary(&mut self, ui: &mut egui::Ui) {
|
||||||
|
/*
|
||||||
|
* Чё надо:
|
||||||
|
* 1. Список платежей.
|
||||||
|
*/
|
||||||
|
let table = TableBuilder::new(ui)
|
||||||
|
.striped(true)
|
||||||
|
.columns(Column::auto(), 4)
|
||||||
|
.header(30.0, |mut header| {
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.heading("Имя сотрудника");
|
||||||
|
});
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.heading("Размер");
|
||||||
|
});
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.heading("Дата");
|
||||||
|
});
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.heading("Описание");
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.body(|mut body| {});
|
||||||
|
/*
|
||||||
|
* 2. Возможность добавить платежи.
|
||||||
|
* 3. Возможность назначить платежи сразу нескольким сотрудникам.
|
||||||
|
* 4. Возможность отменить платежи.
|
||||||
|
*/
|
||||||
|
}
|
||||||
fn show_settings(&mut self, ui: &mut egui::Ui) {
|
fn show_settings(&mut self, ui: &mut egui::Ui) {
|
||||||
ui.checkbox(&mut self.is_dark_theme, "Тёмная тема");
|
ui.checkbox(&mut self.is_dark_theme, "Тёмная тема");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use bigdecimal::BigDecimal;
|
||||||
|
use chrono::DateTime;
|
||||||
use sqlx::Row;
|
use sqlx::Row;
|
||||||
use sqlx::mysql::MySqlPool;
|
use sqlx::mysql::MySqlPool;
|
||||||
use sqlx::mysql::MySqlPoolOptions;
|
use sqlx::mysql::MySqlPoolOptions;
|
||||||
|
|
@ -71,6 +73,7 @@ impl DBOperator {
|
||||||
inv_number: eq.inv_number,
|
inv_number: eq.inv_number,
|
||||||
maintenance_date: eq.maintenance_date,
|
maintenance_date: eq.maintenance_date,
|
||||||
worker: pworker,
|
worker: pworker,
|
||||||
|
is_written_off: eq.is_written_off,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(rets)
|
Ok(rets)
|
||||||
|
|
@ -329,6 +332,78 @@ impl DBOperator {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(ans)
|
Ok(ans)
|
||||||
}
|
}
|
||||||
|
pub async fn write_off_equipment(&self, equipment_id: i32) -> Result<bool, sqlx::Error> {
|
||||||
|
match sqlx::query("UPDATE `equipment` SET is_written_off=1 WHERE id=?")
|
||||||
|
.bind(equipment_id)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(_) => Ok(true),
|
||||||
|
Err(_) => Ok(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub async fn get_salaries(&self) -> Result<Vec<Salary>, sqlx::Error> {
|
||||||
|
let sals = sqlx::query_as::<_, SalaryRow>("SELECT * FROM `salary`")
|
||||||
|
.fetch_all(&self.pool)
|
||||||
|
.await?;
|
||||||
|
let mut rets: Vec<Salary> = Vec::new();
|
||||||
|
let workers = self.get_workers().await.unwrap();
|
||||||
|
for sal in sals {
|
||||||
|
match workers.iter().find(|w| w.id == sal.worker_id) {
|
||||||
|
Some(w) => rets.push(Salary {
|
||||||
|
id: sal.id,
|
||||||
|
worker: w.clone(),
|
||||||
|
salary_date: sal.salary_date,
|
||||||
|
salary_size: sal.salary_size,
|
||||||
|
cluster_id: sal.cluster_id,
|
||||||
|
comment: sal.comment,
|
||||||
|
}),
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(rets)
|
||||||
|
}
|
||||||
|
pub async fn get_salary_clusters(&self) -> Result<Vec<SalaryCluster>, sqlx::Error> {
|
||||||
|
let clus = sqlx::query_as::<_, SalaryCluster>("SELECT * FROM `salary_cluster`")
|
||||||
|
.fetch_all(&self.pool)
|
||||||
|
.await?;
|
||||||
|
Ok(clus)
|
||||||
|
}
|
||||||
|
pub async fn add_salary(
|
||||||
|
&self,
|
||||||
|
worker: Worker,
|
||||||
|
salary_date: DateTime<chrono::Local>,
|
||||||
|
salary_size: Option<BigDecimal>,
|
||||||
|
cluster: SalaryCluster,
|
||||||
|
comment: Option<String>,
|
||||||
|
) -> Result<bool, sqlx::Error> {
|
||||||
|
match sqlx::query("INSERT INTO Brewery.salary (id, worker_id, salary_size, salary_date, comment, cluster_id) VALUES(0, ?, ?, ?, ?, ?);")
|
||||||
|
.bind(worker.id)
|
||||||
|
.bind(salary_size.unwrap_or(worker.position.wage))
|
||||||
|
.bind(salary_date)
|
||||||
|
.bind(comment.unwrap_or(String::new()))
|
||||||
|
.bind(cluster.id)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await{
|
||||||
|
Ok(_) => Ok(true),
|
||||||
|
Err(_) => Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub async fn add_salary_cluster(&self, name: String) -> Result<i32, sqlx::Error> {
|
||||||
|
match sqlx::query("INSERT INTO `salary_cluster` (id, name) VALUES (0, ?)")
|
||||||
|
.bind(name)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(_) => Ok(sqlx::query("SELECT LAST_INSERT_ID();")
|
||||||
|
.fetch_one(&self.pool)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.get(0)),
|
||||||
|
Err(_) => Ok(-1),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn estabilish_connection() -> Result<(), sqlx::Error> {
|
pub async fn estabilish_connection() -> Result<(), sqlx::Error> {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
use std::{any::TypeId, ops::Deref};
|
use std::{any::TypeId, ops::Deref};
|
||||||
|
|
||||||
use egui::TextBuffer;
|
use egui::TextBuffer;
|
||||||
use sqlx::types::{BigDecimal, chrono::DateTime};
|
use sqlx::{
|
||||||
|
prelude::FromRow,
|
||||||
|
types::{BigDecimal, chrono::DateTime},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Hash, sqlx::FromRow, PartialEq)]
|
#[derive(Clone, Hash, sqlx::FromRow, PartialEq)]
|
||||||
pub struct Position {
|
pub struct Position {
|
||||||
|
|
@ -34,11 +37,28 @@ pub struct WorkerRow {
|
||||||
pub position_id: i32,
|
pub position_id: i32,
|
||||||
pub is_fired: bool,
|
pub is_fired: bool,
|
||||||
}
|
}
|
||||||
|
#[derive(sqlx::FromRow, sqlx::Decode)]
|
||||||
|
pub struct SalaryRow {
|
||||||
|
pub id: i32,
|
||||||
|
pub worker_id: i32,
|
||||||
|
pub salary_size: BigDecimal,
|
||||||
|
pub salary_date: chrono::DateTime<chrono::Local>,
|
||||||
|
pub comment: String,
|
||||||
|
pub cluster_id: i32,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Salary {
|
pub struct Salary {
|
||||||
id: i32,
|
pub id: i32,
|
||||||
worker: Worker,
|
pub worker: Worker,
|
||||||
salary_size: rust_decimal::Decimal,
|
pub salary_size: BigDecimal,
|
||||||
salary_date: chrono::DateTime<chrono::Local>,
|
pub salary_date: chrono::DateTime<chrono::Local>,
|
||||||
|
pub comment: String,
|
||||||
|
pub cluster_id: i32,
|
||||||
|
}
|
||||||
|
#[derive(sqlx::Decode, sqlx::FromRow, sqlx::Encode)]
|
||||||
|
pub struct SalaryCluster {
|
||||||
|
pub id: i32,
|
||||||
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone, Hash)]
|
#[derive(Default, Clone, Hash)]
|
||||||
|
|
@ -48,6 +68,7 @@ pub struct Equipment {
|
||||||
pub inv_number: String,
|
pub inv_number: String,
|
||||||
pub maintenance_date: chrono::DateTime<chrono::Local>,
|
pub maintenance_date: chrono::DateTime<chrono::Local>,
|
||||||
pub worker: Worker,
|
pub worker: Worker,
|
||||||
|
pub is_written_off: bool,
|
||||||
}
|
}
|
||||||
#[derive(sqlx::FromRow)]
|
#[derive(sqlx::FromRow)]
|
||||||
pub struct EquipmentRow {
|
pub struct EquipmentRow {
|
||||||
|
|
@ -56,6 +77,7 @@ pub struct EquipmentRow {
|
||||||
pub inv_number: String,
|
pub inv_number: String,
|
||||||
pub maintenance_date: chrono::DateTime<chrono::Local>,
|
pub maintenance_date: chrono::DateTime<chrono::Local>,
|
||||||
pub worker_id: i32,
|
pub worker_id: i32,
|
||||||
|
pub is_written_off: bool,
|
||||||
}
|
}
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Material {
|
pub struct Material {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue