From 7e9ce7e3ed16c4920df0d7e86e4afc7b7e3c107d Mon Sep 17 00:00:00 2001 From: Mantas Masalskis Date: Fri, 6 Nov 2020 10:43:12 +0100 Subject: [PATCH] Fixes #3180 - Calendar counts 24/7 business hours as closed for 1 minute at midnight --- app/models/calendar.rb | 21 +++++++++----------- spec/factories/calendar.rb | 23 ++++++++++++++++++++++ spec/models/calendar_spec.rb | 37 ++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 12 deletions(-) diff --git a/app/models/calendar.rb b/app/models/calendar.rb index e16dfc134..873da047b 100644 --- a/app/models/calendar.rb +++ b/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] + 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 - 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] + # 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 diff --git a/spec/factories/calendar.rb b/spec/factories/calendar.rb index b0aac859b..bda71418e 100644 --- a/spec/factories/calendar.rb +++ b/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 diff --git a/spec/models/calendar_spec.rb b/spec/models/calendar_spec.rb index 0563d31b0..dd7d8ddc1 100644 --- a/spec/models/calendar_spec.rb +++ b/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