Class: Sequence

Inherits:
Ekylibre::Record::Base show all
Defined in:
app/models/sequence.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: sequences

created_at       :datetime         not null
creator_id       :integer
id               :integer          not null, primary key
last_cweek       :integer
last_month       :integer
last_number      :integer
last_year        :integer
lock_version     :integer          default(0), not null
name             :string           not null
number_format    :string           not null
number_increment :integer          default(1), not null
number_start     :integer          default(1), not null
period           :string           default("number"), not null
updated_at       :datetime         not null
updater_id       :integer
usage            :string

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

.best_period_for(format) ⇒ Object


81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'app/models/sequence.rb', line 81

def best_period_for(format)
  keys = []
  format.match(replace_regexp) do |_m|
    key = Regexp.last_match(1)
    size = Regexp.last_match(3)
    pattern = Regexp.last_match(5)
    keys << key.to_sym
  end
  keys.delete(:number)
  # Because period size correspond to alphabetical order
  # We use thaht to find the littlest period
  keys.sort.first
end

.load_defaultsObject

Load defaults sequences


96
97
98
99
100
# File 'app/models/sequence.rb', line 96

def load_defaults
  usage.values.each do |usage|
    of(usage)
  end
end

.of(usage) ⇒ Object


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'app/models/sequence.rb', line 63

def of(usage)
  unless sequence = find_by(usage: usage)
    sequence = new(usage: usage)
    sequence.name = begin
                      sequence.usage.to_s.classify.constantize.model_name.human
                    rescue
                      sequence.usage
                    end
    sequence.number_format = tc("default.#{usage}", default: sequence.usage.to_s.split(/\_/).map { |w| w[0..0] }.join.upcase + '[number|12]')
    while find_by(number_format: sequence.number_format)
      sequence.number_format = ('A'..'Z').to_a.sample + sequence.number_format
    end
    sequence.period = best_period_for(sequence.number_format)
    sequence.save!
  end
  sequence
end

.replace_regexpObject


102
103
104
# File 'app/models/sequence.rb', line 102

def replace_regexp
  @replace_regexp ||= Regexp.new('\[(' + self.period.values.join('|') + ')(\|(\d+)(\|([^\]]*))?)?\]').freeze
end

Instance Method Details

#compute(number = nil) ⇒ Object


111
112
113
114
115
116
117
118
119
120
121
# File 'app/models/sequence.rb', line 111

def compute(number = nil)
  number ||= last_number
  today = Time.zone.today
  self['number_format'].gsub(self.class.replace_regexp) do |_m|
    key = Regexp.last_match(1)
    size = Regexp.last_match(3)
    pattern = Regexp.last_match(5)
    string = (key == 'number' ? number : today.send(key)).to_s
    size.nil? ? string : string.rjust(size.to_i, pattern || '0')
  end
end

#next_valueObject

Produces the next value of the sequence and update last value in DB


124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'app/models/sequence.rb', line 124

def next_value
  reload
  # FIXME: Bad method to prevent concurrency access to the method
  sleep(rand(50) / 1000)
  today = Time.zone.today
  period = self.period.to_s
  if last_number.nil?
    self.last_number = number_start
  else
    self.last_number += number_increment
  end
  if period != 'number' && !send('last_' + period).nil?
    self.last_number = number_start if send('last_' + period) != today.send(period) || last_year != today.year
  end
  self.last_year = today.year
  self.last_month = today.month
  self.last_cweek = today.cweek
  raise [updateable?, destroyable?, errors.to_hash].inspect unless save
  compute
end

#used?Boolean

Returns:

  • (Boolean)

107
108
109
# File 'app/models/sequence.rb', line 107

def used?
  !usage.blank?
end