From 620f873186e9f69a05d88f79cfb899b42e584331 Mon Sep 17 00:00:00 2001 From: xuri Date: Mon, 18 Oct 2021 00:18:56 +0800 Subject: [PATCH] ref #65: new formula function AMORLINC --- calc.go | 35 +++++++++++++++++++++++++++++++++++ calc_test.go | 21 +++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/calc.go b/calc.go index d63bb3f..ba9085e 100644 --- a/calc.go +++ b/calc.go @@ -267,6 +267,7 @@ type formulaFuncs struct { // ACOT // ACOTH // AMORDEGRC +// AMORLINC // AND // ARABIC // ASIN @@ -8459,6 +8460,40 @@ func (fn *formulaFuncs) AMORDEGRC(argsList *list.List) formulaArg { return newNumberFormulaArg(nRate) } +// AMORLINC function is provided for users of the French accounting system. +// The function calculates the prorated linear depreciation of an asset for a +// specified accounting period. The syntax of the function is: +// +// AMORLINC(cost,date_purchased,first_period,salvage,period,rate,[basis]) +// +func (fn *formulaFuncs) AMORLINC(argsList *list.List) formulaArg { + if argsList.Len() != 6 && argsList.Len() != 7 { + return newErrorFormulaArg(formulaErrorVALUE, "AMORLINC requires 6 or 7 arguments") + } + args := fn.prepareAmorArgs("AMORLINC", argsList) + if args.Type != ArgList { + return args + } + cost, datePurchased, firstPeriod, salvage, period, rate, basis := args.List[0], args.List[1], args.List[2], args.List[3], args.List[4], args.List[5], args.List[6] + frac := yearFrac(datePurchased.Number, firstPeriod.Number, int(basis.Number)) + if frac.Type != ArgNumber { + return frac + } + rate1 := frac.Number * cost.Number * rate.Number + if period.Number == 0 { + return newNumberFormulaArg(rate1) + } + rate2 := cost.Number * rate.Number + delta := cost.Number - salvage.Number + periods := int((delta - rate1) / rate2) + if int(period.Number) <= periods { + return newNumberFormulaArg(rate2) + } else if int(period.Number)-1 == periods { + return newNumberFormulaArg(delta - rate2*float64(periods) - rate1) + } + return newNumberFormulaArg(0) +} + // CUMIPMT function calculates the cumulative interest paid on a loan or // investment, between two specified periods. The syntax of the function is: // diff --git a/calc_test.go b/calc_test.go index 6d16ce9..abf6afa 100644 --- a/calc_test.go +++ b/calc_test.go @@ -1242,6 +1242,12 @@ func TestCalcCellValue(t *testing.T) { "=AMORDEGRC(150,\"01/01/2015\",\"09/30/2015\",20,1,25%,4)": "41", "=AMORDEGRC(150,\"01/01/2015\",\"09/30/2015\",109,1,25%,4)": "54", "=AMORDEGRC(150,\"01/01/2015\",\"09/30/2015\",110,2,25%,4)": "0", + // AMORLINC + "=AMORLINC(150,\"01/01/2015\",\"09/30/2015\",20,1,20%,4)": "30", + "=AMORLINC(150,\"01/01/2015\",\"09/30/2015\",20,1,0%,4)": "0", + "=AMORLINC(150,\"01/01/2015\",\"09/30/2015\",20,20,15%,4)": "0", + "=AMORLINC(150,\"01/01/2015\",\"09/30/2015\",20,6,15%,4)": "0.6875", + "=AMORLINC(150,\"01/01/2015\",\"09/30/2015\",20,0,15%,4)": "16.8125", // CUMIPMT "=CUMIPMT(0.05/12,60,50000,1,12,0)": "-2294.97753732664", "=CUMIPMT(0.05/12,60,50000,13,24,0)": "-1833.1000665738893", @@ -2327,6 +2333,21 @@ func TestCalcCellValue(t *testing.T) { "=AMORDEGRC(150,\"01/01/2015\",\"09/30/2015\",20,1,20%,\"\")": "#NUM!", "=AMORDEGRC(150,\"01/01/2015\",\"09/30/2015\",20,1,50%)": "AMORDEGRC requires rate to be < 0.5", "=AMORDEGRC(150,\"01/01/2015\",\"09/30/2015\",20,1,20%,5)": "invalid basis", + // AMORLINC + "=AMORLINC()": "AMORLINC requires 6 or 7 arguments", + "=AMORLINC(\"\",\"01/01/2015\",\"09/30/2015\",20,1,20%)": "AMORLINC requires cost to be number argument", + "=AMORLINC(-1,\"01/01/2015\",\"09/30/2015\",20,1,20%)": "AMORLINC requires cost >= 0", + "=AMORLINC(150,\"\",\"09/30/2015\",20,1,20%)": "#VALUE!", + "=AMORLINC(150,\"01/01/2015\",\"\",20,1,20%)": "#VALUE!", + "=AMORLINC(150,\"09/30/2015\",\"01/01/2015\",20,1,20%)": "#NUM!", + "=AMORLINC(150,\"01/01/2015\",\"09/30/2015\",\"\",1,20%)": "#NUM!", + "=AMORLINC(150,\"01/01/2015\",\"09/30/2015\",-1,1,20%)": "#NUM!", + "=AMORLINC(150,\"01/01/2015\",\"09/30/2015\",20,\"\",20%)": "#NUM!", + "=AMORLINC(150,\"01/01/2015\",\"09/30/2015\",20,-1,20%)": "#NUM!", + "=AMORLINC(150,\"01/01/2015\",\"09/30/2015\",20,1,\"\")": "#NUM!", + "=AMORLINC(150,\"01/01/2015\",\"09/30/2015\",20,1,-1)": "#NUM!", + "=AMORLINC(150,\"01/01/2015\",\"09/30/2015\",20,1,20%,\"\")": "#NUM!", + "=AMORLINC(150,\"01/01/2015\",\"09/30/2015\",20,1,20%,5)": "invalid basis", // CUMIPMT "=CUMIPMT()": "CUMIPMT requires 6 arguments", "=CUMIPMT(0,0,0,0,0,2)": "#N/A",