Class: ListingNode

Inherits:
Ekylibre::Record::Base show all
Defined in:
app/models/listing_node.rb

Overview

Informations

License

Ekylibre - Simple agricultural ERP Copyright (C) 2008-2009 Brice Texier, Thibaud Merigon Copyright (C) 2010-2012 Brice Texier Copyright (C) 2012-2016 Brice Texier, David Joulin

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see www.gnu.org/licenses.

Table: listing_nodes

attribute_name       :string
condition_operator   :string
condition_value      :string
created_at           :datetime         not null
creator_id           :integer
depth                :integer          default(0), not null
exportable           :boolean          default(TRUE), not null
id                   :integer          not null, primary key
item_listing_id      :integer
item_listing_node_id :integer
item_nature          :string
item_value           :text
key                  :string
label                :string           not null
lft                  :integer
listing_id           :integer          not null
lock_version         :integer          default(0), not null
name                 :string           not null
nature               :string           not null
parent_id            :integer
position             :integer
rgt                  :integer
sql_type             :string
updated_at           :datetime         not null
updater_id           :integer

Constant Summary collapse

@@natures =
nature.values
@@comparators =
{
  numeric: %w(any gt lt ge le eq neq vn nvn),
  string: %w(any begins finishes contains equal in not_begins not_finishes not_contains not_equal begins_cs finishes_cs contains_cs equal_cs not_begins_cs not_finishes_cs not_contains_cs not_equal_cs),
  date: %w(any gt lt ge le eq neq vn nvn),
  boolean: %w(any is_true is_false),
  unknown: ['--']
}
@@corresponding_comparators =
{
  eq: '{{COLUMN}} = {{VALUE}}',
  neq: '{{COLUMN}} != {{VALUE}}',
  gt: '{{COLUMN}} > {{VALUE}}',
  lt: '{{COLUMN}} < {{VALUE}}',
  ge: '{{COLUMN}} >= {{VALUE}}',
  le: '{{COLUMN}} <= {{VALUE}}',
  vn: '{{COLUMN}} IS NULL',
  nvn: '{{COLUMN}} IS NOT NULL',
  begins: 'LOWER({{COLUMN}}) LIKE {{VALUE%}}',
  finishes: 'LOWER({{COLUMN}}) LIKE {{%VALUE}}',
  contains: 'LOWER({{COLUMN}}) LIKE {{%VALUE%}}',
  equal: 'LOWER({{COLUMN}}) = {{VALUE}}',
  begins_cs: '{{COLUMN}} LIKE {{VALUE%}}',
  finishes_cs: '{{COLUMN}} LIKE {{%VALUE}}',
  contains_cs: '{{COLUMN}} LIKE {{%VALUE%}}',
  equal_cs: '{{COLUMN}} = {{VALUE}}',
  not_begins: 'LOWER({{COLUMN}}) NOT LIKE {{VALUE%}}',
  not_finishes: 'LOWER({{COLUMN}}) NOT LIKE {{%VALUE}}',
  not_contains: 'LOWER({{COLUMN}}) NOT LIKE {{%VALUE%}}',
  not_equal: 'LOWER({{COLUMN}}) != {{VALUE}}',
  not_begins_cs: '{{COLUMN}} NOT LIKE {{VALUE%}}',
  not_finishes_cs: '{{COLUMN}} NOT LIKE {{%VALUE}}',
  not_contains_cs: '{{COLUMN}} NOT LIKE {{%VALUE%}}',
  not_equal_cs: '{{COLUMN}} != {{VALUE}}',
  is_true: '{{COLUMN}} = {{VALUE}}',
  is_false: '{{COLUMN}} = {{VALUE}}',
  in: '{{COLUMN}} IN {{LIST}}'
}

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Ekylibre::Record::Base

#already_updated?, attr_readonly_with_conditions, #check_if_destroyable?, #check_if_updateable?, columns_definition, complex_scopes, customizable?, #customizable?, #customized?, #destroyable?, #editable?, has_picture, #human_attribute_name, human_attribute_name_with_id, nomenclature_reflections, #old_record, #others, refers_to, scope_with_registration, simple_scopes, #updateable?

Class Method Details

.condition(column, operator, value, datatype = 'string') ⇒ Object


182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'app/models/listing_node.rb', line 182

def self.condition(column, operator, value, datatype = 'string')
  operation = @@corresponding_comparators[operator.to_sym] || @@corresponding_comparators[:equal]
  c = operation.gsub('{{COLUMN}}', column)
  c.gsub!('{{LIST}}', '(' + value.to_s.gsub(/\,\,/, "\t").split(/\s*\,\s*/).collect { |x| connection.quote(x.tr("\t", ',')) }.join(', ') + ')')
  c.gsub!(/\{\{[^\}]*VALUE[^\}]*\}\}/) do |m|
    n = m[2..-3].gsub('VALUE', value.to_s.send(operator.to_s =~ /_cs$/ ? 'to_s' : 'lower'))
    #       if datatype == "date"
    #         "'"+connection.quoted_date(value.to_date)+"'"
    if datatype == 'boolean'
      (operator.to_s == 'is_true' ? connection.quoted_true : connection.quoted_false)
    elsif datatype == 'numeric'
      n
    else
      # "'"+connection.quote(n)+"'"
      connection.quote(n)
    end
  end
  c
end

.naturesObject


144
145
146
147
148
# File 'app/models/listing_node.rb', line 144

def self.natures
  hash = {}
  @@natures.each { |n| hash[n] = tc('natures.' + n.to_s) }
  hash
end

Instance Method Details

#available_nodesObject


229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'app/models/listing_node.rb', line 229

def available_nodes
  nodes = []
  return nodes unless reflection? && model = self.model
  # Columns
  column_nodes = model.content_columns.collect { |x| [model.human_attribute_name(x.name.to_s).to_s, 'column-' + x.name] }
  if model.customizable?
    column_nodes.delete_if { |_, col| col == 'column-custom_fields' }
    model.custom_fields.each do |custom|
      column_nodes << [custom.name, 'special-custom-' + custom.column_name]
    end
  end
  nodes << [tc(:columns), [[tc(:all_columns), 'special-all_columns']] + column_nodes.sort]
  # Reflections
  nodes << [tc(:reflections), model.reflect_on_all_associations.select { |v| [:has_many, :belongs_to].include? v.macro }.collect { |r| [model.human_attribute_name(r.name).to_s, "#{r.macro}-#{r.name}"] }.sort]
  nodes
end

#comparatorsObject


168
169
170
171
172
# File 'app/models/listing_node.rb', line 168

def comparators
  # raise StandardError.new self.sql_type.inspect
  # return @@comparators[self.sql_type.to_sym] if self.sql_type
  @@comparators[sql_type.to_sym].collect { |x| [tc('comparators.' + x), x] } if sql_type
end

#comparisonObject


273
274
275
276
277
278
279
280
281
282
283
# File 'app/models/listing_node.rb', line 273

def comparison
  if condition_operator && condition_operator != 'any'
    if condition_value
      return tc('comparison.with_value', comparator: tc('comparators.' + condition_operator), value: (sql_type == 'date' ? I18n.localize(condition_value.to_date) : condition_value.to_s))
    else
      return tc('comparison.without_value', comparator: tc('comparators.' + condition_operator))
    end
  else
    return tc(:add_filter)
  end
end

#compute_joins(sql_alias = nil) ⇒ Object


150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'app/models/listing_node.rb', line 150

def compute_joins(sql_alias = nil)
  conditions = ''
  children.where('(nature = ? OR nature = ?)', 'belongs_to', 'has_many').each do |child|
    parent = sql_alias || name || child.parent.model.table_name
    if child.nature == 'has_many' # or child.nature == "belongs_to"
      conditions += " LEFT JOIN #{child.model.table_name} AS #{child.name} ON (#{child.name}.#{child.reflection.foreign_key} = #{parent}.id)"
    elsif child.nature == 'belongs_to'
      conditions += " LEFT JOIN #{child.model.table_name} AS #{child.name} ON (#{parent}.#{child.reflection.foreign_key} = #{child.name}.id)"
    end
    conditions += child.compute_joins
  end
  conditions
end

#conditionObject


178
179
180
# File 'app/models/listing_node.rb', line 178

def condition
  self.class.condition(name, condition_operator, condition_value, sql_type)
end

#convert_sql_type(type) ⇒ Object


246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'app/models/listing_node.rb', line 246

def convert_sql_type(type)
  # raise StandardError.new type.inspect
  if type == 'decimal' || type == 'integer'
    return 'numeric'
  elsif type == 'string' || type == 'text'
    return 'string'
  elsif type == 'date' || type == 'datetime'
    return 'date'
  elsif type == 'boolean'
    return type
  else
    return 'unknown'
  end
end

#default_comparison_valueObject


261
262
263
264
265
266
267
268
269
270
271
# File 'app/models/listing_node.rb', line 261

def default_comparison_value
  if sql_type == 'numeric'
    return 0
  elsif sql_type == 'string' || sql_type == 'text'
    return ''
  elsif sql_type == 'date' || sql_type == 'datetime'
    return Time.zone.today
  else
    return ''
  end
end

#duplicate(listing_clone, parent = nil) ⇒ Object


285
286
287
288
289
290
291
292
293
294
295
296
# File 'app/models/listing_node.rb', line 285

def duplicate(listing_clone, parent = nil)
  kepts = [:attribute_name, :condition_operator, :condition_value, :exportable, :item_listing_id, :item_listing_node_id, :item_nature, :item_value, :label, :name, :nature, :position]
  attributes = self.attributes.symbolize_keys.select do |name, _value|
    kepts.include?(name)
  end
  attributes[:listing_id] = listing_clone.id
  attributes[:parent_id]  = (parent ? parent.id : nil)
  node = self.class.create!(attributes)
  for child in children.order(:position)
    child.duplicate(listing_clone, node)
  end
end

#joinsObject


164
165
166
# File 'app/models/listing_node.rb', line 164

def joins
  self
end

#modelObject


210
211
212
213
214
215
216
217
218
# File 'app/models/listing_node.rb', line 210

def model
  if root?
    listing.root_model
  else
    parent.model.reflect_on_association(attribute_name).class_name
  end.pluralize.classify.constantize
rescue
  nil
end

#reflectionObject


220
221
222
223
224
225
226
227
# File 'app/models/listing_node.rb', line 220

def reflection
  return nil unless reflection?
  if root?
    return nil
  else
    return parent.model.reflect_on_association(attribute_name)
  end
end

#reflection?Boolean

Returns:

  • (Boolean)

202
203
204
# File 'app/models/listing_node.rb', line 202

def reflection?
  %w(belongs_to has_many root).include? nature.to_s
end

#root?Boolean

Returns:

  • (Boolean)

206
207
208
# File 'app/models/listing_node.rb', line 206

def root?
  parent_id.nil?
end

#sql_format_comparatorObject


174
175
176
# File 'app/models/listing_node.rb', line 174

def sql_format_comparator
  @@corresponding_comparators[condition_operator.to_sym] || ' = '
end