Completed
Push — master ( 3c7025...906c6b )
by Sheela
01:51
created

DutyUsers::setLastWorkedDate()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 0
cts 17
cp 0
rs 9.488
c 0
b 0
f 0
cc 3
nc 2
nop 0
crap 12
1
<?php
2
3
namespace SET\Handlers\Duty;
4
5
use Carbon\Carbon;
6
use Illuminate\Database\Eloquent\Collection;
7
use Illuminate\Support\Facades\Gate;
8
use Illuminate\Support\Facades\DB;
9
use SET\Duty;
10
use SET\DutySwap;
11
12
class DutyUsers extends DutyHelper
13
{
14
    public function __construct(Duty $duty)
15
    {
16
        parent::__construct($duty);
17
    }
18
19
    /**
20
     * Generate a collection to be used for our view 'duty.show'.
21
     *
22
     * @return Collection
23
     */
24
    public function htmlOutput()
25
    {
26
        $newCollection = new Collection();
27
28
        foreach ($this->list as $entry) {
29
            $rowvalue = $entry['user']->userFullName;
30
31
            if (Gate::allows('view')) {
32
                $rowvalue = "<a href='".url('user', $entry['user']->id)."'>".$entry['user']->userFullName.'</a>';
33
            }
34
35
            $newCollection->push([
36
                'row'  => $rowvalue,
37
                'id'   => $entry['user']->id,
38
                'date' => $entry['date'],
39
            ]);
40
        }
41
        
42
        return $newCollection;
43
    }
44
45
    /**
46
     * Generate a collection to be used for emails. View is either emails.duty_future or emails.duty_today.
47
     *
48
     * @return \Illuminate\Support\Collection
49
     */
50
    public function emailOutput()
51
    {
52
        $collection = $this->list->map(function ($value) {
53
            return [
54
                'users' => new Collection([$value['user']]),
55
                'date'  => $value['date'],
56
            ];
57
        });
58
59
        return $collection;
60
    }
61
62
    /**
63
     * Get function for the list. List is stored on the helper class.
64
     *
65
     * @return Collection
66
     */
67
    public function getList()
68
    {
69
        return $this->list;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->list; of type array<*,array>|Illuminat...ase\Eloquent\Collection adds the type array<*,array> to the return on line 69 which is incompatible with the return type documented by SET\Handlers\Duty\DutyUsers::getList of type Illuminate\Database\Eloquent\Collection.
Loading history...
70
    }
71
72
    /**
73
     * Grab the next user to work the duty roster and record them in our database so they are the current worker.
74
     */
75 View Code Duplication
    public function recordNextEntry()
76
    {
77
        if ($this->list->count() < 2) {
78
            return;
79
        }
80
81
        $nextUser = $this->list->toArray()[1]['user'];
82
        $this->duty->users()->updateExistingPivot($nextUser->id, ['last_worked' => Carbon::today()]);
83
    }
84
85
    /**
86
     * Get the current user in our database who is working the duty roster.
87
     *
88
     * @return DutyUsers
89
     */
90
    public function getLastWorked()
91
    {
92
        $this->lastWorkedUser = $this->duty->users()->orderBy('duty_user.last_worked', 'DESC')->orderBy('last_name')->first();
93
        
94
        return $this;
95
    }
96
97
    /*
98
     * Add new duty user/group to the bottom of the duty list by
99
     * setting the last_worked field to the oldest date
100
     */
101
    public function setLastWorkedDate()
102
    {
103
        // Get the new duty_user just added
104
        $newDutyUserID = $this->duty->users()->whereNull('duty_user.last_worked')->orderBy('last_name', 'DESC')->pluck('id');
105
106
        // Add the new users to the bottom of the duty list by assiging their last_worked dates
107
        // to the most recent weeks. This means that the last_worked dates for the other users
108
        // will need to move further down(depending on number of users added). Do not change the
109
        // last_worked date for the user for the current week.
110
        if($newDutyUserID->isNotEmpty())
111
        {
112
            $newDutyUsersCount = $newDutyUserID->count();
113
114
            DB::table('duty_user')
115
                ->whereNotIn('user_id', [$this->lastWorkedUser->id, $newDutyUserID])
116
                ->update(['last_worked' => DB::raw('DATE_SUB(last_worked, INTERVAL ' . $newDutyUsersCount.' WEEK)')]);
117
118
            $lastWorkedDate = new Carbon($this->lastWorkedUser->pivot->last_worked);
119
120
            // Assign last_worked dates to the new users instead of null
121
            foreach($newDutyUserID as $newUserID)
122
            {
123
                $this->duty->users()->updateExistingPivot($newUserID, ['last_worked' => $lastWorkedDate->subDays($newDutyUsersCount--)]);
124
            }
125
        }
126
        return $this;
127
    }
128
129
    /**
130
     * Get a list of all users for a specific duty sorted by the user's last_worked date.
131
     *
132
     * @return DutyUsers
133
     */
134
    public function queryList()
135
    {
136
        $this->list = $this->duty->users()->active()->orderBy('duty_user.last_worked', 'ASC')->get();
137
        
138
        return $this;
139
    }
140
141
     /**
142
     * Take our list of users and merge them with dates so that each user is assigned a duty date.
143
     *
144
     * @return DutyUsers
145
     */
146
    public function combineListWithDates()
147
    {
148
        $dates = (new DutyDates($this->duty))->getDates();        
149
        $newDatesList = array_values(array_diff($dates, $this->swapDates->toArray())); 
150
        
151
        $count = $this->list->count();
152
        $dateCounter = 0;
153
	
154
        for ($i = 0; $i < $count; $i++) {
155
            // Does list[i] already have date assigned? Is yes, skip assignment
156 View Code Duplication
            if (!empty($this->list[$i]['date'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
157
                continue;
158
            } else {
159
                $this->list[$i] = [
160
                    'date' => $newDatesList[$dateCounter++],
161
                    'user' => $this->list[$i]['user']
162
                ];             
163
            }
164
        }
165
        $this->list = $this->list->sortBy('date');
166
        return $this;
167
    }
168
    
169
    /**
170
     * Query a list of users who we swapped around and insert them into our current duty list of users.
171
     */
172
    public function insertFromDutySwap()
173
    {
174
        $dutySwaps = DutySwap::where('duty_id', $this->duty->id)
175
            ->where('imageable_type', 'SET\User')
176
            ->where('date', '>=', Carbon::now()->subDays(6)) //Omit really old records.
177
            ->orderBy('date', 'ASC')
178
            ->get();
179
180
        $this->convertListToCollection();
181
           
182
        $this->swapDates = new Collection();
183
        foreach ($dutySwaps as $swap) {
184
            $key = key($this->list->pluck('user')->where('id', $swap->imageable_id)->toArray());
185
            if (! is_null($key)) {
186
                $this->swapDates->push($swap->date);
187
                $this->list[$key] = [
188
                        'date' => $swap->date,
189
                        'user' => $swap->imageable()->first(),                        
190
                ];
191
            }
192
        }
193
        return $this;
194
    }
195
    
196
    /**
197
     * Convert the list of users into a collection of date and users
198
     */
199
    private function convertListToCollection()
200
    {
201
        $count = $this->list->count();
202
        $newList = new Collection();
203
        for ($i = 0; $i < $count; $i++) {
204
            $newList->push([
205
                'date' => '',
206
                'user' => $this->list[$i],
207
            ]);
208
        }
209
        $this->list = $newList;
210
    }
211
}
212