930 lines
38 KiB
C#
930 lines
38 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
using System.Data.SQLite;
|
||
using System.Configuration;
|
||
using System.IO;
|
||
|
||
namespace WindowsFormsApp1
|
||
{
|
||
public partial class Form1 : Form
|
||
{
|
||
// Путь к файлу SQLite
|
||
private string connectionString = @"Data Source=EmployeeDB.db;Version=3;";
|
||
|
||
public Form1()
|
||
{
|
||
InitializeComponent();
|
||
this.AcceptButton = buttonLogin;
|
||
this.Text = "Авторизация";
|
||
this.FormBorderStyle = FormBorderStyle.FixedDialog;
|
||
this.MaximizeBox = false;
|
||
this.StartPosition = FormStartPosition.CenterScreen;
|
||
|
||
// Добавляем компоненты
|
||
InitializeLoginComponents();
|
||
|
||
// Создаем базу данных, если она не существует
|
||
CreateDatabaseIfNotExists();
|
||
}
|
||
|
||
private void CreateDatabaseIfNotExists()
|
||
{
|
||
try
|
||
{
|
||
if (!File.Exists("EmployeeDB.db"))
|
||
{
|
||
SQLiteConnection.CreateFile("EmployeeDB.db");
|
||
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
|
||
{
|
||
connection.Open();
|
||
|
||
// Создаем таблицу пользователей
|
||
string createUsersTable = @"CREATE TABLE IF NOT EXISTS Users (
|
||
UserID INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
Login TEXT NOT NULL,
|
||
Password TEXT NOT NULL)";
|
||
using (SQLiteCommand command = new SQLiteCommand(createUsersTable, connection))
|
||
{
|
||
command.ExecuteNonQuery();
|
||
}
|
||
|
||
// Создаем admin пользователя
|
||
string insertAdmin = @"INSERT INTO Users (Login, Password) VALUES ('admin', 'admin')";
|
||
using (SQLiteCommand command = new SQLiteCommand(insertAdmin, connection))
|
||
{
|
||
command.ExecuteNonQuery();
|
||
}
|
||
|
||
// Создаем таблицу сотрудников
|
||
string createEmployeesTable = @"CREATE TABLE IF NOT EXISTS Employees (
|
||
EmployeeID INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
LastName TEXT NOT NULL,
|
||
FirstName TEXT NOT NULL,
|
||
MiddleName TEXT,
|
||
Position TEXT,
|
||
Department TEXT)";
|
||
using (SQLiteCommand command = new SQLiteCommand(createEmployeesTable, connection))
|
||
{
|
||
command.ExecuteNonQuery();
|
||
}
|
||
|
||
// Создаем таблицу посещаемости
|
||
string createAttendanceTable = @"CREATE TABLE IF NOT EXISTS Attendance (
|
||
AttendanceID INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
EmployeeID INTEGER NOT NULL,
|
||
ArrivalTime TEXT NOT NULL,
|
||
DepartureTime TEXT,
|
||
FOREIGN KEY (EmployeeID) REFERENCES Employees(EmployeeID))";
|
||
using (SQLiteCommand command = new SQLiteCommand(createAttendanceTable, connection))
|
||
{
|
||
command.ExecuteNonQuery();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show("Ошибка инициализации базы данных: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void InitializeLoginComponents()
|
||
{
|
||
// Заголовок
|
||
Label lblHeader = new Label
|
||
{
|
||
Text = "Вход в систему учета посещаемости",
|
||
Font = new Font("Arial", 14, FontStyle.Bold),
|
||
Width = 350,
|
||
TextAlign = ContentAlignment.MiddleCenter,
|
||
Location = new Point(70, 20)
|
||
};
|
||
|
||
// Поле логина
|
||
Label lblLogin = new Label
|
||
{
|
||
Text = "Логин:",
|
||
Location = new Point(70, 70),
|
||
Width = 100
|
||
};
|
||
|
||
TextBox txtLogin = new TextBox
|
||
{
|
||
Name = "txtLogin",
|
||
Location = new Point(170, 70),
|
||
Width = 200
|
||
};
|
||
|
||
// Поле пароля
|
||
Label lblPassword = new Label
|
||
{
|
||
Text = "Пароль:",
|
||
Location = new Point(70, 100),
|
||
Width = 100
|
||
};
|
||
|
||
TextBox txtPassword = new TextBox
|
||
{
|
||
Name = "txtPassword",
|
||
Location = new Point(170, 100),
|
||
Width = 200,
|
||
PasswordChar = '*'
|
||
};
|
||
|
||
// Кнопка входа
|
||
Button buttonLogin = new Button
|
||
{
|
||
Name = "buttonLogin",
|
||
Text = "Войти",
|
||
Location = new Point(200, 150),
|
||
Width = 100
|
||
};
|
||
buttonLogin.Click += ButtonLogin_Click;
|
||
|
||
// Добавляем все компоненты на форму
|
||
this.Controls.Add(lblHeader);
|
||
this.Controls.Add(lblLogin);
|
||
this.Controls.Add(txtLogin);
|
||
this.Controls.Add(lblPassword);
|
||
this.Controls.Add(txtPassword);
|
||
this.Controls.Add(buttonLogin);
|
||
|
||
// Устанавливаем размеры формы
|
||
this.Width = 480;
|
||
this.Height = 250;
|
||
}
|
||
|
||
private void ButtonLogin_Click(object sender, EventArgs e)
|
||
{
|
||
string login = this.Controls["txtLogin"].Text;
|
||
string password = this.Controls["txtPassword"].Text;
|
||
|
||
try
|
||
{
|
||
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
|
||
{
|
||
connection.Open();
|
||
string query = "SELECT COUNT(*) FROM Users WHERE Login = @Login AND Password = @Password";
|
||
using (SQLiteCommand command = new SQLiteCommand(query, connection))
|
||
{
|
||
command.Parameters.AddWithValue("@Login", login);
|
||
command.Parameters.AddWithValue("@Password", password);
|
||
int count = Convert.ToInt32(command.ExecuteScalar());
|
||
|
||
if (count > 0)
|
||
{
|
||
MessageBox.Show("Вход выполнен успешно!", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
|
||
// Скрываем текущую форму
|
||
this.Hide();
|
||
|
||
// Открываем главную форму приложения
|
||
MainForm mainForm = new MainForm(connectionString);
|
||
mainForm.FormClosed += (s, args) => this.Close();
|
||
mainForm.Show();
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("Неверный логин или пароль!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show("Ошибка входа: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Форма для работы с таблицами
|
||
public class MainForm : Form
|
||
{
|
||
private string connectionString;
|
||
private TabControl tabControl;
|
||
private TabPage tabEmployees;
|
||
private TabPage tabAttendance;
|
||
private DataGridView dgvEmployees;
|
||
private DataGridView dgvAttendance;
|
||
|
||
public MainForm(string connString)
|
||
{
|
||
connectionString = connString;
|
||
|
||
InitializeComponent();
|
||
LoadEmployeeData();
|
||
LoadAttendanceData();
|
||
}
|
||
|
||
private void InitializeComponent()
|
||
{
|
||
this.Text = "Система учета посещаемости";
|
||
this.Width = 800;
|
||
this.Height = 600;
|
||
this.StartPosition = FormStartPosition.CenterScreen;
|
||
|
||
// Создаем вкладки
|
||
tabControl = new TabControl
|
||
{
|
||
Dock = DockStyle.Fill
|
||
};
|
||
|
||
// Вкладка "Сотрудники"
|
||
tabEmployees = new TabPage
|
||
{
|
||
Text = "Сотрудники"
|
||
};
|
||
|
||
// Вкладка "Посещаемость"
|
||
tabAttendance = new TabPage
|
||
{
|
||
Text = "Посещаемость"
|
||
};
|
||
|
||
// Панель для кнопок сотрудников
|
||
Panel panelEmployeesButtons = new Panel
|
||
{
|
||
Dock = DockStyle.Top,
|
||
Height = 50
|
||
};
|
||
|
||
// Кнопки для управления сотрудниками
|
||
Button btnAddEmployee = new Button
|
||
{
|
||
Text = "Добавить сотрудника",
|
||
Width = 150,
|
||
Location = new Point(10, 10)
|
||
};
|
||
btnAddEmployee.Click += BtnAddEmployee_Click;
|
||
|
||
Button btnEditEmployee = new Button
|
||
{
|
||
Text = "Редактировать",
|
||
Width = 150,
|
||
Location = new Point(170, 10)
|
||
};
|
||
btnEditEmployee.Click += BtnEditEmployee_Click;
|
||
|
||
Button btnDeleteEmployee = new Button
|
||
{
|
||
Text = "Удалить",
|
||
Width = 150,
|
||
Location = new Point(330, 10)
|
||
};
|
||
btnDeleteEmployee.Click += BtnDeleteEmployee_Click;
|
||
|
||
// Добавляем кнопки на панель
|
||
panelEmployeesButtons.Controls.Add(btnAddEmployee);
|
||
panelEmployeesButtons.Controls.Add(btnEditEmployee);
|
||
panelEmployeesButtons.Controls.Add(btnDeleteEmployee);
|
||
|
||
// Таблица для сотрудников
|
||
dgvEmployees = new DataGridView
|
||
{
|
||
AllowUserToAddRows = false,
|
||
AllowUserToDeleteRows = false,
|
||
ReadOnly = true,
|
||
AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill,
|
||
SelectionMode = DataGridViewSelectionMode.FullRowSelect,
|
||
Dock = DockStyle.Fill
|
||
};
|
||
|
||
// ВАЖНО: сначала добавляем DataGridView, затем панель кнопок
|
||
// Это обеспечивает правильное расположение элементов сверху вниз
|
||
tabEmployees.Controls.Add(dgvEmployees);
|
||
tabEmployees.Controls.Add(panelEmployeesButtons);
|
||
|
||
// Панель для кнопок посещаемости
|
||
Panel panelAttendanceButtons = new Panel
|
||
{
|
||
Dock = DockStyle.Top,
|
||
Height = 50
|
||
};
|
||
|
||
// Кнопки для управления посещаемостью
|
||
Button btnArrival = new Button
|
||
{
|
||
Text = "Отметить прибытие",
|
||
Width = 150,
|
||
Location = new Point(10, 10)
|
||
};
|
||
btnArrival.Click += BtnArrival_Click;
|
||
|
||
Button btnDeparture = new Button
|
||
{
|
||
Text = "Отметить убытие",
|
||
Width = 150,
|
||
Location = new Point(170, 10)
|
||
};
|
||
btnDeparture.Click += BtnDeparture_Click;
|
||
|
||
// Добавляем кнопки на панель
|
||
panelAttendanceButtons.Controls.Add(btnArrival);
|
||
panelAttendanceButtons.Controls.Add(btnDeparture);
|
||
|
||
// Таблица для посещаемости
|
||
dgvAttendance = new DataGridView
|
||
{
|
||
AllowUserToAddRows = false,
|
||
AllowUserToDeleteRows = false,
|
||
ReadOnly = true,
|
||
AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill,
|
||
SelectionMode = DataGridViewSelectionMode.FullRowSelect,
|
||
Dock = DockStyle.Fill
|
||
};
|
||
|
||
// ВАЖНО: сначала добавляем DataGridView, затем панель кнопок
|
||
tabAttendance.Controls.Add(dgvAttendance);
|
||
tabAttendance.Controls.Add(panelAttendanceButtons);
|
||
|
||
// Добавляем вкладки в контрол
|
||
tabControl.TabPages.Add(tabEmployees);
|
||
tabControl.TabPages.Add(tabAttendance);
|
||
|
||
// Добавляем контрол вкладок на форму
|
||
this.Controls.Add(tabControl);
|
||
}
|
||
|
||
|
||
private void LoadEmployeeData()
|
||
{
|
||
try
|
||
{
|
||
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
|
||
{
|
||
connection.Open();
|
||
string query = "SELECT EmployeeID, LastName, FirstName, MiddleName, Position, Department FROM Employees";
|
||
SQLiteDataAdapter adapter = new SQLiteDataAdapter(query, connection);
|
||
DataTable dt = new DataTable();
|
||
adapter.Fill(dt);
|
||
dgvEmployees.DataSource = dt;
|
||
|
||
// Переименовываем колонки для отображения
|
||
if (dt.Rows.Count > 0)
|
||
{
|
||
dgvEmployees.Columns["EmployeeID"].HeaderText = "ID";
|
||
dgvEmployees.Columns["LastName"].HeaderText = "Фамилия";
|
||
dgvEmployees.Columns["FirstName"].HeaderText = "Имя";
|
||
dgvEmployees.Columns["MiddleName"].HeaderText = "Отчество";
|
||
dgvEmployees.Columns["Position"].HeaderText = "Должность";
|
||
dgvEmployees.Columns["Department"].HeaderText = "Отдел";
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show("Ошибка загрузки данных сотрудников: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void LoadAttendanceData()
|
||
{
|
||
try
|
||
{
|
||
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
|
||
{
|
||
connection.Open();
|
||
// Изменен синтаксис конкатенации для SQLite
|
||
string query = @"SELECT a.AttendanceID, e.EmployeeID,
|
||
e.LastName || ' ' || e.FirstName || ' ' || COALESCE(e.MiddleName, '') as FullName,
|
||
a.ArrivalTime, a.DepartureTime
|
||
FROM Attendance a
|
||
JOIN Employees e ON a.EmployeeID = e.EmployeeID
|
||
ORDER BY a.ArrivalTime DESC";
|
||
SQLiteDataAdapter adapter = new SQLiteDataAdapter(query, connection);
|
||
DataTable dt = new DataTable();
|
||
adapter.Fill(dt);
|
||
dgvAttendance.DataSource = dt;
|
||
|
||
// Переименовываем колонки для отображения
|
||
if (dt.Rows.Count > 0)
|
||
{
|
||
dgvAttendance.Columns["AttendanceID"].HeaderText = "ID записи";
|
||
dgvAttendance.Columns["EmployeeID"].HeaderText = "ID сотрудника";
|
||
dgvAttendance.Columns["FullName"].HeaderText = "ФИО";
|
||
dgvAttendance.Columns["ArrivalTime"].HeaderText = "Время прибытия";
|
||
dgvAttendance.Columns["DepartureTime"].HeaderText = "Время убытия";
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show("Ошибка загрузки данных посещаемости: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
// Обработчики событий для кнопок
|
||
private void BtnAddEmployee_Click(object sender, EventArgs e)
|
||
{
|
||
EmployeeForm form = new EmployeeForm(connectionString, 0);
|
||
if (form.ShowDialog() == DialogResult.OK)
|
||
{
|
||
LoadEmployeeData();
|
||
}
|
||
}
|
||
|
||
private void BtnEditEmployee_Click(object sender, EventArgs e)
|
||
{
|
||
if (dgvEmployees.SelectedRows.Count > 0)
|
||
{
|
||
int employeeId = Convert.ToInt32(dgvEmployees.SelectedRows[0].Cells["EmployeeID"].Value);
|
||
EmployeeForm form = new EmployeeForm(connectionString, employeeId);
|
||
if (form.ShowDialog() == DialogResult.OK)
|
||
{
|
||
LoadEmployeeData();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("Выберите сотрудника для редактирования", "Информация", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
}
|
||
|
||
private void BtnDeleteEmployee_Click(object sender, EventArgs e)
|
||
{
|
||
if (dgvEmployees.SelectedRows.Count > 0)
|
||
{
|
||
int employeeId = Convert.ToInt32(dgvEmployees.SelectedRows[0].Cells["EmployeeID"].Value);
|
||
string employeeName = dgvEmployees.SelectedRows[0].Cells["LastName"].Value.ToString() + " " +
|
||
dgvEmployees.SelectedRows[0].Cells["FirstName"].Value.ToString();
|
||
|
||
DialogResult result = MessageBox.Show($"Вы уверены, что хотите удалить сотрудника {employeeName}?",
|
||
"Подтверждение", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||
if (result == DialogResult.Yes)
|
||
{
|
||
try
|
||
{
|
||
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
|
||
{
|
||
connection.Open();
|
||
// Начинаем транзакцию
|
||
using (SQLiteTransaction transaction = connection.BeginTransaction())
|
||
{
|
||
try
|
||
{
|
||
// Сначала удаляем записи посещаемости
|
||
string deleteAttendance = "DELETE FROM Attendance WHERE EmployeeID = @EmployeeID";
|
||
using (SQLiteCommand command = new SQLiteCommand(deleteAttendance, connection, transaction))
|
||
{
|
||
command.Parameters.AddWithValue("@EmployeeID", employeeId);
|
||
command.ExecuteNonQuery();
|
||
}
|
||
|
||
// Затем удаляем сотрудника
|
||
string deleteEmployee = "DELETE FROM Employees WHERE EmployeeID = @EmployeeID";
|
||
using (SQLiteCommand command = new SQLiteCommand(deleteEmployee, connection, transaction))
|
||
{
|
||
command.Parameters.AddWithValue("@EmployeeID", employeeId);
|
||
command.ExecuteNonQuery();
|
||
}
|
||
|
||
// Фиксируем изменения
|
||
transaction.Commit();
|
||
MessageBox.Show("Сотрудник успешно удален", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
LoadEmployeeData();
|
||
LoadAttendanceData();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// Откатываем изменения при ошибке
|
||
transaction.Rollback();
|
||
throw ex;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show("Ошибка при удалении сотрудника: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("Выберите сотрудника для удаления", "Информация", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
}
|
||
|
||
private void BtnArrival_Click(object sender, EventArgs e)
|
||
{
|
||
AttendanceForm form = new AttendanceForm(connectionString, true);
|
||
if (form.ShowDialog() == DialogResult.OK)
|
||
{
|
||
LoadAttendanceData();
|
||
}
|
||
}
|
||
|
||
private void BtnDeparture_Click(object sender, EventArgs e)
|
||
{
|
||
AttendanceForm form = new AttendanceForm(connectionString, false);
|
||
if (form.ShowDialog() == DialogResult.OK)
|
||
{
|
||
LoadAttendanceData();
|
||
}
|
||
}
|
||
}
|
||
|
||
// Форма для добавления/редактирования сотрудника
|
||
public class EmployeeForm : Form
|
||
{
|
||
private string connectionString;
|
||
private int employeeId;
|
||
private TextBox txtLastName;
|
||
private TextBox txtFirstName;
|
||
private TextBox txtMiddleName;
|
||
private TextBox txtPosition;
|
||
private TextBox txtDepartment;
|
||
|
||
public EmployeeForm(string connString, int id)
|
||
{
|
||
connectionString = connString;
|
||
employeeId = id;
|
||
|
||
InitializeComponent();
|
||
|
||
if (employeeId > 0)
|
||
{
|
||
this.Text = "Редактирование сотрудника";
|
||
LoadEmployeeData();
|
||
}
|
||
else
|
||
{
|
||
this.Text = "Добавление нового сотрудника";
|
||
}
|
||
}
|
||
|
||
private void InitializeComponent()
|
||
{
|
||
this.Width = 400;
|
||
this.Height = 300;
|
||
this.StartPosition = FormStartPosition.CenterParent;
|
||
this.FormBorderStyle = FormBorderStyle.FixedDialog;
|
||
this.MaximizeBox = false;
|
||
this.MinimizeBox = false;
|
||
|
||
// Поля для ввода данных
|
||
Label lblLastName = new Label
|
||
{
|
||
Text = "Фамилия:",
|
||
Location = new Point(30, 20),
|
||
Width = 100
|
||
};
|
||
|
||
txtLastName = new TextBox
|
||
{
|
||
Location = new Point(150, 20),
|
||
Width = 200
|
||
};
|
||
|
||
Label lblFirstName = new Label
|
||
{
|
||
Text = "Имя:",
|
||
Location = new Point(30, 50),
|
||
Width = 100
|
||
};
|
||
|
||
txtFirstName = new TextBox
|
||
{
|
||
Location = new Point(150, 50),
|
||
Width = 200
|
||
};
|
||
|
||
Label lblMiddleName = new Label
|
||
{
|
||
Text = "Отчество:",
|
||
Location = new Point(30, 80),
|
||
Width = 100
|
||
};
|
||
|
||
txtMiddleName = new TextBox
|
||
{
|
||
Location = new Point(150, 80),
|
||
Width = 200
|
||
};
|
||
|
||
Label lblPosition = new Label
|
||
{
|
||
Text = "Должность:",
|
||
Location = new Point(30, 110),
|
||
Width = 100
|
||
};
|
||
|
||
txtPosition = new TextBox
|
||
{
|
||
Location = new Point(150, 110),
|
||
Width = 200
|
||
};
|
||
|
||
Label lblDepartment = new Label
|
||
{
|
||
Text = "Отдел:",
|
||
Location = new Point(30, 140),
|
||
Width = 100
|
||
};
|
||
|
||
txtDepartment = new TextBox
|
||
{
|
||
Location = new Point(150, 140),
|
||
Width = 200
|
||
};
|
||
|
||
// Кнопки
|
||
Button btnSave = new Button
|
||
{
|
||
Text = "Сохранить",
|
||
DialogResult = DialogResult.OK,
|
||
Location = new Point(150, 180),
|
||
Width = 100
|
||
};
|
||
btnSave.Click += BtnSave_Click;
|
||
|
||
Button btnCancel = new Button
|
||
{
|
||
Text = "Отмена",
|
||
DialogResult = DialogResult.Cancel,
|
||
Location = new Point(260, 180),
|
||
Width = 100
|
||
};
|
||
|
||
// Добавляем компоненты на форму
|
||
this.Controls.Add(lblLastName);
|
||
this.Controls.Add(txtLastName);
|
||
this.Controls.Add(lblFirstName);
|
||
this.Controls.Add(txtFirstName);
|
||
this.Controls.Add(lblMiddleName);
|
||
this.Controls.Add(txtMiddleName);
|
||
this.Controls.Add(lblPosition);
|
||
this.Controls.Add(txtPosition);
|
||
this.Controls.Add(lblDepartment);
|
||
this.Controls.Add(txtDepartment);
|
||
this.Controls.Add(btnSave);
|
||
this.Controls.Add(btnCancel);
|
||
|
||
this.AcceptButton = btnSave;
|
||
this.CancelButton = btnCancel;
|
||
}
|
||
|
||
private void LoadEmployeeData()
|
||
{
|
||
try
|
||
{
|
||
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
|
||
{
|
||
connection.Open();
|
||
string query = "SELECT LastName, FirstName, MiddleName, Position, Department FROM Employees WHERE EmployeeID = @EmployeeID";
|
||
using (SQLiteCommand command = new SQLiteCommand(query, connection))
|
||
{
|
||
command.Parameters.AddWithValue("@EmployeeID", employeeId);
|
||
using (SQLiteDataReader reader = command.ExecuteReader())
|
||
{
|
||
if (reader.Read())
|
||
{
|
||
txtLastName.Text = reader["LastName"].ToString();
|
||
txtFirstName.Text = reader["FirstName"].ToString();
|
||
txtMiddleName.Text = reader["MiddleName"].ToString();
|
||
txtPosition.Text = reader["Position"].ToString();
|
||
txtDepartment.Text = reader["Department"].ToString();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show("Ошибка при загрузке данных сотрудника: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void BtnSave_Click(object sender, EventArgs e)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(txtLastName.Text) || string.IsNullOrWhiteSpace(txtFirstName.Text))
|
||
{
|
||
MessageBox.Show("Фамилия и имя обязательны для заполнения", "Предупреждение", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
this.DialogResult = DialogResult.None;
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
|
||
{
|
||
connection.Open();
|
||
string query;
|
||
|
||
if (employeeId > 0)
|
||
{
|
||
// Обновление существующего сотрудника
|
||
query = @"UPDATE Employees SET
|
||
LastName = @LastName,
|
||
FirstName = @FirstName,
|
||
MiddleName = @MiddleName,
|
||
Position = @Position,
|
||
Department = @Department
|
||
WHERE EmployeeID = @EmployeeID";
|
||
}
|
||
else
|
||
{
|
||
// Добавление нового сотрудника
|
||
query = @"INSERT INTO Employees (LastName, FirstName, MiddleName, Position, Department)
|
||
VALUES (@LastName, @FirstName, @MiddleName, @Position, @Department)";
|
||
}
|
||
|
||
using (SQLiteCommand command = new SQLiteCommand(query, connection))
|
||
{
|
||
command.Parameters.AddWithValue("@LastName", txtLastName.Text);
|
||
command.Parameters.AddWithValue("@FirstName", txtFirstName.Text);
|
||
command.Parameters.AddWithValue("@MiddleName", txtMiddleName.Text);
|
||
command.Parameters.AddWithValue("@Position", txtPosition.Text);
|
||
command.Parameters.AddWithValue("@Department", txtDepartment.Text);
|
||
|
||
if (employeeId > 0)
|
||
{
|
||
command.Parameters.AddWithValue("@EmployeeID", employeeId);
|
||
}
|
||
|
||
command.ExecuteNonQuery();
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show("Ошибка при сохранении данных: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
this.DialogResult = DialogResult.None;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Форма для отметки посещаемости
|
||
public class AttendanceForm : Form
|
||
{
|
||
private string connectionString;
|
||
private bool isArrival;
|
||
private ComboBox cmbEmployees;
|
||
|
||
public AttendanceForm(string connString, bool arrival)
|
||
{
|
||
connectionString = connString;
|
||
isArrival = arrival;
|
||
|
||
InitializeComponent();
|
||
LoadEmployees();
|
||
|
||
this.Text = isArrival ? "Отметка прибытия" : "Отметка убытия";
|
||
}
|
||
|
||
private void InitializeComponent()
|
||
{
|
||
this.Width = 400;
|
||
this.Height = 200;
|
||
this.StartPosition = FormStartPosition.CenterParent;
|
||
this.FormBorderStyle = FormBorderStyle.FixedDialog;
|
||
this.MaximizeBox = false;
|
||
this.MinimizeBox = false;
|
||
|
||
// Заголовок
|
||
Label lblHeader = new Label
|
||
{
|
||
Text = isArrival ? "Отметка прибытия сотрудника" : "Отметка убытия сотрудника",
|
||
Font = new Font("Arial", 12, FontStyle.Bold),
|
||
Location = new Point(50, 20),
|
||
Width = 300,
|
||
TextAlign = ContentAlignment.MiddleCenter
|
||
};
|
||
|
||
// Выбор сотрудника
|
||
Label lblEmployee = new Label
|
||
{
|
||
Text = "Сотрудник:",
|
||
Location = new Point(30, 60),
|
||
Width = 100
|
||
};
|
||
|
||
cmbEmployees = new ComboBox
|
||
{
|
||
Location = new Point(130, 60),
|
||
Width = 220,
|
||
DropDownStyle = ComboBoxStyle.DropDownList
|
||
};
|
||
|
||
// Кнопки
|
||
Button btnSave = new Button
|
||
{
|
||
Text = "Отметить",
|
||
DialogResult = DialogResult.OK,
|
||
Location = new Point(130, 100),
|
||
Width = 100
|
||
};
|
||
btnSave.Click += BtnSave_Click;
|
||
|
||
Button btnCancel = new Button
|
||
{
|
||
Text = "Отмена",
|
||
DialogResult = DialogResult.Cancel,
|
||
Location = new Point(250, 100),
|
||
Width = 100
|
||
};
|
||
|
||
// Добавляем компоненты на форму
|
||
this.Controls.Add(lblHeader);
|
||
this.Controls.Add(lblEmployee);
|
||
this.Controls.Add(cmbEmployees);
|
||
this.Controls.Add(btnSave);
|
||
this.Controls.Add(btnCancel);
|
||
|
||
this.AcceptButton = btnSave;
|
||
this.CancelButton = btnCancel;
|
||
}
|
||
|
||
private void LoadEmployees()
|
||
{
|
||
try
|
||
{
|
||
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
|
||
{
|
||
connection.Open();
|
||
string query = "SELECT EmployeeID, LastName || ' ' || FirstName || ' ' || COALESCE(MiddleName, '') as FullName FROM Employees ORDER BY LastName, FirstName";
|
||
SQLiteDataAdapter adapter = new SQLiteDataAdapter(query, connection);
|
||
DataTable dt = new DataTable();
|
||
adapter.Fill(dt);
|
||
|
||
cmbEmployees.DataSource = dt;
|
||
cmbEmployees.DisplayMember = "FullName";
|
||
cmbEmployees.ValueMember = "EmployeeID";
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show("Ошибка при загрузке списка сотрудников: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void BtnSave_Click(object sender, EventArgs e)
|
||
{
|
||
if (cmbEmployees.SelectedValue == null)
|
||
{
|
||
MessageBox.Show("Необходимо выбрать сотрудника", "Предупреждение", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
this.DialogResult = DialogResult.None;
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
|
||
{
|
||
connection.Open();
|
||
|
||
if (isArrival)
|
||
{
|
||
// Отметка прибытия - создаем новую запись
|
||
string query = "INSERT INTO Attendance (EmployeeID, ArrivalTime) VALUES (@EmployeeID, @ArrivalTime)";
|
||
using (SQLiteCommand command = new SQLiteCommand(query, connection))
|
||
{
|
||
command.Parameters.AddWithValue("@EmployeeID", cmbEmployees.SelectedValue);
|
||
command.Parameters.AddWithValue("@ArrivalTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
|
||
command.ExecuteNonQuery();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Отметка убытия - ищем последнюю запись с прибытием для данного сотрудника
|
||
string query = @"UPDATE Attendance SET DepartureTime = @DepartureTime
|
||
WHERE EmployeeID = @EmployeeID AND DepartureTime IS NULL
|
||
AND AttendanceID = (SELECT AttendanceID FROM Attendance
|
||
WHERE EmployeeID = @EmployeeID AND DepartureTime IS NULL
|
||
ORDER BY ArrivalTime DESC LIMIT 1)";
|
||
using (SQLiteCommand command = new SQLiteCommand(query, connection))
|
||
{
|
||
command.Parameters.AddWithValue("@EmployeeID", cmbEmployees.SelectedValue);
|
||
command.Parameters.AddWithValue("@DepartureTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
|
||
int rowsAffected = command.ExecuteNonQuery();
|
||
|
||
if (rowsAffected == 0)
|
||
{
|
||
MessageBox.Show("Для данного сотрудника нет открытых записей о прибытии",
|
||
"Информация", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
this.DialogResult = DialogResult.None;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
MessageBox.Show("Посещаемость успешно отмечена", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show("Ошибка при сохранении данных: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
this.DialogResult = DialogResult.None;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|