Class: RecurringTodos::MonthlyRepeatPattern

Inherits:
AbstractRepeatPattern show all
Defined in:
app/models/recurring_todos/monthly_repeat_pattern.rb

Instance Attribute Summary

Attributes inherited from AbstractRepeatPattern

#attributes

Instance Method Summary collapse

Methods inherited from AbstractRepeatPattern

#build_from_recurring_todo, #build_recurring_todo, #continues_recurring?, #day_of_week_as_text, #determine_start, #end_date, #ends_on, #errors, #find_last_day_x_of_month, #find_xth_day_of_month, #get, #get_due_date, #get_show_from_date, #get_xth_day_of_month, #month_of_year_as_text, #number_of_occurences, #put_in_tickler?, #recurring_target_as_text, #set_recurrence_on_validations, #show_always?, #show_from_delta, #start_from, #starts_and_ends_on_validations, #target, #update_recurring_todo, #valid?, #validate_not_blank, #validate_not_nil, #xth

Constructor Details

#initialize(user) ⇒ MonthlyRepeatPattern

Returns a new instance of MonthlyRepeatPattern


5
6
7
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 5

def initialize(user)
  super user
end

Instance Method Details

#day_of_weekObject


41
42
43
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 41

def day_of_week
  get :every_count
end

#every_x_dayObject


17
18
19
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 17

def every_x_day
  get(:every_other1)
end

#every_x_day?Boolean

Returns:

  • (Boolean)

13
14
15
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 13

def every_x_day?
  get(:recurrence_selector) == 0
end

#every_x_monthObject


25
26
27
28
29
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 25

def every_x_month
  # in case monthly pattern is every day x, return every_other2 otherwise
  # return a default value
  get(:recurrence_selector) == 0 ? get(:every_other2) : 1
end

#every_x_month2Object


31
32
33
34
35
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 31

def every_x_month2
  # in case monthly pattern is every xth day, return every_other2 otherwise
  # return a default value
  get(:recurrence_selector) == 1 ? get(:every_other2) : 1
end

#every_xth_day(default = nil) ⇒ Object


37
38
39
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 37

def every_xth_day(default=nil)
  get(:every_other3) || default
end

#every_xth_day?Boolean

Returns:

  • (Boolean)

21
22
23
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 21

def every_xth_day?
  get(:recurrence_selector) == 1
end

#find_relative_day_of_month(start, n) ⇒ Object (private)


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 99

def find_relative_day_of_month(start, n)
  the_next = get_xth_day_of_month(every_xth_day, day_of_week, start.month, start.year)
  if the_next.nil? || the_next <= start
    # the nth day is already passed in this month, go to next month and try
    # again

    # fiddle with timezone. Looks like we hit a bug in rails here where
    # 2008-12-01 +0100 plus 1.month becomes 2008-12-31 +0100. For now, just
    # calculate in UTC and convert back to local timezone.
    #  TODO: recheck if future rails versions have this problem too
    the_next = Time.utc(the_next.year, the_next.month, the_next.day)+n.months
    the_next = Time.zone.local(the_next.year, the_next.month, the_next.day)

    # TODO: if there is still no match, start will be set to nil. if we ever
    # support 5th day of the month, we need to handle this case
    the_next = get_xth_day_of_month(every_xth_day, day_of_week, the_next.month, the_next.year)
  end
  the_next
end

#find_specific_day_of_month(previous, start, n) ⇒ Object (private)


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 82

def find_specific_day_of_month(previous, start, n)
  if (previous && start.mday >= every_x_day) || (previous.nil? && start.mday > every_x_day)
    # there is no next day n in this month, search in next month
    #
    #  start += n.months
    #
    # The above seems to not work. Fiddle with timezone. Looks like we hit a
    # bug in rails here where 2008-12-01 +0100 plus 1.month becomes
    # 2008-12-31 +0100. For now, just calculate in UTC and convert back to
    # local timezone.
    #
    #  TODO: recheck if future rails versions have this problem too
    start = Time.utc(start.year, start.month, start.day)+n.months
  end
  Time.zone.local(start.year, start.month, every_x_day)
end

#get_next_date(previous) ⇒ Object


67
68
69
70
71
72
73
74
75
76
77
78
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 67

def get_next_date(previous)
  start = determine_start(previous)
  n = get(:every_other2)

  case recurrence_selector
  when 0 # specific day of the month
    return find_specific_day_of_month(previous, start, n)
  when 1 # relative weekday of a month
    return find_relative_day_of_month(start, n)
  end
  nil
end

#recurrence_patternObject


45
46
47
48
49
50
51
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 45

def recurrence_pattern
  if recurrence_selector == 0
    recurrence_pattern_for_specific_day
  else
    recurrence_pattern_for_relative_day_in_month
  end
end

#recurrence_pattern_for_relative_day_in_monthObject (private)


128
129
130
131
132
133
134
135
136
137
138
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 128

def recurrence_pattern_for_relative_day_in_month
  n_months = if every_x_month2 > 1
               "#{every_x_month2} #{I18n.t('common.months')}"
             else
               I18n.t('common.month')
             end
  I18n.t('todos.recurrence.pattern.every_xth_day_of_every_n_months',
    x:        xth(every_xth_day),
    day:      day_of_week_as_text(day_of_week),
    n_months: n_months)
end

#recurrence_pattern_for_specific_dayObject (private)


119
120
121
122
123
124
125
126
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 119

def recurrence_pattern_for_specific_day
  on_day = " #{I18n.t('todos.recurrence.pattern.on_day_n', :n => every_x_day)}"
  if every_xth_day(0) > 1
    I18n.t("todos.recurrence.pattern.every_n_months", :n => every_xth_day) + on_day
  else
    I18n.t("todos.recurrence.pattern.every_month") + on_day
  end
end

#recurrence_selectorObject


9
10
11
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 9

def recurrence_selector
  get :recurrence_selector
end

#validateObject


53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'app/models/recurring_todos/monthly_repeat_pattern.rb', line 53

def validate
  super

  case recurrence_selector
  when 0 # 'monthly_every_x_day'
    validate_not_blank(every_x_month, "Every other nth month may not be empty for recurrence setting")
  when 1 # 'monthly_every_xth_day'
    validate_not_blank(every_x_month2, "Every other nth month may not be empty for recurrence setting")
    validate_not_blank(day_of_week, "The day of the month may not be empty for recurrence setting")
  else
    raise Exception.new, "unexpected value of recurrence selector '#{recurrence_selector}'"
  end
end