timely 0.5.0 → 0.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 +4 -4
- data/.rubocop.yml +22 -2
- data/.travis.yml +0 -6
- data/CHANGELOG.md +6 -0
- data/Gemfile +2 -0
- data/Rakefile +6 -4
- data/gemfiles/rails5.gemfile +4 -2
- data/gemfiles/rails6.gemfile +3 -1
- data/lib/timely/date.rb +6 -2
- data/lib/timely/date_chooser.rb +29 -30
- data/lib/timely/date_range.rb +17 -19
- data/lib/timely/date_time.rb +3 -1
- data/lib/timely/rails/calendar_tag.rb +3 -3
- data/lib/timely/rails/date.rb +3 -1
- data/lib/timely/rails/date_group.rb +24 -24
- data/lib/timely/rails/date_range_validity_module.rb +8 -6
- data/lib/timely/rails/date_time.rb +5 -3
- data/lib/timely/rails/extensions.rb +12 -37
- data/lib/timely/rails/period.rb +14 -12
- data/lib/timely/rails/season.rb +14 -33
- data/lib/timely/rails/time.rb +7 -3
- data/lib/timely/rails.rb +2 -0
- data/lib/timely/railtie.rb +2 -0
- data/lib/timely/range.rb +4 -2
- data/lib/timely/string.rb +4 -2
- data/lib/timely/time.rb +7 -3
- data/lib/timely/time_since.rb +5 -3
- data/lib/timely/trackable_date_set.rb +21 -21
- data/lib/timely/version.rb +3 -1
- data/lib/timely/week_days.rb +14 -16
- data/lib/timely.rb +2 -0
- data/rails/init.rb +2 -0
- data/spec/calendar_tag_spec.rb +11 -10
- data/spec/date_chooser_spec.rb +67 -62
- data/spec/date_group_spec.rb +18 -15
- data/spec/date_range_spec.rb +29 -19
- data/spec/date_spec.rb +3 -1
- data/spec/extensions_spec.rb +5 -9
- data/spec/rails/date_spec.rb +5 -3
- data/spec/rails/date_time_spec.rb +9 -7
- data/spec/rails/period_spec.rb +2 -0
- data/spec/rails/time_spec.rb +6 -4
- data/spec/schema.rb +4 -3
- data/spec/season_spec.rb +23 -26
- data/spec/spec_helper.rb +3 -1
- data/spec/support/coverage_loader.rb +3 -1
- data/spec/temporal_patterns_spec.rb +5 -5
- data/spec/time_since_spec.rb +6 -4
- data/spec/time_spec.rb +6 -4
- data/spec/trackable_date_set_spec.rb +20 -18
- data/spec/week_days_spec.rb +24 -22
- data/timely.gemspec +20 -18
- metadata +32 -20
- data/spec/string_spec.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6fd5bf30099265da88c4957079fd58a4db290fac8cd4ad239ddb395be546d5d3
|
4
|
+
data.tar.gz: d263dca100292aae36f54b22cc2f3b1eebc1c1df0274fc3ef730ce991fc94c4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 784aede0c406afe8e0213f275150ee3bba930969c28acf9ac2e992a96ce42c7f30e042a6e0ae9779dc17f86e6a7744c4b0a07bf72e1d326d6e6176b3ac4b28c4
|
7
|
+
data.tar.gz: a780a85c02adcf074c53376c7995739d609329256b76c370966bedaccf953e0e3cb7607cb0d381873a8a4585b48505c8d2d04f68bebdc94f0b49c947bab84d28
|
data/.rubocop.yml
CHANGED
@@ -1,8 +1,28 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.6
|
3
|
+
Exclude:
|
4
|
+
- lib/timely/temporal_patterns/*.rb
|
5
|
+
|
1
6
|
Metrics/LineLength:
|
2
|
-
Max:
|
7
|
+
Max: 200
|
3
8
|
|
4
9
|
Style/Documentation:
|
5
10
|
Enabled: false
|
6
11
|
|
7
12
|
Style/FrozenStringLiteralComment:
|
8
|
-
Enabled:
|
13
|
+
Enabled: true
|
14
|
+
|
15
|
+
Metrics/BlockLength:
|
16
|
+
Enabled: false
|
17
|
+
|
18
|
+
Metrics/MethodLength:
|
19
|
+
Enabled: false
|
20
|
+
|
21
|
+
Metrics/AbcSize:
|
22
|
+
Enabled: false
|
23
|
+
|
24
|
+
Metrics/CyclomaticComplexity:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
Metrics/PerceivedComplexity:
|
28
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.6.0
|
4
|
+
|
5
|
+
* [TT-6402] Require date group weekdays bit field to be not null/nil
|
6
|
+
IMPORTANT: Rails projects must add a migration to make this field not null!
|
7
|
+
* [TT-6401] Remove Rails 3 support, unused methods
|
8
|
+
|
3
9
|
## 0.5.0
|
4
10
|
|
5
11
|
* [TT-6193] Date group scopes for more efficient searches/restrictions
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
2
4
|
|
3
5
|
desc 'Default: run specs.'
|
4
|
-
task :
|
6
|
+
task default: :spec
|
5
7
|
|
6
8
|
require 'rspec/core/rake_task'
|
7
9
|
|
8
|
-
desc
|
10
|
+
desc 'Run specs'
|
9
11
|
RSpec::Core::RakeTask.new do |t|
|
10
|
-
t.pattern =
|
12
|
+
t.pattern = './spec/**/*_spec.rb' # don't need this, it's default.
|
11
13
|
# Put spec opts in a file named .rspec in root
|
12
14
|
end
|
data/gemfiles/rails5.gemfile
CHANGED
data/gemfiles/rails6.gemfile
CHANGED
data/lib/timely/date.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Timely
|
2
4
|
module Date
|
3
5
|
def at_time(hour = nil, minute = nil, second = nil)
|
4
6
|
if hour.is_a?(::Time)
|
5
7
|
time = hour
|
6
|
-
hour
|
8
|
+
hour = time.hour
|
9
|
+
minute = time.min
|
10
|
+
second = time.sec
|
7
11
|
end
|
8
12
|
|
9
13
|
::Time.local(year, month, day, hour, minute, second)
|
10
14
|
end
|
11
15
|
|
12
|
-
|
16
|
+
alias at at_time
|
13
17
|
|
14
18
|
# returns true if date between from and to
|
15
19
|
# however if from and/or to are nil, it ignores that query
|
data/lib/timely/date_chooser.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Timely
|
2
4
|
class DateChooser
|
3
5
|
# Where is this used... so far only in one place, _date_range.html.haml
|
4
6
|
# May be good to refactor this as well, after the class behaviour is refactored.
|
5
7
|
INTERVALS = [
|
6
|
-
{:
|
7
|
-
|
8
|
-
{:code => 'week_of_month', :name => 'week of month', :description =>
|
9
|
-
'Weekdays selected will be chosen in their {{ord}} occurance every month,
|
8
|
+
{ code: 'week', name: 'week(s)', description: 'Weekdays selected will be chosen every {{n}} weeks for the date range' },
|
9
|
+
{ code: 'week_of_month', name: 'week of month', description: 'Weekdays selected will be chosen in their {{ord}} occurance every month,
|
10
10
|
e.g. if wednesday and thursday are selected, the first wednesday and
|
11
11
|
first thursday are selected. Note: this may mean the booking is copied
|
12
|
-
to Thursday 1st and Wednesday 7th'}
|
13
|
-
]
|
12
|
+
to Thursday 1st and Wednesday 7th' }
|
13
|
+
].freeze
|
14
14
|
|
15
|
-
attr_accessor
|
15
|
+
attr_accessor :multiple_dates, :from, :to, :select, :dates, :interval, :weekdays
|
16
16
|
|
17
17
|
def initialize(options)
|
18
18
|
@multiple_dates = options[:multiple_dates] || false
|
@@ -28,8 +28,8 @@ module Timely
|
|
28
28
|
|
29
29
|
def process_date(date)
|
30
30
|
case date
|
31
|
-
when Date
|
32
|
-
when NilClass
|
31
|
+
when Date then date
|
32
|
+
when NilClass then nil
|
33
33
|
when String
|
34
34
|
date !~ /[^[:space:]]/ ? nil : date.to_date
|
35
35
|
end
|
@@ -53,7 +53,7 @@ module Timely
|
|
53
53
|
# so every friday and saturday each fornight
|
54
54
|
def choose_dates
|
55
55
|
# Not multiple dates - just return the From date.
|
56
|
-
return [@from]
|
56
|
+
return [@from] unless @multiple_dates
|
57
57
|
|
58
58
|
# Multiple dates - return the array, adjusted as per input
|
59
59
|
all_days = (@from..@to).to_a
|
@@ -66,21 +66,21 @@ module Timely
|
|
66
66
|
days = @specific_dates.gsub(/\s/, '').split(',')
|
67
67
|
days.map(&:to_date)
|
68
68
|
when 'weekdays'
|
69
|
-
raise DateChooserException,
|
70
|
-
raise DateChooserException,
|
69
|
+
raise DateChooserException, 'No days of the week selected' if @weekdays.weekdays.empty?
|
70
|
+
raise DateChooserException, 'No weekly interval selected' if @interval&.empty?
|
71
71
|
|
72
72
|
all_days.select do |date|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
73
|
+
next unless @weekdays.has_day?(date.wday)
|
74
|
+
|
75
|
+
case @interval[:unit]
|
76
|
+
when 'week'
|
77
|
+
# 0 = first week, 1 = second week, 2 = third week, etc.
|
78
|
+
nth_week = (date - @from).to_i / 7
|
79
|
+
# true every 2nd week (0, 2, 4, 6, etc.)
|
80
|
+
(nth_week % @interval[:level].to_i).zero?
|
81
|
+
when 'week_of_month'
|
82
|
+
week = @interval[:level].to_i
|
83
|
+
(date.mday > (week - 1) * 7 && date.mday <= week * 7)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
else
|
@@ -89,15 +89,14 @@ module Timely
|
|
89
89
|
end
|
90
90
|
|
91
91
|
private
|
92
|
+
|
92
93
|
def validate
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
raise DateChooserException, "Start Date is after End Date" if @from > @to
|
98
|
-
end
|
94
|
+
raise DateChooserException, 'A Start Date is required' unless @from
|
95
|
+
raise DateChooserException, 'Start Date is after End Date' if @multiple_dates && @to && @from > @to
|
96
|
+
|
97
|
+
@to ||= @from if @multiple_dates
|
99
98
|
end
|
100
99
|
end
|
101
100
|
|
102
|
-
class DateChooserException <
|
101
|
+
class DateChooserException < RuntimeError; end
|
103
102
|
end
|
data/lib/timely/date_range.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Timely
|
4
4
|
class DateRange < ::Range
|
@@ -15,14 +15,14 @@ module Timely
|
|
15
15
|
super(args.first.to_date, args.last.to_date)
|
16
16
|
end
|
17
17
|
end
|
18
|
-
|
19
|
-
|
18
|
+
alias start_date first
|
19
|
+
alias end_date last
|
20
20
|
|
21
21
|
def self.validate_range(first, last)
|
22
|
-
raise ArgumentError,
|
23
|
-
raise ArgumentError,
|
24
|
-
raise ArgumentError,
|
25
|
-
raise ArgumentError,
|
22
|
+
raise ArgumentError, 'Date range missing start date' if first.nil?
|
23
|
+
raise ArgumentError, 'Date range missing end date' if last.nil?
|
24
|
+
raise ArgumentError, 'Start date is not a date' unless first.is_a? Date
|
25
|
+
raise ArgumentError, 'End date is not a date' unless last.is_a? Date
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.from_params(start_date, duration = nil)
|
@@ -33,19 +33,18 @@ module Timely
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def intersecting_dates(date_range)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
36
|
+
r_start = [start_date, date_range.first].max
|
37
|
+
r_end = [end_date, date_range.last].min
|
38
|
+
|
39
|
+
return [] if r_end < r_start
|
40
|
+
|
41
|
+
r_start..r_end
|
43
42
|
end
|
44
43
|
|
45
44
|
def number_of_nights
|
46
45
|
((last - first) + 1).to_i
|
47
46
|
end
|
48
|
-
|
47
|
+
alias duration number_of_nights
|
49
48
|
|
50
49
|
def to_s(fmt = '%b %Y', date_fmt = '%Y-%m-%d')
|
51
50
|
Timely::DateRange.to_s(first, last, fmt, date_fmt)
|
@@ -65,21 +64,20 @@ module Timely
|
|
65
64
|
"#{first.strftime(month_fmt)} to #{last.strftime(month_fmt)}"
|
66
65
|
end
|
67
66
|
else
|
68
|
-
"#{first.strftime(fmt)} to #{last.strftime(fmt)}#{
|
67
|
+
"#{first.strftime(fmt)} to #{last.strftime(fmt)}#{' (inclusive)' if is_date}"
|
69
68
|
end
|
70
69
|
elsif first
|
71
70
|
"on or after #{first.strftime(fmt)}"
|
72
71
|
elsif last
|
73
72
|
"on or before #{last.strftime(fmt)}"
|
74
73
|
else
|
75
|
-
|
74
|
+
'no date range'
|
76
75
|
end
|
77
76
|
end
|
78
77
|
|
79
|
-
|
80
78
|
private
|
81
79
|
|
82
|
-
def self.default_date_format
|
80
|
+
private_class_method def self.default_date_format
|
83
81
|
# ::Date as we want Ruby's Date not Timely::Date
|
84
82
|
date_format = ::Date::DATE_FORMATS[:short] if ::Date.const_defined?('DATE_FORMATS')
|
85
83
|
date_format || '%Y-%m-%d'
|
data/lib/timely/date_time.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Timely
|
2
4
|
# Uses Date.current to be more accurate for Rails applications
|
3
5
|
def self.current_date
|
4
6
|
::Date.respond_to?(:current) ? ::Date.current : ::Date.today
|
5
7
|
end
|
6
8
|
|
7
|
-
|
8
9
|
module ActionViewHelpers
|
9
10
|
module FormTagHelper
|
10
11
|
def calendar_tag(name, value = Timely.current_date, *args)
|
@@ -24,11 +25,10 @@ module Timely
|
|
24
25
|
options[:size] ||= 10
|
25
26
|
options[:maxlength] ||= 10
|
26
27
|
|
27
|
-
tag(:input, options.merge(:
|
28
|
+
tag(:input, options.merge(name: name, type: 'text', value: value)).html_safe
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
31
|
-
|
32
32
|
module DateHelper
|
33
33
|
def calendar(object_name, method, options = {})
|
34
34
|
value = options[:object] || Timely.current_date
|
data/lib/timely/rails/date.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Timely
|
2
4
|
class DateGroup < ActiveRecord::Base
|
3
|
-
belongs_to :season, :
|
5
|
+
belongs_to :season, class_name: 'Timely::Season', optional: true, inverse_of: :date_groups
|
4
6
|
|
5
7
|
weekdays_field :weekdays
|
6
8
|
|
9
|
+
validates :weekdays_bit_array, presence: true
|
7
10
|
validates_presence_of :start_date, :end_date
|
8
11
|
validate :validate_date_range!
|
9
12
|
|
@@ -16,16 +19,12 @@ module Timely
|
|
16
19
|
# IMPORTANT: Required for correctness in case of string param.
|
17
20
|
dates = Array(date_range)
|
18
21
|
scope = covering_date(dates.first)
|
19
|
-
if dates.first != dates.last
|
20
|
-
scope = scope.or(covering_date(dates.last))
|
21
|
-
end
|
22
|
+
scope = scope.or(covering_date(dates.last)) if dates.first != dates.last
|
22
23
|
scope
|
23
24
|
}
|
24
25
|
|
25
26
|
scope :for_any_weekdays, lambda { |weekdays_int|
|
26
|
-
|
27
|
-
where((arel_table[:weekdays_bit_array] & weekdays_int).not_eq(0))
|
28
|
-
.or(where(weekdays_bit_array: nil))
|
27
|
+
where((arel_table[:weekdays_bit_array] & weekdays_int.to_i).not_eq(0))
|
29
28
|
}
|
30
29
|
|
31
30
|
scope :applying_for_duration, lambda { |date_range|
|
@@ -43,7 +42,7 @@ module Timely
|
|
43
42
|
elsif weekdays.all_days?
|
44
43
|
true
|
45
44
|
else
|
46
|
-
date_range.intersecting_dates(start_date..end_date).any?{|d| weekdays.applies_for_date?(d)}
|
45
|
+
date_range.intersecting_dates(start_date..end_date).any? { |d| weekdays.applies_for_date?(d) }
|
47
46
|
end
|
48
47
|
end
|
49
48
|
|
@@ -70,30 +69,31 @@ module Timely
|
|
70
69
|
date_groups = []
|
71
70
|
Array.wrap(patterns).each do |pattern|
|
72
71
|
if pattern.frequency.unit == :weeks
|
73
|
-
weekdays = pattern.intervals.map { |i| i.first_datetime.wday }.
|
72
|
+
weekdays = pattern.intervals.map { |i| i.first_datetime.wday }.each_with_object({}) do |wday, hash|
|
74
73
|
hash[wday] = 1
|
75
|
-
hash
|
76
74
|
end
|
77
75
|
date_groups << DateGroup.new(
|
78
|
-
:
|
79
|
-
:
|
80
|
-
:
|
76
|
+
start_date: pattern.first_datetime.to_date,
|
77
|
+
end_date: pattern.last_datetime.to_date,
|
78
|
+
weekdays: weekdays
|
79
|
+
)
|
81
80
|
elsif pattern.frequency.unit == :days && pattern.frequency.duration == 1.day
|
82
81
|
date_groups << DateGroup.new(
|
83
|
-
:
|
84
|
-
:
|
85
|
-
:
|
82
|
+
start_date: pattern.first_datetime.to_date,
|
83
|
+
end_date: pattern.last_datetime.to_date,
|
84
|
+
weekdays: 127
|
85
|
+
)
|
86
86
|
else
|
87
87
|
pattern.datetimes.each do |datetimes|
|
88
88
|
datetimes.group_by(&:week).values.each do |dates|
|
89
|
-
weekdays = dates.map(&:wday).
|
89
|
+
weekdays = dates.map(&:wday).each_with_object({}) do |wday, hash|
|
90
90
|
hash[wday] = 1
|
91
|
-
hash
|
92
91
|
end
|
93
92
|
date_groups << DateGroup.new(
|
94
|
-
:
|
95
|
-
:
|
96
|
-
:
|
93
|
+
start_date: dates.min.to_date.beginning_of_week,
|
94
|
+
end_date: dates.max.to_date.end_of_week,
|
95
|
+
weekdays: weekdays
|
96
|
+
)
|
97
97
|
end
|
98
98
|
end
|
99
99
|
end
|
@@ -104,9 +104,9 @@ module Timely
|
|
104
104
|
private
|
105
105
|
|
106
106
|
def validate_date_range!
|
107
|
-
|
108
|
-
|
109
|
-
|
107
|
+
return unless start_date && end_date && start_date > end_date
|
108
|
+
|
109
|
+
raise ArgumentError, "Incorrect date range #{start_date} is before #{end_date}"
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
@@ -1,25 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Timely
|
2
4
|
module DateRangeValidityModule
|
3
5
|
def self.included(base)
|
4
6
|
base.class_eval do
|
5
|
-
validates :from, :to, :
|
7
|
+
validates :from, :to, presence: true
|
6
8
|
end
|
7
9
|
end
|
8
10
|
|
9
11
|
def validity_range
|
10
|
-
(from
|
12
|
+
(from..to)
|
11
13
|
end
|
12
14
|
|
13
15
|
def correctness_of_date_range
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
return unless from.present? && to.present? && from > to
|
17
|
+
|
18
|
+
errors.add(:base, 'Invalid Date Range. From date should be less than or equal to To date')
|
17
19
|
end
|
18
20
|
|
19
21
|
def validity_range_to_s
|
20
22
|
"#{from.to_s(:short)} ~ #{to.to_s(:short)}"
|
21
23
|
end
|
22
|
-
|
24
|
+
|
23
25
|
def valid_on?(date)
|
24
26
|
validity_range.include?(date)
|
25
27
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RailsCoreExtensions
|
2
4
|
module DateTime
|
3
5
|
def advance_considering_calendar(units, num_units)
|
@@ -5,11 +7,11 @@ module RailsCoreExtensions
|
|
5
7
|
when :seconds, :minutes, :hours, :days, :weeks, :months, :years
|
6
8
|
advance(units => num_units)
|
7
9
|
when :calendar_days
|
8
|
-
advance(:
|
10
|
+
advance(days: num_units - 1).end_of_day
|
9
11
|
when :calendar_months
|
10
|
-
advance(:
|
12
|
+
advance(months: num_units - 1).end_of_month
|
11
13
|
when :calendar_years
|
12
|
-
advance(:
|
14
|
+
advance(years: num_units - 1).end_of_year
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -1,55 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Timely
|
2
4
|
module Extensions
|
3
5
|
# Add a WeekDays attribute
|
4
6
|
#
|
5
7
|
# By default it will use attribute_bit_array as db field, but this can
|
6
8
|
# be overridden by specifying :db_field => 'somthing_else'
|
7
|
-
def weekdays_field(attribute, options={})
|
9
|
+
def weekdays_field(attribute, options = {})
|
8
10
|
db_field = options[:db_field] || attribute.to_s + '_bit_array'
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
)
|
11
|
+
composed_of(attribute,
|
12
|
+
class_name: '::Timely::WeekDays',
|
13
|
+
mapping: [[db_field, 'weekdays_int']],
|
14
|
+
converter: proc { |field| ::Timely::WeekDays.new(field) })
|
14
15
|
end
|
15
16
|
|
16
17
|
def acts_as_seasonal
|
17
|
-
belongs_to :season, :
|
18
|
+
belongs_to :season, class_name: 'Timely::Season', optional: true
|
18
19
|
accepts_nested_attributes_for :season
|
19
20
|
validates_associated :season
|
20
21
|
|
21
|
-
if ::ActiveRecord::VERSION::MAJOR >= 3
|
22
|
-
scope :season_on, lambda { |*args|
|
23
|
-
date = args.first || ::Date.current # Can't assign in block in Ruby 1.8
|
24
|
-
joins(:season => :date_groups).where("date_groups.start_date <= ? AND date_groups.end_date >= ?", date, date)
|
25
|
-
}
|
26
|
-
|
27
|
-
scope :available_from, lambda { |*args|
|
28
|
-
date = args.first || ::Date.current # Can't assign in block in Ruby 1.8
|
29
|
-
where("boundary_end >= ?", date)
|
30
|
-
}
|
31
|
-
else
|
32
|
-
named_scope :season_on, lambda { |*args|
|
33
|
-
date = args.first || ::Date.current # Can't assign in block in Ruby 1.8
|
34
|
-
{
|
35
|
-
:joins => {:season => :date_groups},
|
36
|
-
:conditions => ["date_groups.start_date <= ? AND date_groups.end_date >= ?", date, date]
|
37
|
-
}
|
38
|
-
}
|
39
|
-
|
40
|
-
named_scope :available_from, lambda { |*args|
|
41
|
-
date = args.first || ::Date.current # Can't assign in block in Ruby 1.8
|
42
|
-
{:conditions => ["boundary_end >= ?", date]}
|
43
|
-
}
|
44
|
-
end
|
45
|
-
|
46
22
|
before_save do |object|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
23
|
+
next unless object.season
|
24
|
+
|
25
|
+
object.boundary_start = object.season.boundary_start
|
26
|
+
object.boundary_end = object.season.boundary_end
|
51
27
|
end
|
52
28
|
end
|
53
29
|
end
|
54
30
|
end
|
55
|
-
|
data/lib/timely/rails/period.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Timely
|
2
4
|
class Period
|
3
5
|
attr_reader :number, :units
|
4
6
|
|
5
|
-
UNITS = [
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
]
|
7
|
+
UNITS = %i[
|
8
|
+
seconds
|
9
|
+
minutes
|
10
|
+
hours
|
11
|
+
days
|
12
|
+
weeks
|
13
|
+
months
|
14
|
+
years
|
15
|
+
calendar_days
|
16
|
+
calendar_months
|
17
|
+
calendar_years
|
18
|
+
].freeze
|
17
19
|
|
18
20
|
def initialize(number, units)
|
19
21
|
@number = number
|