mirror of
https://gitlab.com/MoonTestUse1/AdministrationItDepartmens.git
synced 2025-08-14 00:25:46 +02:00
Initial commit
This commit is contained in:
21
backend/app/crud/auth.py
Normal file
21
backend/app/crud/auth.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from sqlalchemy.orm import Session
|
||||
from ..schemas import tables
|
||||
from ..utils.auth import verify_password
|
||||
|
||||
|
||||
def authenticate_employee(db: Session, last_name: str, password: str):
|
||||
employee = (
|
||||
db.query(tables.Employee).filter(tables.Employee.last_name == last_name).first()
|
||||
)
|
||||
if not employee:
|
||||
return None
|
||||
if not verify_password(password, employee.password):
|
||||
return None
|
||||
return employee
|
||||
|
||||
|
||||
def authenticate_admin(db: Session, username: str, password: str):
|
||||
# Здесь можно добавить логику для админа, пока используем хардкод
|
||||
if username == "admin" and password == "admin66":
|
||||
return True
|
||||
return False
|
45
backend/app/crud/employees.py
Normal file
45
backend/app/crud/employees.py
Normal file
@@ -0,0 +1,45 @@
|
||||
from sqlalchemy.orm import Session
|
||||
from ..models import employee as models
|
||||
from ..schemas import tables
|
||||
from ..utils.auth import get_password_hash
|
||||
|
||||
|
||||
def get_employee(db: Session, employee_id: int):
|
||||
return db.query(tables.Employee).filter(tables.Employee.id == employee_id).first()
|
||||
|
||||
|
||||
def get_employee_by_lastname(db: Session, last_name: str):
|
||||
return (
|
||||
db.query(tables.Employee).filter(tables.Employee.last_name == last_name).first()
|
||||
)
|
||||
|
||||
|
||||
def get_employees(db: Session, skip: int = 0, limit: int = 100):
|
||||
return db.query(tables.Employee).offset(skip).limit(limit).all()
|
||||
|
||||
|
||||
def create_employee(db: Session, employee: models.EmployeeCreate):
|
||||
hashed_password = get_password_hash(employee.password)
|
||||
db_employee = tables.Employee(
|
||||
first_name=employee.first_name,
|
||||
last_name=employee.last_name,
|
||||
department=employee.department,
|
||||
office=employee.office,
|
||||
password=hashed_password,
|
||||
)
|
||||
db.add(db_employee)
|
||||
db.commit()
|
||||
db.refresh(db_employee)
|
||||
return db_employee
|
||||
|
||||
|
||||
def update_employee(db: Session, employee_id: int, data: dict):
|
||||
db_employee = get_employee(db, employee_id)
|
||||
if db_employee:
|
||||
for key, value in data.items():
|
||||
if key == "password":
|
||||
value = get_password_hash(value)
|
||||
setattr(db_employee, key, value)
|
||||
db.commit()
|
||||
db.refresh(db_employee)
|
||||
return db_employee
|
207
backend/app/crud/requests.py
Normal file
207
backend/app/crud/requests.py
Normal file
@@ -0,0 +1,207 @@
|
||||
from sqlalchemy.orm import Session
|
||||
from ..models import request as models
|
||||
from ..schemas import tables
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
from ..schemas import tables
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def create_request(db: Session, request: models.RequestCreate):
|
||||
db_request = tables.Request(
|
||||
employee_id=request.employee_id,
|
||||
department=request.department,
|
||||
request_type=request.request_type,
|
||||
priority=request.priority,
|
||||
description=request.description,
|
||||
status="new",
|
||||
)
|
||||
db.add(db_request)
|
||||
db.commit()
|
||||
db.refresh(db_request)
|
||||
return db_request
|
||||
|
||||
|
||||
def get_requests(db: Session, skip: int = 0, limit: int = 100):
|
||||
requests = (
|
||||
db.query(
|
||||
tables.Request,
|
||||
tables.Employee.last_name.label("employee_last_name"),
|
||||
tables.Employee.first_name.label("employee_first_name"),
|
||||
)
|
||||
.join(tables.Employee)
|
||||
.offset(skip)
|
||||
.limit(limit)
|
||||
.all()
|
||||
)
|
||||
|
||||
return [
|
||||
{
|
||||
"id": req[0].id,
|
||||
"employee_id": req[0].employee_id,
|
||||
"department": req[0].department,
|
||||
"request_type": req[0].request_type,
|
||||
"priority": req[0].priority,
|
||||
"status": req[0].status,
|
||||
"description": req[0].description,
|
||||
"created_at": req[0].created_at,
|
||||
"employee_last_name": req[1],
|
||||
"employee_first_name": req[2],
|
||||
}
|
||||
for req in requests
|
||||
]
|
||||
|
||||
|
||||
def get_requests_by_employee_lastname(db: Session, last_name: str):
|
||||
requests = (
|
||||
db.query(
|
||||
tables.Request,
|
||||
tables.Employee.last_name.label("employee_last_name"),
|
||||
tables.Employee.first_name.label("employee_first_name"),
|
||||
)
|
||||
.join(tables.Employee)
|
||||
.filter(tables.Employee.last_name.ilike(f"%{last_name}%"))
|
||||
.all()
|
||||
)
|
||||
|
||||
return [
|
||||
{
|
||||
"id": req[0].id,
|
||||
"employee_id": req[0].employee_id,
|
||||
"department": req[0].department,
|
||||
"request_type": req[0].request_type,
|
||||
"priority": req[0].priority,
|
||||
"status": req[0].status,
|
||||
"description": req[0].description,
|
||||
"created_at": req[0].created_at,
|
||||
"employee_last_name": req[1],
|
||||
"employee_first_name": req[2],
|
||||
}
|
||||
for req in requests
|
||||
]
|
||||
|
||||
|
||||
def update_request_status(
|
||||
db: Session, request_id: int, new_status: models.RequestStatus
|
||||
):
|
||||
try:
|
||||
db_request = (
|
||||
db.query(tables.Request).filter(tables.Request.id == request_id).first()
|
||||
)
|
||||
if not db_request:
|
||||
return None
|
||||
|
||||
# Define valid status transitions
|
||||
valid_transitions = {
|
||||
models.RequestStatus.NEW: [models.RequestStatus.IN_PROGRESS],
|
||||
models.RequestStatus.IN_PROGRESS: [models.RequestStatus.RESOLVED],
|
||||
models.RequestStatus.RESOLVED: [models.RequestStatus.CLOSED],
|
||||
models.RequestStatus.CLOSED: [],
|
||||
}
|
||||
|
||||
current_status = models.RequestStatus(db_request.status)
|
||||
if new_status not in valid_transitions[current_status]:
|
||||
raise ValueError(
|
||||
f"Invalid status transition from {current_status} to {new_status}"
|
||||
)
|
||||
|
||||
db_request.status = new_status
|
||||
db.commit()
|
||||
db.refresh(db_request)
|
||||
return db_request
|
||||
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
raise e
|
||||
|
||||
|
||||
def get_request_details(db: Session, request_id: int):
|
||||
"""Get detailed request information including employee details"""
|
||||
request = (
|
||||
db.query(tables.Request)
|
||||
.join(tables.Employee)
|
||||
.filter(tables.Request.id == request_id)
|
||||
.first()
|
||||
)
|
||||
|
||||
if not request:
|
||||
return None
|
||||
|
||||
return {
|
||||
"id": request.id,
|
||||
"employee_last_name": request.employee.last_name,
|
||||
"employee_first_name": request.employee.first_name,
|
||||
"department": request.department,
|
||||
"office": request.employee.office,
|
||||
"request_type": request.request_type,
|
||||
"priority": request.priority,
|
||||
"description": request.description,
|
||||
"status": request.status,
|
||||
"created_at": request.created_at.isoformat(),
|
||||
}
|
||||
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
from ..schemas import tables
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def get_request_details(db: Session, request_id: int):
|
||||
"""Get detailed request information including employee details"""
|
||||
request = (
|
||||
db.query(tables.Request)
|
||||
.join(tables.Employee)
|
||||
.filter(tables.Request.id == request_id)
|
||||
.first()
|
||||
)
|
||||
|
||||
if not request:
|
||||
return None
|
||||
|
||||
return {
|
||||
"id": request.id,
|
||||
"employee_last_name": request.employee.last_name,
|
||||
"employee_first_name": request.employee.first_name,
|
||||
"department": request.department,
|
||||
"office": request.employee.office,
|
||||
"request_type": request.request_type,
|
||||
"priority": request.priority,
|
||||
"description": request.description,
|
||||
"status": request.status,
|
||||
"created_at": request.created_at.isoformat(),
|
||||
}
|
||||
|
||||
|
||||
def update_request_status(db: Session, request_id: int, new_status: str):
|
||||
"""Update request status with validation"""
|
||||
try:
|
||||
# Define valid status transitions
|
||||
valid_transitions = {
|
||||
"new": ["in_progress"],
|
||||
"in_progress": ["resolved"],
|
||||
"resolved": ["closed"],
|
||||
"closed": [],
|
||||
}
|
||||
|
||||
db_request = (
|
||||
db.query(tables.Request).filter(tables.Request.id == request_id).first()
|
||||
)
|
||||
if not db_request:
|
||||
return None
|
||||
|
||||
current_status = db_request.status
|
||||
if new_status not in valid_transitions.get(current_status, []):
|
||||
raise ValueError(
|
||||
f"Invalid status transition from {current_status} to {new_status}"
|
||||
)
|
||||
|
||||
db_request.status = new_status
|
||||
db.commit()
|
||||
db.refresh(db_request)
|
||||
|
||||
# Get full request details after update
|
||||
return get_request_details(db, request_id)
|
||||
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
raise e
|
89
backend/app/crud/statistics.py
Normal file
89
backend/app/crud/statistics.py
Normal file
@@ -0,0 +1,89 @@
|
||||
from sqlalchemy import func, text
|
||||
from sqlalchemy.orm import Session
|
||||
from datetime import datetime, timedelta
|
||||
from ..schemas import tables
|
||||
from ..models.request import RequestStatus
|
||||
|
||||
|
||||
def get_statistics(db: Session, period: str = "week"):
|
||||
# Calculate date range based on period
|
||||
now = datetime.now()
|
||||
if period == "day":
|
||||
start_date = now - timedelta(days=1)
|
||||
elif period == "week":
|
||||
start_date = now - timedelta(weeks=1)
|
||||
elif period == "month":
|
||||
start_date = now - timedelta(days=30)
|
||||
else: # all time
|
||||
start_date = datetime.min
|
||||
|
||||
# Total requests
|
||||
total_requests = db.query(func.count(tables.Request.id)).scalar() or 0
|
||||
|
||||
# Resolved requests in period
|
||||
resolved_requests = (
|
||||
db.query(func.count(tables.Request.id))
|
||||
.filter(tables.Request.status == RequestStatus.RESOLVED)
|
||||
.filter(tables.Request.created_at >= start_date)
|
||||
.scalar()
|
||||
or 0
|
||||
)
|
||||
|
||||
# Average resolution time (in hours)
|
||||
avg_resolution = (
|
||||
db.query(
|
||||
func.avg(func.julianday("now") - func.julianday(tables.Request.created_at))
|
||||
* 24
|
||||
)
|
||||
.filter(
|
||||
tables.Request.status == RequestStatus.RESOLVED,
|
||||
tables.Request.created_at >= start_date,
|
||||
)
|
||||
.scalar()
|
||||
)
|
||||
|
||||
avg_resolution_time = f"{int(avg_resolution or 0)}ч" if avg_resolution else "0ч"
|
||||
|
||||
# Request volume over time
|
||||
volume_data = (
|
||||
db.query(
|
||||
func.date(tables.Request.created_at).label("date"),
|
||||
func.count(tables.Request.id).label("count"),
|
||||
)
|
||||
.filter(tables.Request.created_at >= start_date)
|
||||
.group_by(text("date"))
|
||||
.all()
|
||||
)
|
||||
|
||||
# Request types distribution
|
||||
type_distribution = (
|
||||
db.query(tables.Request.request_type, func.count(tables.Request.id))
|
||||
.group_by(tables.Request.request_type)
|
||||
.all()
|
||||
)
|
||||
|
||||
# Status distribution
|
||||
status_distribution = (
|
||||
db.query(tables.Request.status, func.count(tables.Request.id))
|
||||
.group_by(tables.Request.status)
|
||||
.all()
|
||||
)
|
||||
|
||||
# Ensure all statuses are represented
|
||||
all_statuses = {status.value: 0 for status in RequestStatus}
|
||||
for status, count in status_distribution:
|
||||
all_statuses[status] = count
|
||||
|
||||
status_data = [(status, count) for status, count in all_statuses.items()]
|
||||
|
||||
return {
|
||||
"totalRequests": total_requests,
|
||||
"resolvedRequests": resolved_requests,
|
||||
"averageResolutionTime": avg_resolution_time,
|
||||
"volumeLabels": [str(d[0]) for d in volume_data],
|
||||
"volumeData": [d[1] for d in volume_data],
|
||||
"typeLabels": [t[0] for t in type_distribution],
|
||||
"typeData": [t[1] for t in type_distribution],
|
||||
"statusLabels": [s[0] for s in status_data],
|
||||
"statusData": [s[1] for s in status_data],
|
||||
}
|
Reference in New Issue
Block a user