Skip to content

Instantly share code, notes, and snippets.

@vladimir-e
Created January 10, 2014 10:18
Show Gist options
  • Save vladimir-e/8349627 to your computer and use it in GitHub Desktop.
Save vladimir-e/8349627 to your computer and use it in GitHub Desktop.
Amortization Calculator (accounting project)
#
# @author Vladimir E <mail@evladimir.com>
#
class Finliner.Models.AmortizationCalculator extends Finliner.Models.BaseModel
available_methods: [
"linear_period" # Линеийный способ (от срока)
"linear_percent" # Линеийный способ (от процента)
"residual_reducing" # Способ уменьшения остатка
"years_amount" # По сумме чисел лет
]
defaults :
method : null
price : null
liquidation_price : null
usage_time : null
annual_percent : null
acceleration_rate : null
acceptance_date : null
# call one of the special methods based on selected amortization type
calculate: ->
if @get('method') in @available_methods and @usage_time() > 0
amortization = @[@get('method')]()
# can't be more than initial price. I guess...
if amortization <= @price()
amortization
else
@price()
# переменная {стоимость} далее =
# Первоначальная стоимость или (Первоначальная стоимость – Ликвидационная стоимость)
# в зависимости от типа формулы исчисления (сликвидационной стоимостью или без)
# {стоимость} * (100%/срок использования)
# / 100%)/ 12 = ежемесячная сумма амортизации
linear_period: ->
monthly_percent = 1 / @usage_time()
monthly_payment = @price_value() * monthly_percent / 1
monthly_payment * @months_in_use()
# {стоимость} * Процент амортизации / 12 = ежемесячная сумма амортизации
linear_percent: ->
monthly_payment = @price_value() * ( @annual_percent() / 100 ) / 12
monthly_payment * @months_in_use()
# Годовая норма с учетом ускорения = 100 % / срок использования*коэффициент ускорения
# Амортизация за первый год = первоначальная стоимость * годовую норму с учетом ускорения
# Амортизация за каждый следующий год = (первоначальная стоимость – амортизация за прошлые года) * годовую норму с учетом ускорения
residual_reducing: ->
if @acceleration_rate() > 0
amortization = 0
annualNorm = 1 / @usage_time() * @acceleration_rate() * 12
firstYear = @price_value() * annualNorm
if @months_in_use() <= 12
amortization = @months_in_use() * (firstYear / 12)
else
amortization = firstYear
prevYear = firstYear
if @years_in_use() > 1
for [2..@years_in_use()]
thisYear = ( @price_value() - amortization ) * annualNorm
amortization += thisYear
prevYear = thisYear
# calculate for extra months
thisYear = ( @price_value() - prevYear ) * annualNorm
months = @months_in_use() - @years_in_use() * 12
amortization += months * (thisYear / 12)
amortization
else
0
# Амортизация за первый год = {стоимость} * на последнее число лет/ сумму чисел лет использования
# Амортизация за каждый следующий год = {стоимость} * на предыдущее число лет (от числе лет использованным при расчете амортизации предыдущего года) / сумму чисел лет использования
# примечание: Сумма чисел лет использования = сумме каждого года срока использования (например: срок использования – 3 года, сумма чисел лет использования = 1+2+3 = 6)
years_amount: ->
amortization = 0
yearsSum = @yearsSum()
firstYear = @price_value() * (@usage_time_full_years() or 1) / yearsSum
if @years_in_use() == 0
amortization = @months_in_use() * (firstYear / 12)
else
amortization = firstYear
if @years_in_use() > 1
for y in [2..@years_in_use()]
thisYear = @price_value() * (@usage_time_full_years() - y + 1) / yearsSum
amortization += thisYear
# calculate for extra months
thisYear = @price_value() * 1 / yearsSum
months = @months_in_use() - @years_in_use() * 12
amortization += months * (thisYear / 12)
amortization
yearsSum: ->
yearsSum = 0
yearsSum += y for y in [1..@usage_time_full_years()]
yearsSum
#--------------------------------------------------------------------------#
# #
# #
# Internal methods #
# #
price: ->
_.toF @get('price')
liquidation_price: ->
_.toF @get('liquidation_price')
usage_time: ->
_.toF @get('usage_time')
usage_time_full_years: ->
_.toI @usage_time() / 12
annual_percent: ->
_.toF @get('annual_percent')
acceleration_rate: ->
_.toF @get('acceleration_rate')
# returns moment object
acceptance_date: ->
# accept valid format
if @get('acceptance_date')? and @get("acceptance_date").length is 10
if @get("acceptance_date").indexOf(".") != -1
moment(@get('acceptance_date'), "DD.MM.YYYY")
else
moment(@get('acceptance_date'), "YYYY-MM-DD")
else
moment()
isLiquidationable: ->
@liquidation_price() > 0
# {стоимость} см. выше
price_value: ->
if @isLiquidationable()
_.toF @price() - @liquidation_price()
else
_.toF @price()
days_in_use: ->
seconds_start = @acceptance_date().format("X")
seconds_now = moment().format("X")
seconds_range = seconds_now - seconds_start
_.toI( seconds_range / (24*60*60) )
# return Integer - full months count
months_in_use: ->
# months count between acceptace date and now
months = (moment().years() - @acceptance_date().years()) * 12
months -= @acceptance_date().months()
months += moment().months()
# TODO make this calculation more precise
# calculate average days in months, should be > ~30.44 if there is only full months
average_days = @days_in_use() / months
# round up to 2 decimal places
average_days = Math.round(average_days * 100) / 100
# remove one if last months haven't ended yet
if average_days < 30.44
months -= 1
if months <= 0 then 0 else months
years_in_use: ->
_.toI @months_in_use() / 12
# #
# #
#--------------------------------------------------------------------------#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment