если есть на свете рай - это не камчатский край

master
Алексей Алексей 2026-06-18 08:45:03 +10:00
parent 36561fc1bb
commit 0e4cb90023
3 changed files with 163 additions and 8 deletions

View File

@ -5,7 +5,7 @@ use crate::{
material_tab::MaterialTabViewer,
models::{
Equipment, LoginModalState, LoginStatus, Material, MaterialCategory, MaterialRow,
ModalStatus, ModalWinState, Position, Worker,
ModalStatus, ModalWinState, Position, Salary, Worker,
},
tab::*,
worker_tab::{self, *},
@ -166,6 +166,7 @@ impl eframe::App for App<'_> {
struct MainTabViewer {
workers: Arc<RwLock<Vec<Worker>>>,
equipment: Arc<RwLock<Option<Vec<Equipment>>>>,
salaries: Arc<RwLock<Vec<Salary>>>,
db_oper: DBOperator,
worker_tabs: WorkerTabViewer,
@ -189,6 +190,9 @@ impl Default for MainTabViewer {
equipment: Arc::new(RwLock::new(Option::Some(
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,
worker_tabs: WorkerTabViewer::default(),
worker_tree: egui_dock::DockState::new(vec![
@ -303,7 +307,7 @@ impl MainTabViewer {
});
row.col(|ui| {
if self.is_admin {
if ui.button("Удалить").clicked() {
if ui.button("Списать").clicked() {
self.equipment_modal_state.is_open = true;
self.equipment_modal_state.status = ModalStatus::Remove;
self.equipment_modal_state
@ -415,6 +419,32 @@ impl MainTabViewer {
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)
.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) {
ui.checkbox(&mut self.is_dark_theme, "Тёмная тема");

View File

@ -1,3 +1,5 @@
use bigdecimal::BigDecimal;
use chrono::DateTime;
use sqlx::Row;
use sqlx::mysql::MySqlPool;
use sqlx::mysql::MySqlPoolOptions;
@ -71,6 +73,7 @@ impl DBOperator {
inv_number: eq.inv_number,
maintenance_date: eq.maintenance_date,
worker: pworker,
is_written_off: eq.is_written_off,
});
}
Ok(rets)
@ -329,6 +332,78 @@ impl DBOperator {
.unwrap();
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> {

View File

@ -1,7 +1,10 @@
use std::{any::TypeId, ops::Deref};
use egui::TextBuffer;
use sqlx::types::{BigDecimal, chrono::DateTime};
use sqlx::{
prelude::FromRow,
types::{BigDecimal, chrono::DateTime},
};
#[derive(Clone, Hash, sqlx::FromRow, PartialEq)]
pub struct Position {
@ -34,11 +37,28 @@ pub struct WorkerRow {
pub position_id: i32,
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 {
id: i32,
worker: Worker,
salary_size: rust_decimal::Decimal,
salary_date: chrono::DateTime<chrono::Local>,
pub id: i32,
pub worker: Worker,
pub salary_size: BigDecimal,
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)]
@ -48,6 +68,7 @@ pub struct Equipment {
pub inv_number: String,
pub maintenance_date: chrono::DateTime<chrono::Local>,
pub worker: Worker,
pub is_written_off: bool,
}
#[derive(sqlx::FromRow)]
pub struct EquipmentRow {
@ -56,6 +77,7 @@ pub struct EquipmentRow {
pub inv_number: String,
pub maintenance_date: chrono::DateTime<chrono::Local>,
pub worker_id: i32,
pub is_written_off: bool,
}
#[derive(Clone)]
pub struct Material {