Full demo: complete
This commit is contained in:
parent
bce57e79f2
commit
703adc3326
4 changed files with 1500 additions and 0 deletions
807
control1.py
Normal file
807
control1.py
Normal file
|
|
@ -0,0 +1,807 @@
|
|||
import sys
|
||||
import sqlite3
|
||||
from datetime import datetime
|
||||
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
||||
QLabel, QLineEdit, QTextEdit, QComboBox, QPushButton, QTableWidget,
|
||||
QTableWidgetItem, QTabWidget, QGroupBox, QMessageBox, QFileDialog,
|
||||
QSplitter, QHeaderView, QFormLayout, QCheckBox, QDialog)
|
||||
from PyQt6.QtCore import Qt, pyqtSignal
|
||||
from PyQt6.QtGui import QIcon, QAction
|
||||
import os
|
||||
|
||||
class DatabaseManager:
|
||||
def __init__(self):
|
||||
self.conn = sqlite3.connect('service_requests.db')
|
||||
self.create_tables()
|
||||
|
||||
def create_tables(self):
|
||||
cursor = self.conn.cursor()
|
||||
|
||||
# Таблица пользователей
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
role TEXT NOT NULL,
|
||||
full_name TEXT NOT NULL,
|
||||
phone TEXT
|
||||
)
|
||||
''')
|
||||
|
||||
# Таблица заявок
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS service_requests (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
client_name TEXT NOT NULL,
|
||||
client_phone TEXT NOT NULL,
|
||||
equipment_type TEXT NOT NULL,
|
||||
equipment_model TEXT NOT NULL,
|
||||
problem_description TEXT NOT NULL,
|
||||
status TEXT DEFAULT 'Новая',
|
||||
priority TEXT DEFAULT 'Средний',
|
||||
request_type TEXT DEFAULT 'Ремонт',
|
||||
assigned_operator TEXT,
|
||||
assigned_master TEXT,
|
||||
created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
completed_date TIMESTAMP,
|
||||
observer_group TEXT
|
||||
)
|
||||
''')
|
||||
|
||||
# Таблица истории заявок
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS request_history (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
request_id INTEGER,
|
||||
user_id INTEGER,
|
||||
action TEXT,
|
||||
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (request_id) REFERENCES service_requests (id)
|
||||
)
|
||||
''')
|
||||
|
||||
# Таблица вложений
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS attachments (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
request_id INTEGER,
|
||||
filename TEXT,
|
||||
filepath TEXT,
|
||||
uploaded_by INTEGER,
|
||||
upload_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (request_id) REFERENCES service_requests (id)
|
||||
)
|
||||
''')
|
||||
|
||||
# Таблица отчетов
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS reports (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
request_id INTEGER,
|
||||
master_id INTEGER,
|
||||
work_description TEXT,
|
||||
parts_used TEXT,
|
||||
time_spent REAL,
|
||||
created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (request_id) REFERENCES service_requests (id)
|
||||
)
|
||||
''')
|
||||
|
||||
# Таблица заказов запчастей
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS part_orders (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
request_id INTEGER,
|
||||
part_name TEXT,
|
||||
quantity INTEGER,
|
||||
status TEXT DEFAULT 'Заказан',
|
||||
ordered_by INTEGER,
|
||||
order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (request_id) REFERENCES service_requests (id)
|
||||
)
|
||||
''')
|
||||
|
||||
# Создаем тестовых пользователей
|
||||
self.create_test_users()
|
||||
|
||||
self.conn.commit()
|
||||
|
||||
def create_test_users(self):
|
||||
cursor = self.conn.cursor()
|
||||
|
||||
test_users = [
|
||||
('client1', '123', 'client', 'Иван Иванов', '+79161234567'),
|
||||
('operator1', '123', 'operator', 'Петр Петров', '+79167654321'),
|
||||
('master1', '123', 'master', 'Сергей Сергеев', '+79169998877'),
|
||||
('admin1', '123', 'admin', 'Администратор Системы', '+79160001122')
|
||||
]
|
||||
|
||||
for user in test_users:
|
||||
try:
|
||||
cursor.execute(
|
||||
'INSERT INTO users (username, password, role, full_name, phone) VALUES (?, ?, ?, ?, ?)',
|
||||
user
|
||||
)
|
||||
except sqlite3.IntegrityError:
|
||||
pass # Пользователь уже существует
|
||||
|
||||
self.conn.commit()
|
||||
|
||||
class ServiceRequestApp(QMainWindow):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.db = DatabaseManager()
|
||||
self.current_user = None
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
self.setWindowTitle('Система учета заявок на ремонт оргтехники')
|
||||
self.setGeometry(100, 100, 1200, 700)
|
||||
|
||||
# Центральный виджет
|
||||
central_widget = QWidget()
|
||||
self.setCentralWidget(central_widget)
|
||||
|
||||
# Основной layout
|
||||
layout = QVBoxLayout(central_widget)
|
||||
|
||||
# Панель входа
|
||||
self.login_widget = self.create_login_widget()
|
||||
layout.addWidget(self.login_widget)
|
||||
|
||||
# Основной интерфейс (скрыт до входа)
|
||||
self.main_tabs = QTabWidget()
|
||||
self.main_tabs.setVisible(False)
|
||||
layout.addWidget(self.main_tabs)
|
||||
|
||||
def create_login_widget(self):
|
||||
widget = QWidget()
|
||||
layout = QVBoxLayout(widget)
|
||||
|
||||
layout.addWidget(QLabel('Вход в систему'))
|
||||
|
||||
form_layout = QFormLayout()
|
||||
|
||||
self.username_input = QLineEdit()
|
||||
self.password_input = QLineEdit()
|
||||
self.password_input.setEchoMode(QLineEdit.EchoMode.Password)
|
||||
|
||||
form_layout.addRow('Логин:', self.username_input)
|
||||
form_layout.addRow('Пароль:', self.password_input)
|
||||
|
||||
layout.addLayout(form_layout)
|
||||
|
||||
login_btn = QPushButton('Войти')
|
||||
login_btn.clicked.connect(self.login)
|
||||
layout.addWidget(login_btn)
|
||||
|
||||
return widget
|
||||
|
||||
def login(self):
|
||||
username = self.username_input.text()
|
||||
password = self.password_input.text()
|
||||
|
||||
cursor = self.db.conn.cursor()
|
||||
cursor.execute(
|
||||
'SELECT * FROM users WHERE username = ? AND password = ?',
|
||||
(username, password)
|
||||
)
|
||||
|
||||
user = cursor.fetchone()
|
||||
|
||||
if user:
|
||||
self.current_user = {
|
||||
'id': user[0],
|
||||
'username': user[1],
|
||||
'role': user[3],
|
||||
'full_name': user[4]
|
||||
}
|
||||
self.show_main_interface()
|
||||
else:
|
||||
QMessageBox.warning(self, 'Ошибка', 'Неверный логин или пароль')
|
||||
|
||||
def show_main_interface(self):
|
||||
self.login_widget.setVisible(False)
|
||||
self.main_tabs.setVisible(True)
|
||||
|
||||
# Очищаем предыдущие вкладки
|
||||
self.main_tabs.clear()
|
||||
|
||||
role = self.current_user['role']
|
||||
|
||||
if role == 'client':
|
||||
self.setup_client_interface()
|
||||
elif role == 'operator':
|
||||
self.setup_operator_interface()
|
||||
elif role == 'master':
|
||||
self.setup_master_interface()
|
||||
elif role == 'admin':
|
||||
self.setup_admin_interface()
|
||||
|
||||
def setup_client_interface(self):
|
||||
# Вкладка создания заявки
|
||||
create_tab = QWidget()
|
||||
layout = QVBoxLayout(create_tab)
|
||||
|
||||
form_layout = QFormLayout()
|
||||
|
||||
self.client_name = QLineEdit(self.current_user['full_name'])
|
||||
self.client_phone = QLineEdit()
|
||||
self.equipment_type = QComboBox()
|
||||
self.equipment_type.addItems(['Принтер', 'Копир', 'Сканер', 'МФУ', 'Компьютер'])
|
||||
self.equipment_model = QLineEdit()
|
||||
self.problem_description = QTextEdit()
|
||||
|
||||
form_layout.addRow('ФИО:', self.client_name)
|
||||
form_layout.addRow('Телефон:', self.client_phone)
|
||||
form_layout.addRow('Тип оборудования:', self.equipment_type)
|
||||
form_layout.addRow('Модель:', self.equipment_model)
|
||||
form_layout.addRow('Описание проблемы:', self.problem_description)
|
||||
|
||||
layout.addLayout(form_layout)
|
||||
|
||||
submit_btn = QPushButton('Создать заявку')
|
||||
submit_btn.clicked.connect(self.create_service_request)
|
||||
layout.addWidget(submit_btn)
|
||||
|
||||
self.main_tabs.addTab(create_tab, 'Новая заявка')
|
||||
|
||||
# Вкладка моих заявок
|
||||
requests_tab = QWidget()
|
||||
layout = QVBoxLayout(requests_tab)
|
||||
|
||||
self.client_requests_table = QTableWidget()
|
||||
self.client_requests_table.setColumnCount(6)
|
||||
self.client_requests_table.setHorizontalHeaderLabels([
|
||||
'ID', 'Оборудование', 'Модель', 'Статус', 'Дата создания', 'Приоритет'
|
||||
])
|
||||
layout.addWidget(self.client_requests_table)
|
||||
|
||||
details_btn = QPushButton('Просмотреть детали')
|
||||
details_btn.clicked.connect(self.show_request_details)
|
||||
layout.addWidget(details_btn)
|
||||
|
||||
self.main_tabs.addTab(requests_tab, 'Мои заявки')
|
||||
|
||||
self.load_client_requests()
|
||||
|
||||
def setup_operator_interface(self):
|
||||
# Вкладка всех заявок
|
||||
requests_tab = QWidget()
|
||||
layout = QVBoxLayout(requests_tab)
|
||||
|
||||
self.operator_requests_table = QTableWidget()
|
||||
self.operator_requests_table.setColumnCount(8)
|
||||
self.operator_requests_table.setHorizontalHeaderLabels([
|
||||
'ID', 'Клиент', 'Оборудование', 'Модель', 'Статус', 'Приоритет', 'Дата', 'Оператор'
|
||||
])
|
||||
layout.addWidget(self.operator_requests_table)
|
||||
|
||||
# Панель управления заявкой
|
||||
control_group = QGroupBox('Управление заявкой')
|
||||
control_layout = QHBoxLayout(control_group)
|
||||
|
||||
self.status_combo = QComboBox()
|
||||
self.status_combo.addItems(['Новая', 'В работе', 'Ожидает запчасти', 'Выполнена', 'Отменена'])
|
||||
|
||||
self.priority_combo = QComboBox()
|
||||
self.priority_combo.addItems(['Низкий', 'Средний', 'Высокий', 'Критичный'])
|
||||
|
||||
self.type_combo = QComboBox()
|
||||
self.type_combo.addItems(['Ремонт', 'Обслуживание', 'Консультация'])
|
||||
|
||||
self.observer_group = QLineEdit()
|
||||
|
||||
update_btn = QPushButton('Обновить заявку')
|
||||
update_btn.clicked.connect(self.update_request_operator)
|
||||
|
||||
control_layout.addWidget(QLabel('Статус:'))
|
||||
control_layout.addWidget(self.status_combo)
|
||||
control_layout.addWidget(QLabel('Приоритет:'))
|
||||
control_layout.addWidget(self.priority_combo)
|
||||
control_layout.addWidget(QLabel('Тип:'))
|
||||
control_layout.addWidget(self.type_combo)
|
||||
control_layout.addWidget(QLabel('Группа наблюдателей:'))
|
||||
control_layout.addWidget(self.observer_group)
|
||||
control_layout.addWidget(update_btn)
|
||||
|
||||
layout.addWidget(control_group)
|
||||
|
||||
self.main_tabs.addTab(requests_tab, 'Все заявки')
|
||||
|
||||
# Вкладка архива
|
||||
archive_tab = QWidget()
|
||||
layout = QVBoxLayout(archive_tab)
|
||||
|
||||
search_layout = QHBoxLayout()
|
||||
self.archive_search = QLineEdit()
|
||||
self.archive_search.setPlaceholderText('Поиск в архиве...')
|
||||
search_btn = QPushButton('Найти')
|
||||
search_btn.clicked.connect(self.search_archive)
|
||||
|
||||
search_layout.addWidget(self.archive_search)
|
||||
search_layout.addWidget(search_btn)
|
||||
layout.addLayout(search_layout)
|
||||
|
||||
self.archive_table = QTableWidget()
|
||||
self.archive_table.setColumnCount(8)
|
||||
self.archive_table.setHorizontalHeaderLabels([
|
||||
'ID', 'Клиент', 'Оборудование', 'Модель', 'Статус', 'Дата создания', 'Дата завершения', 'Мастер'
|
||||
])
|
||||
layout.addWidget(self.archive_table)
|
||||
|
||||
self.main_tabs.addTab(archive_tab, 'Архив')
|
||||
|
||||
self.load_operator_requests()
|
||||
self.load_archive()
|
||||
|
||||
def setup_master_interface(self):
|
||||
# Вкладка назначенных заявок
|
||||
requests_tab = QWidget()
|
||||
layout = QVBoxLayout(requests_tab)
|
||||
|
||||
self.master_requests_table = QTableWidget()
|
||||
self.master_requests_table.setColumnCount(7)
|
||||
self.master_requests_table.setHorizontalHeaderLabels([
|
||||
'ID', 'Клиент', 'Оборудование', 'Модель', 'Статус', 'Приоритет', 'Дата'
|
||||
])
|
||||
layout.addWidget(self.master_requests_table)
|
||||
|
||||
# Панель управления для мастера
|
||||
control_group = QGroupBox('Управление ремонтом')
|
||||
control_layout = QVBoxLayout(control_group)
|
||||
|
||||
# Смена статуса
|
||||
status_layout = QHBoxLayout()
|
||||
status_layout.addWidget(QLabel('Статус:'))
|
||||
self.master_status_combo = QComboBox()
|
||||
self.master_status_combo.addItems(['В работе', 'Ожидает запчасти', 'Выполнена'])
|
||||
status_layout.addWidget(self.master_status_combo)
|
||||
|
||||
update_status_btn = QPushButton('Обновить статус')
|
||||
update_status_btn.clicked.connect(self.update_request_master)
|
||||
status_layout.addWidget(update_status_btn)
|
||||
|
||||
control_layout.addLayout(status_layout)
|
||||
|
||||
# Заказ запчастей
|
||||
parts_layout = QHBoxLayout()
|
||||
parts_layout.addWidget(QLabel('Запчасть:'))
|
||||
self.part_name = QLineEdit()
|
||||
self.part_quantity = QLineEdit()
|
||||
self.part_quantity.setText('1')
|
||||
|
||||
parts_layout.addWidget(self.part_name)
|
||||
parts_layout.addWidget(QLabel('Количество:'))
|
||||
parts_layout.addWidget(self.part_quantity)
|
||||
|
||||
order_parts_btn = QPushButton('Заказать запчасти')
|
||||
order_parts_btn.clicked.connect(self.order_parts)
|
||||
parts_layout.addWidget(order_parts_btn)
|
||||
|
||||
control_layout.addLayout(parts_layout)
|
||||
|
||||
# Прикрепление файлов
|
||||
file_layout = QHBoxLayout()
|
||||
attach_file_btn = QPushButton('Прикрепить файл')
|
||||
attach_file_btn.clicked.connect(self.attach_file)
|
||||
file_layout.addWidget(attach_file_btn)
|
||||
|
||||
control_layout.addLayout(file_layout)
|
||||
|
||||
# Создание отчета
|
||||
report_layout = QHBoxLayout()
|
||||
create_report_btn = QPushButton('Создать отчет')
|
||||
create_report_btn.clicked.connect(self.create_report)
|
||||
report_layout.addWidget(create_report_btn)
|
||||
|
||||
control_layout.addLayout(report_layout)
|
||||
|
||||
layout.addWidget(control_group)
|
||||
|
||||
self.main_tabs.addTab(requests_tab, 'Мои заявки')
|
||||
|
||||
self.load_master_requests()
|
||||
|
||||
def setup_admin_interface(self):
|
||||
# Админский интерфейс будет похож на операторский с дополнительными функциями
|
||||
self.setup_operator_interface()
|
||||
|
||||
# Добавляем вкладку управления пользователями
|
||||
users_tab = QWidget()
|
||||
layout = QVBoxLayout(users_tab)
|
||||
|
||||
self.users_table = QTableWidget()
|
||||
self.users_table.setColumnCount(4)
|
||||
self.users_table.setHorizontalHeaderLabels(['ID', 'Логин', 'ФИО', 'Роль'])
|
||||
layout.addWidget(self.users_table)
|
||||
|
||||
add_user_btn = QPushButton('Добавить пользователя')
|
||||
add_user_btn.clicked.connect(self.show_add_user_dialog)
|
||||
layout.addWidget(add_user_btn)
|
||||
|
||||
self.main_tabs.addTab(users_tab, 'Пользователи')
|
||||
|
||||
self.load_users()
|
||||
|
||||
def create_service_request(self):
|
||||
cursor = self.db.conn.cursor()
|
||||
cursor.execute('''
|
||||
INSERT INTO service_requests
|
||||
(client_name, client_phone, equipment_type, equipment_model, problem_description)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', (
|
||||
self.client_name.text(),
|
||||
self.client_phone.text(),
|
||||
self.equipment_type.currentText(),
|
||||
self.equipment_model.text(),
|
||||
self.problem_description.toPlainText()
|
||||
))
|
||||
|
||||
self.db.conn.commit()
|
||||
|
||||
QMessageBox.information(self, 'Успех', 'Заявка успешно создана!')
|
||||
|
||||
# Очищаем форму
|
||||
self.client_phone.clear()
|
||||
self.equipment_model.clear()
|
||||
self.problem_description.clear()
|
||||
|
||||
def load_client_requests(self):
|
||||
cursor = self.db.conn.cursor()
|
||||
cursor.execute('''
|
||||
SELECT id, equipment_type, equipment_model, status, created_date, priority
|
||||
FROM service_requests
|
||||
WHERE client_name = ?
|
||||
ORDER BY created_date DESC
|
||||
''', (self.current_user['full_name'],))
|
||||
|
||||
requests = cursor.fetchall()
|
||||
|
||||
self.client_requests_table.setRowCount(len(requests))
|
||||
for row, request in enumerate(requests):
|
||||
for col, value in enumerate(request):
|
||||
self.client_requests_table.setItem(row, col, QTableWidgetItem(str(value)))
|
||||
|
||||
def load_operator_requests(self):
|
||||
cursor = self.db.conn.cursor()
|
||||
cursor.execute('''
|
||||
SELECT id, client_name, equipment_type, equipment_model, status, priority, created_date, assigned_operator
|
||||
FROM service_requests
|
||||
ORDER BY created_date DESC
|
||||
''')
|
||||
|
||||
requests = cursor.fetchall()
|
||||
|
||||
self.operator_requests_table.setRowCount(len(requests))
|
||||
for row, request in enumerate(requests):
|
||||
for col, value in enumerate(request):
|
||||
self.operator_requests_table.setItem(row, col, QTableWidgetItem(str(value) if value is not None else ''))
|
||||
|
||||
def load_master_requests(self):
|
||||
cursor = self.db.conn.cursor()
|
||||
cursor.execute('''
|
||||
SELECT id, client_name, equipment_type, equipment_model, status, priority, created_date
|
||||
FROM service_requests
|
||||
WHERE status != 'Выполнена' AND status != 'Отменена'
|
||||
ORDER BY
|
||||
CASE priority
|
||||
WHEN 'Критичный' THEN 1
|
||||
WHEN 'Высокий' THEN 2
|
||||
WHEN 'Средний' THEN 3
|
||||
WHEN 'Низкий' THEN 4
|
||||
END,
|
||||
created_date
|
||||
''')
|
||||
|
||||
requests = cursor.fetchall()
|
||||
|
||||
self.master_requests_table.setRowCount(len(requests))
|
||||
for row, request in enumerate(requests):
|
||||
for col, value in enumerate(request):
|
||||
self.master_requests_table.setItem(row, col, QTableWidgetItem(str(value)))
|
||||
|
||||
def load_archive(self):
|
||||
cursor = self.db.conn.cursor()
|
||||
cursor.execute('''
|
||||
SELECT id, client_name, equipment_type, equipment_model, status, created_date, completed_date, assigned_master
|
||||
FROM service_requests
|
||||
WHERE status = 'Выполнена'
|
||||
ORDER BY completed_date DESC
|
||||
''')
|
||||
|
||||
requests = cursor.fetchall()
|
||||
|
||||
self.archive_table.setRowCount(len(requests))
|
||||
for row, request in enumerate(requests):
|
||||
for col, value in enumerate(request):
|
||||
self.archive_table.setItem(row, col, QTableWidgetItem(str(value) if value is not None else ''))
|
||||
|
||||
def load_users(self):
|
||||
cursor = self.db.conn.cursor()
|
||||
cursor.execute('SELECT id, username, full_name, role FROM users')
|
||||
|
||||
users = cursor.fetchall()
|
||||
|
||||
self.users_table.setRowCount(len(users))
|
||||
for row, user in enumerate(users):
|
||||
for col, value in enumerate(user):
|
||||
self.users_table.setItem(row, col, QTableWidgetItem(str(value)))
|
||||
|
||||
def show_request_details(self):
|
||||
current_row = self.client_requests_table.currentRow()
|
||||
if current_row >= 0:
|
||||
request_id = self.client_requests_table.item(current_row, 0).text()
|
||||
|
||||
cursor = self.db.conn.cursor()
|
||||
cursor.execute('SELECT * FROM service_requests WHERE id = ?', (request_id,))
|
||||
request = cursor.fetchone()
|
||||
|
||||
if request:
|
||||
details = f"""
|
||||
ID: {request[0]}
|
||||
Клиент: {request[1]}
|
||||
Телефон: {request[2]}
|
||||
Оборудование: {request[3]}
|
||||
Модель: {request[4]}
|
||||
Описание проблемы: {request[5]}
|
||||
Статус: {request[6]}
|
||||
Приоритет: {request[7]}
|
||||
Тип: {request[8]}
|
||||
Дата создания: {request[11]}
|
||||
"""
|
||||
|
||||
QMessageBox.information(self, 'Детали заявки', details)
|
||||
|
||||
def update_request_operator(self):
|
||||
current_row = self.operator_requests_table.currentRow()
|
||||
if current_row >= 0:
|
||||
request_id = self.operator_requests_table.item(current_row, 0).text()
|
||||
|
||||
cursor = self.db.conn.cursor()
|
||||
cursor.execute('''
|
||||
UPDATE service_requests
|
||||
SET status = ?, priority = ?, request_type = ?, observer_group = ?, assigned_operator = ?
|
||||
WHERE id = ?
|
||||
''', (
|
||||
self.status_combo.currentText(),
|
||||
self.priority_combo.currentText(),
|
||||
self.type_combo.currentText(),
|
||||
self.observer_group.text(),
|
||||
self.current_user['full_name'],
|
||||
request_id
|
||||
))
|
||||
|
||||
self.db.conn.commit()
|
||||
self.load_operator_requests()
|
||||
QMessageBox.information(self, 'Успех', 'Заявка обновлена!')
|
||||
|
||||
def update_request_master(self):
|
||||
current_row = self.master_requests_table.currentRow()
|
||||
if current_row >= 0:
|
||||
request_id = self.master_requests_table.item(current_row, 0).text()
|
||||
|
||||
cursor = self.db.conn.cursor()
|
||||
cursor.execute('''
|
||||
UPDATE service_requests
|
||||
SET status = ?, assigned_master = ?
|
||||
WHERE id = ?
|
||||
''', (
|
||||
self.master_status_combo.currentText(),
|
||||
self.current_user['full_name'],
|
||||
request_id
|
||||
))
|
||||
|
||||
self.db.conn.commit()
|
||||
self.load_master_requests()
|
||||
QMessageBox.information(self, 'Успех', 'Статус заявки обновлен!')
|
||||
|
||||
def order_parts(self):
|
||||
current_row = self.master_requests_table.currentRow()
|
||||
if current_row >= 0:
|
||||
request_id = self.master_requests_table.item(current_row, 0).text()
|
||||
|
||||
cursor = self.db.conn.cursor()
|
||||
cursor.execute('''
|
||||
INSERT INTO part_orders (request_id, part_name, quantity, ordered_by)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', (
|
||||
request_id,
|
||||
self.part_name.text(),
|
||||
int(self.part_quantity.text()),
|
||||
self.current_user['id']
|
||||
))
|
||||
|
||||
self.db.conn.commit()
|
||||
|
||||
# Обновляем статус заявки
|
||||
cursor.execute('''
|
||||
UPDATE service_requests
|
||||
SET status = 'Ожидает запчасти'
|
||||
WHERE id = ?
|
||||
''', (request_id,))
|
||||
|
||||
self.db.conn.commit()
|
||||
|
||||
self.part_name.clear()
|
||||
self.part_quantity.setText('1')
|
||||
self.load_master_requests()
|
||||
|
||||
QMessageBox.information(self, 'Успех', 'Запчасти заказаны!')
|
||||
|
||||
def attach_file(self):
|
||||
current_row = self.master_requests_table.currentRow()
|
||||
if current_row >= 0:
|
||||
request_id = self.master_requests_table.item(current_row, 0).text()
|
||||
|
||||
file_path, _ = QFileDialog.getOpenFileName(self, 'Выберите файл')
|
||||
if file_path:
|
||||
filename = os.path.basename(file_path)
|
||||
|
||||
cursor = self.db.conn.cursor()
|
||||
cursor.execute('''
|
||||
INSERT INTO attachments (request_id, filename, filepath, uploaded_by)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', (
|
||||
request_id,
|
||||
filename,
|
||||
file_path,
|
||||
self.current_user['id']
|
||||
))
|
||||
|
||||
self.db.conn.commit()
|
||||
QMessageBox.information(self, 'Успех', 'Файл прикреплен!')
|
||||
|
||||
def create_report(self):
|
||||
current_row = self.master_requests_table.currentRow()
|
||||
if current_row >= 0:
|
||||
request_id = self.master_requests_table.item(current_row, 0).text()
|
||||
|
||||
# Диалог для ввода отчета
|
||||
report_dialog = QDialog(self)
|
||||
report_dialog.setWindowTitle('Создание отчета')
|
||||
report_dialog.setModal(True)
|
||||
layout = QVBoxLayout(report_dialog)
|
||||
|
||||
form_layout = QFormLayout()
|
||||
work_description = QTextEdit()
|
||||
parts_used = QLineEdit()
|
||||
time_spent = QLineEdit()
|
||||
|
||||
form_layout.addRow('Описание работы:', work_description)
|
||||
form_layout.addRow('Использованные запчасти:', parts_used)
|
||||
form_layout.addRow('Затраченное время (часы):', time_spent)
|
||||
|
||||
layout.addLayout(form_layout)
|
||||
|
||||
buttons_layout = QHBoxLayout()
|
||||
save_btn = QPushButton('Сохранить отчет')
|
||||
cancel_btn = QPushButton('Отмена')
|
||||
|
||||
buttons_layout.addWidget(save_btn)
|
||||
buttons_layout.addWidget(cancel_btn)
|
||||
layout.addLayout(buttons_layout)
|
||||
|
||||
def save_report():
|
||||
cursor = self.db.conn.cursor()
|
||||
cursor.execute('''
|
||||
INSERT INTO reports (request_id, master_id, work_description, parts_used, time_spent)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', (
|
||||
request_id,
|
||||
self.current_user['id'],
|
||||
work_description.toPlainText(),
|
||||
parts_used.text(),
|
||||
float(time_spent.text())
|
||||
))
|
||||
|
||||
# Обновляем статус заявки на выполненную
|
||||
cursor.execute('''
|
||||
UPDATE service_requests
|
||||
SET status = 'Выполнена', completed_date = CURRENT_TIMESTAMP
|
||||
WHERE id = ?
|
||||
''', (request_id,))
|
||||
|
||||
self.db.conn.commit()
|
||||
report_dialog.accept()
|
||||
self.load_master_requests()
|
||||
QMessageBox.information(self, 'Успех', 'Отчет создан!')
|
||||
|
||||
save_btn.clicked.connect(save_report)
|
||||
cancel_btn.clicked.connect(report_dialog.reject)
|
||||
|
||||
report_dialog.exec()
|
||||
|
||||
def search_archive(self):
|
||||
search_text = self.archive_search.text()
|
||||
cursor = self.db.conn.cursor()
|
||||
|
||||
if search_text:
|
||||
cursor.execute('''
|
||||
SELECT id, client_name, equipment_type, equipment_model, status, created_date, completed_date, assigned_master
|
||||
FROM service_requests
|
||||
WHERE status = 'Выполнена' AND
|
||||
(client_name LIKE ? OR equipment_type LIKE ? OR equipment_model LIKE ?)
|
||||
ORDER BY completed_date DESC
|
||||
''', (f'%{search_text}%', f'%{search_text}%', f'%{search_text}%'))
|
||||
else:
|
||||
cursor.execute('''
|
||||
SELECT id, client_name, equipment_type, equipment_model, status, created_date, completed_date, assigned_master
|
||||
FROM service_requests
|
||||
WHERE status = 'Выполнена'
|
||||
ORDER BY completed_date DESC
|
||||
''')
|
||||
|
||||
requests = cursor.fetchall()
|
||||
|
||||
self.archive_table.setRowCount(len(requests))
|
||||
for row, request in enumerate(requests):
|
||||
for col, value in enumerate(request):
|
||||
self.archive_table.setItem(row, col, QTableWidgetItem(str(value) if value is not None else ''))
|
||||
|
||||
def show_add_user_dialog(self):
|
||||
dialog = QDialog(self)
|
||||
dialog.setWindowTitle('Добавить пользователя')
|
||||
dialog.setModal(True)
|
||||
layout = QVBoxLayout(dialog)
|
||||
|
||||
form_layout = QFormLayout()
|
||||
username = QLineEdit()
|
||||
password = QLineEdit()
|
||||
password.setEchoMode(QLineEdit.EchoMode.Password)
|
||||
full_name = QLineEdit()
|
||||
phone = QLineEdit()
|
||||
role = QComboBox()
|
||||
role.addItems(['client', 'operator', 'master', 'admin'])
|
||||
|
||||
form_layout.addRow('Логин:', username)
|
||||
form_layout.addRow('Пароль:', password)
|
||||
form_layout.addRow('ФИО:', full_name)
|
||||
form_layout.addRow('Телефон:', phone)
|
||||
form_layout.addRow('Роль:', role)
|
||||
|
||||
layout.addLayout(form_layout)
|
||||
|
||||
buttons_layout = QHBoxLayout()
|
||||
save_btn = QPushButton('Сохранить')
|
||||
cancel_btn = QPushButton('Отмена')
|
||||
|
||||
buttons_layout.addWidget(save_btn)
|
||||
buttons_layout.addWidget(cancel_btn)
|
||||
layout.addLayout(buttons_layout)
|
||||
|
||||
def save_user():
|
||||
cursor = self.db.conn.cursor()
|
||||
try:
|
||||
cursor.execute('''
|
||||
INSERT INTO users (username, password, role, full_name, phone)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', (
|
||||
username.text(),
|
||||
password.text(),
|
||||
role.currentText(),
|
||||
full_name.text(),
|
||||
phone.text()
|
||||
))
|
||||
|
||||
self.db.conn.commit()
|
||||
dialog.accept()
|
||||
self.load_users()
|
||||
QMessageBox.information(self, 'Успех', 'Пользователь добавлен!')
|
||||
except sqlite3.IntegrityError:
|
||||
QMessageBox.warning(self, 'Ошибка', 'Пользователь с таким логином уже существует!')
|
||||
|
||||
save_btn.clicked.connect(save_user)
|
||||
cancel_btn.clicked.connect(dialog.reject)
|
||||
|
||||
dialog.exec()
|
||||
|
||||
class Dialog(QDialog):
|
||||
pass # Вспомогательный класс для диалогов
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QApplication(sys.argv)
|
||||
window = ServiceRequestApp()
|
||||
window.show()
|
||||
sys.exit(app.exec())
|
||||
Loading…
Add table
Add a link
Reference in a new issue