From a248181857a2ff9f43428cc621a3cdcd004070d8 Mon Sep 17 00:00:00 2001 From: Martin Whitehouse Date: Mon, 25 Jul 2022 04:08:16 +0200 Subject: [PATCH] Add `redirect_from_chosen_ticket` helper function Moves the whole handling to own block, reducing complexity greatly. --- helpdesk/views/staff.py | 190 +++++++++++++++++++++------------------- 1 file changed, 102 insertions(+), 88 deletions(-) diff --git a/helpdesk/views/staff.py b/helpdesk/views/staff.py index 82b4c5d3..3ced684e 100644 --- a/helpdesk/views/staff.py +++ b/helpdesk/views/staff.py @@ -1031,6 +1031,102 @@ def merge_ticket_values( } +def redirect_from_chosen_ticket( + request, + chosen_ticket, + tickets, + custom_fields +) -> HttpResponseRedirect: + # Save ticket fields values + for attribute, __ in TICKET_ATTRIBUTES: + id_for_attribute = request.POST.get(attribute) + if id_for_attribute != chosen_ticket.id: + try: + selected_ticket = tickets.get(id=id_for_attribute) + except (Ticket.DoesNotExist, ValueError): + continue + + # Check if attr is a get_FIELD_display + if attribute.startswith('get_') and attribute.endswith('_display'): + # Keep only the FIELD part + attribute = attribute[4:-8] + # Get value from selected ticket and then save it on + # the chosen ticket + value = getattr(selected_ticket, attribute) + setattr(chosen_ticket, attribute, value) + # Save custom fields values + for custom_field in custom_fields: + id_for_custom_field = request.POST.get(custom_field.name) + if id_for_custom_field != chosen_ticket.id: + try: + selected_ticket = tickets.get( + id=id_for_custom_field) + except (Ticket.DoesNotExist, ValueError): + continue + + # Check if the value for this ticket custom field + # exists + try: + value = selected_ticket.ticketcustomfieldvalue_set.get( + field=custom_field).value + except TicketCustomFieldValue.DoesNotExist: + continue + + # Create the custom field value or update it with the + # value from the selected ticket + custom_field_value, created = chosen_ticket.ticketcustomfieldvalue_set.get_or_create( + field=custom_field, + defaults={'value': value} + ) + if not created: + custom_field_value.value = value + custom_field_value.save(update_fields=['value']) + # Save changes + chosen_ticket.save() + + # For other tickets, save the link to the ticket in which they have been merged to + # and set status to DUPLICATE + for ticket in tickets.exclude(id=chosen_ticket.id): + ticket.merged_to = chosen_ticket + ticket.status = Ticket.DUPLICATE_STATUS + ticket.save() + + # Send mail to submitter email and ticket CC to let them + # know ticket has been merged + context = safe_template_context(ticket) + if ticket.submitter_email: + send_templated_mail( + template_name='merged', + context=context, + recipients=[ticket.submitter_email], + bcc=[ + cc.email_address for cc in ticket.ticketcc_set.select_related('user')], + sender=ticket.queue.from_address, + fail_silently=True + ) + + # Move all followups and update their title to know they + # come from another ticket + ticket.followup_set.update( + ticket=chosen_ticket, + # Next might exceed maximum 200 characters limit + title=_('[Merged from #%(id)d] %(title)s') % { + 'id': ticket.id, 'title': ticket.title} + ) + + # Add submitter_email, assigned_to email and ticketcc to + # chosen ticket if necessary + chosen_ticket.add_email_to_ticketcc_if_not_in( + email=ticket.submitter_email) + if ticket.assigned_to and ticket.assigned_to.email: + chosen_ticket.add_email_to_ticketcc_if_not_in( + email=ticket.assigned_to.email) + for ticketcc in ticket.ticketcc_set.all(): + chosen_ticket.add_email_to_ticketcc_if_not_in( + ticketcc=ticketcc) + return redirect(chosen_ticket) + + @staff_member_required def merge_tickets(request): """ @@ -1060,94 +1156,12 @@ def merge_tickets(request): 'Please choose a ticket in which the others will be merged into.') ) else: - # Save ticket fields values - for attribute, __ in TICKET_ATTRIBUTES: - id_for_attribute = request.POST.get(attribute) - if id_for_attribute != chosen_ticket.id: - try: - selected_ticket = tickets.get(id=id_for_attribute) - except (Ticket.DoesNotExist, ValueError): - continue - - # Check if attr is a get_FIELD_display - if attribute.startswith('get_') and attribute.endswith('_display'): - # Keep only the FIELD part - attribute = attribute[4:-8] - # Get value from selected ticket and then save it on - # the chosen ticket - value = getattr(selected_ticket, attribute) - setattr(chosen_ticket, attribute, value) - # Save custom fields values - for custom_field in custom_fields: - id_for_custom_field = request.POST.get(custom_field.name) - if id_for_custom_field != chosen_ticket.id: - try: - selected_ticket = tickets.get( - id=id_for_custom_field) - except (Ticket.DoesNotExist, ValueError): - continue - - # Check if the value for this ticket custom field - # exists - try: - value = selected_ticket.ticketcustomfieldvalue_set.get( - field=custom_field).value - except TicketCustomFieldValue.DoesNotExist: - continue - - # Create the custom field value or update it with the - # value from the selected ticket - custom_field_value, created = chosen_ticket.ticketcustomfieldvalue_set.get_or_create( - field=custom_field, - defaults={'value': value} - ) - if not created: - custom_field_value.value = value - custom_field_value.save(update_fields=['value']) - # Save changes - chosen_ticket.save() - - # For other tickets, save the link to the ticket in which they have been merged to - # and set status to DUPLICATE - for ticket in tickets.exclude(id=chosen_ticket.id): - ticket.merged_to = chosen_ticket - ticket.status = Ticket.DUPLICATE_STATUS - ticket.save() - - # Send mail to submitter email and ticket CC to let them - # know ticket has been merged - context = safe_template_context(ticket) - if ticket.submitter_email: - send_templated_mail( - template_name='merged', - context=context, - recipients=[ticket.submitter_email], - bcc=[ - cc.email_address for cc in ticket.ticketcc_set.select_related('user')], - sender=ticket.queue.from_address, - fail_silently=True - ) - - # Move all followups and update their title to know they - # come from another ticket - ticket.followup_set.update( - ticket=chosen_ticket, - # Next might exceed maximum 200 characters limit - title=_('[Merged from #%(id)d] %(title)s') % { - 'id': ticket.id, 'title': ticket.title} - ) - - # Add submitter_email, assigned_to email and ticketcc to - # chosen ticket if necessary - chosen_ticket.add_email_to_ticketcc_if_not_in( - email=ticket.submitter_email) - if ticket.assigned_to and ticket.assigned_to.email: - chosen_ticket.add_email_to_ticketcc_if_not_in( - email=ticket.assigned_to.email) - for ticketcc in ticket.ticketcc_set.all(): - chosen_ticket.add_email_to_ticketcc_if_not_in( - ticketcc=ticketcc) - return redirect(chosen_ticket) + return redirect_from_chosen_ticket( + request, + chosen_ticket, + tickets, + custom_fields + ) return render(request, 'helpdesk/ticket_merge.html', { 'tickets': tickets,