active_scaffold_batch 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. data/LICENSE.txt +20 -0
  2. data/README +4 -0
  3. data/app/assets/javascripts/jquery/active_scaffold_batch.js +13 -0
  4. data/app/assets/javascripts/prototype/active_scaffold_batch.js +13 -0
  5. data/app/assets/stylesshets/active_scaffold_batch.css +36 -0
  6. data/app/views/active_scaffold_overrides/_batch_create_form.html.erb +9 -0
  7. data/app/views/active_scaffold_overrides/_batch_create_form_attribute.html.erb +19 -0
  8. data/app/views/active_scaffold_overrides/_batch_create_form_body.html.erb +25 -0
  9. data/app/views/active_scaffold_overrides/_batch_create_form_footer.html.erb +4 -0
  10. data/app/views/active_scaffold_overrides/_batch_create_form_horizontal.html.erb +14 -0
  11. data/app/views/active_scaffold_overrides/_batch_create_form_horizontal_header.html.erb +8 -0
  12. data/app/views/active_scaffold_overrides/_batch_create_form_horizontal_record.html.erb +26 -0
  13. data/app/views/active_scaffold_overrides/_batch_create_form_multiple.html.erb +8 -0
  14. data/app/views/active_scaffold_overrides/_batch_create_form_vertical.html.erb +7 -0
  15. data/app/views/active_scaffold_overrides/_batch_create_form_vertical_record.html.erb +6 -0
  16. data/app/views/active_scaffold_overrides/_batch_update_form.html.erb +7 -0
  17. data/app/views/active_scaffold_overrides/_batch_update_form_attribute.html.erb +12 -0
  18. data/app/views/active_scaffold_overrides/_batch_update_form_attribute_scope.html.erb +14 -0
  19. data/app/views/active_scaffold_overrides/_batch_update_form_body.html.erb +25 -0
  20. data/app/views/active_scaffold_overrides/_form_messages.html.erb +9 -0
  21. data/app/views/active_scaffold_overrides/batch_add.js.erb +5 -0
  22. data/app/views/active_scaffold_overrides/batch_create.html.erb +5 -0
  23. data/app/views/active_scaffold_overrides/batch_update.html.erb +5 -0
  24. data/app/views/active_scaffold_overrides/on_batch_base.js.erb +10 -0
  25. data/app/views/active_scaffold_overrides/on_batch_create.js.erb +15 -0
  26. data/app/views/active_scaffold_overrides/on_batch_update.js.erb +10 -0
  27. data/config/locales/de.yml +22 -0
  28. data/config/locales/en.yml +21 -0
  29. data/config/locales/es.yml +21 -0
  30. data/lib/active_scaffold/actions/batch_base.rb +135 -0
  31. data/lib/active_scaffold/actions/batch_create.rb +247 -0
  32. data/lib/active_scaffold/actions/batch_destroy.rb +77 -0
  33. data/lib/active_scaffold/actions/batch_update.rb +281 -0
  34. data/lib/active_scaffold/config/batch_create.rb +79 -0
  35. data/lib/active_scaffold/config/batch_destroy.rb +54 -0
  36. data/lib/active_scaffold/config/batch_update.rb +52 -0
  37. data/lib/active_scaffold/helpers/batch_create_column_helpers.rb +38 -0
  38. data/lib/active_scaffold/helpers/calendar_date_select_update_column_helpers.rb +33 -0
  39. data/lib/active_scaffold/helpers/datepicker_update_column_helpers.rb +29 -0
  40. data/lib/active_scaffold/helpers/update_column_helpers.rb +93 -0
  41. data/lib/active_scaffold_batch/config/core.rb +13 -0
  42. data/lib/active_scaffold_batch/engine.rb +23 -0
  43. data/lib/active_scaffold_batch/version.rb +9 -0
  44. data/lib/active_scaffold_batch.rb +25 -0
  45. metadata +125 -0
@@ -0,0 +1,247 @@
1
+ module ActiveScaffold::Actions
2
+ module BatchCreate
3
+
4
+ def self.included(base)
5
+ base.send :include, ActiveScaffold::Actions::BatchBase unless base < ActiveScaffold::Actions::BatchBase
6
+ base.before_filter :batch_create_authorized_filter, :only => [:batch_new, :batch_create]
7
+ base.helper_method :batch_create_values
8
+ base.helper_method :batch_create_by_column
9
+ base.helper_method :batch_create_by_records
10
+ end
11
+
12
+ def batch_new
13
+ do_batch_new
14
+ respond_to_action(:batch_new)
15
+ end
16
+
17
+ def batch_add
18
+ do_batch_add
19
+ respond_to_action(:batch_add)
20
+ end
21
+
22
+ def batch_create
23
+ batch_action
24
+ end
25
+
26
+
27
+ protected
28
+ def batch_new_respond_to_html
29
+ if batch_successful?
30
+ render(:action => 'batch_create')
31
+ else
32
+ return_to_main
33
+ end
34
+ end
35
+
36
+ def batch_new_respond_to_js
37
+ render(:partial => 'batch_create_form')
38
+ end
39
+
40
+ def batch_add_respond_to_js
41
+ render
42
+ end
43
+
44
+ def batch_create_values
45
+ @batch_create_values || {}
46
+ end
47
+
48
+ def batch_create_by_records
49
+ if @batch_create_by_records.nil?
50
+ if marked_records_parent
51
+ column = active_scaffold_config.columns[batch_create_by_column.to_sym]
52
+ @batch_create_by_records = if column.polymorphic_association?
53
+ active_scaffold_config_for(params[:batch_create_by].singularize).model.find(marked_records_parent.to_a)
54
+ else
55
+ column_plural_assocation_value_from_value(column, marked_records_parent)
56
+ end
57
+ end
58
+ end
59
+ @batch_create_by_records || []
60
+ end
61
+
62
+ def batch_create_respond_to_html
63
+ if params[:iframe]=='true' # was this an iframe post ?
64
+ do_refresh_list
65
+ responds_to_parent do
66
+ render :action => 'on_batch_create.js', :layout => false
67
+ end
68
+ else # just a regular post
69
+ if batch_successful?
70
+ return_to_main
71
+ else
72
+ render(:action => 'batch_create')
73
+ end
74
+ end
75
+ end
76
+
77
+ def batch_create_respond_to_js
78
+ do_refresh_list
79
+ render :action => 'on_batch_create'
80
+ end
81
+
82
+ def do_batch_new
83
+ self.successful = true
84
+ do_new
85
+ if batch_create_by_column
86
+ batch_scope # that s a dummy call to remove batch_scope parameter
87
+ else
88
+ @scope = temporary_id
89
+ end
90
+ end
91
+
92
+ def do_batch_add
93
+ @records = {}
94
+ t = temporary_id
95
+ params[:num_records].to_i.times do
96
+ @records[t.succ!] = do_new
97
+ end
98
+ end
99
+
100
+ def marked_records_parent
101
+ if @marked_records_parent.nil?
102
+ @marked_records_parent = if params[:batch_create_by]
103
+ session_parent = active_scaffold_session_storage(params[:batch_create_by])
104
+ session_parent[:marked_records] || Set.new
105
+ else
106
+ false
107
+ end
108
+ end
109
+ @marked_records_parent
110
+ end
111
+
112
+ def before_do_batch_create
113
+ if batch_create_by_column
114
+ create_columns = active_scaffold_config.batch_create.columns
115
+ @batch_create_values = create_attribute_values_from_params(create_columns, params[:record])
116
+ else
117
+ @batch_scope = 'multiple'
118
+ end
119
+ end
120
+
121
+ def run_in_transaction?
122
+ active_scaffold_config.batch_create.run_in_transaction
123
+ end
124
+
125
+ def validate_first?
126
+ active_scaffold_config.batch_create.run_in_transaction == :validate_first
127
+ end
128
+
129
+ def run_in_transaction_if_enabled
130
+ processed_records, created_records = 0
131
+ if run_in_transaction?
132
+ active_scaffold_config.model.transaction do
133
+ processed_records, created_records = yield
134
+ if processed_records == created_records
135
+ @error_records.each { |_, record| create_save(record) } if validate_first?
136
+ @error_records = []
137
+ else
138
+ created_records = 0
139
+ raise ActiveRecord::Rollback
140
+ end
141
+ end
142
+ else
143
+ processed_records, created_records = yield
144
+ end
145
+ flash[:info] = as_(:some_records_created, :count => created_records, :model => active_scaffold_config.label(:count => created_records)) if batch_successful? || created_records > 0
146
+ end
147
+
148
+ def batch_create_listed
149
+ run_in_transaction_if_enabled do
150
+ processed_records = created_records = 0
151
+ case active_scaffold_config.batch_create.process_mode
152
+ when :create then
153
+ batch_create_by_records.each do |batch_record|
154
+ create_record_in_batch(batch_record)
155
+ created_records += 1 if successful?
156
+ processed_records += 1
157
+ end
158
+ else
159
+ Rails.logger.error("Unknown process_mode: #{active_scaffold_config.batch_create.process_mode} for action batch_create")
160
+ end
161
+ [processed_records, created_records]
162
+ end
163
+ end
164
+ alias_method :batch_create_marked, :batch_create_listed
165
+
166
+ def batch_create_multiple
167
+ run_in_transaction_if_enabled do
168
+ @error_records = {}
169
+ processed_records = created_records = 0
170
+ params[:record].each do |scope, record_hash|
171
+ do_create(:attributes => record_hash, :skip_save => validate_first?)
172
+ error_records[scope] = @record unless successful? && !run_in_transaction?
173
+ created_records += 1 if successful?
174
+ processed_records += 1
175
+ end
176
+ [processed_records, created_records]
177
+ end
178
+ end
179
+
180
+ def new_batch_create_record(created_by)
181
+ new_model
182
+ end
183
+
184
+ def create_record_in_batch(created_by)
185
+ @successful = nil
186
+ @record = new_batch_create_record(created_by)
187
+ @record.send("#{batch_create_by_column.to_s}=", created_by)
188
+ batch_create_values.each do |attribute, value|
189
+ set_record_attribute(value[:column], attribute, value[:value])
190
+ end
191
+
192
+ if authorized_for_job?(@record)
193
+ create_save(@record)
194
+ if successful?
195
+ marked_records_parent.delete(created_by.id) if batch_scope == 'MARKED' && marked_records_parent
196
+ end
197
+ error_records << @record unless successful? && !run_in_transaction?
198
+ end
199
+ end
200
+
201
+ def batch_create_by_column
202
+ active_scaffold_config.batch_create.default_batch_by_column
203
+ end
204
+
205
+ def create_attribute_values_from_params(columns, attributes)
206
+ values = {}
207
+ columns.each :for => active_scaffold_config.model, :crud_type => :create, :flatten => true do |column|
208
+ next unless attributes.has_key?(column.name)
209
+ if column == batch_create_by_column.to_sym
210
+ @batch_create_by_records = column_plural_assocation_value_from_value(column, attributes[column.name])
211
+ else
212
+ values[column.name] = {:column => column, :value => column_value_from_param_value(nil, column, attributes[column.name])}
213
+ end
214
+ end
215
+ values
216
+ end
217
+
218
+ # The default security delegates to ActiveRecordPermissions.
219
+ # You may override the method to customize.
220
+ def batch_create_authorized?(record = nil)
221
+ authorized_for?(:crud_type => :create)
222
+ end
223
+
224
+ def batch_create_ignore?(record = nil)
225
+ false
226
+ end
227
+
228
+ def override_batch_create_value(form_ui)
229
+ method = "batch_create_value_for_#{form_ui}"
230
+ method if respond_to? method
231
+ end
232
+
233
+ def create_ignore?
234
+ super || batch_create_by_column.blank?
235
+ end
236
+
237
+ private
238
+
239
+ def batch_create_authorized_filter
240
+ link = active_scaffold_config.batch_create.link || active_scaffold_config.batch_create.class.link
241
+ raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
242
+ end
243
+ def batch_new_formats
244
+ (default_formats + active_scaffold_config.formats).uniq
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,77 @@
1
+ module ActiveScaffold::Actions
2
+ module BatchDestroy
3
+
4
+ def self.included(base)
5
+ base.send :include, ActiveScaffold::Actions::BatchBase unless base < ActiveScaffold::Actions::BatchBase
6
+ base.before_filter :batch_destroy_authorized_filter, :only => [:batch_destroy]
7
+ end
8
+
9
+ def batch_destroy
10
+ batch_action
11
+ end
12
+
13
+ protected
14
+
15
+ def before_do_batch_destroy
16
+ end
17
+
18
+ def batch_destroy_listed
19
+ case active_scaffold_config.batch_destroy.process_mode
20
+ when :delete then
21
+ each_record_in_scope do |record|
22
+ destroy_record(record) if authorized_for_job?(record)
23
+ end
24
+ when :delete_all then
25
+ do_search if respond_to? :do_search
26
+ # dummy condition cause we have to call delete_all on relation not on association
27
+ beginning_of_chain.where('1=1').delete_all(all_conditions)
28
+ else
29
+ Rails.logger.error("Unknown process_mode: #{active_scaffold_config.batch_destroy.process_mode} for action batch_destroy")
30
+ end
31
+
32
+ end
33
+
34
+ def batch_destroy_marked
35
+ case active_scaffold_config.batch_destroy.process_mode
36
+ when :delete then
37
+ each_marked_record do |record|
38
+ destroy_record(record) if authorized_for_job?(record)
39
+ end
40
+ when :delete_all then
41
+ active_scaffold_config.model.where(active_scaffold_config.model.primary_key => marked_records.to_a).delete_all
42
+ do_demark_all
43
+ else
44
+ Rails.logger.error("Unknown process_mode: #{active_scaffold_config.batch_destroy.process_mode} for action batch_destroy")
45
+ end
46
+ end
47
+
48
+ def destroy_record(record)
49
+ @successful = nil
50
+ @record = record
51
+
52
+ do_destroy
53
+ if successful?
54
+ @record.as_marked = false if batch_scope == 'MARKED'
55
+ else
56
+ error_records << @record
57
+ end
58
+ end
59
+
60
+ # The default security delegates to ActiveRecordPermissions.
61
+ # You may override the method to customize.
62
+ def batch_destroy_authorized?(record = nil)
63
+ authorized_for?(:crud_type => :delete)
64
+ end
65
+
66
+ def batch_destroy_marked_ignore?(record = nil)
67
+ !active_scaffold_config.actions.include? :mark
68
+ end
69
+
70
+ private
71
+
72
+ def batch_destroy_authorized_filter
73
+ link = active_scaffold_config.batch_destroy.link || active_scaffold_config.batch_destroy.class.link
74
+ raise ActiveScaffold::ActionNotAllowed unless self.send(link.first.security_method)
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,281 @@
1
+ module ActiveScaffold::Actions
2
+ module BatchUpdate
3
+
4
+ GenericOperators = [
5
+ 'NO_UPDATE',
6
+ 'REPLACE'
7
+ ]
8
+ NumericOperators = [
9
+ 'PLUS',
10
+ 'MINUS',
11
+ 'TIMES',
12
+ 'DIVISION'
13
+ ]
14
+ NumericOptions = [
15
+ 'ABSOLUTE',
16
+ 'PERCENT'
17
+ ]
18
+
19
+ DateOperators = [
20
+ 'PLUS',
21
+ 'MINUS'
22
+ ]
23
+
24
+ def self.included(base)
25
+ base.send :include, ActiveScaffold::Actions::BatchBase unless base < ActiveScaffold::Actions::BatchBase
26
+ base.before_filter :batch_update_authorized_filter, :only => [:batch_edit, :batch_update]
27
+ base.helper_method :batch_update_values
28
+ end
29
+
30
+ def batch_edit
31
+ do_batch_edit
32
+ respond_to_action(:batch_edit)
33
+ end
34
+
35
+ def batch_update
36
+ batch_action
37
+ end
38
+
39
+
40
+ protected
41
+ def batch_edit_respond_to_html
42
+ if batch_successful?
43
+ render(:action => 'batch_update')
44
+ else
45
+ return_to_main
46
+ end
47
+ end
48
+
49
+ def batch_edit_respond_to_js
50
+ render(:partial => 'batch_update_form')
51
+ end
52
+
53
+ def batch_update_values
54
+ @batch_update_values || {}
55
+ end
56
+
57
+ def batch_update_respond_to_html
58
+ if params[:iframe]=='true' # was this an iframe post ?
59
+ flash[:info] = as_(:batch_processing_successful) if batch_successful?
60
+ do_refresh_list
61
+ responds_to_parent do
62
+ render :action => 'on_batch_update.js', :layout => false
63
+ end
64
+ else # just a regular post
65
+ if batch_successful?
66
+ flash[:info] = as_(:updated_model, :model => @record.to_label)
67
+ return_to_main
68
+ else
69
+ render(:action => 'batch_update')
70
+ end
71
+ end
72
+ end
73
+
74
+ def batch_update_respond_to_js
75
+ flash[:info] = as_(:batch_processing_successful) if batch_successful?
76
+ do_refresh_list
77
+ render :action => 'on_batch_update'
78
+ end
79
+
80
+ def do_batch_edit
81
+ self.successful = true
82
+ do_new
83
+ end
84
+
85
+ def before_do_batch_update
86
+ @batch_update_values = update_attribute_values_from_params(active_scaffold_config.batch_update.columns, params[:record])
87
+ end
88
+
89
+ def batch_update_listed
90
+ case active_scaffold_config.batch_update.process_mode
91
+ when :update then
92
+ each_record_in_scope {|record| update_record_in_batch(record) if authorized_for_job?(record)}
93
+ when :update_all then
94
+ updates = updates_for_update_all
95
+ unless updates.first.empty?
96
+ do_search if respond_to? :do_search
97
+ # all_conditions might fail cause joins are not working in update_all
98
+ active_scaffold_config.model.update_all(updates, all_conditions)
99
+ end
100
+ else
101
+ Rails.logger.error("Unknown process_mode: #{active_scaffold_config.batch_update.process_mode} for action batch_update")
102
+ end
103
+
104
+ end
105
+
106
+ def batch_update_marked
107
+ case active_scaffold_config.batch_update.process_mode
108
+ when :update then
109
+ each_marked_record {|record| update_record_in_batch(record) if authorized_for_job?(record)}
110
+ when :update_all then
111
+ updates = updates_for_update_all
112
+ unless updates.first.empty?
113
+ active_scaffold_config.model.where(active_scaffold_config.model.primary_key => marked_records.to_a).update_all(updates)
114
+ do_demark_all
115
+ end
116
+ else
117
+ Rails.logger.error("Unknown process_mode: #{active_scaffold_config.batch_update.process_mode} for action batch_update")
118
+ end
119
+ end
120
+
121
+ def updates_for_update_all()
122
+ update_all = [[]]
123
+ batch_update_values.each do |attribute, value|
124
+ sql_set, value = get_update_all_attribute(value[:column], attribute, value[:value])
125
+ unless sql_set.nil?
126
+ update_all.first << sql_set
127
+ update_all << value if value.present?
128
+ end
129
+ end
130
+ update_all[0] = update_all.first.join(',')
131
+ update_all
132
+ end
133
+
134
+ def update_record_in_batch(record)
135
+ @successful = nil
136
+ @record = record
137
+
138
+ batch_update_values.each do |attribute, value|
139
+ set_record_attribute(value[:column], attribute, value[:value])
140
+ end
141
+
142
+ update_save(:no_record_param_update => true)
143
+ if successful?
144
+ @record.as_marked = false if batch_scope == 'MARKED'
145
+ else
146
+ error_records << @record
147
+ end
148
+ end
149
+
150
+ def get_update_all_attribute(column, attribute, value)
151
+ form_ui = column_form_ui(column)
152
+
153
+ if form_ui && (method = override_batch_update_all_value(form_ui))
154
+ update_value = send(method, column, value)
155
+ if update_value.nil?
156
+ sql_set = nil
157
+ else
158
+ sql_set = "#{attribute} = #{update_value}"
159
+ update_value = nil
160
+ end
161
+ else
162
+ sql_set = "#{attribute} = ?"
163
+ update_value = value[:value]
164
+ end
165
+
166
+ return sql_set, update_value
167
+ end
168
+
169
+ def update_attribute_values_from_params(columns, attributes)
170
+ values = {}
171
+ attributes = {} unless attributes.is_a?(Hash)
172
+ columns.each :for => new_model, :crud_type => :update, :flatten => true do |column|
173
+ next unless attributes[column.name].is_a?(Hash) && params[:record][column.name][:operator] != 'NO_UPDATE'
174
+ value = attributes[column.name]
175
+ value = value.merge(:value => (value[:operator] == 'NULL') ? nil : column_value_from_param_value(nil, column, value[:value]))
176
+ values[column.name] = {:column => column, :value => value}
177
+ end
178
+ values
179
+ end
180
+
181
+ # The default security delegates to ActiveRecordPermissions.
182
+ # You may override the method to customize.
183
+ def batch_update_authorized?(record = nil)
184
+ authorized_for?(:crud_type => :update)
185
+ end
186
+
187
+ def batch_update_ignore?(record = nil)
188
+ false
189
+ end
190
+
191
+ def batch_update_value_for_numeric(column, record, calculation_info)
192
+ current_value = record.send(column.name)
193
+ if ActiveScaffold::Actions::BatchUpdate::GenericOperators.include?(calculation_info[:operator]) || ActiveScaffold::Actions::BatchUpdate::NumericOperators.include?(calculation_info[:operator])
194
+ operand = self.class.condition_value_for_numeric(column, calculation_info[:value])
195
+ operand = current_value / 100 * operand if calculation_info[:opt] == 'PERCENT'
196
+ case calculation_info[:operator]
197
+ when 'REPLACE' then operand
198
+ when 'NULL' then nil
199
+ when 'PLUS' then current_value.present? ? current_value + operand : nil
200
+ when 'MINUS' then current_value.present? ? current_value - operand : nil
201
+ when 'TIMES' then current_value.present? ? current_value * operand : nil
202
+ when 'DIVISION' then current_value.present? ? current_value / operand : nil
203
+ else
204
+ current_value
205
+ end
206
+ else
207
+ current_value
208
+ end
209
+ end
210
+ alias_method :batch_update_value_for_integer, :batch_update_value_for_numeric
211
+ alias_method :batch_update_value_for_decimal, :batch_update_value_for_numeric
212
+ alias_method :batch_update_value_for_float, :batch_update_value_for_numeric
213
+
214
+ def batch_update_all_value_for_numeric(column, calculation_info)
215
+ if ActiveScaffold::Actions::BatchUpdate::GenericOperators.include?(calculation_info[:operator]) || ActiveScaffold::Actions::BatchUpdate::NumericOperators.include?(calculation_info[:operator])
216
+ operand = active_scaffold_config.model.quote_value(self.class.condition_value_for_numeric(column, calculation_info[:value]))
217
+ if calculation_info[:opt] == 'PERCENT'
218
+ operand = "#{active_scaffold_config.model.connection.quote_column_name(column.name)} / 100.0 * #{operand}"
219
+ end
220
+ case calculation_info[:operator]
221
+ when 'REPLACE' then operand
222
+ when 'NULL' then active_scaffold_config.model.quote_value(nil)
223
+ when 'PLUS' then "#{active_scaffold_config.model.connection.quote_column_name(column.name)} + #{operand}"
224
+ when 'MINUS' then "#{active_scaffold_config.model.connection.quote_column_name(column.name)} - #{operand}"
225
+ when 'TIMES' then "#{active_scaffold_config.model.connection.quote_column_name(column.name)} * #{operand}"
226
+ when 'DIVISION' then "#{active_scaffold_config.model.connection.quote_column_name(column.name)} / #{operand}"
227
+ else
228
+ nil
229
+ end
230
+ else
231
+ nil
232
+ end
233
+ end
234
+ alias_method :batch_update_all_value_for_integer, :batch_update_all_value_for_numeric
235
+ alias_method :batch_update_all_value_for_decimal, :batch_update_all_value_for_numeric
236
+ alias_method :batch_update_all_value_for_float, :batch_update_all_value_for_numeric
237
+
238
+ def batch_update_value_for_date_picker(column, record, calculation_info)
239
+ current_value = record.send(column.name)
240
+ {"number"=>"", "unit"=>"DAYS", "value"=>"November 16, 2010", "operator"=>"REPLACE"}
241
+ if ActiveScaffold::Actions::BatchUpdate::GenericOperators.include?(calculation_info[:operator]) || ActiveScaffold::Actions::BatchUpdate::DateOperators.include?(calculation_info[:operator])
242
+ operand = self.class.condition_value_for_datetime(calculation_info[:value], column.column.type == :date ? :to_date : :to_time)
243
+ case calculation_info[:operator]
244
+ when 'REPLACE' then operand
245
+ when 'NULL' then nil
246
+ when 'PLUS' then
247
+ trend_number = [calculation_info['number'].to_i, 1].max
248
+ current_value.in((trend_number).send(calculation_info['unit'].downcase.singularize.to_sym))
249
+ when 'MINUS' then
250
+ trend_number = [calculation_info['number'].to_i, 1].max
251
+ current_value.ago((trend_number).send(calculation_info['unit'].downcase.singularize.to_sym))
252
+ else
253
+ current_value
254
+ end
255
+ else
256
+ current_value
257
+ end
258
+ end
259
+ alias_method :batch_update_value_for_calendar_date_select, :batch_update_value_for_date_picker
260
+
261
+ def override_batch_update_value(form_ui)
262
+ method = "batch_update_value_for_#{form_ui}"
263
+ method if respond_to? method
264
+ end
265
+
266
+ def override_batch_update_all_value(form_ui)
267
+ method = "batch_update_all_value_for_#{form_ui}"
268
+ method if respond_to? method
269
+ end
270
+
271
+ private
272
+
273
+ def batch_update_authorized_filter
274
+ link = active_scaffold_config.batch_update.link || active_scaffold_config.batch_update.class.link
275
+ raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
276
+ end
277
+ def batch_edit_formats
278
+ (default_formats + active_scaffold_config.formats).uniq
279
+ end
280
+ end
281
+ end
@@ -0,0 +1,79 @@
1
+ module ActiveScaffold::Config
2
+ class BatchCreate < ActiveScaffold::Config::Form
3
+ self.crud_type = :create
4
+ def initialize(*args)
5
+ super
6
+ @multipart = @core.create.multipart? if @core.actions.include? :create
7
+ @process_mode = self.class.process_mode
8
+ @list_mode_enabled = self.class.list_mode_enabled
9
+ @run_in_transaction = self.class.run_in_transaction
10
+ @layout = self.class.layout
11
+ end
12
+
13
+ # global level configuration
14
+ # --------------------------
15
+ # the ActionLink for this action
16
+ def self.link
17
+ @@link
18
+ end
19
+ def self.link=(val)
20
+ @@link = val
21
+ end
22
+ @@link = ActiveScaffold::DataStructures::ActionLink.new('batch_new', :label => :create, :type => :collection, :security_method => :batch_create_authorized?, :ignore_method => :batch_create_ignore?)
23
+
24
+ # configures where the plugin itself is located. there is no instance version of this.
25
+ cattr_accessor :plugin_directory
26
+ @@plugin_directory = File.expand_path(__FILE__).match(%{(^.*)/lib/active_scaffold/config/batch_create.rb})[1]
27
+
28
+ # configures how batch create should be processed
29
+ # :create => standard activerecord create including validations
30
+ cattr_accessor :process_mode
31
+ @@process_mode = :create
32
+
33
+ # you may update all records in list view or all marked records
34
+ # you might disable list mode with this switch if you think it is
35
+ # too "dangerous"
36
+ cattr_accessor :list_mode_enabled
37
+ @@list_mode_enabled = true
38
+
39
+ # run all create statements in a transaction, so no record is created
40
+ # if someone fails
41
+ cattr_accessor :run_in_transaction
42
+ @@run_in_transaction = true
43
+
44
+ # layout for create multiple records
45
+ cattr_accessor :layout
46
+ @@layout = :vertical
47
+
48
+ # instance-level configuration
49
+ # ----------------------------
50
+
51
+ # see class accessor
52
+ attr_accessor :process_mode
53
+
54
+ attr_accessor :list_mode_enabled
55
+
56
+ # you may use create_batch to create a record for each record
57
+ # of a belong_to association (reverse must be has_many)
58
+ # eg. player belongs to team
59
+ # you may batch create a player records for a list of teams
60
+ attr_accessor :default_batch_by_column
61
+
62
+ # run all create statements in a transaction, so no record is created
63
+ # if someone fails
64
+ attr_accessor :run_in_transaction
65
+
66
+ # layout for create multiple records
67
+ attr_accessor :layout
68
+
69
+ def action_group
70
+ @action_group || (default_batch_by_column ? 'collection.group' : 'collection')
71
+ end
72
+
73
+ # the label= method already exists in the Form base class
74
+ def label(model = nil)
75
+ model ||= @core.label(:count => 2)
76
+ @label ? as_(@label) : as_(:create_model, :model => model)
77
+ end
78
+ end
79
+ end