From f8cccbcf0aea54f74fda2b0ecce59ad5c1b85db6 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Fri, 26 Jul 2024 08:46:26 +0000 Subject: [PATCH 1/8] Display custom fields in Follow-up form --- helpdesk/forms.py | 21 +++++++++++++++++++++ helpdesk/templates/helpdesk/ticket.html | 4 ++++ helpdesk/views/staff.py | 5 +++++ 3 files changed, 30 insertions(+) diff --git a/helpdesk/forms.py b/helpdesk/forms.py index 83a3de45..3b2c3c81 100644 --- a/helpdesk/forms.py +++ b/helpdesk/forms.py @@ -180,6 +180,27 @@ class EditTicketForm(CustomFieldMixin, forms.ModelForm): return super(EditTicketForm, self).save(*args, **kwargs) +class EditTicketCustomFieldForm(EditTicketForm): + """ + Uses the EditTicketForm logic to provide a form for Ticket custom fields. + """ + + def __init__(self, *args, **kwargs): + """ + Add any custom fields that are defined to the form + """ + super(EditTicketCustomFieldForm, self).__init__(*args, **kwargs) + + del self.fields['merged_to'] + + class Meta: + model = Ticket + exclude = ('title', 'queue', 'created', 'modified', + 'submitter_email', 'assigned_to', 'status', + 'on_hold', 'description', 'resolution', 'priority', + 'due_date', 'last_escalation', 'secret_key', 'kbitem') + + class EditFollowUpForm(forms.ModelForm): class Meta: diff --git a/helpdesk/templates/helpdesk/ticket.html b/helpdesk/templates/helpdesk/ticket.html index ce7d61e4..dfa8c9ee 100644 --- a/helpdesk/templates/helpdesk/ticket.html +++ b/helpdesk/templates/helpdesk/ticket.html @@ -163,6 +163,10 @@ +
+
{{ customfields_form }}
+
+ {% if ticket.checklists.exists %} diff --git a/helpdesk/views/staff.py b/helpdesk/views/staff.py index f89b5d08..f98a666e 100644 --- a/helpdesk/views/staff.py +++ b/helpdesk/views/staff.py @@ -46,6 +46,7 @@ from helpdesk.forms import ( CUSTOMFIELD_DATE_FORMAT, EditFollowUpForm, EditTicketForm, + EditTicketCustomFieldForm, EmailIgnoreForm, FormControlDeleteFormSet, MultipleTicketSelectForm, @@ -430,6 +431,9 @@ def view_ticket(request, ticket_id): default=2 )).order_by('rank') + # add custom fields to further details panel + customfields_form = EditTicketCustomFieldForm(None, instance=ticket) + return render(request, 'helpdesk/ticket.html', { 'ticket': ticket, 'dependencies': dependencies, @@ -443,6 +447,7 @@ def view_ticket(request, ticket_id): 'ticketcc_string': ticketcc_string, 'SHOW_SUBSCRIBE': show_subscribe, 'checklist_form': checklist_form, + 'customfields_form': customfields_form, }) From 8901086a809bfc5717331b27fb1a573639ac1d45 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Fri, 26 Jul 2024 09:08:10 +0000 Subject: [PATCH 2/8] If title cannot be retrieved from POST, default should be ticket.title --- helpdesk/views/staff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpdesk/views/staff.py b/helpdesk/views/staff.py index f98a666e..6466bb5c 100644 --- a/helpdesk/views/staff.py +++ b/helpdesk/views/staff.py @@ -578,7 +578,7 @@ def update_ticket_view(request, ticket_id, public=False): comment = request.POST.get('comment', '') new_status = int(request.POST.get('new_status', ticket.status)) - title = request.POST.get('title', '') + title = request.POST.get('title', ticket.title) owner = int(request.POST.get('owner', -1)) priority = int(request.POST.get('priority', ticket.priority)) queue = int(request.POST.get('queue', ticket.queue.id)) From 9ee0207c3c7665e45f9f60d663567e01b900b8b6 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Fri, 26 Jul 2024 10:02:05 +0000 Subject: [PATCH 3/8] Save custom fields in a followup --- helpdesk/forms.py | 20 ++++++++++++++++++++ helpdesk/update_ticket.py | 7 ++++++- helpdesk/views/staff.py | 6 ++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/helpdesk/forms.py b/helpdesk/forms.py index 3b2c3c81..7b2dd459 100644 --- a/helpdesk/forms.py +++ b/helpdesk/forms.py @@ -192,7 +192,27 @@ class EditTicketCustomFieldForm(EditTicketForm): super(EditTicketCustomFieldForm, self).__init__(*args, **kwargs) del self.fields['merged_to'] + + def save(self, *args, **kwargs): + + # if form is saved in a ticket update, it is passed + # a followup instance to trace custom fields changes + if "followup" in kwargs: + followup = kwargs.pop('followup', None) + + for field, value in self.cleaned_data.items(): + if field.startswith('custom_'): + if value != self.fields[field].initial: + c = followup.ticketchange_set.create( + field=field.replace('custom_', '', 1), + old_value=self.fields[field].initial, + new_value=value, + ) + + super(EditTicketCustomFieldForm, self).save(*args, **kwargs) + + class Meta: model = Ticket exclude = ('title', 'queue', 'created', 'modified', diff --git a/helpdesk/update_ticket.py b/helpdesk/update_ticket.py index 989e04e4..20bac2d1 100644 --- a/helpdesk/update_ticket.py +++ b/helpdesk/update_ticket.py @@ -206,6 +206,7 @@ def update_ticket( due_date=None, new_checklists=None, message_id=None, + customfields_form=None, ): # We need to allow the 'ticket' and 'queue' contexts to be applied to the # comment. @@ -312,7 +313,11 @@ def update_ticket( new_value=due_date, ) ticket.due_date = due_date - + + # save custom fields and ticket changes + if customfields_form.is_valid(): + customfields_form.save(followup=f) + for checklist in ticket.checklists.all(): if checklist.id not in new_checklists: continue diff --git a/helpdesk/views/staff.py b/helpdesk/views/staff.py index 6466bb5c..be166546 100644 --- a/helpdesk/views/staff.py +++ b/helpdesk/views/staff.py @@ -583,6 +583,10 @@ def update_ticket_view(request, ticket_id, public=False): priority = int(request.POST.get('priority', ticket.priority)) queue = int(request.POST.get('queue', ticket.queue.id)) + # custom fields + customfields_form = EditTicketCustomFieldForm(request.POST or None, + instance=ticket) + # Check if a change happened on checklists new_checklists = {} changes_in_checklists = False @@ -609,6 +613,7 @@ def update_ticket_view(request, ticket_id, public=False): due_date == ticket.due_date, (owner == -1) or (not owner and not ticket.assigned_to) or (owner and User.objects.get(id=owner) == ticket.assigned_to), + not customfields_form.has_changed(), ]) if no_changes: return return_to_ticket(request.user, helpdesk_settings, ticket) @@ -627,6 +632,7 @@ def update_ticket_view(request, ticket_id, public=False): time_spent = get_time_spent_from_request(request), due_date = get_due_date_from_request_or_ticket(request, ticket), new_checklists = new_checklists, + customfields_form = customfields_form, ) return return_to_ticket(request.user, helpdesk_settings, ticket) From c7b60267eb6ec8a639a827bc263c99d951b4301e Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Fri, 26 Jul 2024 10:31:22 +0000 Subject: [PATCH 4/8] Handle case where update_ticket doesn't handle customfields_form --- helpdesk/update_ticket.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpdesk/update_ticket.py b/helpdesk/update_ticket.py index 20bac2d1..8577472b 100644 --- a/helpdesk/update_ticket.py +++ b/helpdesk/update_ticket.py @@ -315,7 +315,7 @@ def update_ticket( ticket.due_date = due_date # save custom fields and ticket changes - if customfields_form.is_valid(): + if customfields_form and customfields_form.is_valid(): customfields_form.save(followup=f) for checklist in ticket.checklists.all(): From 8eb883e19e549ee8ed4d3bba074073bf63b4d26c Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Fri, 26 Jul 2024 10:49:36 +0000 Subject: [PATCH 5/8] Adding HELPDESK_SHOW_CUSTOM_FIELDS_FOLLOW_UP_LIST to settings --- helpdesk/settings.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/helpdesk/settings.py b/helpdesk/settings.py index d6d1acbb..0d983e53 100644 --- a/helpdesk/settings.py +++ b/helpdesk/settings.py @@ -255,6 +255,10 @@ HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP = getattr(settings, 'HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP', True) +HELPDESK_SHOW_CUSTOM_FIELDS_FOLLOW_UP_LIST = getattr(settings, + 'HELPDESK_SHOW_CUSTOM_FIELDS_FOLLOW_UP_LIST', + []) + # show delete buttons in ticket follow ups if user is 'superuser' HELPDESK_SHOW_DELETE_BUTTON_SUPERUSER_FOLLOW_UP = getattr( settings, 'HELPDESK_SHOW_DELETE_BUTTON_SUPERUSER_FOLLOW_UP', False) From f31f3eb2336d688bc907e6abf92ae09373ec7c5c Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:04:54 +0000 Subject: [PATCH 6/8] Filter custom fields according to settings list --- helpdesk/forms.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/helpdesk/forms.py b/helpdesk/forms.py index 7b2dd459..0ce76c08 100644 --- a/helpdesk/forms.py +++ b/helpdesk/forms.py @@ -33,7 +33,8 @@ from helpdesk.settings import ( CUSTOMFIELD_DATE_FORMAT, CUSTOMFIELD_DATETIME_FORMAT, CUSTOMFIELD_TIME_FORMAT, - CUSTOMFIELD_TO_FIELD_DICT + CUSTOMFIELD_TO_FIELD_DICT, + HELPDESK_SHOW_CUSTOM_FIELDS_FOLLOW_UP_LIST, ) from helpdesk.validators import validate_file_extension from helpdesk.signals import new_ticket_done @@ -191,7 +192,11 @@ class EditTicketCustomFieldForm(EditTicketForm): """ super(EditTicketCustomFieldForm, self).__init__(*args, **kwargs) - del self.fields['merged_to'] + if HELPDESK_SHOW_CUSTOM_FIELDS_FOLLOW_UP_LIST: + fields = list(self.fields) + for field in fields: + if field != 'id' and field.replace("custom_", "", 1) not in HELPDESK_SHOW_CUSTOM_FIELDS_FOLLOW_UP_LIST: + self.fields.pop(field, None) def save(self, *args, **kwargs): From 6a9703fba288d56c89f0dbce02b242fd194bdc91 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:08:47 +0000 Subject: [PATCH 7/8] Add setting documentation --- docs/settings.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/settings.rst b/docs/settings.rst index 3d0131b3..cac6b07a 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -202,6 +202,9 @@ Options that change ticket updates **Default:** ``HELPDESK_STAFF_ONLY_TICKET_CC = False`` +- **HELPDESK_SHOW_CUSTOM_FIELDS_FOLLOW_UP_LIST** Show configured custom fields in the follow-up form. + + **Default:** ``HELPDESK_SHOW_CUSTOM_FIELDS_FOLLOW_UP_LIST = []`` Options that change ticket properties ------------------------------------- From 2ec9f01f00e35c5171d12f79e6acf798853a47b7 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:12:10 +0000 Subject: [PATCH 8/8] Cleaned EditTicketCustomFieldForm --- helpdesk/forms.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/helpdesk/forms.py b/helpdesk/forms.py index 0ce76c08..b2fbdb25 100644 --- a/helpdesk/forms.py +++ b/helpdesk/forms.py @@ -198,7 +198,6 @@ class EditTicketCustomFieldForm(EditTicketForm): if field != 'id' and field.replace("custom_", "", 1) not in HELPDESK_SHOW_CUSTOM_FIELDS_FOLLOW_UP_LIST: self.fields.pop(field, None) - def save(self, *args, **kwargs): # if form is saved in a ticket update, it is passed @@ -217,13 +216,9 @@ class EditTicketCustomFieldForm(EditTicketForm): super(EditTicketCustomFieldForm, self).save(*args, **kwargs) - class Meta: model = Ticket - exclude = ('title', 'queue', 'created', 'modified', - 'submitter_email', 'assigned_to', 'status', - 'on_hold', 'description', 'resolution', 'priority', - 'due_date', 'last_escalation', 'secret_key', 'kbitem') + fields = ('id', 'merged_to',) class EditFollowUpForm(forms.ModelForm):