opening_hours_converter 1.5.3 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 409f7e2aaf835c458739af6789add6a5b124779d
4
- data.tar.gz: ccb1748b1c0f447a220b2f687468833d15382f78
3
+ metadata.gz: 55f6b611b6d6c7dee28596d842441e9201b69866
4
+ data.tar.gz: c20fa4d736826c39c4625ae2cac7a4497fa3ee24
5
5
  SHA512:
6
- metadata.gz: 13bb10fe1ecd18ba1f2a6436cc2996162bc626a7b0d91e0e44ac984728f77fab58f96aa2491abd81a4e09844c9b0e5c0ee99da445321695cd54e1aafd3cea9a4
7
- data.tar.gz: b14b6d859a4efabe586ff8c9d13dfb8ecc8bb6f66394ac7cbb959db21bd5a49523601d541e09c656095fab9165da9b9486c8b8506dde84d92b5caadd1dbf06f1
6
+ metadata.gz: ce5333e34fef43072928e868b3e66f92543acf80c5af99dc517dcb385b9d26597765cc18e4db60eeafca013b0bf927f365fedcf6144ed459d1bb36e95137ff29
7
+ data.tar.gz: 529acd00a440bdc7d3947cea333324a5f4a87acae235dfa1be4d811a1278a5cd29582b35f9d9961a297c4515e40a7fa35673dee3321330abc404511fbe83629a
@@ -16,8 +16,12 @@ module OpeningHoursConverter
16
16
  if !interval.nil?
17
17
  start_minute = nil
18
18
  end_minute = nil
19
+ off = interval.is_off
19
20
 
20
- if interval.day_start == interval.day_end || interval.day_end == DAYS_MAX && interval.end == MINUTES_MAX
21
+ if off
22
+ start_minute = 0
23
+ end_minute = MINUTES_MAX
24
+ elsif interval.day_start == interval.day_end || interval.day_end == DAYS_MAX && interval.end == MINUTES_MAX
21
25
  start_minute = interval.start
22
26
  end_minute = interval.end
23
27
  elsif interval.day_end == interval.day_start + 1 && interval.end == 0
@@ -27,7 +31,7 @@ module OpeningHoursConverter
27
31
 
28
32
  unless start_minute.nil? && end_minute.nil?
29
33
  for minute in start_minute..end_minute
30
- minute_array[minute] = true
34
+ minute_array[minute] = off ? "off" : true
31
35
  end
32
36
  else
33
37
  raise "Invalid interval #{interval.inspect}"
@@ -44,18 +48,23 @@ module OpeningHoursConverter
44
48
  intervals = []
45
49
  minute_start = -1
46
50
  minute_end = nil
51
+ off = false
52
+
47
53
  minute_array.each_with_index do |minute, i|
48
54
  if i == 0 && minute
55
+ off = true if minute == "off"
49
56
  minute_start = i
50
57
  elsif i == minute_array.length - 1 && minute
51
- intervals << OpeningHoursConverter::Interval.new(0, minute_start, 0, i - 1)
58
+ intervals << OpeningHoursConverter::Interval.new(0, minute_start, 0, i - 1, off)
52
59
  minute_start = -1
60
+ off = false
53
61
  else
54
62
  if minute && minute_start < 0
55
63
  minute_start = i
56
64
  elsif !minute && minute_start >= 0
57
- intervals << OpeningHoursConverter::Interval.new(0, minute_start, 0, i - 1)
65
+ intervals << OpeningHoursConverter::Interval.new(0, minute_start, 0, i - 1, off)
58
66
  minute_start = -1
67
+ off = false
59
68
  end
60
69
  end
61
70
  end
@@ -85,7 +94,7 @@ module OpeningHoursConverter
85
94
  def copy_intervals(intervals)
86
95
  @intervals = []
87
96
  intervals.each do |interval|
88
- if !interval.nil? && interval.day_start == 0 && interval.day_end == 0
97
+ if !interval.nil? && !interval.is_off && interval.day_start == 0 && interval.day_end == 0
89
98
  @intervals << interval.dup
90
99
  end
91
100
  end
@@ -3,13 +3,15 @@ require 'opening_hours_converter/constants'
3
3
  module OpeningHoursConverter
4
4
  class Interval
5
5
  include Constants
6
- attr_reader :day_start, :day_end, :start, :end
6
+ attr_reader :day_start, :day_end, :start, :end, :is_off
7
+
8
+ def initialize(day_start, min_start, day_end=0, min_end=0, is_off=false)
7
9
 
8
- def initialize(day_start, min_start, day_end=0, min_end=0)
9
10
  @day_start = day_start
10
11
  @day_end = day_end
11
12
  @start = min_start
12
13
  @end = min_end
14
+ @is_off = is_off
13
15
 
14
16
  if @day_end == 0 && @end == 0
15
17
  @day_end = DAYS_MAX
@@ -14,10 +14,12 @@ module OpeningHoursConverter
14
14
 
15
15
  date_ranges.each_with_index do |date_range, date_range_index|
16
16
  if !date_range.nil?
17
- date_range.typical.intervals.each_with_index do |interval, interval_id|
18
- if interval&.day_start == -2 && interval&.day_start == interval&.day_end
19
- date_range.typical.remove_interval(interval_id)
20
- day_ph = true
17
+ if date_range.typical.intervals.length != 1
18
+ date_range.typical.intervals.each_with_index do |interval, interval_id|
19
+ if interval&.day_start == -2 && interval&.day_start == interval&.day_end
20
+ date_range.typical.remove_interval(interval_id)
21
+ day_ph = true
22
+ end
21
23
  end
22
24
  end
23
25
 
@@ -38,7 +40,7 @@ module OpeningHoursConverter
38
40
  end
39
41
 
40
42
  if date_range_index == 0 || range_general.nil?
41
- if date_range.wide_interval.type == "holiday"
43
+ if date_range.typical&.intervals&.length == 1 && date_range.typical&.intervals[0].day_start == -2 && date_range.typical&.intervals[0].day_end == -2
42
44
  oh_rules = build_holiday(date_range)
43
45
  elsif date_range.defines_typical_week?
44
46
  if !range_general_for.nil?
@@ -104,8 +106,8 @@ module OpeningHoursConverter
104
106
  end
105
107
  end
106
108
  end
107
- result = ""
108
109
 
110
+ result = ""
109
111
  if rules.length == 0
110
112
  date_ranges.each do |dr|
111
113
  result += "#{dr.wide_interval.get_time_selector} off"
@@ -123,18 +125,33 @@ module OpeningHoursConverter
123
125
  end
124
126
 
125
127
  def build_holiday(date_range)
128
+
129
+ start_year = date_range.wide_interval.start&.key?(:year) ? date_range.wide_interval.start[:year] : date_range.wide_interval.start
130
+ end_year = date_range.wide_interval.end&.key?(:year) ? date_range.wide_interval.end[:year] : date_range.wide_interval.end
131
+
132
+
126
133
  intervals = date_range.typical.get_intervals(true)
134
+ date_range = OpeningHoursConverter::DateRange.new(OpeningHoursConverter::WideInterval.new.holiday("PH", start_year, end_year))
127
135
 
136
+ for i in 0..6
137
+ intervals.each do |interval|
138
+ if !interval.nil?
139
+ date_range.typical.add_interval(OpeningHoursConverter::Interval.new(i, interval.start, i, interval.end, interval.is_off))
140
+ end
141
+ end
142
+ end
128
143
  rule = OpeningHoursConverter::OpeningHoursRule.new
129
144
  date = OpeningHoursConverter::OpeningHoursDate.new(date_range.wide_interval, date_range.wide_interval.type, [-1])
130
145
  rule.add_date(date)
131
146
 
132
- intervals.each do |interval|
147
+ date_range.typical.intervals.each do |interval|
133
148
  if !interval.nil?
134
149
  rule.add_time(OpeningHoursConverter::OpeningHoursTime.new(interval.start, interval.end))
150
+ rule.is_defined_off = rule.is_defined_off || interval.is_off
135
151
  end
136
152
  end
137
153
 
154
+
138
155
  return [ rule ]
139
156
  end
140
157
 
@@ -148,6 +165,7 @@ module OpeningHoursConverter
148
165
  intervals.each do |interval|
149
166
  if !interval.nil?
150
167
  rule.add_time(OpeningHoursConverter::OpeningHoursTime.new(interval.start, interval.end))
168
+ rule.is_defined_off = rule.is_defined_off ? true : interval.is_off
151
169
  end
152
170
  end
153
171
 
@@ -158,7 +176,6 @@ module OpeningHoursConverter
158
176
  result = []
159
177
 
160
178
  intervals = date_range.typical.get_intervals(true)
161
-
162
179
  days = create_time_intervals(date_range.wide_interval, date_range.wide_interval.type, intervals)
163
180
 
164
181
  days_status = Array.new(OSM_DAYS.length, 0)
@@ -205,6 +222,7 @@ module OpeningHoursConverter
205
222
  end
206
223
  end
207
224
  end
225
+
208
226
  result = merge_days(result)
209
227
 
210
228
  return result
@@ -212,13 +230,13 @@ module OpeningHoursConverter
212
230
 
213
231
  def build_week_diff(date_range, general_date_range)
214
232
  intervals = date_range.typical.get_intervals_diff(general_date_range.typical)
215
-
216
- time_intervals =
217
233
  days = create_time_intervals(
218
234
  date_range.wide_interval,
219
235
  date_range.wide_interval.type,
220
236
  intervals[:open])
221
237
 
238
+
239
+
222
240
  intervals[:closed].each do |interval|
223
241
  for i in interval.day_start..interval.day_end do
224
242
  days[i].add_time(OpeningHoursConverter::OpeningHoursTime.new)
@@ -326,11 +344,15 @@ module OpeningHoursConverter
326
344
  begin
327
345
  if interval.day_start == interval.day_end
328
346
  days[interval.day_start].add_time(OpeningHoursConverter::OpeningHoursTime.new(interval.start, interval.end))
347
+ days[interval.day_start].is_defined_off = days[interval.day_start].is_defined_off ? true : interval.is_off
329
348
  elsif interval.day_end - interval.day_start == 1
330
349
  days[interval.day_start].add_time(OpeningHoursConverter::OpeningHoursTime.new(interval.start, MINUTES_MAX))
350
+ days[interval.day_start].is_defined_off = days[interval.day_start].is_defined_off ? true : interval.is_off
331
351
  days[interval.day_end].add_time(OpeningHoursConverter::OpeningHoursTime.new(0, interval.end))
352
+ days[interval.day_end].is_defined_off = days[interval.day_end].is_defined_off ? true : interval.is_off
332
353
  else
333
354
  for j in interval.day_start..interval.day_end
355
+ days[j].is_defined_off = days[j].is_defined_off ? true : interval.is_off
334
356
  if j == interval.day_start
335
357
  days[j].add_time(OpeningHoursConverter::OpeningHoursTime.new(interval.start, MINUTES_MAX))
336
358
  elsif j == interval.day_end
@@ -4,6 +4,7 @@ require 'json'
4
4
  module OpeningHoursConverter
5
5
  class OpeningHoursParser
6
6
  include Constants
7
+
7
8
  def initialize
8
9
  @RGX_RULE_MODIFIER = /^(open|closed|off)$/i
9
10
  @RGX_WEEK_KEY = /^week$/
@@ -31,9 +32,7 @@ module OpeningHoursConverter
31
32
  wide_range_selector = nil
32
33
  month_selector = nil
33
34
 
34
- times = nil
35
35
  weekdays = nil
36
- weeks = nil
37
36
  months = nil
38
37
  years = nil
39
38
 
@@ -43,51 +42,68 @@ module OpeningHoursConverter
43
42
  res_dr_id = nil
44
43
 
45
44
  blocks.each do |block|
46
- rule_modifier = nil
47
45
  block.strip!
48
46
  next if block.length == 0
49
47
 
50
48
  tokens = tokenize(block)
51
- current_token = tokens.length - 1
52
-
53
- # get comment
54
- if current_token >= 0 && is_comment?(tokens[current_token])
55
- comment = tokens[current_token]
56
- current_token -= 1
57
- end
49
+ @current_token = tokens.length - 1
58
50
 
51
+ weekdays = {}
59
52
 
60
- # get state
61
- if current_token >= 0 && is_rule_modifier?(tokens[current_token])
62
- rule_modifier = tokens[current_token].downcase
63
- current_token -= 1
53
+ # get comment
54
+ if @current_token >= 0 && is_comment?(tokens[@current_token])
55
+ comment = tokens[@current_token]
56
+ @current_token -= 1
64
57
  end
65
58
 
66
- times = []
67
- if current_token >= 0 && is_time?(tokens[current_token])
68
- time_selector = tokens[current_token]
69
- times = get_times(time_selector)
70
- current_token -= 1
71
- end
72
59
 
73
- # get weekdays selector
74
- weekdays = []
75
- holidays = []
76
- if time_selector == "24/7"
77
- weekdays << {from: 0, to: 6}
78
- elsif current_token >= 0 && is_weekday?(tokens[current_token]) && (@RGX_YEAR_PH =~ "#{tokens[current_token-1]} #{tokens[current_token]}").nil?
79
- weekday_selector = tokens[current_token]
80
- weekdays_and_holidays = get_weekdays(weekday_selector)
81
- weekdays = weekdays_and_holidays[:weekdays]
82
- holidays = weekdays_and_holidays[:holidays]
83
- current_token -= 1
60
+ # get state and time associated with weekdays
61
+ while @current_token >= 0 && (is_rule_modifier?(tokens[@current_token]) || is_time?(tokens[@current_token]))
62
+ if is_rule_modifier?(tokens[@current_token])
63
+ local_modifier = tokens[@current_token].downcase
64
+ @current_token -= 1
65
+ begin
66
+ weekday_selector = tokens[@current_token]
67
+ weekdays_and_holidays = get_weekdays(weekday_selector)
68
+ rescue
69
+ weekdays[[{from: 0, to: 6}]] ||= {}
70
+ weekdays[[{from: 0, to: 6}]][:modifiers] ||= []
71
+ weekdays[[{from: 0, to: 6}]][:modifiers] << local_modifier
72
+ else
73
+ weekdays[weekdays_and_holidays] ||= {}
74
+ weekdays[weekdays_and_holidays][:modifiers] ||= []
75
+ weekdays[weekdays_and_holidays][:modifiers] << local_modifier
76
+ @current_token -= 1
77
+ end
78
+ else
79
+ local_times = []
80
+ while @current_token >= 0 && is_time?(tokens[@current_token])
81
+ time_selector = tokens[@current_token]
82
+ local_times.concat get_times(time_selector)
83
+ @current_token -= 1
84
+ end
85
+ begin
86
+ weekday_selector = tokens[@current_token]
87
+ weekdays_and_holidays = get_weekdays(weekday_selector)
88
+ rescue
89
+ weekdays[[{from: 0, to: 6}]] ||= {}
90
+ weekdays[[{from: 0, to: 6}]][:times] ||= []
91
+ weekdays[[{from: 0, to: 6}]][:times].concat(local_times)
92
+ else
93
+ weekdays[weekdays_and_holidays] ||= {}
94
+ weekdays[weekdays_and_holidays][:times] ||= []
95
+ weekdays[weekdays_and_holidays][:times].concat(local_times)
96
+ @current_token -= 1
97
+ end
98
+ end
84
99
  end
85
100
 
86
101
  months = []
87
102
  years = []
88
- if current_token >= 0
103
+ holidays = []
104
+ if @current_token >= 0
89
105
  wide_range_selector = tokens[0]
90
- for i in 1..current_token
106
+ for i in 1..@current_token
91
107
  wide_range_selector += " #{tokens[i]}"
92
108
  end
93
109
  if wide_range_selector.length > 0
@@ -100,8 +116,6 @@ module OpeningHoursConverter
100
116
  years << get_year_month(wrs)
101
117
  elsif !(@RGX_MONTHDAY =~ wrs).nil?
102
118
  months << get_month_day(wrs)
103
- elsif !(@RGX_YEAR_PH =~ wrs).nil?
104
- holidays << get_year_holiday(wrs)
105
119
  elsif !(@RGX_MONTH =~ wrs).nil?
106
120
  months << get_month(wrs)
107
121
  elsif !(@RGX_YEAR =~ wrs).nil?
@@ -113,14 +127,14 @@ module OpeningHoursConverter
113
127
  end
114
128
  end
115
129
 
116
- if current_token == tokens.length - 1
130
+ if @current_token == tokens.length - 1
117
131
  raise ArgumentError, "Unreadable string"
118
132
  end
119
- # puts "months : #{months}"
133
+
120
134
  # puts "weekdays : #{weekdays}"
121
- # puts "times : #{times}"
135
+ # puts "months : #{months}"
122
136
  # puts "years : #{years}"
123
- # puts "rule_modifier : #{rule_modifier}"
137
+
124
138
  date_ranges = []
125
139
  if months.length > 0
126
140
  months.each do |month|
@@ -141,14 +155,6 @@ module OpeningHoursConverter
141
155
  date_ranges << date_range
142
156
  end
143
157
  end
144
- elsif holidays.length > 0 && weekdays.length == 0
145
- holidays.each do |holiday|
146
- if holiday == "PH"
147
- date_ranges << WideInterval.new.holiday(holiday)
148
- elsif holiday[:holiday] == "PH"
149
- date_ranges << WideInterval.new.holiday(holiday[:holiday], holiday[:start], holiday[:end])
150
- end
151
- end
152
158
  elsif years.length > 0
153
159
  years.each do |year|
154
160
  if !year[:from_day].nil?
@@ -178,22 +184,14 @@ module OpeningHoursConverter
178
184
  date_ranges << OpeningHoursConverter::WideInterval.new.always
179
185
  end
180
186
 
181
-
182
- if weekdays.length > 0 && holidays.length > 0
183
- weekdays << {from: -2, to: -2}
184
- holidays = []
185
- end
186
187
  if weekdays.length == 0
187
- weekdays << {from: 0, to: OSM_DAYS.length - 1}
188
- end
189
- if times.length == 0
190
- times << {from: 0, to: 24*60}
188
+ weekdays[[{from: 0, to: 6}]] = {}
189
+ weekdays[[{from: 0, to: 6}]][:times] = [{from: 0, to: 24*60}]
191
190
  end
192
191
 
193
192
  date_ranges.each do |dr|
194
193
  found_date_range = false
195
194
  res_dr_id = 0
196
-
197
195
  while res_dr_id < result.length && !found_date_range
198
196
  if result[res_dr_id].wide_interval.equals(dr) && result[res_dr_id].comment == comment
199
197
  found_date_range = true
@@ -222,37 +220,46 @@ module OpeningHoursConverter
222
220
  result << dr_obj
223
221
  end
224
222
 
225
- for wd_id in 0...weekdays.length
226
- if weekdays[wd_id][:from] <= weekdays[wd_id][:to]
227
- for wd_rm in weekdays[wd_id][:from]..weekdays[wd_id][:to]
228
- if dr_obj.defines_typical_week?
229
- dr_obj.typical.remove_intervals_during_day(wd_rm)
230
- else
231
- dr_obj.typical.clear_intervals
223
+ weekdays.each do |weekday_ranges, weekday_object|
224
+ weekday_ranges.each do |weekday_range|
225
+ if weekday_range[:from] <= weekday_range[:to]
226
+ for wd_rm in weekday_range[:from]..weekday_range[:to]
227
+ if dr_obj.defines_typical_week?
228
+ dr_obj.typical.remove_intervals_during_day(wd_rm)
229
+ else
230
+ dr_obj.typical.clear_intervals
231
+ end
232
232
  end
233
- end
234
- else
235
- for wd_rm in weekdays[wd_id][:from]..6
236
- if dr_obj.defines_typical_week?
237
- dr_obj.typical.remove_intervals_during_day(wd_rm)
238
- else
239
- dr_obj.typical.clear_intervals
233
+ else
234
+ for wd_rm in weekday_range[:from]..6
235
+ if dr_obj.defines_typical_week?
236
+ dr_obj.typical.remove_intervals_during_day(wd_rm)
237
+ else
238
+ dr_obj.typical.clear_intervals
239
+ end
240
+ end
241
+ for wd_rm in 0..weekday_range[:to]
242
+ if dr_obj.defines_typical_week?
243
+ dr_obj.typical.remove_intervals_during_day(wd_rm)
244
+ else
245
+ dr_obj.typical.clear_intervals
246
+ end
240
247
  end
241
248
  end
242
- for wd_rm in 0..weekdays[wd_id][:to]
243
- if dr_obj.defines_typical_week?
244
- dr_obj.typical.remove_intervals_during_day(wd_rm)
245
- else
246
- dr_obj.typical.clear_intervals
249
+
250
+ if weekday_object[:modifiers]
251
+ weekday_object[:modifiers].each do |modifier|
252
+ if modifier == "closed" || modifier == "off"
253
+ remove_interval(dr_obj, weekday_range)
254
+ add_off_interval(dr_obj, weekday_range)
255
+ end
247
256
  end
248
257
  end
249
- end
250
258
 
251
- for t_id in 0...times.length
252
- if rule_modifier == "closed" || rule_modifier == "off"
253
- remove_interval(dr_obj, weekdays[wd_id], times[t_id])
254
- else
255
- add_interval(dr_obj.typical, weekdays[wd_id], times[t_id])
259
+ if weekday_object[:times]
260
+ weekday_object[:times].each do |time_range|
261
+ add_interval(dr_obj.typical, weekday_range, time_range)
262
+ end
256
263
  end
257
264
  end
258
265
  end
@@ -443,7 +450,6 @@ module OpeningHoursConverter
443
450
  end
444
451
 
445
452
  def get_weekdays(weekday_selector)
446
- holidays = []
447
453
  weekdays = []
448
454
  wd_from = nil
449
455
  wd_to = nil
@@ -451,7 +457,7 @@ module OpeningHoursConverter
451
457
  weekday_selector = weekday_selector.split(',')
452
458
  weekday_selector.each do |wd|
453
459
  if !(@RGX_HOLIDAY =~ wd).nil?
454
- holidays << wd
460
+ weekdays << {from: -2, to: -2}
455
461
  elsif !(@RGX_WD =~ wd).nil?
456
462
  single_weekday = wd.split('-')
457
463
 
@@ -468,10 +474,10 @@ module OpeningHoursConverter
468
474
  end
469
475
  end
470
476
 
471
- { weekdays: weekdays, holidays: holidays }
477
+ weekdays
472
478
  end
473
479
 
474
- def remove_interval(date_range, weekdays, times)
480
+ def remove_interval(date_range, weekdays)
475
481
  if date_range.typical.instance_of?(OpeningHoursConverter::Day)
476
482
  date_range.typical.clear_intervals
477
483
  else
@@ -530,6 +536,33 @@ module OpeningHoursConverter
530
536
  end
531
537
  end
532
538
 
539
+ def add_off_interval(date_range, weekdays)
540
+ if date_range.typical.instance_of?(OpeningHoursConverter::Day)
541
+ if weekdays[:from] != 0
542
+ weekdays = weekdays.dup
543
+ weekdays[:from] = 0
544
+ if times[:from] <= times[:to]
545
+ weekdays[:to] = 0
546
+ else
547
+ weekdays[:to] = 1
548
+ end
549
+ end
550
+ end
551
+
552
+ if weekdays[:from] <= weekdays[:to]
553
+ for wd in weekdays[:from]..weekdays[:to]
554
+ date_range.typical.add_interval(OpeningHoursConverter::Interval.new(wd, 0, wd, 24*60, true))
555
+ end
556
+ else
557
+ for wd in weekdays[:from]..6
558
+ date_range.typical.add_interval(OpeningHoursConverter::Interval.new(wd, 0, wd, 24*60, true))
559
+ end
560
+ for wd in 0..weekdays[:to]
561
+ date_range.typical.add_interval(OpeningHoursConverter::Interval.new(wd, 0, wd, 24*60, true))
562
+ end
563
+ end
564
+ end
565
+
533
566
  def add_interval_wd(typical, times, wd)
534
567
  if times[:to] >= times[:from]
535
568
  typical.add_interval(OpeningHoursConverter::Interval.new(wd, times[:from], wd, times[:to]))
@@ -546,11 +579,32 @@ module OpeningHoursConverter
546
579
  def tokenize(block)
547
580
  if block.split('"').length > 1
548
581
  comment = block.split('"')[1]
549
- tokens = block.split('"')[0].split(' ')
582
+ tokens = block.split('"')[0].split(/\s|,/)
550
583
  tokens << "\"#{comment}\""
584
+ merge_weekdays_tokens(tokens)
551
585
  else
552
- block.split(' ')
586
+ merge_weekdays_tokens(block.split(/\s|,/))
587
+ end
588
+ end
589
+
590
+ def merge_weekdays_tokens(tokens)
591
+ new_tokens = []
592
+ to_merge = []
593
+ tokens.each_with_index do |token, index|
594
+ if is_weekday?(token)
595
+ to_merge << token
596
+ if index == tokens.length - 1
597
+ new_tokens << to_merge.join(',')
598
+ end
599
+ elsif !to_merge.empty?
600
+ new_tokens << to_merge.join(',')
601
+ new_tokens << token
602
+ to_merge = []
603
+ else
604
+ new_tokens << token
605
+ end
553
606
  end
607
+ new_tokens
554
608
  end
555
609
 
556
610
  def as_minutes(time)
@@ -3,25 +3,18 @@ require 'opening_hours_converter/constants'
3
3
  module OpeningHoursConverter
4
4
  class OpeningHoursRule
5
5
  include Constants
6
- attr_accessor :date, :time, :comment
6
+ attr_accessor :date, :time, :comment, :is_defined_off
7
7
 
8
8
  def initialize
9
9
  @date = []
10
10
  @time = []
11
+ @is_defined_off = false
11
12
  @comment = ""
12
13
  end
13
14
 
14
15
  def get
15
16
  result = ""
16
- if @date.length == 1 && @date[0].wide_type == "holiday"
17
- if !@date[0].wide.start[:year].nil?
18
- result += @date[0].wide.start[:year].to_s
19
- end
20
- if !@date[0].wide.end.nil?
21
- result += "-#{@date[0].wide.end[:year].to_s}"
22
- end
23
- result += " PH"
24
- elsif @date.length > 0
17
+ if @date.length > 0
25
18
  result += get_wide_selector
26
19
  end
27
20
 
@@ -31,7 +24,9 @@ module OpeningHoursConverter
31
24
  result += " #{wd}"
32
25
  end
33
26
  end
34
- if @time.length > 0
27
+ if @is_defined_off
28
+ result += " off"
29
+ elsif @time.length > 0
35
30
  result += " "
36
31
  @time.uniq.each_with_index do |t, i|
37
32
  if (i > 0)
@@ -57,8 +52,18 @@ module OpeningHoursConverter
57
52
  end
58
53
 
59
54
  def get_wide_selector
55
+ if @date.length == 1 && @date[0].wide.type == "holiday"
56
+ if @date[0].wide.start[:year].nil?
57
+ return "PH"
58
+ else
59
+ if @date[0].wide.end && @date[0].wide.end[:year]
60
+ return "#{@date[0].wide.start[:year]}-#{@date[0].wide.end[:year]} PH"
61
+ else
62
+ return "#{@date[0].wide.start[:year]} PH"
63
+ end
64
+ end
65
+ end
60
66
  years = OpeningHoursConverter::Year.build_day_array_from_dates(@date)
61
-
62
67
  year_start = -1
63
68
  month_start = -1
64
69
  day_start = -1
@@ -1,6 +1,6 @@
1
1
  module OpeningHoursConverter
2
2
  class OpeningHoursTime
3
- attr_reader :start, :end
3
+ attr_reader :start, :end, :priority
4
4
 
5
5
  def initialize(minute_start=nil, minute_end=nil)
6
6
  @start = minute_start
@@ -17,14 +17,26 @@ module OpeningHoursConverter
17
17
  for day in interval.day_start..interval.day_end
18
18
  start_minute = (day == interval.day_start) ? interval.start : 0
19
19
  end_minute = (day == interval.day_end) ? interval.end : MINUTES_MAX
20
- if start_minute && end_minute
21
- for minute in start_minute..end_minute
22
- minute_array[day][minute] = true
20
+ if interval.is_off
21
+ if start_minute && end_minute
22
+ for minute in 0..MINUTES_MAX
23
+ minute_array[day][minute] = "off"
24
+ end
25
+ end
26
+ else
27
+ if start_minute && end_minute
28
+ if minute_array[day][0] == "off"
29
+ minute_array[day] = Array.new(MINUTES_MAX + 1, false)
30
+ end
31
+ for minute in start_minute..end_minute
32
+ minute_array[day][minute] = true
33
+ end
23
34
  end
24
35
  end
25
36
  end
26
37
  end
27
38
  end
39
+
28
40
  minute_array
29
41
  end
30
42
 
@@ -35,37 +47,41 @@ module OpeningHoursConverter
35
47
  day_start = -1
36
48
  minute_start = -1
37
49
  minute_end = nil
38
-
39
-
50
+ off = false
40
51
  minute_array.each_with_index do |day, day_index|
41
52
  day.each_with_index do |minute, minute_index|
42
53
  if day_index == 0 && minute_index == 0
43
54
  if minute
55
+ off = true if minute == "off"
44
56
  day_start = day_index
45
57
  minute_start = minute_index
46
58
  end
47
59
  elsif minute && day_index == DAYS_MAX && minute_index == day.length - 1
60
+ off = true if minute == "off"
48
61
  if day_start >= 0
49
- intervals << OpeningHoursConverter::Interval.new(day_start, minute_start, day_index, minute_index)
62
+ intervals << OpeningHoursConverter::Interval.new(day_start, minute_start, day_index, minute_index, off)
50
63
  else
51
- intervals << OpeningHoursConverter::Interval.new(6, minute_index, 6, minute_index)
64
+ intervals << OpeningHoursConverter::Interval.new(6, minute_index, 6, minute_index, off)
52
65
  end
53
66
  else
54
67
  if minute && day_start < 0
68
+ off = true if minute == "off"
55
69
  day_start = day_index
56
70
  minute_start = minute_index
57
71
  elsif !minute && day_start >= 0
58
72
  if minute_index == 0
59
- intervals << OpeningHoursConverter::Interval.new(day_start, minute_start, day_index - 1, MINUTES_MAX)
73
+ intervals << OpeningHoursConverter::Interval.new(day_start, minute_start, day_index - 1, MINUTES_MAX, off)
60
74
  else
61
- intervals << OpeningHoursConverter::Interval.new(day_start, minute_start, day_index, minute_index - 1)
75
+ intervals << OpeningHoursConverter::Interval.new(day_start, minute_start, day_index, minute_index - 1, off)
62
76
  end
77
+ off = false
63
78
  day_start = -1
64
79
  minute_start = - 1
65
80
  end
66
81
  end
67
82
  end
68
83
  end
84
+
69
85
  return intervals
70
86
  else
71
87
  return @intervals
@@ -76,16 +92,19 @@ module OpeningHoursConverter
76
92
  self_minutes_array = get_as_minute_array
77
93
  other_minutes_array = week.get_as_minute_array
78
94
 
95
+
79
96
  intervals = { open: [], closed: [] }
80
97
  day_start = -1
81
98
  min_start = -1
82
99
 
83
-
84
100
  for d in 0..DAYS_MAX
85
101
  diff_day = false
86
102
  m = 0
103
+ off = false
87
104
  intervals_length = intervals[:open].length
88
105
  while m <= MINUTES_MAX
106
+ off = self_minutes_array[d][m] == "off"
107
+ break if off
89
108
  # Copy entire day
90
109
  if diff_day
91
110
  # first minute of monday
@@ -97,7 +116,7 @@ module OpeningHoursConverter
97
116
  # last minute of sunday
98
117
  elsif d == DAYS_MAX && m == MINUTES_MAX
99
118
  if day_start >= 0 && self_minutes_array[d][m]
100
- intervals[:open] << OpeningHoursConverter::Interval.new(day_start, min_start, d, m)
119
+ intervals[:open] << OpeningHoursConverter::Interval.new(day_start, min_start, d, m, off)
101
120
  end
102
121
  # other days and minutes
103
122
  else
@@ -108,9 +127,9 @@ module OpeningHoursConverter
108
127
  # end interval
109
128
  elsif !self_minutes_array[d][m] && day_start >= 0
110
129
  if m == 0
111
- intervals[:open] << OpeningHoursConverter::Interval.new(day_start, min_start, d - 1, MINUTES_MAX)
130
+ intervals[:open] << OpeningHoursConverter::Interval.new(day_start, min_start, d - 1, MINUTES_MAX, off)
112
131
  else
113
- intervals[:open] << OpeningHoursConverter::Interval.new(day_start, min_start, d, m - 1)
132
+ intervals[:open] << OpeningHoursConverter::Interval.new(day_start, min_start, d, m - 1, off)
114
133
  end
115
134
  day_start = -1
116
135
  min_start = -1
@@ -119,7 +138,12 @@ module OpeningHoursConverter
119
138
  m += 1
120
139
  # check diff
121
140
  else
122
- diff_day = self_minutes_array[d][m] ? !other_minutes_array[d][m] : other_minutes_array[d][m]
141
+ if !self_minutes_array[d][m]
142
+ diff_day = other_minutes_array[d][m] != "off" && other_minutes_array[d][m]
143
+ else
144
+ diff_day = other_minutes_array[d][m] == "off" || !other_minutes_array[d][m]
145
+ end
146
+
123
147
  if diff_day
124
148
  m = 0
125
149
  else
@@ -127,19 +151,20 @@ module OpeningHoursConverter
127
151
  end
128
152
  end
129
153
  end
130
- if !diff_day && day_start > -1
131
- intervals[:open] << OpeningHoursConverter::Interval.new(day_start, min_start, d-1, MINUTES_MAX)
154
+ if !diff_day && day_start > -1 && !off
155
+ intervals[:open] << OpeningHoursConverter::Interval.new(day_start, min_start, d-1, MINUTES_MAX, off)
132
156
  day_start = -1
133
157
  min_start = -1
134
158
  end
135
- if diff_day && day_start == -1 && intervals_length == intervals[:open].length
159
+ if diff_day && day_start == -1 && intervals_length == intervals[:open].length || off
136
160
  if intervals[:closed].length > 0 && intervals[:closed][intervals[:closed].length - 1].day_end == d - 1
137
- intervals[:closed][intervals[:closed].length - 1] = OpeningHoursConverter::Interval.new(intervals[:closed][intervals[:closed].length - 1].day_start, 0, d, MINUTES_MAX)
161
+ intervals[:closed][-1] = OpeningHoursConverter::Interval.new(intervals[:closed].last.day_start, 0, d, MINUTES_MAX, off)
138
162
  else
139
- intervals[:closed] << OpeningHoursConverter::Interval.new(d, 0, d, MINUTES_MAX)
163
+ intervals[:closed] << OpeningHoursConverter::Interval.new(d, 0, d, MINUTES_MAX, off)
140
164
  end
141
165
  end
142
166
  end
167
+
143
168
  return intervals
144
169
  end
145
170
 
@@ -165,10 +190,10 @@ module OpeningHoursConverter
165
190
  if day_diff > 1 || day_diff == 0 || interval.day_start == day || interval.start <= interval.end
166
191
  if interval.day_end - interval.day_start >= 1 && interval.start <= interval.end
167
192
  if interval.day_start < day
168
- add_interval(OpeningHoursConverter::Interval.new(interval.day_start, interval.start, day - 1, 24*60))
193
+ add_interval(OpeningHoursConverter::Interval.new(interval.day_start, interval.start, day - 1, 24*60, interval.is_off))
169
194
  end
170
195
  if interval.day_end > day
171
- add_interval(OpeningHoursConverter::Interval.new(day + 1, 0, interval.day_end, interval.end))
196
+ add_interval(OpeningHoursConverter::Interval.new(day + 1, 0, interval.day_end, interval.end, interval.is_off))
172
197
  end
173
198
  end
174
199
  remove_interval(i)
@@ -184,8 +209,9 @@ module OpeningHoursConverter
184
209
 
185
210
  def copy_intervals(intervals)
186
211
  @intervals = []
212
+
187
213
  intervals.each do |interval|
188
- unless interval.nil?
214
+ if !interval.nil? && !interval.is_off
189
215
  @intervals << interval.dup
190
216
  end
191
217
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opening_hours_converter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.3
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ziserman Martin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-21 00:00:00.000000000 Z
11
+ date: 2017-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json