Browse Source

Merge branch 'develop' of github.com:martini/zammad into develop

Felix Niklas 9 years ago
parent
commit
2542aa9b78

+ 1 - 1
app/assets/javascripts/app/controllers/_dashboard/first_steps_clues.coffee

@@ -11,7 +11,7 @@ class App.FirstStepsClues extends App.Controller
     {
       container: '.search-holder'
       headline: 'Search'
-      text: 'Here you can search for ticket, customers and organizations. To find everything use the §*§-Placeholder'
+      text: 'Here you can search for ticket, customers and organizations. You can use the §*§-Placeholder as wildcard. E. g. §smi*§ or §rosent*l§. You also can use ||double quotes|| for searching phrases §"some phrase"§.'
     }
     {
       container: '.user-menu'

+ 28 - 48
app/assets/javascripts/app/controllers/_profile/notification.coffee

@@ -11,56 +11,37 @@ class Index extends App.Controller
   render: =>
 
     # matrix
-    config = {}
-    config['matrix'] = {}
-    config['matrix']['create'] = {}
-    config['matrix']['create']['name'] = 'new Ticket'
-    config['matrix']['create']['criteria'] = {}
-    config['matrix']['create']['criteria']['owned_by_me'] = true
-    config['matrix']['create']['criteria']['owned_by_nobody'] = true
-    config['matrix']['create']['criteria']['no'] = false
-    config['matrix']['create']['channel'] = {}
-    config['matrix']['create']['channel']['email'] = true
-    config['matrix']['create']['channel']['online'] = false
-    config['matrix']['update'] = {}
-    config['matrix']['update']['name'] = 'Ticket update'
-    config['matrix']['update']['criteria'] = {}
-    config['matrix']['update']['criteria']['owned_by_me'] = true
-    config['matrix']['update']['criteria']['owned_by_nobody'] = false
-    config['matrix']['update']['criteria']['no'] = false
-    config['matrix']['update']['channel'] = {}
-    config['matrix']['update']['channel']['email'] = true
-    config['matrix']['update']['channel']['online'] = false
-    config['matrix']['move_into'] = {}
-    config['matrix']['move_into']['name'] = 'Ticket moved into my group'
-    config['matrix']['move_into']['criteria'] = {}
-    config['matrix']['move_into']['criteria']['owned_by_me'] = true
-    config['matrix']['move_into']['criteria']['owned_by_nobody'] = true
-    config['matrix']['move_into']['criteria']['no'] = false
-    config['matrix']['move_into']['channel'] = {}
-    config['matrix']['move_into']['channel']['email'] = true
-    config['matrix']['move_into']['channel']['online'] = false
-    config['matrix']['escalation'] = {}
-    config['matrix']['escalation']['name'] = 'Ticket escalation'
-    config['matrix']['escalation']['criteria'] = {}
-    config['matrix']['escalation']['criteria']['owned_by_me'] = true
-    config['matrix']['escalation']['criteria']['owned_by_nobody'] = true
-    config['matrix']['escalation']['criteria']['no'] = false
-    config['matrix']['escalation']['channel'] = {}
-    config['matrix']['escalation']['channel']['email'] = true
-    config['matrix']['escalation']['channel']['online'] = false
+    config =
+      group_ids: []
+      matrix:
+        create:
+          name: 'new Ticket'
+        update:
+          name: 'Ticket update'
+        reminder_reached:
+          name: 'Ticket reminder reached'
+        escalation:
+          name: 'Ticket escalation'
 
     user_config = @Session.get('preferences').notification_config
     if user_config
       config = $.extend(true, {}, config, user_config)
-    console.log('oo', config)
+
     # groups
+    user_group_config = true
+    if !user_config || !user_config['group_ids'] || _.isEmpty(user_config['group_ids']) || user_config['group_ids'][0] is '-'
+      user_group_config = false
+
     groups = []
     group_ids = @Session.get('group_ids')
     if group_ids
       for group_id in group_ids
         group = App.Group.find(group_id)
         groups.push group
+        if !user_group_config
+          if !config['group_ids']
+            config['group_ids'] = []
+          config['group_ids'].push group_id.toString()
 
     @html App.view('profile/notification')( groups: groups, config: config )
 
@@ -72,7 +53,6 @@ class Index extends App.Controller
     params.notification_config = {}
 
     form_params = @formParam(e.target)
-    console.log('P',form_params)
     for key, value of form_params
       if key is 'group_ids'
         if typeof value isnt 'object'
@@ -108,10 +88,10 @@ class Index extends App.Controller
             else
               params.notification_config[area[0]][area[1]][area[2]] = {
                 email:  true
-                online: false
+                online: true
               }
-    console.log('P2',params)
-
+    if !params.notification_config.group_ids || _.isEmpty(params.notification_config.group_ids)
+      params.notification_config.group_ids = ['-']
     @formDisable(e)
 
     # get data
@@ -127,12 +107,12 @@ class Index extends App.Controller
 
   success: (data, status, xhr) =>
     App.User.full(
-      App.Session.get( 'id' ),
+      App.Session.get('id'),
       =>
-        App.Event.trigger( 'ui:rerender' )
+        App.Event.trigger('ui:rerender')
         @notify(
           type: 'success'
-          msg:  App.i18n.translateContent( 'Successfully!' )
+          msg:  App.i18n.translateContent('Successfully!')
         )
       ,
       true
@@ -140,10 +120,10 @@ class Index extends App.Controller
 
   error: (xhr, status, error) =>
     @render()
-    data = JSON.parse( xhr.responseText )
+    data = JSON.parse(xhr.responseText)
     @notify(
       type: 'error'
-      msg:  App.i18n.translateContent( data.message )
+      msg:  App.i18n.translateContent(data.message)
     )
 
 App.Config.set( 'Notifications', { prio: 2600, name: 'Notifications', parent: '#profile', target: '#profile/notifications', role: ['Agent'], controller: Index }, 'NavBarProfile' )

+ 1 - 1
app/assets/javascripts/app/controllers/dashboard.coffee

@@ -2,7 +2,7 @@ class App.Dashboard extends App.Controller
   clueAccess: true
   events:
     'click .tabs .tab': 'toggle'
-    'click .intro': 'clues'
+    'click .js-intro': 'clues'
 
   constructor: ->
     super

+ 2 - 1
app/assets/javascripts/app/lib/app_post/i18n.coffee

@@ -186,7 +186,8 @@ class _i18nSingleton extends Spine.Module
 
     # apply inline markup
     translated
-      .replace(/\*(.+?)\*/gm, '<b>$1</b>')
+      .replace(/\|\|(.+?)\|\|/gm, '<i>$1</i>')
+      .replace(/\|(.+?)\|/gm, '<b>$1</b>')
       .replace(/_(.+?)_/gm, '<u>$1</u>')
       .replace(/§(.+?)§/gm, '<kbd>$1</kbd>')
 

+ 2 - 2
app/assets/javascripts/app/views/profile/notification.jst.eco

@@ -22,7 +22,7 @@
           <td><input type="checkbox" name="matrix.<%= key %>.criteria.owned_by_nobody" value="true"  <% if value.criteria.owned_by_nobody: %>checked<% end %>/></td>
           <td><input type="checkbox" name="matrix.<%= key %>.criteria.no" value="true"  <% if value.criteria.no: %>checked<% end %>/></td>
           <td><input type="radio" name="matrix.<%= key %>.channel" value="email" <% if value.channel.email: %>checked<% end %>/></td>
-          <td><input type="radio" name="matrix.<%= key %>.channel" value="online" <% if value.channel.online: %>checked<% end %>/></td>
+          <td><input type="radio" name="matrix.<%= key %>.channel" value="online" <% if !value.channel.email && value.channel.online: %>checked<% end %>/></td>
         </tr>
         <% end %>
       <% end %>
@@ -31,7 +31,7 @@
 
 
   <h3><%- @T( 'Groups' ) %></h3>
-
+  <%- @T('For "owned by nobody" and "no criteria" only notify about tickets in theres groups.') %>
   <div class="settings-entry">
     <table class="table">
     <% if @groups: %>

+ 1 - 1
app/assets/stylesheets/zammad.scss

@@ -15,7 +15,7 @@ $navigationWidth: 260px;
 
 $highlight-color: hsl(205,90%,60%);
 
-$largeScreenBreakpoint: 1280px;
+$largeScreenBreakpoint: 1260px;
 
 html {
   height: 100%;

+ 4 - 0
app/models/channel/driver/mail_stdin.rb

@@ -8,6 +8,10 @@ process emails from STDIN
 
   cat /path/to/mail.eml | rails r 'Channel::Driver::MailStdin.new'
 
+e. g.
+
+cat test/fixtures/mail1.box | rails r 'Channel::Driver::MailStdin.new'
+
 =end
 
   def initialize

+ 92 - 31
app/models/observer/ticket/notification/background_job.rb

@@ -13,7 +13,7 @@ class Observer::Ticket::Notification::BackgroundJob
     end
 
     # find recipients
-    recipients = []
+    recipients_and_channels = []
 
 =begin
     # group of agents to work on
@@ -43,15 +43,68 @@ class Observer::Ticket::Notification::BackgroundJob
     end
 =end
 
-    if ticket.owner_id != 1
-      recipients.push ticket.owner
-    else
-      recipients = ticket.agent_of_group()
+    # loop through all users
+    possible_recipients = ticket.agent_of_group
+    if ticket.owner_id == 1
+      possible_recipients.push ticket.owner
     end
+    already_checked_recipient_ids = {}
+    possible_recipients.each {|user|
+      next if already_checked_recipient_ids[user.id]
+      already_checked_recipient_ids[user.id] = true
+      next if !user.preferences
+      next if !user.preferences['notification_config']
+      matrix = user.preferences['notification_config']['matrix']
+      if ticket.owner_id != user.id
+        if user.preferences['notification_config']['group_ids'] ||
+           (user.preferences['notification_config']['group_ids'].class == Array && (!user.preferences['notification_config']['group_ids'].empty? || user.preferences['notification_config']['group_ids'][0] != '-'))
+          hit = false
+          user.preferences['notification_config']['group_ids'].each {|notify_group_id|
+            user.group_ids.each {|local_group_id|
+              if local_group_id.to_s == notify_group_id.to_s
+                hit = true
+              end
+            }
+          }
+          next if !hit
+        end
+      end
+      next if !matrix
+      next if !matrix[@p[:type]]
+      data = matrix[@p[:type]]
+      next if !data
+      next if !data['criteria']
+      channels = data['channel']
+      if data['criteria']['owned_by_me'] && ticket.owner_id == user.id
+        data = {
+          user: user,
+          channels: channels
+        }
+        recipients_and_channels.push data
+        next
+      end
+      if data['criteria']['owned_by_nobody'] && ticket.owner_id == 1
+        data = {
+          user: user,
+          channels: channels
+        }
+        recipients_and_channels.push data
+        next
+      end
+      next unless data['criteria']['no']
+      data = {
+        user: user,
+        channels: channels
+      }
+      recipients_and_channels.push data
+      next
+    }
 
     # send notifications
     recipient_list = ''
-    recipients.each do |user|
+    recipients_and_channels.each do |item|
+      user = item[:user]
+      channels = item[:channels]
 
       # ignore user who changed it by him self via web
       if @via_web
@@ -62,32 +115,35 @@ class Observer::Ticket::Notification::BackgroundJob
       # ignore inactive users
       next if !user.active
 
-      # create online notification
-      seen = ticket.online_notification_seen_state(user.id)
-      OnlineNotification.add(
-        type: @p[:type],
-        object: 'Ticket',
-        o_id: ticket.id,
-        seen: seen,
-        created_by_id: ticket.updated_by_id || 1,
-        user_id: user.id,
-      )
-
-      # create email notification
-      next if !user.email || user.email == ''
+      # ignore if no changes has been done
+      changes = human_changes(user, ticket)
+      next if @p[:type] == 'update' && !article && ( !changes || changes.empty? )
 
-      # add recipient_list
-      if recipient_list != ''
-        recipient_list += ','
+      # create online notification
+      used_channels = []
+      if channels['online']
+        used_channels.push 'online'
+        seen = ticket.online_notification_seen_state(user.id)
+        OnlineNotification.add(
+          type: @p[:type],
+          object: 'Ticket',
+          o_id: ticket.id,
+          seen: seen,
+          created_by_id: ticket.updated_by_id || 1,
+          user_id: user.id,
+        )
+        Rails.logger.info "send ticket online notifiaction to agent (#{@p[:type]}/#{ticket.id}/#{user.email})"
       end
-      recipient_list += user.email.to_s
 
-      # ignore if no changes has been done
-      changes = human_changes(user, ticket)
-      if @p[:type] == 'update' && !article && ( !changes || changes.empty? )
+      # ignore email channel notificaiton and empty emails
+      if !channels['email'] || !user.email || user.email == ''
+        add_recipient_list(ticket, user, used_channels)
         next
       end
 
+      used_channels.push 'email'
+      add_recipient_list(ticket, user, used_channels)
+
       # get user based notification template
       # if create, send create message / block update messages
       if @p[:type] == 'create'
@@ -113,10 +169,9 @@ class Observer::Ticket::Notification::BackgroundJob
       }
 
       # rebuild subject
-      notification[:subject] = ticket.subject_build( notification[:subject] )
+      notification[:subject] = ticket.subject_build(notification[:subject])
 
-      # send notification
-      Rails.logger.info "send ticket notifiaction to agent (#{@p[:type]}/#{ticket.id}/#{user.email})"
+      Rails.logger.info "send ticket email notifiaction to agent (#{@p[:type]}/#{ticket.id}/#{user.email})"
 
       NotificationFactory.send(
         recipient: user,
@@ -126,9 +181,15 @@ class Observer::Ticket::Notification::BackgroundJob
       )
     end
 
-    # add history record
-    return if recipient_list == ''
+  end
 
+  def add_recipient_list(ticket, user, channels)
+    return if channels.empty?
+    identifier = user.email
+    if !identifier || identifier == ''
+      identifier = user.login
+    end
+    recipient_list = "#{identifier}(#{channels.join(',')})"
     History.add(
       o_id: ticket.id,
       history_type: 'notification',

+ 14 - 1
app/models/store/file.rb

@@ -11,9 +11,13 @@ add new file to store
 
     store_file_id = Store::File.add(binary_data)
 
+do also verify of written data
+
+    store_file_id = Store::File.add(binary_data, true)
+
 =end
 
-    def self.add(data)
+    def self.add(data, verify = true)
       sha = Digest::SHA256.hexdigest(data)
 
       file = Store::File.find_by(sha: sha)
@@ -30,6 +34,15 @@ add new file to store
           provider: adapter_name,
           sha: sha,
         )
+
+        # verify
+        if verify
+          read_data = adapter.get(sha)
+          read_sha = Digest::SHA256.hexdigest(read_data)
+          if sha != read_sha
+            fail "Content not written correctly (provider #{adapter_name})."
+          end
+        end
       end
       file
     end

+ 6 - 1
app/models/ticket.rb

@@ -84,7 +84,12 @@ returns
 =end
 
   def agent_of_group
-    Group.find( group_id ).users.where( active: true ).joins(:roles).where( 'roles.name' => Z_ROLENAME_AGENT, 'roles.active' => true ).uniq()
+    Group.find(group_id)
+         .users.where(active: true)
+         .joins(:roles)
+         .where('roles.name' => Z_ROLENAME_AGENT, 'roles.active' => true)
+         .order('users.login')
+         .uniq()
   end
 
 =begin

Some files were not shown because too many files changed in this diff