dolibarr 21.0.0-alpha
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 );
133 public $rowid;
134
138 public $ref;
139 public $entity;
140
144 public $label;
145
149 public $qty;
150
154 public $fk_soc;
155
159 public $fk_project;
160 public $fk_user_recruiter;
161
165 public $email_recruiter;
166
170 public $remuneration_suggested;
171
172 public $fk_user_supervisor;
173 public $fk_establishment;
174 public $date_planned;
175 public $description;
176 public $note_public;
177 public $note_private;
178 public $fk_user_creat;
179 public $fk_user_modif;
180 public $last_main_doc;
181 public $import_key;
182 public $model_pdf;
183 public $status;
184 // END MODULEBUILDER PROPERTIES
185
186
192 public function __construct(DoliDB $db)
193 {
194 global $conf, $langs;
195
196 $this->db = $db;
197
198 $this->ismultientitymanaged = 1;
199 $this->isextrafieldmanaged = 1;
200
201 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
202 $this->fields['rowid']['visible'] = 0;
203 }
204 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
205 $this->fields['entity']['enabled'] = 0;
206 }
207
208 // Example to show how to set values of fields definition dynamically
209 /*if ($user->hasRight('recruitment', 'recruitmentjobposition', 'read')) {
210 $this->fields['myfield']['visible'] = 1;
211 $this->fields['myfield']['noteditable'] = 0;
212 }*/
213
214 // Unset fields that are disabled
215 foreach ($this->fields as $key => $val) {
216 if (isset($val['enabled']) && empty($val['enabled'])) {
217 unset($this->fields[$key]);
218 }
219 }
220
221 // Translate some data of arrayofkeyval
222 if (is_object($langs)) {
223 foreach ($this->fields as $key => $val) {
224 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
225 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
226 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
227 }
228 }
229 }
230 }
231 }
232
240 public function create(User $user, $notrigger = 0)
241 {
242 return $this->createCommon($user, $notrigger);
243 }
244
252 public function createFromClone(User $user, $fromid)
253 {
254 global $langs, $extrafields;
255 $error = 0;
256
257 dol_syslog(__METHOD__, LOG_DEBUG);
258
259 $object = new self($this->db);
260
261 $this->db->begin();
262
263 // Load source object
264 $result = $object->fetchCommon($fromid);
265 if ($result > 0 && !empty($object->table_element_line)) {
266 $object->fetchLines();
267 }
268
269 // get lines so they will be clone
270 //foreach($this->lines as $line)
271 // $line->fetch_optionals();
272
273 // Reset some properties
274 unset($object->id);
275 unset($object->fk_user_creat);
276 unset($object->import_key);
277
278 // Clear fields
279 if (property_exists($object, 'ref')) {
280 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
281 }
282 if (property_exists($object, 'label')) {
283 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
284 }
285 if (property_exists($object, 'status')) {
286 $object->status = self::STATUS_DRAFT;
287 }
288 if (property_exists($object, 'date_creation')) {
289 $object->date_creation = dol_now();
290 }
291 if (property_exists($object, 'date_modification')) {
292 $object->date_modification = null;
293 }
294 // ...
295 // Clear extrafields that are unique
296 if (is_array($object->array_options) && count($object->array_options) > 0) {
297 $extrafields->fetch_name_optionals_label($this->table_element);
298 foreach ($object->array_options as $key => $option) {
299 $shortkey = preg_replace('/options_/', '', $key);
300 if (!empty($extrafields->attributes[$this->element]['unique'][$shortkey])) {
301 //var_dump($key);
302 //var_dump($clonedObj->array_options[$key]); exit;
303 unset($object->array_options[$key]);
304 }
305 }
306 }
307
308 // Create clone
309 $object->context['createfromclone'] = 'createfromclone';
310 $result = $object->createCommon($user);
311 if ($result < 0) {
312 $error++;
313 $this->error = $object->error;
314 $this->errors = $object->errors;
315 }
316
317 if (!$error) {
318 // copy internal contacts
319 if ($this->copy_linked_contact($object, 'internal') < 0) {
320 $error++;
321 }
322 }
323
324 if (!$error) {
325 // copy external contacts if same company
326 if (property_exists($this, 'socid') && $this->socid == $object->socid) {
327 if ($this->copy_linked_contact($object, 'external') < 0) {
328 $error++;
329 }
330 }
331 }
332
333 unset($object->context['createfromclone']);
334
335 // End
336 if (!$error) {
337 $this->db->commit();
338 return $object;
339 } else {
340 $this->db->rollback();
341 return -1;
342 }
343 }
344
352 public function fetch($id, $ref = null)
353 {
354 $result = $this->fetchCommon($id, $ref);
355 if ($result > 0 && !empty($this->table_element_line)) {
356 $this->fetchLines();
357 }
358 return $result;
359 }
360
366 public function fetchLines()
367 {
368 $this->lines = array();
369
370 $result = $this->fetchLinesCommon();
371 return $result;
372 }
373
374
387 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
388 {
389 dol_syslog(__METHOD__, LOG_DEBUG);
390
391 $records = array();
392
393 $sql = 'SELECT ';
394 $sql .= $this->getFieldList();
395 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
396 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
397 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
398 } else {
399 $sql .= ' WHERE 1 = 1';
400 }
401
402 // Manage filter
403 $errormessage = '';
404 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
405 if ($errormessage) {
406 $this->errors[] = $errormessage;
407 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
408 return -1;
409 }
410
411 if (!empty($sortfield)) {
412 $sql .= $this->db->order($sortfield, $sortorder);
413 }
414 if (!empty($limit)) {
415 $sql .= $this->db->plimit($limit, $offset);
416 }
417
418 $resql = $this->db->query($sql);
419 if ($resql) {
420 $num = $this->db->num_rows($resql);
421 $i = 0;
422 while ($i < ($limit ? min($limit, $num) : $num)) {
423 $obj = $this->db->fetch_object($resql);
424
425 $record = new self($this->db);
426 $record->setVarsFromFetchObj($obj);
427
428 $records[$record->id] = $record;
429
430 $i++;
431 }
432 $this->db->free($resql);
433
434 return $records;
435 } else {
436 $this->errors[] = 'Error '.$this->db->lasterror();
437 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
438
439 return -1;
440 }
441 }
442
450 public function update(User $user, $notrigger = 0)
451 {
452 return $this->updateCommon($user, $notrigger);
453 }
454
462 public function delete(User $user, $notrigger = 0)
463 {
464 return $this->deleteCommon($user, $notrigger);
465 //return $this->deleteCommon($user, $notrigger, 1);
466 }
467
476 public function deleteLine(User $user, $idline, $notrigger = 0)
477 {
478 if ($this->status < 0) {
479 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
480 return -2;
481 }
482
483 return $this->deleteLineCommon($user, $idline, $notrigger);
484 }
485
486
494 public function validate($user, $notrigger = 0)
495 {
496 global $conf;
497
498 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
499
500 $error = 0;
501
502 // Protection
503 if ($this->status == self::STATUS_VALIDATED) {
504 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
505 return 0;
506 }
507
508 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitmentjobposition->create))
509 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitmentjobposition->recruitmentjobposition_advance->validate))))
510 {
511 $this->error='NotEnoughPermissions';
512 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
513 return -1;
514 }*/
515
516 $now = dol_now();
517
518 $this->db->begin();
519
520 // Define new ref
521 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
522 $num = $this->getNextNumRef();
523 } else {
524 $num = $this->ref;
525 }
526 $this->newref = $num;
527
528 if (!empty($num)) {
529 // Validate
530 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
531 $sql .= " SET ref = '".$this->db->escape($num)."',";
532 $sql .= " status = ".self::STATUS_VALIDATED;
533 if (!empty($this->fields['date_validation'])) {
534 $sql .= ", date_validation = '".$this->db->idate($now)."',";
535 }
536 if (!empty($this->fields['fk_user_valid'])) {
537 $sql .= ", fk_user_valid = ".$user->id;
538 }
539 $sql .= " WHERE rowid = ".((int) $this->id);
540
541 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
542 $resql = $this->db->query($sql);
543 if (!$resql) {
544 dol_print_error($this->db);
545 $this->error = $this->db->lasterror();
546 $error++;
547 }
548
549 if (!$error && !$notrigger) {
550 // Call trigger
551 $result = $this->call_trigger('RECRUITMENTJOBPOSITION_VALIDATE', $user);
552 if ($result < 0) {
553 $error++;
554 }
555 // End call triggers
556 }
557 }
558
559 if (!$error) {
560 $this->oldref = $this->ref;
561
562 // Rename directory if dir was a temporary ref
563 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
564 // Now we rename also files into index
565 $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)."'";
566 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'recruitmentjobposition/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
567 $resql = $this->db->query($sql);
568 if (!$resql) {
569 $error++;
570 $this->error = $this->db->lasterror();
571 }
572 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'recruitmentjobposition/".$this->db->escape($this->newref)."'";
573 $sql .= " WHERE filepath = 'recruitmentjobposition/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
574 $resql = $this->db->query($sql);
575 if (!$resql) {
576 $error++;
577 $this->error = $this->db->lasterror();
578 }
579
580 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
581 $oldref = dol_sanitizeFileName($this->ref);
582 $newref = dol_sanitizeFileName($num);
583 $dirsource = $conf->recruitment->dir_output.'/recruitmentjobposition/'.$oldref;
584 $dirdest = $conf->recruitment->dir_output.'/recruitmentjobposition/'.$newref;
585 if (!$error && file_exists($dirsource)) {
586 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
587
588 if (@rename($dirsource, $dirdest)) {
589 dol_syslog("Rename ok");
590 // Rename docs starting with $oldref with $newref
591 $listoffiles = dol_dir_list($conf->recruitment->dir_output.'/recruitmentjobposition/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
592 foreach ($listoffiles as $fileentry) {
593 $dirsource = $fileentry['name'];
594 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
595 $dirsource = $fileentry['path'].'/'.$dirsource;
596 $dirdest = $fileentry['path'].'/'.$dirdest;
597 @rename($dirsource, $dirdest);
598 }
599 }
600 }
601 }
602 }
603
604 // Set new ref and current status
605 if (!$error) {
606 $this->ref = $num;
608 }
609
610 if (!$error) {
611 $this->db->commit();
612 return 1;
613 } else {
614 $this->db->rollback();
615 return -1;
616 }
617 }
618
619
627 public function setDraft($user, $notrigger = 0)
628 {
629 // Protection
630 if ($this->status <= self::STATUS_DRAFT) {
631 return 0;
632 }
633
634 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
635 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
636 {
637 $this->error='Permission denied';
638 return -1;
639 }*/
640
641 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'RECRUITMENTJOBPOSITION_UNVALIDATE');
642 }
643
651 public function cancel($user, $notrigger = 0)
652 {
653 // Protection
654 if ($this->status != self::STATUS_VALIDATED) {
655 return 0;
656 }
657
658 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
659 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
660 {
661 $this->error='Permission denied';
662 return -1;
663 }*/
664
665 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'RECRUITMENTJOBPOSITION_CLOSE');
666 }
667
677 public function cloture($user, $status, $note = "", $notrigger = 0)
678 {
679 global $langs, $conf;
680
681 $error = 0;
682 $now = dol_now();
683
684 $this->db->begin();
685
686 $newprivatenote = dol_concatdesc($this->note_private, $note);
687
688 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
689 $sql .= " SET status = ".((int) $status).", note_private = '".$this->db->escape($newprivatenote)."'";
690 //$sql .= ", date_cloture='".$this->db->idate($now)."', fk_user_cloture=".$user->id;
691 $sql .= " WHERE rowid = ".((int) $this->id);
692
693 $resql = $this->db->query($sql);
694 if ($resql) {
695 $modelpdf = $this->model_pdf;
696 $triggerName = 'RECRUITMENTJOB_CLOSE_REFUSED';
697
698 if ($status == self::STATUS_RECRUITED) {
699 $triggerName = 'RECRUITMENTJOB_CLOSE_RECRUITED';
700 $modelpdf = $this->model_pdf;
701 }
702
703 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
704 // Define output language
705 $outputlangs = $langs;
706 if (getDolGlobalInt('MAIN_MULTILANGS')) {
707 $outputlangs = new Translate("", $conf);
708 $newlang = (GETPOST('lang_id', 'aZ09') ? GETPOST('lang_id', 'aZ09') : $this->thirdparty->default_lang);
709 $outputlangs->setDefaultLang($newlang);
710 }
711
712 // PDF
713 $hidedetails = (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0);
714 $hidedesc = (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0);
715 $hideref = (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0);
716
717 //$ret=$object->fetch($id); // Reload to get new records
718 $this->generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
719 }
720
721 if (!$error) {
722 $this->oldcopy = clone $this;
723 $this->status = $status;
724 $this->date_cloture = $now;
725 $this->note_private = $newprivatenote;
726 }
727
728 if (!$notrigger && empty($error)) {
729 // Call trigger
730 $result = $this->call_trigger($triggerName, $user);
731 if ($result < 0) {
732 $error++;
733 }
734 // End call triggers
735 }
736
737 if (!$error) {
738 $this->db->commit();
739 return 1;
740 } else {
741 $this->status = $this->oldcopy->status;
742 $this->date_cloture = $this->oldcopy->date_cloture;
743 $this->note_private = $this->oldcopy->note_private;
744
745 $this->db->rollback();
746 return -1;
747 }
748 } else {
749 $this->error = $this->db->lasterror();
750 $this->db->rollback();
751 return -1;
752 }
753 }
754
762 public function reopen($user, $notrigger = 0)
763 {
764 // Protection
765 if ($this->status != self::STATUS_CANCELED) {
766 return 0;
767 }
768
769 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->write))
770 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitment->recruitment_advance->validate))))
771 {
772 $this->error='Permission denied';
773 return -1;
774 }*/
775
776 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'RECRUITMENTJOBPOSITION_REOPEN');
777 }
778
789 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
790 {
791 global $conf, $langs, $hookmanager;
792
793 if (!empty($conf->dol_no_mouse_hover)) {
794 $notooltip = 1; // Force disable tooltips
795 }
796
797 $result = '';
798
799 $label = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("PositionToBeFilled").'</u>';
800 if (isset($this->status)) {
801 $label .= ' '.$this->getLibStatut(5);
802 }
803 $label .= '<br>';
804 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
805 $label .= '<br><b>'.$langs->trans('Label').':</b> '.$this->label;
806
807 $url = dol_buildpath('/recruitment/recruitmentjobposition_card.php', 1).'?id='.$this->id;
808
809 if ($option != 'nolink') {
810 // Add param to save lastsearch_values or not
811 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
812 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
813 $add_save_lastsearch_values = 1;
814 }
815 if ($add_save_lastsearch_values) {
816 $url .= '&save_lastsearch_values=1';
817 }
818 }
819
820 $linkclose = '';
821 if (empty($notooltip)) {
822 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
823 $label = $langs->trans("ShowRecruitmentJobPosition");
824 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
825 }
826 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
827 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
828 } else {
829 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
830 }
831
832 $linkstart = '<a href="'.$url.'"';
833 $linkstart .= $linkclose.'>';
834 $linkend = '</a>';
835
836 $result .= $linkstart;
837
838 if (empty($this->showphoto_on_popup)) {
839 if ($withpicto) {
840 $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);
841 }
842 } else {
843 if ($withpicto) {
844 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
845
846 list($class, $module) = explode('@', $this->picto);
847 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
848 $filearray = dol_dir_list($upload_dir, "files");
849 $filename = $filearray[0]['name'];
850 if (!empty($filename)) {
851 $pospoint = strpos($filearray[0]['name'], '.');
852
853 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
854 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
855 $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>';
856 } else {
857 $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>';
858 }
859
860 $result .= '</div>';
861 } else {
862 $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);
863 }
864 }
865 }
866
867 if ($withpicto != 2) {
868 $result .= $this->ref;
869 }
870
871 $result .= $linkend;
872 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
873
874 global $action, $hookmanager;
875 $hookmanager->initHooks(array('recruitmentjobpositiondao'));
876 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
877 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
878 if ($reshook > 0) {
879 $result = $hookmanager->resPrint;
880 } else {
881 $result .= $hookmanager->resPrint;
882 }
883
884 return $result;
885 }
886
893 public function getLibStatut($mode = 0)
894 {
895 return $this->LibStatut($this->status, $mode);
896 }
897
898 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
906 public function LibStatut($status, $mode = 0)
907 {
908 // phpcs:enable
909 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
910 global $langs;
911 //$langs->load("recruitment");
912 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
913 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
914 $this->labelStatus[self::STATUS_RECRUITED] = $langs->transnoentitiesnoconv('Recruited');
915 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
916 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
917 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
918 $this->labelStatusShort[self::STATUS_RECRUITED] = $langs->transnoentitiesnoconv('Recruited');
919 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled');
920 }
921
922 $statusType = 'status'.$status;
923 if ($status == self::STATUS_VALIDATED) {
924 $statusType = 'status4';
925 }
926 if ($status == self::STATUS_RECRUITED) {
927 $statusType = 'status6';
928 }
929 if ($status == self::STATUS_CANCELED) {
930 $statusType = 'status9';
931 }
932
933 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
934 }
935
942 public function info($id)
943 {
944 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
945 $sql .= ' fk_user_creat, fk_user_modif';
946 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
947 $sql .= ' WHERE t.rowid = '.((int) $id);
948 $result = $this->db->query($sql);
949 if ($result) {
950 if ($this->db->num_rows($result)) {
951 $obj = $this->db->fetch_object($result);
952
953 $this->id = $obj->rowid;
954
955 $this->user_creation_id = $obj->fk_user_creat;
956 $this->user_modification_id = $obj->fk_user_modif;
957 $this->date_creation = $this->db->jdate($obj->datec);
958 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
959 }
960
961 $this->db->free($result);
962 } else {
963 dol_print_error($this->db);
964 }
965 }
966
973 public function initAsSpecimen()
974 {
975 return $this->initAsSpecimenCommon();
976 }
977
983 public function getLinesArray()
984 {
985 $this->lines = array();
986
987 return $this->lines;
988 }
989
995 public function getNextNumRef()
996 {
997 global $langs, $conf;
998 $langs->load("recruitment");
999
1000 if (!getDolGlobalString('RECRUITMENT_RECRUITMENTJOBPOSITION_ADDON')) {
1001 $conf->global->RECRUITMENT_RECRUITMENTJOBPOSITION_ADDON = 'mod_recruitmentjobposition_standard';
1002 }
1003
1004 if (getDolGlobalString('RECRUITMENT_RECRUITMENTJOBPOSITION_ADDON')) {
1005 $mybool = false;
1006
1007 $file = getDolGlobalString('RECRUITMENT_RECRUITMENTJOBPOSITION_ADDON') . ".php";
1008 $classname = getDolGlobalString('RECRUITMENT_RECRUITMENTJOBPOSITION_ADDON');
1009
1010 // Include file with class
1011 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1012 foreach ($dirmodels as $reldir) {
1013 $dir = dol_buildpath($reldir."core/modules/recruitment/");
1014
1015 // Load file with numbering class (if found)
1016 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1017 }
1018
1019 if ($mybool === false) {
1020 dol_print_error(null, "Failed to include file ".$file);
1021 return '';
1022 }
1023
1024 if (class_exists($classname)) {
1025 $obj = new $classname();
1026 $numref = $obj->getNextValue($this);
1027
1028 if ($numref != '' && $numref != '-1') {
1029 return $numref;
1030 } else {
1031 $this->error = $obj->error;
1032 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1033 return "";
1034 }
1035 } else {
1036 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
1037 return "";
1038 }
1039 } else {
1040 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1041 return "";
1042 }
1043 }
1044
1056 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1057 {
1058 global $conf, $langs;
1059
1060 $result = 0;
1061 $includedocgeneration = 1;
1062
1063 $langs->load("recruitment");
1064
1065 if (!dol_strlen($modele)) {
1066 if (getDolGlobalString('RECRUITMENTJOBPOSITION_ADDON_PDF')) {
1067 $modele = getDolGlobalString('RECRUITMENTJOBPOSITION_ADDON_PDF');
1068 } else {
1069 $modele = ''; // No default value. For job position, we allow to disable all PDF generation
1070 }
1071 }
1072
1073 $modelpath = "core/modules/recruitment/doc/";
1074
1075 if ($includedocgeneration && !empty($modele)) {
1076 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1077 }
1078
1079 return $result;
1080 }
1081
1089 public function doScheduledJob()
1090 {
1091 //global $conf, $langs;
1092
1093 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1094
1095 $error = 0;
1096 $this->output = '';
1097 $this->error = '';
1098
1099 dol_syslog(__METHOD__, LOG_DEBUG);
1100
1101 $now = dol_now();
1102
1103 $this->db->begin();
1104
1105 // ...
1106
1107 $this->db->commit();
1108
1109 return $error;
1110 }
1111
1112
1120 public function getKanbanView($option = '', $arraydata = null)
1121 {
1122 global $langs;
1123
1124 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1125
1126 $return = '<div class="box-flex-item box-flex-grow-zero">';
1127 $return .= '<div class="info-box info-box-sm">';
1128 $return .= '<span class="info-box-icon bg-infobox-action">';
1129 $return .= img_picto('', $this->picto);
1130 $return .= '</span>';
1131 $return .= '<div class="info-box-content">';
1132 $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>';
1133 if ($selected >= 0) {
1134 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1135 }
1136 /*
1137 if (property_exists($this, 'date_planned')) {
1138 $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>';
1139 }*/
1140 if (property_exists($this, 'remuneration_suggested')) {
1141 $return .= '<br><span class="opacitymedium">'.$langs->trans("Remuneration").'</span> : <span class="info-box-label">'.$this->remuneration_suggested.'</span>';
1142 }
1143 if (method_exists($this, 'getLibStatut')) {
1144 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).' &nbsp; <span class="opacitymedium" title="'.$langs->trans("RecruitmentCandidatures").'">'.$langs->trans("RecruitmentCandidatures", '', '', '', '', 5).'</span> : <span>';
1145 $return .= $arraydata['nbapplications'];
1146 $return .= '</span></div>';
1147 }
1148 $return .= '</div>';
1149 $return .= '</div>';
1150 $return .= '</div>';
1151 return $return;
1152 }
1153}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition security.php:626
$object ref
Definition info.php:79
Parent class of all other business classes (invoices, contracts, proposals, orders,...
deleteLineCommon(User $user, $idline, $notrigger=0)
Delete a line of object in database.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
createCommon(User $user, $notrigger=0)
Create object in the database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
updateCommon(User $user, $notrigger=0)
Update object into database.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
fetchLinesCommon($morewhere='', $noextrafields=0)
Load object in memory from the database.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
deleteCommon(User $user, $notrigger=0, $forcechilddeletion=0)
Delete object in database.
call_trigger($triggerName, $user)
Call trigger based on this instance.
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 clicable 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.
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...
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 dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.