Browse Source

Fixes #2371 - Zammad misses "weeks" for relative time events

Romit Choudhary 3 years ago
parent
commit
a6bbce9070

+ 3 - 0
app/assets/javascripts/app/controllers/_ui_element/time_range.coffee

@@ -5,8 +5,10 @@ class App.UiElement.time_range
       minute: __('Minute(s)')
       hour: __('Hour(s)')
       day: __('Day(s)')
+      week: __('Week(s)'),
       month: __('Month(s)')
       year: __('Year(s)')
+      
     for key, value of ranges
       ranges[key] = App.i18n.translateInline(value)
 
@@ -17,6 +19,7 @@ class App.UiElement.time_range
       minute: [1..120]
       hour: [1..48]
       day: [1..31]
+      week: [1..53]
       month: [1..12]
       year: [1..20]
 

+ 13 - 90
app/models/ticket.rb

@@ -846,113 +846,29 @@ condition example
         bind_params.push selector['value']
       elsif selector['operator'] == 'within last (relative)'
         query += "#{attribute} BETWEEN ? AND ?"
-        time = nil
-        case selector['range']
-        when 'minute'
-          time = selector['value'].to_i.minutes.ago
-        when 'hour'
-          time = selector['value'].to_i.hours.ago
-        when 'day'
-          time = selector['value'].to_i.days.ago
-        when 'month'
-          time = selector['value'].to_i.months.ago
-        when 'year'
-          time = selector['value'].to_i.years.ago
-        else
-          raise "Unknown selector attributes '#{selector.inspect}'"
-        end
+        time = range(selector).ago
         bind_params.push time
         bind_params.push Time.zone.now
       elsif selector['operator'] == 'within next (relative)'
         query += "#{attribute} BETWEEN ? AND ?"
-        time = nil
-        case selector['range']
-        when 'minute'
-          time = selector['value'].to_i.minutes.from_now
-        when 'hour'
-          time = selector['value'].to_i.hours.from_now
-        when 'day'
-          time = selector['value'].to_i.days.from_now
-        when 'month'
-          time = selector['value'].to_i.months.from_now
-        when 'year'
-          time = selector['value'].to_i.years.from_now
-        else
-          raise "Unknown selector attributes '#{selector.inspect}'"
-        end
+        time = range(selector).from_now
         bind_params.push Time.zone.now
         bind_params.push time
       elsif selector['operator'] == 'before (relative)'
         query += "#{attribute} <= ?"
-        time = nil
-        case selector['range']
-        when 'minute'
-          time = selector['value'].to_i.minutes.ago
-        when 'hour'
-          time = selector['value'].to_i.hours.ago
-        when 'day'
-          time = selector['value'].to_i.days.ago
-        when 'month'
-          time = selector['value'].to_i.months.ago
-        when 'year'
-          time = selector['value'].to_i.years.ago
-        else
-          raise "Unknown selector attributes '#{selector.inspect}'"
-        end
+        time = range(selector).ago
         bind_params.push time
       elsif selector['operator'] == 'after (relative)'
         query += "#{attribute} >= ?"
-        time = nil
-        case selector['range']
-        when 'minute'
-          time = selector['value'].to_i.minutes.from_now
-        when 'hour'
-          time = selector['value'].to_i.hours.from_now
-        when 'day'
-          time = selector['value'].to_i.days.from_now
-        when 'month'
-          time = selector['value'].to_i.months.from_now
-        when 'year'
-          time = selector['value'].to_i.years.from_now
-        else
-          raise "Unknown selector attributes '#{selector.inspect}'"
-        end
+        time = range(selector).from_now
         bind_params.push time
       elsif selector['operator'] == 'till (relative)'
         query += "#{attribute} <= ?"
-        time = nil
-        case selector['range']
-        when 'minute'
-          time = selector['value'].to_i.minutes.from_now
-        when 'hour'
-          time = selector['value'].to_i.hours.from_now
-        when 'day'
-          time = selector['value'].to_i.days.from_now
-        when 'month'
-          time = selector['value'].to_i.months.from_now
-        when 'year'
-          time = selector['value'].to_i.years.from_now
-        else
-          raise "Unknown selector attributes '#{selector.inspect}'"
-        end
+        time = range(selector).from_now
         bind_params.push time
       elsif selector['operator'] == 'from (relative)'
         query += "#{attribute} >= ?"
-        time = nil
-        case selector['range']
-        when 'minute'
-          time = selector['value'].to_i.minutes.ago
-        when 'hour'
-          time = selector['value'].to_i.hours.ago
-        when 'day'
-          time = selector['value'].to_i.days.ago
-        when 'month'
-          time = selector['value'].to_i.months.ago
-        when 'year'
-          time = selector['value'].to_i.years.ago
-        else
-          raise "Unknown selector attributes '#{selector.inspect}'"
-        end
+        time = range(selector).ago
         bind_params.push time
       else
         raise "Invalid operator '#{selector['operator']}' for '#{selector['value'].inspect}'"
@@ -1349,6 +1265,12 @@ perform active triggers on ticket
     [true, ticket, local_options]
   end
 
+  def self.range(selector)
+    selector['value'].to_i.send(selector['range'].pluralize)
+  rescue
+    raise 'unknown selector'
+  end
+
 =begin
 
 get all email references headers of a ticket, to exclude some, parse it as array into method
@@ -1883,4 +1805,5 @@ result
     # blocked for 60 full days
     (user.preferences[:mail_delivery_failed_data].to_date - Time.zone.now.to_date).to_i + 61
   end
+
 end

+ 4 - 0
i18n/zammad.pot

@@ -10318,6 +10318,10 @@ msgstr ""
 msgid "Week"
 msgstr ""
 
+#: app/assets/javascripts/app/controllers/_ui_element/time_range.coffee
+msgid "Week(s)"
+msgstr ""
+
 #: app/assets/javascripts/app/controllers/_profile/linked_accounts.coffee
 msgid "Weibo"
 msgstr ""

+ 69 - 0
spec/models/ticket/selector_2_sql_examples.rb

@@ -0,0 +1,69 @@
+# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
+
+require 'rails_helper'
+
+RSpec.shared_examples 'TicketSelector2Sql' do
+  context 'when relative time range is selected in ticket selector' do
+    def get_condition(operator, range)
+      {
+        'ticket.created_at' => {
+          operator: operator,
+          range:    range, # minute|hour|day|month|
+          value:    '10',
+        },
+      }
+    end
+
+    before do
+      freeze_time
+    end
+
+    it 'calculates proper time interval, when operator is within last relative' do
+      condition = get_condition('within last (relative)', 'minute')
+
+      _, bind_params = Ticket.selector2sql(condition)
+
+      expect(bind_params).to eq([10.minutes.ago, Time.zone.now])
+    end
+
+    it 'calculates proper time interval, when operator is within next relative' do
+      condition = get_condition('within next (relative)', 'hour')
+
+      _, bind_params = Ticket.selector2sql(condition)
+
+      expect(bind_params).to eq([Time.zone.now, 10.hours.from_now])
+    end
+
+    it 'calculates proper time interval, when operator is before (relative)' do
+      condition = get_condition('before (relative)', 'day')
+
+      _, bind_params = Ticket.selector2sql(condition)
+
+      expect(bind_params).to eq([10.days.ago])
+    end
+
+    it 'calculates proper time interval, when operator is after (relative)' do
+      condition = get_condition('after (relative)', 'week')
+
+      _, bind_params = Ticket.selector2sql(condition)
+
+      expect(bind_params).to eq([10.weeks.from_now])
+    end
+
+    it 'calculates proper time interval, when operator is till (relative)' do
+      condition = get_condition('till (relative)', 'month')
+
+      _, bind_params = Ticket.selector2sql(condition)
+
+      expect(bind_params).to eq([10.months.from_now])
+    end
+
+    it 'calculates proper time interval, when operator is from (relative)' do
+      condition = get_condition('from (relative)', 'year')
+
+      _, bind_params = Ticket.selector2sql(condition)
+
+      expect(bind_params).to eq([10.years.ago])
+    end
+  end
+end

+ 2 - 0
spec/models/ticket_spec.rb

@@ -17,6 +17,7 @@ require 'models/ticket/escalation_examples'
 require 'models/ticket/resets_pending_time_seconds_examples'
 require 'models/ticket/sets_close_time_examples'
 require 'models/ticket/sets_last_owner_update_time_examples'
+require 'models/ticket/selector_2_sql_examples'
 
 RSpec.describe Ticket, type: :model do
   subject(:ticket) { create(:ticket) }
@@ -37,6 +38,7 @@ RSpec.describe Ticket, type: :model do
   it_behaves_like 'TicketResetsPendingTimeSeconds'
   it_behaves_like 'TicketSetsCloseTime'
   it_behaves_like 'TicketSetsLastOwnerUpdateTime'
+  it_behaves_like 'TicketSelector2Sql'
 
   describe 'Class methods:' do
     describe '.selectors' do