From: Hirzel P. <ph...@us...> - 2008-06-15 18:39:09
|
Update of /cvsroot/tcotool/TCO-Tool/src/org/tcotool/tools In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv28783/src/org/tcotool/tools Modified Files: Calculator.java Added Files: CalculatorTco.java CalculatorLinearDepreciation.java CalculatorDegressiveDepreciation.java Log Message: Refactoring: Algorithm exchange --- NEW FILE: CalculatorDegressiveDepreciation.java --- package org.tcotool.tools; /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ import org.tcotool.model.Cost; import org.tcotool.model.CostDriver; import org.tcotool.model.FactCost; import org.tcotool.model.Service; import org.tcotool.model.TcoObject; import ch.softenvironment.math.FinancialUtils; import ch.softenvironment.math.MathUtils; /** * Accounting calculator for "linear depreciation with compound interest". * @author Peter Hirzel <i>soft</i>Environment * @version $Revision: 1.1 $ $Date: 2008/06/15 18:39:14 $ */ public class CalculatorDegressiveDepreciation extends Calculator { /** * Initialize calculator for given rootObject and TotalCosts only. * @param object */ public CalculatorDegressiveDepreciation(ModelUtility utility) { this(utility, (TcoObject)utility.getRoot(), 0); } /** * @see #Calculator(ModelUtility, TcoObject, long, ServiceCategory, Responsibility) */ public CalculatorDegressiveDepreciation(ModelUtility utility, TcoObject rootObject, long maxDurationMonths) { super(utility, rootObject, maxDurationMonths, null); } /** * Accumulate costs of financial matters for e.g. accounting, interests, depreciation and the like * for the given cost in driver and service. * * (PersonalCost cannot be depreciated!) * @param service * @param driver * @param cost Consider FactCost's with a depreciationDuration > 1 year * @param capital (cost * factor) */ protected void calculate(Service service, CostDriver driver, Cost cost, double capital) { if (cost instanceof FactCost) { FactCost fCost = (FactCost)cost; boolean repeatable = (cost.getRepeatable() != null) && cost.getRepeatable().booleanValue(); int baseOffset = (cost.getBaseOffset() == null ? 0 : cost.getBaseOffset().intValue()); int baseYear = baseOffset / 12; long depreciationDuration = fCost.getDepreciationDuration() == null ? 0 : fCost.getDepreciationDuration().longValue(); if (depreciationDuration > 0) { // 1) [0] total FactCost independent of depreciation (baseOffset irrelevant) accumulateCodes(service, driver, cost, INDEX_TOTAL, capital); //storeIntoCodeList(serviceMap, KIND_FC, DEPRECIATION_LINEAR, INDEX_TOTAL, capital); // 2) [1+baseOffset..n] year // [1..fCost.depreciationYears] of first period of FactCost's depreciationDuration int year = calcDepreciation(service, driver, fCost, capital, INDEX_TOTAL); // [after fCost.depreciationYears years] repeatable periods if ((cost.getRepeatable() != null) && cost.getRepeatable().booleanValue() && (year < getDurationYears())) { // repeat the costs until maxDuration while (year < getDurationYears()) { //TODO Check: probably degressive depreciation costs from duration before are not calculated further on, which would go infinitely down to 0 year = calcDepreciation(service, driver, fCost, capital, year); } } } } } /** * Calculate the <b>linear depreciation</b> over the whole FactCost-DepreciationDuration. * Algorithm: * - Linear Depreciation * @param costCapital * @param costDuration * @return year of last Cost-entry */ private int calcDepreciation(Service service, CostDriver driver, FactCost cost, double costCapital, int yearIndex) { int duration = cost.getDepreciationDuration().intValue(); int completeYears = duration / 12; if (duration % 12 > 0) { // consider a partial duration after last complete year as one more year completeYears++; } int year = 0; for (; year<completeYears; year++) { int period = year + 1; //double amount = FinancialUtils.calcDepreciationLinear(costCapital, completeYears, period); // [de] Buchwert // depreciation over full year //accumulateCodes(service, driver, cost, DEPRECIATION_LINEAR, yearIndex + period, amount); double amount = FinancialUtils.calcDepreciationGeometricDegressive(costCapital, utility.getInterestRate(), period); // [de] Buchwert // depreciation over full year accumulateCodes(service, driver, cost, yearIndex + period, amount); } return year + yearIndex; } /** * Return cost-list over given object. * @param object null for all services * @return [FactCosts_Total; Depreciation_Year1;.. TCO_YearN] public List getDepreciationCostBlock(TcoObject object, final String type) { TcoObject costObject = (object == null ? rootObject : object); // return getCosts(costObject, KIND_FC, type); List costs = new ArrayList(); List totalFacts = getTotalCosts(costObject, type); costs.add(new Double(getValue(totalFacts, INDEX_TOTAL))); for (int i=0; i<getDurationYears(); i++) { // print Depreciation-Years int index = i + INDEX_TOTAL + 1; costs.add(new Double(getValue(totalFacts, index))); } return costs; }*/ } --- NEW FILE: CalculatorTco.java --- package org.tcotool.tools; /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ import org.tcotool.model.Cost; import org.tcotool.model.CostDriver; import org.tcotool.model.FactCost; import org.tcotool.model.PersonalCost; import org.tcotool.model.Service; import org.tcotool.model.TcoObject; import ch.softenvironment.jomm.mvc.model.DbCodeType; /** * Calculator for specific TCO-Calculations. * @author Peter Hirzel <i>soft</i>Environment * @version $Revision: 1.1 $ $Date: 2008/06/15 18:39:14 $ */ public class CalculatorTco extends Calculator { public CalculatorTco(ModelUtility utility) { this(utility, (TcoObject)utility.getRoot(), 0); } public CalculatorTco(ModelUtility utility, TcoObject rootObject, long maxDurationMonths) { this(utility, rootObject, maxDurationMonths, null); } public CalculatorTco(ModelUtility utility, TcoObject rootObject, long maxDurationMonths, DbCodeType maskCode) { super(utility, rootObject, maxDurationMonths, maskCode); } /** * Accumulate the TCO-Costs for given cost' CostType: * @param driver owner of given cost * @param cost * @param totalCost (costs * factor) */ protected void calculate(Service service, CostDriver driver, Cost cost, double totalCost) { //double totalCost = cost.getAmount().doubleValue() * factor; boolean repeatable = (cost.getRepeatable() != null) && cost.getRepeatable().booleanValue(); int baseOffset = cost.getBaseOffset().intValue(); int baseYear = baseOffset / 12; int year = INDEX_TOTAL + 1 + baseYear; if (cost instanceof PersonalCost) { // usage=12 months! // 1) [0] total PersonalCost for a year (baseOffset irrelevant) accumulateCodes(service, driver, cost, INDEX_TOTAL, totalCost); // [1..n years] personal effort is the SAME for each following TCO-Year (usage=12 months!) /*if (repeatable) { calcTcoRepeatable(service, driver, cost, PERSONAL_TCO, totalCost, baseOffset); } else {*/ // 2) calculate [1+baseOffset] year if (baseOffset % 12 == 0) { accumulateCodes(service, driver, cost, year++, totalCost); } else { // treat first year partially ONLY! double part = totalCost / 12.0 * (12.0 - (double)(baseOffset - baseYear * 12.0)); accumulateCodes(service, driver, cost, year++, part); if (!repeatable) { // 3.1) book rest part of the costs in the following year accumulateCodes(service, driver, cost, year, totalCost - part); } } // 3.2) [2+baseOffset..n] years personal cost is the SAME for each following TCO-Year if (repeatable) { long completeYears = getMaxDurationMonths() / 12; for (; year<completeYears+1; year++) { accumulateCodes(service, driver, cost, year, totalCost); } // if the last year is not even in maxUsage long partialMonthInYear = getMaxDurationMonths() % 12; if (partialMonthInYear > 0) { // ignore partial costs in case of (baseOffset%12!=0) because repeatable anyway accumulateCodes(service, driver, cost, year, totalCost / 12.0 * partialMonthInYear); } } //} } else { FactCost fCost = (FactCost)cost; if ((fCost.getUsageDuration() != null) && (fCost.getUsageDuration().longValue() > 0)) { // 1) [0] total FactCost independent of usage (baseOffset irrelevant) accumulateCodes(service, driver, cost, INDEX_TOTAL, totalCost); // 2) [1+baseOffset..n] year double costPerMonth = totalCost / fCost.getUsageDuration().doubleValue(); for (int month=0; month<getMaxDurationMonths(); month++) { if ((month<fCost.getUsageDuration().intValue()) || repeatable) { if ((month > 0) && (month % 12 == 0)) { // next year year++; } accumulateCodes(service, driver, cost, year, costPerMonth); } else { break; } } /* // [1..n years] FactCost's divided by usage if (repeatable) { // usageDuration is in maxUsage range anyway if (fCost.getUsageDuration().longValue() < 12) { // the given cost-amount counts for whole year calcTcoRepeatable(service, driver, cost, FACT_TCO, totalCost, baseOffset); } else { calcTcoRepeatable(service, driver, cost, FACT_TCO, costPerMonth * 12.0, baseOffset); } } else { // once in maxUsage for whole UsageDuration long completeYears = fCost.getUsageDuration().longValue() / 12; double correctionCosts = 0.0; if (baseYear > 0) { // if baseOffset points to middle of year, only calculate costs partially in first relevant year double months = 12.0 - (double)(baseOffset % 12); correctionCosts = correctionCosts + costPerMonth * months; cummulateCodes(service, driver, cost, FACT_TCO, year, costPerMonth * months); year++; } for (; year<completeYears; year++) { // usage over full year correctionCosts = correctionCosts + costPerMonth * 12.0; cummulateCodes(service, driver, cost, FACT_TCO, year, costPerMonth * 12.0); } long partialMonthInYear = fCost.getUsageDuration().longValue() % 12; if (partialMonthInYear > 0) { // last Usage year adds only fraction part correctionCosts = correctionCosts + costPerMonth * (double)partialMonthInYear; cummulateCodes(service, driver, cost, FACT_TCO, year, costPerMonth * (double)partialMonthInYear); year++; } if (correctionCosts > totalCost) { // NASTY: because of baseOffset to many costs were booked in last year cummulateCodes(service, driver, cost, FACT_TCO, year - 1, totalCost - correctionCosts); } } */ } } } /** * Repeatable Cost's must be reconsidered after UsageDuration in years 1..n. private void calcTcoRepeatable(Service service, CostDriver driver, Cost cost, final String keyPrefix, double costPerYear, int baseOffset) { int baseYear = baseOffset / 12; // [1..n years] personal effort is added to each following TCO-Year long completeYears = getMaxDurationMonths() / 12; int year = 0 + baseYear; for (; year<completeYears; year++) { accumulateCodes(service, driver, cost, METHOD_TCO, year + INDEX_TOTAL + 1, costPerYear); } // if the last year is not even in maxUsage long partialMonthInYear = getMaxDurationMonths() % 12; if (partialMonthInYear > 0) { accumulateCodes(service, driver, cost, METHOD_TCO, year + INDEX_TOTAL + 1, costPerYear / 12.0 * partialMonthInYear); } } */ } --- NEW FILE: CalculatorLinearDepreciation.java --- package org.tcotool.tools; /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ import org.tcotool.model.Cost; import org.tcotool.model.CostDriver; import org.tcotool.model.FactCost; import org.tcotool.model.Service; import org.tcotool.model.TcoObject; import ch.softenvironment.math.MathUtils; /** * Accounting calculator for "linear depreciation". * @author Peter Hirzel <i>soft</i>Environment * @version $Revision: 1.1 $ $Date: 2008/06/15 18:39:14 $ */ public class CalculatorLinearDepreciation extends Calculator { /** * Initialize calculator for given rootObject and TotalCosts only. * @param object */ public CalculatorLinearDepreciation(ModelUtility utility) { this(utility, (TcoObject)utility.getRoot(), 0); } /** * @see #Calculator(ModelUtility, TcoObject, long, ServiceCategory, Responsibility) */ public CalculatorLinearDepreciation(ModelUtility utility, TcoObject rootObject, long maxDurationMonths) { super(utility, rootObject, maxDurationMonths, null); } /** * Accumulate costs of financial matters for e.g. accounting, interests, depreciation and the like * for the given cost in driver and service. * * (PersonalCost cannot be depreciated!) * @param service * @param driver * @param cost Consider FactCost's with a depreciationDuration > 1 year * @param capital (cost * factor) */ protected void calculate(Service service, CostDriver driver, Cost cost, double capital) { if (cost instanceof FactCost) { boolean repeatable = (cost.getRepeatable() != null) && cost.getRepeatable().booleanValue(); int baseOffset = (cost.getBaseOffset() == null ? 0 : cost.getBaseOffset().intValue()); int baseYear = baseOffset / 12; long depreciationDuration = ((FactCost)cost).getDepreciationDuration() == null ? 0 : ((FactCost)cost).getDepreciationDuration().longValue(); if (depreciationDuration > 12) { // 1) [0] total FactCost independent of depreciation (baseOffset irrelevant) accumulateCodes(service, driver, cost, INDEX_TOTAL, capital); //storeIntoCodeList(serviceMap, KIND_FC, DEPRECIATION_LINEAR, INDEX_TOTAL, capital); // 2) [1+baseOffset..n] year double depreciationPerMonth = MathUtils.negate(new Double(capital / (double)depreciationDuration)).doubleValue(); // de: Abschreibungsbetrag per month FinancialUtils.calcDepreciationLinear(capital, cost.getDepreciationDuration().intValue(), 1); double currentCapital = capital; int year = INDEX_TOTAL + 1 + baseYear; // first relevant year accumulateCodes(service, driver, cost, year, capital); //storeIntoCodeList(serviceMap, KIND_FC, DEPRECIATION_LINEAR, year, capital); for (int month=0; month<getMaxDurationMonths(); month++) { if ((month > 0) && (month % 12 == 0)) { // next year year++; // following years accumulateCodes(service, driver, cost, year, currentCapital); //storeIntoCodeList(serviceMap, KIND_FC, DEPRECIATION_LINEAR, year, currentCapital); } accumulateCodes(service, driver, cost, year, depreciationPerMonth); //storeIntoCodeList(serviceMap, KIND_FC, DEPRECIATION_LINEAR, year, depreciationPerMonth); currentCapital = currentCapital + depreciationPerMonth; if ((MathUtils.compare(currentCapital, 0.0) == 0) || (currentCapital < 0.0 /* should not happen */)) { if (repeatable) { // re-invest currentCapital = capital; accumulateCodes(service, driver, cost, year, capital); //storeIntoCodeList(serviceMap, KIND_FC, DEPRECIATION_LINEAR, year, capital); } else { // no more depreciable: currentCapital => 0.0; break; } } } } } } /** * Return cost-list over given object. * @param object null for all services * @return [FactCosts_Total; Depreciation_Year1;.. TCO_YearN] public List getDepreciationCostBlock(TcoObject object, final String type) { TcoObject costObject = (object == null ? rootObject : object); // return getCosts(costObject, KIND_FC, type); List costs = new ArrayList(); List totalFacts = getTotalCosts(costObject, type); costs.add(new Double(getValue(totalFacts, INDEX_TOTAL))); for (int i=0; i<getDurationYears(); i++) { // print Depreciation-Years int index = i + INDEX_TOTAL + 1; costs.add(new Double(getValue(totalFacts, index))); } return costs; }*/ } Index: Calculator.java =================================================================== RCS file: /cvsroot/tcotool/TCO-Tool/src/org/tcotool/tools/Calculator.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Calculator.java 15 May 2008 20:27:35 -0000 1.8 --- Calculator.java 15 Jun 2008 18:39:14 -0000 1.9 *************** *** 24,32 **** import org.tcotool.application.LauncherView; import org.tcotool.model.*; - import org.tcotool.standard.report.ReportTool; - import ch.softenvironment.jomm.mvc.model.DbCodeType; import ch.softenvironment.jomm.mvc.model.DbObject; - import ch.softenvironment.math.FinancialUtils; import ch.softenvironment.util.AmountFormat; import ch.softenvironment.util.DeveloperException; --- 24,29 ---- [...1103 lines suppressed...] - * Return cost-list over given object. - * @param object null for all services - * @return [FactCosts_Total; Depreciation_Year1;.. TCO_YearN] - */ - public List getDepreciationCostBlock(TcoObject object, final String type) { - TcoObject costObject = (object == null ? rootObject : object); - List costs = new ArrayList(); - - List totalFacts = getTotalCosts(costObject, type); - costs.add(new Double(getValue(totalFacts, INDEX_TOTAL))); - for (int i=0; i<getDurationYears(); i++) { - // print Depreciation-Years - int index = i + INDEX_TOTAL + 1; - costs.add(new Double(getValue(totalFacts, index))); - } - return costs; - } } \ No newline at end of file --- 763,765 ---- |