dolibarr 19.0.3
recruitmentcandidature.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2020 Laurent Destailleur <eldy@users.sourceforge.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
24// Put here all includes required by your class file
25require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
26//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
27//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
28
33{
37 public $module = 'recruitment';
38
42 public $element = 'recruitmentcandidature';
43
47 public $table_element = 'recruitment_recruitmentcandidature';
48
53 public $ismultientitymanaged = 1;
54
58 public $isextrafieldmanaged = 1;
59
63 public $picto = 'recruitmentcandidature';
64
68 public $email_fields_no_propagate_in_actioncomm;
69
70
71 const STATUS_DRAFT = 0;
72 const STATUS_VALIDATED = 1;
73 //const STATUS_INTERVIEW_SCHEDULED = 2;
74 const STATUS_CONTRACT_PROPOSED = 3;
75 const STATUS_CONTRACT_SIGNED = 5;
76 const STATUS_CONTRACT_REFUSED = 6;
77 const STATUS_REFUSED = 8;
78 const STATUS_CANCELED = 9;
79
80
106 // BEGIN MODULEBUILDER PROPERTIES
110 public $fields = array(
111 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"),
112 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'position'=>5, 'notnull'=>1, 'default'=>'1', 'index'=>1),
113 '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'),
114 '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'),
115 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,),
116 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,),
117 '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'),
118 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2, 'csslist'=>'tdoverflowmax100'),
119 'lastname' => array('type'=>'varchar(128)', 'label'=>'Lastname', 'enabled'=>'1', 'position'=>20, 'notnull'=>0, 'visible'=>1, 'csslist'=>'tdoverflowmax150'),
120 'firstname' => array('type'=>'varchar(128)', 'label'=>'Firstname', 'enabled'=>'1', 'position'=>21, 'notnull'=>0, 'visible'=>1, 'csslist'=>'tdoverflowmax150'),
121 'email' => array('type'=>'email', 'label'=>'EMail', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'picto'=>'email', 'csslist'=>'tdoverflowmax150'),
122 'phone' => array('type'=>'phone', 'label'=>'Phone', 'enabled'=>'1', 'position'=>31, 'notnull'=>0, 'visible'=>1, 'picto'=>'phone', 'csslist'=>'tdoverflowmax150'),
123 'date_birth' => array('type'=>'date', 'label'=>'DateOfBirth', 'enabled'=>'1', 'position'=>70, 'visible'=>-1,),
124 'email_msgid' => array('type'=>'varchar(255)', 'label'=>'EmailMsgID', 'visible'=>-2, 'enabled'=>1, 'position'=>540, 'notnull'=>-1, 'help'=>'EmailMsgIDDesc'),
125 'email_date' => array('type'=>'datetime', 'label'=>'EmailDate', 'visible'=>-2, 'enabled'=>1, 'position'=>541),
126 //'fk_recruitment_origin' => array('type'=>'integer:CRecruitmentOrigin:recruitment/class/crecruitmentorigin.class.php', 'label'=>'Origin', 'enabled'=>'1', 'position'=>45, 'visible'=>1, 'index'=>1),
127 'remuneration_requested' => array('type'=>'integer', 'label'=>'RequestedRemuneration', 'enabled'=>'1', 'position'=>80, 'notnull'=>0, 'visible'=>-1,),
128 'remuneration_proposed' => array('type'=>'integer', 'label'=>'ProposedRemuneration', 'enabled'=>'1', 'position'=>81, 'notnull'=>0, 'visible'=>-1,),
129 'description' => array('type'=>'html', 'label'=>'Description', 'enabled'=>'1', 'position'=>300, 'notnull'=>0, 'visible'=>3, 'cssview'=>'wordbreak'),
130 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-4, 'csslist'=>'nowraponall'),
131 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2, 'csslist'=>'nowraponall'),
132 'fk_user' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'LinkedToDolibarrUser', 'enabled'=>'1', 'position'=>600, 'notnull'=>0, 'visible'=>-1, 'csslist'=>'tdoverflowmax100'),
133 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,),
134 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,),
135 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'default'=>0, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Received', '3'=>'ContractProposed', '5'=>'ContractSigned', '8'=>'Refused', '9'=>'Canceled')),
136 );
137 public $rowid;
138 public $entity;
139 public $ref;
140 public $fk_recruitmentjobposition;
141 public $description;
142 public $note_public;
143 public $note_private;
144 public $date_creation;
145 public $tms;
146 public $fk_user_creat;
147 public $fk_user_modif;
148 public $fk_user;
149 public $lastname;
150 public $firstname;
151 public $email;
152 public $phone;
153 public $date_birth;
154 public $email_msgid;
155 public $email_date;
156 public $remuneration_requested;
157 public $remuneration_proposed;
158 public $fk_recruitment_origin;
159 public $import_key;
160 public $model_pdf;
161 public $status;
162 // END MODULEBUILDER PROPERTIES
163
164
170 public function __construct(DoliDB $db)
171 {
172 global $conf, $langs;
173
174 $this->db = $db;
175
176 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
177 $this->fields['rowid']['visible'] = 0;
178 }
179 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
180 $this->fields['entity']['enabled'] = 0;
181 }
182
183 // Example to show how to set values of fields definition dynamically
184 /*if ($user->rights->recruitment->recruitmentcandidature->read) {
185 $this->fields['myfield']['visible'] = 1;
186 $this->fields['myfield']['noteditable'] = 0;
187 }*/
188
189 // Unset fields that are disabled
190 foreach ($this->fields as $key => $val) {
191 if (isset($val['enabled']) && empty($val['enabled'])) {
192 unset($this->fields[$key]);
193 }
194 }
195
196 // Translate some data of arrayofkeyval
197 if (is_object($langs)) {
198 foreach ($this->fields as $key => $val) {
199 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
200 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
201 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
202 }
203 }
204 }
205 }
206 }
207
215 public function create(User $user, $notrigger = false)
216 {
217 return $this->createCommon($user, $notrigger);
218 }
219
227 public function createFromClone(User $user, $fromid)
228 {
229 global $langs, $extrafields;
230 $error = 0;
231
232 dol_syslog(__METHOD__, LOG_DEBUG);
233
234 $object = new self($this->db);
235
236 $this->db->begin();
237
238 // Load source object
239 $result = $object->fetchCommon($fromid);
240 if ($result > 0 && !empty($object->table_element_line)) {
241 $object->fetchLines();
242 }
243
244 // get lines so they will be clone
245 //foreach($this->lines as $line)
246 // $line->fetch_optionals();
247
248 // Reset some properties
249 unset($object->id);
250 unset($object->fk_user_creat);
251 unset($object->import_key);
252
253 // Clear fields
254 if (property_exists($object, 'ref')) {
255 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
256 }
257 if (property_exists($object, 'label')) {
258 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
259 }
260 if (property_exists($object, 'status')) {
261 $object->status = self::STATUS_DRAFT;
262 }
263 if (property_exists($object, 'date_creation')) {
264 $object->date_creation = dol_now();
265 }
266 if (property_exists($object, 'date_modification')) {
267 $object->date_modification = null;
268 }
269
270 // ...
271 // Clear extrafields that are unique
272 if (is_array($object->array_options) && count($object->array_options) > 0) {
273 $extrafields->fetch_name_optionals_label($this->table_element);
274 foreach ($object->array_options as $key => $option) {
275 $shortkey = preg_replace('/options_/', '', $key);
276 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
277 //var_dump($key);
278 //var_dump($clonedObj->array_options[$key]); exit;
279 unset($object->array_options[$key]);
280 }
281 }
282 }
283
284 // Create clone
285 $object->context['createfromclone'] = 'createfromclone';
286 $result = $object->createCommon($user);
287 if ($result < 0) {
288 $error++;
289 $this->error = $object->error;
290 $this->errors = $object->errors;
291 }
292
293 if (!$error) {
294 // copy internal contacts
295 if ($this->copy_linked_contact($object, 'internal') < 0) {
296 $error++;
297 }
298 }
299
300 if (!$error) {
301 // copy external contacts if same company
302 if (property_exists($this, 'socid') && $this->socid == $object->socid) {
303 if ($this->copy_linked_contact($object, 'external') < 0) {
304 $error++;
305 }
306 }
307 }
308
309 unset($object->context['createfromclone']);
310
311 // End
312 if (!$error) {
313 $this->db->commit();
314 return $object;
315 } else {
316 $this->db->rollback();
317 return -1;
318 }
319 }
320
329 public function fetch($id, $ref = null, $email_msgid = '')
330 {
331 $morewhere = '';
332 if ($email_msgid) {
333 $morewhere = " AND email_msgid = '".$this->db->escape($email_msgid)."'";
334 }
335 $result = $this->fetchCommon($id, $ref, $morewhere);
336 if ($result > 0 && !empty($this->table_element_line)) {
337 $this->fetchLines();
338 }
339 return $result;
340 }
341
347 public function fetchLines()
348 {
349 $this->lines = array();
350
351 $result = $this->fetchLinesCommon();
352 return $result;
353 }
354
355
367 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
368 {
369 dol_syslog(__METHOD__, LOG_DEBUG);
370
371 $records = array();
372
373 $sql = 'SELECT ';
374 $sql .= $this->getFieldList();
375 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
376 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
377 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
378 } else {
379 $sql .= ' WHERE 1 = 1';
380 }
381 // Manage filter
382 $sqlwhere = array();
383 if (count($filter) > 0) {
384 foreach ($filter as $key => $value) {
385 if ($key == 't.rowid') {
386 $sqlwhere[] = $key." = ".((int) $value);
387 } elseif (array_key_exists($key, $this->fields) && in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) {
388 $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
389 } elseif ($key == 'customsql') {
390 $sqlwhere[] = $value;
391 } elseif (strpos($value, '%') === false) {
392 $sqlwhere[] = $key." IN (".$this->db->sanitize($this->db->escape($value)).")";
393 } else {
394 $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
395 }
396 }
397 }
398 if (count($sqlwhere) > 0) {
399 $sql .= ' AND ('.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere).')';
400 }
401
402 if (!empty($sortfield)) {
403 $sql .= $this->db->order($sortfield, $sortorder);
404 }
405 if (!empty($limit)) {
406 $sql .= $this->db->plimit($limit, $offset);
407 }
408
409 $resql = $this->db->query($sql);
410 if ($resql) {
411 $num = $this->db->num_rows($resql);
412 $i = 0;
413 while ($i < ($limit ? min($limit, $num) : $num)) {
414 $obj = $this->db->fetch_object($resql);
415
416 $record = new self($this->db);
417 $record->setVarsFromFetchObj($obj);
418
419 $records[$record->id] = $record;
420
421 $i++;
422 }
423 $this->db->free($resql);
424
425 return $records;
426 } else {
427 $this->errors[] = 'Error '.$this->db->lasterror();
428 dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
429
430 return -1;
431 }
432 }
433
441 public function update(User $user, $notrigger = false)
442 {
443 return $this->updateCommon($user, $notrigger);
444 }
445
453 public function delete(User $user, $notrigger = false)
454 {
455 return $this->deleteCommon($user, $notrigger);
456 //return $this->deleteCommon($user, $notrigger, 1);
457 }
458
467 public function deleteLine(User $user, $idline, $notrigger = false)
468 {
469 if ($this->status < 0) {
470 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
471 return -2;
472 }
473
474 return $this->deleteLineCommon($user, $idline, $notrigger);
475 }
476
477
485 public function validate($user, $notrigger = 0)
486 {
487 global $conf, $langs;
488
489 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
490
491 $error = 0;
492
493 // Protection
494 if ($this->status == self::STATUS_VALIDATED) {
495 dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
496 return 0;
497 }
498
499 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitmentcandidature->write))
500 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitmentcandidature->recruitmentcandidature_advance->validate))))
501 {
502 $this->error='NotEnoughPermissions';
503 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
504 return -1;
505 }*/
506
507 $now = dol_now();
508
509 $this->db->begin();
510
511 // Define new ref
512 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
513 $num = $this->getNextNumRef();
514 } else {
515 $num = $this->ref;
516 }
517 $this->newref = $num;
518
519 if (!empty($num)) {
520 // Validate
521 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
522 $sql .= " SET ref = '".$this->db->escape($num)."',";
523 $sql .= " status = ".self::STATUS_VALIDATED;
524 if (!empty($this->fields['date_validation'])) {
525 $sql .= ", date_validation = '".$this->db->idate($now)."',";
526 }
527 if (!empty($this->fields['fk_user_valid'])) {
528 $sql .= ", fk_user_valid = ".$user->id;
529 }
530 $sql .= " WHERE rowid = ".((int) $this->id);
531
532 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
533 $resql = $this->db->query($sql);
534 if (!$resql) {
535 dol_print_error($this->db);
536 $this->error = $this->db->lasterror();
537 $error++;
538 }
539
540 if (!$error && !$notrigger) {
541 // Call trigger
542 $result = $this->call_trigger('RECRUITMENTCANDIDATURE_VALIDATE', $user);
543 if ($result < 0) {
544 $error++;
545 }
546 // End call triggers
547 }
548 }
549
550 if (!$error) {
551 $this->oldref = $this->ref;
552
553 // Rename directory if dir was a temporary ref
554 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
555 // Now we rename also files into index
556 $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)."'";
557 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'recruitmentcandidature/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
558 $resql = $this->db->query($sql);
559 if (!$resql) {
560 $error++;
561 $this->error = $this->db->lasterror();
562 }
563 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'recruitmentcandidature/".$this->db->escape($this->newref)."'";
564 $sql .= " WHERE filepath = 'recruitmentcandidature/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
565 $resql = $this->db->query($sql);
566 if (!$resql) {
567 $error++;
568 $this->error = $this->db->lasterror();
569 }
570
571 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
572 $oldref = dol_sanitizeFileName($this->ref);
573 $newref = dol_sanitizeFileName($num);
574 $dirsource = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$oldref;
575 $dirdest = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref;
576 if (!$error && file_exists($dirsource)) {
577 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
578
579 if (@rename($dirsource, $dirdest)) {
580 dol_syslog("Rename ok");
581 // Rename docs starting with $oldref with $newref
582 $listoffiles = dol_dir_list($conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
583 foreach ($listoffiles as $fileentry) {
584 $dirsource = $fileentry['name'];
585 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
586 $dirsource = $fileentry['path'].'/'.$dirsource;
587 $dirdest = $fileentry['path'].'/'.$dirdest;
588 @rename($dirsource, $dirdest);
589 }
590 }
591 }
592 }
593 }
594
595 // Set new ref and current status
596 if (!$error) {
597 $this->ref = $num;
598 $this->status = self::STATUS_VALIDATED;
599 }
600
601 if (!$error) {
602 $this->db->commit();
603 return 1;
604 } else {
605 $this->db->rollback();
606 return -1;
607 }
608 }
609
610
618 public function setDraft($user, $notrigger = 0)
619 {
620 // Protection
621 if ($this->status <= self::STATUS_DRAFT) {
622 return 0;
623 }
624
625 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
626 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
627 {
628 $this->error='Permission denied';
629 return -1;
630 }*/
631
632 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'RECRUITMENTCANDIDATURE_UNVALIDATE');
633 }
634
642 public function cancel($user, $notrigger = 0)
643 {
644 // Protection
645 if ($this->status != self::STATUS_VALIDATED) {
646 return 0;
647 }
648
649 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
650 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
651 {
652 $this->error='Permission denied';
653 return -1;
654 }*/
655
656 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'RECRUITMENTCANDIDATURE_CLOSE');
657 }
658
666 public function reopen($user, $notrigger = 0)
667 {
668 // Protection
669 if ($this->status != self::STATUS_REFUSED && $this->status != self::STATUS_CANCELED && $this->status != self::STATUS_CONTRACT_REFUSED) {
670 return 0;
671 }
672
673 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
674 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
675 {
676 $this->error='Permission denied';
677 return -1;
678 }*/
679
680 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'RECRUITMENTCANDIDATURE_REOPEN');
681 }
682
692 public function getFullName($langs, $option = 0, $nameorder = -1, $maxlen = 0)
693 {
694 $lastname = $this->lastname;
695 $firstname = $this->firstname;
696 if (empty($lastname)) {
697 $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 : '')))));
698 }
699
700 $ret = '';
701
702 $ret .= dolGetFirstLastname($firstname, $lastname, $nameorder);
703
704 return dol_trunc($ret, $maxlen);
705 }
706
717 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
718 {
719 global $conf, $langs, $hookmanager;
720
721 if (!empty($conf->dol_no_mouse_hover)) {
722 $notooltip = 1; // Force disable tooltips
723 }
724
725 $result = '';
726
727 $label = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("RecruitmentCandidature").'</u>';
728 if (isset($this->status)) {
729 $label .= ' '.$this->getLibStatut(5);
730 }
731 $label .= '<br>';
732 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
733 $label .= '<br><b>'.$langs->trans('Email').':</b> '.$this->email;
734 $label .= '<br><b>'.$langs->trans('Name').':</b> '.$this->getFullName($langs);
735
736 $url = dol_buildpath('/recruitment/recruitmentcandidature_card.php', 1).'?id='.$this->id;
737
738 if ($option != 'nolink') {
739 // Add param to save lastsearch_values or not
740 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
741 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
742 $add_save_lastsearch_values = 1;
743 }
744 if ($add_save_lastsearch_values) {
745 $url .= '&save_lastsearch_values=1';
746 }
747 }
748
749 $linkclose = '';
750 if (empty($notooltip)) {
751 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
752 $label = $langs->trans("ShowRecruitmentCandidature");
753 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
754 }
755 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
756 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
757 } else {
758 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
759 }
760
761 $linkstart = '<a href="'.$url.'"';
762 $linkstart .= $linkclose.'>';
763 $linkend = '</a>';
764
765 $result .= $linkstart;
766
767 if (empty($this->showphoto_on_popup)) {
768 if ($withpicto) {
769 $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);
770 }
771 } else {
772 if ($withpicto) {
773 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
774
775 list($class, $module) = explode('@', $this->picto);
776 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
777 $filearray = dol_dir_list($upload_dir, "files");
778 $filename = $filearray[0]['name'];
779 if (!empty($filename)) {
780 $pospoint = strpos($filearray[0]['name'], '.');
781
782 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
783 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
784 $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>';
785 } else {
786 $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>';
787 }
788
789 $result .= '</div>';
790 } else {
791 $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);
792 }
793 }
794 }
795
796 if ($withpicto != 2) {
797 $result .= $this->ref;
798 }
799
800 $result .= $linkend;
801 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
802
803 global $action, $hookmanager;
804 $hookmanager->initHooks(array('recruitmentcandidaturedao'));
805 $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
806 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
807 if ($reshook > 0) {
808 $result = $hookmanager->resPrint;
809 } else {
810 $result .= $hookmanager->resPrint;
811 }
812
813 return $result;
814 }
815
822 public function getLibStatut($mode = 0)
823 {
824 return $this->LibStatut($this->status, $mode);
825 }
826
827 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
835 public function LibStatut($status, $mode = 0)
836 {
837 // phpcs:enable
838 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
839 global $langs;
840 //$langs->load("recruitment@recruitment");
841 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
842 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Received').' ('.$langs->transnoentitiesnoconv("InterviewToDo").')';
843 $this->labelStatus[self::STATUS_CONTRACT_PROPOSED] = $langs->transnoentitiesnoconv('ContractProposed');
844 $this->labelStatus[self::STATUS_CONTRACT_SIGNED] = $langs->transnoentitiesnoconv('ContractSigned');
845 $this->labelStatus[self::STATUS_CONTRACT_REFUSED] = $langs->transnoentitiesnoconv('ContractRefused');
846 $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('Refused');
847 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
848 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
849 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Received');
850 $this->labelStatusShort[self::STATUS_CONTRACT_PROPOSED] = $langs->transnoentitiesnoconv('ContractProposed');
851 $this->labelStatusShort[self::STATUS_CONTRACT_SIGNED] = $langs->transnoentitiesnoconv('ContractSigned');
852 $this->labelStatusShort[self::STATUS_CONTRACT_REFUSED] = $langs->transnoentitiesnoconv('ContractRefused');
853 $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('Refused');
854 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
855 }
856
857 $statusType = 'status'.$status;
858 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
859 if ($status == self::STATUS_CANCELED) {
860 $statusType = 'status9';
861 }
862 if ($status == self::STATUS_CONTRACT_PROPOSED) {
863 $statusType = 'status4';
864 }
865 if ($status == self::STATUS_CONTRACT_SIGNED) {
866 $statusType = 'status6';
867 }
868 if ($status == self::STATUS_REFUSED) {
869 $statusType = 'status10';
870 }
871
872 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
873 }
874
881 public function info($id)
882 {
883 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
884 $sql .= ' fk_user_creat, fk_user_modif';
885 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
886 $sql .= ' WHERE t.rowid = '.((int) $id);
887 $result = $this->db->query($sql);
888 if ($result) {
889 if ($this->db->num_rows($result)) {
890 $obj = $this->db->fetch_object($result);
891
892 $this->id = $obj->rowid;
893
894 $this->user_creation_id = $obj->fk_user_creat;
895 $this->user_modification_id = $obj->fk_user_modif;
896 $this->date_creation = $this->db->jdate($obj->datec);
897 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
898 }
899
900 $this->db->free($result);
901 } else {
902 dol_print_error($this->db);
903 }
904 }
905
912 public function initAsSpecimen()
913 {
914 $this->initAsSpecimenCommon();
915 }
916
922 public function getLinesArray()
923 {
924 $this->lines = array();
925
926 $objectline = new RecruitmentCandidatureLine($this->db);
927 $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_recruitmentcandidature = '.((int) $this->id)));
928
929 if (is_numeric($result)) {
930 $this->error = $objectline->error;
931 $this->errors = $objectline->errors;
932 return $result;
933 } else {
934 $this->lines = $result;
935 return $this->lines;
936 }
937 }
938
944 public function getNextNumRef()
945 {
946 global $langs, $conf;
947 $langs->load("recruitment@recruitment");
948
949 if (!getDolGlobalString('RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON')) {
950 $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON = 'mod_recruitmentcandidature_standard';
951 }
952
953 if (getDolGlobalString('RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON')) {
954 $mybool = false;
955
956 $file = getDolGlobalString('RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON') . ".php";
957 $classname = $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON;
958
959 // Include file with class
960 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
961 foreach ($dirmodels as $reldir) {
962 $dir = dol_buildpath($reldir."core/modules/recruitment/");
963
964 // Load file with numbering class (if found)
965 $mybool |= @include_once $dir.$file;
966 }
967
968 if ($mybool === false) {
969 dol_print_error('', "Failed to include file ".$file);
970 return '';
971 }
972
973 if (class_exists($classname)) {
974 $obj = new $classname();
975 $numref = $obj->getNextValue($this);
976
977 if ($numref != '' && $numref != '-1') {
978 return $numref;
979 } else {
980 $this->error = $obj->error;
981 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
982 return "";
983 }
984 } else {
985 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
986 return "";
987 }
988 } else {
989 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
990 return "";
991 }
992 }
993
1005 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1006 {
1007 global $conf, $langs;
1008
1009 $result = 0;
1010 $includedocgeneration = 0;
1011
1012 $langs->load("recruitment@recruitment");
1013
1014 if (!dol_strlen($modele)) {
1015 if (getDolGlobalString('RECRUITMENTCANDIDATURE_ADDON_PDF')) {
1016 $modele = $conf->global->RECRUITMENTCANDIDATURE_ADDON_PDF;
1017 } else {
1018 $modele = ''; // No default value. For job application, we allow to disable all PDF generation
1019 }
1020 }
1021
1022 $modelpath = "core/modules/recruitment/doc/";
1023
1024 if ($includedocgeneration && !empty($modele)) {
1025 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1026 }
1027
1028 return $result;
1029 }
1030
1038 public function doScheduledJob()
1039 {
1040 global $conf, $langs;
1041
1042 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1043
1044 $error = 0;
1045 $this->output = '';
1046 $this->error = '';
1047
1048 dol_syslog(__METHOD__, LOG_DEBUG);
1049
1050 $now = dol_now();
1051
1052 $this->db->begin();
1053
1054 // ...
1055
1056 $this->db->commit();
1057
1058 return $error;
1059 }
1060
1068 public function getKanbanView($option = '', $arraydata = null)
1069 {
1070 global $langs;
1071
1072 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1073
1074 $return = '<div class="box-flex-item box-flex-grow-zero">';
1075 $return .= '<div class="info-box info-box-sm">';
1076 $return .= '<span class="info-box-icon bg-infobox-action">';
1077 $return .= img_picto('', $this->picto);
1078 $return .= '</span>';
1079 $return .= '<div class="info-box-content">';
1080 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
1081 if ($selected >= 0) {
1082 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1083 }
1084 if (property_exists($this, 'fk_recruitmentjobposition')) {
1085 $return .= '<br>';
1086 //$return .= '<span class="opacitymedium">';
1087 //$return .= $langs->trans('Job').'</span> : ';
1088 $return .= '<span class="info-box-label">';
1089 $tmpjob = new RecruitmentJobPosition($this->db);
1090 $tmpjob->fetch($this->fk_recruitmentjobposition);
1091 //$return .= $this->fk_recruitmentjobposition;
1092 $return .= $tmpjob->label;
1093 $return .= '</span>';
1094 }
1095 if (property_exists($this, 'phone') && $this->phone) {
1096 $return .= '<br><span class="info-box-label opacitymedium small">'.img_picto('', 'phone').' '.$this->phone.'</span>';
1097 }
1098 if (property_exists($this, 'email') && $this->email) {
1099 $return .= '<br><span class="info-box-label opacitymedium small">'.img_picto('', 'email').' '.$this->email.'</span>';
1100 }
1101 if (method_exists($this, 'getLibStatut')) {
1102 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1103 }
1104 $return .= '</div>';
1105 $return .= '</div>';
1106 $return .= '</div>';
1107 return $return;
1108 }
1109}
1110
1111
1112require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1113
1118{
1119 // To complete with content of an object RecruitmentCandidatureLine
1120 // We should have a field rowid, fk_recruitmentcandidature and position
1121
1127 public function __construct(DoliDB $db)
1128 {
1129 $this->db = $db;
1130 }
1131}
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Definition security.php:604
$object ref
Definition info.php:79
Parent class of all other business classes (invoices, contracts, proposals, orders,...
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
createCommon(User $user, $notrigger=false)
Create object into database.
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
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.
updateCommon(User $user, $notrigger=false)
Update object into database.
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.
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.
create(User $user, $notrigger=false)
Create object into database.
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 optionaly 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.
update(User $user, $notrigger=false)
Update object into database.
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.
validate($user, $notrigger=0)
Validate object.
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
LibStatut($status, $mode=0)
Return the status.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $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.
info($id)
Load the info information in the object.
Class RecruitmentCandidatureLine.
Class for RecruitmentJobPosition.
Class to manage Dolibarr users.
dol_dir_list($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:62
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_now($mode='auto')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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_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:124