dolibarr 20.0.0
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';
28//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
29//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
30
35{
39 public $module = 'recruitment';
40
44 public $element = 'recruitmentcandidature';
45
49 public $table_element = 'recruitment_recruitmentcandidature';
50
54 public $picto = 'recruitmentcandidature';
55
59 public $email_fields_no_propagate_in_actioncomm;
60
61
62 const STATUS_DRAFT = 0;
63 const STATUS_VALIDATED = 1;
64 //const STATUS_INTERVIEW_SCHEDULED = 2;
65 const STATUS_CONTRACT_PROPOSED = 3;
66 const STATUS_CONTRACT_SIGNED = 5;
67 const STATUS_CONTRACT_REFUSED = 6;
68 const STATUS_REFUSED = 8;
69 const STATUS_CANCELED = 9;
70
71
97 // BEGIN MODULEBUILDER PROPERTIES
101 public $fields = array(
102 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'comment' => "Id"),
103 'entity' => array('type' => 'integer', 'label' => 'Entity', 'enabled' => 1, 'visible' => 0, 'position' => 5, 'notnull' => 1, 'default' => '1', 'index' => 1),
104 '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'),
105 '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'),
106 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 61, 'notnull' => 0, 'visible' => 0,),
107 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 62, 'notnull' => 0, 'visible' => 0,),
108 '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'),
109 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2, 'csslist' => 'tdoverflowmax100'),
110 'lastname' => array('type' => 'varchar(128)', 'label' => 'Lastname', 'enabled' => 1, 'position' => 20, 'notnull' => 0, 'visible' => 1, 'csslist' => 'tdoverflowmax150'),
111 'firstname' => array('type' => 'varchar(128)', 'label' => 'Firstname', 'enabled' => 1, 'position' => 21, 'notnull' => 0, 'visible' => 1, 'csslist' => 'tdoverflowmax150'),
112 'email' => array('type' => 'email', 'label' => 'EMail', 'enabled' => 1, 'position' => 30, 'notnull' => 1, 'visible' => 1, 'picto' => 'email', 'csslist' => 'tdoverflowmax150'),
113 'phone' => array('type' => 'phone', 'label' => 'Phone', 'enabled' => 1, 'position' => 31, 'notnull' => 0, 'visible' => 1, 'picto' => 'phone', 'csslist' => 'tdoverflowmax150'),
114 'date_birth' => array('type' => 'date', 'label' => 'DateOfBirth', 'enabled' => 1, 'position' => 70, 'visible' => -1,),
115 'email_msgid' => array('type' => 'varchar(255)', 'label' => 'EmailMsgID', 'visible' => -2, 'enabled' => 1, 'position' => 540, 'notnull' => -1, 'help' => 'EmailMsgIDDesc'),
116 'email_date' => array('type' => 'datetime', 'label' => 'EmailDate', 'visible' => -2, 'enabled' => 1, 'position' => 541),
117 //'fk_recruitment_origin' => array('type'=>'integer:CRecruitmentOrigin:recruitment/class/crecruitmentorigin.class.php', 'label'=>'Origin', 'enabled'=>'1', 'position'=>45, 'visible'=>1, 'index'=>1),
118 'remuneration_requested' => array('type' => 'integer', 'label' => 'RequestedRemuneration', 'enabled' => 1, 'position' => 80, 'notnull' => 0, 'visible' => -1,),
119 'remuneration_proposed' => array('type' => 'integer', 'label' => 'ProposedRemuneration', 'enabled' => 1, 'position' => 81, 'notnull' => 0, 'visible' => -1,),
120 'description' => array('type' => 'html', 'label' => 'Description', 'enabled' => 1, 'position' => 300, 'notnull' => 0, 'visible' => 3, 'cssview' => 'wordbreak'),
121 'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -4, 'csslist' => 'nowraponall'),
122 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2, 'csslist' => 'nowraponall'),
123 'fk_user' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'LinkedToDolibarrUser', 'enabled' => 1, 'position' => 600, 'notnull' => 0, 'visible' => -1, 'csslist' => 'tdoverflowmax100'),
124 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => -2,),
125 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'position' => 1010, 'notnull' => -1, 'visible' => 0,),
126 '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')),
127 );
128 public $rowid;
129 public $entity;
130 public $ref;
131 public $fk_recruitmentjobposition;
132 public $description;
133 public $note_public;
134 public $note_private;
135 public $date_creation;
136 public $fk_user_creat;
137 public $fk_user_modif;
138 public $fk_user;
139 public $lastname;
140 public $firstname;
141 public $email;
142 public $phone;
143 public $date_birth;
144 public $email_msgid;
145 public $email_date;
146 public $remuneration_requested;
147 public $remuneration_proposed;
148 public $fk_recruitment_origin;
149 public $import_key;
150 public $model_pdf;
151 public $status;
152 // END MODULEBUILDER PROPERTIES
153
154
160 public function __construct(DoliDB $db)
161 {
162 global $conf, $langs;
163
164 $this->db = $db;
165
166 $this->ismultientitymanaged = 1;
167 $this->isextrafieldmanaged = 1;
168
169 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
170 $this->fields['rowid']['visible'] = 0;
171 }
172 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
173 $this->fields['entity']['enabled'] = 0;
174 }
175
176 // Example to show how to set values of fields definition dynamically
177 /*if ($user->rights->recruitment->recruitmentcandidature->read) {
178 $this->fields['myfield']['visible'] = 1;
179 $this->fields['myfield']['noteditable'] = 0;
180 }*/
181
182 // Unset fields that are disabled
183 foreach ($this->fields as $key => $val) {
184 if (isset($val['enabled']) && empty($val['enabled'])) {
185 unset($this->fields[$key]);
186 }
187 }
188
189 // Translate some data of arrayofkeyval
190 if (is_object($langs)) {
191 foreach ($this->fields as $key => $val) {
192 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
193 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
194 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
195 }
196 }
197 }
198 }
199 }
200
208 public function create(User $user, $notrigger = 0)
209 {
210 return $this->createCommon($user, $notrigger);
211 }
212
220 public function createFromClone(User $user, $fromid)
221 {
222 global $langs, $extrafields;
223 $error = 0;
224
225 dol_syslog(__METHOD__, LOG_DEBUG);
226
227 $object = new self($this->db);
228
229 $this->db->begin();
230
231 // Load source object
232 $result = $object->fetchCommon($fromid);
233 if ($result > 0 && !empty($object->table_element_line)) {
234 $object->fetchLines();
235 }
236
237 // get lines so they will be clone
238 //foreach($this->lines as $line)
239 // $line->fetch_optionals();
240
241 // Reset some properties
242 unset($object->id);
243 unset($object->fk_user_creat);
244 unset($object->import_key);
245
246 // Clear fields
247 if (property_exists($object, 'ref')) {
248 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
249 }
250 if (property_exists($object, 'label')) {
251 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
252 }
253 if (property_exists($object, 'status')) {
254 $object->status = self::STATUS_DRAFT;
255 }
256 if (property_exists($object, 'date_creation')) {
257 $object->date_creation = dol_now();
258 }
259 if (property_exists($object, 'date_modification')) {
260 $object->date_modification = null;
261 }
262
263 // ...
264 // Clear extrafields that are unique
265 if (is_array($object->array_options) && count($object->array_options) > 0) {
266 $extrafields->fetch_name_optionals_label($this->table_element);
267 foreach ($object->array_options as $key => $option) {
268 $shortkey = preg_replace('/options_/', '', $key);
269 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
270 //var_dump($key);
271 //var_dump($clonedObj->array_options[$key]); exit;
272 unset($object->array_options[$key]);
273 }
274 }
275 }
276
277 // Create clone
278 $object->context['createfromclone'] = 'createfromclone';
279 $result = $object->createCommon($user);
280 if ($result < 0) {
281 $error++;
282 $this->error = $object->error;
283 $this->errors = $object->errors;
284 }
285
286 if (!$error) {
287 // copy internal contacts
288 if ($this->copy_linked_contact($object, 'internal') < 0) {
289 $error++;
290 }
291 }
292
293 if (!$error) {
294 // copy external contacts if same company
295 if (property_exists($this, 'socid') && $this->socid == $object->socid) {
296 if ($this->copy_linked_contact($object, 'external') < 0) {
297 $error++;
298 }
299 }
300 }
301
302 unset($object->context['createfromclone']);
303
304 // End
305 if (!$error) {
306 $this->db->commit();
307 return $object;
308 } else {
309 $this->db->rollback();
310 return -1;
311 }
312 }
313
322 public function fetch($id, $ref = null, $email_msgid = '')
323 {
324 $morewhere = '';
325 if ($email_msgid) {
326 $morewhere = " AND email_msgid = '".$this->db->escape($email_msgid)."'";
327 }
328 $result = $this->fetchCommon($id, $ref, $morewhere);
329 if ($result > 0 && !empty($this->table_element_line)) {
330 $this->fetchLines();
331 }
332 return $result;
333 }
334
340 public function fetchLines()
341 {
342 $this->lines = array();
343
344 $result = $this->fetchLinesCommon();
345 return $result;
346 }
347
348
361 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
362 {
363 dol_syslog(__METHOD__, LOG_DEBUG);
364
365 $records = array();
366
367 $sql = 'SELECT ';
368 $sql .= $this->getFieldList();
369 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
370 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
371 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
372 } else {
373 $sql .= ' WHERE 1 = 1';
374 }
375
376 // Manage filter
377 $errormessage = '';
378 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
379 if ($errormessage) {
380 $this->errors[] = $errormessage;
381 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
382 return -1;
383 }
384
385 if (!empty($sortfield)) {
386 $sql .= $this->db->order($sortfield, $sortorder);
387 }
388 if (!empty($limit)) {
389 $sql .= $this->db->plimit($limit, $offset);
390 }
391
392 $resql = $this->db->query($sql);
393 if ($resql) {
394 $num = $this->db->num_rows($resql);
395 $i = 0;
396 while ($i < ($limit ? min($limit, $num) : $num)) {
397 $obj = $this->db->fetch_object($resql);
398
399 $record = new self($this->db);
400 $record->setVarsFromFetchObj($obj);
401
402 $records[$record->id] = $record;
403
404 $i++;
405 }
406 $this->db->free($resql);
407
408 return $records;
409 } else {
410 $this->errors[] = 'Error '.$this->db->lasterror();
411 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
412
413 return -1;
414 }
415 }
416
424 public function update(User $user, $notrigger = 0)
425 {
426 return $this->updateCommon($user, $notrigger);
427 }
428
436 public function delete(User $user, $notrigger = 0)
437 {
438 return $this->deleteCommon($user, $notrigger);
439 //return $this->deleteCommon($user, $notrigger, 1);
440 }
441
450 public function deleteLine(User $user, $idline, $notrigger = 0)
451 {
452 if ($this->status < 0) {
453 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
454 return -2;
455 }
456
457 return $this->deleteLineCommon($user, $idline, $notrigger);
458 }
459
460
468 public function validate($user, $notrigger = 0)
469 {
470 global $conf, $langs;
471
472 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
473
474 $error = 0;
475
476 // Protection
477 if ($this->status == self::STATUS_VALIDATED) {
478 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
479 return 0;
480 }
481
482 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitmentcandidature->write))
483 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitmentcandidature->recruitmentcandidature_advance->validate))))
484 {
485 $this->error='NotEnoughPermissions';
486 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
487 return -1;
488 }*/
489
490 $now = dol_now();
491
492 $this->db->begin();
493
494 // Define new ref
495 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
496 $num = $this->getNextNumRef();
497 } else {
498 $num = $this->ref;
499 }
500 $this->newref = $num;
501
502 if (!empty($num)) {
503 // Validate
504 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
505 $sql .= " SET ref = '".$this->db->escape($num)."',";
506 $sql .= " status = ".self::STATUS_VALIDATED;
507 if (!empty($this->fields['date_validation'])) {
508 $sql .= ", date_validation = '".$this->db->idate($now)."',";
509 }
510 if (!empty($this->fields['fk_user_valid'])) {
511 $sql .= ", fk_user_valid = ".$user->id;
512 }
513 $sql .= " WHERE rowid = ".((int) $this->id);
514
515 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
516 $resql = $this->db->query($sql);
517 if (!$resql) {
518 dol_print_error($this->db);
519 $this->error = $this->db->lasterror();
520 $error++;
521 }
522
523 if (!$error && !$notrigger) {
524 // Call trigger
525 $result = $this->call_trigger('RECRUITMENTCANDIDATURE_VALIDATE', $user);
526 if ($result < 0) {
527 $error++;
528 }
529 // End call triggers
530 }
531 }
532
533 if (!$error) {
534 $this->oldref = $this->ref;
535
536 // Rename directory if dir was a temporary ref
537 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
538 // Now we rename also files into index
539 $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)."'";
540 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'recruitmentcandidature/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
541 $resql = $this->db->query($sql);
542 if (!$resql) {
543 $error++;
544 $this->error = $this->db->lasterror();
545 }
546 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'recruitmentcandidature/".$this->db->escape($this->newref)."'";
547 $sql .= " WHERE filepath = 'recruitmentcandidature/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
548 $resql = $this->db->query($sql);
549 if (!$resql) {
550 $error++;
551 $this->error = $this->db->lasterror();
552 }
553
554 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
555 $oldref = dol_sanitizeFileName($this->ref);
556 $newref = dol_sanitizeFileName($num);
557 $dirsource = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$oldref;
558 $dirdest = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref;
559 if (!$error && file_exists($dirsource)) {
560 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
561
562 if (@rename($dirsource, $dirdest)) {
563 dol_syslog("Rename ok");
564 // Rename docs starting with $oldref with $newref
565 $listoffiles = dol_dir_list($conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
566 foreach ($listoffiles as $fileentry) {
567 $dirsource = $fileentry['name'];
568 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
569 $dirsource = $fileentry['path'].'/'.$dirsource;
570 $dirdest = $fileentry['path'].'/'.$dirdest;
571 @rename($dirsource, $dirdest);
572 }
573 }
574 }
575 }
576 }
577
578 // Set new ref and current status
579 if (!$error) {
580 $this->ref = $num;
581 $this->status = self::STATUS_VALIDATED;
582 }
583
584 if (!$error) {
585 $this->db->commit();
586 return 1;
587 } else {
588 $this->db->rollback();
589 return -1;
590 }
591 }
592
593
601 public function setDraft($user, $notrigger = 0)
602 {
603 // Protection
604 if ($this->status <= self::STATUS_DRAFT) {
605 return 0;
606 }
607
608 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
609 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
610 {
611 $this->error='Permission denied';
612 return -1;
613 }*/
614
615 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'RECRUITMENTCANDIDATURE_UNVALIDATE');
616 }
617
625 public function cancel($user, $notrigger = 0)
626 {
627 // Protection
628 if ($this->status != self::STATUS_VALIDATED) {
629 return 0;
630 }
631
632 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
633 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
634 {
635 $this->error='Permission denied';
636 return -1;
637 }*/
638
639 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'RECRUITMENTCANDIDATURE_CLOSE');
640 }
641
649 public function reopen($user, $notrigger = 0)
650 {
651 // Protection
652 if ($this->status != self::STATUS_REFUSED && $this->status != self::STATUS_CANCELED && $this->status != self::STATUS_CONTRACT_REFUSED) {
653 return 0;
654 }
655
656 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
657 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
658 {
659 $this->error='Permission denied';
660 return -1;
661 }*/
662
663 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'RECRUITMENTCANDIDATURE_REOPEN');
664 }
665
675 public function getFullName($langs, $option = 0, $nameorder = -1, $maxlen = 0)
676 {
677 $lastname = $this->lastname;
678 $firstname = $this->firstname;
679 if (empty($lastname)) {
680 $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 : '')))));
681 }
682
683 $ret = '';
684
685 $ret .= dolGetFirstLastname($firstname, $lastname, $nameorder);
686
687 return dol_trunc($ret, $maxlen);
688 }
689
700 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
701 {
702 global $conf, $langs, $hookmanager;
703
704 if (!empty($conf->dol_no_mouse_hover)) {
705 $notooltip = 1; // Force disable tooltips
706 }
707
708 $result = '';
709
710 $label = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("RecruitmentCandidature").'</u>';
711 if (isset($this->status)) {
712 $label .= ' '.$this->getLibStatut(5);
713 }
714 $label .= '<br>';
715 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
716 $label .= '<br><b>'.$langs->trans('Email').':</b> '.$this->email;
717 $label .= '<br><b>'.$langs->trans('Name').':</b> '.$this->getFullName($langs);
718
719 $url = dol_buildpath('/recruitment/recruitmentcandidature_card.php', 1).'?id='.$this->id;
720
721 if ($option != 'nolink') {
722 // Add param to save lastsearch_values or not
723 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
724 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
725 $add_save_lastsearch_values = 1;
726 }
727 if ($add_save_lastsearch_values) {
728 $url .= '&save_lastsearch_values=1';
729 }
730 }
731
732 $linkclose = '';
733 if (empty($notooltip)) {
734 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
735 $label = $langs->trans("ShowRecruitmentCandidature");
736 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
737 }
738 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
739 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
740 } else {
741 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
742 }
743
744 $linkstart = '<a href="'.$url.'"';
745 $linkstart .= $linkclose.'>';
746 $linkend = '</a>';
747
748 $result .= $linkstart;
749
750 if (empty($this->showphoto_on_popup)) {
751 if ($withpicto) {
752 $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);
753 }
754 } else {
755 if ($withpicto) {
756 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
757
758 list($class, $module) = explode('@', $this->picto);
759 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
760 $filearray = dol_dir_list($upload_dir, "files");
761 $filename = $filearray[0]['name'];
762 if (!empty($filename)) {
763 $pospoint = strpos($filearray[0]['name'], '.');
764
765 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
766 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
767 $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>';
768 } else {
769 $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>';
770 }
771
772 $result .= '</div>';
773 } else {
774 $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);
775 }
776 }
777 }
778
779 if ($withpicto != 2) {
780 $result .= $this->ref;
781 }
782
783 $result .= $linkend;
784 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
785
786 global $action, $hookmanager;
787 $hookmanager->initHooks(array('recruitmentcandidaturedao'));
788 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
789 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
790 if ($reshook > 0) {
791 $result = $hookmanager->resPrint;
792 } else {
793 $result .= $hookmanager->resPrint;
794 }
795
796 return $result;
797 }
798
805 public function getLibStatut($mode = 0)
806 {
807 return $this->LibStatut($this->status, $mode);
808 }
809
810 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
818 public function LibStatut($status, $mode = 0)
819 {
820 // phpcs:enable
821 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
822 global $langs;
823 //$langs->load("recruitment@recruitment");
824 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
825 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Received').' ('.$langs->transnoentitiesnoconv("InterviewToDo").')';
826 $this->labelStatus[self::STATUS_CONTRACT_PROPOSED] = $langs->transnoentitiesnoconv('ContractProposed');
827 $this->labelStatus[self::STATUS_CONTRACT_SIGNED] = $langs->transnoentitiesnoconv('ContractSigned');
828 $this->labelStatus[self::STATUS_CONTRACT_REFUSED] = $langs->transnoentitiesnoconv('ContractRefused');
829 $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('Refused');
830 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
831 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
832 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Received');
833 $this->labelStatusShort[self::STATUS_CONTRACT_PROPOSED] = $langs->transnoentitiesnoconv('ContractProposed');
834 $this->labelStatusShort[self::STATUS_CONTRACT_SIGNED] = $langs->transnoentitiesnoconv('ContractSigned');
835 $this->labelStatusShort[self::STATUS_CONTRACT_REFUSED] = $langs->transnoentitiesnoconv('ContractRefused');
836 $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('Refused');
837 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
838 }
839
840 $statusType = 'status'.$status;
841 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
842 if ($status == self::STATUS_CANCELED) {
843 $statusType = 'status9';
844 }
845 if ($status == self::STATUS_CONTRACT_PROPOSED) {
846 $statusType = 'status4';
847 }
848 if ($status == self::STATUS_CONTRACT_SIGNED) {
849 $statusType = 'status6';
850 }
851 if ($status == self::STATUS_REFUSED) {
852 $statusType = 'status10';
853 }
854
855 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
856 }
857
864 public function info($id)
865 {
866 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
867 $sql .= ' fk_user_creat, fk_user_modif';
868 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
869 $sql .= ' WHERE t.rowid = '.((int) $id);
870 $result = $this->db->query($sql);
871 if ($result) {
872 if ($this->db->num_rows($result)) {
873 $obj = $this->db->fetch_object($result);
874
875 $this->id = $obj->rowid;
876
877 $this->user_creation_id = $obj->fk_user_creat;
878 $this->user_modification_id = $obj->fk_user_modif;
879 $this->date_creation = $this->db->jdate($obj->datec);
880 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
881 }
882
883 $this->db->free($result);
884 } else {
885 dol_print_error($this->db);
886 }
887 }
888
895 public function initAsSpecimen()
896 {
897 return $this->initAsSpecimenCommon();
898 }
899
905 public function getLinesArray()
906 {
907 $this->lines = array();
908
909 $objectline = new RecruitmentCandidatureLine($this->db);
910 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_recruitmentcandidature:=:'.((int) $this->id).')');
911
912 if (is_numeric($result)) {
913 $this->error = $objectline->error;
914 $this->errors = $objectline->errors;
915 return $result;
916 } else {
917 $this->lines = $result;
918 return $this->lines;
919 }
920 }
921
927 public function getNextNumRef()
928 {
929 global $langs, $conf;
930 $langs->load("recruitment@recruitment");
931
932 if (!getDolGlobalString('RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON')) {
933 $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON = 'mod_recruitmentcandidature_standard';
934 }
935
936 if (getDolGlobalString('RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON')) {
937 $mybool = false;
938
939 $file = getDolGlobalString('RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON') . ".php";
940 $classname = getDolGlobalString('RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON');
941
942 // Include file with class
943 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
944 foreach ($dirmodels as $reldir) {
945 $dir = dol_buildpath($reldir."core/modules/recruitment/");
946
947 // Load file with numbering class (if found)
948 $mybool = ((bool) @include_once $dir.$file) || $mybool;
949 }
950
951 if ($mybool === false) {
952 dol_print_error(null, "Failed to include file ".$file);
953 return '';
954 }
955
956 if (class_exists($classname)) {
957 $obj = new $classname();
958 $numref = $obj->getNextValue($this);
959
960 if ($numref != '' && $numref != '-1') {
961 return $numref;
962 } else {
963 $this->error = $obj->error;
964 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
965 return "";
966 }
967 } else {
968 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
969 return "";
970 }
971 } else {
972 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
973 return "";
974 }
975 }
976
988 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
989 {
990 global $conf, $langs;
991
992 $result = 0;
993 $includedocgeneration = 0;
994
995 $langs->load("recruitment@recruitment");
996
997 if (!dol_strlen($modele)) {
998 if (getDolGlobalString('RECRUITMENTCANDIDATURE_ADDON_PDF')) {
999 $modele = getDolGlobalString('RECRUITMENTCANDIDATURE_ADDON_PDF');
1000 } else {
1001 $modele = ''; // No default value. For job application, we allow to disable all PDF generation
1002 }
1003 }
1004
1005 $modelpath = "core/modules/recruitment/doc/";
1006
1007 if ($includedocgeneration && !empty($modele)) {
1008 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1009 }
1010
1011 return $result;
1012 }
1013
1021 public function doScheduledJob()
1022 {
1023 global $conf, $langs;
1024
1025 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1026
1027 $error = 0;
1028 $this->output = '';
1029 $this->error = '';
1030
1031 dol_syslog(__METHOD__, LOG_DEBUG);
1032
1033 $now = dol_now();
1034
1035 $this->db->begin();
1036
1037 // ...
1038
1039 $this->db->commit();
1040
1041 return $error;
1042 }
1043
1051 public function getKanbanView($option = '', $arraydata = null)
1052 {
1053 global $mysoc;
1054
1055 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1056
1057 $return = '<div class="box-flex-item box-flex-grow-zero">';
1058 $return .= '<div class="info-box info-box-sm">';
1059 $return .= '<span class="info-box-icon bg-infobox-action">';
1060 $return .= img_picto('', $this->picto);
1061 $return .= '</span>';
1062 $return .= '<div class="info-box-content">';
1063 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
1064 if ($selected >= 0) {
1065 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1066 }
1067 if (property_exists($this, 'fk_recruitmentjobposition')) {
1068 $return .= '<br>';
1069 //$return .= '<span class="opacitymedium">';
1070 //$return .= $langs->trans('Job').'</span> : ';
1071 $return .= '<div class="info-box-label tdoverflowmax150">';
1072 $tmpjob = new RecruitmentJobPosition($this->db);
1073 $tmpjob->fetch($this->fk_recruitmentjobposition);
1074 //$return .= $this->fk_recruitmentjobposition;
1075 $return .= dolPrintHTML($tmpjob->label);
1076 $return .= '</div>';
1077 }
1078 if (property_exists($this, 'phone') && $this->phone) {
1079 $return .= '<div class="info-box-label small">'.dol_print_phone($this->phone, $mysoc->country_code, 0, 0, 'AC_TEL', '&nbsp;', 'phone').'</div>';
1080 }
1081 if (property_exists($this, 'email') && $this->email) {
1082 $return .= '<div class="info-box-label small">'.dol_print_email($this->email, 0, 0, 1, 64, 1, 1).'</div>';
1083 }
1084 if (method_exists($this, 'getLibStatut')) {
1085 $return .= '<div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1086 }
1087 $return .= '</div>';
1088 $return .= '</div>';
1089 $return .= '</div>';
1090 return $return;
1091 }
1092}
1093
1094
1095require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1096
1101{
1102 // To complete with content of an object RecruitmentCandidatureLine
1103 // We should have a field rowid, fk_recruitmentcandidature and position
1104
1110 public function __construct(DoliDB $db)
1111 {
1112 $this->db = $db;
1113 }
1114}
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:636
$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.
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:142