Class: FixedAsset

Inherits:
Ekylibre::Record::Base show all
Includes:
Attachable, Customizable
Defined in:
app/models/fixed_asset.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: fixed_assets

allocation_account_id   :integer          not null
ceded                   :boolean
ceded_on                :date
created_at              :datetime         not null
creator_id              :integer
currency                :string           not null
current_amount          :decimal(19, 4)
custom_fields           :jsonb
depreciable_amount      :decimal(19, 4)   not null
depreciated_amount      :decimal(19, 4)   not null
depreciation_method     :string           not null
depreciation_percentage :decimal(19, 4)
description             :text
expenses_account_id     :integer
id                      :integer          not null, primary key
journal_id              :integer          not null
lock_version            :integer          default(0), not null
name                    :string           not null
number                  :string           not null
purchase_amount         :decimal(19, 4)
purchase_id             :integer
purchase_item_id        :integer
purchased_on            :date
sale_id                 :integer
sale_item_id            :integer
started_on              :date             not null
stopped_on              :date             not null
updated_at              :datetime         not null
updater_id              :integer

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?, 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

.duration(started_on, stopped_on, options = {}) ⇒ Object

Returns the duration in days between to 2 times


230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'app/models/fixed_asset.rb', line 230

def self.duration(started_on, stopped_on, options = {})
  days = 0
  options[:mode] ||= :linear
  if options[:mode] == :simplified_linear
    sa = ((started_on.day >= 30 || (started_on.end_of_month == started_on)) ? 30 : started_on.day)
    so = ((stopped_on.day >= 30 || (stopped_on.end_of_month == stopped_on)) ? 30 : stopped_on.day)

    if started_on.beginning_of_month == stopped_on.beginning_of_month
      days = so - sa + 1
    else
      days = 30 - sa + 1
      cursor = started_on.beginning_of_month
      while (cursor >> 1) < stopped_on.beginning_of_month
        cursor = cursor >> 1
        days += 30
      end
      days += so
    end

  # cursor = started_on.to_date
  # if started_on == started_on.end_of_month or started_on.day >= 30
  #   days += 1
  #   cursor = started_on.end_of_month + 1
  # elsif started_on.month == stopped_on.month and started_on.year == stopped_on.year
  #   days += so - sa + 1
  #   cursor = stopped_on
  # elsif started_on != started_on.beginning_of_month
  #   days += 30 - sa + 1
  #   cursor = started_on.end_of_month + 1
  # end

  # while (cursor >> 1).beginning_of_month < stopped_on.beginning_of_month
  #   cursor = cursor >> 1
  #   days += 30
  # end
  # if cursor < stopped_on
  #   days += [30, (so - cursor.day + 1)].min
  # end
  elsif options[:mode] == :linear
    days = (stopped_on - started_on) + 1
  else
    raise "What ? #{options[:mode].inspect}"
  end
  days.to_f
end

Instance Method Details

#depreciate!Object


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

def depreciate!
  planned_depreciations.clear
  # Computes periods
  starts = [started_on, self.stopped_on + 1]
  starts += depreciations.pluck(:started_on)

  FinancialYear.at(self.stopped_on)
  for financial_year in FinancialYear.where(started_on: started_on..self.stopped_on).reorder(:started_on)
    start = financial_year.started_on
    starts << start if started_on <= start && start <= self.stopped_on
  end
  starts = starts.uniq.sort
  send("depreciate_with_#{depreciation_method}_method", starts)
  self
end

#depreciate_with_linear_method(starts) ⇒ Object

Depreciate using linear method


166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'app/models/fixed_asset.rb', line 166

def depreciate_with_linear_method(starts)
  depreciable_days = duration.round(2)
  depreciable_amount = self.depreciable_amount
  for depreciation in depreciations
    depreciable_days -= depreciation.duration.round(2)
    depreciable_amount -= depreciation.amount
  end

  # Create it if not exists?
  remaining_amount = depreciable_amount.to_d
  position = 1
  starts.each_with_index do |start, index|
    next if starts[index + 1].nil?
    unless depreciation = depreciations.find_by(started_on: start)
      depreciation = depreciations.new(started_on: start, stopped_on: starts[index + 1] - 1)
      duration = depreciation.duration.round(2)
      depreciation.amount = [remaining_amount, currency.to_currency.round(depreciable_amount * duration / depreciable_days)].min
      remaining_amount -= depreciation.amount
    end
    depreciation.financial_year = FinancialYear.at(depreciation.started_on)

    depreciation.position = position
    position += 1
    unless depreciation.save
      raise 'AAAAAAAAAAAAAAAAAAAARrrrrrrrrrrrrrrrrr' + depreciation.errors.inspect
    end
  end
end

#depreciate_with_simplified_linear_method(starts) ⇒ Object

Depreciate using simplified linear method Years have 12 months with 30 days


197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'app/models/fixed_asset.rb', line 197

def depreciate_with_simplified_linear_method(starts)
  depreciable_days = duration
  depreciable_amount = self.depreciable_amount
  for depreciation in reload.depreciations
    depreciable_days -= depreciation.duration
    depreciable_amount -= depreciation.amount
  end

  # Create it if not exists?
  remaining_amount = depreciable_amount.to_d
  position = 1
  starts.each_with_index do |start, index|
    next if starts[index + 1].nil?
    unless depreciation = depreciations.find_by(started_on: start)
      depreciation = depreciations.new(started_on: start, stopped_on: starts[index + 1] - 1)
      duration = depreciation.duration
      depreciation.amount = [remaining_amount, currency.to_currency.round(depreciable_amount * duration / depreciable_days)].min
      remaining_amount -= depreciation.amount
    end
    depreciation.financial_year = FinancialYear.at(depreciation.started_on)

    depreciation.position = position
    position += 1
    depreciation.save!
  end
end

#durationObject

Returns the duration in days of all the depreciations


225
226
227
# File 'app/models/fixed_asset.rb', line 225

def duration
  self.class.duration(started_on, self.stopped_on, mode: depreciation_method.to_sym)
end