kpi-dashboard / models.py
Admin
Initial HF deploy
04477e7
Raw
History Blame
11.2 kB
from datetime import datetime, date
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
from extensions import db
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False, index=True)
email = db.Column(db.String(120), unique=True, nullable=True)
password_hash = db.Column(db.String(256), nullable=False)
full_name = db.Column(db.String(200), nullable=False)
role = db.Column(db.String(20), nullable=False, default='employee')
is_active = db.Column(db.Boolean, default=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
senior_expert_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
telegram_chat_id = db.Column(db.String(100), nullable=True)
profile_pic = db.Column(db.String(300), nullable=True)
grade = db.Column(db.String(50), nullable=True)
project_start_date = db.Column(db.Date, nullable=True)
phone = db.Column(db.String(30), nullable=True)
telegram = db.Column(db.String(100), nullable=True)
emergency_contact = db.Column(db.String(200), nullable=True)
emergency_contact_phone = db.Column(db.String(30), nullable=True)
position = db.Column(db.String(100), nullable=True)
delegated_admin_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
previous_review_rating = db.Column(db.String(50), nullable=True)
senior_expert = db.relationship('User', remote_side=[id], backref='subordinates', foreign_keys=[senior_expert_id])
delegated_admin = db.relationship('User', remote_side=[id], foreign_keys=[delegated_admin_id])
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
def has_role(self, *roles):
return self.role in roles
def _is_admin(self):
if self.role in ('admin', 'sm'):
return True
if self.position == 'руководитель':
return True
if self.delegated_admin_id is not None:
return True
return False
def can_view_employee(self, employee):
if not self.is_authenticated:
return False
if self._is_admin():
return True
if self.role == 'guest':
return True
if self.id == employee.id:
return True
if employee.is_active:
return True
return False
def can_edit(self):
return self._is_admin()
def get_visible_users(self):
if self._is_admin():
return User.query.filter_by(is_active=True).all()
if self.role == 'guest':
return User.query.filter_by(is_active=True).all()
if self.role == 'senior_expert':
visible = [self]
visible.extend(User.query.filter_by(senior_expert_id=self.id, is_active=True).all())
return visible
return [self]
class KpiDefinition(db.Model):
__tablename__ = 'kpi_definitions'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(200), nullable=False)
description = db.Column(db.Text, nullable=True)
unit = db.Column(db.String(50), nullable=True)
category = db.Column(db.String(100), nullable=True)
target_value = db.Column(db.Float, nullable=True)
is_active = db.Column(db.Boolean, default=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
class KpiValue(db.Model):
__tablename__ = 'kpi_values'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, index=True)
kpi_id = db.Column(db.Integer, db.ForeignKey('kpi_definitions.id'), nullable=False, index=True)
value = db.Column(db.Float, nullable=True)
month = db.Column(db.Integer, nullable=False)
year = db.Column(db.Integer, nullable=False)
uploaded_file_id = db.Column(db.Integer, db.ForeignKey('uploaded_files.id'), nullable=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
user = db.relationship('User', backref='kpi_values')
kpi = db.relationship('KpiDefinition', backref='values')
uploaded_file = db.relationship('UploadedFile', backref='kpi_values')
class UploadedFile(db.Model):
__tablename__ = 'uploaded_files'
id = db.Column(db.Integer, primary_key=True)
filename = db.Column(db.String(300), nullable=False)
original_name = db.Column(db.String(300), nullable=False)
file_type = db.Column(db.String(10), nullable=False)
file_size = db.Column(db.Integer, default=0)
description = db.Column(db.String(500), nullable=True)
kpi_name = db.Column(db.String(200), nullable=True)
uploaded_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
upload_date = db.Column(db.DateTime, default=datetime.utcnow)
uploader = db.relationship('User', backref='uploads')
class Notification(db.Model):
__tablename__ = 'notifications'
__table_args__ = (
db.Index('ix_notif_user_read', 'user_id', 'is_read'),
)
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, index=True)
message = db.Column(db.Text, nullable=False)
type = db.Column(db.String(50), default='info')
is_read = db.Column(db.Boolean, default=False)
link = db.Column(db.String(500), nullable=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
user = db.relationship('User', backref='notifications')
class Task(db.Model):
__tablename__ = 'tasks'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(300), nullable=False)
description = db.Column(db.Text, nullable=True)
assigned_to = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, index=True)
assigned_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
status = db.Column(db.String(20), default='pending')
priority = db.Column(db.String(20), default='medium')
due_date = db.Column(db.Date, nullable=True)
comment = db.Column(db.Text, nullable=True)
rework_comment = db.Column(db.Text, nullable=True)
completed_at = db.Column(db.DateTime, nullable=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
assignee = db.relationship('User', foreign_keys=[assigned_to], backref='assigned_tasks')
assigner = db.relationship('User', foreign_keys=[assigned_by], backref='created_tasks')
class KpiWeeklyData(db.Model):
__tablename__ = 'kpi_weekly_data'
__table_args__ = (
db.Index('ix_kwd_week_cat_metric', 'week_start', 'category', 'metric_name'),
)
id = db.Column(db.Integer, primary_key=True)
category = db.Column(db.String(100), nullable=False)
metric_name = db.Column(db.String(200), nullable=False)
week_start = db.Column(db.Date, nullable=False, index=True)
value = db.Column(db.String(50), nullable=True)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
class EmployeeKpiValue(db.Model):
__tablename__ = 'employee_kpi_values'
__table_args__ = (
db.Index('ix_ekv_lookup', 'user_id', 'week_start', 'category', 'metric_name'),
db.Index('ix_ekv_week', 'week_start'),
)
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, index=True)
category = db.Column(db.String(100), nullable=False)
metric_name = db.Column(db.String(200), nullable=False)
week_start = db.Column(db.Date, nullable=False, index=True)
value_date = db.Column(db.Date, nullable=True)
plan_value = db.Column(db.String(50), nullable=True)
fact_value = db.Column(db.String(50), nullable=True)
aggregation = db.Column(db.String(10), default='sum')
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
user = db.relationship('User', backref='kpi_entries')
class EmployeeMapping(db.Model):
__tablename__ = 'employee_mappings'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, unique=True, index=True)
rebus_login = db.Column(db.String(200), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
user = db.relationship('User', backref='rebus_mapping', uselist=False)
class Training(db.Model):
__tablename__ = 'trainings'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(300), nullable=False)
description = db.Column(db.Text, nullable=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, index=True)
date = db.Column(db.Date, nullable=False, default=date.today)
hours = db.Column(db.Float, nullable=True)
status = db.Column(db.String(20), default='completed')
file_path = db.Column(db.String(300), nullable=True)
original_name = db.Column(db.String(300), nullable=True)
file_size = db.Column(db.Integer, default=0)
uploaded_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
upload_date = db.Column(db.DateTime, default=datetime.utcnow)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
user = db.relationship('User', foreign_keys=[user_id], backref='trainings')
uploader = db.relationship('User', foreign_keys=[uploaded_by], backref='uploaded_trainings')
class Audit(db.Model):
__tablename__ = 'audits'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, index=True)
file_name = db.Column(db.String(300), nullable=False)
original_name = db.Column(db.String(300), nullable=False)
audit_type = db.Column(db.String(20), nullable=False, default='audit')
file_size = db.Column(db.Integer, default=0)
uploaded_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
upload_date = db.Column(db.DateTime, default=datetime.utcnow)
user = db.relationship('User', foreign_keys=[user_id], backref='audits')
uploader = db.relationship('User', foreign_keys=[uploaded_by], backref='uploaded_audits')
class ScheduleShift(db.Model):
__tablename__ = 'schedule_shifts'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, index=True)
date = db.Column(db.Date, nullable=False, index=True)
shift_type = db.Column(db.String(20), nullable=False, default='shift')
time_from = db.Column(db.String(5), nullable=True)
time_to = db.Column(db.String(5), nullable=True)
hours = db.Column(db.Float, nullable=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
user = db.relationship('User', backref='schedule_shifts')
__table_args__ = (
db.UniqueConstraint('user_id', 'date', name='uq_user_date'),
)