Created
January 10, 2014 10:18
-
-
Save vladimir-e/8349627 to your computer and use it in GitHub Desktop.
Amortization Calculator (accounting project)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# @author Vladimir E <[email protected]> | |
# | |
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