Completed
Push — master ( b96e37...44ada8 )
by Vladimir
02:23
created

AnnuityPaymentScheduleCalculator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 3
crap 1
1
<?php
2
/**
3
 * @author: Vova Lando <[email protected]>
4
 * @package: LoanPaymentsCalculator
5
 * @subpackage:
6
 * @created: 06/09/2017 13:30
7
 */
8
9
namespace cog\LoanPaymentsCalculator\PaymentSchedule;
10
11
12
use cog\LoanPaymentsCalculator\Payment\Payment;
13
use cog\LoanPaymentsCalculator\Period\Period;
14
use cog\LoanPaymentsCalculator\Schedule\Schedule;
15
16
17
class AnnuityPaymentScheduleCalculator implements PaymentScheduleCalculator
18
{
19
    /**
20
     * @var Schedule[]
21
     */
22
    private $schedulePeriods;
23
24
    /**
25
     * @var float
26
     */
27
    private $principalAmount;
28
29
    /**
30
     * @var float
31
     */
32
    private $dailyInterestRate;
33
34
    /**
35
     * AnnuityPaymentScheduleCalculator constructor.
36
     * @param Period[] $schedulePeriods
37
     * @param float    $principalAmount
38
     * @param float    $dailyInterestRate
39
     */
40 2
    public function __construct($schedulePeriods, $principalAmount, $dailyInterestRate)
41
    {
42 2
        $this->schedulePeriods = $schedulePeriods;
0 ignored issues
show
Documentation Bug introduced by
It seems like $schedulePeriods of type array<integer,object<cog...culator\Period\Period>> is incompatible with the declared type array<integer,object<cog...tor\Schedule\Schedule>> of property $schedulePeriods.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
43 2
        $this->principalAmount = $principalAmount;
44 2
        $this->dailyInterestRate = $dailyInterestRate;
45 2
    }
46
47
    /**
48
     * @inheritdoc
49
     */
50 2
    public function calculateSchedule()
51
    {
52
        /**
53
         * @var Payment[] $payments
54
         */
55 2
        $payments = [];
56 2
        $numberOfPeriods = count($this->schedulePeriods);
57 2
        $periodInterestRate = $this->calculateInterestPerPeriod();
58 2
        $paymentAmount = $this->calculateAnnuityPaymentAmount($periodInterestRate);
59 2
        $totalPrincipalToPay = $this->principalAmount;
60
61 2
        for ($i=0; $i<$numberOfPeriods; $i++) {
62 2
            $payment = new Payment($this->schedulePeriods[$i]);
0 ignored issues
show
Documentation introduced by
$this->schedulePeriods[$i] is of type object<cog\LoanPaymentsC...ator\Schedule\Schedule>, but the function expects a object<cog\LoanPaymentsCalculator\Period\Period>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
63
            // Payment interest
64 2
            $paymentInterest = $totalPrincipalToPay * $periodInterestRate;
65 2
            $payment->setInterest($paymentInterest);
66
            // Payment principal
67 2
            $paymentPrincipal = $i == $numberOfPeriods-1 ? $totalPrincipalToPay : $paymentAmount - $paymentInterest;
68 2
            $payment->setPrincipal($paymentPrincipal);
69
            // Payment totals
70 2
            $totalPrincipalToPay-=$paymentPrincipal;
71 2
            $payment->setPrincipalBalanceLeft($totalPrincipalToPay);
72
73 2
            $payments[] = $payment;
74
        }
75
76 2
        return $payments;
77
    }
78
79
    /**
80
     * @param $interestPerPeriod
0 ignored issues
show
Coding Style Documentation introduced by
Missing parameter name
Loading history...
81
     * @return float|int
82
     */
83 2
    private function calculateAnnuityPaymentAmount($interestPerPeriod)
84
    {
85
        // Payment = InterestPerPeriod x TotalPrincipal / 1 - ( 1 + InterestPerPeriod)^(-numberOfPeriods)
86 2
        return (($interestPerPeriod) *  $this->principalAmount) / (1 - pow(1 + ($interestPerPeriod), -count($this->schedulePeriods)));
87
    }
88
89
    /**
90
     * @return float
91
     */
92 2
    private function calculateInterestPerPeriod()
93
    {
94 2
        $startDate = $this->schedulePeriods[0]->startDate;
0 ignored issues
show
Bug introduced by
The property startDate does not seem to exist. Did you mean scheduleStartDate?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
95 2
        $endDate = $this->schedulePeriods[count($this->schedulePeriods)-1]->endDate;
0 ignored issues
show
Bug introduced by
The property endDate does not seem to exist in cog\LoanPaymentsCalculator\Schedule\Schedule.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
96 2
        $daysDiff = $startDate->diff($endDate)->days;
97
98 2
        return $this->dailyInterestRate * $daysDiff/count($this->schedulePeriods);
99
    }
100
}