dolibarr  19.0.0-dev
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
25 require_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', '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 (empty($conf->global->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  global $conf;
370 
371  dol_syslog(__METHOD__, LOG_DEBUG);
372 
373  $records = array();
374 
375  $sql = 'SELECT ';
376  $sql .= $this->getFieldList();
377  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
378  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
379  $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
380  } else {
381  $sql .= ' WHERE 1 = 1';
382  }
383  // Manage filter
384  $sqlwhere = array();
385  if (count($filter) > 0) {
386  foreach ($filter as $key => $value) {
387  if ($key == 't.rowid') {
388  $sqlwhere[] = $key." = ".((int) $value);
389  } elseif (in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) {
390  $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
391  } elseif ($key == 'customsql') {
392  $sqlwhere[] = $value;
393  } elseif (strpos($value, '%') === false) {
394  $sqlwhere[] = $key." IN (".$this->db->sanitize($this->db->escape($value)).")";
395  } else {
396  $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
397  }
398  }
399  }
400  if (count($sqlwhere) > 0) {
401  $sql .= ' AND ('.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere).')';
402  }
403 
404  if (!empty($sortfield)) {
405  $sql .= $this->db->order($sortfield, $sortorder);
406  }
407  if (!empty($limit)) {
408  $sql .= $this->db->plimit($limit, $offset);
409  }
410 
411  $resql = $this->db->query($sql);
412  if ($resql) {
413  $num = $this->db->num_rows($resql);
414  $i = 0;
415  while ($i < ($limit ? min($limit, $num) : $num)) {
416  $obj = $this->db->fetch_object($resql);
417 
418  $record = new self($this->db);
419  $record->setVarsFromFetchObj($obj);
420 
421  $records[$record->id] = $record;
422 
423  $i++;
424  }
425  $this->db->free($resql);
426 
427  return $records;
428  } else {
429  $this->errors[] = 'Error '.$this->db->lasterror();
430  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
431 
432  return -1;
433  }
434  }
435 
443  public function update(User $user, $notrigger = false)
444  {
445  return $this->updateCommon($user, $notrigger);
446  }
447 
455  public function delete(User $user, $notrigger = false)
456  {
457  return $this->deleteCommon($user, $notrigger);
458  //return $this->deleteCommon($user, $notrigger, 1);
459  }
460 
469  public function deleteLine(User $user, $idline, $notrigger = false)
470  {
471  if ($this->status < 0) {
472  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
473  return -2;
474  }
475 
476  return $this->deleteLineCommon($user, $idline, $notrigger);
477  }
478 
479 
487  public function validate($user, $notrigger = 0)
488  {
489  global $conf, $langs;
490 
491  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
492 
493  $error = 0;
494 
495  // Protection
496  if ($this->status == self::STATUS_VALIDATED) {
497  dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
498  return 0;
499  }
500 
501  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitmentcandidature->write))
502  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitmentcandidature->recruitmentcandidature_advance->validate))))
503  {
504  $this->error='NotEnoughPermissions';
505  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
506  return -1;
507  }*/
508 
509  $now = dol_now();
510 
511  $this->db->begin();
512 
513  // Define new ref
514  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
515  $num = $this->getNextNumRef();
516  } else {
517  $num = $this->ref;
518  }
519  $this->newref = $num;
520 
521  if (!empty($num)) {
522  // Validate
523  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
524  $sql .= " SET ref = '".$this->db->escape($num)."',";
525  $sql .= " status = ".self::STATUS_VALIDATED;
526  if (!empty($this->fields['date_validation'])) {
527  $sql .= ", date_validation = '".$this->db->idate($now)."',";
528  }
529  if (!empty($this->fields['fk_user_valid'])) {
530  $sql .= ", fk_user_valid = ".$user->id;
531  }
532  $sql .= " WHERE rowid = ".((int) $this->id);
533 
534  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
535  $resql = $this->db->query($sql);
536  if (!$resql) {
537  dol_print_error($this->db);
538  $this->error = $this->db->lasterror();
539  $error++;
540  }
541 
542  if (!$error && !$notrigger) {
543  // Call trigger
544  $result = $this->call_trigger('RECRUITMENTCANDIDATURE_VALIDATE', $user);
545  if ($result < 0) {
546  $error++;
547  }
548  // End call triggers
549  }
550  }
551 
552  if (!$error) {
553  $this->oldref = $this->ref;
554 
555  // Rename directory if dir was a temporary ref
556  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
557  // Now we rename also files into index
558  $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)."'";
559  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'recruitmentcandidature/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
560  $resql = $this->db->query($sql);
561  if (!$resql) {
562  $error++; $this->error = $this->db->lasterror();
563  }
564 
565  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
566  $oldref = dol_sanitizeFileName($this->ref);
567  $newref = dol_sanitizeFileName($num);
568  $dirsource = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$oldref;
569  $dirdest = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref;
570  if (!$error && file_exists($dirsource)) {
571  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
572 
573  if (@rename($dirsource, $dirdest)) {
574  dol_syslog("Rename ok");
575  // Rename docs starting with $oldref with $newref
576  $listoffiles = dol_dir_list($conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
577  foreach ($listoffiles as $fileentry) {
578  $dirsource = $fileentry['name'];
579  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
580  $dirsource = $fileentry['path'].'/'.$dirsource;
581  $dirdest = $fileentry['path'].'/'.$dirdest;
582  @rename($dirsource, $dirdest);
583  }
584  }
585  }
586  }
587  }
588 
589  // Set new ref and current status
590  if (!$error) {
591  $this->ref = $num;
592  $this->status = self::STATUS_VALIDATED;
593  }
594 
595  if (!$error) {
596  $this->db->commit();
597  return 1;
598  } else {
599  $this->db->rollback();
600  return -1;
601  }
602  }
603 
604 
612  public function setDraft($user, $notrigger = 0)
613  {
614  // Protection
615  if ($this->status <= self::STATUS_DRAFT) {
616  return 0;
617  }
618 
619  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
620  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
621  {
622  $this->error='Permission denied';
623  return -1;
624  }*/
625 
626  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'RECRUITMENTCANDIDATURE_UNVALIDATE');
627  }
628 
636  public function cancel($user, $notrigger = 0)
637  {
638  // Protection
639  if ($this->status != self::STATUS_VALIDATED) {
640  return 0;
641  }
642 
643  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
644  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
645  {
646  $this->error='Permission denied';
647  return -1;
648  }*/
649 
650  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'RECRUITMENTCANDIDATURE_CLOSE');
651  }
652 
660  public function reopen($user, $notrigger = 0)
661  {
662  // Protection
663  if ($this->status != self::STATUS_REFUSED && $this->status != self::STATUS_CANCELED && $this->status != self::STATUS_CONTRACT_REFUSED) {
664  return 0;
665  }
666 
667  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
668  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
669  {
670  $this->error='Permission denied';
671  return -1;
672  }*/
673 
674  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'RECRUITMENTCANDIDATURE_REOPEN');
675  }
676 
686  public function getFullName($langs, $option = 0, $nameorder = -1, $maxlen = 0)
687  {
688  $lastname = $this->lastname;
689  $firstname = $this->firstname;
690  if (empty($lastname)) {
691  $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 : '')))));
692  }
693 
694  $ret = '';
695 
696  $ret .= dolGetFirstLastname($firstname, $lastname, $nameorder);
697 
698  return dol_trunc($ret, $maxlen);
699  }
700 
711  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
712  {
713  global $conf, $langs, $hookmanager;
714 
715  if (!empty($conf->dol_no_mouse_hover)) {
716  $notooltip = 1; // Force disable tooltips
717  }
718 
719  $result = '';
720 
721  $label = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("RecruitmentCandidature").'</u>';
722  if (isset($this->status)) {
723  $label .= ' '.$this->getLibStatut(5);
724  }
725  $label .= '<br>';
726  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
727  $label .= '<br><b>'.$langs->trans('Email').':</b> '.$this->email;
728  $label .= '<br><b>'.$langs->trans('Name').':</b> '.$this->getFullName($langs);
729 
730  $url = dol_buildpath('/recruitment/recruitmentcandidature_card.php', 1).'?id='.$this->id;
731 
732  if ($option != 'nolink') {
733  // Add param to save lastsearch_values or not
734  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
735  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
736  $add_save_lastsearch_values = 1;
737  }
738  if ($add_save_lastsearch_values) {
739  $url .= '&save_lastsearch_values=1';
740  }
741  }
742 
743  $linkclose = '';
744  if (empty($notooltip)) {
745  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
746  $label = $langs->trans("ShowRecruitmentCandidature");
747  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
748  }
749  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
750  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
751  } else {
752  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
753  }
754 
755  $linkstart = '<a href="'.$url.'"';
756  $linkstart .= $linkclose.'>';
757  $linkend = '</a>';
758 
759  $result .= $linkstart;
760 
761  if (empty($this->showphoto_on_popup)) {
762  if ($withpicto) {
763  $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);
764  }
765  } else {
766  if ($withpicto) {
767  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
768 
769  list($class, $module) = explode('@', $this->picto);
770  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
771  $filearray = dol_dir_list($upload_dir, "files");
772  $filename = $filearray[0]['name'];
773  if (!empty($filename)) {
774  $pospoint = strpos($filearray[0]['name'], '.');
775 
776  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
777  if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
778  $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>';
779  } else {
780  $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>';
781  }
782 
783  $result .= '</div>';
784  } else {
785  $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);
786  }
787  }
788  }
789 
790  if ($withpicto != 2) {
791  $result .= $this->ref;
792  }
793 
794  $result .= $linkend;
795  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
796 
797  global $action, $hookmanager;
798  $hookmanager->initHooks(array('recruitmentcandidaturedao'));
799  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
800  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
801  if ($reshook > 0) {
802  $result = $hookmanager->resPrint;
803  } else {
804  $result .= $hookmanager->resPrint;
805  }
806 
807  return $result;
808  }
809 
816  public function getLibStatut($mode = 0)
817  {
818  return $this->LibStatut($this->status, $mode);
819  }
820 
821  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
829  public function LibStatut($status, $mode = 0)
830  {
831  // phpcs:enable
832  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
833  global $langs;
834  //$langs->load("recruitment@recruitment");
835  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
836  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Received').' ('.$langs->transnoentitiesnoconv("InterviewToDo").')';
837  $this->labelStatus[self::STATUS_CONTRACT_PROPOSED] = $langs->transnoentitiesnoconv('ContractProposed');
838  $this->labelStatus[self::STATUS_CONTRACT_SIGNED] = $langs->transnoentitiesnoconv('ContractSigned');
839  $this->labelStatus[self::STATUS_CONTRACT_REFUSED] = $langs->transnoentitiesnoconv('ContractRefused');
840  $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('Refused');
841  $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
842  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
843  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Received');
844  $this->labelStatusShort[self::STATUS_CONTRACT_PROPOSED] = $langs->transnoentitiesnoconv('ContractProposed');
845  $this->labelStatusShort[self::STATUS_CONTRACT_SIGNED] = $langs->transnoentitiesnoconv('ContractSigned');
846  $this->labelStatusShort[self::STATUS_CONTRACT_REFUSED] = $langs->transnoentitiesnoconv('ContractRefused');
847  $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('Refused');
848  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
849  }
850 
851  $statusType = 'status'.$status;
852  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
853  if ($status == self::STATUS_CANCELED) {
854  $statusType = 'status9';
855  }
856  if ($status == self::STATUS_CONTRACT_PROPOSED) {
857  $statusType = 'status4';
858  }
859  if ($status == self::STATUS_CONTRACT_SIGNED) {
860  $statusType = 'status6';
861  }
862  if ($status == self::STATUS_REFUSED) {
863  $statusType = 'status10';
864  }
865 
866  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
867  }
868 
875  public function info($id)
876  {
877  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
878  $sql .= ' fk_user_creat, fk_user_modif';
879  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
880  $sql .= ' WHERE t.rowid = '.((int) $id);
881  $result = $this->db->query($sql);
882  if ($result) {
883  if ($this->db->num_rows($result)) {
884  $obj = $this->db->fetch_object($result);
885  $this->id = $obj->rowid;
886 
887  $this->user_creation_id = $obj->fk_user_creat;
888  $this->user_modification_id = $obj->fk_user_modif;
889  $this->date_creation = $this->db->jdate($obj->datec);
890  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
891  }
892 
893  $this->db->free($result);
894  } else {
895  dol_print_error($this->db);
896  }
897  }
898 
905  public function initAsSpecimen()
906  {
907  $this->initAsSpecimenCommon();
908  }
909 
915  public function getLinesArray()
916  {
917  $this->lines = array();
918 
919  $objectline = new RecruitmentCandidatureLine($this->db);
920  $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_recruitmentcandidature = '.((int) $this->id)));
921 
922  if (is_numeric($result)) {
923  $this->error = $objectline->error;
924  $this->errors = $objectline->errors;
925  return $result;
926  } else {
927  $this->lines = $result;
928  return $this->lines;
929  }
930  }
931 
937  public function getNextNumRef()
938  {
939  global $langs, $conf;
940  $langs->load("recruitment@recruitment");
941 
942  if (empty($conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON)) {
943  $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON = 'mod_recruitmentcandidature_standard';
944  }
945 
946  if (!empty($conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON)) {
947  $mybool = false;
948 
949  $file = $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON.".php";
950  $classname = $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON;
951 
952  // Include file with class
953  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
954  foreach ($dirmodels as $reldir) {
955  $dir = dol_buildpath($reldir."core/modules/recruitment/");
956 
957  // Load file with numbering class (if found)
958  $mybool |= @include_once $dir.$file;
959  }
960 
961  if ($mybool === false) {
962  dol_print_error('', "Failed to include file ".$file);
963  return '';
964  }
965 
966  if (class_exists($classname)) {
967  $obj = new $classname();
968  $numref = $obj->getNextValue($this);
969 
970  if ($numref != '' && $numref != '-1') {
971  return $numref;
972  } else {
973  $this->error = $obj->error;
974  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
975  return "";
976  }
977  } else {
978  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
979  return "";
980  }
981  } else {
982  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
983  return "";
984  }
985  }
986 
998  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
999  {
1000  global $conf, $langs;
1001 
1002  $result = 0;
1003  $includedocgeneration = 0;
1004 
1005  $langs->load("recruitment@recruitment");
1006 
1007  if (!dol_strlen($modele)) {
1008  if (!empty($conf->global->RECRUITMENTCANDIDATURE_ADDON_PDF)) {
1009  $modele = $conf->global->RECRUITMENTCANDIDATURE_ADDON_PDF;
1010  } else {
1011  $modele = ''; // No default value. For job application, we allow to disable all PDF generation
1012  }
1013  }
1014 
1015  $modelpath = "core/modules/recruitment/doc/";
1016 
1017  if ($includedocgeneration && !empty($modele)) {
1018  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1019  }
1020 
1021  return $result;
1022  }
1023 
1031  public function doScheduledJob()
1032  {
1033  global $conf, $langs;
1034 
1035  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1036 
1037  $error = 0;
1038  $this->output = '';
1039  $this->error = '';
1040 
1041  dol_syslog(__METHOD__, LOG_DEBUG);
1042 
1043  $now = dol_now();
1044 
1045  $this->db->begin();
1046 
1047  // ...
1048 
1049  $this->db->commit();
1050 
1051  return $error;
1052  }
1053 
1061  public function getKanbanView($option = '', $arraydata = null)
1062  {
1063  global $langs;
1064 
1065  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1066 
1067  $return = '<div class="box-flex-item box-flex-grow-zero">';
1068  $return .= '<div class="info-box info-box-sm">';
1069  $return .= '<span class="info-box-icon bg-infobox-action">';
1070  $return .= img_picto('', $this->picto);
1071  $return .= '</span>';
1072  $return .= '<div class="info-box-content">';
1073  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
1074  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1075  if (property_exists($this, 'fk_recruitmentjobposition')) {
1076  $return .= '<br><span class="opacitymedium">'.$langs->trans('Job').'</span> : <span class="info-box-label">'.$this->fk_recruitmentjobposition.'</span>';
1077  }
1078  if (property_exists($this, 'phone')) {
1079  $return .= '<br><span class="opacitymedium">'.$langs->trans("phone").'</span> : <span class="info-box-label">'.$this->phone.'</span>';
1080  }
1081  if (method_exists($this, 'getLibStatut')) {
1082  $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).'</div>';
1083  }
1084  $return .= '</div>';
1085  $return .= '</div>';
1086  $return .= '</div>';
1087  return $return;
1088  }
1089 }
1090 
1091 
1092 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1093 
1098 {
1099  // To complete with content of an object RecruitmentCandidatureLine
1100  // We should have a field rowid, fk_recruitmentcandidature and position
1101 
1107  public function __construct(DoliDB $db)
1108  {
1109  $this->db = $db;
1110  }
1111 }
$object ref
Definition: info.php:78
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.
getFieldList($alias='')
Function to concat keys of fields.
fetchCommon($id, $ref=null, $morewhere='')
Load object in memory from the database.
createCommon(User $user, $notrigger=false)
Create object into database.
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in 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.
updateCommon(User $user, $notrigger=false)
Update object into database.
fetchLinesCommon($morewhere='')
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.
__construct(DoliDB $db)
Constructor.
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 to manage Dolibarr users.
Definition: user.class.php:48
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
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.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
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.
isModEnabled($module)
Is Dolibarr module enabled.
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:123