1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* Copyright (C) 2011 Dimitri Mouillard <[email protected]> |
4
|
|
|
* Copyright (C) 2012-2014 Laurent Destailleur <[email protected]> |
5
|
|
|
* Copyright (C) 2012-2016 Regis Houssin <[email protected]> |
6
|
|
|
* Copyright (C) 2013 Florian Henry <[email protected]> |
7
|
|
|
* Copyright (C) 2016 Juanjo Menent <[email protected]> |
8
|
|
|
* Copyright (C) 2018-2024 Frédéric France <[email protected]> |
9
|
|
|
* Copyright (C) 2024 MDW <[email protected]> |
10
|
|
|
* Copyright (C) 2024 Rafael San José <[email protected]> |
11
|
|
|
* |
12
|
|
|
* This program is free software; you can redistribute it and/or modify |
13
|
|
|
* it under the terms of the GNU General Public License as published by |
14
|
|
|
* the Free Software Foundation; either version 3 of the License, or |
15
|
|
|
* (at your option) any later version. |
16
|
|
|
* |
17
|
|
|
* This program is distributed in the hope that it will be useful, |
18
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
19
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20
|
|
|
* GNU General Public License for more details. |
21
|
|
|
* |
22
|
|
|
* You should have received a copy of the GNU General Public License |
23
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. |
24
|
|
|
*/ |
25
|
|
|
|
26
|
|
|
namespace Dolibarr\Code\Holiday\Classes; |
27
|
|
|
|
28
|
|
|
use Dolibarr\Code\Core\Classes\WorkboardResponse; |
29
|
|
|
use Dolibarr\Core\Base\CommonObject; |
30
|
|
|
use DoliDB; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* \file holiday.class.php |
34
|
|
|
* \ingroup holiday |
35
|
|
|
* \brief Class file of the module paid holiday. |
36
|
|
|
*/ |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* Class of the module paid holiday. Developed by Teclib ( http://www.teclib.com/ ) |
40
|
|
|
*/ |
41
|
|
|
class Holiday extends CommonObject |
42
|
|
|
{ |
43
|
|
|
/** |
44
|
|
|
* @var string ID to identify managed object |
45
|
|
|
*/ |
46
|
|
|
public $element = 'holiday'; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @var string Name of table without prefix where object is stored |
50
|
|
|
*/ |
51
|
|
|
public $table_element = 'holiday'; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* @var string Field with ID of parent key if this field has a parent |
55
|
|
|
*/ |
56
|
|
|
public $fk_element = 'fk_holiday'; |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png |
60
|
|
|
*/ |
61
|
|
|
public $picto = 'holiday'; |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* @var int User ID |
65
|
|
|
*/ |
66
|
|
|
public $fk_user; |
67
|
|
|
|
68
|
|
|
public $date_create = ''; |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* @var string description |
72
|
|
|
*/ |
73
|
|
|
public $description; |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* @var int|string Date start in PHP server TZ |
77
|
|
|
*/ |
78
|
|
|
public $date_debut = ''; |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* @var int|string Date end in PHP server TZ |
82
|
|
|
*/ |
83
|
|
|
public $date_fin = ''; |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* @var int|string Date start in GMT |
87
|
|
|
*/ |
88
|
|
|
public $date_debut_gmt = ''; |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* @var int|string Date end in GMT |
92
|
|
|
*/ |
93
|
|
|
public $date_fin_gmt = ''; |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* @var int|string 0:Full days, 2:Start afternoon end morning, -1:Start afternoon end afternoon, 1:Start morning end morning |
97
|
|
|
*/ |
98
|
|
|
public $halfday = ''; |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* @var int Status 1=draft, 2=validated, 3=approved, 4 canceled, 5 refused |
102
|
|
|
* @deprecated |
103
|
|
|
*/ |
104
|
|
|
public $statut = 0; |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* @var int ID of user that must approve. Real user for approval is fk_user_valid (old version) or fk_user_approve (new versions) |
108
|
|
|
*/ |
109
|
|
|
public $fk_validator; |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* @var int Date of validation or approval. TODO: Use date_valid instead for validation. |
113
|
|
|
*/ |
114
|
|
|
public $date_valid = 0; |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* @var int ID of user that has validated |
118
|
|
|
*/ |
119
|
|
|
public $fk_user_valid; |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* @var int Date approval |
123
|
|
|
*/ |
124
|
|
|
public $date_approval; |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* @var int ID of user that has approved |
128
|
|
|
*/ |
129
|
|
|
public $fk_user_approve; |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* @var int Date for refuse |
133
|
|
|
*/ |
134
|
|
|
public $date_refuse = 0; |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* @var int ID for refuse |
138
|
|
|
*/ |
139
|
|
|
public $fk_user_refuse; |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* @var int Date for cancellation |
143
|
|
|
*/ |
144
|
|
|
public $date_cancel = 0; |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* @var int ID for cancellation |
148
|
|
|
*/ |
149
|
|
|
public $fk_user_cancel; |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* @var int ID for creation |
153
|
|
|
*/ |
154
|
|
|
public $fk_user_create; |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* @var string Detail of refuse |
158
|
|
|
*/ |
159
|
|
|
public $detail_refuse = ''; |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* @var int ID |
163
|
|
|
*/ |
164
|
|
|
public $fk_type; |
165
|
|
|
|
166
|
|
|
public $holiday = array(); |
167
|
|
|
public $events = array(); |
168
|
|
|
public $logs = array(); |
169
|
|
|
|
170
|
|
|
public $optName = ''; |
171
|
|
|
public $optValue = ''; |
172
|
|
|
public $optRowid = ''; |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* Draft status |
176
|
|
|
*/ |
177
|
|
|
const STATUS_DRAFT = 1; |
178
|
|
|
/** |
179
|
|
|
* Validated status |
180
|
|
|
*/ |
181
|
|
|
const STATUS_VALIDATED = 2; |
182
|
|
|
/** |
183
|
|
|
* Approved |
184
|
|
|
*/ |
185
|
|
|
const STATUS_APPROVED = 3; |
186
|
|
|
/** |
187
|
|
|
* Canceled |
188
|
|
|
*/ |
189
|
|
|
const STATUS_CANCELED = 4; |
190
|
|
|
/** |
191
|
|
|
* Refused |
192
|
|
|
*/ |
193
|
|
|
const STATUS_REFUSED = 5; |
194
|
|
|
|
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* Constructor |
198
|
|
|
* |
199
|
|
|
* @param DoliDB $db Database handler |
200
|
|
|
*/ |
201
|
|
|
public function __construct($db) |
202
|
|
|
{ |
203
|
|
|
$this->db = $db; |
204
|
|
|
|
205
|
|
|
$this->ismultientitymanaged = 0; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* Returns the reference to the following non used Order depending on the active numbering module |
211
|
|
|
* defined into HOLIDAY_ADDON |
212
|
|
|
* |
213
|
|
|
* @param Societe $objsoc third party object |
214
|
|
|
* @return string Holiday free reference |
215
|
|
|
*/ |
216
|
|
|
public function getNextNumRef($objsoc) |
217
|
|
|
{ |
218
|
|
|
global $langs, $conf; |
219
|
|
|
$langs->load("order"); |
220
|
|
|
|
221
|
|
|
if (!getDolGlobalString('HOLIDAY_ADDON')) { |
222
|
|
|
$conf->global->HOLIDAY_ADDON = 'mod_holiday_madonna'; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
if (getDolGlobalString('HOLIDAY_ADDON')) { |
226
|
|
|
$mybool = false; |
227
|
|
|
|
228
|
|
|
$file = getDolGlobalString('HOLIDAY_ADDON') . ".php"; |
229
|
|
|
$classname = getDolGlobalString('HOLIDAY_ADDON'); |
230
|
|
|
|
231
|
|
|
// Include file with class |
232
|
|
|
$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); |
233
|
|
|
foreach ($dirmodels as $reldir) { |
234
|
|
|
$dir = dol_buildpath($reldir . "core/modules/holiday/"); |
235
|
|
|
|
236
|
|
|
// Load file with numbering class (if found) |
237
|
|
|
$mybool = ((bool) @include_once $dir . $file) || $mybool; |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
if ($mybool === false) { |
241
|
|
|
dol_print_error(null, "Failed to include file " . $file); |
242
|
|
|
return ''; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
$obj = new $classname(); |
246
|
|
|
$numref = $obj->getNextValue($objsoc, $this); |
247
|
|
|
|
248
|
|
|
if ($numref != "") { |
249
|
|
|
return $numref; |
250
|
|
|
} else { |
251
|
|
|
$this->error = $obj->error; |
252
|
|
|
//dol_print_error($this->db,get_only_class($this)."::getNextNumRef ".$obj->error); |
253
|
|
|
return ""; |
254
|
|
|
} |
255
|
|
|
} else { |
256
|
|
|
print $langs->trans("Error") . " " . $langs->trans("Error_HOLIDAY_ADDON_NotDefined"); |
257
|
|
|
return ""; |
258
|
|
|
} |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* Update balance of vacations and check table of users for holidays is complete. If not complete. |
263
|
|
|
* |
264
|
|
|
* @return int Return integer <0 if KO, >0 if OK |
265
|
|
|
*/ |
266
|
|
|
public function updateBalance() |
267
|
|
|
{ |
268
|
|
|
$this->db->begin(); |
269
|
|
|
|
270
|
|
|
// Update sold of vocations |
271
|
|
|
$result = $this->updateSoldeCP(); |
272
|
|
|
|
273
|
|
|
// Check nb of users into table llx_holiday_users and update with empty lines |
274
|
|
|
//if ($result > 0) $result = $this->verifNbUsers($this->countActiveUsersWithoutCP(), $this->getConfCP('nbUser')); |
275
|
|
|
|
276
|
|
|
if ($result >= 0) { |
277
|
|
|
$this->db->commit(); |
278
|
|
|
return 0; // for cronjob use (0 is OK, any other value is an error code) |
279
|
|
|
} else { |
280
|
|
|
$this->db->rollback(); |
281
|
|
|
return -1; |
282
|
|
|
} |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
/** |
286
|
|
|
* Créer un congés payés dans la base de données |
287
|
|
|
* |
288
|
|
|
* @param User $user User that create |
289
|
|
|
* @param int $notrigger 0=launch triggers after, 1=disable triggers |
290
|
|
|
* @return int Return integer <0 if KO, Id of created object if OK |
291
|
|
|
*/ |
292
|
|
|
public function create($user, $notrigger = 0) |
293
|
|
|
{ |
294
|
|
|
global $conf; |
295
|
|
|
$error = 0; |
296
|
|
|
|
297
|
|
|
$now = dol_now(); |
298
|
|
|
|
299
|
|
|
// Check parameters |
300
|
|
|
if (empty($this->fk_user) || !is_numeric($this->fk_user) || $this->fk_user < 0) { |
301
|
|
|
$this->error = "ErrorBadParameterFkUser"; |
302
|
|
|
return -1; |
303
|
|
|
} |
304
|
|
|
if (empty($this->fk_validator) || !is_numeric($this->fk_validator) || $this->fk_validator < 0) { |
305
|
|
|
$this->error = "ErrorBadParameterFkValidator"; |
306
|
|
|
return -1; |
307
|
|
|
} |
308
|
|
|
if (empty($this->fk_type) || !is_numeric($this->fk_type) || $this->fk_type < 0) { |
309
|
|
|
$this->error = "ErrorBadParameterFkType"; |
310
|
|
|
return -1; |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
// Insert request |
314
|
|
|
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "holiday("; |
315
|
|
|
$sql .= "ref,"; |
316
|
|
|
$sql .= "fk_user,"; |
317
|
|
|
$sql .= "date_create,"; |
318
|
|
|
$sql .= "description,"; |
319
|
|
|
$sql .= "date_debut,"; |
320
|
|
|
$sql .= "date_fin,"; |
321
|
|
|
$sql .= "halfday,"; |
322
|
|
|
$sql .= "statut,"; |
323
|
|
|
$sql .= "fk_validator,"; |
324
|
|
|
$sql .= "fk_type,"; |
325
|
|
|
$sql .= "fk_user_create,"; |
326
|
|
|
$sql .= "entity"; |
327
|
|
|
$sql .= ") VALUES ("; |
328
|
|
|
$sql .= "'(PROV)',"; |
329
|
|
|
$sql .= " " . ((int) $this->fk_user) . ","; |
330
|
|
|
$sql .= " '" . $this->db->idate($now) . "',"; |
331
|
|
|
$sql .= " '" . $this->db->escape($this->description) . "',"; |
332
|
|
|
$sql .= " '" . $this->db->idate($this->date_debut) . "',"; |
333
|
|
|
$sql .= " '" . $this->db->idate($this->date_fin) . "',"; |
334
|
|
|
$sql .= " " . ((int) $this->halfday) . ","; |
335
|
|
|
$sql .= " '1',"; |
336
|
|
|
$sql .= " " . ((int) $this->fk_validator) . ","; |
337
|
|
|
$sql .= " " . ((int) $this->fk_type) . ","; |
338
|
|
|
$sql .= " " . ((int) $user->id) . ","; |
339
|
|
|
$sql .= " " . ((int) $conf->entity); |
340
|
|
|
$sql .= ")"; |
341
|
|
|
|
342
|
|
|
$this->db->begin(); |
343
|
|
|
|
344
|
|
|
dol_syslog(get_only_class($this) . "::create", LOG_DEBUG); |
345
|
|
|
$resql = $this->db->query($sql); |
346
|
|
|
if (!$resql) { |
347
|
|
|
$error++; |
348
|
|
|
$this->errors[] = "Error " . $this->db->lasterror(); |
349
|
|
|
} |
350
|
|
|
|
351
|
|
|
if (!$error) { |
352
|
|
|
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "holiday"); |
353
|
|
|
|
354
|
|
|
if ($this->id) { |
355
|
|
|
// update ref |
356
|
|
|
$initialref = '(PROV' . $this->id . ')'; |
357
|
|
|
if (!empty($this->ref)) { |
358
|
|
|
$initialref = $this->ref; |
359
|
|
|
} |
360
|
|
|
|
361
|
|
|
$sql = 'UPDATE ' . MAIN_DB_PREFIX . "holiday SET ref='" . $this->db->escape($initialref) . "' WHERE rowid=" . ((int) $this->id); |
362
|
|
|
if ($this->db->query($sql)) { |
363
|
|
|
$this->ref = $initialref; |
364
|
|
|
|
365
|
|
|
if (!$error) { |
366
|
|
|
$result = $this->insertExtraFields(); |
367
|
|
|
if ($result < 0) { |
368
|
|
|
$error++; |
369
|
|
|
} |
370
|
|
|
} |
371
|
|
|
|
372
|
|
|
if (!$error && !$notrigger) { |
373
|
|
|
// Call trigger |
374
|
|
|
$result = $this->call_trigger('HOLIDAY_CREATE', $user); |
375
|
|
|
if ($result < 0) { |
376
|
|
|
$error++; |
377
|
|
|
} |
378
|
|
|
// End call triggers |
379
|
|
|
} |
380
|
|
|
} |
381
|
|
|
} |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
// Commit or rollback |
385
|
|
|
if ($error) { |
386
|
|
|
foreach ($this->errors as $errmsg) { |
387
|
|
|
dol_syslog(get_only_class($this) . "::create " . $errmsg, LOG_ERR); |
388
|
|
|
$this->error .= ($this->error ? ', ' . $errmsg : $errmsg); |
389
|
|
|
} |
390
|
|
|
$this->db->rollback(); |
391
|
|
|
return -1 * $error; |
392
|
|
|
} else { |
393
|
|
|
$this->db->commit(); |
394
|
|
|
return $this->id; |
395
|
|
|
} |
396
|
|
|
} |
397
|
|
|
|
398
|
|
|
|
399
|
|
|
/** |
400
|
|
|
* Load object in memory from database |
401
|
|
|
* |
402
|
|
|
* @param int $id Id object |
403
|
|
|
* @param string $ref Ref object |
404
|
|
|
* @return int Return integer <0 if KO, 0 if not found, >0 if OK |
405
|
|
|
*/ |
406
|
|
|
public function fetch($id, $ref = '') |
407
|
|
|
{ |
408
|
|
|
$sql = "SELECT"; |
409
|
|
|
$sql .= " cp.rowid,"; |
410
|
|
|
$sql .= " cp.ref,"; |
411
|
|
|
$sql .= " cp.fk_user,"; |
412
|
|
|
$sql .= " cp.date_create,"; |
413
|
|
|
$sql .= " cp.description,"; |
414
|
|
|
$sql .= " cp.date_debut,"; |
415
|
|
|
$sql .= " cp.date_fin,"; |
416
|
|
|
$sql .= " cp.halfday,"; |
417
|
|
|
$sql .= " cp.statut as status,"; |
418
|
|
|
$sql .= " cp.fk_validator,"; |
419
|
|
|
$sql .= " cp.date_valid,"; |
420
|
|
|
$sql .= " cp.fk_user_valid,"; |
421
|
|
|
$sql .= " cp.date_approval,"; |
422
|
|
|
$sql .= " cp.fk_user_approve,"; |
423
|
|
|
$sql .= " cp.date_refuse,"; |
424
|
|
|
$sql .= " cp.fk_user_refuse,"; |
425
|
|
|
$sql .= " cp.date_cancel,"; |
426
|
|
|
$sql .= " cp.fk_user_cancel,"; |
427
|
|
|
$sql .= " cp.detail_refuse,"; |
428
|
|
|
$sql .= " cp.note_private,"; |
429
|
|
|
$sql .= " cp.note_public,"; |
430
|
|
|
$sql .= " cp.fk_user_create,"; |
431
|
|
|
$sql .= " cp.fk_type,"; |
432
|
|
|
$sql .= " cp.entity"; |
433
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "holiday as cp"; |
434
|
|
|
if ($id > 0) { |
435
|
|
|
$sql .= " WHERE cp.rowid = " . ((int) $id); |
436
|
|
|
} else { |
437
|
|
|
$sql .= " WHERE cp.ref = '" . $this->db->escape($ref) . "'"; |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
dol_syslog(get_only_class($this) . "::fetch", LOG_DEBUG); |
441
|
|
|
$resql = $this->db->query($sql); |
442
|
|
|
if ($resql) { |
443
|
|
|
if ($this->db->num_rows($resql)) { |
444
|
|
|
$obj = $this->db->fetch_object($resql); |
445
|
|
|
|
446
|
|
|
$this->id = $obj->rowid; |
447
|
|
|
$this->ref = ($obj->ref ? $obj->ref : $obj->rowid); |
448
|
|
|
$this->fk_user = $obj->fk_user; |
449
|
|
|
$this->date_create = $this->db->jdate($obj->date_create); |
450
|
|
|
$this->description = $obj->description; |
451
|
|
|
$this->date_debut = $this->db->jdate($obj->date_debut); |
452
|
|
|
$this->date_fin = $this->db->jdate($obj->date_fin); |
453
|
|
|
$this->date_debut_gmt = $this->db->jdate($obj->date_debut, 1); |
454
|
|
|
$this->date_fin_gmt = $this->db->jdate($obj->date_fin, 1); |
455
|
|
|
$this->halfday = $obj->halfday; |
456
|
|
|
$this->status = $obj->status; |
457
|
|
|
$this->statut = $obj->status; // deprecated |
458
|
|
|
$this->fk_validator = $obj->fk_validator; |
459
|
|
|
$this->date_valid = $this->db->jdate($obj->date_valid); |
|
|
|
|
460
|
|
|
$this->fk_user_valid = $obj->fk_user_valid; |
461
|
|
|
$this->user_validation_id = $obj->fk_user_valid; |
462
|
|
|
$this->date_approval = $this->db->jdate($obj->date_approval); |
|
|
|
|
463
|
|
|
$this->fk_user_approve = $obj->fk_user_approve; |
464
|
|
|
$this->date_refuse = $this->db->jdate($obj->date_refuse); |
|
|
|
|
465
|
|
|
$this->fk_user_refuse = $obj->fk_user_refuse; |
466
|
|
|
$this->date_cancel = $this->db->jdate($obj->date_cancel); |
|
|
|
|
467
|
|
|
$this->fk_user_cancel = $obj->fk_user_cancel; |
468
|
|
|
$this->detail_refuse = $obj->detail_refuse; |
469
|
|
|
$this->note_private = $obj->note_private; |
470
|
|
|
$this->note_public = $obj->note_public; |
471
|
|
|
$this->fk_user_create = $obj->fk_user_create; |
472
|
|
|
$this->fk_type = $obj->fk_type; |
473
|
|
|
$this->entity = $obj->entity; |
474
|
|
|
|
475
|
|
|
$this->fetch_optionals(); |
476
|
|
|
|
477
|
|
|
$result = 1; |
478
|
|
|
} else { |
479
|
|
|
$result = 0; |
480
|
|
|
} |
481
|
|
|
$this->db->free($resql); |
482
|
|
|
|
483
|
|
|
return $result; |
484
|
|
|
} else { |
485
|
|
|
$this->error = "Error " . $this->db->lasterror(); |
486
|
|
|
return -1; |
487
|
|
|
} |
488
|
|
|
} |
489
|
|
|
|
490
|
|
|
/** |
491
|
|
|
* List holidays for a particular user or list of users |
492
|
|
|
* |
493
|
|
|
* @param int|string $user_id ID of user to list, or comma separated list of IDs of users to list |
494
|
|
|
* @param string $order Sort order |
495
|
|
|
* @param string $filter SQL Filter |
496
|
|
|
* @return int -1 if KO, 1 if OK, 2 if no result |
497
|
|
|
*/ |
498
|
|
|
public function fetchByUser($user_id, $order = '', $filter = '') |
499
|
|
|
{ |
500
|
|
|
$sql = "SELECT"; |
501
|
|
|
$sql .= " cp.rowid,"; |
502
|
|
|
$sql .= " cp.ref,"; |
503
|
|
|
|
504
|
|
|
$sql .= " cp.fk_user,"; |
505
|
|
|
$sql .= " cp.fk_type,"; |
506
|
|
|
$sql .= " cp.date_create,"; |
507
|
|
|
$sql .= " cp.description,"; |
508
|
|
|
$sql .= " cp.date_debut,"; |
509
|
|
|
$sql .= " cp.date_fin,"; |
510
|
|
|
$sql .= " cp.halfday,"; |
511
|
|
|
$sql .= " cp.statut as status,"; |
512
|
|
|
$sql .= " cp.fk_validator,"; |
513
|
|
|
$sql .= " cp.date_valid,"; |
514
|
|
|
$sql .= " cp.fk_user_valid,"; |
515
|
|
|
$sql .= " cp.date_approval,"; |
516
|
|
|
$sql .= " cp.fk_user_approve,"; |
517
|
|
|
$sql .= " cp.date_refuse,"; |
518
|
|
|
$sql .= " cp.fk_user_refuse,"; |
519
|
|
|
$sql .= " cp.date_cancel,"; |
520
|
|
|
$sql .= " cp.fk_user_cancel,"; |
521
|
|
|
$sql .= " cp.detail_refuse,"; |
522
|
|
|
|
523
|
|
|
$sql .= " uu.lastname as user_lastname,"; |
524
|
|
|
$sql .= " uu.firstname as user_firstname,"; |
525
|
|
|
$sql .= " uu.login as user_login,"; |
526
|
|
|
$sql .= " uu.statut as user_status,"; |
527
|
|
|
$sql .= " uu.photo as user_photo,"; |
528
|
|
|
|
529
|
|
|
$sql .= " ua.lastname as validator_lastname,"; |
530
|
|
|
$sql .= " ua.firstname as validator_firstname,"; |
531
|
|
|
$sql .= " ua.login as validator_login,"; |
532
|
|
|
$sql .= " ua.statut as validator_status,"; |
533
|
|
|
$sql .= " ua.photo as validator_photo"; |
534
|
|
|
|
535
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "holiday as cp, " . MAIN_DB_PREFIX . "user as uu, " . MAIN_DB_PREFIX . "user as ua"; |
536
|
|
|
$sql .= " WHERE cp.entity IN (" . getEntity('holiday') . ")"; |
537
|
|
|
$sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid"; // Hack pour la recherche sur le tableau |
538
|
|
|
$sql .= " AND cp.fk_user IN (" . $this->db->sanitize($user_id) . ")"; |
539
|
|
|
|
540
|
|
|
// Selection filter |
541
|
|
|
if (!empty($filter)) { |
542
|
|
|
$sql .= $filter; |
543
|
|
|
} |
544
|
|
|
|
545
|
|
|
// Order of display of the result |
546
|
|
|
if (!empty($order)) { |
547
|
|
|
$sql .= $order; |
548
|
|
|
} |
549
|
|
|
|
550
|
|
|
dol_syslog(get_only_class($this) . "::fetchByUser", LOG_DEBUG); |
551
|
|
|
$resql = $this->db->query($sql); |
552
|
|
|
|
553
|
|
|
// If no SQL error |
554
|
|
|
if ($resql) { |
555
|
|
|
$i = 0; |
556
|
|
|
$tab_result = $this->holiday; |
557
|
|
|
$num = $this->db->num_rows($resql); |
558
|
|
|
|
559
|
|
|
// If no registration |
560
|
|
|
if (!$num) { |
561
|
|
|
return 2; |
562
|
|
|
} |
563
|
|
|
|
564
|
|
|
// List the records and add them to the table |
565
|
|
|
while ($i < $num) { |
566
|
|
|
$obj = $this->db->fetch_object($resql); |
567
|
|
|
|
568
|
|
|
$tab_result[$i]['rowid'] = $obj->rowid; |
569
|
|
|
$tab_result[$i]['id'] = $obj->rowid; |
570
|
|
|
$tab_result[$i]['ref'] = ($obj->ref ? $obj->ref : $obj->rowid); |
571
|
|
|
|
572
|
|
|
$tab_result[$i]['fk_user'] = $obj->fk_user; |
573
|
|
|
$tab_result[$i]['fk_type'] = $obj->fk_type; |
574
|
|
|
$tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create); |
575
|
|
|
$tab_result[$i]['description'] = $obj->description; |
576
|
|
|
$tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut); |
577
|
|
|
$tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin); |
578
|
|
|
$tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1); |
579
|
|
|
$tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1); |
580
|
|
|
$tab_result[$i]['halfday'] = $obj->halfday; |
581
|
|
|
$tab_result[$i]['statut'] = $obj->status; |
582
|
|
|
$tab_result[$i]['status'] = $obj->status; |
583
|
|
|
$tab_result[$i]['fk_validator'] = $obj->fk_validator; |
584
|
|
|
$tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid); |
585
|
|
|
$tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid; |
586
|
|
|
$tab_result[$i]['date_approval'] = $this->db->jdate($obj->date_approval); |
587
|
|
|
$tab_result[$i]['fk_user_approve'] = $obj->fk_user_approve; |
588
|
|
|
$tab_result[$i]['date_refuse'] = $this->db->jdate($obj->date_refuse); |
589
|
|
|
$tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse; |
590
|
|
|
$tab_result[$i]['date_cancel'] = $this->db->jdate($obj->date_cancel); |
591
|
|
|
$tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel; |
592
|
|
|
$tab_result[$i]['detail_refuse'] = $obj->detail_refuse; |
593
|
|
|
|
594
|
|
|
$tab_result[$i]['user_firstname'] = $obj->user_firstname; |
595
|
|
|
$tab_result[$i]['user_lastname'] = $obj->user_lastname; |
596
|
|
|
$tab_result[$i]['user_login'] = $obj->user_login; |
597
|
|
|
$tab_result[$i]['user_statut'] = $obj->user_status; |
598
|
|
|
$tab_result[$i]['user_status'] = $obj->user_status; |
599
|
|
|
$tab_result[$i]['user_photo'] = $obj->user_photo; |
600
|
|
|
|
601
|
|
|
$tab_result[$i]['validator_firstname'] = $obj->validator_firstname; |
602
|
|
|
$tab_result[$i]['validator_lastname'] = $obj->validator_lastname; |
603
|
|
|
$tab_result[$i]['validator_login'] = $obj->validator_login; |
604
|
|
|
$tab_result[$i]['validator_statut'] = $obj->validator_status; |
605
|
|
|
$tab_result[$i]['validator_status'] = $obj->validator_status; |
606
|
|
|
$tab_result[$i]['validator_photo'] = $obj->validator_photo; |
607
|
|
|
|
608
|
|
|
$i++; |
609
|
|
|
} |
610
|
|
|
|
611
|
|
|
// Returns 1 with the filled array |
612
|
|
|
$this->holiday = $tab_result; |
613
|
|
|
return 1; |
614
|
|
|
} else { |
615
|
|
|
// SQL Error |
616
|
|
|
$this->error = "Error " . $this->db->lasterror(); |
617
|
|
|
return -1; |
618
|
|
|
} |
619
|
|
|
} |
620
|
|
|
|
621
|
|
|
/** |
622
|
|
|
* List all holidays of all users |
623
|
|
|
* |
624
|
|
|
* @param string $order Sort order |
625
|
|
|
* @param string $filter SQL Filter |
626
|
|
|
* @return int -1 if KO, 1 if OK, 2 if no result |
627
|
|
|
*/ |
628
|
|
|
public function fetchAll($order, $filter) |
629
|
|
|
{ |
630
|
|
|
$sql = "SELECT"; |
631
|
|
|
$sql .= " cp.rowid,"; |
632
|
|
|
$sql .= " cp.ref,"; |
633
|
|
|
$sql .= " cp.fk_user,"; |
634
|
|
|
$sql .= " cp.fk_type,"; |
635
|
|
|
$sql .= " cp.date_create,"; |
636
|
|
|
$sql .= " cp.tms as date_modification,"; |
637
|
|
|
$sql .= " cp.description,"; |
638
|
|
|
$sql .= " cp.date_debut,"; |
639
|
|
|
$sql .= " cp.date_fin,"; |
640
|
|
|
$sql .= " cp.halfday,"; |
641
|
|
|
$sql .= " cp.statut as status,"; |
642
|
|
|
$sql .= " cp.fk_validator,"; |
643
|
|
|
$sql .= " cp.date_valid,"; |
644
|
|
|
$sql .= " cp.fk_user_valid,"; |
645
|
|
|
$sql .= " cp.date_approval,"; |
646
|
|
|
$sql .= " cp.fk_user_approve,"; |
647
|
|
|
$sql .= " cp.date_refuse,"; |
648
|
|
|
$sql .= " cp.fk_user_refuse,"; |
649
|
|
|
$sql .= " cp.date_cancel,"; |
650
|
|
|
$sql .= " cp.fk_user_cancel,"; |
651
|
|
|
$sql .= " cp.detail_refuse,"; |
652
|
|
|
|
653
|
|
|
$sql .= " uu.lastname as user_lastname,"; |
654
|
|
|
$sql .= " uu.firstname as user_firstname,"; |
655
|
|
|
$sql .= " uu.login as user_login,"; |
656
|
|
|
$sql .= " uu.statut as user_status,"; |
657
|
|
|
$sql .= " uu.photo as user_photo,"; |
658
|
|
|
|
659
|
|
|
$sql .= " ua.lastname as validator_lastname,"; |
660
|
|
|
$sql .= " ua.firstname as validator_firstname,"; |
661
|
|
|
$sql .= " ua.login as validator_login,"; |
662
|
|
|
$sql .= " ua.statut as validator_status,"; |
663
|
|
|
$sql .= " ua.photo as validator_photo"; |
664
|
|
|
|
665
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "holiday as cp, " . MAIN_DB_PREFIX . "user as uu, " . MAIN_DB_PREFIX . "user as ua"; |
666
|
|
|
$sql .= " WHERE cp.entity IN (" . getEntity('holiday') . ")"; |
667
|
|
|
$sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid "; // Hack pour la recherche sur le tableau |
668
|
|
|
|
669
|
|
|
// Selection filtering |
670
|
|
|
if (!empty($filter)) { |
671
|
|
|
$sql .= $filter; |
672
|
|
|
} |
673
|
|
|
|
674
|
|
|
// order of display |
675
|
|
|
if (!empty($order)) { |
676
|
|
|
$sql .= $order; |
677
|
|
|
} |
678
|
|
|
|
679
|
|
|
dol_syslog(get_only_class($this) . "::fetchAll", LOG_DEBUG); |
680
|
|
|
$resql = $this->db->query($sql); |
681
|
|
|
|
682
|
|
|
// If no SQL error |
683
|
|
|
if ($resql) { |
684
|
|
|
$i = 0; |
685
|
|
|
$tab_result = $this->holiday; |
686
|
|
|
$num = $this->db->num_rows($resql); |
687
|
|
|
|
688
|
|
|
// If no registration |
689
|
|
|
if (!$num) { |
690
|
|
|
return 2; |
691
|
|
|
} |
692
|
|
|
|
693
|
|
|
// List the records and add them to the table |
694
|
|
|
while ($i < $num) { |
695
|
|
|
$obj = $this->db->fetch_object($resql); |
696
|
|
|
|
697
|
|
|
$tab_result[$i]['rowid'] = $obj->rowid; |
698
|
|
|
$tab_result[$i]['id'] = $obj->rowid; |
699
|
|
|
$tab_result[$i]['ref'] = ($obj->ref ? $obj->ref : $obj->rowid); |
700
|
|
|
|
701
|
|
|
$tab_result[$i]['fk_user'] = $obj->fk_user; |
702
|
|
|
$tab_result[$i]['fk_type'] = $obj->fk_type; |
703
|
|
|
$tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create); |
704
|
|
|
$tab_result[$i]['date_modification'] = $this->db->jdate($obj->date_modification); |
705
|
|
|
$tab_result[$i]['description'] = $obj->description; |
706
|
|
|
$tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut); |
707
|
|
|
$tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin); |
708
|
|
|
$tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1); |
709
|
|
|
$tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1); |
710
|
|
|
$tab_result[$i]['halfday'] = $obj->halfday; |
711
|
|
|
$tab_result[$i]['statut'] = $obj->status; |
712
|
|
|
$tab_result[$i]['status'] = $obj->status; |
713
|
|
|
$tab_result[$i]['fk_validator'] = $obj->fk_validator; |
714
|
|
|
$tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid); |
715
|
|
|
$tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid; |
716
|
|
|
$tab_result[$i]['date_approval'] = $this->db->jdate($obj->date_approval); |
717
|
|
|
$tab_result[$i]['fk_user_approve'] = $obj->fk_user_approve; |
718
|
|
|
$tab_result[$i]['date_refuse'] = $obj->date_refuse; |
719
|
|
|
$tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse; |
720
|
|
|
$tab_result[$i]['date_cancel'] = $obj->date_cancel; |
721
|
|
|
$tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel; |
722
|
|
|
$tab_result[$i]['detail_refuse'] = $obj->detail_refuse; |
723
|
|
|
|
724
|
|
|
$tab_result[$i]['user_firstname'] = $obj->user_firstname; |
725
|
|
|
$tab_result[$i]['user_lastname'] = $obj->user_lastname; |
726
|
|
|
$tab_result[$i]['user_login'] = $obj->user_login; |
727
|
|
|
$tab_result[$i]['user_statut'] = $obj->user_status; |
728
|
|
|
$tab_result[$i]['user_status'] = $obj->user_status; |
729
|
|
|
$tab_result[$i]['user_photo'] = $obj->user_photo; |
730
|
|
|
|
731
|
|
|
$tab_result[$i]['validator_firstname'] = $obj->validator_firstname; |
732
|
|
|
$tab_result[$i]['validator_lastname'] = $obj->validator_lastname; |
733
|
|
|
$tab_result[$i]['validator_login'] = $obj->validator_login; |
734
|
|
|
$tab_result[$i]['validator_statut'] = $obj->validator_status; |
735
|
|
|
$tab_result[$i]['validator_status'] = $obj->validator_status; |
736
|
|
|
$tab_result[$i]['validator_photo'] = $obj->validator_photo; |
737
|
|
|
|
738
|
|
|
$i++; |
739
|
|
|
} |
740
|
|
|
// Returns 1 and adds the array to the variable |
741
|
|
|
$this->holiday = $tab_result; |
742
|
|
|
return 1; |
743
|
|
|
} else { |
744
|
|
|
// SQL Error |
745
|
|
|
$this->error = "Error " . $this->db->lasterror(); |
746
|
|
|
return -1; |
747
|
|
|
} |
748
|
|
|
} |
749
|
|
|
|
750
|
|
|
|
751
|
|
|
/** |
752
|
|
|
* Validate leave request |
753
|
|
|
* |
754
|
|
|
* @param User $user User that validate |
755
|
|
|
* @param int $notrigger 0=launch triggers after, 1=disable triggers |
756
|
|
|
* @return int Return integer <0 if KO, >0 if OK |
757
|
|
|
*/ |
758
|
|
|
public function validate($user = null, $notrigger = 0) |
759
|
|
|
{ |
760
|
|
|
global $conf, $langs; |
761
|
|
|
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/files.lib.php'; |
762
|
|
|
$error = 0; |
763
|
|
|
|
764
|
|
|
$checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type); |
765
|
|
|
|
766
|
|
|
if ($checkBalance > 0) { |
767
|
|
|
$balance = $this->getCPforUser($this->fk_user, $this->fk_type); |
768
|
|
|
|
769
|
|
|
if ($balance < 0) { |
770
|
|
|
$this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative'; |
771
|
|
|
return -1; |
772
|
|
|
} |
773
|
|
|
} |
774
|
|
|
|
775
|
|
|
// Define new ref |
776
|
|
|
if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref) || $this->ref == $this->id)) { |
777
|
|
|
$num = $this->getNextNumRef(null); |
778
|
|
|
} else { |
779
|
|
|
$num = $this->ref; |
780
|
|
|
} |
781
|
|
|
$this->newref = dol_sanitizeFileName($num); |
782
|
|
|
|
783
|
|
|
// Update status |
784
|
|
|
$sql = "UPDATE " . MAIN_DB_PREFIX . "holiday SET"; |
785
|
|
|
$sql .= " fk_user_valid = " . ((int) $user->id) . ","; |
786
|
|
|
$sql .= " date_valid = '" . $this->db->idate(dol_now()) . "',"; |
787
|
|
|
if (!empty($this->status) && is_numeric($this->status)) { |
788
|
|
|
$sql .= " statut = " . ((int) $this->status) . ","; |
789
|
|
|
} else { |
790
|
|
|
$this->error = 'Property status must be a numeric value'; |
791
|
|
|
$error++; |
792
|
|
|
} |
793
|
|
|
$sql .= " ref = '" . $this->db->escape($num) . "'"; |
794
|
|
|
$sql .= " WHERE rowid = " . ((int) $this->id); |
795
|
|
|
|
796
|
|
|
$this->db->begin(); |
797
|
|
|
|
798
|
|
|
dol_syslog(get_only_class($this) . "::validate", LOG_DEBUG); |
799
|
|
|
$resql = $this->db->query($sql); |
800
|
|
|
if (!$resql) { |
801
|
|
|
$error++; |
802
|
|
|
$this->errors[] = "Error " . $this->db->lasterror(); |
803
|
|
|
} |
804
|
|
|
|
805
|
|
|
if (!$error) { |
806
|
|
|
if (!$notrigger) { |
807
|
|
|
// Call trigger |
808
|
|
|
$result = $this->call_trigger('HOLIDAY_VALIDATE', $user); |
809
|
|
|
if ($result < 0) { |
810
|
|
|
$error++; |
811
|
|
|
} |
812
|
|
|
// End call triggers |
813
|
|
|
} |
814
|
|
|
} |
815
|
|
|
|
816
|
|
|
if (!$error) { |
817
|
|
|
$this->oldref = $this->ref; |
818
|
|
|
|
819
|
|
|
// Rename directory if dir was a temporary ref |
820
|
|
|
if (preg_match('/^[\(]?PROV/i', $this->ref)) { |
821
|
|
|
// Now we rename also files into index |
822
|
|
|
$sql = 'UPDATE ' . MAIN_DB_PREFIX . "ecm_files set filename = CONCAT('" . $this->db->escape($this->newref) . "', SUBSTR(filename, " . (strlen($this->ref) + 1) . ")), filepath = 'holiday/" . $this->db->escape($this->newref) . "'"; |
823
|
|
|
$sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'holiday/" . $this->db->escape($this->ref) . "' and entity = " . ((int) $conf->entity); |
824
|
|
|
$resql = $this->db->query($sql); |
825
|
|
|
if (!$resql) { |
826
|
|
|
$error++; |
827
|
|
|
$this->error = $this->db->lasterror(); |
828
|
|
|
} |
829
|
|
|
$sql = 'UPDATE ' . MAIN_DB_PREFIX . "ecm_files set filepath = 'holiday/" . $this->db->escape($this->newref) . "'"; |
830
|
|
|
$sql .= " WHERE filepath = 'holiday/" . $this->db->escape($this->ref) . "' and entity = " . $conf->entity; |
831
|
|
|
$resql = $this->db->query($sql); |
832
|
|
|
if (!$resql) { |
833
|
|
|
$error++; |
834
|
|
|
$this->error = $this->db->lasterror(); |
835
|
|
|
} |
836
|
|
|
|
837
|
|
|
// We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments |
838
|
|
|
$oldref = dol_sanitizeFileName($this->ref); |
839
|
|
|
$newref = dol_sanitizeFileName($num); |
840
|
|
|
$dirsource = $conf->holiday->multidir_output[$this->entity] . '/' . $oldref; |
841
|
|
|
$dirdest = $conf->holiday->multidir_output[$this->entity] . '/' . $newref; |
842
|
|
|
if (!$error && file_exists($dirsource)) { |
843
|
|
|
dol_syslog(get_only_class($this) . "::validate rename dir " . $dirsource . " into " . $dirdest); |
844
|
|
|
if (@rename($dirsource, $dirdest)) { |
845
|
|
|
dol_syslog("Rename ok"); |
846
|
|
|
// Rename docs starting with $oldref with $newref |
847
|
|
|
$listoffiles = dol_dir_list($dirdest, 'files', 1, '^' . preg_quote($oldref, '/')); |
848
|
|
|
foreach ($listoffiles as $fileentry) { |
849
|
|
|
$dirsource = $fileentry['name']; |
850
|
|
|
$dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource); |
851
|
|
|
$dirsource = $fileentry['path'] . '/' . $dirsource; |
852
|
|
|
$dirdest = $fileentry['path'] . '/' . $dirdest; |
853
|
|
|
@rename($dirsource, $dirdest); |
|
|
|
|
854
|
|
|
} |
855
|
|
|
} |
856
|
|
|
} |
857
|
|
|
} |
858
|
|
|
} |
859
|
|
|
|
860
|
|
|
|
861
|
|
|
// Commit or rollback |
862
|
|
|
if ($error) { |
863
|
|
|
foreach ($this->errors as $errmsg) { |
864
|
|
|
dol_syslog(get_only_class($this) . "::validate " . $errmsg, LOG_ERR); |
865
|
|
|
$this->error .= ($this->error ? ', ' . $errmsg : $errmsg); |
866
|
|
|
} |
867
|
|
|
$this->db->rollback(); |
868
|
|
|
return -1 * $error; |
869
|
|
|
} else { |
870
|
|
|
$this->db->commit(); |
871
|
|
|
return 1; |
872
|
|
|
} |
873
|
|
|
} |
874
|
|
|
|
875
|
|
|
|
876
|
|
|
/** |
877
|
|
|
* Approve leave request |
878
|
|
|
* |
879
|
|
|
* @param User $user User that approve |
880
|
|
|
* @param int $notrigger 0=launch triggers after, 1=disable triggers |
881
|
|
|
* @return int Return integer <0 if KO, >0 if OK |
882
|
|
|
*/ |
883
|
|
|
public function approve($user = null, $notrigger = 0) |
884
|
|
|
{ |
885
|
|
|
$error = 0; |
886
|
|
|
|
887
|
|
|
$checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type); |
888
|
|
|
|
889
|
|
|
if ($checkBalance > 0) { |
890
|
|
|
$balance = $this->getCPforUser($this->fk_user, $this->fk_type); |
891
|
|
|
|
892
|
|
|
if ($balance < 0) { |
893
|
|
|
$this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative'; |
894
|
|
|
return -1; |
895
|
|
|
} |
896
|
|
|
} |
897
|
|
|
|
898
|
|
|
// Update request |
899
|
|
|
$sql = "UPDATE " . MAIN_DB_PREFIX . "holiday SET"; |
900
|
|
|
$sql .= " description= '" . $this->db->escape($this->description) . "',"; |
901
|
|
|
if (!empty($this->date_debut)) { |
902
|
|
|
$sql .= " date_debut = '" . $this->db->idate($this->date_debut) . "',"; |
903
|
|
|
} else { |
904
|
|
|
$error++; |
905
|
|
|
} |
906
|
|
|
if (!empty($this->date_fin)) { |
907
|
|
|
$sql .= " date_fin = '" . $this->db->idate($this->date_fin) . "',"; |
908
|
|
|
} else { |
909
|
|
|
$error++; |
910
|
|
|
} |
911
|
|
|
$sql .= " halfday = " . ((int) $this->halfday) . ","; |
912
|
|
|
if (!empty($this->status) && is_numeric($this->status)) { |
913
|
|
|
$sql .= " statut = " . ((int) $this->status) . ","; |
914
|
|
|
} else { |
915
|
|
|
$error++; |
916
|
|
|
} |
917
|
|
|
if (!empty($this->fk_validator)) { |
918
|
|
|
$sql .= " fk_validator = " . ((int) $this->fk_validator) . ","; |
919
|
|
|
} else { |
920
|
|
|
$error++; |
921
|
|
|
} |
922
|
|
|
if (!empty($this->date_valid)) { |
923
|
|
|
$sql .= " date_valid = '" . $this->db->idate($this->date_valid) . "',"; |
924
|
|
|
} else { |
925
|
|
|
$sql .= " date_valid = NULL,"; |
926
|
|
|
} |
927
|
|
|
if (!empty($this->fk_user_valid)) { |
928
|
|
|
$sql .= " fk_user_valid = " . ((int) $this->fk_user_valid) . ","; |
929
|
|
|
} else { |
930
|
|
|
$sql .= " fk_user_valid = NULL,"; |
931
|
|
|
} |
932
|
|
|
if (!empty($this->date_approval)) { |
933
|
|
|
$sql .= " date_approval = '" . $this->db->idate($this->date_approval) . "',"; |
934
|
|
|
} else { |
935
|
|
|
$sql .= " date_approval = NULL,"; |
936
|
|
|
} |
937
|
|
|
if (!empty($this->fk_user_approve)) { |
938
|
|
|
$sql .= " fk_user_approve = " . ((int) $this->fk_user_approve) . ","; |
939
|
|
|
} else { |
940
|
|
|
$sql .= " fk_user_approve = NULL,"; |
941
|
|
|
} |
942
|
|
|
if (!empty($this->date_refuse)) { |
943
|
|
|
$sql .= " date_refuse = '" . $this->db->idate($this->date_refuse) . "',"; |
944
|
|
|
} else { |
945
|
|
|
$sql .= " date_refuse = NULL,"; |
946
|
|
|
} |
947
|
|
|
if (!empty($this->fk_user_refuse)) { |
948
|
|
|
$sql .= " fk_user_refuse = " . ((int) $this->fk_user_refuse) . ","; |
949
|
|
|
} else { |
950
|
|
|
$sql .= " fk_user_refuse = NULL,"; |
951
|
|
|
} |
952
|
|
|
if (!empty($this->date_cancel)) { |
953
|
|
|
$sql .= " date_cancel = '" . $this->db->idate($this->date_cancel) . "',"; |
954
|
|
|
} else { |
955
|
|
|
$sql .= " date_cancel = NULL,"; |
956
|
|
|
} |
957
|
|
|
if (!empty($this->fk_user_cancel)) { |
958
|
|
|
$sql .= " fk_user_cancel = " . ((int) $this->fk_user_cancel) . ","; |
959
|
|
|
} else { |
960
|
|
|
$sql .= " fk_user_cancel = NULL,"; |
961
|
|
|
} |
962
|
|
|
if (!empty($this->detail_refuse)) { |
963
|
|
|
$sql .= " detail_refuse = '" . $this->db->escape($this->detail_refuse) . "'"; |
964
|
|
|
} else { |
965
|
|
|
$sql .= " detail_refuse = NULL"; |
966
|
|
|
} |
967
|
|
|
$sql .= " WHERE rowid = " . ((int) $this->id); |
968
|
|
|
|
969
|
|
|
$this->db->begin(); |
970
|
|
|
|
971
|
|
|
dol_syslog(get_only_class($this) . "::approve", LOG_DEBUG); |
972
|
|
|
$resql = $this->db->query($sql); |
973
|
|
|
if (!$resql) { |
974
|
|
|
$error++; |
975
|
|
|
$this->errors[] = "Error " . $this->db->lasterror(); |
976
|
|
|
} |
977
|
|
|
|
978
|
|
|
if (!$error) { |
979
|
|
|
if (!$notrigger) { |
980
|
|
|
// Call trigger |
981
|
|
|
$result = $this->call_trigger('HOLIDAY_APPROVE', $user); |
982
|
|
|
if ($result < 0) { |
983
|
|
|
$error++; |
984
|
|
|
} |
985
|
|
|
// End call triggers |
986
|
|
|
} |
987
|
|
|
} |
988
|
|
|
|
989
|
|
|
// Commit or rollback |
990
|
|
|
if ($error) { |
991
|
|
|
foreach ($this->errors as $errmsg) { |
992
|
|
|
dol_syslog(get_only_class($this) . "::approve " . $errmsg, LOG_ERR); |
993
|
|
|
$this->error .= ($this->error ? ', ' . $errmsg : $errmsg); |
994
|
|
|
} |
995
|
|
|
$this->db->rollback(); |
996
|
|
|
return -1 * $error; |
997
|
|
|
} else { |
998
|
|
|
$this->db->commit(); |
999
|
|
|
return 1; |
1000
|
|
|
} |
1001
|
|
|
} |
1002
|
|
|
|
1003
|
|
|
/** |
1004
|
|
|
* Update database |
1005
|
|
|
* |
1006
|
|
|
* @param User $user User that modify |
1007
|
|
|
* @param int $notrigger 0=launch triggers after, 1=disable triggers |
1008
|
|
|
* @return int Return integer <0 if KO, >0 if OK |
1009
|
|
|
*/ |
1010
|
|
|
public function update($user = null, $notrigger = 0) |
1011
|
|
|
{ |
1012
|
|
|
global $conf, $langs; |
1013
|
|
|
$error = 0; |
1014
|
|
|
|
1015
|
|
|
$checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type); |
1016
|
|
|
|
1017
|
|
|
if ($checkBalance > 0 && $this->status != self::STATUS_DRAFT) { |
1018
|
|
|
$balance = $this->getCPforUser($this->fk_user, $this->fk_type); |
1019
|
|
|
|
1020
|
|
|
if ($balance < 0) { |
1021
|
|
|
$this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative'; |
1022
|
|
|
return -1; |
1023
|
|
|
} |
1024
|
|
|
} |
1025
|
|
|
|
1026
|
|
|
// Update request |
1027
|
|
|
$sql = "UPDATE " . MAIN_DB_PREFIX . "holiday SET"; |
1028
|
|
|
|
1029
|
|
|
$sql .= " description= '" . $this->db->escape($this->description) . "',"; |
1030
|
|
|
|
1031
|
|
|
if (!empty($this->date_debut)) { |
1032
|
|
|
$sql .= " date_debut = '" . $this->db->idate($this->date_debut) . "',"; |
1033
|
|
|
} else { |
1034
|
|
|
$error++; |
1035
|
|
|
} |
1036
|
|
|
if (!empty($this->date_fin)) { |
1037
|
|
|
$sql .= " date_fin = '" . $this->db->idate($this->date_fin) . "',"; |
1038
|
|
|
} else { |
1039
|
|
|
$error++; |
1040
|
|
|
} |
1041
|
|
|
$sql .= " halfday = " . $this->halfday . ","; |
1042
|
|
|
if (!empty($this->status) && is_numeric($this->status)) { |
1043
|
|
|
$sql .= " statut = " . $this->status . ","; |
1044
|
|
|
} else { |
1045
|
|
|
$error++; |
1046
|
|
|
} |
1047
|
|
|
if (!empty($this->fk_validator)) { |
1048
|
|
|
$sql .= " fk_validator = '" . $this->db->escape($this->fk_validator) . "',"; |
1049
|
|
|
} else { |
1050
|
|
|
$error++; |
1051
|
|
|
} |
1052
|
|
|
if (!empty($this->date_valid)) { |
1053
|
|
|
$sql .= " date_valid = '" . $this->db->idate($this->date_valid) . "',"; |
1054
|
|
|
} else { |
1055
|
|
|
$sql .= " date_valid = NULL,"; |
1056
|
|
|
} |
1057
|
|
|
if (!empty($this->fk_user_valid)) { |
1058
|
|
|
$sql .= " fk_user_valid = " . ((int) $this->fk_user_valid) . ","; |
1059
|
|
|
} else { |
1060
|
|
|
$sql .= " fk_user_valid = NULL,"; |
1061
|
|
|
} |
1062
|
|
|
if (!empty($this->date_approval)) { |
1063
|
|
|
$sql .= " date_approval = '" . $this->db->idate($this->date_approval) . "',"; |
1064
|
|
|
} else { |
1065
|
|
|
$sql .= " date_approval = NULL,"; |
1066
|
|
|
} |
1067
|
|
|
if (!empty($this->fk_user_approve)) { |
1068
|
|
|
$sql .= " fk_user_approve = " . ((int) $this->fk_user_approve) . ","; |
1069
|
|
|
} else { |
1070
|
|
|
$sql .= " fk_user_approve = NULL,"; |
1071
|
|
|
} |
1072
|
|
|
if (!empty($this->date_refuse)) { |
1073
|
|
|
$sql .= " date_refuse = '" . $this->db->idate($this->date_refuse) . "',"; |
1074
|
|
|
} else { |
1075
|
|
|
$sql .= " date_refuse = NULL,"; |
1076
|
|
|
} |
1077
|
|
|
if (!empty($this->fk_user_refuse)) { |
1078
|
|
|
$sql .= " fk_user_refuse = " . ((int) $this->fk_user_refuse) . ","; |
1079
|
|
|
} else { |
1080
|
|
|
$sql .= " fk_user_refuse = NULL,"; |
1081
|
|
|
} |
1082
|
|
|
if (!empty($this->date_cancel)) { |
1083
|
|
|
$sql .= " date_cancel = '" . $this->db->idate($this->date_cancel) . "',"; |
1084
|
|
|
} else { |
1085
|
|
|
$sql .= " date_cancel = NULL,"; |
1086
|
|
|
} |
1087
|
|
|
if (!empty($this->fk_user_cancel)) { |
1088
|
|
|
$sql .= " fk_user_cancel = " . ((int) $this->fk_user_cancel) . ","; |
1089
|
|
|
} else { |
1090
|
|
|
$sql .= " fk_user_cancel = NULL,"; |
1091
|
|
|
} |
1092
|
|
|
if (!empty($this->detail_refuse)) { |
1093
|
|
|
$sql .= " detail_refuse = '" . $this->db->escape($this->detail_refuse) . "'"; |
1094
|
|
|
} else { |
1095
|
|
|
$sql .= " detail_refuse = NULL"; |
1096
|
|
|
} |
1097
|
|
|
|
1098
|
|
|
$sql .= " WHERE rowid = " . ((int) $this->id); |
1099
|
|
|
|
1100
|
|
|
$this->db->begin(); |
1101
|
|
|
|
1102
|
|
|
dol_syslog(get_only_class($this) . "::update", LOG_DEBUG); |
1103
|
|
|
$resql = $this->db->query($sql); |
1104
|
|
|
if (!$resql) { |
1105
|
|
|
$error++; |
1106
|
|
|
$this->errors[] = "Error " . $this->db->lasterror(); |
1107
|
|
|
} |
1108
|
|
|
|
1109
|
|
|
if (!$error) { |
1110
|
|
|
if (!$notrigger) { |
1111
|
|
|
// Call trigger |
1112
|
|
|
$result = $this->call_trigger('HOLIDAY_MODIFY', $user); |
1113
|
|
|
if ($result < 0) { |
1114
|
|
|
$error++; |
1115
|
|
|
} |
1116
|
|
|
// End call triggers |
1117
|
|
|
} |
1118
|
|
|
} |
1119
|
|
|
|
1120
|
|
|
// Commit or rollback |
1121
|
|
|
if ($error) { |
1122
|
|
|
foreach ($this->errors as $errmsg) { |
1123
|
|
|
dol_syslog(get_only_class($this) . "::update " . $errmsg, LOG_ERR); |
1124
|
|
|
$this->error .= ($this->error ? ', ' . $errmsg : $errmsg); |
1125
|
|
|
} |
1126
|
|
|
$this->db->rollback(); |
1127
|
|
|
return -1 * $error; |
1128
|
|
|
} else { |
1129
|
|
|
$this->db->commit(); |
1130
|
|
|
return 1; |
1131
|
|
|
} |
1132
|
|
|
} |
1133
|
|
|
|
1134
|
|
|
|
1135
|
|
|
/** |
1136
|
|
|
* Delete object in database |
1137
|
|
|
* |
1138
|
|
|
* @param User $user User that delete |
1139
|
|
|
* @param int $notrigger 0=launch triggers after, 1=disable triggers |
1140
|
|
|
* @return int Return integer <0 if KO, >0 if OK |
1141
|
|
|
*/ |
1142
|
|
|
public function delete($user, $notrigger = 0) |
1143
|
|
|
{ |
1144
|
|
|
global $conf, $langs; |
1145
|
|
|
$error = 0; |
1146
|
|
|
|
1147
|
|
|
$sql = "DELETE FROM " . MAIN_DB_PREFIX . "holiday"; |
1148
|
|
|
$sql .= " WHERE rowid=" . ((int) $this->id); |
1149
|
|
|
|
1150
|
|
|
$this->db->begin(); |
1151
|
|
|
|
1152
|
|
|
dol_syslog(get_only_class($this) . "::delete", LOG_DEBUG); |
1153
|
|
|
$resql = $this->db->query($sql); |
1154
|
|
|
if (!$resql) { |
1155
|
|
|
$error++; |
1156
|
|
|
$this->errors[] = "Error " . $this->db->lasterror(); |
1157
|
|
|
} |
1158
|
|
|
|
1159
|
|
|
if (!$error) { |
1160
|
|
|
if (!$notrigger) { |
1161
|
|
|
// Call trigger |
1162
|
|
|
$result = $this->call_trigger('HOLIDAY_DELETE', $user); |
1163
|
|
|
if ($result < 0) { |
1164
|
|
|
$error++; |
1165
|
|
|
} |
1166
|
|
|
// End call triggers |
1167
|
|
|
} |
1168
|
|
|
} |
1169
|
|
|
|
1170
|
|
|
// Commit or rollback |
1171
|
|
|
if ($error) { |
1172
|
|
|
foreach ($this->errors as $errmsg) { |
1173
|
|
|
dol_syslog(get_only_class($this) . "::delete " . $errmsg, LOG_ERR); |
1174
|
|
|
$this->error .= ($this->error ? ', ' . $errmsg : $errmsg); |
1175
|
|
|
} |
1176
|
|
|
$this->db->rollback(); |
1177
|
|
|
return -1 * $error; |
1178
|
|
|
} else { |
1179
|
|
|
$this->db->commit(); |
1180
|
|
|
return 1; |
1181
|
|
|
} |
1182
|
|
|
} |
1183
|
|
|
|
1184
|
|
|
/** |
1185
|
|
|
* Check if a user is on holiday (partially or completely) into a period. |
1186
|
|
|
* This function can be used to avoid to have 2 leave requests on same period for example. |
1187
|
|
|
* Warning: It consumes a lot of memory because it load in ->holiday all holiday of a dedicated user at each call. |
1188
|
|
|
* |
1189
|
|
|
* @param int $fk_user Id user |
1190
|
|
|
* @param integer $dateStart Start date of period to check |
1191
|
|
|
* @param integer $dateEnd End date of period to check |
1192
|
|
|
* @param int $halfday Tag to define how start and end the period to check: |
1193
|
|
|
* 0:Full days, 2:Start afternoon end morning, -1:Start afternoon end afternoon, 1:Start morning end morning |
1194
|
|
|
* @return boolean False = New range overlap an existing holiday, True = no overlapping (is never on holiday during checked period). |
1195
|
|
|
* @see verifDateHolidayForTimestamp() |
1196
|
|
|
*/ |
1197
|
|
|
public function verifDateHolidayCP($fk_user, $dateStart, $dateEnd, $halfday = 0) |
1198
|
|
|
{ |
1199
|
|
|
$this->fetchByUser($fk_user, '', ''); |
1200
|
|
|
|
1201
|
|
|
foreach ($this->holiday as $infos_CP) { |
1202
|
|
|
if ($infos_CP['statut'] == Holiday::STATUS_CANCELED) { |
1203
|
|
|
continue; // ignore not validated holidays |
1204
|
|
|
} |
1205
|
|
|
if ($infos_CP['statut'] == Holiday::STATUS_REFUSED) { |
1206
|
|
|
continue; // ignore refused holidays |
1207
|
|
|
} |
1208
|
|
|
//var_dump("--"); |
1209
|
|
|
//var_dump("old: ".dol_print_date($infos_CP['date_debut'],'dayhour').' '.dol_print_date($infos_CP['date_fin'],'dayhour').' '.$infos_CP['halfday']); |
1210
|
|
|
//var_dump("new: ".dol_print_date($dateStart,'dayhour').' '.dol_print_date($dateEnd,'dayhour').' '.$halfday); |
1211
|
|
|
|
1212
|
|
|
if ($halfday == 0) { |
1213
|
|
|
if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) { |
1214
|
|
|
return false; |
1215
|
|
|
} |
1216
|
|
|
if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) { |
1217
|
|
|
return false; |
1218
|
|
|
} |
1219
|
|
|
} elseif ($halfday == -1) { |
1220
|
|
|
// new start afternoon, new end afternoon |
1221
|
|
|
if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) { |
1222
|
|
|
if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) { |
1223
|
|
|
return false; |
1224
|
|
|
} |
1225
|
|
|
} |
1226
|
|
|
if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) { |
1227
|
|
|
if ($dateStart < $dateEnd) { |
1228
|
|
|
return false; |
1229
|
|
|
} |
1230
|
|
|
if ($dateEnd < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) { |
1231
|
|
|
return false; |
1232
|
|
|
} |
1233
|
|
|
} |
1234
|
|
|
} elseif ($halfday == 1) { |
1235
|
|
|
// new start morning, new end morning |
1236
|
|
|
if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) { |
1237
|
|
|
if ($dateStart < $dateEnd) { |
1238
|
|
|
return false; |
1239
|
|
|
} |
1240
|
|
|
if ($dateStart > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) { |
1241
|
|
|
return false; |
1242
|
|
|
} |
1243
|
|
|
} |
1244
|
|
|
if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) { |
1245
|
|
|
if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) { |
1246
|
|
|
return false; |
1247
|
|
|
} |
1248
|
|
|
} |
1249
|
|
|
} elseif ($halfday == 2) { |
1250
|
|
|
// new start afternoon, new end morning |
1251
|
|
|
if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) { |
1252
|
|
|
if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) { |
1253
|
|
|
return false; |
1254
|
|
|
} |
1255
|
|
|
} |
1256
|
|
|
if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) { |
1257
|
|
|
if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) { |
1258
|
|
|
return false; |
1259
|
|
|
} |
1260
|
|
|
} |
1261
|
|
|
} else { |
1262
|
|
|
dol_print_error(null, 'Bad value of parameter halfday when calling function verifDateHolidayCP'); |
1263
|
|
|
} |
1264
|
|
|
} |
1265
|
|
|
|
1266
|
|
|
return true; |
1267
|
|
|
} |
1268
|
|
|
|
1269
|
|
|
|
1270
|
|
|
/** |
1271
|
|
|
* Check that a user is not on holiday for a particular timestamp. Can check approved leave requests and not into public holidays of company. |
1272
|
|
|
* |
1273
|
|
|
* @param int $fk_user Id user |
1274
|
|
|
* @param integer $timestamp Time stamp date for a day (YYYY-MM-DD) without hours (= 12:00AM in english and not 12:00PM that is 12:00) |
1275
|
|
|
* @param string $status Filter on holiday status. '-1' = no filter. |
1276
|
|
|
* @return array array('morning'=> ,'afternoon'=> ), Boolean is true if user is available for day timestamp. |
1277
|
|
|
* @see verifDateHolidayCP() |
1278
|
|
|
*/ |
1279
|
|
|
public function verifDateHolidayForTimestamp($fk_user, $timestamp, $status = '-1') |
1280
|
|
|
{ |
1281
|
|
|
$isavailablemorning = true; |
1282
|
|
|
$isavailableafternoon = true; |
1283
|
|
|
|
1284
|
|
|
// Check into leave requests |
1285
|
|
|
$sql = "SELECT cp.rowid, cp.date_debut as date_start, cp.date_fin as date_end, cp.halfday, cp.statut as status"; |
1286
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "holiday as cp"; |
1287
|
|
|
$sql .= " WHERE cp.entity IN (" . getEntity('holiday') . ")"; |
1288
|
|
|
$sql .= " AND cp.fk_user = " . (int) $fk_user; |
1289
|
|
|
$sql .= " AND cp.date_debut <= '" . $this->db->idate($timestamp) . "' AND cp.date_fin >= '" . $this->db->idate($timestamp) . "'"; |
1290
|
|
|
if ($status != '-1') { |
1291
|
|
|
$sql .= " AND cp.statut IN (" . $this->db->sanitize($status) . ")"; |
1292
|
|
|
} |
1293
|
|
|
|
1294
|
|
|
$resql = $this->db->query($sql); |
1295
|
|
|
if ($resql) { |
1296
|
|
|
$num_rows = $this->db->num_rows($resql); // Note, we can have 2 records if on is morning and the other one is afternoon |
1297
|
|
|
if ($num_rows > 0) { |
1298
|
|
|
$arrayofrecord = array(); |
1299
|
|
|
$i = 0; |
1300
|
|
|
while ($i < $num_rows) { |
1301
|
|
|
$obj = $this->db->fetch_object($resql); |
1302
|
|
|
|
1303
|
|
|
// Note: $obj->halfday is 0:Full days, 2:Start afternoon end morning, -1:Start afternoon, 1:End morning |
1304
|
|
|
$arrayofrecord[$obj->rowid] = array('date_start' => $this->db->jdate($obj->date_start), 'date_end' => $this->db->jdate($obj->date_end), 'halfday' => $obj->halfday, 'status' => $obj->status); |
1305
|
|
|
$i++; |
1306
|
|
|
} |
1307
|
|
|
|
1308
|
|
|
// We found a record, user is on holiday by default, so is not available is true. |
1309
|
|
|
$isavailablemorning = true; |
1310
|
|
|
foreach ($arrayofrecord as $record) { |
1311
|
|
|
if ($timestamp == $record['date_start'] && $record['halfday'] == 2) { |
1312
|
|
|
continue; |
1313
|
|
|
} |
1314
|
|
|
if ($timestamp == $record['date_start'] && $record['halfday'] == -1) { |
1315
|
|
|
continue; |
1316
|
|
|
} |
1317
|
|
|
$isavailablemorning = false; |
1318
|
|
|
break; |
1319
|
|
|
} |
1320
|
|
|
$isavailableafternoon = true; |
1321
|
|
|
foreach ($arrayofrecord as $record) { |
1322
|
|
|
if ($timestamp == $record['date_end'] && $record['halfday'] == 2) { |
1323
|
|
|
continue; |
1324
|
|
|
} |
1325
|
|
|
if ($timestamp == $record['date_end'] && $record['halfday'] == 1) { |
1326
|
|
|
continue; |
1327
|
|
|
} |
1328
|
|
|
$isavailableafternoon = false; |
1329
|
|
|
break; |
1330
|
|
|
} |
1331
|
|
|
} |
1332
|
|
|
} else { |
1333
|
|
|
dol_print_error($this->db); |
1334
|
|
|
} |
1335
|
|
|
|
1336
|
|
|
$result = array('morning' => $isavailablemorning, 'afternoon' => $isavailableafternoon); |
1337
|
|
|
if (!$isavailablemorning) { |
1338
|
|
|
$result['morning_reason'] = 'leave_request'; |
1339
|
|
|
} |
1340
|
|
|
if (!$isavailableafternoon) { |
1341
|
|
|
$result['afternoon_reason'] = 'leave_request'; |
1342
|
|
|
} |
1343
|
|
|
return $result; |
1344
|
|
|
} |
1345
|
|
|
|
1346
|
|
|
/** |
1347
|
|
|
* getTooltipContentArray |
1348
|
|
|
* |
1349
|
|
|
* @param array $params ex option, infologin |
1350
|
|
|
* @since v18 |
1351
|
|
|
* @return array |
1352
|
|
|
*/ |
1353
|
|
|
public function getTooltipContentArray($params) |
1354
|
|
|
{ |
1355
|
|
|
global $langs; |
1356
|
|
|
|
1357
|
|
|
$langs->load('holiday'); |
1358
|
|
|
$nofetch = !empty($params['nofetch']); |
1359
|
|
|
|
1360
|
|
|
$datas = array(); |
1361
|
|
|
$datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("Holiday") . '</u>'; |
1362
|
|
|
if (isset($this->status)) { |
1363
|
|
|
$datas['picto'] .= ' ' . $this->getLibStatut(5); |
1364
|
|
|
} |
1365
|
|
|
$datas['ref'] = '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref; |
1366
|
|
|
// show type for this record only in ajax to not overload lists |
1367
|
|
|
if (!$nofetch && !empty($this->fk_type)) { |
1368
|
|
|
$typeleaves = $this->getTypes(1, -1); |
1369
|
|
|
if (empty($typeleaves[$this->fk_type])) { |
1370
|
|
|
$labeltoshow = $langs->trans("TypeWasDisabledOrRemoved", $this->fk_type); |
1371
|
|
|
} else { |
1372
|
|
|
$labeltoshow = (($typeleaves[$this->fk_type]['code'] && $langs->trans($typeleaves[$this->fk_type]['code']) != $typeleaves[$this->fk_type]['code']) ? $langs->trans($typeleaves[$this->fk_type]['code']) : $typeleaves[$this->fk_type]['label']); |
1373
|
|
|
} |
1374
|
|
|
$datas['type'] = '<br><b>' . $langs->trans("Type") . ':</b> ' . $labeltoshow; |
1375
|
|
|
} |
1376
|
|
|
if (isset($this->halfday) && !empty($this->date_debut) && !empty($this->date_fin)) { |
1377
|
|
|
$listhalfday = array( |
1378
|
|
|
'morning' => $langs->trans("Morning"), |
1379
|
|
|
"afternoon" => $langs->trans("Afternoon") |
1380
|
|
|
); |
1381
|
|
|
$starthalfday = ($this->halfday == -1 || $this->halfday == 2) ? 'afternoon' : 'morning'; |
1382
|
|
|
$endhalfday = ($this->halfday == 1 || $this->halfday == 2) ? 'morning' : 'afternoon'; |
1383
|
|
|
$datas['date_start'] = '<br><b>' . $langs->trans('DateDebCP') . '</b>: ' . dol_print_date($this->date_debut, 'day') . ' <span class="opacitymedium">' . $langs->trans($listhalfday[$starthalfday]) . '</span>'; |
1384
|
|
|
$datas['date_end'] = '<br><b>' . $langs->trans('DateFinCP') . '</b>: ' . dol_print_date($this->date_fin, 'day') . ' <span class="opacitymedium">' . $langs->trans($listhalfday[$endhalfday]) . '</span>'; |
1385
|
|
|
} |
1386
|
|
|
|
1387
|
|
|
|
1388
|
|
|
return $datas; |
1389
|
|
|
} |
1390
|
|
|
|
1391
|
|
|
/** |
1392
|
|
|
* Return clicable name (with picto eventually) |
1393
|
|
|
* |
1394
|
|
|
* @param int $withpicto 0=_No picto, 1=Includes the picto in the linkn, 2=Picto only |
1395
|
|
|
* @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking |
1396
|
|
|
* @param int $notooltip 1=Disable tooltip |
1397
|
|
|
* @param string $morecss Add more css on link |
1398
|
|
|
* @return string String with URL |
1399
|
|
|
*/ |
1400
|
|
|
public function getNomUrl($withpicto = 0, $save_lastsearch_value = -1, $notooltip = 0, $morecss = '') |
1401
|
|
|
{ |
1402
|
|
|
global $conf, $langs, $hookmanager; |
1403
|
|
|
|
1404
|
|
|
if (!empty($conf->dol_no_mouse_hover)) { |
1405
|
|
|
$notooltip = 1; // Force disable tooltips |
1406
|
|
|
} |
1407
|
|
|
|
1408
|
|
|
$result = ''; |
1409
|
|
|
$params = [ |
1410
|
|
|
'id' => $this->id, |
1411
|
|
|
'objecttype' => $this->element, |
1412
|
|
|
'nofetch' => 1, |
1413
|
|
|
]; |
1414
|
|
|
$classfortooltip = 'classfortooltip'; |
1415
|
|
|
$dataparams = ''; |
1416
|
|
|
if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) { |
1417
|
|
|
$classfortooltip = 'classforajaxtooltip'; |
1418
|
|
|
$dataparams = ' data-params="' . dol_escape_htmltag(json_encode($params)) . '"'; |
1419
|
|
|
$label = ''; |
1420
|
|
|
} else { |
1421
|
|
|
$label = implode($this->getTooltipContentArray($params)); |
1422
|
|
|
} |
1423
|
|
|
|
1424
|
|
|
$url = constant('BASE_URL') . '/holiday/card.php?id=' . $this->id; |
1425
|
|
|
|
1426
|
|
|
//if ($option != 'nolink') |
1427
|
|
|
//{ |
1428
|
|
|
// Add param to save lastsearch_values or not |
1429
|
|
|
$add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); |
1430
|
|
|
if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) { |
1431
|
|
|
$add_save_lastsearch_values = 1; |
1432
|
|
|
} |
1433
|
|
|
if ($add_save_lastsearch_values) { |
1434
|
|
|
$url .= '&save_lastsearch_values=1'; |
1435
|
|
|
} |
1436
|
|
|
//} |
1437
|
|
|
|
1438
|
|
|
$linkclose = ''; |
1439
|
|
|
if (empty($notooltip)) { |
1440
|
|
|
if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) { |
1441
|
|
|
$label = $langs->trans("ShowMyObject"); |
1442
|
|
|
$linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"'; |
1443
|
|
|
} |
1444
|
|
|
$linkclose .= ($label ? ' title="' . dol_escape_htmltag($label, 1) . '"' : ' title="tocomplete"'); |
1445
|
|
|
$linkclose .= $dataparams . ' class="' . $classfortooltip . ($morecss ? ' ' . $morecss : '') . '"'; |
1446
|
|
|
} else { |
1447
|
|
|
$linkclose = ($morecss ? ' class="' . $morecss . '"' : ''); |
1448
|
|
|
} |
1449
|
|
|
|
1450
|
|
|
$linkstart = '<a href="' . $url . '"'; |
1451
|
|
|
$linkstart .= $linkclose . '>'; |
1452
|
|
|
$linkend = '</a>'; |
1453
|
|
|
|
1454
|
|
|
$result .= $linkstart; |
1455
|
|
|
|
1456
|
|
|
if ($withpicto) { |
1457
|
|
|
$result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="' . (($withpicto != 2) ? 'paddingright ' : '') . '"'), 0, 0, $notooltip ? 0 : 1); |
1458
|
|
|
} |
1459
|
|
|
if ($withpicto != 2) { |
1460
|
|
|
$result .= $this->ref; |
1461
|
|
|
} |
1462
|
|
|
$result .= $linkend; |
1463
|
|
|
|
1464
|
|
|
global $action; |
1465
|
|
|
$hookmanager->initHooks(array($this->element . 'dao')); |
1466
|
|
|
$parameters = array('id' => $this->id, 'getnomurl' => &$result); |
1467
|
|
|
$reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks |
1468
|
|
|
if ($reshook > 0) { |
1469
|
|
|
$result = $hookmanager->resPrint; |
1470
|
|
|
} else { |
1471
|
|
|
$result .= $hookmanager->resPrint; |
1472
|
|
|
} |
1473
|
|
|
return $result; |
1474
|
|
|
} |
1475
|
|
|
|
1476
|
|
|
|
1477
|
|
|
/** |
1478
|
|
|
* Returns the label status |
1479
|
|
|
* |
1480
|
|
|
* @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto |
1481
|
|
|
* @return string Label |
1482
|
|
|
*/ |
1483
|
|
|
public function getLibStatut($mode = 0) |
1484
|
|
|
{ |
1485
|
|
|
return $this->LibStatut($this->status, $mode, $this->date_debut); |
1486
|
|
|
} |
1487
|
|
|
|
1488
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
1489
|
|
|
/** |
1490
|
|
|
* Returns the label of a status |
1491
|
|
|
* |
1492
|
|
|
* @param int $status Id status |
1493
|
|
|
* @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto |
1494
|
|
|
* @param int|string $startdate Date holiday should start |
1495
|
|
|
* @return string Label |
1496
|
|
|
*/ |
1497
|
|
|
public function LibStatut($status, $mode = 0, $startdate = '') |
1498
|
|
|
{ |
1499
|
|
|
// phpcs:enable |
1500
|
|
|
global $langs; |
1501
|
|
|
|
1502
|
|
|
if (empty($this->labelStatus) || empty($this->labelStatusShort)) { |
1503
|
|
|
global $langs; |
1504
|
|
|
//$langs->load("mymodule"); |
1505
|
|
|
$this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP'); |
1506
|
|
|
$this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP'); |
1507
|
|
|
$this->labelStatus[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP'); |
1508
|
|
|
$this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP'); |
1509
|
|
|
$this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP'); |
1510
|
|
|
$this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP'); |
1511
|
|
|
$this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP'); |
1512
|
|
|
$this->labelStatusShort[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP'); |
1513
|
|
|
$this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP'); |
1514
|
|
|
$this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP'); |
1515
|
|
|
} |
1516
|
|
|
|
1517
|
|
|
$params = array(); |
1518
|
|
|
$statusType = 'status6'; |
1519
|
|
|
if (!empty($startdate) && $startdate >= dol_now()) { // If not yet passed, we use a green "in live" color |
1520
|
|
|
$statusType = 'status4'; |
1521
|
|
|
$params = array('tooltip' => $this->labelStatus[$status] . ' - ' . $langs->trans("Forthcoming")); |
1522
|
|
|
} |
1523
|
|
|
if ($status == self::STATUS_DRAFT) { |
1524
|
|
|
$statusType = 'status0'; |
1525
|
|
|
} |
1526
|
|
|
if ($status == self::STATUS_VALIDATED) { |
1527
|
|
|
$statusType = 'status1'; |
1528
|
|
|
} |
1529
|
|
|
if ($status == self::STATUS_CANCELED) { |
1530
|
|
|
$statusType = 'status9'; |
1531
|
|
|
} |
1532
|
|
|
if ($status == self::STATUS_REFUSED) { |
1533
|
|
|
$statusType = 'status9'; |
1534
|
|
|
} |
1535
|
|
|
|
1536
|
|
|
return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode, '', $params); |
1537
|
|
|
} |
1538
|
|
|
|
1539
|
|
|
|
1540
|
|
|
/** |
1541
|
|
|
* Show select with list of leave status |
1542
|
|
|
* |
1543
|
|
|
* @param int $selected Id of preselected status |
1544
|
|
|
* @param string $htmlname Name of HTML select field |
1545
|
|
|
* @param string $morecss More CSS on select component |
1546
|
|
|
* @return string Show select of status |
1547
|
|
|
*/ |
1548
|
|
|
public function selectStatutCP($selected = 0, $htmlname = 'select_statut', $morecss = 'minwidth125') |
1549
|
|
|
{ |
1550
|
|
|
global $langs; |
1551
|
|
|
|
1552
|
|
|
// List of status label |
1553
|
|
|
$name = array('DraftCP', 'ToReviewCP', 'ApprovedCP', 'CancelCP', 'RefuseCP'); |
1554
|
|
|
$nb = count($name) + 1; |
1555
|
|
|
|
1556
|
|
|
// Select HTML |
1557
|
|
|
$out = '<select name="' . $htmlname . '" id="' . $htmlname . '" class="flat' . ($morecss ? ' ' . $morecss : '') . '">' . "\n"; |
1558
|
|
|
$out .= '<option value="-1"> </option>' . "\n"; |
1559
|
|
|
|
1560
|
|
|
// Loop on status |
1561
|
|
|
for ($i = 1; $i < $nb; $i++) { |
1562
|
|
|
if ($i == $selected) { |
1563
|
|
|
$out .= '<option value="' . $i . '" selected>' . $langs->trans($name[$i - 1]) . '</option>' . "\n"; |
1564
|
|
|
} else { |
1565
|
|
|
$out .= '<option value="' . $i . '">' . $langs->trans($name[$i - 1]) . '</option>' . "\n"; |
1566
|
|
|
} |
1567
|
|
|
} |
1568
|
|
|
|
1569
|
|
|
$out .= "</select>\n"; |
1570
|
|
|
|
1571
|
|
|
$showempty = 0; |
1572
|
|
|
$out .= ajax_combobox($htmlname, array(), 0, 0, 'resolve', ($showempty < 0 ? (string) $showempty : '-1'), $morecss); |
1573
|
|
|
|
1574
|
|
|
return $out; |
1575
|
|
|
} |
1576
|
|
|
|
1577
|
|
|
/** |
1578
|
|
|
* Met à jour une option du module Holiday Payés |
1579
|
|
|
* |
1580
|
|
|
* @param string $name name du paramètre de configuration |
1581
|
|
|
* @param string $value vrai si mise à jour OK sinon faux |
1582
|
|
|
* @return boolean ok or ko |
1583
|
|
|
*/ |
1584
|
|
|
public function updateConfCP($name, $value) |
1585
|
|
|
{ |
1586
|
|
|
$sql = "UPDATE " . MAIN_DB_PREFIX . "holiday_config SET"; |
1587
|
|
|
$sql .= " value = '" . $this->db->escape($value) . "'"; |
1588
|
|
|
$sql .= " WHERE name = '" . $this->db->escape($name) . "'"; |
1589
|
|
|
|
1590
|
|
|
dol_syslog(get_only_class($this) . '::updateConfCP name=' . $name, LOG_DEBUG); |
1591
|
|
|
$result = $this->db->query($sql); |
1592
|
|
|
if ($result) { |
1593
|
|
|
return true; |
1594
|
|
|
} |
1595
|
|
|
|
1596
|
|
|
return false; |
1597
|
|
|
} |
1598
|
|
|
|
1599
|
|
|
/** |
1600
|
|
|
* Return value of a conf parameter for leave module |
1601
|
|
|
* TODO Move this into llx_const table |
1602
|
|
|
* |
1603
|
|
|
* @param string $name Name of parameter |
1604
|
|
|
* @param string $createifnotfound 'stringvalue'=Create entry with string value if not found. For example 'YYYYMMDDHHMMSS'. |
1605
|
|
|
* @return string|int<min,0> Value of parameter. Example: 'YYYYMMDDHHMMSS' or < 0 if error |
1606
|
|
|
*/ |
1607
|
|
|
public function getConfCP($name, $createifnotfound = '') |
1608
|
|
|
{ |
1609
|
|
|
$sql = "SELECT value"; |
1610
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "holiday_config"; |
1611
|
|
|
$sql .= " WHERE name = '" . $this->db->escape($name) . "'"; |
1612
|
|
|
|
1613
|
|
|
dol_syslog(get_only_class($this) . '::getConfCP name=' . $name . ' createifnotfound=' . $createifnotfound, LOG_DEBUG); |
1614
|
|
|
$result = $this->db->query($sql); |
1615
|
|
|
|
1616
|
|
|
if ($result) { |
1617
|
|
|
$obj = $this->db->fetch_object($result); |
1618
|
|
|
// Return value |
1619
|
|
|
if (empty($obj)) { |
1620
|
|
|
if ($createifnotfound) { |
1621
|
|
|
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "holiday_config(name, value)"; |
1622
|
|
|
$sql .= " VALUES('" . $this->db->escape($name) . "', '" . $this->db->escape($createifnotfound) . "')"; |
1623
|
|
|
$result = $this->db->query($sql); |
1624
|
|
|
if ($result) { |
1625
|
|
|
return $createifnotfound; |
1626
|
|
|
} else { |
1627
|
|
|
$this->error = $this->db->lasterror(); |
1628
|
|
|
return -2; |
1629
|
|
|
} |
1630
|
|
|
} else { |
1631
|
|
|
return ''; |
1632
|
|
|
} |
1633
|
|
|
} else { |
1634
|
|
|
return $obj->value; |
1635
|
|
|
} |
1636
|
|
|
} else { |
1637
|
|
|
// Erreur SQL |
1638
|
|
|
$this->error = $this->db->lasterror(); |
1639
|
|
|
return -1; |
1640
|
|
|
} |
1641
|
|
|
} |
1642
|
|
|
|
1643
|
|
|
/** |
1644
|
|
|
* Met à jour le timestamp de la dernière mise à jour du solde des CP |
1645
|
|
|
* |
1646
|
|
|
* @param int $userID Id of user |
1647
|
|
|
* @param float $nbHoliday Nb of days |
1648
|
|
|
* @param int $fk_type Type of vacation |
1649
|
|
|
* @return int 0=Nothing done, 1=OK, -1=KO |
1650
|
|
|
*/ |
1651
|
|
|
public function updateSoldeCP($userID = 0, $nbHoliday = 0, $fk_type = 0) |
1652
|
|
|
{ |
1653
|
|
|
global $user, $langs; |
1654
|
|
|
|
1655
|
|
|
$error = 0; |
1656
|
|
|
|
1657
|
|
|
if (empty($userID) && empty($nbHoliday) && empty($fk_type)) { |
1658
|
|
|
$langs->load("holiday"); |
1659
|
|
|
|
1660
|
|
|
// Si mise à jour pour tout le monde en début de mois |
1661
|
|
|
$now = dol_now(); |
1662
|
|
|
|
1663
|
|
|
$month = date('m', $now); |
1664
|
|
|
$newdateforlastupdate = dol_print_date($now, '%Y%m%d%H%M%S'); |
1665
|
|
|
|
1666
|
|
|
// Get month of last update |
1667
|
|
|
$lastUpdate = $this->getConfCP('lastUpdate', $newdateforlastupdate); |
1668
|
|
|
$monthLastUpdate = $lastUpdate[4] . $lastUpdate[5]; |
1669
|
|
|
//print 'month: '.$month.' lastUpdate:'.$lastUpdate.' monthLastUpdate:'.$monthLastUpdate;exit; |
1670
|
|
|
|
1671
|
|
|
// If month date is not same than the one of last update (the one we saved in database), then we update the timestamp and balance of each open user. |
1672
|
|
|
if ($month != $monthLastUpdate) { |
1673
|
|
|
$this->db->begin(); |
1674
|
|
|
|
1675
|
|
|
$users = $this->fetchUsers(false, false, ' AND u.statut > 0'); |
1676
|
|
|
$nbUser = count($users); |
1677
|
|
|
|
1678
|
|
|
$sql = "UPDATE " . MAIN_DB_PREFIX . "holiday_config SET"; |
1679
|
|
|
$sql .= " value = '" . $this->db->escape($newdateforlastupdate) . "'"; |
1680
|
|
|
$sql .= " WHERE name = 'lastUpdate'"; |
1681
|
|
|
$result = $this->db->query($sql); |
1682
|
|
|
|
1683
|
|
|
$typeleaves = $this->getTypes(1, 1); |
1684
|
|
|
|
1685
|
|
|
// Update each user counter |
1686
|
|
|
foreach ($users as $userCounter) { |
1687
|
|
|
$nbDaysToAdd = (isset($typeleaves[$userCounter['type']]['newbymonth']) ? $typeleaves[$userCounter['type']]['newbymonth'] : 0); |
1688
|
|
|
if (empty($nbDaysToAdd)) { |
1689
|
|
|
continue; |
1690
|
|
|
} |
1691
|
|
|
|
1692
|
|
|
dol_syslog("We update leave type id " . $userCounter['type'] . " for user id " . $userCounter['rowid'], LOG_DEBUG); |
1693
|
|
|
|
1694
|
|
|
$nowHoliday = $userCounter['nb_holiday']; |
1695
|
|
|
$newSolde = $nowHoliday + $nbDaysToAdd; |
1696
|
|
|
|
1697
|
|
|
// We add a log for each user |
1698
|
|
|
$this->addLogCP($user->id, $userCounter['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $newSolde, $userCounter['type']); |
1699
|
|
|
|
1700
|
|
|
$result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type']); |
1701
|
|
|
|
1702
|
|
|
if ($result < 0) { |
1703
|
|
|
$error++; |
1704
|
|
|
break; |
1705
|
|
|
} |
1706
|
|
|
} |
1707
|
|
|
|
1708
|
|
|
if (!$error) { |
1709
|
|
|
$this->db->commit(); |
1710
|
|
|
return 1; |
1711
|
|
|
} else { |
1712
|
|
|
$this->db->rollback(); |
1713
|
|
|
return -1; |
1714
|
|
|
} |
1715
|
|
|
} |
1716
|
|
|
|
1717
|
|
|
return 0; |
1718
|
|
|
} else { |
1719
|
|
|
// Mise à jour pour un utilisateur |
1720
|
|
|
$nbHoliday = price2num($nbHoliday, 5); |
1721
|
|
|
|
1722
|
|
|
$sql = "SELECT nb_holiday FROM " . MAIN_DB_PREFIX . "holiday_users"; |
1723
|
|
|
$sql .= " WHERE fk_user = " . (int) $userID . " AND fk_type = " . (int) $fk_type; |
1724
|
|
|
$resql = $this->db->query($sql); |
1725
|
|
|
if ($resql) { |
1726
|
|
|
$num = $this->db->num_rows($resql); |
1727
|
|
|
|
1728
|
|
|
if ($num > 0) { |
1729
|
|
|
// Update for user |
1730
|
|
|
$sql = "UPDATE " . MAIN_DB_PREFIX . "holiday_users SET"; |
1731
|
|
|
$sql .= " nb_holiday = " . ((float) $nbHoliday); |
1732
|
|
|
$sql .= " WHERE fk_user = " . (int) $userID . " AND fk_type = " . (int) $fk_type; |
1733
|
|
|
$result = $this->db->query($sql); |
1734
|
|
|
if (!$result) { |
1735
|
|
|
$error++; |
1736
|
|
|
$this->errors[] = $this->db->lasterror(); |
1737
|
|
|
} |
1738
|
|
|
} else { |
1739
|
|
|
// Insert for user |
1740
|
|
|
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "holiday_users(nb_holiday, fk_user, fk_type) VALUES ("; |
1741
|
|
|
$sql .= ((float) $nbHoliday); |
1742
|
|
|
$sql .= ", " . (int) $userID . ", " . (int) $fk_type . ")"; |
1743
|
|
|
$result = $this->db->query($sql); |
1744
|
|
|
if (!$result) { |
1745
|
|
|
$error++; |
1746
|
|
|
$this->errors[] = $this->db->lasterror(); |
1747
|
|
|
} |
1748
|
|
|
} |
1749
|
|
|
} else { |
1750
|
|
|
$this->errors[] = $this->db->lasterror(); |
1751
|
|
|
$error++; |
1752
|
|
|
} |
1753
|
|
|
|
1754
|
|
|
if (!$error) { |
1755
|
|
|
return 1; |
1756
|
|
|
} else { |
1757
|
|
|
return -1; |
1758
|
|
|
} |
1759
|
|
|
} |
1760
|
|
|
} |
1761
|
|
|
|
1762
|
|
|
/** |
1763
|
|
|
* Create entries for each user at setup step |
1764
|
|
|
* |
1765
|
|
|
* @param boolean $single Single |
1766
|
|
|
* @param int $userid Id user |
1767
|
|
|
* @return void |
1768
|
|
|
*/ |
1769
|
|
|
public function createCPusers($single = false, $userid = 0) |
1770
|
|
|
{ |
1771
|
|
|
// do we have to add balance for all users ? |
1772
|
|
|
if (!$single) { |
1773
|
|
|
dol_syslog(get_only_class($this) . '::createCPusers'); |
1774
|
|
|
$arrayofusers = $this->fetchUsers(false, true); |
1775
|
|
|
|
1776
|
|
|
foreach ($arrayofusers as $users) { |
1777
|
|
|
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "holiday_users"; |
1778
|
|
|
$sql .= " (fk_user, nb_holiday)"; |
1779
|
|
|
$sql .= " VALUES (" . ((int) $users['rowid']) . "', '0')"; |
1780
|
|
|
|
1781
|
|
|
$resql = $this->db->query($sql); |
1782
|
|
|
if (!$resql) { |
1783
|
|
|
dol_print_error($this->db); |
1784
|
|
|
} |
1785
|
|
|
} |
1786
|
|
|
} else { |
1787
|
|
|
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "holiday_users"; |
1788
|
|
|
$sql .= " (fk_user, nb_holiday)"; |
1789
|
|
|
$sql .= " VALUES (" . ((int) $userid) . "', '0')"; |
1790
|
|
|
|
1791
|
|
|
$resql = $this->db->query($sql); |
1792
|
|
|
if (!$resql) { |
1793
|
|
|
dol_print_error($this->db); |
1794
|
|
|
} |
1795
|
|
|
} |
1796
|
|
|
} |
1797
|
|
|
|
1798
|
|
|
/** |
1799
|
|
|
* Return the balance of annual leave of a user |
1800
|
|
|
* |
1801
|
|
|
* @param int $user_id User ID |
1802
|
|
|
* @param int $fk_type Filter on type |
1803
|
|
|
* @return float|null Balance of annual leave if OK, null if KO. |
1804
|
|
|
*/ |
1805
|
|
|
public function getCPforUser($user_id, $fk_type = 0) |
1806
|
|
|
{ |
1807
|
|
|
$sql = "SELECT nb_holiday"; |
1808
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "holiday_users"; |
1809
|
|
|
$sql .= " WHERE fk_user = " . (int) $user_id; |
1810
|
|
|
if ($fk_type > 0) { |
1811
|
|
|
$sql .= " AND fk_type = " . (int) $fk_type; |
1812
|
|
|
} |
1813
|
|
|
|
1814
|
|
|
dol_syslog(get_only_class($this) . '::getCPforUser user_id=' . $user_id . ' type_id=' . $fk_type, LOG_DEBUG); |
1815
|
|
|
$result = $this->db->query($sql); |
1816
|
|
|
if ($result) { |
1817
|
|
|
$obj = $this->db->fetch_object($result); |
1818
|
|
|
//return number_format($obj->nb_holiday,2); |
1819
|
|
|
if ($obj) { |
1820
|
|
|
return $obj->nb_holiday; |
1821
|
|
|
} else { |
1822
|
|
|
return null; |
1823
|
|
|
} |
1824
|
|
|
} else { |
1825
|
|
|
return null; |
1826
|
|
|
} |
1827
|
|
|
} |
1828
|
|
|
|
1829
|
|
|
/** |
1830
|
|
|
* Get list of Users or list of vacation balance. |
1831
|
|
|
* |
1832
|
|
|
* @param boolean $stringlist If true return a string list of id. If false, return an array with detail. |
1833
|
|
|
* @param boolean $type If true, read Dolibarr user list, if false, return vacation balance list. |
1834
|
|
|
* @param string $filters Filters. Warning: This must not contains data from user input. |
1835
|
|
|
* @return array|string|int Return an array |
1836
|
|
|
*/ |
1837
|
|
|
public function fetchUsers($stringlist = true, $type = true, $filters = '') |
1838
|
|
|
{ |
1839
|
|
|
global $conf; |
1840
|
|
|
|
1841
|
|
|
dol_syslog(get_only_class($this) . "::fetchUsers", LOG_DEBUG); |
1842
|
|
|
|
1843
|
|
|
if ($stringlist) { |
1844
|
|
|
if ($type) { |
1845
|
|
|
// If user of Dolibarr |
1846
|
|
|
$sql = "SELECT"; |
1847
|
|
|
if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) { |
1848
|
|
|
$sql .= " DISTINCT"; |
1849
|
|
|
} |
1850
|
|
|
$sql .= " u.rowid"; |
1851
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "user as u"; |
1852
|
|
|
|
1853
|
|
|
if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) { |
1854
|
|
|
$sql .= ", " . MAIN_DB_PREFIX . "usergroup_user as ug"; |
1855
|
|
|
$sql .= " WHERE ((ug.fk_user = u.rowid"; |
1856
|
|
|
$sql .= " AND ug.entity IN (" . getEntity('usergroup') . "))"; |
1857
|
|
|
$sql .= " OR u.entity = 0)"; // Show always superadmin |
1858
|
|
|
} else { |
1859
|
|
|
$sql .= " WHERE u.entity IN (" . getEntity('user') . ")"; |
1860
|
|
|
} |
1861
|
|
|
$sql .= " AND u.statut > 0"; |
1862
|
|
|
$sql .= " AND u.employee = 1"; // We only want employee users for holidays |
1863
|
|
|
if ($filters) { |
1864
|
|
|
$sql .= $filters; |
1865
|
|
|
} |
1866
|
|
|
|
1867
|
|
|
$resql = $this->db->query($sql); |
1868
|
|
|
|
1869
|
|
|
// Si pas d'erreur SQL |
1870
|
|
|
if ($resql) { |
1871
|
|
|
$i = 0; |
1872
|
|
|
$num = $this->db->num_rows($resql); |
1873
|
|
|
$stringlist = ''; |
1874
|
|
|
|
1875
|
|
|
// Boucles du listage des utilisateurs |
1876
|
|
|
while ($i < $num) { |
1877
|
|
|
$obj = $this->db->fetch_object($resql); |
1878
|
|
|
|
1879
|
|
|
if ($i == 0) { |
1880
|
|
|
$stringlist .= $obj->rowid; |
1881
|
|
|
} else { |
1882
|
|
|
$stringlist .= ', ' . $obj->rowid; |
1883
|
|
|
} |
1884
|
|
|
|
1885
|
|
|
$i++; |
1886
|
|
|
} |
1887
|
|
|
// Retoune le tableau des utilisateurs |
1888
|
|
|
return $stringlist; |
1889
|
|
|
} else { |
1890
|
|
|
// Erreur SQL |
1891
|
|
|
$this->error = "Error " . $this->db->lasterror(); |
1892
|
|
|
return -1; |
1893
|
|
|
} |
1894
|
|
|
} else { |
1895
|
|
|
// We want only list of vacation balance for user ids |
1896
|
|
|
$sql = "SELECT DISTINCT cpu.fk_user"; |
1897
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "holiday_users as cpu, " . MAIN_DB_PREFIX . "user as u"; |
1898
|
|
|
$sql .= " WHERE cpu.fk_user = u.rowid"; |
1899
|
|
|
if ($filters) { |
1900
|
|
|
$sql .= $filters; |
1901
|
|
|
} |
1902
|
|
|
|
1903
|
|
|
$resql = $this->db->query($sql); |
1904
|
|
|
|
1905
|
|
|
// Si pas d'erreur SQL |
1906
|
|
|
if ($resql) { |
1907
|
|
|
$i = 0; |
1908
|
|
|
$num = $this->db->num_rows($resql); |
1909
|
|
|
$stringlist = ''; |
1910
|
|
|
|
1911
|
|
|
// Boucles du listage des utilisateurs |
1912
|
|
|
while ($i < $num) { |
1913
|
|
|
$obj = $this->db->fetch_object($resql); |
1914
|
|
|
|
1915
|
|
|
if ($i == 0) { |
1916
|
|
|
$stringlist .= $obj->fk_user; |
1917
|
|
|
} else { |
1918
|
|
|
$stringlist .= ', ' . $obj->fk_user; |
1919
|
|
|
} |
1920
|
|
|
|
1921
|
|
|
$i++; |
1922
|
|
|
} |
1923
|
|
|
// Retoune le tableau des utilisateurs |
1924
|
|
|
return $stringlist; |
1925
|
|
|
} else { |
1926
|
|
|
// Erreur SQL |
1927
|
|
|
$this->error = "Error " . $this->db->lasterror(); |
1928
|
|
|
return -1; |
1929
|
|
|
} |
1930
|
|
|
} |
1931
|
|
|
} else { |
1932
|
|
|
// Si faux donc return array |
1933
|
|
|
// List for Dolibarr users |
1934
|
|
|
if ($type) { |
1935
|
|
|
// If we need users of Dolibarr |
1936
|
|
|
$sql = "SELECT"; |
1937
|
|
|
if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) { |
1938
|
|
|
$sql .= " DISTINCT"; |
1939
|
|
|
} |
1940
|
|
|
$sql .= " u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut as status, u.fk_user"; |
1941
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "user as u"; |
1942
|
|
|
|
1943
|
|
|
if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) { |
1944
|
|
|
$sql .= ", " . MAIN_DB_PREFIX . "usergroup_user as ug"; |
1945
|
|
|
$sql .= " WHERE ((ug.fk_user = u.rowid"; |
1946
|
|
|
$sql .= " AND ug.entity IN (" . getEntity('usergroup') . "))"; |
1947
|
|
|
$sql .= " OR u.entity = 0)"; // Show always superadmin |
1948
|
|
|
} else { |
1949
|
|
|
$sql .= " WHERE u.entity IN (" . getEntity('user') . ")"; |
1950
|
|
|
} |
1951
|
|
|
|
1952
|
|
|
$sql .= " AND u.statut > 0"; |
1953
|
|
|
$sql .= " AND u.employee = 1"; // We only want employee users for holidays |
1954
|
|
|
if ($filters) { |
1955
|
|
|
$sql .= $filters; |
1956
|
|
|
} |
1957
|
|
|
|
1958
|
|
|
$resql = $this->db->query($sql); |
1959
|
|
|
|
1960
|
|
|
// Si pas d'erreur SQL |
1961
|
|
|
if ($resql) { |
1962
|
|
|
$i = 0; |
1963
|
|
|
$tab_result = $this->holiday; |
1964
|
|
|
$num = $this->db->num_rows($resql); |
1965
|
|
|
|
1966
|
|
|
// Boucles du listage des utilisateurs |
1967
|
|
|
while ($i < $num) { |
1968
|
|
|
$obj = $this->db->fetch_object($resql); |
1969
|
|
|
|
1970
|
|
|
$tab_result[$i]['rowid'] = $obj->rowid; // rowid of user |
1971
|
|
|
$tab_result[$i]['id'] = $obj->rowid; // id of user |
1972
|
|
|
$tab_result[$i]['name'] = $obj->lastname; // deprecated |
1973
|
|
|
$tab_result[$i]['lastname'] = $obj->lastname; |
1974
|
|
|
$tab_result[$i]['firstname'] = $obj->firstname; |
1975
|
|
|
$tab_result[$i]['gender'] = $obj->gender; |
1976
|
|
|
$tab_result[$i]['status'] = $obj->status; |
1977
|
|
|
$tab_result[$i]['employee'] = $obj->employee; |
1978
|
|
|
$tab_result[$i]['photo'] = $obj->photo; |
1979
|
|
|
$tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager |
1980
|
|
|
//$tab_result[$i]['type'] = $obj->type; |
1981
|
|
|
//$tab_result[$i]['nb_holiday'] = $obj->nb_holiday; |
1982
|
|
|
|
1983
|
|
|
$i++; |
1984
|
|
|
} |
1985
|
|
|
// Retoune le tableau des utilisateurs |
1986
|
|
|
return $tab_result; |
1987
|
|
|
} else { |
1988
|
|
|
// Erreur SQL |
1989
|
|
|
$this->errors[] = "Error " . $this->db->lasterror(); |
1990
|
|
|
return -1; |
1991
|
|
|
} |
1992
|
|
|
} else { |
1993
|
|
|
// List of vacation balance users |
1994
|
|
|
$sql = "SELECT cpu.fk_type, cpu.nb_holiday, u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut as status, u.fk_user"; |
1995
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "holiday_users as cpu, " . MAIN_DB_PREFIX . "user as u"; |
1996
|
|
|
$sql .= " WHERE cpu.fk_user = u.rowid"; |
1997
|
|
|
if ($filters) { |
1998
|
|
|
$sql .= $filters; |
1999
|
|
|
} |
2000
|
|
|
|
2001
|
|
|
$resql = $this->db->query($sql); |
2002
|
|
|
|
2003
|
|
|
// Si pas d'erreur SQL |
2004
|
|
|
if ($resql) { |
2005
|
|
|
$i = 0; |
2006
|
|
|
$tab_result = $this->holiday; |
2007
|
|
|
$num = $this->db->num_rows($resql); |
2008
|
|
|
|
2009
|
|
|
// Boucles du listage des utilisateurs |
2010
|
|
|
while ($i < $num) { |
2011
|
|
|
$obj = $this->db->fetch_object($resql); |
2012
|
|
|
|
2013
|
|
|
$tab_result[$i]['rowid'] = $obj->rowid; // rowid of user |
2014
|
|
|
$tab_result[$i]['id'] = $obj->rowid; // id of user |
2015
|
|
|
$tab_result[$i]['name'] = $obj->lastname; // deprecated |
2016
|
|
|
$tab_result[$i]['lastname'] = $obj->lastname; |
2017
|
|
|
$tab_result[$i]['firstname'] = $obj->firstname; |
2018
|
|
|
$tab_result[$i]['gender'] = $obj->gender; |
2019
|
|
|
$tab_result[$i]['status'] = $obj->status; |
2020
|
|
|
$tab_result[$i]['employee'] = $obj->employee; |
2021
|
|
|
$tab_result[$i]['photo'] = $obj->photo; |
2022
|
|
|
$tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager |
2023
|
|
|
|
2024
|
|
|
$tab_result[$i]['type'] = $obj->fk_type; |
2025
|
|
|
$tab_result[$i]['nb_holiday'] = $obj->nb_holiday; |
2026
|
|
|
|
2027
|
|
|
$i++; |
2028
|
|
|
} |
2029
|
|
|
// Retoune le tableau des utilisateurs |
2030
|
|
|
return $tab_result; |
2031
|
|
|
} else { |
2032
|
|
|
// Erreur SQL |
2033
|
|
|
$this->error = "Error " . $this->db->lasterror(); |
2034
|
|
|
return -1; |
2035
|
|
|
} |
2036
|
|
|
} |
2037
|
|
|
} |
2038
|
|
|
} |
2039
|
|
|
|
2040
|
|
|
|
2041
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
2042
|
|
|
/** |
2043
|
|
|
* Return list of people with permission to validate leave requests. |
2044
|
|
|
* Search for permission "approve leave requests" |
2045
|
|
|
* |
2046
|
|
|
* @return array|int Array of user ids or -1 if error |
2047
|
|
|
*/ |
2048
|
|
|
public function fetch_users_approver_holiday() |
2049
|
|
|
{ |
2050
|
|
|
// phpcs:enable |
2051
|
|
|
$users_validator = array(); |
2052
|
|
|
|
2053
|
|
|
$sql = "SELECT DISTINCT ur.fk_user"; |
2054
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "user_rights as ur, " . MAIN_DB_PREFIX . "rights_def as rd"; |
2055
|
|
|
$sql .= " WHERE ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve'; |
2056
|
|
|
$sql .= "UNION"; |
2057
|
|
|
$sql .= " SELECT DISTINCT ugu.fk_user"; |
2058
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "usergroup_user as ugu, " . MAIN_DB_PREFIX . "usergroup_rights as ur, " . MAIN_DB_PREFIX . "rights_def as rd"; |
2059
|
|
|
$sql .= " WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve'; |
2060
|
|
|
//print $sql; |
2061
|
|
|
|
2062
|
|
|
dol_syslog(get_only_class($this) . "::fetch_users_approver_holiday sql=" . $sql); |
2063
|
|
|
$result = $this->db->query($sql); |
2064
|
|
|
if ($result) { |
2065
|
|
|
$num_rows = $this->db->num_rows($result); |
2066
|
|
|
$i = 0; |
2067
|
|
|
while ($i < $num_rows) { |
2068
|
|
|
$objp = $this->db->fetch_object($result); |
2069
|
|
|
array_push($users_validator, $objp->fk_user); |
2070
|
|
|
$i++; |
2071
|
|
|
} |
2072
|
|
|
return $users_validator; |
2073
|
|
|
} else { |
2074
|
|
|
$this->error = $this->db->lasterror(); |
2075
|
|
|
dol_syslog(get_only_class($this) . "::fetch_users_approver_holiday Error " . $this->error, LOG_ERR); |
2076
|
|
|
return -1; |
2077
|
|
|
} |
2078
|
|
|
} |
2079
|
|
|
|
2080
|
|
|
|
2081
|
|
|
/** |
2082
|
|
|
* Compte le nombre d'utilisateur actifs dans Dolibarr |
2083
|
|
|
* |
2084
|
|
|
* @return int retourne le nombre d'utilisateur |
2085
|
|
|
*/ |
2086
|
|
|
public function countActiveUsers() |
2087
|
|
|
{ |
2088
|
|
|
$sql = "SELECT count(u.rowid) as compteur"; |
2089
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "user as u"; |
2090
|
|
|
$sql .= " WHERE u.statut > 0"; |
2091
|
|
|
|
2092
|
|
|
$result = $this->db->query($sql); |
2093
|
|
|
$object = $this->db->fetch_object($result); |
2094
|
|
|
|
2095
|
|
|
return $object->compteur; |
2096
|
|
|
} |
2097
|
|
|
/** |
2098
|
|
|
* Compte le nombre d'utilisateur actifs dans Dolibarr sans CP |
2099
|
|
|
* |
2100
|
|
|
* @return int retourne le nombre d'utilisateur |
2101
|
|
|
*/ |
2102
|
|
|
public function countActiveUsersWithoutCP() |
2103
|
|
|
{ |
2104
|
|
|
$sql = "SELECT count(u.rowid) as compteur"; |
2105
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "user as u LEFT OUTER JOIN " . MAIN_DB_PREFIX . "holiday_users hu ON (hu.fk_user=u.rowid)"; |
2106
|
|
|
$sql .= " WHERE u.statut > 0 AND hu.fk_user IS NULL"; |
2107
|
|
|
|
2108
|
|
|
$result = $this->db->query($sql); |
2109
|
|
|
$object = $this->db->fetch_object($result); |
2110
|
|
|
|
2111
|
|
|
return $object->compteur; |
2112
|
|
|
} |
2113
|
|
|
|
2114
|
|
|
/** |
2115
|
|
|
* Compare le nombre d'utilisateur actif de Dolibarr à celui des utilisateurs des congés payés |
2116
|
|
|
* |
2117
|
|
|
* @param int $userDolibarrWithoutCP Number of active users in Dolibarr without holidays |
2118
|
|
|
* @param int $userCP Number of active users into table of holidays |
2119
|
|
|
* @return int Return integer <0 if KO, >0 if OK |
2120
|
|
|
*/ |
2121
|
|
|
public function verifNbUsers($userDolibarrWithoutCP, $userCP) |
2122
|
|
|
{ |
2123
|
|
|
if (empty($userCP)) { |
2124
|
|
|
$userCP = 0; |
2125
|
|
|
} |
2126
|
|
|
dol_syslog(get_only_class($this) . '::verifNbUsers userDolibarr=' . $userDolibarrWithoutCP . ' userCP=' . $userCP); |
2127
|
|
|
return 1; |
2128
|
|
|
} |
2129
|
|
|
|
2130
|
|
|
|
2131
|
|
|
/** |
2132
|
|
|
* addLogCP |
2133
|
|
|
* |
2134
|
|
|
* @param int $fk_user_action Id user creation |
2135
|
|
|
* @param int $fk_user_update Id user update |
2136
|
|
|
* @param string $label Label (Example: 'Leave', 'Manual update', 'Leave request cancelation'...) |
2137
|
|
|
* @param int $new_solde New value |
2138
|
|
|
* @param int $fk_type Type of vacation |
2139
|
|
|
* @return int Id of record added, 0 if nothing done, < 0 if KO |
2140
|
|
|
*/ |
2141
|
|
|
public function addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type) |
2142
|
|
|
{ |
2143
|
|
|
global $conf, $langs; |
2144
|
|
|
|
2145
|
|
|
$error = 0; |
2146
|
|
|
|
2147
|
|
|
$prev_solde = price2num($this->getCPforUser($fk_user_update, $fk_type), 5); |
2148
|
|
|
$new_solde = price2num($new_solde, 5); |
2149
|
|
|
//print "$prev_solde == $new_solde"; |
2150
|
|
|
|
2151
|
|
|
if ($prev_solde == $new_solde) { |
2152
|
|
|
return 0; |
2153
|
|
|
} |
2154
|
|
|
|
2155
|
|
|
$this->db->begin(); |
2156
|
|
|
|
2157
|
|
|
// Insert request |
2158
|
|
|
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "holiday_logs ("; |
2159
|
|
|
$sql .= "date_action,"; |
2160
|
|
|
$sql .= "fk_user_action,"; |
2161
|
|
|
$sql .= "fk_user_update,"; |
2162
|
|
|
$sql .= "type_action,"; |
2163
|
|
|
$sql .= "prev_solde,"; |
2164
|
|
|
$sql .= "new_solde,"; |
2165
|
|
|
$sql .= "fk_type"; |
2166
|
|
|
$sql .= ") VALUES ("; |
2167
|
|
|
$sql .= " '" . $this->db->idate(dol_now()) . "',"; |
2168
|
|
|
$sql .= " " . ((int) $fk_user_action) . ","; |
2169
|
|
|
$sql .= " " . ((int) $fk_user_update) . ","; |
2170
|
|
|
$sql .= " '" . $this->db->escape($label) . "',"; |
2171
|
|
|
$sql .= " " . ((float) $prev_solde) . ","; |
2172
|
|
|
$sql .= " " . ((float) $new_solde) . ","; |
2173
|
|
|
$sql .= " " . ((int) $fk_type); |
2174
|
|
|
$sql .= ")"; |
2175
|
|
|
|
2176
|
|
|
$resql = $this->db->query($sql); |
2177
|
|
|
if (!$resql) { |
2178
|
|
|
$error++; |
2179
|
|
|
$this->errors[] = "Error " . $this->db->lasterror(); |
2180
|
|
|
} |
2181
|
|
|
|
2182
|
|
|
if (!$error) { |
2183
|
|
|
$this->optRowid = $this->db->last_insert_id(MAIN_DB_PREFIX . "holiday_logs"); |
2184
|
|
|
} |
2185
|
|
|
|
2186
|
|
|
// Commit or rollback |
2187
|
|
|
if ($error) { |
2188
|
|
|
foreach ($this->errors as $errmsg) { |
2189
|
|
|
dol_syslog(get_only_class($this) . "::addLogCP " . $errmsg, LOG_ERR); |
2190
|
|
|
$this->error .= ($this->error ? ', ' . $errmsg : $errmsg); |
2191
|
|
|
} |
2192
|
|
|
$this->db->rollback(); |
2193
|
|
|
return -1 * $error; |
2194
|
|
|
} else { |
2195
|
|
|
$this->db->commit(); |
2196
|
|
|
return $this->optRowid; |
2197
|
|
|
} |
2198
|
|
|
} |
2199
|
|
|
|
2200
|
|
|
/** |
2201
|
|
|
* Liste le log des congés payés |
2202
|
|
|
* |
2203
|
|
|
* @param string $order Filtrage par ordre |
2204
|
|
|
* @param string $filter Filtre de séléction |
2205
|
|
|
* @return int -1 si erreur, 1 si OK et 2 si pas de résultat |
2206
|
|
|
*/ |
2207
|
|
|
public function fetchLog($order, $filter) |
2208
|
|
|
{ |
2209
|
|
|
$sql = "SELECT"; |
2210
|
|
|
$sql .= " cpl.rowid,"; |
2211
|
|
|
$sql .= " cpl.date_action,"; |
2212
|
|
|
$sql .= " cpl.fk_user_action,"; |
2213
|
|
|
$sql .= " cpl.fk_user_update,"; |
2214
|
|
|
$sql .= " cpl.type_action,"; |
2215
|
|
|
$sql .= " cpl.prev_solde,"; |
2216
|
|
|
$sql .= " cpl.new_solde,"; |
2217
|
|
|
$sql .= " cpl.fk_type"; |
2218
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "holiday_logs as cpl"; |
2219
|
|
|
$sql .= " WHERE cpl.rowid > 0"; // To avoid error with other search and criteria |
2220
|
|
|
|
2221
|
|
|
// Filtrage de séléction |
2222
|
|
|
if (!empty($filter)) { |
2223
|
|
|
$sql .= " " . $filter; |
2224
|
|
|
} |
2225
|
|
|
|
2226
|
|
|
// Ordre d'affichage |
2227
|
|
|
if (!empty($order)) { |
2228
|
|
|
$sql .= " " . $order; |
2229
|
|
|
} |
2230
|
|
|
|
2231
|
|
|
dol_syslog(get_only_class($this) . "::fetchLog", LOG_DEBUG); |
2232
|
|
|
$resql = $this->db->query($sql); |
2233
|
|
|
|
2234
|
|
|
// Si pas d'erreur SQL |
2235
|
|
|
if ($resql) { |
2236
|
|
|
$i = 0; |
2237
|
|
|
$tab_result = $this->logs; |
2238
|
|
|
$num = $this->db->num_rows($resql); |
2239
|
|
|
|
2240
|
|
|
// Si pas d'enregistrement |
2241
|
|
|
if (!$num) { |
2242
|
|
|
return 2; |
2243
|
|
|
} |
2244
|
|
|
|
2245
|
|
|
// On liste les résultats et on les ajoutent dans le tableau |
2246
|
|
|
while ($i < $num) { |
2247
|
|
|
$obj = $this->db->fetch_object($resql); |
2248
|
|
|
|
2249
|
|
|
$tab_result[$i]['rowid'] = $obj->rowid; |
2250
|
|
|
$tab_result[$i]['id'] = $obj->rowid; |
2251
|
|
|
$tab_result[$i]['date_action'] = $obj->date_action; |
2252
|
|
|
$tab_result[$i]['fk_user_action'] = $obj->fk_user_action; |
2253
|
|
|
$tab_result[$i]['fk_user_update'] = $obj->fk_user_update; |
2254
|
|
|
$tab_result[$i]['type_action'] = $obj->type_action; |
2255
|
|
|
$tab_result[$i]['prev_solde'] = $obj->prev_solde; |
2256
|
|
|
$tab_result[$i]['new_solde'] = $obj->new_solde; |
2257
|
|
|
$tab_result[$i]['fk_type'] = $obj->fk_type; |
2258
|
|
|
|
2259
|
|
|
$i++; |
2260
|
|
|
} |
2261
|
|
|
// Retourne 1 et ajoute le tableau à la variable |
2262
|
|
|
$this->logs = $tab_result; |
2263
|
|
|
return 1; |
2264
|
|
|
} else { |
2265
|
|
|
// Erreur SQL |
2266
|
|
|
$this->error = "Error " . $this->db->lasterror(); |
2267
|
|
|
return -1; |
2268
|
|
|
} |
2269
|
|
|
} |
2270
|
|
|
|
2271
|
|
|
|
2272
|
|
|
/** |
2273
|
|
|
* Return array with list of types |
2274
|
|
|
* |
2275
|
|
|
* @param int $active Status of type. -1 = Both |
2276
|
|
|
* @param int $affect Filter on affect (a request will change sold or not). -1 = Both |
2277
|
|
|
* @return array Return array with list of types |
2278
|
|
|
*/ |
2279
|
|
|
public function getTypes($active = -1, $affect = -1) |
2280
|
|
|
{ |
2281
|
|
|
global $mysoc; |
2282
|
|
|
|
2283
|
|
|
$sql = "SELECT rowid, code, label, affect, delay, newbymonth"; |
2284
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "c_holiday_types"; |
2285
|
|
|
$sql .= " WHERE (fk_country IS NULL OR fk_country = " . ((int) $mysoc->country_id) . ')'; |
2286
|
|
|
if ($active >= 0) { |
2287
|
|
|
$sql .= " AND active = " . ((int) $active); |
2288
|
|
|
} |
2289
|
|
|
if ($affect >= 0) { |
2290
|
|
|
$sql .= " AND affect = " . ((int) $affect); |
2291
|
|
|
} |
2292
|
|
|
$sql .= " ORDER BY sortorder"; |
2293
|
|
|
|
2294
|
|
|
$result = $this->db->query($sql); |
2295
|
|
|
if ($result) { |
2296
|
|
|
$num = $this->db->num_rows($result); |
2297
|
|
|
if ($num) { |
2298
|
|
|
$types = array(); |
2299
|
|
|
while ($obj = $this->db->fetch_object($result)) { |
2300
|
|
|
$types[$obj->rowid] = array('id' => $obj->rowid, 'rowid' => $obj->rowid, 'code' => $obj->code, 'label' => $obj->label, 'affect' => $obj->affect, 'delay' => $obj->delay, 'newbymonth' => $obj->newbymonth); |
2301
|
|
|
} |
2302
|
|
|
|
2303
|
|
|
return $types; |
2304
|
|
|
} |
2305
|
|
|
} else { |
2306
|
|
|
dol_print_error($this->db); |
2307
|
|
|
} |
2308
|
|
|
|
2309
|
|
|
return array(); |
2310
|
|
|
} |
2311
|
|
|
|
2312
|
|
|
|
2313
|
|
|
/** |
2314
|
|
|
* Load information on object |
2315
|
|
|
* |
2316
|
|
|
* @param int $id Id of object |
2317
|
|
|
* @return void |
2318
|
|
|
*/ |
2319
|
|
|
public function info($id) |
2320
|
|
|
{ |
2321
|
|
|
global $conf; |
2322
|
|
|
|
2323
|
|
|
$sql = "SELECT f.rowid, f.statut as status,"; |
2324
|
|
|
$sql .= " f.date_create as datec,"; |
2325
|
|
|
$sql .= " f.tms as date_modification,"; |
2326
|
|
|
$sql .= " f.date_valid as datev,"; |
2327
|
|
|
$sql .= " f.date_approval as datea,"; |
2328
|
|
|
$sql .= " f.date_refuse as dater,"; |
2329
|
|
|
$sql .= " f.fk_user_create as fk_user_creation,"; |
2330
|
|
|
$sql .= " f.fk_user_modif as fk_user_modification,"; |
2331
|
|
|
$sql .= " f.fk_user_valid as fk_user_validation,"; |
2332
|
|
|
$sql .= " f.fk_user_approve as fk_user_approval_done,"; |
2333
|
|
|
$sql .= " f.fk_validator as fk_user_approval_expected,"; |
2334
|
|
|
$sql .= " f.fk_user_refuse as fk_user_refuse"; |
2335
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "holiday as f"; |
2336
|
|
|
$sql .= " WHERE f.rowid = " . ((int) $id); |
2337
|
|
|
$sql .= " AND f.entity = " . $conf->entity; |
2338
|
|
|
|
2339
|
|
|
$resql = $this->db->query($sql); |
2340
|
|
|
if ($resql) { |
2341
|
|
|
if ($this->db->num_rows($resql)) { |
2342
|
|
|
$obj = $this->db->fetch_object($resql); |
2343
|
|
|
|
2344
|
|
|
$this->id = $obj->rowid; |
2345
|
|
|
|
2346
|
|
|
$this->date_creation = $this->db->jdate($obj->datec); |
2347
|
|
|
$this->date_modification = $this->db->jdate($obj->date_modification); |
2348
|
|
|
$this->date_validation = $this->db->jdate($obj->datev); |
2349
|
|
|
$this->date_approval = $this->db->jdate($obj->datea); |
|
|
|
|
2350
|
|
|
|
2351
|
|
|
$this->user_creation_id = $obj->fk_user_creation; |
2352
|
|
|
$this->user_validation_id = $obj->fk_user_validation; |
2353
|
|
|
$this->user_modification_id = $obj->fk_user_modification; |
2354
|
|
|
|
2355
|
|
|
if ($obj->status == Holiday::STATUS_APPROVED || $obj->status == Holiday::STATUS_CANCELED) { |
2356
|
|
|
if ($obj->fk_user_approval_done) { |
2357
|
|
|
$this->fk_user_approve = $obj->fk_user_approval_done; |
2358
|
|
|
} |
2359
|
|
|
} |
2360
|
|
|
} |
2361
|
|
|
$this->db->free($resql); |
2362
|
|
|
} else { |
2363
|
|
|
dol_print_error($this->db); |
2364
|
|
|
} |
2365
|
|
|
} |
2366
|
|
|
|
2367
|
|
|
|
2368
|
|
|
/** |
2369
|
|
|
* Initialise an instance with random values. |
2370
|
|
|
* Used to build previews or test instances. |
2371
|
|
|
* id must be 0 if object instance is a specimen. |
2372
|
|
|
* |
2373
|
|
|
* @return int |
2374
|
|
|
*/ |
2375
|
|
|
public function initAsSpecimen() |
2376
|
|
|
{ |
2377
|
|
|
global $user, $langs; |
2378
|
|
|
|
2379
|
|
|
// Initialise parameters |
2380
|
|
|
$this->id = 0; |
2381
|
|
|
$this->specimen = 1; |
2382
|
|
|
|
2383
|
|
|
$this->fk_user = $user->id; |
2384
|
|
|
$this->description = 'SPECIMEN description'; |
2385
|
|
|
$this->date_debut = dol_now(); |
2386
|
|
|
$this->date_fin = dol_now() + (24 * 3600); |
2387
|
|
|
$this->date_valid = dol_now(); |
2388
|
|
|
$this->fk_validator = $user->id; |
2389
|
|
|
$this->halfday = 0; |
2390
|
|
|
$this->fk_type = 1; |
2391
|
|
|
$this->status = Holiday::STATUS_VALIDATED; |
2392
|
|
|
|
2393
|
|
|
return 1; |
2394
|
|
|
} |
2395
|
|
|
|
2396
|
|
|
/** |
2397
|
|
|
* Load this->nb for dashboard |
2398
|
|
|
* |
2399
|
|
|
* @return int Return integer <0 if KO, >0 if OK |
2400
|
|
|
*/ |
2401
|
|
|
public function loadStateBoard() |
2402
|
|
|
{ |
2403
|
|
|
global $user; |
2404
|
|
|
|
2405
|
|
|
$this->nb = array(); |
2406
|
|
|
|
2407
|
|
|
$sql = "SELECT count(h.rowid) as nb"; |
2408
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "holiday as h"; |
2409
|
|
|
$sql .= " WHERE h.statut > 1"; |
2410
|
|
|
$sql .= " AND h.entity IN (" . getEntity('holiday') . ")"; |
2411
|
|
|
if (!$user->hasRight('expensereport', 'readall')) { |
2412
|
|
|
$userchildids = $user->getAllChildIds(1); |
2413
|
|
|
$sql .= " AND (h.fk_user IN (" . $this->db->sanitize(implode(',', $userchildids)) . ")"; |
2414
|
|
|
$sql .= " OR h.fk_validator IN (" . $this->db->sanitize(implode(',', $userchildids)) . "))"; |
2415
|
|
|
} |
2416
|
|
|
|
2417
|
|
|
$resql = $this->db->query($sql); |
2418
|
|
|
if ($resql) { |
2419
|
|
|
while ($obj = $this->db->fetch_object($resql)) { |
2420
|
|
|
$this->nb["holidays"] = $obj->nb; |
2421
|
|
|
} |
2422
|
|
|
$this->db->free($resql); |
2423
|
|
|
return 1; |
2424
|
|
|
} else { |
2425
|
|
|
dol_print_error($this->db); |
2426
|
|
|
$this->error = $this->db->error(); |
2427
|
|
|
return -1; |
2428
|
|
|
} |
2429
|
|
|
} |
2430
|
|
|
|
2431
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
2432
|
|
|
/** |
2433
|
|
|
* Load indicators for dashboard (this->nbtodo and this->nbtodolate) |
2434
|
|
|
* |
2435
|
|
|
* @param User $user Object user |
2436
|
|
|
* @return WorkboardResponse|int Return integer <0 if KO, WorkboardResponse if OK |
2437
|
|
|
*/ |
2438
|
|
|
public function load_board($user) |
2439
|
|
|
{ |
2440
|
|
|
// phpcs:enable |
2441
|
|
|
global $conf, $langs; |
2442
|
|
|
|
2443
|
|
|
if ($user->socid) { |
2444
|
|
|
return -1; // protection pour eviter appel par utilisateur externe |
2445
|
|
|
} |
2446
|
|
|
|
2447
|
|
|
$now = dol_now(); |
2448
|
|
|
|
2449
|
|
|
$sql = "SELECT h.rowid, h.date_debut"; |
2450
|
|
|
$sql .= " FROM " . MAIN_DB_PREFIX . "holiday as h"; |
2451
|
|
|
$sql .= " WHERE h.statut = 2"; |
2452
|
|
|
$sql .= " AND h.entity IN (" . getEntity('holiday') . ")"; |
2453
|
|
|
if (!$user->hasRight('expensereport', 'read_all')) { |
2454
|
|
|
$userchildids = $user->getAllChildIds(1); |
2455
|
|
|
$sql .= " AND (h.fk_user IN (" . $this->db->sanitize(implode(',', $userchildids)) . ")"; |
2456
|
|
|
$sql .= " OR h.fk_validator IN (" . $this->db->sanitize(implode(',', $userchildids)) . "))"; |
2457
|
|
|
} |
2458
|
|
|
|
2459
|
|
|
$resql = $this->db->query($sql); |
2460
|
|
|
if ($resql) { |
2461
|
|
|
$langs->load("members"); |
2462
|
|
|
|
2463
|
|
|
$response = new WorkboardResponse(); |
2464
|
|
|
$response->warning_delay = $conf->holiday->approve->warning_delay / 60 / 60 / 24; |
2465
|
|
|
$response->label = $langs->trans("HolidaysToApprove"); |
2466
|
|
|
$response->labelShort = $langs->trans("ToApprove"); |
2467
|
|
|
$response->url = constant('BASE_URL') . '/holiday/list.php?search_status=2&mainmenu=hrm&leftmenu=holiday'; |
2468
|
|
|
$response->img = img_object('', "holiday"); |
2469
|
|
|
|
2470
|
|
|
while ($obj = $this->db->fetch_object($resql)) { |
2471
|
|
|
$response->nbtodo++; |
2472
|
|
|
|
2473
|
|
|
if ($this->db->jdate($obj->date_debut) < ($now - $conf->holiday->approve->warning_delay)) { |
2474
|
|
|
$response->nbtodolate++; |
2475
|
|
|
} |
2476
|
|
|
} |
2477
|
|
|
|
2478
|
|
|
return $response; |
2479
|
|
|
} else { |
2480
|
|
|
dol_print_error($this->db); |
2481
|
|
|
$this->error = $this->db->error(); |
2482
|
|
|
return -1; |
2483
|
|
|
} |
2484
|
|
|
} |
2485
|
|
|
/** |
2486
|
|
|
* Return clicable link of object (with eventually picto) |
2487
|
|
|
* |
2488
|
|
|
* @param string $option Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link) |
2489
|
|
|
* @param array $arraydata Label of holiday type (if known) |
2490
|
|
|
* @return string HTML Code for Kanban thumb. |
2491
|
|
|
*/ |
2492
|
|
|
public function getKanbanView($option = '', $arraydata = null) |
2493
|
|
|
{ |
2494
|
|
|
global $langs; |
2495
|
|
|
|
2496
|
|
|
$selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); |
2497
|
|
|
|
2498
|
|
|
$return = '<div class="box-flex-item box-flex-grow-zero">'; |
2499
|
|
|
$return .= '<div class="info-box info-box-sm">'; |
2500
|
|
|
$return .= '<span class="info-box-icon bg-infobox-action">'; |
2501
|
|
|
$return .= img_picto('', $this->picto); |
2502
|
|
|
$return .= '</span>'; |
2503
|
|
|
$return .= '<div class="info-box-content">'; |
2504
|
|
|
$return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . $arraydata['user']->getNomUrl(-1) . '</span>'; |
2505
|
|
|
if ($selected >= 0) { |
2506
|
|
|
$return .= '<input id="cb' . $this->id . '" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="' . $this->id . '"' . ($selected ? ' checked="checked"' : '') . '>'; |
2507
|
|
|
} |
2508
|
|
|
if (property_exists($this, 'fk_type')) { |
2509
|
|
|
$return .= '<br>'; |
2510
|
|
|
//$return .= '<span class="opacitymedium">'.$langs->trans("Type").'</span> : '; |
2511
|
|
|
$return .= '<div class="info_box-label tdoverflowmax100" title="' . dol_escape_htmltag($arraydata['labeltype']) . '">' . dol_escape_htmltag($arraydata['labeltype']) . '</div>'; |
2512
|
|
|
} |
2513
|
|
|
if (property_exists($this, 'date_debut') && property_exists($this, 'date_fin')) { |
2514
|
|
|
$return .= '<span class="info-box-label small">' . dol_print_date($this->date_debut, 'day') . '</span>'; |
2515
|
|
|
$return .= ' <span class="opacitymedium small">' . $langs->trans("To") . '</span> '; |
2516
|
|
|
$return .= '<span class="info-box-label small">' . dol_print_date($this->date_fin, 'day') . '</span>'; |
2517
|
|
|
if (!empty($arraydata['nbopenedday'])) { |
2518
|
|
|
$return .= ' (' . $arraydata['nbopenedday'] . ')'; |
2519
|
|
|
} |
2520
|
|
|
} |
2521
|
|
|
if (method_exists($this, 'getLibStatut')) { |
2522
|
|
|
$return .= '<div class="info-box-status">' . $this->getLibStatut(3) . '</div>'; |
2523
|
|
|
} |
2524
|
|
|
$return .= '</div>'; |
2525
|
|
|
$return .= '</div>'; |
2526
|
|
|
$return .= '</div>'; |
2527
|
|
|
return $return; |
2528
|
|
|
} |
2529
|
|
|
} |
2530
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.