Class: Timely::DateChooser

Inherits:
Object
  • Object
show all
Defined in:
lib/timely/date_chooser.rb

Constant Summary collapse

INTERVALS =

Where is this used… so far only in one place, _date_range.html.haml May be good to refactor this as well, after the class behaviour is refactored.

[
  { code: 'week', name: 'week(s)', description: 'Weekdays selected will be chosen every {{n}} weeks for the date range' },
  { code: 'week_of_month', name: 'week of month', description:           'Weekdays selected will be chosen in their {{ord}} occurance every month,
      e.g. if wednesday and thursday are selected, the first wednesday and
      first thursday are selected. Note: this may mean the booking is copied
      to Thursday 1st and Wednesday 7th' }
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ DateChooser

Returns a new instance of DateChooser.



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/timely/date_chooser.rb', line 17

def initialize(options)
  @multiple_dates = options[:multiple_dates] || false
  @from     = process_date(options[:from])
  @to       = process_date(options[:to])
  @select   = options[:select]
  @dates    = options[:dates]
  @specific_dates = options[:specific_dates]
  @interval = options[:interval]
  @weekdays = WeekDays.new(options[:weekdays]) if @select == 'weekdays'
  validate
end

Instance Attribute Details

#datesObject

Returns the value of attribute dates.



15
16
17
# File 'lib/timely/date_chooser.rb', line 15

def dates
  @dates
end

#fromObject

Returns the value of attribute from.



15
16
17
# File 'lib/timely/date_chooser.rb', line 15

def from
  @from
end

#intervalObject

Returns the value of attribute interval.



15
16
17
# File 'lib/timely/date_chooser.rb', line 15

def interval
  @interval
end

#multiple_datesObject

Returns the value of attribute multiple_dates.



15
16
17
# File 'lib/timely/date_chooser.rb', line 15

def multiple_dates
  @multiple_dates
end

#selectObject

Returns the value of attribute select.



15
16
17
# File 'lib/timely/date_chooser.rb', line 15

def select
  @select
end

#toObject

Returns the value of attribute to.



15
16
17
# File 'lib/timely/date_chooser.rb', line 15

def to
  @to
end

#weekdaysObject

Returns the value of attribute weekdays.



15
16
17
# File 'lib/timely/date_chooser.rb', line 15

def weekdays
  @weekdays
end

Instance Method Details

#choose_datesObject

Chooses a set of dates from a date range, based on conditions. date_info - A hash with conditions and date information

:from     - The start of the date range
:to       - The end of the date range

You can either specify specific dates to be chosen each month:

:dates          - A comma separated string of days of the month, e.g. 1,16
:specific_dates - A comma separated string of dates, e.g. 26-10-2012, 03-11-2012, 01-01-2013

or you can specify how to select the dates

:day      - A hash of days, the index being the wday, e.g. 0 = sunday, and the value being 1 if chosen
:interval - A hash of information about the interval
  :level  - The level/multiplier of the interval unit
  :unit   - The unit of the interval, e.g. w for week, mow for month of week
  e.g. :level => 2, :unit => w would try to select the days of the week every fortnight,
       so every friday and saturday each fornight


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/timely/date_chooser.rb', line 54

def choose_dates
  # Not multiple dates - just return the From date.
  return [@from] unless @multiple_dates

  # Multiple dates - return the array, adjusted as per input
  all_days = (@from..@to).to_a

  case @select
  when 'days'
    days = @dates.gsub(/\s/, '').split(',')
    all_days.select { |date| days.include?(date.mday.to_s) }
  when 'specific_days'
    days = @specific_dates.gsub(/\s/, '').split(',')
    days.map(&:to_date)
  when 'weekdays'
    raise DateChooserException, 'No days of the week selected' if @weekdays.weekdays.empty?
    raise DateChooserException, 'No weekly interval selected' if @interval&.empty?

    all_days.select do |date|
      next unless @weekdays.has_day?(date.wday)

      case @interval[:unit]
      when 'week'
        # 0 = first week, 1 = second week, 2 = third week, etc.
        nth_week = (date - @from).to_i / 7
        # true every 2nd week (0, 2, 4, 6, etc.)
        (nth_week % @interval[:level].to_i).zero?
      when 'week_of_month'
        week = @interval[:level].to_i
        (date.mday > (week - 1) * 7 && date.mday <= week * 7)
      end
    end
  else
    all_days
  end
end

#process_date(date) ⇒ Object



29
30
31
32
33
34
35
36
# File 'lib/timely/date_chooser.rb', line 29

def process_date(date)
  case date
  when Date then date
  when NilClass then nil
  when String
    date !~ /[^[:space:]]/ ? nil : date.to_date
  end
end