Files
2026-04-03 21:12:02 +07:00

139 lines
4.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import re
from datetime import datetime
from flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///accounting.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = "lab4_secret_key"
db = SQLAlchemy(app)
# ---------------- МОДЕЛЬ ----------------
class Employee(db.Model):
id = db.Column(db.Integer, primary_key=True)
fullname = db.Column(db.String(120), nullable=False)
salary = db.Column(db.Integer, nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return f'<Employee {self.id}>'
# ----------- ВАЛИДАЦИЯ БЭКЕНДА ------------
def validate_employee(fullname: str, salary: str):
errors = []
fullname = fullname.strip()
if not fullname:
errors.append("ФИО не может быть пустым")
elif len(fullname) < 5 or len(fullname) > 120:
errors.append("ФИО должно быть от 5 до 120 символов")
elif not re.fullmatch(r"[A-Za-zА-Яа-яЁё\s\-\']+", fullname):
errors.append("ФИО может содержать только буквы, пробелы, дефисы и апострофы")
if not salary:
errors.append("Зарплата обязательна")
else:
try:
salary = int(salary)
if salary <= 0 or salary > 10_000_000:
errors.append("Зарплата должна быть от 1 до 10 000 000")
except:
errors.append("Зарплата должна быть числом")
return errors
# ---------------- РОУТЫ ----------------
@app.route("/")
def index():
return render_template("index.html")
@app.route("/employees")
def employees():
items = Employee.query.order_by(Employee.created_at.desc()).all()
total_salary = sum(e.salary for e in items)
return render_template("employees.html", employees=items, total_salary=total_salary)
@app.route("/create", methods=["GET", "POST"])
def create_employee():
if request.method == "POST":
fullname = request.form.get("fullname", "")
salary = request.form.get("salary", "")
errors = validate_employee(fullname, salary)
if errors:
for e in errors:
flash(e, "error")
return render_template("create_employee.html", fullname=fullname, salary=salary)
employee = Employee(fullname=fullname.strip(), salary=int(salary))
try:
db.session.add(employee)
db.session.commit()
return redirect(url_for("employees"))
except:
return render_template("error.html", msg="Ошибка добавления")
return render_template("create_employee.html")
@app.route("/employees/<int:id>")
def employee_detail(id):
emp = Employee.query.get_or_404(id)
return render_template("employee_detail.html", emp=emp)
@app.route("/employees/<int:id>/delete")
def employee_delete(id):
emp = Employee.query.get_or_404(id)
try:
db.session.delete(emp)
db.session.commit()
return redirect(url_for("employees"))
except:
return render_template("error.html", msg="Ошибка удаления")
@app.route("/employees/<int:id>/update", methods=["GET", "POST"])
def employee_update(id):
emp = Employee.query.get_or_404(id)
if request.method == "POST":
fullname = request.form.get("fullname", "")
salary = request.form.get("salary", "")
errors = validate_employee(fullname, salary)
if errors:
for e in errors:
flash(e, "error")
return render_template("employee_update.html", emp=emp)
emp.fullname = fullname.strip()
emp.salary = int(salary)
try:
db.session.commit()
return redirect(url_for("employees"))
except:
return render_template("error.html", msg="Ошибка обновления")
return render_template("employee_update.html", emp=emp)
if __name__ == "__main__":
with app.app_context():
db.create_all()
app.run(debug=True)