diff --git a/app/models/recurring_todo.rb b/app/models/recurring_todo.rb index ba40527e..e39a15e3 100644 --- a/app/models/recurring_todo.rb +++ b/app/models/recurring_todo.rb @@ -394,11 +394,19 @@ class RecurringTodo < ActiveRecord::Base # the due date in time) # # assumes self.recurring_period == 'daily' + + # determine start if previous.nil? start = self.start_from.nil? ? Time.now.utc : self.start_from else # use the next day start = previous + 1.day + + unless self.start_from.nil? + # check if the start_from date is later than previous. If so, use + # start_from as start to search for next date + start = self.start_from if self.start_from > previous + end end if self.only_work_days @@ -419,6 +427,7 @@ class RecurringTodo < ActiveRecord::Base end def get_weekly_date(previous) + # determine start if previous == nil start = self.start_from.nil? ? Time.now.utc : self.start_from else @@ -428,7 +437,13 @@ class RecurringTodo < ActiveRecord::Base # that week start += self.every_other1.week end + unless self.start_from.nil? + # check if the start_from date is later than previous. If so, use + # start_from as start to search for next date + start = self.start_from if self.start_from > previous + end end + # check if there are any days left this week for the next todo start.wday().upto 6 do |i| return start + (i-start.wday()).days unless self.every_day[i,1] == ' ' @@ -447,11 +462,8 @@ class RecurringTodo < ActiveRecord::Base end def get_monthly_date(previous) - if previous.nil? - start = self.start_from.nil? ? Time.now.utc : self.start_from - else - start = previous - end + + start = determine_start(previous) day = self.every_other1 n = self.every_other2 @@ -505,18 +517,8 @@ class RecurringTodo < ActiveRecord::Base end def get_yearly_date(previous) - if previous.nil? - start = self.start_from.nil? ? Time.now.utc : self.start_from - else - if self.start_from.nil? - start = previous - else - # check if the start_from date is later than previous. If so, use - # start_from as start to search for next date - start = self.start_from > previous ? self.start_from : previous - end - end + start = determine_start(previous) day = self.every_other1 month = self.every_other2 @@ -598,4 +600,19 @@ class RecurringTodo < ActiveRecord::Base errors.add("", "At least one day must be selected in the weekly pattern") if self.every_day == ' ' end + def determine_start(previous) + if previous.nil? + start = self.start_from.nil? ? Time.now.utc : self.start_from + else + start = previous + + unless self.start_from.nil? + # check if the start_from date is later than previous. If so, use + # start_from as start to search for next date + start = self.start_from if self.start_from > previous + end + end + return start + end + end diff --git a/test/unit/recurring_todo_test.rb b/test/unit/recurring_todo_test.rb index 4ef86ddd..b3982d4e 100644 --- a/test/unit/recurring_todo_test.rb +++ b/test/unit/recurring_todo_test.rb @@ -34,23 +34,13 @@ class RecurringTodoTest < Test::Rails::TestCase def test_daily_every_day # every_day should return todays date if there was no previous date due_date = @every_day.get_due_date(nil) - # use to_s in compare, because milisec could be different - assert_equal @today.to_s, due_date.to_s + # use strftime in compare, because milisec / secs could be different + assert_equal @today.strftime("%d-%m-%y"), due_date.strftime("%d-%m-%y") # when the last todo was completed today, the next todo is due tomorrow due_date =@every_day.get_due_date(@today) assert_equal @tomorrow, due_date - - # every_day should return start_day if it is in the future - @every_day.start_from = @in_three_days - due_date = @every_day.get_due_date(nil) - assert_equal @in_three_days, due_date - - # if we give a date in the future for the previous todo, the next to do - # should be based on that future date. - due_date = @every_day.get_due_date(@in_four_days) - assert_equal @in_four_days+1.day, due_date - + # do something every 14 days @every_day.every_other1=14 due_date = @every_day.get_due_date(@today) @@ -168,7 +158,6 @@ class RecurringTodoTest < Test::Rails::TestCase due_date = @monthly.get_due_date(@sunday) # june 8th assert_equal Time.utc(2008,8,8), due_date # aug 8th - end def test_yearly_pattern @@ -206,10 +195,33 @@ class RecurringTodoTest < Test::Rails::TestCase end def test_start_from_in_future + # every_day should return start_day if it is in the future + @every_day.start_from = @in_three_days + due_date = @every_day.get_due_date(nil) + assert_equal @in_three_days, due_date + due_date = @every_day.get_due_date(@tomorrow) + assert_equal @in_three_days, due_date + + # if we give a date in the future for the previous todo, the next to do + # should be based on that future date. + due_date = @every_day.get_due_date(@in_four_days) + assert_equal @in_four_days+1.day, due_date + + @weekly_every_day.start_from = Time.utc(2020,1,1) + assert_equal Time.utc(2020,1,1), @weekly_every_day.get_due_date(nil) + assert_equal Time.utc(2020,1,1), @weekly_every_day.get_due_date(Time.utc(2019,10,1)) + assert_equal Time.utc(2020,1,10), @weekly_every_day.get_due_date(Time.utc(2020,1,9)) + + @monthly_every_last_friday.start_from = Time.utc(2020,1,1) + assert_equal Time.utc(2020,1,31), @monthly_every_last_friday.get_due_date(nil) # last friday of jan + assert_equal Time.utc(2020,1,31), @monthly_every_last_friday.get_due_date(Time.utc(2019,12,1)) # last friday of jan + assert_equal Time.utc(2020,2,28), @monthly_every_last_friday.get_due_date(Time.utc(2020,2,1)) # last friday of feb + # start from after june 8th 2008 - @yearly.start_from = Time.utc(2008,6,12) - assert_equal Time.utc(2009,6,8), @yearly.get_due_date(nil) # jun 8th next year - assert_equal Time.utc(2009,6,8), @yearly.get_due_date(Time.utc(2008,6,1)) # also next year + @yearly.start_from = Time.utc(2020,6,12) + assert_equal Time.utc(2021,6,8), @yearly.get_due_date(nil) # jun 8th next year + assert_equal Time.utc(2021,6,8), @yearly.get_due_date(Time.utc(2019,6,1)) # also next year + assert_equal Time.utc(2021,6,8), @yearly.get_due_date(Time.utc(2020,6,15)) # also next year this_year = Time.now.utc.year @yearly.start_from = Time.utc(this_year+1,6,12)