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 ------------------------------------- diff --git a/helpdesk/forms.py b/helpdesk/forms.py index 83a3de45..b2fbdb25 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 @@ -180,6 +181,46 @@ 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) + + 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): + + # 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 + fields = ('id', 'merged_to',) + + class EditFollowUpForm(forms.ModelForm): class Meta: 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) 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/update_ticket.py b/helpdesk/update_ticket.py index 989e04e4..8577472b 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 and 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 f89b5d08..be166546 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, }) @@ -573,11 +578,15 @@ 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)) + # custom fields + customfields_form = EditTicketCustomFieldForm(request.POST or None, + instance=ticket) + # Check if a change happened on checklists new_checklists = {} changes_in_checklists = False @@ -604,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) @@ -622,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)