Class: ProductNature

Inherits:
Ekylibre::Record::Base show all
Includes:
Customizable
Defined in:
app/models/product_nature.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-2019 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: product_natures

abilities_list            :text
active                    :boolean          default(FALSE), not null
category_id               :integer          not null
created_at                :datetime         not null
creator_id                :integer
custom_fields             :jsonb
derivative_of             :string
derivatives_list          :text
description               :text
evolvable                 :boolean          default(FALSE), not null
frozen_indicators_list    :text
id                        :integer          not null, primary key
linkage_points_list       :text
lock_version              :integer          default(0), not null
name                      :string           not null
number                    :string           not null
picture_content_type      :string
picture_file_name         :string
picture_file_size         :integer
picture_updated_at        :datetime
population_counting       :string           not null
reference_name            :string
subscribing               :boolean          default(FALSE), not null
subscription_days_count   :integer          default(0), not null
subscription_months_count :integer          default(0), not null
subscription_nature_id    :integer
subscription_years_count  :integer          default(0), not null
updated_at                :datetime         not null
updater_id                :integer
variable_indicators_list  :text
variety                   :string           not null

Defined Under Namespace

Classes: Item

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Customizable

#custom_value, #set_custom_value, #validate_custom_fields

Methods inherited from Ekylibre::Record::Base

#already_updated?, #check_if_destroyable?, #check_if_updateable?, columns_definition, #customizable?, customizable?, #customized?, #destroyable?, #editable?, has_picture, #human_attribute_name, nomenclature_reflections, #old_record, #others, refers_to, #unsuppress, #updateable?

Methods included from Userstamp::Stampable

included

Methods included from Userstamp::Stamper

included

Class Method Details

.any_reference_available?Boolean

Returns some nomenclature items are available to be imported, e.g. not already imported

Returns:

  • (Boolean)

318
319
320
# File 'app/models/product_nature.rb', line 318

def any_reference_available?
  Nomen::ProductNature.without(ProductNature.pluck(:reference_name).uniq).any?
end

.flattened_nomenclatureObject

Returns core attributes of nomenclature merge with nature if necessary name, variety, derivative_of, abilities


326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'app/models/product_nature.rb', line 326

def flattened_nomenclature
  @flattened_nomenclature ||= Nomen::ProductNature.list.collect do |item|
    f = (item.frozen_indicators || []).map(&:to_sym)
    v = (item.variable_indicators || []).map(&:to_sym)
    Item.new(
      item.name,
      Nomen::Variety.find(item.variety),
      Nomen::Variety.find(item.derivative_of),
      WorkingSet::AbilityArray.load(item.abilities),
      f + v, f, v
    )
  end
end

.import_from_nomenclature(reference_name, force = false) ⇒ Object

Load a product nature from product nature nomenclature


349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# File 'app/models/product_nature.rb', line 349

def import_from_nomenclature(reference_name, force = false)
  unless item = Nomen::ProductNature.find(reference_name)
    raise ArgumentError, "The product nature #{reference_name.inspect} is unknown"
  end
  unless category_item = Nomen::ProductNatureCategory.find(item.category)
    raise ArgumentError, "The category of the product_nature #{item.category.inspect} is unknown"
  end
  if !force && (nature = ProductNature.find_by(reference_name: reference_name))
    return nature
  end
  attributes = {
    variety: item.variety,
    derivative_of: item.derivative_of.to_s,
    name: item.human_name,
    population_counting: item.population_counting,
    category: ProductNatureCategory.import_from_nomenclature(item.category),
    reference_name: item.name,
    abilities_list: WorkingSet::AbilityArray.load(item.abilities),
    derivatives_list: (item.derivatives ? item.derivatives.sort : nil),
    frozen_indicators_list: (item.frozen_indicators ? item.frozen_indicators.sort : nil),
    variable_indicators_list: (item.variable_indicators ? item.variable_indicators.sort : nil),
    active: true
  }
  attributes[:linkage_points_list] = item.linkage_points if item.linkage_points
  create!(attributes)
end

.items_of_expression(expression) ⇒ Object

Lists ProductNature::Item which match given expression Fully compatible with WSQL


342
343
344
345
346
# File 'app/models/product_nature.rb', line 342

def items_of_expression(expression)
  flattened_nomenclature.select do |item|
    WorkingSet.check_record(expression, item)
  end
end

.load_defaultsObject Also known as: import_all_from_nomenclature

Load all product nature from product nature nomenclature


377
378
379
380
381
# File 'app/models/product_nature.rb', line 377

def load_defaults
  Nomen::ProductNature.find_each do |product_nature|
    import_from_nomenclature(product_nature.name)
  end
end

.matching_model(variety) ⇒ Object

Returns the closest matching model based on the given variety


189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'app/models/product_nature.rb', line 189

def self.matching_model(variety)
  if item = Nomen::Variety.find(variety)
    for ancestor in item.self_and_parents
      next unless model = begin
                            ancestor.name.camelcase.constantize
                          rescue
                            nil
                          end
      return model if model <= Product
    end
  end
  nil
end

Instance Method Details

#abilitiesObject

Returns list of abilities as an array of ability items from the nomenclature


264
265
266
267
268
# File 'app/models/product_nature.rb', line 264

def abilities
  abilities_list.collect do |i|
    (Nomen::Ability[i.to_s.split(/\(/).first] ? i.to_s : nil)
  end.compact
end

#ability(name) ⇒ Object


270
271
272
273
274
# File 'app/models/product_nature.rb', line 270

def ability(name)
  abilities_list.select do |a|
    a.to_s.split(/\(/).first == name.to_s
  end
end

#able_to?(ability) ⇒ Boolean

Returns:

  • (Boolean)

276
277
278
# File 'app/models/product_nature.rb', line 276

def able_to?(ability)
  of_expression("can #{ability}")
end

#able_to_each?(abilities) ⇒ Boolean

tests if all abilities are present @params: *abilities, a list of abilities to check. Can't be empty @returns: true if all abilities are matched, false if at least one ability is missing

Returns:

  • (Boolean)

283
284
285
# File 'app/models/product_nature.rb', line 283

def able_to_each?(abilities)
  of_expression(abilities.map { |a| "can #{a}" }.join(' and '))
end

#frozen_indicatorsObject

Returns list of froezen indicators as an array of indicator items from the nomenclature


229
230
231
# File 'app/models/product_nature.rb', line 229

def frozen_indicators
  frozen_indicators_list.collect { |i| Nomen::Indicator[i] }.compact
end

#has_indicator?(indicator) ⇒ Boolean

Returns:

  • (Boolean)

179
180
181
# File 'app/models/product_nature.rb', line 179

def has_indicator?(indicator)
  indicators_list.include? indicator
end

#identifiable?Boolean

Returns:

  • (Boolean)

175
176
177
# File 'app/models/product_nature.rb', line 175

def identifiable?
  of_variety?(:animal) || population_counting_unitary?
end

#indicatorsObject

Returns list of all indicators


219
220
221
# File 'app/models/product_nature.rb', line 219

def indicators
  (frozen_indicators + variable_indicators)
end

#indicators_listObject

Returns list of all indicators names


224
225
226
# File 'app/models/product_nature.rb', line 224

def indicators_list
  (frozen_indicators_list + variable_indicators_list)
end

Returns list of indicators as an array of indicator items from the nomenclature


239
240
241
# File 'app/models/product_nature.rb', line 239

def indicators_related_to(aspect)
  indicators.select { |i| i.related_to == aspect }
end

#individual_indicatorsObject

Returns individual indicators


254
255
256
# File 'app/models/product_nature.rb', line 254

def individual_indicators
  indicators_related_to(:individual)
end

#individual_indicators_listObject

Returns individual indicator names


259
260
261
# File 'app/models/product_nature.rb', line 259

def individual_indicators_list
  individual_indicators.map { |i| i.name.to_sym }
end

#linkage_pointsObject

Returns list of abilities as an array of ability items from the nomenclature


288
289
290
# File 'app/models/product_nature.rb', line 288

def linkage_points
  linkage_points_list
end

#matching_modelObject

Returns the matching model for the record


204
205
206
# File 'app/models/product_nature.rb', line 204

def matching_model
  self.class.matching_model(self.variety)
end

#of_expression(expression) ⇒ Object

Permit to check WSQL expression “locally” to ensure performance


184
185
186
# File 'app/models/product_nature.rb', line 184

def of_expression(expression)
  WorkingSet.check_record(expression, self)
end

#picture_path(style = :original) ⇒ Object


292
293
294
# File 'app/models/product_nature.rb', line 292

def picture_path(style = :original)
  picture.path(style)
end

#population_frozen?Boolean

Returns if population is frozen

Returns:

  • (Boolean)

209
210
211
# File 'app/models/product_nature.rb', line 209

def population_frozen?
  population_counting_unitary?
end

#population_moduloObject

Returns the minimum couting element


214
215
216
# File 'app/models/product_nature.rb', line 214

def population_modulo
  (population_counting_decimal? ? 0.0001 : 1)
end

#subscription_durationObject

Return humanized duration


297
298
299
300
301
302
303
# File 'app/models/product_nature.rb', line 297

def subscription_duration
  l = []
  l << 'x_years'.tl(count: self.subscription_years_count) if self.subscription_years_count > 0
  l << 'x_months'.tl(count: self.subscription_months_count) if self.subscription_months_count > 0
  l << 'x_days'.tl(count: self.subscription_days_count) if self.subscription_days_count > 0
  l.to_sentence
end

#subscription_stopped_on(started_on) ⇒ Object

Compute stopped_on date from a started_on date for subsrbing product nature


306
307
308
309
310
311
312
313
# File 'app/models/product_nature.rb', line 306

def subscription_stopped_on(started_on)
  stopped_on = started_on
  stopped_on += self.subscription_years_count.years
  stopped_on += self.subscription_months_count.months
  stopped_on += self.subscription_days_count.months
  stopped_on -= 1.day if stopped_on > started_on
  stopped_on
end

#variable_indicatorsObject

Returns list of variable indicators as an array of indicator items from the nomenclature


234
235
236
# File 'app/models/product_nature.rb', line 234

def variable_indicators
  variable_indicators_list.collect { |i| Nomen::Indicator[i] }.compact
end

#whole_indicatorsObject

Returns whole indicators


244
245
246
# File 'app/models/product_nature.rb', line 244

def whole_indicators
  indicators_related_to(:whole)
end

#whole_indicators_listObject

Returns whole indicator names


249
250
251
# File 'app/models/product_nature.rb', line 249

def whole_indicators_list
  whole_indicators.map { |i| i.name.to_sym }
end