Browse Source

Fixes #3180 - Calendar counts 24/7 business hours as closed for 1 minute at midnight

Mantas Masalskis 4 years ago
parent
commit
7e9ce7e3ed
3 changed files with 70 additions and 13 deletions
  1. 10 13
      app/models/calendar.rb
  2. 23 0
      spec/factories/calendar.rb
  3. 37 0
      spec/models/calendar_spec.rb

+ 10 - 13
app/models/calendar.rb

@@ -284,20 +284,17 @@ returns
 =end
 
   def business_hours_to_hash
-    hours = {}
-    business_hours.each do |day, meta|
-      next if !meta[:active]
-      next if !meta[:timeframes]
-
-      hours[day.to_sym] = {}
-      meta[:timeframes].each do |frame|
-        next if !frame[0]
-        next if !frame[1]
-
-        hours[day.to_sym][frame[0]] = frame[1]
+    business_hours
+      .filter { |_, value| value[:active] && value[:timeframes] }
+      .each_with_object({}) do |(day, meta), days_memo|
+        days_memo[day.to_sym] = meta[:timeframes]
+          .each_with_object({}) do |(from, to), hours_memo|
+            next if !from || !to
+
+            # convert "last minute of the day" format from Zammad/UI to biz-gem
+            hours_memo[from] = to == '23:59' ? '24:00' : to
+          end
       end
-    end
-    hours
   end
 
 =begin

+ 23 - 0
spec/factories/calendar.rb

@@ -75,5 +75,28 @@ FactoryBot.define do
         }
       end
     end
+
+    trait '23:59/7' do
+      business_hours_generated
+
+      timeframe_alldays { ['00:00', '23:59'] }
+    end
+
+    trait :business_hours_generated do
+      transient do
+        timeframe_alldays  { nil }
+        timeframe_workdays { timeframe_alldays }
+        timeframe_weekends { timeframe_alldays }
+        config_workdays    { timeframe_workdays ? { active: true, timeframes: [timeframe_workdays] } : {} }
+        config_weekends    { timeframe_weekends ? { active: true, timeframes: [timeframe_weekends] } : {} }
+      end
+
+      business_hours do
+        hash = {}
+        %i[mon tue wed thu fri].each_with_object(hash) { |elem, memo| memo[elem] = config_workdays }
+        %i[sat sun].each_with_object(hash)             { |elem, memo| memo[elem] = config_weekends }
+        hash
+      end
+    end
   end
 end

+ 37 - 0
spec/models/calendar_spec.rb

@@ -220,4 +220,41 @@ RSpec.describe Calendar, type: :model do
       end
     end
   end
+
+  describe '#biz' do
+    it 'overnight minutes are counted correctly' do
+      travel_to Time.current.noon
+
+      calendar = create(:calendar, '23:59/7')
+      biz      = calendar.biz
+
+      expect(biz.time(24, :hours).after(Time.current)).to eq 1.day.from_now
+    end
+  end
+
+  describe '#business_hours_to_hash' do
+    it 'returns a hash with all weekdays' do
+      calendar = create(:calendar, '23:59/7')
+      hash     = calendar.business_hours_to_hash
+
+      expect(hash.keys).to eq %i[mon tue wed thu fri sat sun]
+    end
+
+    context 'with mocked hours' do
+      let(:calendar) { create(:calendar, '23:59/7') }
+      let(:result)   { calendar.business_hours_to_hash }
+
+      before do
+        calendar.business_hours = {
+          day_1: { active: true, timeframes: [['09:00', '17:00']] },
+          day_2: { active: true, timeframes: [['00:01', '02:00'], ['09:00', '17:00']] },
+          day_3: { active: false, timeframes: [['09:00', '17:00']] }
+        }
+      end
+
+      it { expect(result.keys).to eq %i[day_1 day_2] }
+      it { expect(result[:day_1]).to eq({ '09:00' => '17:00' }) }
+      it { expect(result[:day_2]).to eq({ '09:00' => '17:00', '00:01' => '02:00' }) }
+    end
+  end
 end