dolibarr 20.0.2
recruitmentcandidature.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2020 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
4 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
26// Put here all includes required by your class file
27require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
28require_once DOL_DOCUMENT_ROOT.'/core/class/commonpeople.class.php';
29
34{
35 use CommonPeople;
36
40 public $module = 'recruitment';
41
45 public $element = 'recruitmentcandidature';
46
50 public $table_element = 'recruitment_recruitmentcandidature';
51
55 public $picto = 'recruitmentcandidature';
56
60 public $email_fields_no_propagate_in_actioncomm;
61
62
63 const STATUS_DRAFT = 0;
64 const STATUS_VALIDATED = 1;
65 //const STATUS_INTERVIEW_SCHEDULED = 2;
66 const STATUS_CONTRACT_PROPOSED = 3;
67 const STATUS_CONTRACT_SIGNED = 5;
68 const STATUS_CONTRACT_REFUSED = 6;
69 const STATUS_REFUSED = 8;
70 const STATUS_CANCELED = 9;
71
72
98 // BEGIN MODULEBUILDER PROPERTIES
102 public $fields = array(
103 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'comment' => "Id"),
104 'entity' => array('type' => 'integer', 'label' => 'Entity', 'enabled' => 1, 'visible' => 0, 'position' => 5, 'notnull' => 1, 'default' => '1', 'index' => 1),
105 'ref' => array('type' => 'varchar(128)', 'label' => 'Ref', 'enabled' => 1, 'position' => 10, 'notnull' => 1, 'visible' => 4, 'noteditable' => 1, 'default' => '(PROV)', 'index' => 1, 'searchall' => 1, 'showoncombobox' => 1, 'comment' => "Reference of candidature", 'csslist' => 'nowraponall'),
106 'fk_recruitmentjobposition' => array('type' => 'integer:RecruitmentJobPosition:recruitment/class/recruitmentjobposition.class.php:0:(t.status:=:1)', 'label' => 'Job', 'enabled' => 1, 'position' => 15, 'notnull' => 0, 'visible' => 1, 'index' => 1, 'picto' => 'recruitmentjobposition', 'css' => 'minwidth300 maxwidth500 widthcentpercentminusx', 'csslist' => 'minwidth100 nowraponall'),
107 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 61, 'notnull' => 0, 'visible' => 0,),
108 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 62, 'notnull' => 0, 'visible' => 0,),
109 'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'position' => 510, 'notnull' => 1, 'visible' => -2, 'foreignkey' => 'user.rowid', 'csslist' => 'tdoverflowmax100'),
110 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2, 'csslist' => 'tdoverflowmax100'),
111 'lastname' => array('type' => 'varchar(128)', 'label' => 'Lastname', 'enabled' => 1, 'position' => 20, 'notnull' => 0, 'visible' => 1, 'csslist' => 'tdoverflowmax150'),
112 'firstname' => array('type' => 'varchar(128)', 'label' => 'Firstname', 'enabled' => 1, 'position' => 21, 'notnull' => 0, 'visible' => 1, 'csslist' => 'tdoverflowmax150'),
113 'email' => array('type' => 'email', 'label' => 'EMail', 'enabled' => 1, 'position' => 30, 'notnull' => 1, 'visible' => 1, 'picto' => 'email', 'csslist' => 'tdoverflowmax150'),
114 'phone' => array('type' => 'phone', 'label' => 'Phone', 'enabled' => 1, 'position' => 31, 'notnull' => 0, 'visible' => 1, 'picto' => 'phone', 'csslist' => 'tdoverflowmax150'),
115 'date_birth' => array('type' => 'date', 'label' => 'DateOfBirth', 'enabled' => 1, 'position' => 70, 'visible' => -1,),
116 'email_msgid' => array('type' => 'varchar(255)', 'label' => 'EmailMsgID', 'visible' => -2, 'enabled' => 1, 'position' => 540, 'notnull' => -1, 'help' => 'EmailMsgIDDesc'),
117 'email_date' => array('type' => 'datetime', 'label' => 'EmailDate', 'visible' => -2, 'enabled' => 1, 'position' => 541),
118 //'fk_recruitment_origin' => array('type'=>'integer:CRecruitmentOrigin:recruitment/class/crecruitmentorigin.class.php', 'label'=>'Origin', 'enabled'=>'1', 'position'=>45, 'visible'=>1, 'index'=>1),
119 'remuneration_requested' => array('type' => 'integer', 'label' => 'RequestedRemuneration', 'enabled' => 1, 'position' => 80, 'notnull' => 0, 'visible' => -1,),
120 'remuneration_proposed' => array('type' => 'integer', 'label' => 'ProposedRemuneration', 'enabled' => 1, 'position' => 81, 'notnull' => 0, 'visible' => -1,),
121 'description' => array('type' => 'html', 'label' => 'Description', 'enabled' => 1, 'position' => 300, 'notnull' => 0, 'visible' => 3, 'cssview' => 'wordbreak'),
122 'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -4, 'csslist' => 'nowraponall'),
123 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2, 'csslist' => 'nowraponall'),
124 'fk_user' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'LinkedToDolibarrUser', 'enabled' => 1, 'position' => 600, 'notnull' => 0, 'visible' => -1, 'csslist' => 'tdoverflowmax100'),
125 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => -2,),
126 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'position' => 1010, 'notnull' => -1, 'visible' => 0,),
127 'status' => array('type' => 'smallint', 'label' => 'Status', 'enabled' => 1, 'position' => 1000, 'notnull' => 1, 'visible' => 2, 'index' => 1, 'default' => '0', 'arrayofkeyval' => array('0' => 'Draft', '1' => 'Received', '3' => 'ContractProposed', '5' => 'ContractSigned', '8' => 'Refused', '9' => 'Canceled')),
128 );
129 public $rowid;
130 public $entity;
131 public $ref;
132 public $fk_recruitmentjobposition;
133 public $description;
134 public $note_public;
135 public $note_private;
136 public $date_creation;
137 public $fk_user_creat;
138 public $fk_user_modif;
139 public $fk_user;
140 public $lastname;
141 public $firstname;
142 public $email;
143 public $phone;
144 public $date_birth;
145 public $email_msgid;
146 public $email_date;
147 public $remuneration_requested;
148 public $remuneration_proposed;
149 public $fk_recruitment_origin;
150 public $import_key;
151 public $model_pdf;
152 public $status;
153 // END MODULEBUILDER PROPERTIES
154
155
161 public function __construct(DoliDB $db)
162 {
163 global $conf, $langs;
164
165 $this->db = $db;
166
167 $this->ismultientitymanaged = 1;
168 $this->isextrafieldmanaged = 1;
169
170 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
171 $this->fields['rowid']['visible'] = 0;
172 }
173 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
174 $this->fields['entity']['enabled'] = 0;
175 }
176
177 // Example to show how to set values of fields definition dynamically
178 /*if ($user->rights->recruitment->recruitmentcandidature->read) {
179 $this->fields['myfield']['visible'] = 1;
180 $this->fields['myfield']['noteditable'] = 0;
181 }*/
182
183 // Unset fields that are disabled
184 foreach ($this->fields as $key => $val) {
185 if (isset($val['enabled']) && empty($val['enabled'])) {
186 unset($this->fields[$key]);
187 }
188 }
189
190 // Translate some data of arrayofkeyval
191 if (is_object($langs)) {
192 foreach ($this->fields as $key => $val) {
193 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
194 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
195 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
196 }
197 }
198 }
199 }
200 }
201
209 public function create(User $user, $notrigger = 0)
210 {
211 return $this->createCommon($user, $notrigger);
212 }
213
221 public function createFromClone(User $user, $fromid)
222 {
223 global $langs, $extrafields;
224 $error = 0;
225
226 dol_syslog(__METHOD__, LOG_DEBUG);
227
228 $object = new self($this->db);
229
230 $this->db->begin();
231
232 // Load source object
233 $result = $object->fetchCommon($fromid);
234 if ($result > 0 && !empty($object->table_element_line)) {
235 $object->fetchLines();
236 }
237
238 // get lines so they will be clone
239 //foreach($this->lines as $line)
240 // $line->fetch_optionals();
241
242 // Reset some properties
243 unset($object->id);
244 unset($object->fk_user_creat);
245 unset($object->import_key);
246
247 // Clear fields
248 if (property_exists($object, 'ref')) {
249 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
250 }
251 if (property_exists($object, 'label')) {
252 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
253 }
254 if (property_exists($object, 'status')) {
255 $object->status = self::STATUS_DRAFT;
256 }
257 if (property_exists($object, 'date_creation')) {
258 $object->date_creation = dol_now();
259 }
260 if (property_exists($object, 'date_modification')) {
261 $object->date_modification = null;
262 }
263
264 // ...
265 // Clear extrafields that are unique
266 if (is_array($object->array_options) && count($object->array_options) > 0) {
267 $extrafields->fetch_name_optionals_label($this->table_element);
268 foreach ($object->array_options as $key => $option) {
269 $shortkey = preg_replace('/options_/', '', $key);
270 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
271 //var_dump($key);
272 //var_dump($clonedObj->array_options[$key]); exit;
273 unset($object->array_options[$key]);
274 }
275 }
276 }
277
278 // Create clone
279 $object->context['createfromclone'] = 'createfromclone';
280 $result = $object->createCommon($user);
281 if ($result < 0) {
282 $error++;
283 $this->error = $object->error;
284 $this->errors = $object->errors;
285 }
286
287 if (!$error) {
288 // copy internal contacts
289 if ($this->copy_linked_contact($object, 'internal') < 0) {
290 $error++;
291 }
292 }
293
294 if (!$error) {
295 // copy external contacts if same company
296 if (property_exists($this, 'socid') && $this->socid == $object->socid) {
297 if ($this->copy_linked_contact($object, 'external') < 0) {
298 $error++;
299 }
300 }
301 }
302
303 unset($object->context['createfromclone']);
304
305 // End
306 if (!$error) {
307 $this->db->commit();
308 return $object;
309 } else {
310 $this->db->rollback();
311 return -1;
312 }
313 }
314
323 public function fetch($id, $ref = null, $email_msgid = '')
324 {
325 $morewhere = '';
326 if ($email_msgid) {
327 $morewhere = " AND email_msgid = '".$this->db->escape($email_msgid)."'";
328 }
329 $result = $this->fetchCommon($id, $ref, $morewhere);
330 if ($result > 0 && !empty($this->table_element_line)) {
331 $this->fetchLines();
332 }
333 return $result;
334 }
335
341 public function fetchLines()
342 {
343 $this->lines = array();
344
345 $result = $this->fetchLinesCommon();
346 return $result;
347 }
348
349
362 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
363 {
364 dol_syslog(__METHOD__, LOG_DEBUG);
365
366 $records = array();
367
368 $sql = 'SELECT ';
369 $sql .= $this->getFieldList();
370 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
371 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
372 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
373 } else {
374 $sql .= ' WHERE 1 = 1';
375 }
376
377 // Manage filter
378 $errormessage = '';
379 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
380 if ($errormessage) {
381 $this->errors[] = $errormessage;
382 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
383 return -1;
384 }
385
386 if (!empty($sortfield)) {
387 $sql .= $this->db->order($sortfield, $sortorder);
388 }
389 if (!empty($limit)) {
390 $sql .= $this->db->plimit($limit, $offset);
391 }
392
393 $resql = $this->db->query($sql);
394 if ($resql) {
395 $num = $this->db->num_rows($resql);
396 $i = 0;
397 while ($i < ($limit ? min($limit, $num) : $num)) {
398 $obj = $this->db->fetch_object($resql);
399
400 $record = new self($this->db);
401 $record->setVarsFromFetchObj($obj);
402
403 $records[$record->id] = $record;
404
405 $i++;
406 }
407 $this->db->free($resql);
408
409 return $records;
410 } else {
411 $this->errors[] = 'Error '.$this->db->lasterror();
412 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
413
414 return -1;
415 }
416 }
417
425 public function update(User $user, $notrigger = 0)
426 {
427 return $this->updateCommon($user, $notrigger);
428 }
429
437 public function delete(User $user, $notrigger = 0)
438 {
439 return $this->deleteCommon($user, $notrigger);
440 //return $this->deleteCommon($user, $notrigger, 1);
441 }
442
451 public function deleteLine(User $user, $idline, $notrigger = 0)
452 {
453 if ($this->status < 0) {
454 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
455 return -2;
456 }
457
458 return $this->deleteLineCommon($user, $idline, $notrigger);
459 }
460
461
469 public function validate($user, $notrigger = 0)
470 {
471 global $conf, $langs;
472
473 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
474
475 $error = 0;
476
477 // Protection
478 if ($this->status == self::STATUS_VALIDATED) {
479 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
480 return 0;
481 }
482
483 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitmentcandidature->write))
484 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitmentcandidature->recruitmentcandidature_advance->validate))))
485 {
486 $this->error='NotEnoughPermissions';
487 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
488 return -1;
489 }*/
490
491 $now = dol_now();
492
493 $this->db->begin();
494
495 // Define new ref
496 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
497 $num = $this->getNextNumRef();
498 } else {
499 $num = $this->ref;
500 }
501 $this->newref = $num;
502
503 if (!empty($num)) {
504 // Validate
505 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
506 $sql .= " SET ref = '".$this->db->escape($num)."',";
507 $sql .= " status = ".self::STATUS_VALIDATED;
508 if (!empty($this->fields['date_validation'])) {
509 $sql .= ", date_validation = '".$this->db->idate($now)."',";
510 }
511 if (!empty($this->fields['fk_user_valid'])) {
512 $sql .= ", fk_user_valid = ".$user->id;
513 }
514 $sql .= " WHERE rowid = ".((int) $this->id);
515
516 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
517 $resql = $this->db->query($sql);
518 if (!$resql) {
519 dol_print_error($this->db);
520 $this->error = $this->db->lasterror();
521 $error++;
522 }
523
524 if (!$error && !$notrigger) {
525 // Call trigger
526 $result = $this->call_trigger('RECRUITMENTCANDIDATURE_VALIDATE', $user);
527 if ($result < 0) {
528 $error++;
529 }
530 // End call triggers
531 }
532 }
533
534 if (!$error) {
535 $this->oldref = $this->ref;
536
537 // Rename directory if dir was a temporary ref
538 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
539 // Now we rename also files into index
540 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'recruitmentcandidature/".$this->db->escape($this->newref)."'";
541 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'recruitmentcandidature/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
542 $resql = $this->db->query($sql);
543 if (!$resql) {
544 $error++;
545 $this->error = $this->db->lasterror();
546 }
547 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'recruitmentcandidature/".$this->db->escape($this->newref)."'";
548 $sql .= " WHERE filepath = 'recruitmentcandidature/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
549 $resql = $this->db->query($sql);
550 if (!$resql) {
551 $error++;
552 $this->error = $this->db->lasterror();
553 }
554
555 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
556 $oldref = dol_sanitizeFileName($this->ref);
557 $newref = dol_sanitizeFileName($num);
558 $dirsource = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$oldref;
559 $dirdest = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref;
560 if (!$error && file_exists($dirsource)) {
561 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
562
563 if (@rename($dirsource, $dirdest)) {
564 dol_syslog("Rename ok");
565 // Rename docs starting with $oldref with $newref
566 $listoffiles = dol_dir_list($conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
567 foreach ($listoffiles as $fileentry) {
568 $dirsource = $fileentry['name'];
569 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
570 $dirsource = $fileentry['path'].'/'.$dirsource;
571 $dirdest = $fileentry['path'].'/'.$dirdest;
572 @rename($dirsource, $dirdest);
573 }
574 }
575 }
576 }
577 }
578
579 // Set new ref and current status
580 if (!$error) {
581 $this->ref = $num;
582 $this->status = self::STATUS_VALIDATED;
583 }
584
585 if (!$error) {
586 $this->db->commit();
587 return 1;
588 } else {
589 $this->db->rollback();
590 return -1;
591 }
592 }
593
594
602 public function setDraft($user, $notrigger = 0)
603 {
604 // Protection
605 if ($this->status <= self::STATUS_DRAFT) {
606 return 0;
607 }
608
609 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
610 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
611 {
612 $this->error='Permission denied';
613 return -1;
614 }*/
615
616 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'RECRUITMENTCANDIDATURE_UNVALIDATE');
617 }
618
626 public function cancel($user, $notrigger = 0)
627 {
628 // Protection
629 if ($this->status != self::STATUS_VALIDATED) {
630 return 0;
631 }
632
633 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
634 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
635 {
636 $this->error='Permission denied';
637 return -1;
638 }*/
639
640 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'RECRUITMENTCANDIDATURE_CLOSE');
641 }
642
650 public function reopen($user, $notrigger = 0)
651 {
652 // Protection
653 if ($this->status != self::STATUS_REFUSED && $this->status != self::STATUS_CANCELED && $this->status != self::STATUS_CONTRACT_REFUSED) {
654 return 0;
655 }
656
657 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
658 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
659 {
660 $this->error='Permission denied';
661 return -1;
662 }*/
663
664 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'RECRUITMENTCANDIDATURE_REOPEN');
665 }
666
676 public function getFullName($langs, $option = 0, $nameorder = -1, $maxlen = 0)
677 {
678 $lastname = $this->lastname;
679 $firstname = $this->firstname;
680 if (empty($lastname)) {
681 $lastname = (isset($this->lastname) ? $this->lastname : (isset($this->name) ? $this->name : (isset($this->nom) ? $this->nom : (isset($this->societe) ? $this->societe : (isset($this->company) ? $this->company : '')))));
682 }
683
684 $ret = '';
685
686 $ret .= dolGetFirstLastname($firstname, $lastname, $nameorder);
687
688 return dol_trunc($ret, $maxlen);
689 }
690
701 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
702 {
703 global $conf, $langs, $hookmanager;
704
705 if (!empty($conf->dol_no_mouse_hover)) {
706 $notooltip = 1; // Force disable tooltips
707 }
708
709 $result = '';
710
711 $label = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("RecruitmentCandidature").'</u>';
712 if (isset($this->status)) {
713 $label .= ' '.$this->getLibStatut(5);
714 }
715 $label .= '<br>';
716 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
717 $label .= '<br><b>'.$langs->trans('Email').':</b> '.$this->email;
718 $label .= '<br><b>'.$langs->trans('Name').':</b> '.$this->getFullName($langs);
719
720 $url = dol_buildpath('/recruitment/recruitmentcandidature_card.php', 1).'?id='.$this->id;
721
722 if ($option != 'nolink') {
723 // Add param to save lastsearch_values or not
724 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
725 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
726 $add_save_lastsearch_values = 1;
727 }
728 if ($add_save_lastsearch_values) {
729 $url .= '&save_lastsearch_values=1';
730 }
731 }
732
733 $linkclose = '';
734 if (empty($notooltip)) {
735 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
736 $label = $langs->trans("ShowRecruitmentCandidature");
737 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
738 }
739 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
740 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
741 } else {
742 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
743 }
744
745 $linkstart = '<a href="'.$url.'"';
746 $linkstart .= $linkclose.'>';
747 $linkend = '</a>';
748
749 $result .= $linkstart;
750
751 if (empty($this->showphoto_on_popup)) {
752 if ($withpicto) {
753 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
754 }
755 } else {
756 if ($withpicto) {
757 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
758
759 list($class, $module) = explode('@', $this->picto);
760 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
761 $filearray = dol_dir_list($upload_dir, "files");
762 $filename = $filearray[0]['name'];
763 if (!empty($filename)) {
764 $pospoint = strpos($filearray[0]['name'], '.');
765
766 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
767 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
768 $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref"><img class="photo'.$module.'" alt="No photo" border="0" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$module.'&entity='.$conf->entity.'&file='.urlencode($pathtophoto).'"></div></div>';
769 } else {
770 $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photouserphoto userphoto" alt="No photo" border="0" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$module.'&entity='.$conf->entity.'&file='.urlencode($pathtophoto).'"></div>';
771 }
772
773 $result .= '</div>';
774 } else {
775 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
776 }
777 }
778 }
779
780 if ($withpicto != 2) {
781 $result .= $this->ref;
782 }
783
784 $result .= $linkend;
785 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
786
787 global $action, $hookmanager;
788 $hookmanager->initHooks(array('recruitmentcandidaturedao'));
789 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
790 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
791 if ($reshook > 0) {
792 $result = $hookmanager->resPrint;
793 } else {
794 $result .= $hookmanager->resPrint;
795 }
796
797 return $result;
798 }
799
806 public function getLibStatut($mode = 0)
807 {
808 return $this->LibStatut($this->status, $mode);
809 }
810
811 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
819 public function LibStatut($status, $mode = 0)
820 {
821 // phpcs:enable
822 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
823 global $langs;
824 //$langs->load("recruitment@recruitment");
825 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
826 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Received').' ('.$langs->transnoentitiesnoconv("InterviewToDo").')';
827 $this->labelStatus[self::STATUS_CONTRACT_PROPOSED] = $langs->transnoentitiesnoconv('ContractProposed');
828 $this->labelStatus[self::STATUS_CONTRACT_SIGNED] = $langs->transnoentitiesnoconv('ContractSigned');
829 $this->labelStatus[self::STATUS_CONTRACT_REFUSED] = $langs->transnoentitiesnoconv('ContractRefused');
830 $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('Refused');
831 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
832 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
833 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Received');
834 $this->labelStatusShort[self::STATUS_CONTRACT_PROPOSED] = $langs->transnoentitiesnoconv('ContractProposed');
835 $this->labelStatusShort[self::STATUS_CONTRACT_SIGNED] = $langs->transnoentitiesnoconv('ContractSigned');
836 $this->labelStatusShort[self::STATUS_CONTRACT_REFUSED] = $langs->transnoentitiesnoconv('ContractRefused');
837 $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('Refused');
838 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
839 }
840
841 $statusType = 'status'.$status;
842 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
843 if ($status == self::STATUS_CANCELED) {
844 $statusType = 'status9';
845 }
846 if ($status == self::STATUS_CONTRACT_PROPOSED) {
847 $statusType = 'status4';
848 }
849 if ($status == self::STATUS_CONTRACT_SIGNED) {
850 $statusType = 'status6';
851 }
852 if ($status == self::STATUS_REFUSED) {
853 $statusType = 'status10';
854 }
855
856 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
857 }
858
865 public function info($id)
866 {
867 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
868 $sql .= ' fk_user_creat, fk_user_modif';
869 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
870 $sql .= ' WHERE t.rowid = '.((int) $id);
871 $result = $this->db->query($sql);
872 if ($result) {
873 if ($this->db->num_rows($result)) {
874 $obj = $this->db->fetch_object($result);
875
876 $this->id = $obj->rowid;
877
878 $this->user_creation_id = $obj->fk_user_creat;
879 $this->user_modification_id = $obj->fk_user_modif;
880 $this->date_creation = $this->db->jdate($obj->datec);
881 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
882 }
883
884 $this->db->free($result);
885 } else {
886 dol_print_error($this->db);
887 }
888 }
889
896 public function initAsSpecimen()
897 {
898 return $this->initAsSpecimenCommon();
899 }
900
906 public function getLinesArray()
907 {
908 $this->lines = array();
909
910 $objectline = new RecruitmentCandidatureLine($this->db);
911 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_recruitmentcandidature:=:'.((int) $this->id).')');
912
913 if (is_numeric($result)) {
914 $this->error = $objectline->error;
915 $this->errors = $objectline->errors;
916 return $result;
917 } else {
918 $this->lines = $result;
919 return $this->lines;
920 }
921 }
922
928 public function getNextNumRef()
929 {
930 global $langs, $conf;
931 $langs->load("recruitment@recruitment");
932
933 if (!getDolGlobalString('RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON')) {
934 $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON = 'mod_recruitmentcandidature_standard';
935 }
936
937 if (getDolGlobalString('RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON')) {
938 $mybool = false;
939
940 $file = getDolGlobalString('RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON') . ".php";
941 $classname = getDolGlobalString('RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON');
942
943 // Include file with class
944 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
945 foreach ($dirmodels as $reldir) {
946 $dir = dol_buildpath($reldir."core/modules/recruitment/");
947
948 // Load file with numbering class (if found)
949 $mybool = ((bool) @include_once $dir.$file) || $mybool;
950 }
951
952 if ($mybool === false) {
953 dol_print_error(null, "Failed to include file ".$file);
954 return '';
955 }
956
957 if (class_exists($classname)) {
958 $obj = new $classname();
959 $numref = $obj->getNextValue($this);
960
961 if ($numref != '' && $numref != '-1') {
962 return $numref;
963 } else {
964 $this->error = $obj->error;
965 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
966 return "";
967 }
968 } else {
969 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
970 return "";
971 }
972 } else {
973 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
974 return "";
975 }
976 }
977
989 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
990 {
991 global $conf, $langs;
992
993 $result = 0;
994 $includedocgeneration = 0;
995
996 $langs->load("recruitment@recruitment");
997
998 if (!dol_strlen($modele)) {
999 if (getDolGlobalString('RECRUITMENTCANDIDATURE_ADDON_PDF')) {
1000 $modele = getDolGlobalString('RECRUITMENTCANDIDATURE_ADDON_PDF');
1001 } else {
1002 $modele = ''; // No default value. For job application, we allow to disable all PDF generation
1003 }
1004 }
1005
1006 $modelpath = "core/modules/recruitment/doc/";
1007
1008 if ($includedocgeneration && !empty($modele)) {
1009 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1010 }
1011
1012 return $result;
1013 }
1014
1022 public function doScheduledJob()
1023 {
1024 global $conf, $langs;
1025
1026 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1027
1028 $error = 0;
1029 $this->output = '';
1030 $this->error = '';
1031
1032 dol_syslog(__METHOD__, LOG_DEBUG);
1033
1034 $now = dol_now();
1035
1036 $this->db->begin();
1037
1038 // ...
1039
1040 $this->db->commit();
1041
1042 return $error;
1043 }
1044
1052 public function getKanbanView($option = '', $arraydata = null)
1053 {
1054 global $mysoc;
1055
1056 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1057
1058 $return = '<div class="box-flex-item box-flex-grow-zero">';
1059 $return .= '<div class="info-box info-box-sm">';
1060 $return .= '<span class="info-box-icon bg-infobox-action">';
1061 $return .= img_picto('', $this->picto);
1062 $return .= '</span>';
1063 $return .= '<div class="info-box-content">';
1064 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
1065 if ($selected >= 0) {
1066 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1067 }
1068 if (property_exists($this, 'fk_recruitmentjobposition')) {
1069 $return .= '<br>';
1070 //$return .= '<span class="opacitymedium">';
1071 //$return .= $langs->trans('Job').'</span> : ';
1072 $return .= '<div class="info-box-label tdoverflowmax150">';
1073 $tmpjob = new RecruitmentJobPosition($this->db);
1074 $tmpjob->fetch($this->fk_recruitmentjobposition);
1075 //$return .= $this->fk_recruitmentjobposition;
1076 $return .= dolPrintHTML($tmpjob->label);
1077 $return .= '</div>';
1078 }
1079 if (property_exists($this, 'phone') && $this->phone) {
1080 $return .= '<div class="info-box-label small">'.dol_print_phone($this->phone, $mysoc->country_code, 0, 0, 'AC_TEL', '&nbsp;', 'phone').'</div>';
1081 }
1082 if (property_exists($this, 'email') && $this->email) {
1083 $return .= '<div class="info-box-label small">'.dol_print_email($this->email, 0, 0, 1, 64, 1, 1).'</div>';
1084 }
1085 if (method_exists($this, 'getLibStatut')) {
1086 $return .= '<div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1087 }
1088 $return .= '</div>';
1089 $return .= '</div>';
1090 $return .= '</div>';
1091 return $return;
1092 }
1093}
1094
1095
1096require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1097
1102{
1103 // To complete with content of an object RecruitmentCandidatureLine
1104 // We should have a field rowid, fk_recruitmentcandidature and position
1105
1111 public function __construct(DoliDB $db)
1112 {
1113 $this->db = $db;
1114 }
1115}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition security.php:637
$object ref
Definition info.php:79
Parent class of all other business classes (invoices, contracts, proposals, orders,...
deleteLineCommon(User $user, $idline, $notrigger=0)
Delete a line of object in database.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
createCommon(User $user, $notrigger=0)
Create object in the database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
updateCommon(User $user, $notrigger=0)
Update object into database.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
fetchLinesCommon($morewhere='', $noextrafields=0)
Load object in memory from the database.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
deleteCommon(User $user, $notrigger=0, $forcechilddeletion=0)
Delete object in database.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
Class for RecruitmentCandidature.
getLinesArray()
Create an array of lines.
createFromClone(User $user, $fromid)
Clone an object into another one.
cancel($user, $notrigger=0)
Set cancel status.
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionally the picto)
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
reopen($user, $notrigger=0)
Set back to validated status.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
getLibStatut($mode=0)
Return label of the status.
fetch($id, $ref=null, $email_msgid='')
Load object in memory from the database.
fetchLines()
Load object lines in memory from the database.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
update(User $user, $notrigger=0)
Update object into database.
validate($user, $notrigger=0)
Validate object.
deleteLine(User $user, $idline, $notrigger=0)
Delete a line of object in database.
LibStatut($status, $mode=0)
Return the status.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load list of objects in memory from the database.
getFullName($langs, $option=0, $nameorder=-1, $maxlen=0)
Return full name ('name+' '+lastname)
setDraft($user, $notrigger=0)
Set draft status.
create(User $user, $notrigger=0)
Create object into database.
info($id)
Load the info information in the object.
Class RecruitmentCandidatureLine.
Class for RecruitmentJobPosition.
Class to manage Dolibarr users.
trait CommonPeople
Support class for thirdparties, contacts, members, users or resources.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:63
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dolPrintHTML($s, $allowiframe=0)
Return a string (that can be on several lines) ready to be output on a HTML page.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dol_now($mode='auto')
Return date for now.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140