import os
from datetime import date, datetime
from django.db import models
from django.forms import ValidationError
from django.middleware.csrf import get_token
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from base.horilla_company_manager import HorillaCompanyManager
from base.models import Company, Department, JobPosition, Tags
from employee.models import Employee
from horilla import horilla_middlewares
from horilla.horilla_middlewares import _thread_locals
from horilla.models import HorillaModel, upload_path
from horilla_audit.methods import get_diff
from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog
from horilla_views.cbv_methods import render_template
PRIORITY = [
("low", "Low"),
("medium", "Medium"),
("high", "High"),
]
MANAGER_TYPES = [
("department", "Department"),
("job_position", "Job Position"),
("individual", "Individual"),
]
TICKET_TYPES = [
("suggestion", "Suggestion"),
("complaint", "Complaint"),
("service_request", "Service Request"),
("meeting_request", "Meeting Request"),
("anounymous_complaint", "Anonymous Complaint"),
("others", "Others"),
]
TICKET_STATUS = [
("new", "New"),
("in_progress", "In Progress"),
("on_hold", "On Hold"),
("resolved", "Resolved"),
("canceled", "Canceled"),
]
class DepartmentManager(HorillaModel):
manager = models.ForeignKey(
Employee,
verbose_name=_("Manager"),
related_name="dep_manager",
on_delete=models.CASCADE,
)
department = models.ForeignKey(
Department,
verbose_name=_("Department"),
related_name="dept_manager",
on_delete=models.CASCADE,
)
company_id = models.ForeignKey(
Company, null=True, editable=False, on_delete=models.PROTECT
)
objects = HorillaCompanyManager("manager__employee_work_info__company_id")
def get_update_url(self):
"""
This method to get update url
"""
url = reverse_lazy("department-manager-update-view", kwargs={"pk": self.pk})
return url
def get_delete_url(self):
"""
This method to get delete url
"""
url = reverse_lazy("department-manager-delete", kwargs={"dep_id": self.pk})
return url
def get_instance_id(self):
return self.id
class Meta:
unique_together = ("department", "manager")
verbose_name = _("Department Manager")
verbose_name_plural = _("Department Managers")
def clean(self, *args, **kwargs):
super().clean(*args, **kwargs)
if not self.manager.get_department() == self.department:
raise ValidationError(_(f"This employee is not from {self.department} ."))
class TicketType(HorillaModel):
title = models.CharField(max_length=100, unique=True, verbose_name=_("Title"))
type = models.CharField(choices=TICKET_TYPES, max_length=50, verbose_name=_("Type"))
prefix = models.CharField(max_length=3, unique=True, verbose_name=_("Prefix"))
company_id = models.ForeignKey(
Company, null=True, editable=False, on_delete=models.PROTECT
)
objects = HorillaCompanyManager(related_company_field="company_id")
def __str__(self):
return self.title
def get_update_url(self):
"""
This method to get update url
"""
url = reverse_lazy("ticket-update-form", kwargs={"pk": self.pk})
return url
def get_delete_url(self):
"""
This method to get delete url
"""
url = reverse_lazy("generic-delete")
return url
def get_delete_instance(self):
"""
to get instance for delete
"""
return self.pk
class Meta:
verbose_name = _("Ticket Type")
verbose_name_plural = _("Ticket Types")
class Ticket(HorillaModel):
title = models.CharField(max_length=50)
employee_id = models.ForeignKey(
Employee, on_delete=models.PROTECT, related_name="ticket", verbose_name="Owner"
)
ticket_type = models.ForeignKey(
TicketType,
on_delete=models.PROTECT,
verbose_name="Ticket Type",
)
description = models.TextField(max_length=255)
priority = models.CharField(choices=PRIORITY, max_length=100, default="low")
created_date = models.DateField(auto_now_add=True)
resolved_date = models.DateField(blank=True, null=True)
assigning_type = models.CharField(
choices=MANAGER_TYPES, max_length=100, verbose_name=_("Assigning Type")
)
raised_on = models.CharField(max_length=100, verbose_name=_("Forward To"))
assigned_to = models.ManyToManyField(
Employee, blank=True, related_name="ticket_assigned_to"
)
deadline = models.DateField(null=True, blank=True)
tags = models.ManyToManyField(Tags, blank=True, related_name="ticket_tags")
status = models.CharField(choices=TICKET_STATUS, default="new", max_length=50)
history = HorillaAuditLog(
related_name="history_set",
bases=[
HorillaAuditInfo,
],
)
objects = HorillaCompanyManager(
related_company_field="employee_id__employee_work_info__company_id"
)
class Meta:
ordering = ["-created_date"]
verbose_name = _("Ticket")
verbose_name_plural = _("Tickets")
def clean(self, *args, **kwargs):
super().clean(*args, **kwargs)
deadline = self.deadline
today = datetime.today().date()
if deadline < today:
raise ValidationError(_("Deadline should be greater than today"))
def get_raised_on(self):
obj_id = self.raised_on
if self.assigning_type == "department":
raised_on = Department.objects.get(id=obj_id).department
elif self.assigning_type == "job_position":
raised_on = JobPosition.objects.get(id=obj_id).job_position
elif self.assigning_type == "individual":
raised_on = Employee.objects.get(id=obj_id).get_full_name()
return raised_on
def get_raised_on_object(self):
obj_id = self.raised_on
if self.assigning_type == "department":
raised_on = Department.objects.get(id=obj_id)
elif self.assigning_type == "job_position":
raised_on = JobPosition.objects.get(id=obj_id)
elif self.assigning_type == "individual":
raised_on = Employee.objects.get(id=obj_id)
return raised_on
def get_ticket_id_col(self):
"""
This method is used to get the ticket id
"""
today = date.today()
ticket_id = f"{self.ticket_type.prefix}-{self.pk:03d}"
if self.deadline == today:
due_text = "Due today"
else:
days_diff = (self.deadline - today).days
if days_diff < 0:
days_diff = abs(days_diff)
due_text = f"Overdue by {days_diff} days"
else:
due_text = f"Due in {days_diff} days"
if self.deadline < today:
icon_class = "danger"
elif self.deadline == today:
icon_class = "warning"
else:
icon_class = "success"
col = f"""
{ticket_id}