dolibarr 21.0.0-beta
recruitmentjobposition.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2020 Laurent Destailleur <eldy@users.sourceforge.net>
3/* Copyright (C) 2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
4 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
27// Put here all includes required by your class file
28require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
29//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
30//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
31
36{
40 public $module = 'recruitment';
41
45 public $element = 'recruitmentjobposition';
46
50 public $table_element = 'recruitment_recruitmentjobposition';
51
55 public $picto = 'recruitmentjobposition';
56
60 const STATUS_DRAFT = 0;
61
66
71
75 const STATUS_CANCELED = 9;
76
77
103 // BEGIN MODULEBUILDER PROPERTIES
107 public $fields = array(
108 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'comment' => "Id"),
109 'entity' => array('type' => 'integer', 'label' => 'Entity', 'enabled' => 1, 'visible' => 0, 'position' => 5, 'notnull' => 1, 'default' => '1', 'index' => 1),
110 '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 object", 'css' => 'nowraponall'),
111 'label' => array('type' => 'varchar(255)', 'label' => 'JobLabel', 'enabled' => 1, 'position' => 30, 'notnull' => 1, 'visible' => 1, 'searchall' => 1, 'css' => 'minwidth500', 'csslist' => 'tdoverflowmax300', 'showoncombobox' => 2, 'autofocusoncreate' => 1),
112 'qty' => array('type' => 'integer', 'label' => 'NbOfEmployeesExpected', 'enabled' => 1, 'position' => 45, 'notnull' => 1, 'visible' => 1, 'default' => '1', 'isameasure' => 1, 'css' => 'maxwidth75imp'),
113 'fk_project' => array('type' => 'integer:Project:projet/class/project.class.php:1', 'label' => 'Project', 'enabled' => '$conf->project->enabled', 'position' => 52, 'notnull' => -1, 'visible' => -1, 'index' => 1, 'css' => 'maxwidth500', 'picto' => 'project'),
114 'fk_user_recruiter' => array('type' => 'integer:User:user/class/user.class.php:1:(statut:=:1)', 'label' => 'ResponsibleOfRecruitement', 'enabled' => 1, 'position' => 54, 'notnull' => 1, 'visible' => 1, 'foreignkey' => 'user.rowid', 'css' => 'maxwidth500', 'csslist' => 'tdoverflowmax150', 'picto' => 'user'),
115 'email_recruiter' => array('type' => 'varchar(255)', 'label' => 'EmailRecruiter', 'enabled' => 1, 'position' => 54, 'notnull' => 0, 'visible' => -1, 'help' => 'ToUseAGenericEmail', 'picto' => 'email'),
116 'fk_user_supervisor' => array('type' => 'integer:User:user/class/user.class.php:1:(statut:=:1)', 'label' => 'FutureManager', 'enabled' => 1, 'position' => 55, 'notnull' => 0, 'visible' => -1, 'foreignkey' => 'user.rowid', 'css' => 'maxwidth500', 'csslist' => 'tdoverflowmax150', 'picto' => 'user'),
117 'fk_establishment' => array('type' => 'integer:Establishment:hrm/class/establishment.class.php', 'label' => 'Establishment', 'enabled' => '$conf->hrm->enabled', 'position' => 56, 'notnull' => 0, 'visible' => -1, 'foreignkey' => 'establishment.rowid',),
118 'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label' => 'WorkPlace', 'enabled' => 'isModEnabled("societe")', 'position' => 57, 'notnull' => -1, 'visible' => -1, 'css' => 'maxwidth500', 'index' => 1, 'help' => "IfJobIsLocatedAtAPartner", 'picto' => 'company'),
119 'date_planned' => array('type' => 'date', 'label' => 'DateExpected', 'enabled' => 1, 'position' => 60, 'notnull' => 0, 'visible' => 1,),
120 'remuneration_suggested' => array('type' => 'varchar(255)', 'label' => 'Remuneration', 'enabled' => 1, 'position' => 62, 'notnull' => 0, 'visible' => 1,),
121 'description' => array('type' => 'html', 'label' => 'Description', 'enabled' => 1, 'position' => 65, 'notnull' => 0, 'visible' => 3,),
122 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 101, 'notnull' => 0, 'visible' => 0,),
123 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 102, 'notnull' => 0, 'visible' => 0,),
124 'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -4,),
125 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2,),
126 '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',),
127 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2,),
128 'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'LastMainDoc', 'enabled' => 1, 'position' => 900, 'notnull' => 0, 'visible' => 0,),
129 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => -2,),
130 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'position' => 1010, 'notnull' => -1, 'visible' => 0,),
131 'status' => array('type' => 'smallint', 'label' => 'Status', 'enabled' => 1, 'position' => 1000, 'notnull' => 1, 'visible' => 5, 'default' => '0', 'index' => 1, 'arrayofkeyval' => array(0 => 'Draft', 1 => 'Validated', 3 => 'Recruited', 9 => 'Canceled'),),
132 );
136 public $rowid;
137
141 public $ref;
145 public $entity;
146
150 public $label;
151
155 public $qty;
156
160 public $fk_soc;
161
165 public $fk_project;
169 public $fk_user_recruiter;
170
174 public $email_recruiter;
175
179 public $remuneration_suggested;
180
184 public $fk_user_supervisor;
188 public $fk_establishment;
192 public $date_planned;
196 public $description;
200 public $note_public;
204 public $note_private;
208 public $fk_user_creat;
212 public $fk_user_modif;
216 public $last_main_doc;
220 public $import_key;
224 public $model_pdf;
228 public $status;
229 // END MODULEBUILDER PROPERTIES
230
231
237 public function __construct(DoliDB $db)
238 {
239 global $conf, $langs;
240
241 $this->db = $db;
242
243 $this->ismultientitymanaged = 1;
244 $this->isextrafieldmanaged = 1;
245
246 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
247 $this->fields['rowid']['visible'] = 0;
248 }
249 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
250 $this->fields['entity']['enabled'] = 0;
251 }
252
253 // Example to show how to set values of fields definition dynamically
254 /*if ($user->hasRight('recruitment', 'recruitmentjobposition', 'read')) {
255 $this->fields['myfield']['visible'] = 1;
256 $this->fields['myfield']['noteditable'] = 0;
257 }*/
258
259 // Unset fields that are disabled
260 foreach ($this->fields as $key => $val) {
261 if (isset($val['enabled']) && empty($val['enabled'])) {
262 unset($this->fields[$key]);
263 }
264 }
265
266 // Translate some data of arrayofkeyval
267 if (is_object($langs)) {
268 foreach ($this->fields as $key => $val) {
269 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
270 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
271 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
272 }
273 }
274 }
275 }
276 }
277
285 public function create(User $user, $notrigger = 0)
286 {
287 return $this->createCommon($user, $notrigger);
288 }
289
297 public function createFromClone(User $user, $fromid)
298 {
299 global $langs, $extrafields;
300 $error = 0;
301
302 dol_syslog(__METHOD__, LOG_DEBUG);
303
304 $object = new self($this->db);
305
306 $this->db->begin();
307
308 // Load source object
309 $result = $object->fetchCommon($fromid);
310 if ($result > 0 && !empty($object->table_element_line)) {
311 $object->fetchLines();
312 }
313
314 // get lines so they will be clone
315 //foreach($this->lines as $line)
316 // $line->fetch_optionals();
317
318 // Reset some properties
319 unset($object->id);
320 unset($object->fk_user_creat);
321 unset($object->import_key);
322
323 // Clear fields
324 if (property_exists($object, 'ref')) {
325 // @phan-suppress-next-line PhanTypeMismatchProperty
326 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
327 }
328 if (property_exists($object, 'label')) {
329 // @phan-suppress-next-line PhanTypeInvalidDimOffset
330 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
331 }
332 if (property_exists($object, 'status')) {
333 $object->status = self::STATUS_DRAFT;
334 }
335 if (property_exists($object, 'date_creation')) {
336 $object->date_creation = dol_now();
337 }
338 if (property_exists($object, 'date_modification')) {
339 $object->date_modification = null;
340 }
341 // ...
342 // Clear extrafields that are unique
343 if (is_array($object->array_options) && count($object->array_options) > 0) {
344 $extrafields->fetch_name_optionals_label($this->table_element);
345 foreach ($object->array_options as $key => $option) {
346 $shortkey = preg_replace('/options_/', '', $key);
347 if (!empty($extrafields->attributes[$this->element]['unique'][$shortkey])) {
348 //var_dump($key);
349 //var_dump($clonedObj->array_options[$key]); exit;
350 unset($object->array_options[$key]);
351 }
352 }
353 }
354
355 // Create clone
356 $object->context['createfromclone'] = 'createfromclone';
357 $result = $object->createCommon($user);
358 if ($result < 0) {
359 $error++;
360 $this->error = $object->error;
361 $this->errors = $object->errors;
362 }
363
364 if (!$error) {
365 // copy internal contacts
366 if ($this->copy_linked_contact($object, 'internal') < 0) {
367 $error++;
368 }
369 }
370
371 if (!$error) {
372 // copy external contacts if same company
373 if (property_exists($this, 'socid') && $this->socid == $object->socid) {
374 if ($this->copy_linked_contact($object, 'external') < 0) {
375 $error++;
376 }
377 }
378 }
379
380 unset($object->context['createfromclone']);
381
382 // End
383 if (!$error) {
384 $this->db->commit();
385 return $object;
386 } else {
387 $this->db->rollback();
388 return -1;
389 }
390 }
391
399 public function fetch($id, $ref = null)
400 {
401 $result = $this->fetchCommon($id, $ref);
402 if ($result > 0 && !empty($this->table_element_line)) {
403 $this->fetchLines();
404 }
405 return $result;
406 }
407
413 public function fetchLines()
414 {
415 $this->lines = array();
416
417 $result = $this->fetchLinesCommon();
418 return $result;
419 }
420
421
434 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
435 {
436 dol_syslog(__METHOD__, LOG_DEBUG);
437
438 $records = array();
439
440 $sql = 'SELECT ';
441 $sql .= $this->getFieldList();
442 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
443 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
444 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
445 } else {
446 $sql .= ' WHERE 1 = 1';
447 }
448
449 // Manage filter
450 $errormessage = '';
451 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
452 if ($errormessage) {
453 $this->errors[] = $errormessage;
454 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
455 return -1;
456 }
457
458 if (!empty($sortfield)) {
459 $sql .= $this->db->order($sortfield, $sortorder);
460 }
461 if (!empty($limit)) {
462 $sql .= $this->db->plimit($limit, $offset);
463 }
464
465 $resql = $this->db->query($sql);
466 if ($resql) {
467 $num = $this->db->num_rows($resql);
468 $i = 0;
469 while ($i < ($limit ? min($limit, $num) : $num)) {
470 $obj = $this->db->fetch_object($resql);
471
472 $record = new self($this->db);
473 $record->setVarsFromFetchObj($obj);
474
475 $records[$record->id] = $record;
476
477 $i++;
478 }
479 $this->db->free($resql);
480
481 return $records;
482 } else {
483 $this->errors[] = 'Error '.$this->db->lasterror();
484 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
485
486 return -1;
487 }
488 }
489
497 public function update(User $user, $notrigger = 0)
498 {
499 return $this->updateCommon($user, $notrigger);
500 }
501
509 public function delete(User $user, $notrigger = 0)
510 {
511 return $this->deleteCommon($user, $notrigger);
512 //return $this->deleteCommon($user, $notrigger, 1);
513 }
514
523 public function deleteLine(User $user, $idline, $notrigger = 0)
524 {
525 if ($this->status < 0) {
526 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
527 return -2;
528 }
529
530 return $this->deleteLineCommon($user, $idline, $notrigger);
531 }
532
533
541 public function validate($user, $notrigger = 0)
542 {
543 global $conf;
544
545 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
546
547 $error = 0;
548
549 // Protection
550 if ($this->status == self::STATUS_VALIDATED) {
551 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
552 return 0;
553 }
554
555 $now = dol_now();
556
557 $this->db->begin();
558
559 // Define new ref
560 if (/* !$error && */ (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
561 $num = $this->getNextNumRef();
562 } else {
563 $num = $this->ref;
564 }
565 $this->newref = $num;
566
567 if (!empty($num)) {
568 // Validate
569 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
570 $sql .= " SET ref = '".$this->db->escape($num)."',";
571 $sql .= " status = ".self::STATUS_VALIDATED;
572 if (!empty($this->fields['date_validation'])) {
573 $sql .= ", date_validation = '".$this->db->idate($now)."',";
574 }
575 if (!empty($this->fields['fk_user_valid'])) { // @phan-suppress-current-line PhanTypeMismatchProperty
576 $sql .= ", fk_user_valid = ".((int) $user->id);
577 }
578 $sql .= " WHERE rowid = ".((int) $this->id);
579
580 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
581 $resql = $this->db->query($sql);
582 if (!$resql) {
583 dol_print_error($this->db);
584 $this->error = $this->db->lasterror();
585 $error++;
586 }
587
588 if (!$error && !$notrigger) {
589 // Call trigger
590 $result = $this->call_trigger('RECRUITMENTJOBPOSITION_VALIDATE', $user);
591 if ($result < 0) {
592 $error++;
593 }
594 // End call triggers
595 }
596 }
597
598 if (!$error) {
599 $this->oldref = $this->ref;
600
601 // Rename directory if dir was a temporary ref
602 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
603 // Now we rename also files into index
604 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'recruitmentjobposition/".$this->db->escape($this->newref)."'";
605 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'recruitmentjobposition/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
606 $resql = $this->db->query($sql);
607 if (!$resql) {
608 $error++;
609 $this->error = $this->db->lasterror();
610 }
611 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'recruitmentjobposition/".$this->db->escape($this->newref)."'";
612 $sql .= " WHERE filepath = 'recruitmentjobposition/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
613 $resql = $this->db->query($sql);
614 if (!$resql) {
615 $error++;
616 $this->error = $this->db->lasterror();
617 }
618
619 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
620 $oldref = dol_sanitizeFileName($this->ref);
621 $newref = dol_sanitizeFileName($num);
622 $dirsource = $conf->recruitment->dir_output.'/recruitmentjobposition/'.$oldref;
623 $dirdest = $conf->recruitment->dir_output.'/recruitmentjobposition/'.$newref;
624 if (!$error && file_exists($dirsource)) {
625 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
626
627 if (@rename($dirsource, $dirdest)) {
628 dol_syslog("Rename ok");
629 // Rename docs starting with $oldref with $newref
630 $listoffiles = dol_dir_list($conf->recruitment->dir_output.'/recruitmentjobposition/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
631 foreach ($listoffiles as $fileentry) {
632 $dirsource = $fileentry['name'];
633 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
634 $dirsource = $fileentry['path'].'/'.$dirsource;
635 $dirdest = $fileentry['path'].'/'.$dirdest;
636 @rename($dirsource, $dirdest);
637 }
638 }
639 }
640 }
641 }
642
643 // Set new ref and current status
644 if (!$error) {
645 $this->ref = $num;
647 }
648
649 if (!$error) {
650 $this->db->commit();
651 return 1;
652 } else {
653 $this->db->rollback();
654 return -1;
655 }
656 }
657
658
666 public function setDraft($user, $notrigger = 0)
667 {
668 // Protection
669 if ($this->status <= self::STATUS_DRAFT) {
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_DRAFT, $notrigger, 'RECRUITMENTJOBPOSITION_UNVALIDATE');
681 }
682
690 public function cancel($user, $notrigger = 0)
691 {
692 // Protection
693 if ($this->status != self::STATUS_VALIDATED) {
694 return 0;
695 }
696
697 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
698 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
699 {
700 $this->error='Permission denied';
701 return -1;
702 }*/
703
704 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'RECRUITMENTJOBPOSITION_CLOSE');
705 }
706
716 public function cloture($user, $status, $note = "", $notrigger = 0)
717 {
718 global $langs, $conf;
719
720 $error = 0;
721 $now = dol_now();
722
723 $this->db->begin();
724
725 $newprivatenote = dol_concatdesc($this->note_private, $note);
726
727 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
728 $sql .= " SET status = ".((int) $status).", note_private = '".$this->db->escape($newprivatenote)."'";
729 //$sql .= ", date_cloture='".$this->db->idate($now)."', fk_user_cloture=".$user->id;
730 $sql .= " WHERE rowid = ".((int) $this->id);
731
732 $resql = $this->db->query($sql);
733 if ($resql) {
734 $modelpdf = $this->model_pdf;
735 $triggerName = 'RECRUITMENTJOB_CLOSE_REFUSED';
736
737 if ($status == self::STATUS_RECRUITED) {
738 $triggerName = 'RECRUITMENTJOB_CLOSE_RECRUITED';
739 $modelpdf = $this->model_pdf;
740 }
741
742 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
743 // Define output language
744 $outputlangs = $langs;
745 if (getDolGlobalInt('MAIN_MULTILANGS')) {
746 $outputlangs = new Translate("", $conf);
747 $newlang = (GETPOST('lang_id', 'aZ09') ? GETPOST('lang_id', 'aZ09') : $this->thirdparty->default_lang);
748 $outputlangs->setDefaultLang($newlang);
749 }
750
751 // PDF
752 $hidedetails = (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0);
753 $hidedesc = (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0);
754 $hideref = (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0);
755
756 //$ret=$object->fetch($id); // Reload to get new records
757 $this->generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
758 }
759
760 $this->oldcopy = clone $this;
761 $this->status = $status;
762 $this->date_cloture = $now;
763 $this->note_private = $newprivatenote;
764
765 if (!$notrigger /* && empty($error) */) {
766 // Call trigger
767 $result = $this->call_trigger($triggerName, $user);
768 if ($result < 0) {
769 $error++;
770 }
771 // End call triggers
772 }
773
774 if (!$error) {
775 $this->db->commit();
776 return 1;
777 } else {
778 $this->status = $this->oldcopy->status;
779 $this->date_cloture = $this->oldcopy->date_cloture;
780 $this->note_private = $this->oldcopy->note_private;
781
782 $this->db->rollback();
783 return -1;
784 }
785 } else {
786 $this->error = $this->db->lasterror();
787 $this->db->rollback();
788 return -1;
789 }
790 }
791
799 public function reopen($user, $notrigger = 0)
800 {
801 // Protection
802 if ($this->status != self::STATUS_CANCELED) {
803 return 0;
804 }
805
806 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
807 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
808 {
809 $this->error='Permission denied';
810 return -1;
811 }*/
812
813 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'RECRUITMENTJOBPOSITION_REOPEN');
814 }
815
826 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
827 {
828 global $conf, $langs, $hookmanager;
829
830 if (!empty($conf->dol_no_mouse_hover)) {
831 $notooltip = 1; // Force disable tooltips
832 }
833
834 $result = '';
835
836 $label = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("PositionToBeFilled").'</u>';
837 if (isset($this->status)) {
838 $label .= ' '.$this->getLibStatut(5);
839 }
840 $label .= '<br>';
841 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
842 $label .= '<br><b>'.$langs->trans('Label').':</b> '.$this->label;
843
844 $url = dol_buildpath('/recruitment/recruitmentjobposition_card.php', 1).'?id='.$this->id;
845
846 if ($option != 'nolink') {
847 // Add param to save lastsearch_values or not
848 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
849 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
850 $add_save_lastsearch_values = 1;
851 }
852 if ($add_save_lastsearch_values) {
853 $url .= '&save_lastsearch_values=1';
854 }
855 }
856
857 $linkclose = '';
858 if (empty($notooltip)) {
859 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
860 $label = $langs->trans("ShowRecruitmentJobPosition");
861 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
862 }
863 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
864 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
865 } else {
866 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
867 }
868
869 $linkstart = '<a href="'.$url.'"';
870 $linkstart .= $linkclose.'>';
871 $linkend = '</a>';
872
873 $result .= $linkstart;
874
875 if (empty($this->showphoto_on_popup)) {
876 if ($withpicto) {
877 $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);
878 }
879 } else {
880 if ($withpicto) {
881 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
882
883 list($class, $module) = explode('@', $this->picto);
884 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
885 $filearray = dol_dir_list($upload_dir, "files");
886 $filename = $filearray[0]['name'];
887 if (!empty($filename)) {
888 $pospoint = strpos($filearray[0]['name'], '.');
889
890 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
891 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
892 $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>';
893 } else {
894 $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>';
895 }
896
897 $result .= '</div>';
898 } else {
899 $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);
900 }
901 }
902 }
903
904 if ($withpicto != 2) {
905 $result .= $this->ref;
906 }
907
908 $result .= $linkend;
909 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
910
911 global $action, $hookmanager;
912 $hookmanager->initHooks(array('recruitmentjobpositiondao'));
913 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
914 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
915 if ($reshook > 0) {
916 $result = $hookmanager->resPrint;
917 } else {
918 $result .= $hookmanager->resPrint;
919 }
920
921 return $result;
922 }
923
930 public function getLibStatut($mode = 0)
931 {
932 return $this->LibStatut($this->status, $mode);
933 }
934
935 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
943 public function LibStatut($status, $mode = 0)
944 {
945 // phpcs:enable
946 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
947 global $langs;
948 //$langs->load("recruitment");
949 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
950 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
951 $this->labelStatus[self::STATUS_RECRUITED] = $langs->transnoentitiesnoconv('Recruited');
952 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
953 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
954 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
955 $this->labelStatusShort[self::STATUS_RECRUITED] = $langs->transnoentitiesnoconv('Recruited');
956 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
957 }
958
959 $statusType = 'status'.$status;
960 if ($status == self::STATUS_VALIDATED) {
961 $statusType = 'status4';
962 }
963 if ($status == self::STATUS_RECRUITED) {
964 $statusType = 'status6';
965 }
966 if ($status == self::STATUS_CANCELED) {
967 $statusType = 'status9';
968 }
969
970 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
971 }
972
979 public function info($id)
980 {
981 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
982 $sql .= ' fk_user_creat, fk_user_modif';
983 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
984 $sql .= ' WHERE t.rowid = '.((int) $id);
985 $result = $this->db->query($sql);
986 if ($result) {
987 if ($this->db->num_rows($result)) {
988 $obj = $this->db->fetch_object($result);
989
990 $this->id = $obj->rowid;
991
992 $this->user_creation_id = $obj->fk_user_creat;
993 $this->user_modification_id = $obj->fk_user_modif;
994 $this->date_creation = $this->db->jdate($obj->datec);
995 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
996 }
997
998 $this->db->free($result);
999 } else {
1000 dol_print_error($this->db);
1001 }
1002 }
1003
1010 public function initAsSpecimen()
1011 {
1012 return $this->initAsSpecimenCommon();
1013 }
1014
1020 public function getLinesArray()
1021 {
1022 $this->lines = array();
1023
1024 return $this->lines;
1025 }
1026
1032 public function getNextNumRef()
1033 {
1034 global $langs, $conf;
1035 $langs->load("recruitment");
1036
1037 if (!getDolGlobalString('RECRUITMENT_RECRUITMENTJOBPOSITION_ADDON')) {
1038 $conf->global->RECRUITMENT_RECRUITMENTJOBPOSITION_ADDON = 'mod_recruitmentjobposition_standard';
1039 }
1040
1041 if (getDolGlobalString('RECRUITMENT_RECRUITMENTJOBPOSITION_ADDON')) {
1042 $mybool = false;
1043
1044 $file = getDolGlobalString('RECRUITMENT_RECRUITMENTJOBPOSITION_ADDON') . ".php";
1045 $classname = getDolGlobalString('RECRUITMENT_RECRUITMENTJOBPOSITION_ADDON');
1046
1047 // Include file with class
1048 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1049 foreach ($dirmodels as $reldir) {
1050 $dir = dol_buildpath($reldir."core/modules/recruitment/");
1051
1052 // Load file with numbering class (if found)
1053 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1054 }
1055
1056 if (!$mybool) {
1057 dol_print_error(null, "Failed to include file ".$file);
1058 return '';
1059 }
1060
1061 if (class_exists($classname)) {
1062 $obj = new $classname();
1063 '@phan-var-force ModeleNumRefRecruitmentJobPosition $obj';
1064 $numref = $obj->getNextValue($this);
1065
1066 if ($numref != '' && $numref != '-1') {
1067 return $numref;
1068 } else {
1069 $this->error = $obj->error;
1070 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1071 return "";
1072 }
1073 } else {
1074 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
1075 return "";
1076 }
1077 } else {
1078 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1079 return "";
1080 }
1081 }
1082
1094 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1095 {
1096 global $conf, $langs;
1097
1098 $result = 0;
1099 $includedocgeneration = 1;
1100
1101 $langs->load("recruitment");
1102
1103 if (!dol_strlen($modele)) {
1104 if (getDolGlobalString('RECRUITMENTJOBPOSITION_ADDON_PDF')) {
1105 $modele = getDolGlobalString('RECRUITMENTJOBPOSITION_ADDON_PDF');
1106 } else {
1107 $modele = ''; // No default value. For job position, we allow to disable all PDF generation
1108 }
1109 }
1110
1111 $modelpath = "core/modules/recruitment/doc/";
1112
1113 if ($includedocgeneration && !empty($modele)) {
1114 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1115 }
1116
1117 return $result;
1118 }
1119
1127 public function doScheduledJob()
1128 {
1129 //global $conf, $langs;
1130
1131 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1132
1133 $error = 0;
1134 $this->output = '';
1135 $this->error = '';
1136
1137 dol_syslog(__METHOD__, LOG_DEBUG);
1138
1139 $now = dol_now();
1140
1141 $this->db->begin();
1142
1143 // ...
1144
1145 $this->db->commit();
1146
1147 return $error;
1148 }
1149
1150
1158 public function getKanbanView($option = '', $arraydata = null)
1159 {
1160 global $langs;
1161
1162 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1163
1164 $return = '<div class="box-flex-item box-flex-grow-zero">';
1165 $return .= '<div class="info-box info-box-sm">';
1166 $return .= '<span class="info-box-icon bg-infobox-action">';
1167 $return .= img_picto('', $this->picto);
1168 $return .= '</span>';
1169 $return .= '<div class="info-box-content">';
1170 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).($this->qty > 1 ? ' <span title="'.$langs->trans("NbOfEmployeesExpected").'">('.$this->qty.')</span>' : '').'</span>';
1171 if ($selected >= 0) {
1172 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1173 }
1174 /*
1175 if (property_exists($this, 'date_planned')) {
1176 $return .= '<br><span class="opacitymedium">'.$langs->trans("Date").'</span> : <span class="info-box-label">'.dol_print_date($this->db->jdate($this->date_planned), 'day').'</span>';
1177 }*/
1178 if (property_exists($this, 'remuneration_suggested')) {
1179 $return .= '<br><span class="opacitymedium">'.$langs->trans("Remuneration").'</span> : <span class="info-box-label">'.$this->remuneration_suggested.'</span>';
1180 }
1181 if (method_exists($this, 'getLibStatut')) {
1182 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).' &nbsp; <span class="opacitymedium" title="'.$langs->trans("RecruitmentCandidatures").'">'.$langs->trans("RecruitmentCandidatures", '', '', '', '', 5).'</span> : <span>';
1183 $return .= $arraydata['nbapplications'];
1184 $return .= '</span></div>';
1185 }
1186 $return .= '</div>';
1187 $return .= '</div>';
1188 $return .= '</div>';
1189 return $return;
1190 }
1191}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
$object ref
Definition info.php:89
Parent class of all other business classes (invoices, contracts, proposals, orders,...
deleteLineCommon(User $user, $idline, $notrigger=0)
Delete a line of object in database.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
createCommon(User $user, $notrigger=0)
Create object in the database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
updateCommon(User $user, $notrigger=0)
Update object into database.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
fetchLinesCommon($morewhere='', $noextrafields=0)
Load object in memory from the database.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
deleteCommon(User $user, $notrigger=0, $forcechilddeletion=0)
Delete object in database.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Class to manage Dolibarr database access.
Class for RecruitmentJobPosition.
validate($user, $notrigger=0)
Validate object.
deleteLine(User $user, $idline, $notrigger=0)
Delete a line of object in database.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
info($id)
Load the info information in the object.
cloture($user, $status, $note="", $notrigger=0)
Close the recruitment.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionally the picto)
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
setDraft($user, $notrigger=0)
Set draft status.
getLibStatut($mode=0)
Return label of the status.
create(User $user, $notrigger=0)
Create object into database.
LibStatut($status, $mode=0)
Return the status.
getLinesArray()
Create an array of lines.
reopen($user, $notrigger=0)
Set back to validated status.
getKanbanView($option='', $arraydata=null)
Return clickable link of object (with eventually picto)
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load list of objects in memory from the database.
update(User $user, $notrigger=0)
Update object into database.
fetch($id, $ref=null)
Load object in memory from the database.
cancel($user, $notrigger=0)
Set cancel status.
createFromClone(User $user, $fromid)
Clone an object into another one.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
fetchLines()
Load object lines in memory from the database.
Class to manage translations.
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:171
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:63
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79