12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
# File 'lib/schedulable/acts_as_schedulable.rb', line 12
def acts_as_schedulable(options = {})
name = options[:name] || :schedule
attribute = :date
has_one name, as: :schedulable, dependent: :destroy
accepts_nested_attributes_for name
if options[:occurrences]
if options[:occurrences].is_a?(String) || options[:occurrences].is_a?(Symbol)
occurrences_association = options[:occurrences].to_sym
options[:occurrences] = {}
else
occurrences_association = options[:occurrences][:name]
options[:occurrences].delete(:name)
end
options[:occurrences][:class_name] = occurrences_association.to_s.classify
options[:occurrences][:as]||= :schedulable
options[:occurrences][:dependent]||:destroy
options[:occurrences][:autosave]||= true
has_many occurrences_association, options[:occurrences]
occurrences_table_name = occurrences_association.to_s.tableize
puts "SCHEDULABLE OCCURRENCES TABLE NAME: " + occurrences_table_name.to_s
remaining_occurrences_options = options[:occurrences].clone
remaining_occurrences_association = ("remaining_" << occurrences_association.to_s).to_sym
has_many remaining_occurrences_association, -> { where "#{occurrences_table_name}.date >= ?", Time.now}, remaining_occurrences_options
previous_occurrences_options = options[:occurrences].clone
previous_occurrences_association = ("previous_" << occurrences_association.to_s).to_sym
has_many previous_occurrences_association, -> { where "#{occurrences_table_name}.date < ?", Time.now}, previous_occurrences_options
ActsAsSchedulable.add_occurrences_association(self, occurrences_association)
after_save "build_#{occurrences_association}"
self.class.instance_eval do
define_method("build_#{occurrences_association}") do
schedulables = self.all
puts "build occurrences for #{schedulables.length} #{self.name.tableize}"
schedulables.each do |schedulable|
schedulable.send("build_#{occurrences_association}")
end
end
end
define_method "build_#{occurrences_association}" do
schedule = self.send(name)
now = Time.now
occurrence_attribute = :date
schedulable = schedule.schedulable
terminating = schedule.until.present? || schedule.count.present? && schedule.count > 0
max_build_period = Schedulable.config.max_build_period || 1.year
max_date = now + max_build_period
max_date = terminating ? [max_date, schedule.last.to_time].min : max_date
max_build_count = Schedulable.config.max_build_count || 0
max_build_count = terminating ? [max_build_count, schedule.remaining_occurrences.count].min : max_build_count
if max_build_count > 0
occurrences = schedule.next_occurrences(max_build_count)
end
if !occurrences || occurrences.last && occurrences.last.to_time > max_date
all_occurrences = schedule.occurrences(max_date)
occurrences = []
all_occurrences.each do |occurrence_date|
if occurrence_date.to_time > now
occurrences << occurrence_date
end
end
end
puts 'build occurrences'
assocs = schedulable.class.reflect_on_all_associations(:has_many)
assocs.each do |assoc|
puts assoc.name
end
occurrences_records = schedulable.send(occurrences_association)
record_count = 0
occurrences_records.each do |occurrence_record|
if occurrence_record.date > now
if !schedule.occurs_on?(occurrence_record.date) || occurrence_record.date > max_date || record_count > max_build_count
if occurrences_records.destroy(occurrence_record)
puts 'an error occurred while destroying an unused occurrence record'
end
end
record_count = record_count + 1
end
end
occurrences.each do |occurrence|
existing = occurrences_records.select { |record|
record.date.to_date == occurrence.to_date
}
if existing.length > 0
existing.each { |record|
if !occurrences_records.update(record, date: occurrence.to_datetime)
puts 'an error occurred while saving an existing occurrence record'
end
}
else
if !occurrences_records.create(date: occurrence.to_datetime)
puts 'an error occurred while creating an occurrence record'
end
end
end
end
end
end
|