From 4997ed477020f24ac6447dbf91d129faaaa14057 Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Sun, 22 Feb 2015 19:12:09 +0100 Subject: [PATCH] Added ical ticket export feature. --- Gemfile | 3 + app/controllers/ical_tickets_controller.rb | 195 +++++++++++++++++++++ config/routes/ical_tickets.rb | 9 + 3 files changed, 207 insertions(+) create mode 100644 app/controllers/ical_tickets_controller.rb create mode 100644 config/routes/ical_tickets.rb diff --git a/Gemfile b/Gemfile index 87338c24f..ee7827cee 100644 --- a/Gemfile +++ b/Gemfile @@ -105,3 +105,6 @@ gem 'prawn' gem 'prawn-table' gem 'puma' + +# ical export +gem 'icalendar' diff --git a/app/controllers/ical_tickets_controller.rb b/app/controllers/ical_tickets_controller.rb new file mode 100644 index 000000000..82c6f87fe --- /dev/null +++ b/app/controllers/ical_tickets_controller.rb @@ -0,0 +1,195 @@ +# Copyright (C) 2012-2015 Zammad Foundation, http://zammad-foundation.org/ + +require 'icalendar' + +class IcalTicketsController < ApplicationController + before_filter { authentication_check_action_token 'iCal' } + + # @path [GET] /ical/tickets_all/:action_token + # + # @summary Returns an iCal file with all tickets (open, new, pending, esclation) as events. + # + # @parameter action_token(required) [String] The action_token identifying the requested User privileged for 'iCal' action. + # + # @response_message 200 [String] iCal file ready to import in calendar applications. + # @response_message 500 Permission denied. + def all + + new_open_events_data = new_open_events_data_get + pending_events_data = pending_events_data_get + escalation_events_data = escalation_events_data_get + + events_data = new_open_events_data + pending_events_data + escalation_events_data + + events_data_to_ical( events_data ) + end + + # @path [GET] /ical/tickets_new_open/:action_token + # + # @summary Returns an iCal file with all new and open tickets as events. + # + # @parameter action_token(required) [String] The action_token identifying the requested User privileged for 'iCal' action. + # + # @response_message 200 [String] iCal file ready to import in calendar applications. + # @response_message 500 Permission denied. + def new_open + + events_data = new_open_events_data_get + + events_data_to_ical( events_data ) + end + + # @path [GET] /ical/tickets_pending/:action_token + # + # @summary Returns an iCal file with all pending tickets as events. + # + # @parameter action_token(required) [String] The action_token identifying the requested User privileged for 'iCal' action. + # + # @response_message 200 [String] iCal file ready to import in calendar applications. + # @response_message 500 Permission denied. + def pending + events_data = pending_events_data_get + + events_data_to_ical( events_data ) + end + + # @path [GET] /ical/ticket_escalation/:action_token + # + # @summary Returns an iCal file with all escalation times for tickets as events. + # + # @parameter action_token(required) [String] The action_token identifying the requested User privileged for 'iCal' action. + # + # @response_message 200 [String] iCal file ready to import in calendar applications. + # @response_message 500 Permission denied. + def escalation + events_data = escalation_events_data_get + + events_data_to_ical( events_data ) + end + + private + + def new_open_events_data_get + + condition = { + 'tickets.owner_id' => current_user.id, + 'tickets.state_id' => Ticket::State.where( + :state_type_id => Ticket::StateType.where( + :name => [ + 'new', + 'open', + ], + ), + ), + } + + tickets = Ticket.search( + :current_user => current_user, + :condition => condition, + ) + + events_data = [] + tickets.each do |ticket| + + event_data = {} + + event_data[:dtstart] = Icalendar::Values::Date.new( Date.today ) + event_data[:dtend] = Icalendar::Values::Date.new( Date.today ) + event_data[:summary] = "#{ ticket.state.name } ticket: '#{ ticket.title }'" + event_data[:description] = "T##{ ticket.number }" + + events_data.push event_data + end + + return events_data + end + + def pending_events_data_get + + condition = { + 'tickets.owner_id' => current_user.id, + 'tickets.state_id' => Ticket::State.where( + :state_type_id => Ticket::StateType.where( + :name => [ + 'pending reminder', + 'pending action', + ], + ), + ), + } + + tickets = Ticket.search( + :current_user => current_user, + :condition => condition, + ) + + events_data = [] + tickets.each do |ticket| + + event_data = {} + + event_data[:dtstart] = Icalendar::Values::DateTime.new( ticket.pending_time ) + event_data[:dtend] = Icalendar::Values::DateTime.new( ticket.pending_time ) + event_data[:summary] = "#{ ticket.state.name } ticket: '#{ ticket.title }'" + event_data[:description] = "T##{ ticket.number }" + + events_data.push event_data + end + + return events_data + end + + + def escalation_events_data_get + + condition = [ + 'tickets.escalation_time IS NOT NULL', + 'tickets.owner_id = ?', current_user.id + ] + + tickets = Ticket.search( + :current_user => current_user, + :condition => condition, + ) + + events_data = [] + tickets.each do |ticket| + + event_data = {} + + event_data[:dtstart] = Icalendar::Values::DateTime.new( ticket.escalation_time ) + event_data[:dtend] = Icalendar::Values::DateTime.new( ticket.escalation_time ) + event_data[:summary] = "ticket escalation: '#{ ticket.title }'" + event_data[:description] = "T##{ ticket.number }" + + events_data.push event_data + end + + return events_data + end + + def events_data_to_ical(events_data) + + cal = Icalendar::Calendar.new + + events_data.each do |event_data| + + cal.event do |e| + e.dtstart = event_data[:dtstart] + e.dtend = event_data[:dtend] + e.summary = event_data[:summary] + e.description = event_data[:description] + e.ip_class = "PRIVATE" + end + + end + + send_data( + cal.to_ical, + :filename => 'new_open.ical', + :type => 'text/plain', + :disposition => 'inline' + ) + end + +end \ No newline at end of file diff --git a/config/routes/ical_tickets.rb b/config/routes/ical_tickets.rb new file mode 100644 index 000000000..b5cd0a9f0 --- /dev/null +++ b/config/routes/ical_tickets.rb @@ -0,0 +1,9 @@ +Zammad::Application.routes.draw do + api_path = Rails.configuration.api_path + + # ical ticket + match api_path + '/ical/tickets/:action_token', :to => 'ical_tickets#all', :via => :get + match api_path + '/ical/tickets_new_open/:action_token', :to => 'ical_tickets#new_open', :via => :get + match api_path + '/ical/tickets_pending/:action_token', :to => 'ical_tickets#pending', :via => :get + match api_path + '/ical/tickets_escalation/:action_token', :to => 'ical_tickets#escalation', :via => :get +end \ No newline at end of file