PluginProbe
ShiftController Employee Shift Scheduling / 2.2.3
ShiftController Employee Shift Scheduling v2.2.3
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.3, at application/models/shift_model.php

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