Completed
Push — master ( fc4ead...c5d222 )
by Andrii
05:51
created

Leasing::isFirstMonthAfterLeasingPassed()   B

Complexity

Conditions 8
Paths 6

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
cc 8
eloc 11
nc 6
nop 1
dl 0
loc 20
ccs 0
cts 12
cp 0
crap 72
rs 8.4444
c 0
b 0
f 0
1
<?php
2
/**
3
 * PHP Billing Library
4
 *
5
 * @link      https://github.com/hiqdev/php-billing
6
 * @package   php-billing
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2017-2018, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\php\billing\charge\modifiers;
12
13
use hiqdev\php\billing\action\ActionInterface;
14
use hiqdev\php\billing\charge\Charge;
15
use hiqdev\php\billing\charge\ChargeInterface;
16
use hiqdev\php\billing\charge\modifiers\event\LeasingWasFinished;
17
use hiqdev\php\billing\formula\FormulaSemanticsError;
18
use hiqdev\php\billing\price\SinglePrice;
19
use hiqdev\php\billing\target\Target;
20
use hiqdev\php\billing\type\Type;
21
use hiqdev\php\units\Quantity;
22
use Money\Money;
23
24
/**
25
 * Leasing.
26
 *
27
 * @author Andrii Vasyliev <[email protected]>
28
 */
29
class Leasing extends Modifier
30
{
31
    public function buildPrice(Money $sum)
32
    {
33
        $type = $this->getType();
34
        $target = $this->getTarget();
35
        $prepaid = Quantity::create('items', 0);
36
37
        return new SinglePrice(null, $type, $target, null, $prepaid, $sum);
38
    }
39
40
    public function getType()
41
    {
42
        return new Type(Type::ANY, 'discount,leasing');
43
    }
44
45
    public function getTarget()
46
    {
47
        return new Target(Target::ANY, Target::ANY);
48
    }
49
50 1
    public function till($dummy)
0 ignored issues
show
Unused Code introduced by
The parameter $dummy is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

50
    public function till(/** @scrutinizer ignore-unused */ $dummy)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
51
    {
52 1
        throw new FormulaSemanticsError('till can not be defined for leasing');
53
    }
54
55 1
    public function modifyCharge(?ChargeInterface $charge, ActionInterface $action): array
56
    {
57 1
        if ($charge === null) {
58
            throw new \Exception('unexpected null charge in Leasing, to be implemented');
59
        }
60
61 1
        $this->ensureIsValid();
62
63 1
        $reason = $this->getReason();
64 1
        if ($reason) {
0 ignored issues
show
introduced by
$reason is of type hiqdev\php\billing\charge\modifiers\addons\Reason, thus it always evaluated to true.
Loading history...
65
            $charge->setComment($reason->getValue());
66
        }
67
68 1
        $month = $action->getTime()->modify('first day of this month midnight');
69 1
        if (!$this->checkPeriod($month)) {
70
            if ($this->isFirstMonthAfterLeasingPassed($month)) {
71
                return [$this->createLeasingFinishingCharge($charge, $month)];
72
            }
73
74
            return [];
75
        }
76
77 1
        return [$charge];
78
    }
79
80 1
    protected function ensureIsValid(): void
81
    {
82 1
        $since = $this->getSince();
83 1
        if ($since === null) {
84
            throw new FormulaSemanticsError('no since given for leasing');
85
        }
86
87 1
        $term = $this->getTerm();
88 1
        if ($term === null) {
89
            throw new FormulaSemanticsError('no term given for leasing');
90
        }
91 1
    }
92
93
    private function isFirstMonthAfterLeasingPassed(\DateTimeImmutable $time): bool
94
    {
95
        $since = $this->getSince();
96
        if ($since && $since->getValue() > $time) {
97
            return false;
98
        }
99
100
        $till = $this->getTill();
101
        if ($till && $till->getValue() <= $time) {
102
            if ($till->getValue()->diff($time)->format('%a') === '0') {
103
                return true;
104
            }
105
        }
106
107
        $term = $this->getTerm();
108
        if ($term && $term->addTo($since->getValue())->diff($time)->format('%a') === '0') {
109
            return true;
110
        }
111
112
        return false;
113
    }
114
115
    private function createLeasingFinishingCharge(ChargeInterface $charge, \DateTimeImmutable $month): ChargeInterface
116
    {
117
        $result = new Charge(
118
            null,
119
            $charge->getType(),
120
            $charge->getTarget(),
121
            $charge->getAction(),
122
            $charge->getPrice(),
123
            $charge->getUsage(),
124
            new Money(0, $charge->getSum()->getCurrency())
125
        );
126
        $result->recordThat(LeasingWasFinished::forPriceInMonth($charge->getPrice(), $month));
127
        if ($charge->getComment()) {
128
            $result->setComment($charge->getComment());
129
        }
130
131
        return $result;
132
    }
133
}
134