Failed Conditions
Push — master ( ea97af...216db0 )
by
unknown
15:51 queued 07:40
created

AccruedInterest::periodic()   A

Complexity

Conditions 5
Paths 20

Size

Total Lines 42
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 5.0144

Importance

Changes 0
Metric Value
eloc 24
c 0
b 0
f 0
dl 0
loc 42
ccs 22
cts 24
cp 0.9167
rs 9.2248
cc 5
nc 20
nop 8
crap 5.0144

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Calculation\Financial\Securities;
4
5
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\YearFrac;
6
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
7
use PhpOffice\PhpSpreadsheet\Calculation\Financial\Constants as FinancialConstants;
8
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
9
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
10
11
class AccruedInterest
12
{
13
    public const ACCRINT_CALCMODE_ISSUE_TO_SETTLEMENT = true;
14
15
    public const ACCRINT_CALCMODE_FIRST_INTEREST_TO_SETTLEMENT = false;
16
17
    /**
18
     * ACCRINT.
19
     *
20
     * Returns the accrued interest for a security that pays periodic interest.
21
     *
22
     * Excel Function:
23
     *        ACCRINT(issue,firstinterest,settlement,rate,par,frequency[,basis][,calc_method])
24
     *
25
     * @param mixed $issue the security's issue date
26
     * @param mixed $firstInterest the security's first interest date
27
     * @param mixed $settlement The security's settlement date.
28
     *                              The security settlement date is the date after the issue date
29
     *                                  when the security is traded to the buyer.
30
     * @param mixed $rate The security's annual coupon rate
31
     * @param mixed $parValue The security's par value.
32
     *                            If you omit par, ACCRINT uses $1,000.
33
     * @param mixed $frequency The number of coupon payments per year.
34
     *                             Valid frequency values are:
35
     *                               1    Annual
36
     *                               2    Semi-Annual
37
     *                               4    Quarterly
38
     * @param mixed $basis The type of day count to use.
39
     *                         0 or omitted    US (NASD) 30/360
40
     *                         1               Actual/actual
41
     *                         2               Actual/360
42
     *                         3               Actual/365
43
     *                         4               European 30/360
44
     * @param mixed $calcMethod Unused by PhpSpreadsheet, and apparently by Excel (https://exceljet.net/functions/accrint-function)
45
     *
46
     * @return float|string Result, or a string containing an error
47
     */
48 22
    public static function periodic(
49
        mixed $issue,
50
        mixed $firstInterest,
51
        mixed $settlement,
52
        mixed $rate,
53
        mixed $parValue = 1000,
54
        mixed $frequency = FinancialConstants::FREQUENCY_ANNUAL,
55
        mixed $basis = FinancialConstants::BASIS_DAYS_PER_YEAR_NASD,
56
        mixed $calcMethod = self::ACCRINT_CALCMODE_ISSUE_TO_SETTLEMENT
57
    ) {
58 22
        $issue = Functions::flattenSingleValue($issue);
59 22
        $firstInterest = Functions::flattenSingleValue($firstInterest);
60 22
        $settlement = Functions::flattenSingleValue($settlement);
61 22
        $rate = Functions::flattenSingleValue($rate);
62 22
        $parValue = ($parValue === null) ? 1000 : Functions::flattenSingleValue($parValue);
63 22
        $frequency = Functions::flattenSingleValue($frequency) ?? FinancialConstants::FREQUENCY_ANNUAL;
64 22
        $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD;
65
66
        try {
67 22
            $issue = SecurityValidations::validateIssueDate($issue);
68 21
            $settlement = SecurityValidations::validateSettlementDate($settlement);
69 21
            SecurityValidations::validateSecurityPeriod($issue, $settlement);
70 21
            $rate = SecurityValidations::validateRate($rate);
71 17
            $parValue = SecurityValidations::validateParValue($parValue);
72 14
            SecurityValidations::validateFrequency($frequency);
73 13
            $basis = SecurityValidations::validateBasis($basis);
74 11
        } catch (Exception $e) {
75 11
            return $e->getMessage();
76
        }
77
78 11
        $daysBetweenIssueAndSettlement = Functions::scalar(YearFrac::fraction($issue, $settlement, $basis));
79 11
        if (!is_numeric($daysBetweenIssueAndSettlement)) {
80
            //    return date error
81
            return StringHelper::convertToString($daysBetweenIssueAndSettlement);
82
        }
83 11
        $daysBetweenFirstInterestAndSettlement = Functions::scalar(YearFrac::fraction($firstInterest, $settlement, $basis));
84 11
        if (!is_numeric($daysBetweenFirstInterestAndSettlement)) {
85
            //    return date error
86
            return StringHelper::convertToString($daysBetweenFirstInterestAndSettlement);
87
        }
88
89 11
        return $parValue * $rate * $daysBetweenIssueAndSettlement;
90
    }
91
92
    /**
93
     * ACCRINTM.
94
     *
95
     * Returns the accrued interest for a security that pays interest at maturity.
96
     *
97
     * Excel Function:
98
     *        ACCRINTM(issue,settlement,rate[,par[,basis]])
99
     *
100
     * @param mixed $issue The security's issue date
101
     * @param mixed $settlement The security's settlement (or maturity) date
102
     * @param mixed $rate The security's annual coupon rate
103
     * @param mixed $parValue The security's par value.
104
     *                            If you omit parValue, ACCRINT uses $1,000.
105
     * @param mixed $basis The type of day count to use.
106
     *                         0 or omitted    US (NASD) 30/360
107
     *                         1               Actual/actual
108
     *                         2               Actual/360
109
     *                         3               Actual/365
110
     *                         4               European 30/360
111
     *
112
     * @return float|string Result, or a string containing an error
113
     */
114 14
    public static function atMaturity(
115
        mixed $issue,
116
        mixed $settlement,
117
        mixed $rate,
118
        mixed $parValue = 1000,
119
        mixed $basis = FinancialConstants::BASIS_DAYS_PER_YEAR_NASD
120
    ) {
121 14
        $issue = Functions::flattenSingleValue($issue);
122 14
        $settlement = Functions::flattenSingleValue($settlement);
123 14
        $rate = Functions::flattenSingleValue($rate);
124 14
        $parValue = ($parValue === null) ? 1000 : Functions::flattenSingleValue($parValue);
125 14
        $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD;
126
127
        try {
128 14
            $issue = SecurityValidations::validateIssueDate($issue);
129 13
            $settlement = SecurityValidations::validateSettlementDate($settlement);
130 13
            SecurityValidations::validateSecurityPeriod($issue, $settlement);
131 13
            $rate = SecurityValidations::validateRate($rate);
132 10
            $parValue = SecurityValidations::validateParValue($parValue);
133 8
            $basis = SecurityValidations::validateBasis($basis);
134 8
        } catch (Exception $e) {
135 8
            return $e->getMessage();
136
        }
137
138 6
        $daysBetweenIssueAndSettlement = Functions::scalar(YearFrac::fraction($issue, $settlement, $basis));
139 6
        if (!is_numeric($daysBetweenIssueAndSettlement)) {
140
            //    return date error
141
            return StringHelper::convertToString($daysBetweenIssueAndSettlement);
142
        }
143
144 6
        return $parValue * $rate * $daysBetweenIssueAndSettlement;
145
    }
146
}
147