Completed
Push — master ( 89d00a...0b5d6e )
by Shawn
02:32
created

RenewTraining::timeToRenew()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 10
nc 3
nop 1
1
<?php
2
3
namespace SET\Console\Commands;
4
5
use Carbon\Carbon;
6
use Illuminate\Console\Command;
7
use Illuminate\Database\Eloquent\Collection;
8
use Illuminate\Support\Facades\Event;
9
use SET\Events\TrainingAssigned;
10
use SET\TrainingUser;
11
12
class RenewTraining extends Command
13
{
14
    /**
15
     * The number of days to renew a training before it expires.
16
     *
17
     * @var int
18
     */
19
    protected $offset = 14;
20
21
22
    /**
23
     * List of all renewed notes.
24
     *
25
     * @var Collection
26
     */
27
    protected $trainingAdminRecord;
28
29
    /**
30
     * The name and signature of the console command.
31
     *
32
     * @var string
33
     */
34
    protected $signature = 'training:renew';
35
36
    /**
37
     * The console command description.
38
     *
39
     * @var string
40
     */
41
    protected $description = 'Renews training before it expires.';
42
43
    /**
44
     * Create a new command instance.
45
     */
46
    public function __construct()
47
    {
48
        parent::__construct();
49
        $this->trainingAdminRecord = new Collection();
50
    }
51
52
    /**
53
     * Execute the console command.
54
     *
55
     * @return mixed
56
     */
57
    public function handle()
58
    {
59
        $trainingUsers = TrainingUser::with('user', 'training')
60
            ->whereNotNull('completed_date')
61
            ->where('due_date', '<', Carbon::today())
62
            ->activeUsers()
63
            ->orderBy('completed_date', 'desc')
64
            ->get()
65
            ->unique('user_id', 'training_id');
66
67
        foreach ($trainingUsers as $trainingUser) {
68
            if (!$this->renewedAlready($trainingUser) && $this->timeToRenew($trainingUser)) {
69
                $this->processRenewal($trainingUser);
70
            }
71
        }
72
73
        return $this;
74
    }
75
76
    public function getTrainingAdminRecord()
77
    {
78
        return $this->trainingAdminRecord->sortBy('userFullName');
79
    }
80
81
    /**
82
     * Check if training note has been renewed already.
83
     *
84
     * @param $trainingUser
85
     *
86
     * @return bool
87
     */
88
    private function renewedAlready($trainingUser)
89
    {
90
        $trainingRecord = TrainingUser::where('training_id', $trainingUser->training_id)
91
            ->where('user_id', $trainingUser->user_id)
92
            ->where('due_date', '>', Carbon::today())
93
            ->get();
94
95
        return !$trainingRecord->isEmpty();
96
    }
97
98
    /**
99
     * Check if the training is past the renews_in value.
100
     *
101
     * @param $trainingUser
102
     *
103
     * @return bool
104
     */
105
    private function timeToRenew($trainingUser)
106
    {
107
        if ($trainingUser->training->renews_in == 0) {
108
            return false;
109
        }
110
111
        $today = Carbon::today();
112
113
        $renewalDate = Carbon::createFromFormat('Y-m-d', $trainingUser->completed_date)
114
            ->addDays($trainingUser->training->renews_in)
115
            ->subDays($this->offset);
116
117
        if ($renewalDate >= $today) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !($renewalDate >= $today);.
Loading history...
118
            return false;
119
        }
120
121
        return true;
122
    }
123
124
    /**
125
     * Generate a new Training note that will be due $this->offset days from now.
126
     *
127
     * @param $trainingUser
128
     */
129
    private function processRenewal($trainingUser)
130
    {
131
        $dueDate = Carbon::createFromFormat('Y-m-d', $trainingUser->completed_date)
132
            ->addDays($trainingUser->training->renews_in);
133
134
        $assignedTraining = $this->createRecord($trainingUser, $dueDate);
135
136
        //Email user of new training is due
137
        Event::fire(new TrainingAssigned($assignedTraining));
138
139
        //
140
        $this->trainingAdminRecord->push([
141
            'name'     => $assignedTraining->user->userFullName,
1 ignored issue
show
Documentation introduced by
The property user does not exist on object<SET\TrainingUser>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
142
            'training' => $assignedTraining->training->name,
1 ignored issue
show
Documentation introduced by
The property training does not exist on object<SET\TrainingUser>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
143
            'due_date' => $dueDate->toDateString(),
144
        ]);
145
    }
146
147
    /**
148
     * @param $trainingUser
149
     * @param Carbon $dueDate
150
     *
151
     * @return TrainingUser
152
     */
153
    private function createRecord($trainingUser, $dueDate)
154
    {
155
        $newNote = TrainingUser::create([
156
            'user_id'        => $trainingUser->user_id,
157
            'author_id'      => 1,
158
            'training_id'    => $trainingUser->training_id,
159
            'due_date'       => $dueDate->toDateString(),
160
            'completed_date' => null
161
        ]);
162
163
        return $newNote;
164
    }
165
}
166