dolibarr  16.0.1
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 = 0;
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'=>'minwidth125 tdoverflowmax200'),
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',),
118  'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,),
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'=>'tdoverflowmax200'),
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  //'fk_recruitment_origin' => array('type'=>'integer:CRecruitmentOrigin:recruitment/class/crecruitmentorigin.class.php', 'label'=>'Origin', 'enabled'=>'1', 'position'=>45, 'visible'=>1, 'index'=>1),
126  'remuneration_requested' => array('type'=>'integer', 'label'=>'RequestedRemuneration', 'enabled'=>'1', 'position'=>80, 'notnull'=>0, 'visible'=>-1,),
127  'remuneration_proposed' => array('type'=>'integer', 'label'=>'ProposedRemuneration', 'enabled'=>'1', 'position'=>81, 'notnull'=>0, 'visible'=>-1,),
128  'description' => array('type'=>'html', 'label'=>'Description', 'enabled'=>'1', 'position'=>300, 'notnull'=>0, 'visible'=>3, 'cssview'=>'wordbreak'),
129  'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>1, 'csslist'=>'nowraponall'),
130  'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2, 'csslist'=>'nowraponall'),
131  'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,),
132  'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,),
133  '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')),
134  );
135  public $rowid;
136  public $entity;
137  public $ref;
138  public $fk_recruitmentjobposition;
139  public $description;
140  public $note_public;
141  public $note_private;
142  public $date_creation;
143  public $tms;
144  public $fk_user_creat;
145  public $fk_user_modif;
146  public $lastname;
147  public $firstname;
148  public $email;
149  public $phone;
150  public $date_birth;
151  public $email_msgid;
152  public $remuneration_requested;
153  public $remuneration_proposed;
154  public $fk_recruitment_origin;
155  public $import_key;
156  public $model_pdf;
157  public $status;
158  // END MODULEBUILDER PROPERTIES
159 
160 
166  public function __construct(DoliDB $db)
167  {
168  global $conf, $langs;
169 
170  $this->db = $db;
171 
172  if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) {
173  $this->fields['rowid']['visible'] = 0;
174  }
175  if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) {
176  $this->fields['entity']['enabled'] = 0;
177  }
178 
179  // Example to show how to set values of fields definition dynamically
180  /*if ($user->rights->recruitment->recruitmentcandidature->read) {
181  $this->fields['myfield']['visible'] = 1;
182  $this->fields['myfield']['noteditable'] = 0;
183  }*/
184 
185  // Unset fields that are disabled
186  foreach ($this->fields as $key => $val) {
187  if (isset($val['enabled']) && empty($val['enabled'])) {
188  unset($this->fields[$key]);
189  }
190  }
191 
192  // Translate some data of arrayofkeyval
193  if (is_object($langs)) {
194  foreach ($this->fields as $key => $val) {
195  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
196  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
197  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
198  }
199  }
200  }
201  }
202  }
203 
211  public function create(User $user, $notrigger = false)
212  {
213  return $this->createCommon($user, $notrigger);
214  }
215 
223  public function createFromClone(User $user, $fromid)
224  {
225  global $langs, $extrafields;
226  $error = 0;
227 
228  dol_syslog(__METHOD__, LOG_DEBUG);
229 
230  $object = new self($this->db);
231 
232  $this->db->begin();
233 
234  // Load source object
235  $result = $object->fetchCommon($fromid);
236  if ($result > 0 && !empty($object->table_element_line)) {
237  $object->fetchLines();
238  }
239 
240  // get lines so they will be clone
241  //foreach($this->lines as $line)
242  // $line->fetch_optionals();
243 
244  // Reset some properties
245  unset($object->id);
246  unset($object->fk_user_creat);
247  unset($object->import_key);
248 
249  // Clear fields
250  if (property_exists($object, 'ref')) {
251  $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
252  }
253  if (property_exists($object, 'label')) {
254  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
255  }
256  if (property_exists($object, 'status')) {
257  $object->status = self::STATUS_DRAFT;
258  }
259  if (property_exists($object, 'date_creation')) {
260  $object->date_creation = dol_now();
261  }
262  if (property_exists($object, 'date_modification')) {
263  $object->date_modification = null;
264  }
265 
266  // ...
267  // Clear extrafields that are unique
268  if (is_array($object->array_options) && count($object->array_options) > 0) {
269  $extrafields->fetch_name_optionals_label($this->table_element);
270  foreach ($object->array_options as $key => $option) {
271  $shortkey = preg_replace('/options_/', '', $key);
272  if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
273  //var_dump($key);
274  //var_dump($clonedObj->array_options[$key]); exit;
275  unset($object->array_options[$key]);
276  }
277  }
278  }
279 
280  // Create clone
281  $object->context['createfromclone'] = 'createfromclone';
282  $result = $object->createCommon($user);
283  if ($result < 0) {
284  $error++;
285  $this->error = $object->error;
286  $this->errors = $object->errors;
287  }
288 
289  if (!$error) {
290  // copy internal contacts
291  if ($this->copy_linked_contact($object, 'internal') < 0) {
292  $error++;
293  }
294  }
295 
296  if (!$error) {
297  // copy external contacts if same company
298  if (property_exists($this, 'socid') && $this->socid == $object->socid) {
299  if ($this->copy_linked_contact($object, 'external') < 0) {
300  $error++;
301  }
302  }
303  }
304 
305  unset($object->context['createfromclone']);
306 
307  // End
308  if (!$error) {
309  $this->db->commit();
310  return $object;
311  } else {
312  $this->db->rollback();
313  return -1;
314  }
315  }
316 
325  public function fetch($id, $ref = null, $email_msgid = '')
326  {
327  $morewhere = '';
328  if ($email_msgid) {
329  $morewhere = " AND email_msgid = '".$this->db->escape($email_msgid)."'";
330  }
331  $result = $this->fetchCommon($id, $ref, $morewhere);
332  if ($result > 0 && !empty($this->table_element_line)) {
333  $this->fetchLines();
334  }
335  return $result;
336  }
337 
343  public function fetchLines()
344  {
345  $this->lines = array();
346 
347  $result = $this->fetchLinesCommon();
348  return $result;
349  }
350 
351 
363  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
364  {
365  global $conf;
366 
367  dol_syslog(__METHOD__, LOG_DEBUG);
368 
369  $records = array();
370 
371  $sql = 'SELECT ';
372  $sql .= $this->getFieldList();
373  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
374  if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
375  $sql .= ' WHERE t.entity IN ('.getEntity($this->table_element).')';
376  } else {
377  $sql .= ' WHERE 1 = 1';
378  }
379  // Manage filter
380  $sqlwhere = array();
381  if (count($filter) > 0) {
382  foreach ($filter as $key => $value) {
383  if ($key == 't.rowid') {
384  $sqlwhere[] = $key." = ".((int) $value);
385  } elseif (in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) {
386  $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
387  } elseif ($key == 'customsql') {
388  $sqlwhere[] = $value;
389  } elseif (strpos($value, '%') === false) {
390  $sqlwhere[] = $key." IN (".$this->db->sanitize($this->db->escape($value)).")";
391  } else {
392  $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
393  }
394  }
395  }
396  if (count($sqlwhere) > 0) {
397  $sql .= ' AND ('.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere).')';
398  }
399 
400  if (!empty($sortfield)) {
401  $sql .= $this->db->order($sortfield, $sortorder);
402  }
403  if (!empty($limit)) {
404  $sql .= $this->db->plimit($limit, $offset);
405  }
406 
407  $resql = $this->db->query($sql);
408  if ($resql) {
409  $num = $this->db->num_rows($resql);
410  $i = 0;
411  while ($i < ($limit ? min($limit, $num) : $num)) {
412  $obj = $this->db->fetch_object($resql);
413 
414  $record = new self($this->db);
415  $record->setVarsFromFetchObj($obj);
416 
417  $records[$record->id] = $record;
418 
419  $i++;
420  }
421  $this->db->free($resql);
422 
423  return $records;
424  } else {
425  $this->errors[] = 'Error '.$this->db->lasterror();
426  dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
427 
428  return -1;
429  }
430  }
431 
439  public function update(User $user, $notrigger = false)
440  {
441  return $this->updateCommon($user, $notrigger);
442  }
443 
451  public function delete(User $user, $notrigger = false)
452  {
453  return $this->deleteCommon($user, $notrigger);
454  //return $this->deleteCommon($user, $notrigger, 1);
455  }
456 
465  public function deleteLine(User $user, $idline, $notrigger = false)
466  {
467  if ($this->status < 0) {
468  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
469  return -2;
470  }
471 
472  return $this->deleteLineCommon($user, $idline, $notrigger);
473  }
474 
475 
483  public function validate($user, $notrigger = 0)
484  {
485  global $conf, $langs;
486 
487  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
488 
489  $error = 0;
490 
491  // Protection
492  if ($this->status == self::STATUS_VALIDATED) {
493  dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
494  return 0;
495  }
496 
497  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitmentcandidature->write))
498  || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitmentcandidature->recruitmentcandidature_advance->validate))))
499  {
500  $this->error='NotEnoughPermissions';
501  dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
502  return -1;
503  }*/
504 
505  $now = dol_now();
506 
507  $this->db->begin();
508 
509  // Define new ref
510  if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
511  $num = $this->getNextNumRef();
512  } else {
513  $num = $this->ref;
514  }
515  $this->newref = $num;
516 
517  if (!empty($num)) {
518  // Validate
519  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
520  $sql .= " SET ref = '".$this->db->escape($num)."',";
521  $sql .= " status = ".self::STATUS_VALIDATED;
522  if (!empty($this->fields['date_validation'])) {
523  $sql .= ", date_validation = '".$this->db->idate($now)."',";
524  }
525  if (!empty($this->fields['fk_user_valid'])) {
526  $sql .= ", fk_user_valid = ".$user->id;
527  }
528  $sql .= " WHERE rowid = ".((int) $this->id);
529 
530  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
531  $resql = $this->db->query($sql);
532  if (!$resql) {
533  dol_print_error($this->db);
534  $this->error = $this->db->lasterror();
535  $error++;
536  }
537 
538  if (!$error && !$notrigger) {
539  // Call trigger
540  $result = $this->call_trigger('RECRUITMENTCANDIDATURE_VALIDATE', $user);
541  if ($result < 0) {
542  $error++;
543  }
544  // End call triggers
545  }
546  }
547 
548  if (!$error) {
549  $this->oldref = $this->ref;
550 
551  // Rename directory if dir was a temporary ref
552  if (preg_match('/^[\(]?PROV/i', $this->ref)) {
553  // Now we rename also files into index
554  $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)."'";
555  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'recruitmentcandidature/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
556  $resql = $this->db->query($sql);
557  if (!$resql) {
558  $error++; $this->error = $this->db->lasterror();
559  }
560 
561  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
562  $oldref = dol_sanitizeFileName($this->ref);
563  $newref = dol_sanitizeFileName($num);
564  $dirsource = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$oldref;
565  $dirdest = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref;
566  if (!$error && file_exists($dirsource)) {
567  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
568 
569  if (@rename($dirsource, $dirdest)) {
570  dol_syslog("Rename ok");
571  // Rename docs starting with $oldref with $newref
572  $listoffiles = dol_dir_list($conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
573  foreach ($listoffiles as $fileentry) {
574  $dirsource = $fileentry['name'];
575  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
576  $dirsource = $fileentry['path'].'/'.$dirsource;
577  $dirdest = $fileentry['path'].'/'.$dirdest;
578  @rename($dirsource, $dirdest);
579  }
580  }
581  }
582  }
583  }
584 
585  // Set new ref and current status
586  if (!$error) {
587  $this->ref = $num;
588  $this->status = self::STATUS_VALIDATED;
589  }
590 
591  if (!$error) {
592  $this->db->commit();
593  return 1;
594  } else {
595  $this->db->rollback();
596  return -1;
597  }
598  }
599 
600 
608  public function setDraft($user, $notrigger = 0)
609  {
610  // Protection
611  if ($this->status <= self::STATUS_DRAFT) {
612  return 0;
613  }
614 
615  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->write))
616  || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitment_advance->validate))))
617  {
618  $this->error='Permission denied';
619  return -1;
620  }*/
621 
622  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'RECRUITMENTCANDIDATURE_UNVALIDATE');
623  }
624 
632  public function cancel($user, $notrigger = 0)
633  {
634  // Protection
635  if ($this->status != self::STATUS_VALIDATED) {
636  return 0;
637  }
638 
639  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->write))
640  || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitment_advance->validate))))
641  {
642  $this->error='Permission denied';
643  return -1;
644  }*/
645 
646  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'RECRUITMENTCANDIDATURE_CLOSE');
647  }
648 
656  public function reopen($user, $notrigger = 0)
657  {
658  // Protection
659  if ($this->status != self::STATUS_REFUSED && $this->status != self::STATUS_CANCELED && $this->status != self::STATUS_CONTRACT_REFUSED) {
660  return 0;
661  }
662 
663  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->write))
664  || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitment_advance->validate))))
665  {
666  $this->error='Permission denied';
667  return -1;
668  }*/
669 
670  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'RECRUITMENTCANDIDATURE_REOPEN');
671  }
672 
683  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
684  {
685  global $conf, $langs, $hookmanager;
686 
687  if (!empty($conf->dol_no_mouse_hover)) {
688  $notooltip = 1; // Force disable tooltips
689  }
690 
691  $result = '';
692 
693  $label = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("RecruitmentCandidature").'</u>';
694  if (isset($this->status)) {
695  $label .= ' '.$this->getLibStatut(5);
696  }
697  $label .= '<br>';
698  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
699  $label .= '<br><b>'.$langs->trans('Email').':</b> '.$this->email;
700  $label .= '<br><b>'.$langs->trans('Name').':</b> '.$this->getFullName($langs);
701 
702  $url = dol_buildpath('/recruitment/recruitmentcandidature_card.php', 1).'?id='.$this->id;
703 
704  if ($option != 'nolink') {
705  // Add param to save lastsearch_values or not
706  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
707  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
708  $add_save_lastsearch_values = 1;
709  }
710  if ($add_save_lastsearch_values) {
711  $url .= '&save_lastsearch_values=1';
712  }
713  }
714 
715  $linkclose = '';
716  if (empty($notooltip)) {
717  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
718  $label = $langs->trans("ShowRecruitmentCandidature");
719  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
720  }
721  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
722  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
723  } else {
724  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
725  }
726 
727  $linkstart = '<a href="'.$url.'"';
728  $linkstart .= $linkclose.'>';
729  $linkend = '</a>';
730 
731  $result .= $linkstart;
732 
733  if (empty($this->showphoto_on_popup)) {
734  if ($withpicto) {
735  $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);
736  }
737  } else {
738  if ($withpicto) {
739  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
740 
741  list($class, $module) = explode('@', $this->picto);
742  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
743  $filearray = dol_dir_list($upload_dir, "files");
744  $filename = $filearray[0]['name'];
745  if (!empty($filename)) {
746  $pospoint = strpos($filearray[0]['name'], '.');
747 
748  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
749  if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) {
750  $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>';
751  } else {
752  $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>';
753  }
754 
755  $result .= '</div>';
756  } else {
757  $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);
758  }
759  }
760  }
761 
762  if ($withpicto != 2) {
763  $result .= $this->ref;
764  }
765 
766  $result .= $linkend;
767  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
768 
769  global $action, $hookmanager;
770  $hookmanager->initHooks(array('recruitmentcandidaturedao'));
771  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
772  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
773  if ($reshook > 0) {
774  $result = $hookmanager->resPrint;
775  } else {
776  $result .= $hookmanager->resPrint;
777  }
778 
779  return $result;
780  }
781 
788  public function getLibStatut($mode = 0)
789  {
790  return $this->LibStatut($this->status, $mode);
791  }
792 
793  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
801  public function LibStatut($status, $mode = 0)
802  {
803  // phpcs:enable
804  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
805  global $langs;
806  //$langs->load("recruitment@recruitment");
807  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
808  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Received').' ('.$langs->transnoentitiesnoconv("InterviewToDo").')';
809  $this->labelStatus[self::STATUS_CONTRACT_PROPOSED] = $langs->transnoentitiesnoconv('ContractProposed');
810  $this->labelStatus[self::STATUS_CONTRACT_SIGNED] = $langs->transnoentitiesnoconv('ContractSigned');
811  $this->labelStatus[self::STATUS_CONTRACT_REFUSED] = $langs->transnoentitiesnoconv('ContractRefused');
812  $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('Refused');
813  $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
814  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
815  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Received');
816  $this->labelStatusShort[self::STATUS_CONTRACT_PROPOSED] = $langs->transnoentitiesnoconv('ContractProposed');
817  $this->labelStatusShort[self::STATUS_CONTRACT_SIGNED] = $langs->transnoentitiesnoconv('ContractSigned');
818  $this->labelStatusShort[self::STATUS_CONTRACT_REFUSED] = $langs->transnoentitiesnoconv('ContractRefused');
819  $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('Refused');
820  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
821  }
822 
823  $statusType = 'status'.$status;
824  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
825  if ($status == self::STATUS_CANCELED) {
826  $statusType = 'status6';
827  }
828  if ($status == self::STATUS_REFUSED) {
829  $statusType = 'status10';
830  }
831 
832  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
833  }
834 
841  public function info($id)
842  {
843  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
844  $sql .= ' fk_user_creat, fk_user_modif';
845  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
846  $sql .= ' WHERE t.rowid = '.((int) $id);
847  $result = $this->db->query($sql);
848  if ($result) {
849  if ($this->db->num_rows($result)) {
850  $obj = $this->db->fetch_object($result);
851  $this->id = $obj->rowid;
852 
853  $this->user_creation_id = $obj->fk_user_creat;
854  $this->user_modification_id = $obj->fk_user_modif;
855  $this->date_creation = $this->db->jdate($obj->datec);
856  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
857  }
858 
859  $this->db->free($result);
860  } else {
861  dol_print_error($this->db);
862  }
863  }
864 
871  public function initAsSpecimen()
872  {
873  $this->initAsSpecimenCommon();
874  }
875 
881  public function getLinesArray()
882  {
883  $this->lines = array();
884 
885  $objectline = new RecruitmentCandidatureLine($this->db);
886  $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_recruitmentcandidature = '.((int) $this->id)));
887 
888  if (is_numeric($result)) {
889  $this->error = $this->error;
890  $this->errors = $this->errors;
891  return $result;
892  } else {
893  $this->lines = $result;
894  return $this->lines;
895  }
896  }
897 
903  public function getNextNumRef()
904  {
905  global $langs, $conf;
906  $langs->load("recruitment@recruitment");
907 
908  if (empty($conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON)) {
909  $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON = 'mod_recruitmentcandidature_standard';
910  }
911 
912  if (!empty($conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON)) {
913  $mybool = false;
914 
915  $file = $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON.".php";
916  $classname = $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON;
917 
918  // Include file with class
919  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
920  foreach ($dirmodels as $reldir) {
921  $dir = dol_buildpath($reldir."core/modules/recruitment/");
922 
923  // Load file with numbering class (if found)
924  $mybool |= @include_once $dir.$file;
925  }
926 
927  if ($mybool === false) {
928  dol_print_error('', "Failed to include file ".$file);
929  return '';
930  }
931 
932  if (class_exists($classname)) {
933  $obj = new $classname();
934  $numref = $obj->getNextValue($this);
935 
936  if ($numref != '' && $numref != '-1') {
937  return $numref;
938  } else {
939  $this->error = $obj->error;
940  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
941  return "";
942  }
943  } else {
944  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
945  return "";
946  }
947  } else {
948  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
949  return "";
950  }
951  }
952 
964  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
965  {
966  global $conf, $langs;
967 
968  $result = 0;
969  $includedocgeneration = 0;
970 
971  $langs->load("recruitment@recruitment");
972 
973  if (!dol_strlen($modele)) {
974  if (!empty($conf->global->RECRUITMENTCANDIDATURE_ADDON_PDF)) {
975  $modele = $conf->global->RECRUITMENTCANDIDATURE_ADDON_PDF;
976  } else {
977  $modele = ''; // No default value. For job application, we allow to disable all PDF generation
978  }
979  }
980 
981  $modelpath = "core/modules/recruitment/doc/";
982 
983  if ($includedocgeneration && !empty($modele)) {
984  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
985  }
986 
987  return $result;
988  }
989 
997  public function doScheduledJob()
998  {
999  global $conf, $langs;
1000 
1001  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1002 
1003  $error = 0;
1004  $this->output = '';
1005  $this->error = '';
1006 
1007  dol_syslog(__METHOD__, LOG_DEBUG);
1008 
1009  $now = dol_now();
1010 
1011  $this->db->begin();
1012 
1013  // ...
1014 
1015  $this->db->commit();
1016 
1017  return $error;
1018  }
1019 }
1020 
1021 
1022 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1023 
1028 {
1029  // To complete with content of an object RecruitmentCandidatureLine
1030  // We should have a field rowid, fk_recruitmentcandidature and position
1031 
1037  public function __construct(DoliDB $db)
1038  {
1039  $this->db = $db;
1040  }
1041 }
info($id)
Load the info information in the object.
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
reopen($user, $notrigger=0)
Set back to validated status.
getLibStatut($mode=0)
Return label of the status.
create(User $user, $notrigger=false)
Create object into database.
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
fetchLinesCommon($morewhere= '')
Load object in memory from the database.
$conf db
API class for accounts.
Definition: inc.php:41
fetch($id, $ref=null, $email_msgid= '')
Load object 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.
Class RecruitmentCandidatureLine.
dol_now($mode= 'auto')
Return date for now.
validate($user, $notrigger=0)
Validate object.
Class to manage Dolibarr users.
Definition: user.class.php:44
Class to manage Dolibarr database access.
update(User $user, $notrigger=false)
Update object into database.
createCommon(User $user, $notrigger=false)
Create object into database.
createFromClone(User $user, $fromid)
Clone an object into another one.
fetchLines()
Load object lines in memory from the database.
getNomUrl($withpicto=0, $option= '', $notooltip=0, $morecss= '', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
getFullName($langs, $option=0, $nameorder=-1, $maxlen=0)
Return full name (civility+&#39; &#39;+name+&#39; &#39;+lastname)
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module...
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
getLinesArray()
Create an array of lines.
LibStatut($status, $mode=0)
Return the status.
dol_strlen($string, $stringencoding= 'UTF-8')
Make a strlen call.
getFieldList($alias= '')
Function to concat keys of fields.
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it&#39;s its name (generic function)
fetchAll($sortorder= '', $sortfield= '', $limit=0, $offset=0, array $filter=array(), $filtermode= 'AND')
Load list of objects in memory from the database.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
img_object($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
cancel($user, $notrigger=0)
Set cancel status.
updateCommon(User $user, $notrigger=false)
Update object into database.
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:60
setDraft($user, $notrigger=0)
Set draft status.
if(isModEnabled('facture')&&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur')&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)&&$user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice')&&$user->rights->supplier_invoice->lire)) if(isModEnabled('don')&&!empty($user->rights->don->lire)) if(isModEnabled('tax')&&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture')&&isModEnabled('commande')&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
Class for RecruitmentCandidature.
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
copy_linked_contact($objFrom, $source= 'internal')
Copy contact from one element to current.
call_trigger($triggerName, $user)
Call trigger based on this instance.
$object ref
Definition: info.php:77
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
__construct(DoliDB $db)
Constructor.
setStatusCommon($user, $status, $notrigger=0, $triggercode= '')
Set to a status.
dolGetStatus($statusLabel= '', $statusLabelShort= '', $html= '', $statusType= 'status0', $displayMode=0, $url= '', $params=array())
Output the badge of a status.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
Parent class of all other business classes (invoices, contracts, proposals, orders, ...)
fetchCommon($id, $ref=null, $morewhere= '')
Load object in memory from the database.