Test Failed
Push — master ( 10ac63...d71b5a )
by noitran
08:44
created

RecalculateInterestService::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 4
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace FinCore\Domain\Invoice\Service\InterestCalculation;
6
7
use Agreements\Entity\LoanItem;
0 ignored issues
show
Bug introduced by
The type Agreements\Entity\LoanItem was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Applications\Entity\Application;
0 ignored issues
show
Bug introduced by
The type Applications\Entity\Application was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Applications\Enum\ApplicationTypeEnum;
0 ignored issues
show
Bug introduced by
The type Applications\Enum\ApplicationTypeEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Common\Model\TimePeriod;
0 ignored issues
show
Bug introduced by
The type Common\Model\TimePeriod was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Common\Service\MoneyMathematics\MoneyMath;
0 ignored issues
show
Bug introduced by
The type Common\Service\MoneyMathematics\MoneyMath was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Common\Tool\NumberTool;
0 ignored issues
show
Bug introduced by
The type Common\Tool\NumberTool was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use FinCore\Domain\Calculator\Arithmetic\Service\ArithmeticResolver\ArithmeticResolverInterface;
0 ignored issues
show
Bug introduced by
The type FinCore\Domain\Calculato...hmeticResolverInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use FinCore\Domain\Calculator\Payload\ValueObject\CalculatorConstructorPayload;
0 ignored issues
show
Bug introduced by
The type FinCore\Domain\Calculato...latorConstructorPayload was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use FinCore\Domain\FinanceService\ValueObject\FinanceServiceModel;
0 ignored issues
show
Bug introduced by
The type FinCore\Domain\FinanceSe...ect\FinanceServiceModel was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use FinCore\Domain\Invoice\Service\InterestCalculationChecker\InterestCalculationCheckerServiceInterface;
0 ignored issues
show
Bug introduced by
The type FinCore\Domain\Invoice\S...CheckerServiceInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use FinCore\Domain\Loan\ValueObject\LoanAmountModel;
0 ignored issues
show
Bug introduced by
The type FinCore\Domain\Loan\ValueObject\LoanAmountModel was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use FinCore\Domain\LoanItem\Service\CalculateLoanItem\CalculateLoanItemServiceInterface;
0 ignored issues
show
Bug introduced by
The type FinCore\Domain\LoanItem\...oanItemServiceInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use Invoices\Entity\Invoice;
0 ignored issues
show
Bug introduced by
The type Invoices\Entity\Invoice was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use SystemSettings\Interfaces\SettingsReaderInterface;
0 ignored issues
show
Bug introduced by
The type SystemSettings\Interfaces\SettingsReaderInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
22
class RecalculateInterestService implements RecalculateInterestServiceInterface
0 ignored issues
show
Bug introduced by
The type FinCore\Domain\Invoice\S...nterestServiceInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
{
24
    /**
25
     * @var ArithmeticResolverInterface
26
     */
27
    private $arithmeticResolver;
28
29
    /**
30
     * @var SettingsReaderInterface
31
     */
32
    private $settingsReader;
33
34
    /**
35
     * @var InterestCalculationCheckerServiceInterface
36
     */
37
    private $checkerService;
38
39
    /**
40
     * @var CalculateLoanItemServiceInterface
41
     */
42
    private $loanItemService;
43
44
    public function __construct(
45
        ArithmeticResolverInterface $arithmeticResolver,
46
        SettingsReaderInterface $settingsReader,
47
        InterestCalculationCheckerServiceInterface $checkerService,
48
        CalculateLoanItemServiceInterface $loanItemService
49
    ) {
50
        $this->arithmeticResolver = $arithmeticResolver;
51
        $this->settingsReader = $settingsReader;
52
        $this->checkerService = $checkerService;
53
        $this->loanItemService = $loanItemService;
54
    }
55
56
    /**
57
     * @param Invoice $invoice
58
     * @param $overdueDays
59
     *
60
     * @throws \Common\Service\MoneyMathematics\MathOperationException
61
     *
62
     * @return bool
63
     */
64
    public function recalculate(Invoice $invoice, $overdueDays): bool
65
    {
66
        /** @var Invoice $invoice */
67
        $loan = $invoice->getLoan();
68
69
        if (! $this->checkerService->isCalculationAllowed($invoice, $overdueDays)) {
70
            return false;
71
        }
72
        $disableLoanZeroInterestSetting = $this
73
            ->settingsReader
74
            ->get('financial_services.loan_zero_interest_disable_after_duedays');
75
76
        $disableLoanZeroInterest = ($disableLoanZeroInterestSetting > 0 && $overdueDays >= $disableLoanZeroInterestSetting + 1);
77
78
        if (! $disableLoanZeroInterest) {
79
            return false;
80
        }
81
82
        $finVersionNum = $loan->getFinancialServiceVersion()->getVersion();
83
        $loanPaidPrincipal = new MoneyMath($invoice->getLoan()->getPaidPrincipalAmount());
84
85
        $loanAmountModel = new LoanAmountModel($loan);
86
87
        /** @var LoanItem $loanItem */
88
        foreach ($loan->getLoanItems() as $loanItem) {
89
            if ($loanPaidPrincipal->isGreaterThenOrEqualTo($loanItem->getPrincipalAmount())) {
90
                $loanPaidPrincipal->sub($loanItem->getPrincipalAmount());
91
92
                continue;
93
            }
94
95
            /** @var Application $application */
96
            $application = $loanItem->getApplication();
97
98
            $currentLoanItemPrincipal = new MoneyMath($loanItem->getPrincipalAmount());
99
100
            if ($this->checkerService->isPrincipalDecreaseAllowed($loanPaidPrincipal)) {
101
                $currentLoanItemPrincipal->sub($loanPaidPrincipal->getResult());
102
                $loanPaidPrincipal->zero();
103
            }
104
105
            $applicationTypeEnum = ($application->isItemTypeAdditional()
106
                ? ApplicationTypeEnum::ADDITIONAL()
107
                : ApplicationTypeEnum::MAIN());
108
109
            // TODO TD lesser evil
110
            $payload = new CalculatorConstructorPayload(
111
                new FinanceServiceModel($application->getServiceTypeEnum(), $finVersionNum),
112
                $currentLoanItemPrincipal->getResult(),
113
                $application->getAppDate(),
114
                $application->getTerm(), // TODO KZ + dueDays
115
                // $term, // TODO KZ + dueDays
116
                /*
117
                 * PL 30
118
                 * KZ 30 +1 (daily 30)
119
                 */
120
                $applicationTypeEnum
121
            );
122
123
            $payload
124
                ->setIsDiscountEnabled(false)
125
                ->setUseRecalculation(true)
126
            ;
127
128
            $calcResult = $this->arithmeticResolver->calculate($payload);
129
130
            // TODO TD lesser evil
131
            if (($invoice->getDueDays() < 0) && 'kz' == getenv('COUNTRY_ENV')) {
132
                $days = (int) NumberTool::add($application->getTerm()->getValue(), abs($invoice->getDueDays()));
133
                if ($days > 60) {
134
                    $days = 60;
135
                }
136
137
                $term = TimePeriod::fromDays($days);
138
139
                // TODO TD lesser evil
140
                $fakePayload = new CalculatorConstructorPayload(
141
                    new FinanceServiceModel($application->getServiceTypeEnum(), $finVersionNum),
142
                    $currentUnpaidLoanItemPrincipal->getResult(),
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $currentUnpaidLoanItemPrincipal seems to be never defined.
Loading history...
143
                    $application->getAppDate(),
144
                    $term, // TODO KZ + dueDays
145
                    // $application->getTerm(), // TODO KZ + dueDays
146
                    /*
147
                     * PL 30
148
                     * KZ 30 +1 (daily 30)
149
                     */
150
                    $applicationTypeEnum
151
                );
152
153
                $fakePayload
154
                    ->setIsDiscountEnabled(false)
155
                    ->setUseRecalculation(true)
156
                ;
157
158
                $fakeCalcResult = $this->arithmeticResolver->calculate($fakePayload);
159
160
                $calcResult->setInterestAmount($fakeCalcResult->getInterestAmount());
161
                $calcResult->setInterestRate($fakeCalcResult->getInterestRate());
162
            }
163
164
            $result = $this->loanItemService->calculate($loanItem, $calcResult, $loanAmountModel);
165
166
            if (getenv('COUNTRY_ENV')) {
167
                $maxOverall = NumberTool::percent($loan->getPrincipalAmount()->getAmount(), 100);
168
                $overallAmount = NumberTool::addAll(
169
                    $result->getServiceFeeAmount()->getAmount(),
170
                    $result->getInterestAmount()->getAmount(),
171
                    $loan->getRemindersAmount()->getAmount(),
172
                    $loan->getFinesAmount()->getAmount()
173
                );
174
175
                if (NumberTool::gt($overallAmount, $maxOverall)) {
176
                    return false;
177
                }
178
            }
179
180
            $loanItem
181
                ->setServiceFeeAmount($result->getServiceFeeAmount())
182
                ->setInterestAmount($result->getInterestAmount())
183
                ->setTotalRepayableAmount($result->getTotalRepayableAmount())
184
                ->setPeriodEndRepayableAmount($result->getTotalRepayableAmount())
185
            ;
186
        }
187
188
        $invoice->setHasRecalculateInterest(true);
189
190
        $loan->doUpdateAmountsFromLoanItems();
191
192
        return true;
193
    }
194
}
195