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
         
     |