Browse Source

ShariX Open Tickets v.1.10

- Added display of status names instead of codes
- Fixed identifiers and names of initialized lists
- Fixies and improvements in design and layouts
TonyKurts 1 year ago
parent
commit
f978d2e69d

+ 68 - 5
models/ticket.py

@@ -8,14 +8,74 @@ from tickets.models.ticket_list import TicketList
 
 class Ticket(models.Model):
     TICKET_TYPES = (
-        (1, "ST_REQUEST", [[111, 121, 149, 159], [110, 121, 149, 159], [121, 131, 149, 159], [131, 141, 149], [141, 151, 110], [149, 151, 110], [159], [151]]),
-        (2, "SERVICE_REQUEST", [[210, 211, 251], [211, 212, 220, 238, 249], [212, 221, 229, 238, 249], [221, 222, 238, 249], [220, 211, 238, 249], [229, 211, 251], [222, 231, 238, 249], [231, 241, 238, 249], [238, 231, 239, 211, 212, 221, 220, 222, 249], [239, 231, 239, 211, 212, 221, 220, 222, 249], [241, 251], [249, 251], [251]]),
-        (3, "ACCESS_REQUEST", [[320, 321, 359], [321], [359]]),
-        (4, "NEG_REQUEST", [[420, 421, 459], [421], [459]])
+        (1,"ST_REQUEST", [
+            [111, 121, 149, 159],
+            [110, 121, 149, 159],
+            [121, 131, 149, 159],
+            [131, 141, 149],
+            [141, 151, 110],
+            [149, 151, 110],
+            [159],
+            [151]
+        ]),
+        (2, "SERVICE_REQUEST", [
+            [210, 211, 251],
+            [211, 212, 220, 238, 249],
+            [212, 221, 229, 238, 249],
+            [221, 222, 238, 249],
+            [220, 211, 238, 249],
+            [229, 211, 251],
+            [222, 231, 238, 249],
+            [231, 241, 238, 249],
+            [238, 231, 239, 211, 212, 221, 220, 222, 249],
+            [239, 231, 239, 211, 212, 221, 220, 222, 249],
+            [241, 251],
+            [249, 251],
+            [251]
+        ]),
+        (3, "ACCESS_REQUEST", [
+            [320, 321, 359],
+            [321],
+            [359]
+        ]),
+        (4, "NEG_REQUEST", [
+            [420, 421, 459],
+            [421],
+            [459]
+        ])
     )
 
-    TICKET_TYPES_CHOICES = tuple((item[0], item[1]) for item in TICKET_TYPES)
+    TICKET_STATUSES_NAMES = {
+        111: "NEW",
+        110: "REOPENED",
+        121: "ASSIGNED",
+        131: "IN PROCESS",
+        149: "WONTFIX",
+        141: "DONE",
+        159: "DUPLICATE",
+        151: "CLOSED",
+        210: "TEMPLATE",
+        211: "BOOKED",
+        212: "ASSIGNED",
+        221: "ACCEPTED",
+        220: "PENDING",
+        229: "DECLINED",
+        222: "PRE-START",
+        231: "PROCESS",
+        238: "PRE-FORCEMAJEUER",
+        239: "FORCEMAJEUER",
+        241: "DONE",
+        249: "CANCELLED",
+        251: "CLOSED",
+        320: "PENDING",
+        321: "ACCEPTED",
+        359: "DECLINED",
+        420: "PENDING",
+        421: "ACCEPTED",
+        459: "DECLINED"
+    }
 
+    TICKET_TYPES_CHOICES = tuple((item[0], item[1]) for item in TICKET_TYPES)
     LIFE_CYCLE_DICT = dict((item[0], item[2]) for item in TICKET_TYPES)
     TICKET_TYPES_DICT = dict(TICKET_TYPES_CHOICES)
 
@@ -45,6 +105,9 @@ class Ticket(models.Model):
     def set_first_status(self):
         self.status = self._get_statuses()[0][0]
 
+    def get_status_display(self):
+        return self.TICKET_STATUSES_NAMES.get(self.status)
+
     def save(self, *args, **kwargs):
         if not self.status:
             self.set_first_status()

+ 37 - 22
signals.py

@@ -8,25 +8,40 @@ from tickets.models import TicketList
 @receiver(post_migrate)
 def create_initial_ticket_lists(sender, **kwargs):
     if sender.name == 'tickets':
-        TicketList.objects.get_or_create(pk=100, name='MS-ADMIN активация партнеров NEG_REQUEST', group=Group.objects.get(name='METASERVICE-ADMIN'))
-        TicketList.objects.get_or_create(pk=101, name='MS-ADMIN права в сервисе ACCESS_REQUEST', group=Group.objects.get(name='METASERVICE-ADMIN'))
-        TicketList.objects.get_or_create(pk=102, name='MS-ADMIN проверка документов ST_REQUEST', group=Group.objects.get(name='METASERVICE-ADMIN'))
-        TicketList.objects.get_or_create(pk=103, name='MS-SUPER активность пользователей ST_REQUEST', group=Group.objects.get(name='METASERVICE-SUPERVISOR'))
-        TicketList.objects.get_or_create(pk=104, name='MS-SUPER оперативный доступ ST_REQUEST', group=Group.objects.get(name='METASERVICE-SUPERVISOR'))
-        TicketList.objects.get_or_create(pk=106, name='MS-SUPER опер доступ экстра ACCESS_REQUEST', group=Group.objects.get(name='METASERVICE-SUPERVISOR'))
-        TicketList.objects.get_or_create(pk=107, name='MS-SUPER права сервиса ST_REQUEST', group=Group.objects.get(name='METASERVICE-SUPERVISOR'))
-        TicketList.objects.get_or_create(pk=108, name='MS-SUPER проверка документов ST_REQUEST', group=Group.objects.get(name='METASERVICE-SUPERVISOR'))
-        TicketList.objects.get_or_create(pk=109, name='MS-SUP входящие обычные заявки ST_REQUEST', group=Group.objects.get(name='METASERVICE-SUPPORT'))
-        TicketList.objects.get_or_create(pk=110, name='MS-SUP заявки на услуги сервиса SERVICE_REQUEST', group=Group.objects.get(name='METASERVICE-SUPPORT'))
-        TicketList.objects.get_or_create(pk=111, name='MS-TSUP входящие тех заявки ST_REQUEST', group=Group.objects.get(name='METASERVICE-TECHSUPPORT'))
-        TicketList.objects.get_or_create(pk=112, name='P-ADMIN документы исполнителей ST_REQUEST', group=Group.objects.get(name='PARTNER-ADMIN'))
-        TicketList.objects.get_or_create(pk=113, name='P-ADMIN документы ресурсов ST_REQUEST', group=Group.objects.get(name='PARTNER-ADMIN'))
-        TicketList.objects.get_or_create(pk=114, name='P-ADMIN права в партнерке ACCESS_REQUEST', group=Group.objects.get(name='PARTNER-ADMIN'))
-        TicketList.objects.get_or_create(pk=115, name='P-SUPER активность внутри партнера ST_REQUEST', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
-        TicketList.objects.get_or_create(pk=116, name='P-SUPER документы исполнителей ST_REQUEST', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
-        TicketList.objects.get_or_create(pk=117, name='P-SUPER документы ресурсов ST_REQUEST', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
-        TicketList.objects.get_or_create(pk=118, name='P-SUPER доступ внутри партнера ST_REQUEST', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
-        TicketList.objects.get_or_create(pk=119, name='P-SUPER оперативный доступ ST_REQUEST', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
-        TicketList.objects.get_or_create(pk=120, name='P-SUPER оперативный доступ экстра ST_REQUEST', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
-        TicketList.objects.get_or_create(pk=121, name='P-SUPER ручной аппрув заявок ACCESS-REQUEST', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
-        TicketList.objects.get_or_create(pk=122, name='P-TSUP входящие тех заявки ST_REQUEST', group=Group.objects.get(name='PARTNER-TECHSUPPORT'))
+        # METASERVICE
+        ## ADMIN
+        TicketList.objects.get_or_create(pk=111, name='Активация партнеров (NEG_REQUEST)', group=Group.objects.get(name='METASERVICE-ADMIN'))
+        TicketList.objects.get_or_create(pk=112, name='Права в сервисе (ACCESS_REQUEST)', group=Group.objects.get(name='METASERVICE-ADMIN'))
+        TicketList.objects.get_or_create(pk=113, name='Проверка документов (ST_REQUEST)', group=Group.objects.get(name='METASERVICE-ADMIN'))
+
+        ## SUPERVISOR
+        TicketList.objects.get_or_create(pk=121, name='Активность пользователей (ST_REQUEST)', group=Group.objects.get(name='METASERVICE-SUPERVISOR'))
+        TicketList.objects.get_or_create(pk=122, name='Оперативный доступ (ST_REQUEST)', group=Group.objects.get(name='METASERVICE-SUPERVISOR'))
+        TicketList.objects.get_or_create(pk=123, name='Оперативный доступ экстра (ACCESS_REQUEST)', group=Group.objects.get(name='METASERVICE-SUPERVISOR'))
+        TicketList.objects.get_or_create(pk=124, name='Права сервиса (ST_REQUEST)', group=Group.objects.get(name='METASERVICE-SUPERVISOR'))
+        TicketList.objects.get_or_create(pk=125, name='Проверка документов (ST_REQUEST)', group=Group.objects.get(name='METASERVICE-SUPERVISOR'))
+
+        ## SUPPORT
+        TicketList.objects.get_or_create(pk=131, name='Входящие обычные заявки (ST_REQUEST)', group=Group.objects.get(name='METASERVICE-SUPPORT'))
+        TicketList.objects.get_or_create(pk=132, name='Заявки на услуги сервиса (SERVICE_REQUEST)', group=Group.objects.get(name='METASERVICE-SUPPORT'))
+
+        ## TECHSUPPORT
+        TicketList.objects.get_or_create(pk=141, name='Входящие технические заявки (ST_REQUEST)', group=Group.objects.get(name='METASERVICE-TECHSUPPORT'))
+
+        # PARTNER
+        ## ADMIN
+        TicketList.objects.get_or_create(pk=211, name='Документы исполнителей (ST_REQUEST)', group=Group.objects.get(name='PARTNER-ADMIN'))
+        TicketList.objects.get_or_create(pk=212, name='Документы ресурсов (ST_REQUEST)', group=Group.objects.get(name='PARTNER-ADMIN'))
+        TicketList.objects.get_or_create(pk=213, name='Права в партнерке (ACCESS_REQUEST)', group=Group.objects.get(name='PARTNER-ADMIN'))
+        
+        ## SUPERVISOR
+        TicketList.objects.get_or_create(pk=221, name='Активность внутри партнера (ST_REQUEST)', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
+        TicketList.objects.get_or_create(pk=222, name='Документы исполнителей (ST_REQUEST)', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
+        TicketList.objects.get_or_create(pk=223, name='Документы ресурсов (ST_REQUEST)', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
+        TicketList.objects.get_or_create(pk=224, name='Доступ внутри партнера (ST_REQUEST)', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
+        TicketList.objects.get_or_create(pk=225, name='Оперативный доступ (ST_REQUEST)', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
+        TicketList.objects.get_or_create(pk=226, name='Оперативный доступ экстра (ST_REQUEST)', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
+        TicketList.objects.get_or_create(pk=227, name='Ручное подтверждение заявок (ACCESS-REQUEST)', group=Group.objects.get(name='PARTNER-SUPERVISOR'))
+        
+        ## TECHSUPPORT
+        TicketList.objects.get_or_create(pk=241, name='Входящие технические заявки (ST_REQUEST)', group=Group.objects.get(name='PARTNER-TECHSUPPORT'))

+ 3 - 3
templates/tickets/ticket_detail.html

@@ -6,7 +6,7 @@
     <div class="col-12 col-md-8 mb-2 mb-md-0">
       <div class="card h-100">
         <div class="card-body">
-          <h3 class="card-title">{{ ticket.title }}</h3>
+          <h3 class="card-title fw-bold">{{ ticket.title }}</h3>
             {% if ticket.note %}
               <div class="card-text overflow-auto">{{ ticket.note|safe|urlize|linebreaks }}</div>
             {% endif %}
@@ -36,7 +36,7 @@
           </li>
           <li class="list-group-item">
             <strong>Status:</strong>
-            {{ ticket.status }}
+            {{ ticket.get_status_display }}
           </li>
           <li class="list-group-item">
             <strong>Priority:</strong>
@@ -65,7 +65,7 @@
           <div class="input-group">
             <select class="form-select" id="select-ticket-status" name="ticket-status">
               {% for status in available_statuses %}
-                <option {% if forloop.first %}selected{% endif %} value="{{ status }}">{{ status }}</option>
+                <option {% if forloop.first %}selected{% endif %} value="{{ status.0 }}">{{ status.1 }}</option>
               {% endfor %}
             </select>
             

+ 56 - 52
templates/tickets/ticket_list_detail.html

@@ -7,7 +7,7 @@
   {% elif assignments %}
     <h1>Assignments (in all groups)</h1>
   {% else %}
-    <h1>{{ ticket_list.group }} > {{ ticket_list.name }}</h1>
+    <h1 class="mb-4">{{ ticket_list.group }} > <b>{{ ticket_list.name }}</b></h1>
     
     <div class="d-flex justify-content-between">
       <button type="button" data-bs-toggle="modal" data-bs-target="#ticket-create-modal" class="btn btn-primary">
@@ -84,59 +84,63 @@
   
   <hr>
   {% if tickets %} 
-    {% for ticket_type in ticket_types %}
-      <input type="radio" class="btn-check ticket_type-filter" name="btnradio" id="{{ ticket_type }}-radio">
-      <label class="btn btn-outline-secondary" for="{{ ticket_type }}-radio">
-        {{ ticket_type }}
-      </label>
-    {% endfor %}
+    <div class="d-flex flex-wrap gap-1">
+      {% for ticket_type in ticket_types %}
+        <input type="radio" class="btn-check ticket_type-filter" name="btnradio" id="{{ ticket_type }}-radio">
+        <label class="btn btn-outline-secondary" for="{{ ticket_type }}-radio">
+          {{ ticket_type }}
+        </label>
+      {% endfor %}
+    </div>
     <hr>
-
-    <table class="table" id="tickettable">
-      <thead>
-        <tr class="nodrop">
-          <th>ID</th>
-          <th>Title</th>
-          <th>Created at</th>
-          <th>Due on</th>
-          <th>Owner</th>
-          <th>Assigned</th>
-          <th>Status</th>
-          <th>Priority</th>
-        </tr>
-      </thead>
-
-      <tbody>
-        {% for ticket in tickets %}
-          <tr class="ticket" id="{{ ticket.pk }}" data-ticket-type="{{ ticket.get_ticket_type_display }}">
-            <td>
-              {{ ticket.pk }}
-            </td>
-            <td>
-              <a href="{% url 'tickets:ticket_detail' ticket.pk %}">{{ ticket.title|truncatewords:10 }}</a>
-            </td>
-            <td>
-                {{ ticket.created_at }}
-            </td>
-            <td>
-                {{ ticket.due_date }}
-            </td>
-            <td>
-              {{ ticket.created_by_username }}
-            </td>
-            <td>
-              {% if ticket.assigned_to_username %}{{ ticket.assigned_to_username }}{% else %}Anyone{% endif %}
-            </td>
-            <td>
-              {{ ticket.status }}
-            </td>
-            <td>
-              {{ ticket.priority }}
-            </td>
+    
+    <div class="overflow-x-scroll">
+      <table class="table" id="tickettable">
+        <thead>
+          <tr class="nodrop">
+            <th>ID</th>
+            <th>Title</th>
+            <th class="text-nowrap">Created at</th>
+            <th class="text-nowrap">Due on</th>
+            <th>Owner</th>
+            <th>Assigned</th>
+            <th>Status</th>
+            <th>Priority</th>
           </tr>
-        {% endfor %}
-      </tbody>
-    </table>
+        </thead>
+
+        <tbody>
+          {% for ticket in tickets %}
+            <tr class="ticket" id="{{ ticket.pk }}" data-ticket-type="{{ ticket.get_ticket_type_display }}">
+              <td>
+                {{ ticket.pk }}
+              </td>
+              <td>
+                <a href="{% url 'tickets:ticket_detail' ticket.pk %}">{{ ticket.title|truncatewords:10 }}</a>
+              </td>
+              <td>
+                  {{ ticket.created_at }}
+              </td>
+              <td>
+                  {{ ticket.due_date }}
+              </td>
+              <td>
+                {{ ticket.created_by_username }}
+              </td>
+              <td>
+                {% if ticket.assigned_to_username %}{{ ticket.assigned_to_username }}{% else %}Anyone{% endif %}
+              </td>
+              <td>
+                {{ ticket.get_status_display }}
+              </td>
+              <td>
+                {{ ticket.priority }}
+              </td>
+            </tr>
+          {% endfor %}
+        </tbody>
+      </table>
+    </div>
     
   {% else %}
     <h4>There are no Tickets!</h4>

+ 1 - 1
templates/tickets/ticket_list_list.html

@@ -1,7 +1,7 @@
 {% extends "tickets/base.html" %}
 
 {% block content %}
-  <h1>Lists</h1>
+  <h1 class="fw-bold mb-4">Lists</h1>
 
   {% if user.is_staff or user.is_superuser %}
     <button type="button" data-bs-toggle="modal" data-bs-target="#ticket_list-create-modal" class="btn btn-primary">

+ 10 - 1
views/ticket_detail.py

@@ -29,7 +29,16 @@ class TicketDetailView(LoginRequiredMixin, UserCanReadTicketMixin, DetailView):
             author_username=F("author__username"), author_email=F("author__email")
         )
         context['attachments'] = Attachment.objects.filter(ticket=self.object.pk).select_related("added_by")
-        context['available_statuses'] = self.object.get_available_statuses()
+        
+        # List with statuses codes & their names
+        available_statuses_with_names = []
+        available_statuses = self.object.get_available_statuses()
+        if available_statuses:
+            for status_code in available_statuses:
+                status_name = Ticket.TICKET_STATUSES_NAMES.get(status_code)
+                available_statuses_with_names.append([status_code, status_name])
+        context["available_statuses"] = available_statuses_with_names
+
         return context
 
     def post(self, request, *args, **kwargs):