After Graduate Update
This commit is contained in:
parent
b92a91ab37
commit
c6917dd85e
69 changed files with 7540 additions and 0 deletions
|
|
@ -0,0 +1,108 @@
|
|||
from PyQt6.QtWidgets import (
|
||||
QDialog,
|
||||
QVBoxLayout,
|
||||
QFormLayout,
|
||||
QLineEdit,
|
||||
QPushButton,
|
||||
QComboBox,
|
||||
QSpinBox,
|
||||
QMessageBox,
|
||||
)
|
||||
from PyQt6.QtCore import Qt
|
||||
from res.colors import ACCENT_COLOR
|
||||
from dto.partners_dto import PartnerUpdateDto, PartnersInfo
|
||||
|
||||
|
||||
class EditPartnerDialog(QDialog):
|
||||
def __init__(self, partner_data: PartnersInfo, parent=None):
|
||||
super().__init__(parent)
|
||||
self.partner_data = partner_data
|
||||
self.setup_ui()
|
||||
self.load_partner_types()
|
||||
self.fill_form()
|
||||
self.result = None
|
||||
|
||||
def setup_ui(self):
|
||||
self.setWindowTitle("Редактирование партнера")
|
||||
self.setFixedSize(500, 400)
|
||||
|
||||
layout = QVBoxLayout()
|
||||
form_layout = QFormLayout()
|
||||
|
||||
# Создаем поля формы
|
||||
self.partner_type = QComboBox()
|
||||
self.partner_name = QLineEdit()
|
||||
self.first_name = QLineEdit()
|
||||
self.last_name = QLineEdit()
|
||||
self.middle_name = QLineEdit()
|
||||
self.email = QLineEdit()
|
||||
self.phone = QLineEdit()
|
||||
self.address = QLineEdit()
|
||||
self.inn = QLineEdit()
|
||||
self.rating = QSpinBox()
|
||||
self.rating.setRange(0, 10)
|
||||
|
||||
# Добавляем поля в форму
|
||||
form_layout.addRow("Тип партнера:", self.partner_type)
|
||||
form_layout.addRow("Название:", self.partner_name)
|
||||
form_layout.addRow("Имя директора:", self.first_name)
|
||||
form_layout.addRow("Фамилия директора:", self.last_name)
|
||||
form_layout.addRow("Отчество директора:", self.middle_name)
|
||||
form_layout.addRow("Email:", self.email)
|
||||
form_layout.addRow("Телефон:", self.phone)
|
||||
form_layout.addRow("Адрес:", self.address)
|
||||
form_layout.addRow("ИНН:", self.inn)
|
||||
form_layout.addRow("Рейтинг:", self.rating)
|
||||
|
||||
# Кнопки
|
||||
self.save_button = QPushButton("Сохранить")
|
||||
self.cancel_button = QPushButton("Отмена")
|
||||
|
||||
self.save_button.clicked.connect(self.save_changes)
|
||||
self.cancel_button.clicked.connect(self.reject)
|
||||
|
||||
layout.addLayout(form_layout)
|
||||
layout.addWidget(self.save_button)
|
||||
layout.addWidget(self.cancel_button)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
# Стили
|
||||
self.setStyleSheet(
|
||||
f"""
|
||||
QPushButton {{
|
||||
background-color: {ACCENT_COLOR};
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
}}
|
||||
"""
|
||||
)
|
||||
|
||||
def load_partner_types(self):
|
||||
types = ['ООО', "ЗАО"]
|
||||
for i, val in enumerate(types):
|
||||
self.partner_type.addItem(val, i + 1)
|
||||
|
||||
def fill_form(self):
|
||||
pass
|
||||
def save_changes(self):
|
||||
try:
|
||||
partner_data = PartnerUpdateDto(
|
||||
id=self.partner_data.id,
|
||||
partner_type_id=self.partner_type.currentData(),
|
||||
partner_name=self.partner_name.text(),
|
||||
first_name=self.first_name.text(),
|
||||
last_name=self.last_name.text(),
|
||||
middle_name=self.middle_name.text(),
|
||||
email=self.email.text(),
|
||||
phone=self.phone.text(),
|
||||
address=self.address.text(),
|
||||
inn=self.inn.text(),
|
||||
rating=self.rating.value(),
|
||||
)
|
||||
db.update_partner(partner_data)
|
||||
self.accept()
|
||||
except Exception as e:
|
||||
QMessageBox.critical(
|
||||
self, "Ошибка", f"Не удалось сохранить изменения: {str(e)}"
|
||||
)
|
||||
94
robbery/master_pol-module_1_2/app/components/partner_card.py
Normal file
94
robbery/master_pol-module_1_2/app/components/partner_card.py
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
from dataclasses import dataclass
|
||||
from PyQt6.QtWidgets import QWidget, QLabel, QVBoxLayout, QHBoxLayout, QFrame
|
||||
from PyQt6.QtCore import Qt, pyqtSignal
|
||||
from res.colors import ACCENT_COLOR, SECONDARY_COLOR
|
||||
from res.fonts import MAIN_FONT
|
||||
from dto.partners_dto import PartnersInfo
|
||||
|
||||
|
||||
|
||||
|
||||
class PartnerCard(QFrame):
|
||||
doubleClicked = pyqtSignal(PartnersInfo)
|
||||
|
||||
def __init__(self, info: PartnersInfo):
|
||||
super().__init__()
|
||||
self.info = info
|
||||
|
||||
self.init_ui()
|
||||
self.set_styles()
|
||||
|
||||
def mouseDoubleClickEvent(self, a0):
|
||||
self.doubleClicked.emit(self.info)
|
||||
return super().mouseDoubleClickEvent(a0)
|
||||
|
||||
def init_ui(self):
|
||||
main_layout = QVBoxLayout()
|
||||
self.setLayout(main_layout)
|
||||
|
||||
# Верхняя строка: Тип | Наименование и скидка
|
||||
header_layout = QHBoxLayout()
|
||||
header_text = QLabel(f"{self.info.type_name} | {self.info.partner_name}")
|
||||
header_text.setObjectName("partnerHeader")
|
||||
discount_text = QLabel(f"{self.info.discount}%")
|
||||
discount_text.setObjectName("partnerDiscount")
|
||||
|
||||
header_layout.addWidget(header_text)
|
||||
header_layout.addWidget(discount_text, alignment=Qt.AlignmentFlag.AlignRight)
|
||||
|
||||
# Информация о директоре
|
||||
director_text = QLabel(f"Директор")
|
||||
director_text.setObjectName("fieldLabel")
|
||||
director_name = QLabel(
|
||||
f"{self.info.last_name_director} {self.info.first_name_director} {self.info.middle_name_director}"
|
||||
)
|
||||
|
||||
# Контактная информация
|
||||
phone_text = QLabel(f"+{self.info.phone_partner}")
|
||||
|
||||
# Рейтинг
|
||||
rating_layout = QHBoxLayout()
|
||||
rating_label = QLabel("Рейтинг:")
|
||||
rating_label.setObjectName("fieldLabel")
|
||||
rating_value = QLabel(str(self.info.rating))
|
||||
rating_layout.addWidget(rating_label)
|
||||
rating_layout.addWidget(rating_value)
|
||||
rating_layout.addStretch()
|
||||
|
||||
# Добавляем все элементы в главный layout
|
||||
main_layout.addLayout(header_layout)
|
||||
main_layout.addWidget(director_text)
|
||||
main_layout.addWidget(director_name)
|
||||
main_layout.addWidget(phone_text)
|
||||
main_layout.addLayout(rating_layout)
|
||||
|
||||
def set_styles(self):
|
||||
self.setStyleSheet(
|
||||
"""
|
||||
PartnerCard {
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
padding: 10px;
|
||||
margin: 5px;
|
||||
background-color: white;
|
||||
}
|
||||
QLabel {
|
||||
font-family: %s;
|
||||
}
|
||||
#partnerHeader {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: %s;
|
||||
}
|
||||
#partnerDiscount {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: %s;
|
||||
}
|
||||
#fieldLabel {
|
||||
color: gray;
|
||||
font-size: 14px;
|
||||
}
|
||||
"""
|
||||
% (MAIN_FONT, ACCENT_COLOR, SECONDARY_COLOR)
|
||||
)
|
||||
84
robbery/master_pol-module_1_2/app/database/db.py
Normal file
84
robbery/master_pol-module_1_2/app/database/db.py
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import pymysql as psql
|
||||
from dto.partners_dto import PartnerUpdateDto
|
||||
|
||||
|
||||
class Database:
|
||||
def __init__(self, host, user, password, db):
|
||||
self.connection = psql.connect(
|
||||
host=host,
|
||||
user=user,
|
||||
password=password,
|
||||
database=db,
|
||||
cursorclass=psql.cursors.DictCursor,
|
||||
)
|
||||
|
||||
def authorize_user(self, username, password):
|
||||
query = "SELECT * FROM users WHERE username=%s AND password=%s"
|
||||
with self.connection.cursor() as cur:
|
||||
cur.execute(query, (username, password))
|
||||
result = cur.fetchone()
|
||||
return result is not None
|
||||
|
||||
def execute_select(self, query, params=None):
|
||||
"""Выполняет SELECT запрос и возвращает результаты"""
|
||||
with self.connection.cursor() as cur:
|
||||
if params:
|
||||
cur.execute(query, params)
|
||||
else:
|
||||
cur.execute(query)
|
||||
return cur.fetchall()
|
||||
|
||||
def get_partner_types(self):
|
||||
"""Получает все типы партнеров из таблицы partner_types"""
|
||||
query = "SELECT * FROM partners_type"
|
||||
with self.connection.cursor() as cur:
|
||||
cur.execute(query)
|
||||
return cur.fetchall()
|
||||
|
||||
def update_partner(self, partners_info: PartnerUpdateDto):
|
||||
with self.connection.cursor() as cur:
|
||||
cur.callproc(
|
||||
"upd_partner",
|
||||
(
|
||||
partners_info.partner_type_id,
|
||||
partners_info.id,
|
||||
partners_info.partner_name,
|
||||
partners_info.first_name,
|
||||
partners_info.last_name,
|
||||
partners_info.middle_name,
|
||||
partners_info.email,
|
||||
partners_info.phone,
|
||||
partners_info.address,
|
||||
partners_info.inn,
|
||||
partners_info.rating,
|
||||
),
|
||||
)
|
||||
self.connection.commit()
|
||||
|
||||
def get_disc(self, partner_name):
|
||||
"""
|
||||
Получает скидку для партнера, вызывая функцию get_disc из БД
|
||||
"""
|
||||
# Сначала получим ID партнера по его имени
|
||||
query = "SELECT id FROM partners WHERE partner_name = %s"
|
||||
with self.connection.cursor() as cur:
|
||||
cur.execute(query, (partner_name,))
|
||||
result = cur.fetchone()
|
||||
|
||||
if not result:
|
||||
return 0
|
||||
|
||||
# Вызываем функцию get_disc из БД
|
||||
query = "SELECT get_disc(%s) as discount"
|
||||
cur.execute(query, (result["id"],))
|
||||
discount_result = cur.fetchone()
|
||||
|
||||
return discount_result["discount"] if discount_result else 0
|
||||
|
||||
|
||||
db = None
|
||||
try:
|
||||
db = Database(host="localhost", user="root", password="", db="master_pol")
|
||||
print("Database connection established.")
|
||||
except psql.MySQLError as e:
|
||||
print(f"Error connecting to database: {e}")
|
||||
460
robbery/master_pol-module_1_2/app/database/script.sql
Normal file
460
robbery/master_pol-module_1_2/app/database/script.sql
Normal file
|
|
@ -0,0 +1,460 @@
|
|||
CREATE DATABASE master_pol;
|
||||
use master_pol;
|
||||
|
||||
CREATE TABLE `partners` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`partner_type_id` INTEGER NOT NULL,
|
||||
`partner_name` VARCHAR(255) NOT NULL,
|
||||
`first_name_director` VARCHAR(50) NOT NULL,
|
||||
`last_name_director` VARCHAR(50) NOT NULL,
|
||||
`middle_name_director` VARCHAR(255),
|
||||
`email_partner` VARCHAR(100) NOT NULL,
|
||||
`phone_partner` VARCHAR(15) NOT NULL,
|
||||
`address` VARCHAR(255) NOT NULL,
|
||||
`INN` VARCHAR(10) NOT NULL,
|
||||
`rating` INTEGER NOT NULL,
|
||||
`logo` LONGBLOB,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `partners_type` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`name` VARCHAR(255),
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `products` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`article` VARCHAR(10) NOT NULL,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`product_type_id` INTEGER NOT NULL,
|
||||
`description` VARCHAR(255),
|
||||
`picture` LONGBLOB,
|
||||
`min_price_partners` DECIMAL(10,2) NOT NULL,
|
||||
`cert_quality` LONGBLOB,
|
||||
`standard_number` VARCHAR(255),
|
||||
`selfcost` DECIMAL(10,2),
|
||||
`length` DECIMAL(10,2),
|
||||
`width` DECIMAL(10,2),
|
||||
`height` DECIMAL(10,2),
|
||||
`weight_no_package` DECIMAL(10,2),
|
||||
`weight_with_package` DECIMAL(10,2),
|
||||
`time_to_create_min` INTEGER,
|
||||
`workshop_number` INTEGER,
|
||||
`people_count_production` INTEGER,
|
||||
`product_current_stock` INTEGER NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `products_types` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`name` VARCHAR(70) NOT NULL,
|
||||
`coefficent` DECIMAL(3,2) NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `product_partners` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`product_id` INTEGER NOT NULL,
|
||||
`partner_id` INTEGER NOT NULL,
|
||||
`amount` INTEGER NOT NULL,
|
||||
`sale_date` DATE NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `employees` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`employee_type_id` INTEGER NOT NULL,
|
||||
`first_name` VARCHAR(50) NOT NULL,
|
||||
`last_name` VARCHAR(50) NOT NULL,
|
||||
`middle_name` VARCHAR(60) NULL,
|
||||
`birth_date` DATE NOT NULL,
|
||||
`passport_data` VARCHAR(11) NOT NULL,
|
||||
`bank_details` VARCHAR(100) NOT NULL,
|
||||
`has_family` BOOLEAN,
|
||||
`health_status` VARCHAR(25),
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `employees_types` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`name` VARCHAR(50) NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `users` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`username` VARCHAR(30) NOT NULL,
|
||||
`password` VARCHAR(80) NOT NULL,
|
||||
`employee_id` INTEGER NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `materials` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`material_type_id` INTEGER NOT NULL,
|
||||
`supplier_id` INTEGER NOT NULL,
|
||||
`name` VARCHAR(60) NOT NULL,
|
||||
`package_quantity` INTEGER NOT NULL,
|
||||
`unit` VARCHAR(20) NOT NULL,
|
||||
`cost` DECIMAL(8,2) NOT NULL,
|
||||
`image` LONGBLOB,
|
||||
`min_stock` INTEGER,
|
||||
`material_current_stock` INTEGER NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `materials_type` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`name` VARCHAR(50) NOT NULL,
|
||||
`defect_percent` DECIMAL(10,2) NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `products_recipes` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`product_id` INTEGER NOT NULL,
|
||||
`material_id` INTEGER NOT NULL,
|
||||
`material_count` INTEGER NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `partners_rating_history` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`partner_id` INTEGER NOT NULL,
|
||||
`new_rating` INTEGER NOT NULL,
|
||||
`changed` DATETIME NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `orders` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`partner_id` INTEGER NOT NULL,
|
||||
`manager_id` INTEGER NOT NULL,
|
||||
`total_price` DECIMAL(10,2) NOT NULL,
|
||||
`order_payment` DECIMAL(10,2) NOT NULL DEFAULT 0,
|
||||
`created` DATETIME NOT NULL,
|
||||
`status` ENUM('created', 'waiting prepayment', 'prepayment received', 'completed', 'canceled', 'ready for shipment', 'pending', 'in production') NOT NULL,
|
||||
`prepayment_date` DATETIME,
|
||||
`payment_date` DATETIME,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `products_orders` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`order_id` INTEGER NOT NULL,
|
||||
`product_id` INTEGER NOT NULL,
|
||||
`quantity` INTEGER NOT NULL,
|
||||
`agreed_price_per` DECIMAL(8,2),
|
||||
`production_date` DATE,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `suppliers` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`name` VARCHAR(50) NOT NULL,
|
||||
`INN` VARCHAR(10) NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `materials_supply_history` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`material_id` INTEGER NOT NULL,
|
||||
`supplier_id` INTEGER NOT NULL,
|
||||
`quantity` INTEGER NOT NULL,
|
||||
`delivery_date` DATE NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `materials_movement` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`material_id` INTEGER NOT NULL,
|
||||
`amount` INTEGER NOT NULL,
|
||||
`movement_type` ENUM('incoming', 'reserve', 'write off') NOT NULL DEFAULT 'incoming',
|
||||
`movement_date` DATETIME NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `employees_access` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
`employee_id` INTEGER NOT NULL,
|
||||
`door_id` INTEGER NOT NULL,
|
||||
`access_date` DATETIME NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
|
||||
ALTER TABLE `partners`
|
||||
ADD FOREIGN KEY(`partner_type_id`) REFERENCES `partners_type`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `products`
|
||||
ADD FOREIGN KEY(`product_type_id`) REFERENCES `products_types`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `product_partners`
|
||||
ADD FOREIGN KEY(`product_id`) REFERENCES `products`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `product_partners`
|
||||
ADD FOREIGN KEY(`partner_id`) REFERENCES `partners`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `employees`
|
||||
ADD FOREIGN KEY(`employee_type_id`) REFERENCES `employees_types`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `users`
|
||||
ADD FOREIGN KEY(`employee_id`) REFERENCES `employees`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `materials`
|
||||
ADD FOREIGN KEY(`material_type_id`) REFERENCES `materials_type`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `products_recipes`
|
||||
ADD FOREIGN KEY(`product_id`) REFERENCES `products`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `products_recipes`
|
||||
ADD FOREIGN KEY(`material_id`) REFERENCES `materials`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `partners_rating_history`
|
||||
ADD FOREIGN KEY(`partner_id`) REFERENCES `partners`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `orders`
|
||||
ADD FOREIGN KEY(`partner_id`) REFERENCES `partners`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `orders`
|
||||
ADD FOREIGN KEY(`manager_id`) REFERENCES `employees`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `products_orders`
|
||||
ADD FOREIGN KEY(`order_id`) REFERENCES `orders`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `products_orders`
|
||||
ADD FOREIGN KEY(`product_id`) REFERENCES `products`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `materials`
|
||||
ADD FOREIGN KEY(`supplier_id`) REFERENCES `suppliers`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `materials_supply_history`
|
||||
ADD FOREIGN KEY(`material_id`) REFERENCES `materials`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `materials_supply_history`
|
||||
ADD FOREIGN KEY(`supplier_id`) REFERENCES `suppliers`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `materials_movement`
|
||||
ADD FOREIGN KEY(`material_id`) REFERENCES `materials`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
ALTER TABLE `employees_access`
|
||||
ADD FOREIGN KEY(`employee_id`) REFERENCES `employees`(`id`)
|
||||
ON UPDATE NO ACTION ON DELETE NO ACTION;
|
||||
|
||||
INSERT INTO materials_type (name, defect_percent) VALUES
|
||||
('Тип материала 1', 0.001),
|
||||
('Тип материала 2', 0.0095),
|
||||
('Тип материала 3', 0.0028),
|
||||
('Тип материала 4', 0.0055),
|
||||
('Тип материала 5', 0.0034);
|
||||
|
||||
INSERT INTO products_types (name, coefficent) VALUES
|
||||
('Ламинат', 2.35),
|
||||
('Массивная доска', 5.15),
|
||||
('Паркетная доска', 4.34),
|
||||
('Пробковое покрытие', 1.5);
|
||||
|
||||
INSERT INTO partners_type (name) VALUES
|
||||
('ЗАО'),
|
||||
('ООО'),
|
||||
('ПАО'),
|
||||
('ОАО');
|
||||
|
||||
|
||||
INSERT INTO partners (partner_type_id, partner_name, first_name_director, last_name_director, middle_name_director, email_partner, phone_partner, address, INN, rating) VALUES
|
||||
(1, 'База Строитель', 'Александра', 'Иванова', 'Ивановна', 'aleksandraivanova@ml.ru', '4931234567', '652050, Кемеровская область, город Юрга, ул. Лесная, 15', '2222455179', 7),
|
||||
(2, 'Паркет 29', 'Василий', 'Петров', 'Петрович', 'vppetrov@vl.ru', '9871235678', '164500, Архангельская область, город Северодвинск, ул. Строителей, 18', '3333888520', 7),
|
||||
(3, 'Стройсервис', 'Андрей', 'Соловьев', 'Николаевич', 'ansolovev@st.ru', '8122233200', '188910, Ленинградская область, город Приморск, ул. Парковая, 21', '4440391035', 7),
|
||||
(4, 'Ремонт и отделка', 'Екатерина', 'Воробьева', 'Валерьевна', 'ekaterina.vorobeva@ml.ru', '4442223311', '143960, Московская область, город Реутов, ул. Свободы, 51', '1111520857', 5),
|
||||
(1, 'МонтажПро', 'Степан', 'Степанов', 'Сергеевич', 'stepanov@stepan.ru', '9128883333', '309500, Белгородская область, город Старый Оскол, ул. Рабочая, 122', '5552431140', 10);
|
||||
|
||||
INSERT INTO products (article, name, product_type_id, min_price_partners) VALUES
|
||||
('8758385', 'Паркетная доска Ясень темный однополосная 14 мм', 3, 4456.90),
|
||||
('8858958', 'Инженерная доска Дуб Французская елка однополосная 12 мм', 3, 7330.99),
|
||||
('7750282', 'Ламинат Дуб дымчато-белый 33 класс 12 мм', 1, 1799.33),
|
||||
('7028748', 'Ламинат Дуб серый 32 класс 8 мм с фаской', 1, 3890.41),
|
||||
('5012543', 'Пробковое напольное клеевое покрытие 32 класс 4 мм', 4, 5450.59);
|
||||
|
||||
INSERT INTO product_partners (product_id, partner_id, amount, sale_date) VALUES
|
||||
(1, 1, 15500, '2023-03-23'),
|
||||
(3, 1, 12350, '2023-12-18'),
|
||||
(4, 1, 37400, '2024-06-07'),
|
||||
(2, 2, 35000, '2022-12-02'),
|
||||
(5, 2, 1250, '2023-05-17'),
|
||||
(3, 2, 1000, '2024-06-07'),
|
||||
(1, 2, 7550, '2024-07-01'),
|
||||
(1, 3, 7250, '2023-01-22'),
|
||||
(2, 3, 2500, '2024-07-05'),
|
||||
(4, 4, 59050, '2023-03-20'),
|
||||
(3, 4, 37200, '2024-03-12'),
|
||||
(5, 4, 4500, '2024-05-14'),
|
||||
(3, 5, 50000, '2023-09-19'),
|
||||
(4, 5, 670000, '2023-11-10'),
|
||||
(1, 5, 35000, '2024-04-15'),
|
||||
(2, 5, 25000, '2024-06-12');
|
||||
|
||||
-- === 1. Типы сотрудников ===
|
||||
INSERT INTO employees_types (name)
|
||||
VALUES
|
||||
('Менеджер'),
|
||||
('Бухгалтер'),
|
||||
('Программист'),
|
||||
('Охранник'),
|
||||
('Уборщик');
|
||||
|
||||
-- === 2. Сотрудники ===
|
||||
INSERT INTO employees (
|
||||
employee_type_id, first_name, last_name, middle_name, birth_date,
|
||||
passport_data, bank_details, has_family, health_status
|
||||
)
|
||||
VALUES
|
||||
-- Менеджеры
|
||||
(1, 'Иван', 'Петров', 'Сергеевич', '1988-03-15', '40051234567', '123456789', TRUE, 'Хорошее'),
|
||||
(1, 'Мария', 'Сидорова', 'Игоревна', '1990-11-02', '40057891234', '987654321', FALSE, 'Отличное'),
|
||||
|
||||
-- Программист
|
||||
(3, 'Андрей', 'Кузнецов', 'Алексеевич', '1995-07-21', '40101234567', '111122223333', TRUE, 'Хорошее'),
|
||||
|
||||
-- Бухгалтер
|
||||
(2, 'Елена', 'Морозова', 'Павловна', '1982-05-08', '40104561234', '444455556666', TRUE, 'Удовлетворительное'),
|
||||
|
||||
-- Охранник
|
||||
(4, 'Сергей', 'Волков', 'Владимирович', '1979-09-10', '40205678901', '555566667777', FALSE, 'Хорошее'),
|
||||
|
||||
-- Уборщик
|
||||
(5, 'Наталья', 'Орлова', 'Геннадьевна', '1975-12-25', '40307891234', '888899990000', TRUE, 'Хорошее');
|
||||
|
||||
-- === 3. Пользователи ===
|
||||
-- Пользователи, связанные с менеджерами
|
||||
INSERT INTO users (username, password, employee_id)
|
||||
VALUES
|
||||
('ivan', 'test', 1),
|
||||
('manager_maria', 'hashed_password_456', 2);
|
||||
|
||||
|
||||
CREATE VIEW show_partners
|
||||
AS
|
||||
SELECT p.id, pt.name AS type_name, p.partner_name, p.first_name_director, p.last_name_director, p.middle_name_director, p.phone_partner, p.rating
|
||||
FROM partners p JOIN partners_type pt
|
||||
ON
|
||||
p.partner_type_id = pt.id;
|
||||
|
||||
|
||||
DELIMITER //
|
||||
CREATE PROCEDURE add_parther (IN p_partner_type_id INT, IN p_partner_name VARCHAR(255),
|
||||
IN p_first_name_director VARCHAR(50), IN p_last_name_director VARCHAR(50), IN p_middle_name_director VARCHAR(255),
|
||||
IN p_email_partner VARCHAR(100), IN p_phone_partner VARCHAR(15), IN p_address VARCHAR(255), IN p_INN VARCHAR(10), IN p_rating INT)
|
||||
|
||||
BEGIN
|
||||
INSERT INTO partners (
|
||||
partner_type_id,
|
||||
partner_name,
|
||||
first_name_director,
|
||||
last_name_director,
|
||||
middle_name_director,
|
||||
email_partner,
|
||||
phone_partner,
|
||||
address,
|
||||
INN,
|
||||
rating
|
||||
) VALUES (
|
||||
p_partner_type_id,
|
||||
p_partner_name,
|
||||
p_first_name_director,
|
||||
p_last_name_director,
|
||||
p_middle_name_director,
|
||||
p_email_partner,
|
||||
p_phone_partner,
|
||||
p_address,
|
||||
p_INN,
|
||||
p_rating
|
||||
);
|
||||
END //
|
||||
|
||||
DELIMITER ;
|
||||
|
||||
|
||||
DELIMITER //
|
||||
|
||||
CREATE PROCEDURE upd_partner (IN p_partner_type_id INT, IN p_id INT, IN p_partner_name VARCHAR(255),
|
||||
IN p_first_name_director VARCHAR(50), IN p_last_name_director VARCHAR(50), IN p_middle_name_director VARCHAR(255),
|
||||
IN p_email_partner VARCHAR(100), IN p_phone_partner VARCHAR(15), IN p_address VARCHAR(255), IN p_INN VARCHAR(10), IN p_rating INT)
|
||||
|
||||
BEGIN
|
||||
UPDATE partners
|
||||
SET
|
||||
partner_type_id = p_partner_type_id,
|
||||
partner_name = p_partner_name,
|
||||
first_name_director = p_first_name_director,
|
||||
last_name_director = p_last_name_director,
|
||||
middle_name_director = p_middle_name_director,
|
||||
email_partner = p_email_partner,
|
||||
phone_partner = p_phone_partner,
|
||||
address = p_address,
|
||||
INN = p_INN,
|
||||
rating = p_rating
|
||||
WHERE id = p_id;
|
||||
|
||||
END //
|
||||
|
||||
DELIMITER ;
|
||||
|
||||
|
||||
DELIMITER //
|
||||
|
||||
CREATE FUNCTION get_disc(partner_id INT)
|
||||
RETURNS INT
|
||||
BEGIN
|
||||
|
||||
DECLARE total_amount INT;
|
||||
|
||||
SELECT SUM(amount) INTO total_amount
|
||||
FROM product_partners
|
||||
WHERE partner_id = partner_id;
|
||||
|
||||
IF total_amount >= 300000 THEN RETURN 15;
|
||||
ELSEIF total_amount >= 50000 THEN RETURN 10;
|
||||
ELSEIF total_amount >= 10000 THEN RETURN 5;
|
||||
ELSE RETURN 0;
|
||||
END IF;
|
||||
|
||||
END //
|
||||
|
||||
DELIMITER ;
|
||||
|
||||
|
||||
|
||||
DELIMITER //
|
||||
|
||||
CREATE PROCEDURE partner_history(IN p_partner_id INT)
|
||||
BEGIN
|
||||
SELECT
|
||||
pr.name AS product_name,
|
||||
pp.amount AS quantity,
|
||||
pp.sale_date AS sale_date
|
||||
FROM product_partners pp JOIN products pr
|
||||
ON
|
||||
pp.product_id = pr.id
|
||||
WHERE pp.partner_id = p_partner_id
|
||||
ORDER BY pp.sale_date DESC;
|
||||
END//
|
||||
|
||||
DELIMITER ;
|
||||
29
robbery/master_pol-module_1_2/app/dto/partners_dto.py
Normal file
29
robbery/master_pol-module_1_2/app/dto/partners_dto.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class PartnersInfo:
|
||||
id: int
|
||||
type_name: str
|
||||
partner_name: str
|
||||
first_name_director: str
|
||||
last_name_director: str
|
||||
middle_name_director: str
|
||||
phone_partner: str
|
||||
rating: int
|
||||
discount: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class PartnerUpdateDto:
|
||||
id: int
|
||||
partner_type_id: int
|
||||
partner_name: str
|
||||
first_name: str
|
||||
last_name: str
|
||||
middle_name: str
|
||||
email: str
|
||||
phone: str
|
||||
address: str
|
||||
inn: str
|
||||
rating: int
|
||||
11
robbery/master_pol-module_1_2/app/main.py
Normal file
11
robbery/master_pol-module_1_2/app/main.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
from PyQt6.QtWidgets import QApplication
|
||||
from PyQt6.QtGui import QIcon
|
||||
from pages.auth_page import AuthPage
|
||||
|
||||
app = QApplication([])
|
||||
|
||||
app.setWindowIcon(QIcon("app/res/imgs/master_pol.ico"))
|
||||
start_page = AuthPage()
|
||||
start_page.show()
|
||||
|
||||
app.exec()
|
||||
94
robbery/master_pol-module_1_2/app/pages/auth_page.py
Normal file
94
robbery/master_pol-module_1_2/app/pages/auth_page.py
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
from PyQt6.QtWidgets import (
|
||||
QWidget,
|
||||
QLabel,
|
||||
QFormLayout,
|
||||
QPushButton,
|
||||
QMessageBox,
|
||||
QLineEdit,
|
||||
QVBoxLayout,
|
||||
)
|
||||
from PyQt6.QtCore import Qt
|
||||
from res.colors import ACCENT_COLOR, SECONDARY_COLOR, ACCENT_COLOR_HOVER
|
||||
from res.fonts import MAIN_FONT
|
||||
|
||||
|
||||
class AuthPage(QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setup_window()
|
||||
self.init_ui()
|
||||
self.set_styles()
|
||||
|
||||
def setup_window(self):
|
||||
self.setWindowTitle("Авторизация")
|
||||
self.setFixedSize(400, 250)
|
||||
|
||||
def init_ui(self):
|
||||
self.main_layout = QVBoxLayout()
|
||||
self.form_layout: QFormLayout = QFormLayout()
|
||||
|
||||
self.title = QLabel("Авторизация")
|
||||
self.title.setObjectName("title")
|
||||
|
||||
self.username_label = QLabel("Логин:")
|
||||
self.password_label = QLabel("Пароль:")
|
||||
|
||||
self.username_input = QLineEdit()
|
||||
self.password_input = QLineEdit()
|
||||
self.password_input.setEchoMode(QLineEdit.EchoMode.Password)
|
||||
|
||||
self.login_button = QPushButton("Войти")
|
||||
|
||||
self.form_layout.addRow(self.username_label, self.username_input)
|
||||
self.form_layout.addRow(self.password_label, self.password_input)
|
||||
self.form_layout.addRow(self.login_button)
|
||||
|
||||
self.setLayout(self.main_layout)
|
||||
self.main_layout.addWidget(self.title, alignment=Qt.AlignmentFlag.AlignHCenter)
|
||||
|
||||
self.main_layout.addStretch()
|
||||
self.main_layout.addLayout(self.form_layout)
|
||||
self.main_layout.addStretch()
|
||||
|
||||
self.login_button.clicked.connect(self.handle_login)
|
||||
|
||||
def handle_login(self):
|
||||
username = self.username_input.text()
|
||||
password = self.password_input.text()
|
||||
|
||||
if not username or not password:
|
||||
QMessageBox.warning(self, "Ошибка", "Пожалуйста, заполните все поля.")
|
||||
return
|
||||
|
||||
from pages.partners_page import PartnersPage
|
||||
|
||||
self.partners_page = PartnersPage()
|
||||
self.partners_page.show()
|
||||
self.close()
|
||||
|
||||
def set_styles(self):
|
||||
self.setStyleSheet(
|
||||
"""QLabel { font-size: 16px; font-family: %(MAIN_FONT)s}
|
||||
#title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: %(ACCENT_COLOR)s;
|
||||
}
|
||||
QPushButton {
|
||||
background-color: %(ACCENT_COLOR)s;
|
||||
border: 1px solid black;
|
||||
color: %(SECONDARY_COLOR)s;
|
||||
font-weight: bold;
|
||||
padding: 5px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: %(ACCENT_COLOR_HOVER)s;
|
||||
}
|
||||
"""
|
||||
% {
|
||||
"ACCENT_COLOR": ACCENT_COLOR,
|
||||
"SECONDARY_COLOR": SECONDARY_COLOR,
|
||||
"MAIN_FONT": MAIN_FONT,
|
||||
"ACCENT_COLOR_HOVER": ACCENT_COLOR_HOVER,
|
||||
}
|
||||
)
|
||||
130
robbery/master_pol-module_1_2/app/pages/partners_page.py
Normal file
130
robbery/master_pol-module_1_2/app/pages/partners_page.py
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
from PyQt6.QtWidgets import QWidget, QLabel, QVBoxLayout, QScrollArea, QVBoxLayout
|
||||
from PyQt6.QtCore import Qt
|
||||
from components.partner_card import PartnerCard, PartnersInfo
|
||||
from res.colors import ACCENT_COLOR
|
||||
|
||||
|
||||
class PartnersPage(QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setup_window()
|
||||
self.init_ui()
|
||||
self.load_partners()
|
||||
|
||||
def setup_window(self):
|
||||
self.setWindowTitle("Партнеры")
|
||||
self.resize(800, 600)
|
||||
|
||||
def init_ui(self):
|
||||
main_layout = QVBoxLayout()
|
||||
self.setLayout(main_layout)
|
||||
|
||||
# Заголовок
|
||||
title = QLabel("Партнеры")
|
||||
title.setObjectName("title")
|
||||
title.setStyleSheet(
|
||||
f"""
|
||||
#title {{
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: {ACCENT_COLOR};
|
||||
margin-bottom: 20px;
|
||||
}}
|
||||
"""
|
||||
)
|
||||
main_layout.addWidget(title, alignment=Qt.AlignmentFlag.AlignHCenter)
|
||||
|
||||
# Создаем область прокрутки
|
||||
scroll_area = QScrollArea()
|
||||
scroll_area.setWidgetResizable(True)
|
||||
scroll_content = QWidget()
|
||||
self.partners_layout = QVBoxLayout(scroll_content)
|
||||
scroll_area.setWidget(scroll_content)
|
||||
main_layout.addWidget(scroll_area)
|
||||
|
||||
def handle_partner_double_click(self, partner_info: PartnersInfo):
|
||||
from components.edit_partner_dialog import EditPartnerDialog
|
||||
|
||||
dialog = EditPartnerDialog(partner_info, self)
|
||||
dialog.exec()
|
||||
|
||||
def load_partners(self):
|
||||
# Тестовые данные партнеров
|
||||
test_partners = [
|
||||
{
|
||||
"id": 1,
|
||||
"type_name": "Золотой партнер",
|
||||
"partner_name": "ООО 'ТехноПрофи'",
|
||||
"first_name_director": "Иван",
|
||||
"last_name_director": "Петров",
|
||||
"middle_name_director": "Сергеевич",
|
||||
"phone_partner": "+7 (495) 123-45-67",
|
||||
"rating": 4.8,
|
||||
"discount": 15.0
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"type_name": "Серебряный партнер",
|
||||
"partner_name": "ИП Сидоров А.В.",
|
||||
"first_name_director": "Алексей",
|
||||
"last_name_director": "Сидоров",
|
||||
"middle_name_director": "Викторович",
|
||||
"phone_partner": "+7 (495) 234-56-78",
|
||||
"rating": 4.2,
|
||||
"discount": 10.0
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"type_name": "Бронзовый партнер",
|
||||
"partner_name": "ООО 'СтройМастер'",
|
||||
"first_name_director": "Мария",
|
||||
"last_name_director": "Иванова",
|
||||
"middle_name_director": "Олеговна",
|
||||
"phone_partner": "+7 (495) 345-67-89",
|
||||
"rating": 3.9,
|
||||
"discount": 7.5
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"type_name": "Золотой партнер",
|
||||
"partner_name": "АО 'ПромИнвест'",
|
||||
"first_name_director": "Сергей",
|
||||
"last_name_director": "Козлов",
|
||||
"middle_name_director": "Анатольевич",
|
||||
"phone_partner": "+7 (495) 456-78-90",
|
||||
"rating": 4.9,
|
||||
"discount": 18.0
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"type_name": "Стандартный партнер",
|
||||
"partner_name": "ООО 'ТоргСервис'",
|
||||
"first_name_director": "Ольга",
|
||||
"last_name_director": "Смирнова",
|
||||
"middle_name_director": "Дмитриевна",
|
||||
"phone_partner": "+7 (495) 567-89-01",
|
||||
"rating": 3.5,
|
||||
"discount": 5.0
|
||||
}
|
||||
]
|
||||
|
||||
# Создаем карточки партнеров на основе тестовых данных
|
||||
for partner in test_partners:
|
||||
partner_info = PartnersInfo(
|
||||
id=partner["id"],
|
||||
type_name=partner["type_name"],
|
||||
partner_name=partner["partner_name"],
|
||||
first_name_director=partner["first_name_director"],
|
||||
last_name_director=partner["last_name_director"],
|
||||
middle_name_director=partner["middle_name_director"],
|
||||
phone_partner=partner["phone_partner"],
|
||||
rating=partner["rating"],
|
||||
discount=partner["discount"],
|
||||
)
|
||||
|
||||
# Создаем и добавляем карточку партнера
|
||||
partner_card = PartnerCard(partner_info)
|
||||
partner_card.doubleClicked.connect(self.handle_partner_double_click)
|
||||
self.partners_layout.addWidget(partner_card)
|
||||
|
||||
self.partners_layout.addStretch()
|
||||
4
robbery/master_pol-module_1_2/app/res/colors.py
Normal file
4
robbery/master_pol-module_1_2/app/res/colors.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
MAIN_COLOR = "#FFFFFF"
|
||||
SECONDARY_COLOR = "#F4E8D3"
|
||||
ACCENT_COLOR = "#67BA80"
|
||||
ACCENT_COLOR_HOVER = "#529265"
|
||||
1
robbery/master_pol-module_1_2/app/res/fonts.py
Normal file
1
robbery/master_pol-module_1_2/app/res/fonts.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
MAIN_FONT = "Segoe UI"
|
||||
BIN
robbery/master_pol-module_1_2/app/res/imgs/master_pol.ico
Normal file
BIN
robbery/master_pol-module_1_2/app/res/imgs/master_pol.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
robbery/master_pol-module_1_2/app/res/imgs/master_pol.png
Normal file
BIN
robbery/master_pol-module_1_2/app/res/imgs/master_pol.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 158 KiB |
35
robbery/master_pol-module_1_2/app/res/styles.py
Normal file
35
robbery/master_pol-module_1_2/app/res/styles.py
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
from string import Template
|
||||
from res.colors import MAIN_COLOR, SECONDARY_COLOR, ACCENT_COLOR
|
||||
from res.fonts import MAIN_FONT
|
||||
|
||||
styles_template = Template(
|
||||
"""
|
||||
QWidget {
|
||||
font-family: {MAIN_FONT};
|
||||
background-color: {MAIN_COLOR}
|
||||
color: {SECONDARY_COLOR};
|
||||
}
|
||||
QPushButton {
|
||||
background-color: {ACCENT_COLOR};
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: {SECONDARY_COLOR};
|
||||
}
|
||||
QLineEdit {
|
||||
padding: 6px;
|
||||
border: 1px solid {ACCENT_COLOR};
|
||||
border-radius: 4px;
|
||||
background-color: white;
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
styles = styles_template.substitute(
|
||||
MAIN_FONT=MAIN_FONT,
|
||||
MAIN_COLOR=MAIN_COLOR,
|
||||
SECONDARY_COLOR=SECONDARY_COLOR,
|
||||
ACCENT_COLOR=ACCENT_COLOR,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue