Просмотр исходного кода

Added support of pending reminder notifications.

Martin Edenhofer 9 лет назад
Родитель
Сommit
7c46db4be4

+ 30 - 4
app/models/observer/ticket/notification/background_job.rb

@@ -120,11 +120,33 @@ class Observer::Ticket::Notification::BackgroundJob
       changes = human_changes(user, ticket)
       next if @p[:type] == 'update' && !article && ( !changes || changes.empty? )
 
+      # check if today already notified within last 24 hours
+      if @p[:type] == 'reminder_reached' || @p[:type] == 'escalation'
+        identifier = user.email
+        if !identifier || identifier == ''
+          identifier = user.login
+        end
+        already_notified = false
+        History.list('Ticket', ticket.id).each {|history|
+          next if history['type'] != 'notification'
+          next if history['value_to'] !~ /\(#{Regexp.escape(@p[:type])}:/
+          next if history['value_to'] !~ /#{Regexp.escape(identifier)}\(/
+          next if history['created_at'] < Time.zone.now - 24.hours
+          already_notified = true
+        }
+        next if already_notified
+      end
+
       # create online notification
       used_channels = []
       if channels['online']
         used_channels.push 'online'
         seen = ticket.online_notification_seen_state(user.id)
+
+        # delete old notifications
+        if @p[:type] == 'reminder_reached' || @p[:type] == 'escalation'
+          OnlineNotification.remove_by_type('Ticket', ticket.id, @p[:type])
+        end
         OnlineNotification.add(
           type: @p[:type],
           object: 'Ticket',
@@ -138,12 +160,12 @@ class Observer::Ticket::Notification::BackgroundJob
 
       # ignore email channel notificaiton and empty emails
       if !channels['email'] || !user.email || user.email == ''
-        add_recipient_list(ticket, user, used_channels)
+        add_recipient_list(ticket, user, used_channels, @p[:type])
         next
       end
 
       used_channels.push 'email'
-      add_recipient_list(ticket, user, used_channels)
+      add_recipient_list(ticket, user, used_channels, @p[:type])
 
       # get user based notification template
       # if create, send create message / block update messages
@@ -152,6 +174,10 @@ class Observer::Ticket::Notification::BackgroundJob
         template = 'ticket_create'
       elsif @p[:type] == 'update'
         template = 'ticket_update'
+      elsif @p[:type] == 'reminder_reached'
+        template = 'ticket_reminder_reached'
+      elsif @p[:type] == 'escalation'
+        template = 'ticket_escalation'
       else
         fail "unknown type for notification #{@p[:type]}"
       end
@@ -173,13 +199,13 @@ class Observer::Ticket::Notification::BackgroundJob
 
   end
 
-  def add_recipient_list(ticket, user, channels)
+  def add_recipient_list(ticket, user, channels, type)
     return if channels.empty?
     identifier = user.email
     if !identifier || identifier == ''
       identifier = user.login
     end
-    recipient_list = "#{identifier}(#{channels.join(',')})"
+    recipient_list = "#{identifier}(#{type}:#{channels.join(',')})"
     History.add(
       o_id: ticket.id,
       history_type: 'notification',

+ 36 - 18
app/models/online_notification.rb

@@ -28,10 +28,10 @@ add a new online notification for this user
 
     # lookups
     if data[:type]
-      type_id = TypeLookup.by_name( data[:type] )
+      type_id = TypeLookup.by_name(data[:type])
     end
     if data[:object]
-      object_id = ObjectLookup.by_name( data[:object] )
+      object_id = ObjectLookup.by_name(data[:object])
     end
 
     record = {
@@ -66,12 +66,12 @@ mark online notification as seen
 
 remove whole online notifications of an object
 
-  OnlineNotification.remove( 'Ticket', 123 )
+  OnlineNotification.remove('Ticket', 123)
 
 =end
 
-  def self.remove( object_name, o_id )
-    object_id = ObjectLookup.by_name( object_name )
+  def self.remove(object_name, o_id)
+    object_id = ObjectLookup.by_name(object_name)
     OnlineNotification.where(
       object_lookup_id: object_id,
       o_id: o_id,
@@ -80,22 +80,40 @@ remove whole online notifications of an object
 
 =begin
 
+remove whole online notifications of an object by type
+
+  OnlineNotification.remove_by_type('Ticket', 123, type)
+
+=end
+
+  def self.remove_by_type(object_name, o_id, type)
+    object_id = ObjectLookup.by_name(object_name)
+    type_id = TypeLookup.by_name(type)
+    OnlineNotification.where(
+      object_lookup_id: object_id,
+      type_lookup_id: type_id,
+      o_id: o_id,
+    ).destroy_all
+  end
+
+=begin
+
 return all online notifications of an user
 
-  notifications = OnlineNotification.list( user, limit )
+  notifications = OnlineNotification.list(user, limit)
 
 =end
 
   def self.list(user, limit)
 
     notifications = OnlineNotification.where(user_id: user.id)
-                                      .order( 'created_at DESC, id DESC' )
-                                      .limit( limit )
+                                      .order('created_at DESC, id DESC')
+                                      .limit(limit)
     list = []
     notifications.each do |item|
       data           = item.attributes
-      data['object'] = ObjectLookup.by_id( data['object_lookup_id'] )
-      data['type']   = TypeLookup.by_id( data['type_lookup_id'] )
+      data['object'] = ObjectLookup.by_id(data['object_lookup_id'])
+      data['type']   = TypeLookup.by_id(data['type_lookup_id'])
       data.delete('object_lookup_id')
       data.delete('type_lookup_id')
       list.push data
@@ -107,18 +125,18 @@ return all online notifications of an user
 
 return all online notifications of an object
 
-  notifications = OnlineNotification.list_by_object( 'Ticket', 123 )
+  notifications = OnlineNotification.list_by_object('Ticket', 123)
 
 =end
 
-  def self.list_by_object( object_name, o_id)
-    object_id = ObjectLookup.by_name( object_name )
+  def self.list_by_object(object_name, o_id)
+    object_id = ObjectLookup.by_name(object_name)
     notifications = OnlineNotification.where(
       object_lookup_id: object_id,
       o_id: o_id,
     )
-                                      .order( 'created_at DESC, id DESC' )
-                                      .limit( 10_000 )
+                                      .order('created_at DESC, id DESC')
+                                      .limit(10_000)
     notifications
   end
 
@@ -126,12 +144,12 @@ return all online notifications of an object
 
 mark online notification as seen by object
 
-  OnlineNotification.seen_by_object( 'Ticket', 123, user_id )
+  OnlineNotification.seen_by_object('Ticket', 123, user_id)
 
 =end
 
   def self.seen_by_object(object_name, o_id)
-    object_id     = ObjectLookup.by_name( object_name )
+    object_id     = ObjectLookup.by_name(object_name)
     notifications = OnlineNotification.where(
       object_lookup_id: object_id,
       o_id: o_id,
@@ -148,7 +166,7 @@ mark online notification as seen by object
 
 return all online notifications of an user with assets
 
-  OnlineNotification.list_full( user )
+  OnlineNotification.list_full(user)
 
 returns:
 

+ 48 - 26
app/models/ticket.rb

@@ -135,39 +135,61 @@ returns
 =end
 
   def self.process_pending
+    result = []
 
-    ticket_states = Ticket::State.where(
-      state_type_id: Ticket::StateType.find_by( name: 'pending action' ),
-    )
-                                 .where.not(next_state_id: nil)
+    # process pending action tickets
+    pending_action = Ticket::StateType.find_by(name: 'pending action')
+    ticket_states_pending_action = Ticket::State.where(state_type_id: pending_action)
+                                                .where.not(next_state_id: nil)
+    if !ticket_states_pending_action.empty?
+      next_state_map = {}
+      ticket_states_pending_action.each { |state|
+        next_state_map[state.id] = state.next_state_id
+      }
+
+      tickets = where(state_id: next_state_map.keys)
+                .where('pending_time <= ?', Time.zone.now)
+
+      tickets.each { |ticket|
+        ticket.state_id      = next_state_map[ticket.state_id]
+        ticket.updated_at    = Time.zone.now
+        ticket.updated_by_id = 1
+        ticket.save!
+
+        # we do not have an destructor at this point, so we need to
+        # execute ticket events manually
+        Observer::Ticket::Notification.transaction
+
+        result.push ticket
+      }
+    end
 
-    return [] if !ticket_states
+    # process pending reminder tickets
+    pending_reminder = Ticket::StateType.find_by(name: 'pending reminder')
+    ticket_states_pending_reminder = Ticket::State.where(state_type_id: pending_reminder)
 
-    next_state_map = {}
-    ticket_states.each { |state|
-      next_state_map[state.id] = state.next_state_id
-    }
+    if !ticket_states_pending_reminder.empty?
+      reminder_state_map = {}
+      ticket_states_pending_reminder.each { |state|
+        reminder_state_map[state.id] = state.next_state_id
+      }
 
-    tickets = where(
-      state_id: next_state_map.keys,
-    )
-              .where( 'pending_time <= ?', Time.zone.now )
+      tickets = where(state_id: reminder_state_map.keys)
+                .where('pending_time <= ?', Time.zone.now)
 
-    return [] if !tickets
+      tickets.each { |ticket|
 
-    result = []
-    tickets.each { |ticket|
-      ticket.state_id      = next_state_map[ticket.state_id]
-      ticket.updated_at    = Time.zone.now
-      ticket.updated_by_id = 1
-      ticket.save!
-
-      result.push ticket
-    }
+        # send notification
+        bg = Observer::Ticket::Notification::BackgroundJob.new(
+          ticket_id: ticket.id,
+          article_id: ticket.articles.last.id,
+          type: 'reminder_reached',
+        )
+        bg.perform
 
-    # we do not have an destructor at this point, so we need to
-    # execute ticket events manually
-    Observer::Ticket::Notification.transaction
+        result.push ticket
+      }
+    end
 
     result
   end

+ 37 - 9
app/models/user.rb

@@ -78,7 +78,7 @@ class User < ApplicationModel
 fullname of user
 
   user = User.find(123)
-  result = user.fulename
+  result = user.fullname
 
 returns
 
@@ -87,20 +87,48 @@ returns
 =end
 
   def fullname
-    fullname = ''
+    name = ''
     if firstname && !firstname.empty?
-      fullname = fullname + firstname
+      name = name + firstname
     end
     if lastname && !lastname.empty?
-      if fullname != ''
-        fullname = fullname + ' '
+      if name != ''
+        name += ' '
       end
-      fullname = fullname + lastname
+      name += lastname
     end
-    if fullname == '' && email
-      fullname = email
+    if name == '' && email
+      name = email
     end
-    fullname
+    name
+  end
+
+=begin
+
+longname of user
+
+  user = User.find(123)
+  result = user.longname
+
+returns
+
+  result = "Bob Smith"
+
+  or with org
+
+  result = "Bob Smith (Org ABC)"
+
+=end
+
+  def longname
+    name = fullname
+    if organization_id
+      organization = Organization.lookup(id: organization_id)
+      if organization
+        name += " (#{organization.name})"
+      end
+    end
+    name
   end
 
 =begin

+ 1 - 1
app/views/mailer/ticket_create/de.html.erb

@@ -2,7 +2,7 @@ Neues Ticket (<%= d 'ticket.title' %>)
 
 <p>Hallo <%= d 'recipient.firstname' %>,</p>
 <br>
-<p>es wurde ein neues Ticket (<%= d 'ticket.title' %>) von "<b><%= d 'ticket.updated_by.fullname' %></b>" erstellt.</p>
+<p>es wurde ein neues Ticket (<%= d 'ticket.title' %>) von "<b><%= d 'ticket.updated_by.longname' %></b>" erstellt.</p>
 <br>
 <p>
 <%= t 'Group' %>: <%= d 'ticket.group.name' %><br>

+ 1 - 1
app/views/mailer/ticket_create/en.html.erb

@@ -2,7 +2,7 @@ New Ticket (<%= d 'ticket.title' %>)
 
 <p>Hi <%= d 'recipient.firstname' %>,</p>
 <br>
-<p>a new Ticket (<%= d 'ticket.title' %>) has been created by "<b><%= d 'ticket.updated_by.fullname' %></b>".</p>
+<p>a new Ticket (<%= d 'ticket.title' %>) has been created by "<b><%= d 'ticket.updated_by.longname' %></b>".</p>
 <br>
 <p>
 <%= t 'Group' %>: <%= d 'ticket.group.name' %><br>

+ 18 - 0
app/views/mailer/ticket_reminder_reached/de.html.erb

@@ -0,0 +1,18 @@
+Warten auf Erinnerung erreicht! (<%= d 'ticket.title' %>)
+
+<p>Hallo <%= d 'recipient.firstname' %>,</p>
+<br>
+<p>dieses Ticket benötigt Deine Aufmerksamkeit, warten auf Erinnerung für (<%= d 'ticket.title' %>) mit dem Kunden "<b><%= d 'ticket.customer.longname' %></b>" ist erreicht.</p>
+<br>
+<% if @objects[:article] %>
+  <p>
+  <%= t 'Information' %>:
+  <blockquote type="cite">
+  <%= a 'article' %>
+  </blockquote>
+  </p>
+<% end %>
+<br>
+<p>
+  <a href="<%= c 'http_type' %>://<%= c 'fqdn' %>/#ticket/zoom/<%= d 'ticket.id' %>" target="zammad_app"><%= t 'View this in Zammad' %></a>
+</p>

+ 18 - 0
app/views/mailer/ticket_reminder_reached/en.html.erb

@@ -0,0 +1,18 @@
+Reminder reached (<%= d 'ticket.title' %>)
+
+<p>Hi <%= d 'recipient.firstname' %>,</p>
+<br>
+<p>ticket needs attachen, reminder reached for Ticket (<%= d 'ticket.title' %>) with customer "<b><%= d 'ticket.customer.longname' %></b>".</p>
+<br>
+<% if @objects[:article] %>
+  <p>
+  <%= t 'Information' %>:
+  <blockquote type="cite">
+  <%= a 'article' %>
+  </blockquote>
+  </p>
+<% end %>
+<br>
+<p>
+  <a href="<%= c 'http_type' %>://<%= c 'fqdn' %>/#ticket/zoom/<%= d 'ticket.id' %>" target="zammad_app"><%= t 'View this in Zammad' %></a>
+</p>

+ 1 - 1
app/views/mailer/ticket_update/de.html.erb

@@ -3,7 +3,7 @@ Ticket aktualisiert (<%= d 'ticket.title' %>)
 <p>Hi <%= d 'recipient.firstname' %>,</p>
 <br>
 <div>
-Ticket (<%= d 'ticket.title' %>) wurde von "<b><%= d 'ticket.updated_by.fullname' %></b>" aktualisiert.
+Ticket (<%= d 'ticket.title' %>) wurde von "<b><%= d 'ticket.updated_by.longname' %></b>" aktualisiert.
 </div>
 <br>
 <% if @objects[:changes] && !@objects[:changes].empty? %>

+ 1 - 1
app/views/mailer/ticket_update/en.html.erb

@@ -3,7 +3,7 @@ Updated Ticket (<%= d 'ticket.title' %>)
 <p>Hi <%= d 'recipient.firstname' %>,</p>
 <br>
 <div>
-Ticket (<%= d 'ticket.title' %>) has been updated by "<b><%= d 'ticket.updated_by.fullname' %></b>".
+Ticket (<%= d 'ticket.title' %>) has been updated by "<b><%= d 'ticket.updated_by.longname' %></b>".
 </div>
 <br>
 <% if @objects[:changes] && !@objects[:changes].empty? %>