PluginProbe
ShiftController Employee Shift Scheduling / 2.2.6
ShiftController Employee Shift Scheduling v2.2.6
4.9.97 4.9.96 4.9.95 4.9.74 4.9.75 4.9.76 4.9.77 4.9.78 4.9.84 4.9.85 4.9.87 4.9.91 4.9.92 trunk 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 3.2.4 All 38 releases
shiftcontroller / application / models / shift_model.php

shift_model.php in ShiftController Employee Shift Scheduling 2.2.6, at application/models/shift_model.php

299 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 include_once( dirname(__FILE__) . '/_timeblock_model.php');
3 class Shift_model extends _Timeblock_model
4 {
5 var $table = 'shifts';
6 var $default_order_by = array(
7 'date' => 'ASC',
8 'start' => 'ASC',
9 'id' => 'ASC'
10 );
11 var $has_one = array(
12 'user' => array(
13 'class' => 'user_model',
14 'other_field' => 'shift',
15 ),
16 'location' => array(
17 'class' => 'location_model',
18 'other_field' => 'shift',
19 ),
20 );
21
22 const STATUS_ACTIVE = 1; // Published, With Staff
23 const STATUS_DRAFT = 2; // Not Published, No Staff
24 const STATUS_OPEN = 3; // not saved - Published, No Staff
25 const STATUS_PENDING = 4; // not saved - Not Published, With Staff
26
27 var $prop_text = array(
28 'status' => array(
29 self::STATUS_ACTIVE => array( 'lang:shift_status_active', 'success' ),
30 self::STATUS_DRAFT => array( 'lang:shift_status_draft', 'warning' ),
31 self::STATUS_OPEN => array( 'lang:shift_status_open', 'danger' ),
32 self::STATUS_PENDING => array( 'lang:shift_status_pending', 'info' ),
33 ),
34 );
35
36 var $validation = array(
37 'date' => array(
38 'label' => 'lang:time_date',
39 'rules' => array('required', 'trim'),
40 ),
41 'location' => array(
42 'label' => 'lang:location',
43 'rules' => array('required'),
44 ),
45 'end' => array(
46 'label' => 'lang:shift_end',
47 'rules' => array('check_time', 'conflict'),
48 ),
49 'status' => array(
50 'label' => 'lang:shift_status',
51 'rules' => array(
52 'enum' => array(
53 self::STATUS_ACTIVE,
54 self::STATUS_DRAFT,
55 )
56 ),
57 ),
58 );
59
60 var $my_fields = array(
61 array(
62 'name' => 'date',
63 'type' => 'date',
64 'label' => 'lang:time_date',
65 // 'hide' => TRUE,
66 ),
67 array(
68 'name' => 'location',
69 'label' => 'lang:location',
70 'type' => 'dropdown',
71 ),
72 array(
73 'name' => 'user',
74 'label' => 'lang:user_level_staff',
75 'type' => 'dropdown',
76 ),
77 array(
78 'name' => 'start',
79 'type' => 'time',
80 'label' => 'lang:shift_start',
81 'required' => TRUE,
82 'rules' => array(),
83 ),
84 array(
85 'name' => 'end',
86 'type' => 'time',
87 'label' => 'lang:shift_end',
88 'required' => TRUE,
89 'rules' => array('check_time', 'conflict'),
90 ),
91 array(
92 'name' => 'status',
93 'label' => 'lang:shift_status',
94 'hide' => TRUE,
95 ),
96 array(
97 'name' => 'has_trade',
98 'label' => 'lang:trade_request',
99 'type' => 'boolean',
100 'hide' => TRUE,
101 'default' => 0,
102 ),
103 );
104
105 public function get_status()
106 {
107 /* ACTIVE - published with staff */
108 /* OPEN - published with no staff */
109 /* PENDING - not published with staff */
110 /* DRAFT - not published with no staff */
111
112 if( $this->status == self::STATUS_ACTIVE )
113 {
114 if( $this->user_id )
115 $return = self::STATUS_ACTIVE;
116 else
117 $return = self::STATUS_OPEN;
118 }
119 else
120 {
121 if( $this->user_id )
122 $return = self::STATUS_PENDING;
123 else
124 $return = self::STATUS_DRAFT;
125 }
126 return $return;
127 }
128
129 public function view_text( $skip = array() )
130 {
131 $return = parent::view_text( $skip );
132 unset( $return['start'] );
133 unset( $return['end'] );
134 unset( $return['status'] );
135 $return['date'][1] = $this->date_view($skip);
136
137 /* optimize it sometime later */
138 $lm = new Location_Model;
139 $location_count = $lm->count();
140 if( $location_count < 2 )
141 {
142 unset( $return['location'] );
143 }
144
145 return $return;
146 }
147
148 public function title( $html = FALSE )
149 {
150 $return = '';
151 if( $html )
152 {
153 $return .= '<i class="fa fa-clock-o"></i> ';
154 }
155 else
156 {
157 $return .= lang('shift') . ': ';
158 }
159
160 $return .= $this->date_view();
161 return $return;
162 }
163
164 public function date_view( $skip = array() )
165 {
166 $return = '';
167 $CI =& ci_get_instance();
168 $CI->hc_time->setDateDb( $this->date );
169
170 $return .= $CI->hc_time->formatWeekdayShort() . ', ' . $CI->hc_time->formatDate();
171
172 $return .= ' [' . $CI->hc_time->formatTimeOfDay($this->start);
173 if( ! in_array('end', $skip) )
174 {
175 $return .= ' - ' . $CI->hc_time->formatTimeOfDay($this->end);
176 }
177 $return .= ']';
178 return $return;
179 }
180
181 public function id_label()
182 {
183 return $this->prop_text('status', TRUE);
184 }
185
186 public function get_duration()
187 {
188 if( $this->end > $this->start )
189 $return = $this->end - $this->start;
190 else
191 $return = $this->end + (24*60*60 - $this->start);
192 return $return;
193 }
194
195 /* remove archived users if any */
196 public function get_form_fields()
197 {
198 $return = parent::get_form_fields();
199
200 $remove_users = array();
201 $um = new User_Model;
202 $um
203 ->select( 'id' )
204 ->where( 'active', USER_MODEL::STATUS_ARCHIVE )
205 ->get();
206 foreach( $um as $u )
207 {
208 $remove_users[] = $u->id;
209 }
210
211 if( $remove_users )
212 {
213 reset( $remove_users );
214 foreach( $remove_users as $rid )
215 {
216 unset( $return['user']['options'][$rid] );
217 }
218 }
219 return $return;
220 }
221
222 public function find_staff()
223 {
224 /* should have date, start, end set */
225 $um = new User_Model;
226 $all_staff = $um->get_staff();
227
228 $return = array();
229 foreach( $all_staff as $u )
230 {
231 $u->warning = array();
232 $return[ $u->id ] = $u;
233 }
234
235 /* find users with shifts that fully overlap this one */
236 $um->clear();
237 $bad_staff = $um
238 ->distinct()
239 ->select('id')
240 ->where_in( 'id', array_keys($return) )
241 ->where_related( 'shift', 'date', $this->date )
242 ->where_related( 'shift', 'start <=', $this->start )
243 ->where_related( 'shift', 'end >=', $this->end )
244 ->get()->all;
245 foreach( $bad_staff as $u )
246 {
247 unset( $return[$u->id] );
248 }
249
250 /* find overlapping timeoffs */
251 $tm = new Timeoff_Model;
252 $timeoffs = $tm
253 ->where_related( 'user', 'id', array_keys($return) )
254 ->include_related( 'user', 'id' )
255
256 ->where( 'date <=', $this->date )
257 ->where( 'date_end >=', $this->date )
258 ->where( 'start <', $this->end )
259 ->where( 'end >', $this->start )
260 ->get()->all;
261
262 foreach( $timeoffs as $to )
263 {
264 $return[$to->user_id]->warning = $to;
265 }
266
267 return $return;
268 }
269
270 /* gets conflicting shifts and timeoffs */
271 public function conflicts( $shifts = NULL, $timeoffs = NULL )
272 {
273 return parent::conflicts( TRUE, TRUE, $shifts, $timeoffs );
274 }
275
276 function publish()
277 {
278 $this->status = SHIFT_MODEL::STATUS_ACTIVE;
279 return $this->save();
280 }
281
282 function unpublish()
283 {
284 $this->status = SHIFT_MODEL::STATUS_DRAFT;
285 return $this->save();
286 }
287
288 protected function _before_delete()
289 {
290 $CI =& ci_get_instance();
291
292 /* delete notes */
293 if( $CI->hc_modules->exists('notes') )
294 {
295 $this->note->get()->delete_all();
296 }
297 }
298 }
299