active_scaffold_batch 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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