(real) fix for bug #44691. Modified Pmt.java to allow for 3 arguments. Added TestPm...
[poi.git] / src / scratchpad / src / org / apache / poi / hssf / record / formula / functions / Pmt.java
blob58628053c0ba19645d907d0c3cddd5bbda20263a
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 package org.apache.poi.hssf.record.formula.functions;
19 import org.apache.poi.hssf.record.formula.eval.BoolEval;
20 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
21 import org.apache.poi.hssf.record.formula.eval.Eval;
22 import org.apache.poi.hssf.record.formula.eval.EvaluationException;
23 import org.apache.poi.hssf.record.formula.eval.NumberEval;
24 import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
25 import org.apache.poi.hssf.record.formula.eval.ValueEval;
27 /**
28 * Implementation for the PMT() Excel function.<p/>
30 * <b>Syntax:</b><br/>
31 * <b>PMT</b>(<b>rate</b>, <b>nper</b>, <b>pv</b>, fv, type)<p/>
33 * Returns the constant repayment amount required for a loan assuming a constant interest rate.<p/>
35 * <b>rate</b> the loan interest rate.<br/>
36 * <b>nper</b> the number of loan repayments.<br/>
37 * <b>pv</b> the present value of the future payments (or principle).<br/>
38 * <b>fv</b> the future value (default zero) surplus cash at the end of the loan lifetime.<br/>
39 * <b>type</b> whether payments are due at the beginning(1) or end(0 - default) of each payment period.<br/>
42 public final class Pmt extends FinanceFunction {
44 public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
46 if(args.length < 3 || args.length > 5) {
47 return ErrorEval.VALUE_INVALID;
50 try {
51 // evaluate first three (always present) args
52 double rate = evalArg(args[0], srcRow, srcCol);
53 double nper = evalArg(args[1], srcRow, srcCol);
54 double pv = evalArg(args[2], srcRow, srcCol);
55 double fv = 0;
56 boolean arePaymentsAtPeriodBeginning = false;
58 switch (args.length) {
59 case 5:
60 ValueEval ve = singleOperandNumericAsBoolean(args[4], srcRow, srcCol);
61 if (ve instanceof ErrorEval) {
62 return ve;
64 arePaymentsAtPeriodBeginning = ((BoolEval) ve).getBooleanValue();
65 case 4:
66 fv = evalArg(args[3], srcRow, srcCol);
68 double d = FinanceLib.pmt(rate, nper, pv, fv, arePaymentsAtPeriodBeginning);
69 if (Double.isNaN(d)) {
70 return (ValueEval) ErrorEval.VALUE_INVALID;
72 if (Double.isInfinite(d)) {
73 return (ValueEval) ErrorEval.NUM_ERROR;
75 return new NumberEval(d);
76 } catch (EvaluationException e) {
77 return e.getErrorEval();
81 private double evalArg(Eval arg, int srcRow, short srcCol) throws EvaluationException {
82 ValueEval ve = singleOperandEvaluate(arg, srcRow, srcCol);
83 if(ve instanceof ErrorEval) {
84 throw new EvaluationException((ErrorEval) ve);
86 if (ve instanceof NumericValueEval) {
87 return ((NumericValueEval) ve).getNumberValue();
89 throw new EvaluationException(ErrorEval.VALUE_INVALID);