From 8697b61c01a327e45f761b6a960cf24b5b6537a8 Mon Sep 17 00:00:00 2001 From: Horilla Date: Wed, 31 Jan 2024 16:25:07 +0530 Subject: [PATCH] [UPDT] HELPDESK: Dynamic creation in ticket form --- helpdesk/forms.py | 32 ++-- helpdesk/models.py | 14 +- .../helpdesk/ticket/ticket_card.html | 75 ++-------- .../helpdesk/ticket/ticket_detail.html | 26 +++- .../helpdesk/ticket/ticket_form.html | 129 +++++++++++++++- .../helpdesk/ticket/ticket_group.html | 135 +++++++++-------- .../helpdesk/ticket/ticket_list.html | 139 +++++++++--------- .../helpdesk/ticket/ticket_view.html | 53 ++++++- helpdesk/views.py | 25 +++- static/images/ui/orange_star.png | Bin 0 -> 13063 bytes static/images/ui/star.png | Bin 0 -> 14522 bytes 11 files changed, 387 insertions(+), 241 deletions(-) create mode 100644 static/images/ui/orange_star.png create mode 100644 static/images/ui/star.png diff --git a/helpdesk/forms.py b/helpdesk/forms.py index bf482344c..79bace94c 100644 --- a/helpdesk/forms.py +++ b/helpdesk/forms.py @@ -20,8 +20,10 @@ class YourForm(forms.Form): # Custom validation logic goes here pass """ +from typing import Any from base.forms import ModelForm from base.models import Department, JobPosition +from employee.forms import MultipleFileField from employee.models import Employee from helpdesk.models import Attachment, DepartmentManager, TicketType, FAQ,Ticket, FAQCategory, Comment from django import forms @@ -73,27 +75,15 @@ class TicketForm(ModelForm): context = {"form": self} table_html = render_to_string("attendance_form.html", context) return table_html - -# def get_updated_choices(assigning_type): -# new_choices =[ -# ('', '---------'), -# ] -# if assigning_type: -# if assigning_type == 'department': -# # Retrieve data from the Department model and format it as a list of dictionaries -# departments = Department.objects.values('id', 'department') -# raised_on = [{'id': dept['id'], 'name': dept['department']} for dept in departments] -# elif assigning_type == 'job_position': -# jobpositions = JobPosition.objects.values('id','job_position') -# raised_on = [{'id': job['id'], 'name': job['job_position']} for job in jobpositions] -# elif assigning_type == 'individual': -# employees = Employee.objects.values('id','employee_first_name','employee_last_name') -# raised_on = [{'id': employee['id'], 'name': f"{employee['employee_first_name']} {employee['employee_last_name']}"} for employee in employees] - -# new_choices = [ -# (choice['id'], choice['name']) for choice in raised_on -# ] -# return new_choices + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields["attachment"] = MultipleFileField( + label="Attachements", required=False + ) + self.fields["tags"].choices = list(self.fields["tags"].choices) + self.fields["tags"].choices.append(("create_new_tag", "Create new tag")) + self.fields["ticket_type"].choices = list(self.fields["ticket_type"].choices) + self.fields["ticket_type"].choices.append(("create_new_ticket_type", "Create new ticket type")) class TicketTagForm(ModelForm): class Meta: diff --git a/helpdesk/models.py b/helpdesk/models.py index f8b631134..e0b9f1676 100644 --- a/helpdesk/models.py +++ b/helpdesk/models.py @@ -1,9 +1,10 @@ -import datetime +from datetime import datetime import os from django import apps from django.db import models +from django.forms import ValidationError from base.models import Department, JobPosition, Tags - +from django.utils.translation import gettext_lazy as _ from employee.models import Employee from base.models import Company from base.horilla_company_manager import HorillaCompanyManager @@ -93,7 +94,7 @@ class Ticket(models.Model): 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) - raised_on = models.CharField(max_length=100) + 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") @@ -108,7 +109,12 @@ class Ticket(models.Model): objects = HorillaCompanyManager( related_company_field="employee_id__employee__work_info__company_id" ) - + 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': diff --git a/helpdesk/templates/helpdesk/ticket/ticket_card.html b/helpdesk/templates/helpdesk/ticket/ticket_card.html index 249adf317..f52ab17c4 100644 --- a/helpdesk/templates/helpdesk/ticket/ticket_card.html +++ b/helpdesk/templates/helpdesk/ticket/ticket_card.html @@ -212,27 +212,10 @@ {% else %} -
-
- -

- {% trans "There are no tickets at the moment." %} -

-
-
+
+ Page not found. 404. +
{% trans "There are no tickets at the moment." %}
+
{% endif %} @@ -466,27 +449,10 @@ {% else %} -
-
- -

- {% trans "There are no tickets at the moment." %} -

-
-
+
+ Page not found. 404. +
{% trans "There are no tickets at the moment." %}
+
{% endif %} @@ -703,27 +669,10 @@ {% else %} -
-
- -

- {% trans "There are no tickets at the moment." %} -

-
-
+
+ Page not found. 404. +
{% trans "There are no tickets at the moment." %}
+
{% endif %} diff --git a/helpdesk/templates/helpdesk/ticket/ticket_detail.html b/helpdesk/templates/helpdesk/ticket/ticket_detail.html index f64f9ebfe..8b013f4b0 100644 --- a/helpdesk/templates/helpdesk/ticket/ticket_detail.html +++ b/helpdesk/templates/helpdesk/ticket/ticket_detail.html @@ -29,7 +29,13 @@

{{ticket.title}}

- {% for status in ticket_status %} @@ -273,11 +279,17 @@ {% trans "Priority" %} {% if ticket.priority == 'high' %} - + + + {% elif ticket.priority == 'medium' %} - + + + {% elif ticket.priority == 'low' %} - + + + {% endif %} @@ -311,7 +323,7 @@
- {% trans "Raised on" %} + {% trans "Forward to" %} {% if perms.helpdesk.changeticket or request.user.employee_get == ticket.employee_id %}
+ +
@@ -447,9 +461,9 @@
+ \ No newline at end of file diff --git a/helpdesk/templates/helpdesk/ticket/ticket_group.html b/helpdesk/templates/helpdesk/ticket/ticket_group.html index 5aa12ab50..0089f439f 100644 --- a/helpdesk/templates/helpdesk/ticket/ticket_group.html +++ b/helpdesk/templates/helpdesk/ticket/ticket_group.html @@ -43,16 +43,17 @@
{% trans "Title" %}
{% trans "Owner" %}
{% trans "Type" %}
-
{% trans "Raised on" %}
+
{% trans "Forward to" %}
{% trans "Assigned to" %}
{% trans "Status" %}
+
{% trans "Priority" %}
{% trans "Tags" %}
{% trans "Actions" %}
{% for ticket in my_ticket_list.list %} -
+
{{ticket.get_raised_on}}
{{ticket.assigned_to.all|join:" , "}}
{{ticket.get_status_display}}
+
+ {% if ticket.priority == 'high' %} + + + + {% elif ticket.priority == 'medium' %} + + + + {% elif ticket.priority == 'low' %} + + + + {% endif %} +
{{ticket.tags.all|join:" , "}}
@@ -201,27 +217,10 @@
{% else %} -
-
- -

- {% trans "There are no tickets at the moment." %} -

-
-
+
+ Page not found. 404. +
{% trans "There are no tickets at the moment." %}
+
{% endif %}
@@ -264,16 +263,17 @@
{% trans "Title" %}
{% trans "Owner" %}
{% trans "Type" %}
-
{% trans "Raised on" %}
+
{% trans "Forward to" %}
{% trans "Assigned to" %}
{% trans "Status" %}
+
{% trans "Priority" %}
{% trans "Tags" %}
{% trans "Actions" %}
{% for ticket in allocated_tickets_list.list %} -
+
{{ticket.get_raised_on}}
{{ticket.assigned_to.all|join:" , "}}
{{ticket.get_status_display}}
+
+ {% if ticket.priority == 'high' %} + + + + {% elif ticket.priority == 'medium' %} + + + + {% elif ticket.priority == 'low' %} + + + + {% endif %} +
{{ticket.tags.all|join:" , "}}
@@ -422,27 +437,10 @@
{% else %} -
-
- -

- {% trans "There are no tickets at the moment." %} -

-
-
+
+ Page not found. 404. +
{% trans "There are no tickets at the moment." %}
+
{% endif %}
@@ -484,16 +482,17 @@
{% trans "Title" %}
{% trans "Owner" %}
{% trans "Type" %}
-
{% trans "Raised on" %}
+
{% trans "Forward to" %}
{% trans "Assigned to" %}
{% trans "Status" %}
+
{% trans "Priority" %}
{% trans "Tags" %}
{% trans "Actions" %}
{% for ticket in all_tickets_list.list %} -
+
{{ticket.get_raised_on}}
{{ticket.assigned_to.all|join:" , "}}
{{ticket.get_status_display}}
+
+ {% if ticket.priority == 'high' %} + + + + {% elif ticket.priority == 'medium' %} + + + + {% elif ticket.priority == 'low' %} + + + + {% endif %} +
{{ticket.tags.all|join:" , "}}
@@ -642,27 +656,10 @@
{% else %} -
-
- -

- {% trans "There are no tickets at the moment." %} -

-
-
+
+ Page not found. 404. +
{% trans "There are no tickets at the moment." %}
+
{% endif %}
diff --git a/helpdesk/templates/helpdesk/ticket/ticket_list.html b/helpdesk/templates/helpdesk/ticket/ticket_list.html index e2c965ec8..4644c2270 100644 --- a/helpdesk/templates/helpdesk/ticket/ticket_list.html +++ b/helpdesk/templates/helpdesk/ticket/ticket_list.html @@ -20,21 +20,23 @@
{% trans "Title" %}
{% trans "Owner" %}
{% trans "Type" %}
-
{% trans "Raised on" %}
+
{% trans "Forward to" %}
{% trans "Assigned to" %}
{% trans "Status" %}
+
{% trans "Priority" %}
{% trans "Tags" %}
{% trans "Actions" %}
{% for ticket in my_tickets %} -
+
{{ticket.get_raised_on}}
{{ticket.assigned_to.all|join:" , "}}
{{ticket.get_status_display}}
+
+ {% if ticket.priority == 'high' %} + + + + {% elif ticket.priority == 'medium' %} + + + + {% elif ticket.priority == 'low' %} + + + + {% endif %} +
+
{{ticket.tags.all|join:" , "}}
@@ -172,27 +190,10 @@
{% else %} -
-
- -

- {% trans "There are no tickets at the moment." %} -

-
-
+
+ Page not found. 404. +
{% trans "There are no tickets at the moment." %}
+
{% endif %}
@@ -215,9 +216,10 @@
{% trans "Title" %}
{% trans "Owner" %}
{% trans "Type" %}
-
{% trans "Raised on" %}
+
{% trans "Forward to" %}
{% trans "Assigned to" %}
{% trans "Status" %}
+
{% trans "Priority" %}
{% trans "Tags" %}
{% trans "Actions" %}
@@ -225,12 +227,13 @@
{% for ticket in allocated_tickets %} -
+
{{ticket.get_raised_on}}
{{ticket.assigned_to.all|join:" , "}}
{{ticket.get_status_display}}
+
+ {% if ticket.priority == 'high' %} + + + + {% elif ticket.priority == 'medium' %} + + + + {% elif ticket.priority == 'low' %} + + + + {% endif %} +
{{ticket.tags.all|join:" , "}}
@@ -390,27 +408,10 @@
{% else %} -
-
- -

- {% trans "There are no tickets at the moment." %} -

-
-
+
+ Page not found. 404. +
{% trans "There are no tickets at the moment." %}
+
{% endif %}
@@ -433,21 +434,23 @@
{% trans "Title" %}
{% trans "Owner" %}
{% trans "Type" %}
-
{% trans "Raised on" %}
+
{% trans "Forward to" %}
{% trans "Assigned to" %}
{% trans "Status" %}
+
{% trans "Priority" %}
{% trans "Tags" %}
{% trans "Actions" %}
{% for ticket in all_tickets %} -
+
{{ticket.get_raised_on}}
{{ticket.assigned_to.all|join:" , "}}
{{ticket.get_status_display}}
+
+ {% if ticket.priority == 'high' %} + + + + {% elif ticket.priority == 'medium' %} + + + + {% elif ticket.priority == 'low' %} + + + + {% endif %} +
{{ticket.tags.all|join:" , "}}
@@ -584,27 +602,10 @@
{% else %} -
-
- -

- {% trans "There are no tickets at the moment." %} -

-
-
+
+ Page not found. 404. +
{% trans "There are no tickets at the moment." %}
+
{% endif %}
diff --git a/helpdesk/templates/helpdesk/ticket/ticket_view.html b/helpdesk/templates/helpdesk/ticket/ticket_view.html index ccab77fe5..ed752cbb0 100644 --- a/helpdesk/templates/helpdesk/ticket/ticket_view.html +++ b/helpdesk/templates/helpdesk/ticket/ticket_view.html @@ -131,7 +131,7 @@ {% trans "My Tickets" %}
  • - {% trans "Allocated Tickets" %} + {% trans "Suggested Tickets" %}
  • {% if request.user|is_reportingmanager %}
  • @@ -232,6 +232,57 @@ $(".ticket-view-type").attr("hx-vals", hxVals); }); }); + function saveTag(){ + var title=$('#id_tag_title').val() + var color = $("#id_tag_color").val() + var is_active = $("#id_tag_is_active").val() + $.ajax({ + type: "post", + url: `/helpdesk/ticket-create-tag`, + data: { + csrfmiddlewaretoken: getCookie("csrftoken"), + "title": title, + "color":color, + "is_active":is_active, + }, + success: function (response) { + if (response.errors === "no_error") { + var newOption = $('').val(response.tag_id).text(response.title) + $("#createTagModal").removeClass("oh-modal--show"); + $("#id_tags option[value='create_new_tag']").before(newOption); + $("#id_tags option[value='create_new_tag']").prop('selected',false) + {% comment %} updateTag() {% endcomment %} + } + } + }); + } + function saveTicketType(){ + var title=$('#id_ticket_type_title').val() + var type = $("#id_type").val() + var prefix = $("#id_prefix").val() + var is_active = $("#id_ticket_type_is_active").val() + $.ajax({ + type: "post", + url: "{% url 'ticket-type-create' %}?ajax=True", + data: { + csrfmiddlewaretoken: getCookie("csrftoken"), + "title": title, + "type":type, + 'prefix':prefix, + "is_active":is_active, + }, + success: function (response) { + if (response.errors === "no_error") { + var newOption = $('').val(response.ticket_id).text(response.title) + $("#createTicketTypeModal").removeClass("oh-modal--show"); + $("#id_ticket_type option[value='create_new_ticket_type']").before(newOption); + $("#id_ticket_type option[value='create_new_ticket_type']").prop('selected',false) + {% comment %} updateTag() {% endcomment %} + } + } + }); + } + {% endblock %} \ No newline at end of file diff --git a/helpdesk/views.py b/helpdesk/views.py index ee64fb4dc..b246c2768 100644 --- a/helpdesk/views.py +++ b/helpdesk/views.py @@ -9,7 +9,7 @@ from base.methods import filtersubordinates, get_key_instances, get_pagination from base.models import Department, JobPosition, Tags from employee.models import Employee from helpdesk.filter import FAQCategoryFilter, FAQFilter,TicketFilter, TicketReGroup -from helpdesk.forms import AttachmentForm, CommentForm, DepartmentManagerCreateForm, FAQCategoryForm, FAQForm,TicketForm, TicketRaisedOnForm, TicketTagForm ,TicketAssigneesForm +from helpdesk.forms import AttachmentForm, CommentForm, DepartmentManagerCreateForm, FAQCategoryForm, FAQForm,TicketForm, TicketRaisedOnForm, TicketTagForm ,TicketAssigneesForm, TicketTypeForm from django.utils.translation import gettext as _ from django.contrib import messages from django.db.models import ProtectedError @@ -402,9 +402,13 @@ def ticket_create(request): status = request.GET.get('status') form = TicketForm(initial={'status':status}) if request.method == "POST": - form = TicketForm(request.POST) - if form.is_valid(): + form = TicketForm(request.POST,request.FILES) + 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() mail_thread = TicketSendThread(request, ticket, type="create") mail_thread.start() messages.success( @@ -431,6 +435,7 @@ def ticket_create(request): return HttpResponse("") context = { 'form': form, + 't_type_form':TicketTypeForm(), } return render(request, "helpdesk/ticket/ticket_form.html", context) @@ -452,9 +457,13 @@ 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,instance=ticket) + form = TicketForm(request.POST,request.FILES,instance=ticket) if form.is_valid(): - form.save() + 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.') ) @@ -729,8 +738,11 @@ def ticket_detail(request,ticket_id,**kwargs): context=context ) @login_required -@owner_can_enter("perms.helpdesk.helpdesk_changeticket", 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[]') @@ -807,6 +819,7 @@ def create_tag(request): """ This is an ajax method to return json response to create tag in the change tag form. """ + if request.method == "POST": form = TagsForm(request.POST) diff --git a/static/images/ui/orange_star.png b/static/images/ui/orange_star.png new file mode 100644 index 0000000000000000000000000000000000000000..529d2b4fe80a916ff8b25c8bee2a8ffa6207db21 GIT binary patch literal 13063 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 literal 0 HcmV?d00001 diff --git a/static/images/ui/star.png b/static/images/ui/star.png new file mode 100644 index 0000000000000000000000000000000000000000..97b0aa893a8e31a36884c7ea7c5ba87c7ad66bea GIT binary patch literal 14522 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 J>Vn6k{{hwyMeqOs literal 0 HcmV?d00001