dolibarr  18.0.6
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: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 (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  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'recruitmentcandidature/".$this->db->escape($this->newref)."'";
565  $sql .= " WHERE filepath = 'recruitmentcandidature/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
566  $resql = $this->db->query($sql);
567  if (!$resql) {
568  $error++; $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 && 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 (!empty($conf->global->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 (empty($conf->global->{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  $this->id = $obj->rowid;
892 
893  $this->user_creation_id = $obj->fk_user_creat;
894  $this->user_modification_id = $obj->fk_user_modif;
895  $this->date_creation = $this->db->jdate($obj->datec);
896  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
897  }
898 
899  $this->db->free($result);
900  } else {
901  dol_print_error($this->db);
902  }
903  }
904 
911  public function initAsSpecimen()
912  {
913  $this->initAsSpecimenCommon();
914  }
915 
921  public function getLinesArray()
922  {
923  $this->lines = array();
924 
925  $objectline = new RecruitmentCandidatureLine($this->db);
926  $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_recruitmentcandidature = '.((int) $this->id)));
927 
928  if (is_numeric($result)) {
929  $this->error = $objectline->error;
930  $this->errors = $objectline->errors;
931  return $result;
932  } else {
933  $this->lines = $result;
934  return $this->lines;
935  }
936  }
937 
943  public function getNextNumRef()
944  {
945  global $langs, $conf;
946  $langs->load("recruitment@recruitment");
947 
948  if (empty($conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON)) {
949  $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON = 'mod_recruitmentcandidature_standard';
950  }
951 
952  if (!empty($conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON)) {
953  $mybool = false;
954 
955  $file = $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON.".php";
956  $classname = $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON;
957 
958  // Include file with class
959  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
960  foreach ($dirmodels as $reldir) {
961  $dir = dol_buildpath($reldir."core/modules/recruitment/");
962 
963  // Load file with numbering class (if found)
964  $mybool |= @include_once $dir.$file;
965  }
966 
967  if ($mybool === false) {
968  dol_print_error('', "Failed to include file ".$file);
969  return '';
970  }
971 
972  if (class_exists($classname)) {
973  $obj = new $classname();
974  $numref = $obj->getNextValue($this);
975 
976  if ($numref != '' && $numref != '-1') {
977  return $numref;
978  } else {
979  $this->error = $obj->error;
980  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
981  return "";
982  }
983  } else {
984  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
985  return "";
986  }
987  } else {
988  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
989  return "";
990  }
991  }
992 
1004  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1005  {
1006  global $conf, $langs;
1007 
1008  $result = 0;
1009  $includedocgeneration = 0;
1010 
1011  $langs->load("recruitment@recruitment");
1012 
1013  if (!dol_strlen($modele)) {
1014  if (!empty($conf->global->RECRUITMENTCANDIDATURE_ADDON_PDF)) {
1015  $modele = $conf->global->RECRUITMENTCANDIDATURE_ADDON_PDF;
1016  } else {
1017  $modele = ''; // No default value. For job application, we allow to disable all PDF generation
1018  }
1019  }
1020 
1021  $modelpath = "core/modules/recruitment/doc/";
1022 
1023  if ($includedocgeneration && !empty($modele)) {
1024  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1025  }
1026 
1027  return $result;
1028  }
1029 
1037  public function doScheduledJob()
1038  {
1039  global $conf, $langs;
1040 
1041  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1042 
1043  $error = 0;
1044  $this->output = '';
1045  $this->error = '';
1046 
1047  dol_syslog(__METHOD__, LOG_DEBUG);
1048 
1049  $now = dol_now();
1050 
1051  $this->db->begin();
1052 
1053  // ...
1054 
1055  $this->db->commit();
1056 
1057  return $error;
1058  }
1059 
1067  public function getKanbanView($option = '', $arraydata = null)
1068  {
1069  global $langs;
1070 
1071  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1072 
1073  $return = '<div class="box-flex-item box-flex-grow-zero">';
1074  $return .= '<div class="info-box info-box-sm">';
1075  $return .= '<span class="info-box-icon bg-infobox-action">';
1076  $return .= img_picto('', $this->picto);
1077  $return .= '</span>';
1078  $return .= '<div class="info-box-content">';
1079  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
1080  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1081  if (property_exists($this, 'fk_recruitmentjobposition')) {
1082  $return .= '<br><span class="opacitymedium">'.$langs->trans('Job').'</span> : <span class="info-box-label">'.$this->fk_recruitmentjobposition.'</span>';
1083  }
1084  if (property_exists($this, 'phone')) {
1085  $return .= '<br><span class="opacitymedium">'.$langs->trans("phone").'</span> : <span class="info-box-label">'.$this->phone.'</span>';
1086  }
1087  if (method_exists($this, 'getLibStatut')) {
1088  $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).'</div>';
1089  }
1090  $return .= '</div>';
1091  $return .= '</div>';
1092  $return .= '</div>';
1093  return $return;
1094  }
1095 }
1096 
1097 
1098 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1099 
1104 {
1105  // To complete with content of an object RecruitmentCandidatureLine
1106  // We should have a field rowid, fk_recruitmentcandidature and position
1107 
1113  public function __construct(DoliDB $db)
1114  {
1115  $this->db = $db;
1116  }
1117 }
$object ref
Definition: info.php:78
Parent class of all other business classes (invoices, contracts, proposals, orders,...
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
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.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
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.
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