tangled
alpha
login
or
join now
aottr.dev
/
paw
0
fork
atom
Free and open source ticket system written in python
0
fork
atom
overview
issues
pulls
pipelines
Allow ReadOnly-Roles
Dustin Kroeger
2 years ago
fa7326a1
44e56637
+36
-10
4 changed files
expand all
collapse all
unified
split
paw
templates
ticketing
ticket_detail.html
ticketing
migrations
0014_team_readonly_access.py
models.py
views.py
+8
-8
paw/templates/ticketing/ticket_detail.html
···
36
36
<h1 class="text-xl font-bold my-4">{% trans 'Activity' %}</h1>
37
37
<div class="mb-4">
38
38
{% for comment in comments %}
39
39
-
{% if not comment.is_only_for_staff or comment.is_only_for_staff and request.user.is_staff %}
39
39
+
{% if not comment.is_only_for_staff or comment.is_only_for_staff and can_edit %}
40
40
{% if comment.user == request.user %}
41
41
<div class="chat chat-start">
42
42
{% else %}
···
62
62
</div>
63
63
<div class="mb-10">
64
64
{% if ticket.status != 'closed' %}
65
65
-
{% if request.user.is_staff %}
65
65
+
{% if can_edit %}
66
66
<form action="" method="post">
67
67
{% csrf_token %}
68
68
<div class="flex justify-end items-center mt-4 mb-2">
···
88
88
</div>
89
89
<div class="grow"></div>
90
90
<button type="submit" name="submit" class="btn btn-success">{% trans 'Add Comment' %}</button>
91
91
-
{% if request.user.is_staff %}
91
91
+
{% if can_edit %}
92
92
<button type="submit" name="close" class="btn btn-error ml-4">{% trans 'Close Ticket' %}</button>
93
93
{% endif %}
94
94
</div>
···
106
106
</form>
107
107
{% else %}
108
108
<div class="divider">{% trans 'Ticket has been closed' %}</div>
109
109
-
{% if request.user.is_staff and ticket.status == 'closed' %}
109
109
+
{% if can_edit and ticket.status == 'closed' %}
110
110
<div class="flex justify-end items-center mt-4">
111
111
<form method="post">
112
112
{% csrf_token %}
113
113
<button class="btn btn-warning ml-2" name="reopen_ticket">{% trans 'Re-Open Ticket' %}</button>
114
114
</form>
115
115
</div>
116
116
-
{% endif %} {% comment %} request.user.is_staff and ticket.status == 'closed' {% endcomment %}
116
116
+
{% endif %} {% comment %} can_edit and ticket.status == 'closed' {% endcomment %}
117
117
{% endif %}
118
118
</div>
119
119
</div>
···
162
162
<span>{% trans 'General' %}</span>
163
163
{% endif %}
164
164
</div>
165
165
-
{% if request.user.is_staff %}
165
165
+
{% if can_edit %}
166
166
<form action="" method="post">
167
167
{% csrf_token %}
168
168
<h2 class="font-semibold text-xs mb-2">{% trans 'Assign to new category' %}</h2>
···
177
177
<div class="text-base-content/85 flex items-center text-sm mb-4">
178
178
<svg xmlns="http://www.w3.org/2000/svg" class="mr-2 w-6 h-6" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0" /><path d="M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2" /></svg>
179
179
{% include 'partials/assigned_to.html' with assigned_to=ticket.assigned_to %}
180
180
-
{% if request.user.is_staff and ticket.assigned_to != request.user %}
180
180
+
{% if can_edit and ticket.assigned_to != request.user %}
181
181
<form method="post">
182
182
{% csrf_token %}
183
183
<button class="btn btn-xs btn-neutral ml-2" name="assign_self">{% trans 'Assign to me' %}</button>
···
192
192
<span class="italic">{% trans 'Unassigned' %}</span>
193
193
{% endif %}
194
194
</div>
195
195
-
{% if request.user.is_staff %}
195
195
+
{% if can_edit %}
196
196
<form action="" method="post">
197
197
{% csrf_token %}
198
198
<h2 class="font-semibold text-xs mb-2">{% trans 'Assign to new team' %}</h2>
+18
ticketing/migrations/0014_team_readonly_access.py
···
1
1
+
# Generated by Django 5.0.3 on 2024-03-24 18:30
2
2
+
3
3
+
from django.db import migrations, models
4
4
+
5
5
+
6
6
+
class Migration(migrations.Migration):
7
7
+
8
8
+
dependencies = [
9
9
+
("ticketing", "0013_team_access_non_category_tickets"),
10
10
+
]
11
11
+
12
12
+
operations = [
13
13
+
migrations.AddField(
14
14
+
model_name="team",
15
15
+
name="readonly_access",
16
16
+
field=models.BooleanField(default=False),
17
17
+
),
18
18
+
]
+8
-1
ticketing/models.py
···
19
19
description = models.TextField(blank=True)
20
20
members = models.ManyToManyField(PawUser)
21
21
access_non_category_tickets = models.BooleanField(default=False)
22
22
+
readonly_access = models.BooleanField(default=False)
22
23
23
24
def __str__(self):
24
25
return self.name
···
102
103
return cls._get_tickets(user).filter(status=cls.Status.CLOSED)
103
104
104
105
def can_open(self, user):
105
105
-
return self in Ticket._get_tickets(user)
106
106
+
return self.user == user or self.assigned_to == user or self.assigned_team in user.team_set.all() or self.assigned_team is None and user.team_set.filter(access_non_category_tickets=True).exists()
107
107
+
108
108
+
def can_edit(self, user):
109
109
+
assigned_and_write_access = self.assigned_team in user.team_set.filter(readonly_access=False)
110
110
+
unassigned_and_write_access = self.assigned_team is None and user.team_set.filter(access_non_category_tickets=True, readonly_access=False).exists()
111
111
+
print(assigned_and_write_access, unassigned_and_write_access)
112
112
+
return self.can_open(user) and (assigned_and_write_access or unassigned_and_write_access)
106
113
107
114
108
115
def close_ticket(self):
+2
-1
ticketing/views.py
···
76
76
context = {
77
77
"ticket": ticket, "comments": comments, "attachments": [attachment.file for attachment in ticket.fileattachment_set.all()],
78
78
"form": form, "template_form": template_form,
79
79
-
"team_assignment_form": team_assignment_form, "category_assignment_form": category_assignment_form
79
79
+
"team_assignment_form": team_assignment_form, "category_assignment_form": category_assignment_form,
80
80
+
"can_edit": ticket.can_edit(request.user)
80
81
}
81
82
return render(request, "ticketing/ticket_detail.html", context)
82
83