Passed
Push — master ( 43186b...d45fb7 )
by Gabriel
14:32
created

CalculateNextCharge   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 49
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 21
c 1
b 0
f 1
dl 0
loc 49
rs 10
wmc 9

3 Methods

Rating   Name   Duplication   Size   Complexity  
A for() 0 6 1
A determineStartDate() 0 7 3
A nextBillingDate() 0 17 5
1
<?php
2
3
namespace ByTIC\Payments\Actions\Subscriptions\Charges;
4
5
use ByTIC\Payments\Models\Subscriptions\Subscription;
6
use ByTIC\Payments\Subscriptions\Billing\BillingPeriod;
7
use Nip\Utility\Date;
8
9
/**
10
 * Class CalculateNextCharge
11
 * @package ByTIC\Payments\Actions\Subscriptions\Charges
12
 */
13
class CalculateNextCharge
14
{
15
    /**
16
     * @param Subscription $subscription
17
     */
18
    public static function for($subscription)
19
    {
20
        $subscription->charge_at = static::nextBillingDate(
21
            static::determineStartDate($subscription),
22
            $subscription->billing_period,
23
            $subscription->billing_interval
24
        );
25
    }
26
27
    /**
28
     * @param Subscription $subscription
29
     * @return \DateTime
30
     */
31
    protected static function determineStartDate(Subscription $subscription): \DateTime
32
    {
33
        $chargeAt = $subscription->charge_at;
34
        if ($chargeAt instanceof \DateTime && $chargeAt->year > 0) {
35
            return $chargeAt;
36
        }
37
        return $subscription->start_at;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $subscription->start_at could return the type string which is incompatible with the type-hinted return DateTime. Consider adding an additional type-check to rule them out.
Loading history...
38
    }
39
40
    /**
41
     * @param \DateTime $startDate
42
     * @param $period
43
     * @param $interval
44
     */
45
    protected static function nextBillingDate(\DateTime $startDate, $period, $interval)
46
    {
47
        $startDate = Date::instance($startDate);
48
        switch ($period) {
49
            case BillingPeriod::DAILY:
50
                return $startDate->addDays($interval);
51
52
            case BillingPeriod::WEEKLY:
53
                return $startDate->addWeeks($interval);
54
55
            case BillingPeriod::MONTHLY:
56
                return $startDate->addMonths($interval);
57
58
            case BillingPeriod::YEARLY:
59
                return $startDate->addYears($interval);
60
        }
61
        throw new \InvalidArgumentException("Invalid period [{$period}] provided.");
62
    }
63
}