[FIX] HELPDESK: Permission for department manager added
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from datetime import datetime
|
||||
from distutils.util import strtobool
|
||||
from operator import itemgetter
|
||||
from urllib.parse import parse_qs
|
||||
|
||||
@@ -8,6 +11,7 @@ from django.core.paginator import Paginator
|
||||
from django.db.models import ProtectedError, Q
|
||||
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
|
||||
from django.shortcuts import redirect, render
|
||||
from django.template.loader import render_to_string
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext as _
|
||||
from django.views.decorators.http import require_http_methods
|
||||
@@ -23,6 +27,7 @@ from base.methods import (
|
||||
)
|
||||
from base.models import Department, JobPosition, Tags
|
||||
from employee.models import Employee
|
||||
from employee.views import get_content_type
|
||||
from helpdesk.decorators import ticket_owner_can_enter
|
||||
from helpdesk.filter import FAQCategoryFilter, FAQFilter, TicketFilter, TicketReGroup
|
||||
from helpdesk.forms import (
|
||||
@@ -37,10 +42,12 @@ from helpdesk.forms import (
|
||||
TicketTagForm,
|
||||
TicketTypeForm,
|
||||
)
|
||||
from helpdesk.methods import is_department_manager
|
||||
from helpdesk.models import (
|
||||
FAQ,
|
||||
TICKET_STATUS,
|
||||
Attachment,
|
||||
ClaimRequest,
|
||||
Comment,
|
||||
DepartmentManager,
|
||||
FAQCategory,
|
||||
@@ -57,6 +64,8 @@ from horilla.decorators import (
|
||||
from horilla.group_by import group_by_queryset
|
||||
from notifications.signals import notify
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Create your views here.
|
||||
|
||||
|
||||
@@ -377,11 +386,10 @@ def ticket_view(request):
|
||||
Parameters:
|
||||
request (HttpRequest): The HTTP request object.
|
||||
"""
|
||||
tickets = Ticket.objects.filter(is_active=True).order_by("-created_date")
|
||||
tickets = Ticket.objects.filter(is_active=True)
|
||||
view = request.GET.get("view") if request.GET.get("view") else "list"
|
||||
employee = request.user.employee_get
|
||||
previous_data = request.GET.urlencode()
|
||||
if request.method == "GET":
|
||||
tickets = TicketFilter(request.GET).qs
|
||||
my_page_number = request.GET.get("my_page")
|
||||
all_page_number = request.GET.get("all_page")
|
||||
allocated_page_number = request.GET.get("allocated_page")
|
||||
@@ -422,7 +430,7 @@ def ticket_view(request):
|
||||
"f": TicketFilter(request.GET),
|
||||
"gp_fields": TicketReGroup.fields,
|
||||
"ticket_status": TICKET_STATUS,
|
||||
"view": request.GET.get("view"),
|
||||
"view": view,
|
||||
"today": datetime.today().date(),
|
||||
"filter_dict": data_dict,
|
||||
}
|
||||
@@ -444,10 +452,14 @@ def ticket_create(request):
|
||||
POST : return Ticket view
|
||||
"""
|
||||
|
||||
form = TicketForm(initial={"employee_id": request.user})
|
||||
form = TicketForm()
|
||||
if request.GET.get("status"):
|
||||
status = request.GET.get("status")
|
||||
form = TicketForm(initial={"status": status, "employee_id": request.user})
|
||||
form = TicketForm(
|
||||
initial={
|
||||
"status": status,
|
||||
}
|
||||
)
|
||||
if request.method == "POST":
|
||||
form = TicketForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
@@ -489,7 +501,6 @@ def ticket_create(request):
|
||||
|
||||
@login_required
|
||||
@hx_request_required
|
||||
@ticket_owner_can_enter(perm="helpdesk.change_ticket", model=Ticket)
|
||||
def ticket_update(request, ticket_id):
|
||||
"""
|
||||
This function is responsible for updating the Ticket.
|
||||
@@ -503,27 +514,44 @@ def ticket_update(request, ticket_id):
|
||||
"""
|
||||
|
||||
ticket = Ticket.objects.get(id=ticket_id)
|
||||
form = TicketForm(instance=ticket)
|
||||
if request.method == "POST":
|
||||
form = TicketForm(request.POST, request.FILES, instance=ticket)
|
||||
if form.is_valid():
|
||||
ticket = form.save()
|
||||
attachments = form.files.getlist("attachment")
|
||||
for attachment in attachments:
|
||||
attachment_instance = Attachment(file=attachment, ticket=ticket)
|
||||
attachment_instance.save()
|
||||
messages.success(request, _("The Ticket updated successfully."))
|
||||
return HttpResponse("<script>window.location.reload()</script>")
|
||||
context = {
|
||||
"form": form,
|
||||
"ticket_id": ticket_id,
|
||||
"t_type_form": TicketTypeForm(),
|
||||
}
|
||||
return render(request, "helpdesk/ticket/ticket_form.html", context)
|
||||
if (
|
||||
request.user.has_perm("helpdesk.change_ticket")
|
||||
or is_department_manager(request, ticket)
|
||||
or request.user.employee_get == ticket.employee_id
|
||||
or request.user.employee_get in ticket.assigned_to.all()
|
||||
):
|
||||
form = TicketForm(instance=ticket)
|
||||
if request.method == "POST":
|
||||
form = TicketForm(request.POST, request.FILES, instance=ticket)
|
||||
if form.is_valid():
|
||||
ticket = form.save()
|
||||
attachments = form.files.getlist("attachment")
|
||||
for attachment in attachments:
|
||||
attachment_instance = Attachment(file=attachment, ticket=ticket)
|
||||
attachment_instance.save()
|
||||
messages.success(request, _("The Ticket updated successfully."))
|
||||
return HttpResponse("<script>window.location.reload()</script>")
|
||||
context = {
|
||||
"form": form,
|
||||
"ticket_id": ticket_id,
|
||||
"t_type_form": TicketTypeForm(),
|
||||
}
|
||||
return render(request, "helpdesk/ticket/ticket_form.html", context)
|
||||
else:
|
||||
messages.info(request, _("You don't have permission."))
|
||||
|
||||
previous_url = request.META.get("HTTP_REFERER", "/")
|
||||
|
||||
# Handle request for HTMX if needed
|
||||
if "HTTP_HX_REQUEST" in request.META:
|
||||
return render(request, "decorator_404.html")
|
||||
else:
|
||||
return HttpResponse(
|
||||
f'<script>window.location.href = "{previous_url}"</script>'
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required("helpdesk.change_ticket")
|
||||
def ticket_archive(request, ticket_id):
|
||||
"""
|
||||
This function is responsible for archiving the Ticket.
|
||||
@@ -536,15 +564,37 @@ def ticket_archive(request, ticket_id):
|
||||
"""
|
||||
|
||||
ticket = Ticket.objects.get(id=ticket_id)
|
||||
if ticket.is_active:
|
||||
ticket.is_active = False
|
||||
|
||||
# Check if the user has permission or is the employee or their reporting manager
|
||||
if (
|
||||
request.user.has_perm("helpdesk.delete_ticket")
|
||||
or ticket.employee_id == request.user.employee_get
|
||||
or is_department_manager(request, ticket)
|
||||
):
|
||||
|
||||
# Toggle the ticket's active state
|
||||
ticket.is_active = not ticket.is_active
|
||||
ticket.save()
|
||||
messages.success(request, _("The Ticket archived successfully."))
|
||||
|
||||
if ticket.is_active:
|
||||
messages.success(request, _("The Ticket un-archived successfully."))
|
||||
else:
|
||||
messages.success(request, _("The Ticket archived successfully."))
|
||||
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
|
||||
|
||||
else:
|
||||
ticket.is_active = True
|
||||
ticket.save()
|
||||
messages.success(request, _("The Ticket un-archived successfully."))
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
|
||||
messages.info(request, _("You don't have permission."))
|
||||
|
||||
previous_url = request.META.get("HTTP_REFERER", "/")
|
||||
|
||||
# Handle request for HTMX if needed
|
||||
if "HTTP_HX_REQUEST" in request.META:
|
||||
return render(request, "decorator_404.html")
|
||||
else:
|
||||
return HttpResponse(
|
||||
f'<script>window.location.href = "{previous_url}"</script>'
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@@ -620,7 +670,7 @@ def change_ticket_status(request, ticket_id):
|
||||
|
||||
|
||||
@login_required
|
||||
@ticket_owner_can_enter(perm="helpdesk.change_ticket", model=Ticket)
|
||||
@ticket_owner_can_enter(perm="helpdesk.delete_ticket", model=Ticket)
|
||||
def ticket_delete(request, ticket_id):
|
||||
"""
|
||||
This function is responsible for deleting the Ticket.
|
||||
@@ -634,37 +684,40 @@ def ticket_delete(request, ticket_id):
|
||||
"""
|
||||
try:
|
||||
ticket = Ticket.objects.get(id=ticket_id)
|
||||
|
||||
mail_thread = TicketSendThread(
|
||||
request,
|
||||
ticket,
|
||||
type="delete",
|
||||
)
|
||||
mail_thread.start()
|
||||
employees = ticket.assigned_to.all()
|
||||
assignees = [employee.employee_user_id for employee in employees]
|
||||
assignees.append(ticket.employee_id.employee_user_id)
|
||||
if hasattr(ticket.get_raised_on_object(), "dept_manager"):
|
||||
if ticket.get_raised_on_object().dept_manager.all():
|
||||
manager = (
|
||||
ticket.get_raised_on_object().dept_manager.all().first().manager
|
||||
)
|
||||
assignees.append(manager.employee_user_id)
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=assignees,
|
||||
verb=f"The ticket has been deleted.",
|
||||
verb_ar="تم حذف التذكرة.",
|
||||
verb_de="Das Ticket wurde gelöscht",
|
||||
verb_es="El billete ha sido eliminado.",
|
||||
verb_fr="Le ticket a été supprimé.",
|
||||
icon="infinite",
|
||||
redirect=reverse("ticket-view"),
|
||||
)
|
||||
ticket.delete()
|
||||
messages.success(
|
||||
request, _('The Ticket "{}" has been deleted successfully.').format(ticket)
|
||||
)
|
||||
if ticket.status == "new":
|
||||
mail_thread = TicketSendThread(
|
||||
request,
|
||||
ticket,
|
||||
type="delete",
|
||||
)
|
||||
mail_thread.start()
|
||||
employees = ticket.assigned_to.all()
|
||||
assignees = [employee.employee_user_id for employee in employees]
|
||||
assignees.append(ticket.employee_id.employee_user_id)
|
||||
if hasattr(ticket.get_raised_on_object(), "dept_manager"):
|
||||
if ticket.get_raised_on_object().dept_manager.all():
|
||||
manager = (
|
||||
ticket.get_raised_on_object().dept_manager.all().first().manager
|
||||
)
|
||||
assignees.append(manager.employee_user_id)
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=assignees,
|
||||
verb=f"The ticket has been deleted.",
|
||||
verb_ar="تم حذف التذكرة.",
|
||||
verb_de="Das Ticket wurde gelöscht",
|
||||
verb_es="El billete ha sido eliminado.",
|
||||
verb_fr="Le ticket a été supprimé.",
|
||||
icon="infinite",
|
||||
redirect=reverse("ticket-view"),
|
||||
)
|
||||
ticket.delete()
|
||||
messages.success(
|
||||
request,
|
||||
_('The Ticket "{}" has been deleted successfully.').format(ticket),
|
||||
)
|
||||
else:
|
||||
messages.error(request, _('The ticket is not in the "New" status'))
|
||||
except ProtectedError:
|
||||
messages.error(request, _("You cannot delete this Ticket."))
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
|
||||
@@ -709,17 +762,17 @@ def ticket_filter(request):
|
||||
my_page_number = request.GET.get("my_page")
|
||||
all_page_number = request.GET.get("all_page")
|
||||
allocated_page_number = request.GET.get("allocated_page")
|
||||
tickets_items1 = []
|
||||
tickets_items2 = []
|
||||
tickets_items1 = Ticket.objects.none()
|
||||
tickets_items2 = Ticket.objects.none()
|
||||
|
||||
my_tickets = tickets.filter(employee_id=request.user.employee_get).order_by(
|
||||
"-created_date"
|
||||
my_tickets = tickets.filter(employee_id=request.user.employee_get) | tickets.filter(
|
||||
created_by=request.user
|
||||
)
|
||||
|
||||
all_tickets = tickets.filter(is_active=True).order_by("-created_date")
|
||||
all_tickets = tickets.filter(is_active=True)
|
||||
all_tickets = filtersubordinates(request, tickets, "helpdesk.add_tickets")
|
||||
|
||||
allocated_tickets = []
|
||||
allocated_tickets = Ticket.objects.none()
|
||||
user = request.user.employee_get
|
||||
department = user.employee_work_info.department_id
|
||||
job_position = user.employee_work_info.job_position_id
|
||||
@@ -795,149 +848,242 @@ def ticket_filter(request):
|
||||
|
||||
|
||||
@login_required
|
||||
@ticket_owner_can_enter(perm="helpdesk.change_ticket", model=Ticket)
|
||||
def ticket_detail(request, ticket_id, **kwargs):
|
||||
today = datetime.now().date()
|
||||
ticket = Ticket.objects.get(id=ticket_id)
|
||||
c_form = CommentForm()
|
||||
f_form = AttachmentForm()
|
||||
attachments = ticket.ticket_attachment.all()
|
||||
if (
|
||||
request.user.has_perm("helpdesk.view_ticket")
|
||||
or ticket.employee_id.get_reporting_manager() == request.user.employee_get
|
||||
or is_department_manager(request, ticket)
|
||||
or request.user.employee_get == ticket.employee_id
|
||||
or request.user.employee_get in ticket.assigned_to.all()
|
||||
):
|
||||
today = datetime.now().date()
|
||||
c_form = CommentForm()
|
||||
f_form = AttachmentForm()
|
||||
attachments = ticket.ticket_attachment.all()
|
||||
|
||||
activity_list = []
|
||||
comments = ticket.comment.all()
|
||||
trackings = ticket.tracking()
|
||||
for comment in comments:
|
||||
activity_list.append(
|
||||
{"type": "comment", "comment": comment, "date": comment.date}
|
||||
)
|
||||
for history in trackings:
|
||||
activity_list.append(
|
||||
{
|
||||
"type": "history",
|
||||
"history": history,
|
||||
"date": history["pair"][0].history_date,
|
||||
}
|
||||
)
|
||||
activity_list = []
|
||||
comments = ticket.comment.all()
|
||||
trackings = ticket.tracking()
|
||||
for comment in comments:
|
||||
activity_list.append(
|
||||
{"type": "comment", "comment": comment, "date": comment.date}
|
||||
)
|
||||
for history in trackings:
|
||||
activity_list.append(
|
||||
{
|
||||
"type": "history",
|
||||
"history": history,
|
||||
"date": history["pair"][0].history_date,
|
||||
}
|
||||
)
|
||||
|
||||
sorted_activity_list = sorted(activity_list, key=itemgetter("date"))
|
||||
sorted_activity_list = sorted(activity_list, key=itemgetter("date"))
|
||||
|
||||
color = "success"
|
||||
remaining_days = ticket.deadline - today
|
||||
remaining = f"Due in {remaining_days.days} days"
|
||||
if remaining_days.days < 0:
|
||||
remaining = f"{abs(remaining_days.days)} days overdue"
|
||||
color = "danger"
|
||||
elif remaining_days.days == 0:
|
||||
remaining = "Due Today"
|
||||
color = "warning"
|
||||
color = "success"
|
||||
remaining_days = ticket.deadline - today
|
||||
remaining = f"Due in {remaining_days.days} days"
|
||||
if remaining_days.days < 0:
|
||||
remaining = f"{abs(remaining_days.days)} days overdue"
|
||||
color = "danger"
|
||||
elif remaining_days.days == 0:
|
||||
remaining = "Due Today"
|
||||
color = "warning"
|
||||
|
||||
rating = ""
|
||||
if ticket.priority == "low":
|
||||
rating = "1"
|
||||
elif ticket.priority == "medium":
|
||||
rating = "2"
|
||||
rating = ""
|
||||
if ticket.priority == "low":
|
||||
rating = "1"
|
||||
elif ticket.priority == "medium":
|
||||
rating = "2"
|
||||
else:
|
||||
rating = "3"
|
||||
|
||||
context = {
|
||||
"ticket": ticket,
|
||||
"c_form": c_form,
|
||||
"f_form": f_form,
|
||||
"attachments": attachments,
|
||||
"ticket_status": TICKET_STATUS,
|
||||
"tag_form": TicketTagForm(instance=ticket),
|
||||
"sorted_activity_list": sorted_activity_list,
|
||||
"create_tag_f": TagsForm(),
|
||||
"color": color,
|
||||
"remaining": remaining,
|
||||
"rating": rating,
|
||||
}
|
||||
return render(request, "helpdesk/ticket/ticket_detail.html", context=context)
|
||||
else:
|
||||
rating = "3"
|
||||
messages.info(request, _("You don't have permission."))
|
||||
previous_url = request.META.get("HTTP_REFERER", "/")
|
||||
|
||||
context = {
|
||||
"ticket": ticket,
|
||||
"c_form": c_form,
|
||||
"f_form": f_form,
|
||||
"attachments": attachments,
|
||||
"ticket_status": TICKET_STATUS,
|
||||
"tag_form": TicketTagForm(instance=ticket),
|
||||
"sorted_activity_list": sorted_activity_list,
|
||||
"create_tag_f": TagsForm(),
|
||||
"color": color,
|
||||
"remaining": remaining,
|
||||
"rating": rating,
|
||||
}
|
||||
return render(request, "helpdesk/ticket/ticket_detail.html", context=context)
|
||||
# Handle request for HTMX if needed
|
||||
if "HTTP_HX_REQUEST" in request.META:
|
||||
return render(request, "decorator_404.html")
|
||||
else:
|
||||
return HttpResponse(
|
||||
f'<script>window.location.href = "{previous_url}"</script>'
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
def ticket_individual_view(request, ticket_id):
|
||||
ticket = Ticket.objects.filter(id=ticket_id).first()
|
||||
context = {
|
||||
"ticket": ticket,
|
||||
}
|
||||
return render(
|
||||
request, "helpdesk/ticket/ticket_individual_view.html", context=context
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
def view_ticket_claim_request(request, ticket_id):
|
||||
ticket = Ticket.objects.filter(id=ticket_id).first()
|
||||
if request.user.has_perm("helpdesk.change_ticket") or is_department_manager(
|
||||
request, ticket
|
||||
):
|
||||
claim_requests = ticket.claimrequest_set.all()
|
||||
context = {
|
||||
"claim_requests": claim_requests,
|
||||
}
|
||||
return render(request, "helpdesk/ticket/ticket_claim_requests.html", context)
|
||||
else:
|
||||
messages.info(request, _("You don't have permission."))
|
||||
previous_url = request.META.get("HTTP_REFERER", "/")
|
||||
|
||||
# Handle request for HTMX if needed
|
||||
if "HTTP_HX_REQUEST" in request.META:
|
||||
return render(request, "decorator_404.html")
|
||||
else:
|
||||
return HttpResponse(
|
||||
f'<script>window.location.href = "{previous_url}"</script>'
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
# @ticket_owner_can_enter("perms.helpdesk.helpdesk_changeticket", Ticket)
|
||||
def ticket_update_tag(request):
|
||||
"""
|
||||
method to update the tags of ticket
|
||||
"""
|
||||
data = request.GET
|
||||
ticket = Ticket.objects.get(id=data["ticketId"])
|
||||
tagids = data.getlist("selectedValues[]")
|
||||
ticket.tags.clear()
|
||||
for tagId in tagids:
|
||||
tag = Tags.objects.get(id=tagId)
|
||||
ticket.tags.add(tag)
|
||||
response = {
|
||||
"type": "success",
|
||||
"message": _("The Ticket tag updated successfully."),
|
||||
}
|
||||
return JsonResponse(response)
|
||||
if (
|
||||
request.user.has_perm("helpdesk.view_ticket")
|
||||
or request.user.employee_get == ticket.employee_id
|
||||
or is_department_manager(request, ticket)
|
||||
):
|
||||
tagids = data.getlist("selectedValues[]")
|
||||
ticket.tags.clear()
|
||||
for tagId in tagids:
|
||||
tag = Tags.objects.get(id=tagId)
|
||||
ticket.tags.add(tag)
|
||||
response = {
|
||||
"type": "success",
|
||||
"message": _("The Ticket tag updated successfully."),
|
||||
}
|
||||
return JsonResponse(response)
|
||||
else:
|
||||
messages.info(request, _("You don't have permission."))
|
||||
previous_url = request.META.get("HTTP_REFERER", "/")
|
||||
|
||||
# Handle request for HTMX if needed
|
||||
if "HTTP_HX_REQUEST" in request.META:
|
||||
return render(request, "decorator_404.html")
|
||||
else:
|
||||
return HttpResponse(
|
||||
f'<script>window.location.href = "{previous_url}"</script>'
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@hx_request_required
|
||||
@ticket_owner_can_enter(perm="helpdesk.change_ticket", model=Ticket)
|
||||
def ticket_change_raised_on(request, ticket_id):
|
||||
ticket = Ticket.objects.get(id=ticket_id)
|
||||
form = TicketRaisedOnForm(instance=ticket)
|
||||
if request.method == "POST":
|
||||
form = TicketRaisedOnForm(request.POST, instance=ticket)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request, _("Responsibility updated for the Ticket"))
|
||||
return redirect(ticket_detail, ticket_id=ticket_id)
|
||||
return render(
|
||||
request,
|
||||
"helpdesk/ticket/forms/change_raised_on.html",
|
||||
{"form": form, "ticket_id": ticket_id},
|
||||
)
|
||||
if (
|
||||
request.user.has_perm("helpdesk.view_ticket")
|
||||
or request.user.employee_get == ticket.employee_id
|
||||
):
|
||||
form = TicketRaisedOnForm(instance=ticket)
|
||||
if request.method == "POST":
|
||||
form = TicketRaisedOnForm(request.POST, instance=ticket)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request, _("Responsibility updated for the Ticket"))
|
||||
return redirect(ticket_detail, ticket_id=ticket_id)
|
||||
return render(
|
||||
request,
|
||||
"helpdesk/ticket/forms/change_raised_on.html",
|
||||
{"form": form, "ticket_id": ticket_id},
|
||||
)
|
||||
else:
|
||||
messages.info(request, _("You don't have permission."))
|
||||
previous_url = request.META.get("HTTP_REFERER", "/")
|
||||
|
||||
# Handle request for HTMX if needed
|
||||
if "HTTP_HX_REQUEST" in request.META:
|
||||
return render(request, "decorator_404.html")
|
||||
else:
|
||||
return HttpResponse(
|
||||
f'<script>window.location.href = "{previous_url}"</script>'
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@hx_request_required
|
||||
@manager_can_enter("helpdesk.change_ticket")
|
||||
def ticket_change_assignees(request, ticket_id):
|
||||
ticket = Ticket.objects.get(id=ticket_id)
|
||||
prev_assignee_ids = ticket.assigned_to.values_list("id", flat=True)
|
||||
form = TicketAssigneesForm(instance=ticket)
|
||||
if request.method == "POST":
|
||||
form = TicketAssigneesForm(request.POST, instance=ticket)
|
||||
if form.is_valid():
|
||||
form.save(commit=False)
|
||||
if request.user.has_perm("helpdesk.change_ticket") or is_department_manager(
|
||||
request, ticket
|
||||
):
|
||||
prev_assignee_ids = ticket.assigned_to.values_list("id", flat=True)
|
||||
form = TicketAssigneesForm(instance=ticket)
|
||||
if request.method == "POST":
|
||||
form = TicketAssigneesForm(request.POST, instance=ticket)
|
||||
if form.is_valid():
|
||||
form.save(commit=False)
|
||||
|
||||
new_assignee_ids = form.cleaned_data["assigned_to"].values_list(
|
||||
"id", flat=True
|
||||
new_assignee_ids = form.cleaned_data["assigned_to"].values_list(
|
||||
"id", flat=True
|
||||
)
|
||||
added_assignee_ids = set(new_assignee_ids) - set(prev_assignee_ids)
|
||||
removed_assignee_ids = set(prev_assignee_ids) - set(new_assignee_ids)
|
||||
added_assignees = Employee.objects.filter(id__in=added_assignee_ids)
|
||||
removed_assignees = Employee.objects.filter(id__in=removed_assignee_ids)
|
||||
|
||||
form.save()
|
||||
|
||||
mail_thread = AddAssigneeThread(
|
||||
request,
|
||||
ticket,
|
||||
added_assignees,
|
||||
)
|
||||
mail_thread.start()
|
||||
mail_thread = RemoveAssigneeThread(
|
||||
request,
|
||||
ticket,
|
||||
removed_assignees,
|
||||
)
|
||||
mail_thread.start()
|
||||
|
||||
messages.success(request, _("Assinees updated for the Ticket"))
|
||||
return HttpResponse("<script>window.location.reload()</script>")
|
||||
|
||||
return render(
|
||||
request,
|
||||
"helpdesk/ticket/forms/change_assinees.html",
|
||||
{"form": form, "ticket_id": ticket_id},
|
||||
)
|
||||
else:
|
||||
messages.info(request, _("You don't have permission."))
|
||||
previous_url = request.META.get("HTTP_REFERER", "/")
|
||||
|
||||
# Handle request for HTMX if needed
|
||||
if "HTTP_HX_REQUEST" in request.META:
|
||||
return render(request, "decorator_404.html")
|
||||
else:
|
||||
return HttpResponse(
|
||||
f'<script>window.location.href = "{previous_url}"</script>'
|
||||
)
|
||||
added_assignee_ids = set(new_assignee_ids) - set(prev_assignee_ids)
|
||||
removed_assignee_ids = set(prev_assignee_ids) - set(new_assignee_ids)
|
||||
added_assignees = Employee.objects.filter(id__in=added_assignee_ids)
|
||||
removed_assignees = Employee.objects.filter(id__in=removed_assignee_ids)
|
||||
|
||||
form.save()
|
||||
|
||||
mail_thread = AddAssigneeThread(
|
||||
request,
|
||||
ticket,
|
||||
added_assignees,
|
||||
)
|
||||
mail_thread.start()
|
||||
mail_thread = RemoveAssigneeThread(
|
||||
request,
|
||||
ticket,
|
||||
removed_assignees,
|
||||
)
|
||||
mail_thread.start()
|
||||
|
||||
messages.success(request, _("Assinees updated for the Ticket"))
|
||||
|
||||
return redirect(ticket_detail, ticket_id=ticket_id)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"helpdesk/ticket/forms/change_assinees.html",
|
||||
{"form": form, "ticket_id": ticket_id},
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@@ -984,6 +1130,41 @@ def remove_tag(request):
|
||||
return JsonResponse({"message": message, "type": type})
|
||||
|
||||
|
||||
@login_required
|
||||
@hx_request_required
|
||||
def view_ticket_document(request, doc_id):
|
||||
"""
|
||||
This function used to view the uploaded document in the modal.
|
||||
Parameters:
|
||||
|
||||
request (HttpRequest): The HTTP request object.
|
||||
id (int): The id of the document.
|
||||
|
||||
Returns: return view_file template
|
||||
"""
|
||||
|
||||
document_obj = Attachment.objects.filter(id=doc_id).first()
|
||||
context = {
|
||||
"document": document_obj,
|
||||
}
|
||||
if document_obj.file:
|
||||
file_path = document_obj.file.path
|
||||
file_extension = os.path.splitext(file_path)[1][
|
||||
1:
|
||||
].lower() # Get the lowercase file extension
|
||||
content_type = get_content_type(file_extension)
|
||||
try:
|
||||
with open(file_path, "rb") as file:
|
||||
file_content = file.read() # Decode the binary content for display
|
||||
except:
|
||||
file_content = None
|
||||
|
||||
context["file_content"] = file_content
|
||||
context["file_extension"] = file_extension
|
||||
context["content_type"] = content_type
|
||||
return render(request, "helpdesk/ticket/ticket_document.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
def comment_create(request, ticket_id):
|
||||
""" "
|
||||
@@ -1030,14 +1211,14 @@ def comment_edit(request):
|
||||
|
||||
@login_required
|
||||
def comment_delete(request, comment_id):
|
||||
comment = Comment.objects.filter(id=comment_id)
|
||||
comment = Comment.objects.filter(id=comment_id).first()
|
||||
employee = comment.employee_id
|
||||
if not request.user.has_perm("helpdesk.delete_comment"):
|
||||
comment = comment.filter(employee_id__employee_user_id=request.user)
|
||||
comment.delete()
|
||||
messages.success(
|
||||
request, _('The comment "{}" has been deleted successfully.').format(comment)
|
||||
request, _("{}'s comment has been deleted successfully.").format(employee)
|
||||
)
|
||||
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
|
||||
|
||||
|
||||
@@ -1077,13 +1258,116 @@ def get_raised_on(request):
|
||||
|
||||
@login_required
|
||||
def claim_ticket(request, id):
|
||||
"""
|
||||
This is a function to create a claim request for requested employee
|
||||
"""
|
||||
ticket = Ticket.objects.get(id=id)
|
||||
if ticket.employee_id != request.user.employee_get:
|
||||
ticket.assigned_to.set([request.user.employee_get])
|
||||
ticket.save()
|
||||
if not ClaimRequest.objects.filter(
|
||||
employee_id=request.user.employee_get, ticket_id=ticket
|
||||
).exists():
|
||||
ClaimRequest(employee_id=request.user.employee_get, ticket_id=ticket).save()
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
|
||||
|
||||
|
||||
@login_required
|
||||
def approve_claim_request(request, req_id):
|
||||
"""
|
||||
Function for approve claim request and send notifications to the responsibles.
|
||||
"""
|
||||
claim_request = ClaimRequest.objects.filter(id=req_id).first()
|
||||
if not claim_request:
|
||||
return HttpResponse("Invalid claim request", status=404)
|
||||
|
||||
approve = strtobool(
|
||||
request.GET.get("approve", "False")
|
||||
) # Safely convert to boolean
|
||||
|
||||
ticket = claim_request.ticket_id
|
||||
employee = claim_request.employee_id
|
||||
refresh = False
|
||||
if approve:
|
||||
# message
|
||||
message = _("Claim request approved successfully.")
|
||||
refresh = True
|
||||
if employee not in ticket.assigned_to.all():
|
||||
ticket.assigned_to.add(employee) # Approve and assign to employee
|
||||
try:
|
||||
# send notification
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=employee.employee_user_id,
|
||||
verb=f"You have been assigned to a new Ticket-{ticket}.",
|
||||
verb_ar=f"لقد تم تعيينك لتذكرة جديدة {ticket}.",
|
||||
verb_de=f"Ihnen wurde ein neues Ticket {ticket} zugewiesen.",
|
||||
verb_es=f"Se te ha asignado un nuevo ticket {ticket}.",
|
||||
verb_fr=f"Un nouveau ticket {ticket} vous a été attribué.",
|
||||
icon="infinite",
|
||||
redirect=reverse("ticket-detail", kwargs={"ticket_id": ticket.id}),
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
if not ticket.employee_id == ticket.created_by.employee_get:
|
||||
for emp in [ticket.created_by.employee_get, ticket.employee_id]:
|
||||
try:
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=emp.employee_user_id,
|
||||
verb=f"{employee} assigned to your ticket - {ticket}.",
|
||||
verb_ar=f"تم تعيين {employee} إلى تذكرتك - {ticket}.",
|
||||
verb_de=f"{employee} wurde Ihrem Ticket {ticket} zugewiesen.",
|
||||
verb_es=f"{employee} ha sido asignado a tu ticket - {ticket}.",
|
||||
verb_fr=f"{employee} a été assigné à votre ticket - {ticket}.",
|
||||
icon="infinite",
|
||||
redirect=reverse(
|
||||
"ticket-detail", kwargs={"ticket_id": ticket.id}
|
||||
),
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
try:
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=ticket.employee_id.employee_user_id,
|
||||
verb=f"{employee} assigned to your ticket - {ticket}.",
|
||||
verb_ar=f"تم تعيين {employee} إلى تذكرتك - {ticket}.",
|
||||
verb_de=f"{employee} wurde Ihrem Ticket {ticket} zugewiesen.",
|
||||
verb_es=f"{employee} ha sido asignado a tu ticket - {ticket}.",
|
||||
verb_fr=f"{employee} a été assigné à votre ticket - {ticket}.",
|
||||
icon="infinite",
|
||||
redirect=reverse("ticket-detail", kwargs={"ticket_id": ticket.id}),
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
else:
|
||||
# message
|
||||
message = _("Claim request rejected successfully.")
|
||||
refresh = True
|
||||
if employee in ticket.assigned_to.all():
|
||||
ticket.assigned_to.remove(employee) # Reject and remove from assignment
|
||||
|
||||
# send notification
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=employee.employee_user_id,
|
||||
verb=f"Your claim request is rejected for Ticket-{ticket}",
|
||||
verb_ar=f"تم رفض طلبك للمطالبة بالتذكرة {ticket}.",
|
||||
verb_de=f"Ihre Anspruchsanfrage für Ticket-{ticket} wurde abgelehnt.",
|
||||
verb_es=f"Tu solicitud de reclamación ha sido rechazada para el ticket {ticket}.",
|
||||
verb_fr=f"Votre demande de réclamation pour le ticket {ticket} a été rejetée.",
|
||||
icon="infinite",
|
||||
)
|
||||
ticket.save()
|
||||
claim_request.is_approved = approve
|
||||
claim_request.is_rejected = not approve
|
||||
claim_request.save()
|
||||
html = render_to_string(
|
||||
"helpdesk/ticket/ticket_claim_requests.html",
|
||||
{"claim_requests": ticket.claimrequest_set.all(), "refresh": refresh},
|
||||
)
|
||||
messages.success(request, message)
|
||||
return HttpResponse(html)
|
||||
|
||||
|
||||
@login_required
|
||||
def tickets_select_filter(request):
|
||||
"""
|
||||
@@ -1142,7 +1426,7 @@ def tickets_bulk_archive(request):
|
||||
|
||||
|
||||
@login_required
|
||||
# @ticket_owner_can_enter("perms.helpdesk.helpdesk_changeticket", Ticket)
|
||||
# @ticket_owner_can_enter("perms.helpdesk.helpdesk_change_ticket", Ticket)
|
||||
@permission_required("helpdesk.delete_ticket")
|
||||
def tickets_bulk_delete(request):
|
||||
"""
|
||||
@@ -1246,7 +1530,7 @@ def update_department_manager(request, dep_id):
|
||||
def delete_department_manager(request, dep_id):
|
||||
department_manager = DepartmentManager.objects.get(id=dep_id)
|
||||
department_manager.delete()
|
||||
messages.error(request, _("The department manager has been deleted successfully"))
|
||||
messages.success(request, _("The department manager has been deleted successfully"))
|
||||
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
|
||||
|
||||
@@ -1257,18 +1541,36 @@ def update_priority(request, ticket_id):
|
||||
This function is used to update the priority
|
||||
from the detailed view
|
||||
"""
|
||||
ti = Ticket.objects.get(id=ticket_id)
|
||||
rating = request.POST.get("rating")
|
||||
ticket = Ticket.objects.get(id=ticket_id)
|
||||
if (
|
||||
request.user.has_perm("helpdesk.view_ticket")
|
||||
or ticket.employee_id.get_reporting_manager() == request.user.employee_get
|
||||
or is_department_manager(request, ticket)
|
||||
or request.user.employee_get == ticket.employee_id
|
||||
or request.user.employee_get in ticket.assigned_to.all()
|
||||
):
|
||||
rating = request.POST.get("rating")
|
||||
|
||||
if rating == "1":
|
||||
ti.priority = "low"
|
||||
elif rating == "2":
|
||||
ti.priority = "medium"
|
||||
if rating == "1":
|
||||
ticket.priority = "low"
|
||||
elif rating == "2":
|
||||
ticket.priority = "medium"
|
||||
else:
|
||||
ticket.priority = "high"
|
||||
ticket.save()
|
||||
messages.success(request, _("Priority updated successfully."))
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
|
||||
else:
|
||||
ti.priority = "high"
|
||||
ti.save()
|
||||
messages.success(request, _("Priority updated successfully."))
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
|
||||
messages.info(request, _("You don't have permission."))
|
||||
previous_url = request.META.get("HTTP_REFERER", "/")
|
||||
|
||||
# Handle request for HTMX if needed
|
||||
if "HTTP_HX_REQUEST" in request.META:
|
||||
return render(request, "decorator_404.html")
|
||||
else:
|
||||
return HttpResponse(
|
||||
f'<script>window.location.href = "{previous_url}"</script>'
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@@ -1356,6 +1658,7 @@ def ticket_type_delete(request, t_type_id):
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required("helpdesk.view_departmentmanager")
|
||||
def view_department_managers(request):
|
||||
department_managers = DepartmentManager.objects.all()
|
||||
|
||||
@@ -1363,3 +1666,26 @@ def view_department_managers(request):
|
||||
"department_managers": department_managers,
|
||||
}
|
||||
return render(request, "department_managers/department_managers.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required("helpdesk.change_departmentmanager")
|
||||
def get_department_employees(request):
|
||||
"""
|
||||
Method to return employee in the department
|
||||
"""
|
||||
department = (
|
||||
Department.objects.filter(id=request.GET.get("dep_id")).first()
|
||||
if request.GET.get("dep_id")
|
||||
else None
|
||||
)
|
||||
if department:
|
||||
employees_queryset = department.employeeworkinformation_set.all().values_list(
|
||||
"employee_id__id", "employee_id__employee_first_name"
|
||||
)
|
||||
else:
|
||||
employees_queryset = None
|
||||
employees = list(employees_queryset)
|
||||
context = {"employees": employees}
|
||||
employee_html = render_to_string("employee/employees_select.html", context)
|
||||
return HttpResponse(employee_html)
|
||||
|
||||
Reference in New Issue
Block a user