public
Description: Tracks is a GTD(TM) web application, built with Ruby on Rails
Homepage: http://www.rousette.org.uk/projects/
Clone URL: git://github.com/bsag/tracks.git
Click here to lend your support to: tracks and make a donation at www.pledgie.com !
fix case with future start_from for other recurrence periods too

this patch belongs to previous
lrbalt (author)
Tue Aug 19 13:04:53 -0700 2008
commit  88ea02d29a44c51031e7e45eb4b4d3729646b5d5
tree    d19322be8eef4a8fa4dd236e305bf06159ae2e15
parent  f4378ffde1b2364bbcbf999191a76f580fa02904
...
394
395
396
 
 
397
398
399
400
401
 
 
 
 
 
 
402
403
404
...
419
420
421
 
422
423
424
...
428
429
430
 
 
 
 
 
431
 
432
433
434
...
447
448
449
450
451
452
453
454
 
 
455
456
457
...
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
 
520
521
522
...
598
599
600
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
601
...
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
...
427
428
429
430
431
432
433
...
437
438
439
440
441
442
443
444
445
446
447
448
449
...
462
463
464
 
 
 
 
 
465
466
467
468
469
...
517
518
519
 
 
 
 
 
 
 
 
 
 
 
520
521
522
523
524
...
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
0
@@ -394,11 +394,19 @@ class RecurringTodo < ActiveRecord::Base
0
     # the due date in time)
0
     # 
0
     # assumes self.recurring_period == 'daily'
0
+  
0
+    # determine start
0
     if previous.nil?
0
       start = self.start_from.nil? ? Time.now.utc : self.start_from
0
     else
0
       # use the next day
0
       start = previous + 1.day
0
+
0
+      unless self.start_from.nil?
0
+        # check if the start_from date is later than previous. If so, use
0
+        # start_from as start to search for next date
0
+        start = self.start_from if self.start_from > previous 
0
+      end
0
     end
0
 
0
     if self.only_work_days
0
@@ -419,6 +427,7 @@ class RecurringTodo < ActiveRecord::Base
0
   end
0
   
0
   def get_weekly_date(previous)
0
+    # determine start
0
     if previous == nil
0
       start = self.start_from.nil? ? Time.now.utc : self.start_from
0
     else
0
@@ -428,7 +437,13 @@ class RecurringTodo < ActiveRecord::Base
0
         # that week
0
         start += self.every_other1.week
0
       end
0
+      unless self.start_from.nil?
0
+        # check if the start_from date is later than previous. If so, use
0
+        # start_from as start to search for next date
0
+        start = self.start_from if self.start_from > previous 
0
+      end
0
     end
0
+    
0
     # check if there are any days left this week for the next todo
0
     start.wday().upto 6 do |i|
0
       return start + (i-start.wday()).days unless self.every_day[i,1] == ' '
0
@@ -447,11 +462,8 @@ class RecurringTodo < ActiveRecord::Base
0
   end
0
   
0
   def get_monthly_date(previous)
0
-    if previous.nil?
0
-      start = self.start_from.nil? ? Time.now.utc : self.start_from
0
-    else
0
-      start = previous
0
-    end
0
+    
0
+    start = determine_start(previous)
0
     day = self.every_other1
0
     n = self.every_other2
0
     
0
@@ -505,18 +517,8 @@ class RecurringTodo < ActiveRecord::Base
0
   end
0
   
0
   def get_yearly_date(previous)
0
-    if previous.nil?
0
-      start = self.start_from.nil? ? Time.now.utc : self.start_from
0
-    else
0
-      if self.start_from.nil?
0
-        start = previous
0
-      else
0
-        # check if the start_from date is later than previous. If so, use
0
-        # start_from as start to search for next date
0
-        start = self.start_from > previous ? self.start_from : previous
0
-      end
0
-    end
0
 
0
+    start = determine_start(previous)
0
     day = self.every_other1
0
     month = self.every_other2
0
     
0
@@ -598,4 +600,19 @@ class RecurringTodo < ActiveRecord::Base
0
     errors.add("", "At least one day must be selected in the weekly pattern") if self.every_day == '       '
0
   end
0
   
0
+  def determine_start(previous)
0
+    if previous.nil?
0
+      start = self.start_from.nil? ? Time.now.utc : self.start_from
0
+    else
0
+      start = previous
0
+
0
+      unless self.start_from.nil?
0
+        # check if the start_from date is later than previous. If so, use
0
+        # start_from as start to search for next date
0
+        start = self.start_from if self.start_from > previous 
0
+      end
0
+    end
0
+    return start
0
+  end
0
+  
0
 end
...
34
35
36
37
38
 
 
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 
54
55
56
...
168
169
170
171
172
173
174
...
206
207
208
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
210
211
212
 
 
 
 
213
214
215
...
34
35
36
 
 
37
38
39
40
41
42
 
 
 
 
 
 
 
 
 
 
 
43
44
45
46
...
158
159
160
 
161
162
163
...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
 
 
 
221
222
223
224
225
226
227
0
@@ -34,23 +34,13 @@ class RecurringTodoTest < Test::Rails::TestCase
0
   def test_daily_every_day
0
     # every_day should return todays date if there was no previous date
0
     due_date = @every_day.get_due_date(nil)
0
-    # use to_s in compare, because milisec could be different
0
-    assert_equal @today.to_s, due_date.to_s
0
+    # use strftime in compare, because milisec / secs could be different
0
+    assert_equal @today.strftime("%d-%m-%y"), due_date.strftime("%d-%m-%y")
0
 
0
     # when the last todo was completed today, the next todo is due tomorrow
0
     due_date =@every_day.get_due_date(@today)
0
     assert_equal @tomorrow, due_date
0
-    
0
-    # every_day should return start_day if it is in the future
0
-    @every_day.start_from = @in_three_days
0
-    due_date = @every_day.get_due_date(nil)
0
-    assert_equal @in_three_days, due_date
0
-    
0
-    # if we give a date in the future for the previous todo, the next to do
0
-    # should be based on that future date.
0
-    due_date = @every_day.get_due_date(@in_four_days)
0
-    assert_equal @in_four_days+1.day, due_date    
0
-    
0
+        
0
     # do something every 14 days
0
     @every_day.every_other1=14
0
     due_date = @every_day.get_due_date(@today)
0
@@ -168,7 +158,6 @@ class RecurringTodoTest < Test::Rails::TestCase
0
     
0
     due_date = @monthly.get_due_date(@sunday) # june 8th
0
     assert_equal Time.utc(2008,8,8), due_date # aug 8th    
0
-  
0
   end
0
   
0
   def test_yearly_pattern
0
@@ -206,10 +195,33 @@ class RecurringTodoTest < Test::Rails::TestCase
0
   end
0
 
0
   def test_start_from_in_future
0
+    # every_day should return start_day if it is in the future
0
+    @every_day.start_from = @in_three_days
0
+    due_date = @every_day.get_due_date(nil)
0
+    assert_equal @in_three_days, due_date
0
+    due_date = @every_day.get_due_date(@tomorrow)
0
+    assert_equal @in_three_days, due_date
0
+    
0
+    # if we give a date in the future for the previous todo, the next to do
0
+    # should be based on that future date.
0
+    due_date = @every_day.get_due_date(@in_four_days)
0
+    assert_equal @in_four_days+1.day, due_date    
0
+
0
+    @weekly_every_day.start_from = Time.utc(2020,1,1)
0
+    assert_equal Time.utc(2020,1,1), @weekly_every_day.get_due_date(nil)
0
+    assert_equal Time.utc(2020,1,1), @weekly_every_day.get_due_date(Time.utc(2019,10,1))
0
+    assert_equal Time.utc(2020,1,10), @weekly_every_day.get_due_date(Time.utc(2020,1,9))
0
+
0
+    @monthly_every_last_friday.start_from = Time.utc(2020,1,1)
0
+    assert_equal Time.utc(2020,1,31), @monthly_every_last_friday.get_due_date(nil) # last friday of jan
0
+    assert_equal Time.utc(2020,1,31), @monthly_every_last_friday.get_due_date(Time.utc(2019,12,1)) # last friday of jan
0
+    assert_equal Time.utc(2020,2,28), @monthly_every_last_friday.get_due_date(Time.utc(2020,2,1)) # last friday of feb
0
+
0
     # start from after june 8th 2008
0
-    @yearly.start_from = Time.utc(2008,6,12)
0
-    assert_equal Time.utc(2009,6,8), @yearly.get_due_date(nil) # jun 8th next year
0
-    assert_equal Time.utc(2009,6,8), @yearly.get_due_date(Time.utc(2008,6,1)) # also next year
0
+    @yearly.start_from = Time.utc(2020,6,12)
0
+    assert_equal Time.utc(2021,6,8), @yearly.get_due_date(nil) # jun 8th next year
0
+    assert_equal Time.utc(2021,6,8), @yearly.get_due_date(Time.utc(2019,6,1)) # also next year
0
+    assert_equal Time.utc(2021,6,8), @yearly.get_due_date(Time.utc(2020,6,15)) # also next year
0
     
0
     this_year = Time.now.utc.year
0
     @yearly.start_from = Time.utc(this_year+1,6,12)

Comments