From 0bd0693de9cd687cc5da0852d816677fc3cd2029 Mon Sep 17 00:00:00 2001 From: Rolf Schmidt Date: Fri, 5 May 2017 11:17:34 +0200 Subject: [PATCH] Fixed issue #377 - Reply to merged ticket gets appended to the wrong ticket. --- app/models/channel/email_parser.rb | 5 -- app/models/channel/filter/follow_up_merged.rb | 43 ++++++++++++ db/migrate/20170504144100_follow_up_merged.rb | 17 +++++ db/seeds/settings.rb | 9 +++ .../channel/filter/follow_up_merged_spec.rb | 65 +++++++++++++++++++ 5 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 app/models/channel/filter/follow_up_merged.rb create mode 100644 db/migrate/20170504144100_follow_up_merged.rb create mode 100644 spec/models/channel/filter/follow_up_merged_spec.rb diff --git a/app/models/channel/email_parser.rb b/app/models/channel/email_parser.rb index 724ddacc5..994a87dbc 100644 --- a/app/models/channel/email_parser.rb +++ b/app/models/channel/email_parser.rb @@ -504,11 +504,6 @@ returns state = Ticket::State.find(ticket.state_id) state_type = Ticket::StateType.find(state.state_type_id) - # if tickte is merged, find linked ticket - if state_type.name == 'merged' - - end - # set ticket to open again or keep create state if !mail['x-zammad-ticket-followup-state'.to_sym] && !mail['x-zammad-ticket-followup-state_id'.to_sym] new_state = Ticket::State.find_by(default_create: true) diff --git a/app/models/channel/filter/follow_up_merged.rb b/app/models/channel/filter/follow_up_merged.rb new file mode 100644 index 000000000..14c273b49 --- /dev/null +++ b/app/models/channel/filter/follow_up_merged.rb @@ -0,0 +1,43 @@ +# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ + +module Channel::Filter::FollowUpMerged + + def self.run(_channel, mail) + return if mail[:'x-zammad-ticket-id'].blank? + + # get ticket# from subject + ticket = Ticket.find(mail[:'x-zammad-ticket-id']) + return if ticket.blank? + + ticket = find_merge_follow_up_ticket(ticket) + return if ticket.blank? + + mail[:'x-zammad-ticket-id'] = ticket.id + end + + def self.find_merge_follow_up_ticket(ticket) + return if ticket.state.name != 'merged' + + links = Link.list( + link_object: 'Ticket', + link_object_value: ticket.id + ) + return if links.blank? + + merge_ticket = nil + links.each { |link| + next if link['link_type'] != 'parent' + next if link['link_object'] != 'Ticket' + + check_ticket = Ticket.find(link['link_object_value']) + + next if check_ticket.blank? + next if check_ticket.state.name == 'merged' + + merge_ticket = check_ticket + + break + } + merge_ticket + end +end diff --git a/db/migrate/20170504144100_follow_up_merged.rb b/db/migrate/20170504144100_follow_up_merged.rb new file mode 100644 index 000000000..6b0427763 --- /dev/null +++ b/db/migrate/20170504144100_follow_up_merged.rb @@ -0,0 +1,17 @@ +class FollowUpMerged < ActiveRecord::Migration + def up + + # return if it's a new setup + return if !Setting.find_by(name: 'system_init_done') + + Setting.create_if_not_exists( + title: 'Defines postmaster filter.', + name: '0110_postmaster_filter_follow_up_merged', + area: 'Postmaster::PreFilter', + description: 'Defines postmaster filter to identify follow-up ticket for merged tickets.', + options: {}, + state: 'Channel::Filter::FollowUpMerged', + frontend: false + ) + end +end diff --git a/db/seeds/settings.rb b/db/seeds/settings.rb index cec9085ef..99c5305c8 100644 --- a/db/seeds/settings.rb +++ b/db/seeds/settings.rb @@ -2271,6 +2271,15 @@ Setting.create_if_not_exists( state: 'Channel::Filter::FollowUpCheck', frontend: false ) +Setting.create_if_not_exists( + title: 'Defines postmaster filter.', + name: '0110_postmaster_filter_follow_up_merged', + area: 'Postmaster::PreFilter', + description: 'Defines postmaster filter to identify follow-up ticket for merged tickets.', + options: {}, + state: 'Channel::Filter::FollowUpMerged', + frontend: false +) Setting.create_if_not_exists( title: 'Defines postmaster filter.', name: '0200_postmaster_filter_follow_up_possible_check', diff --git a/spec/models/channel/filter/follow_up_merged_spec.rb b/spec/models/channel/filter/follow_up_merged_spec.rb new file mode 100644 index 000000000..3f24956fd --- /dev/null +++ b/spec/models/channel/filter/follow_up_merged_spec.rb @@ -0,0 +1,65 @@ +require 'rails_helper' + +RSpec.describe Channel::Filter::FollowUpMerged do + + describe '#find_merge_follow_up_ticket' do + + it 'finds the follow up ticket for merged tickets' do + ticket1 = create(:ticket) + ticket2 = create(:ticket) + ticket3 = create(:ticket) + ticket4 = create(:ticket) + ticket5 = create(:ticket) + + ticket1.merge_to( ticket_id: ticket2.id, user_id: 1 ) + ticket2.merge_to( ticket_id: ticket3.id, user_id: 1 ) + ticket3.merge_to( ticket_id: ticket4.id, user_id: 1 ) + ticket4.merge_to( ticket_id: ticket5.id, user_id: 1 ) + + ticket = Channel::Filter::FollowUpMerged.find_merge_follow_up_ticket(ticket1) + expect(ticket.id).to eq(ticket5.id) + + follow_up_raw = "From: me@example.com +To: customer@example.com +Subject: #{ticket1.subject_build('some new subject')} + +blub follow up" + ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, follow_up_raw) + expect(ticket_p.id).to eq(ticket5.id) + + follow_up_raw = "From: me@example.com +To: customer@example.com +Subject: #{ticket2.subject_build('some new subject')} + +blub follow up" + ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, follow_up_raw) + expect(ticket_p.id).to eq(ticket5.id) + + follow_up_raw = "From: me@example.com +To: customer@example.com +Subject: #{ticket3.subject_build('some new subject')} + +blub follow up" + ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, follow_up_raw) + expect(ticket_p.id).to eq(ticket5.id) + + follow_up_raw = "From: me@example.com +To: customer@example.com +Subject: #{ticket4.subject_build('some new subject')} + +blub follow up" + ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, follow_up_raw) + expect(ticket_p.id).to eq(ticket5.id) + + follow_up_raw = "From: me@example.com +To: customer@example.com +Subject: #{ticket5.subject_build('some new subject')} + +blub follow up" + ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, follow_up_raw) + expect(ticket_p.id).to eq(ticket5.id) + end + + end + +end