dolibarr 19.0.3
availabilities.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2022 Alice Adminson <aadminson@example.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
25// Put here all includes required by your class file
26require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
27//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
28//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
29
34{
38 public $module = 'bookcal';
39
43 public $element = 'availabilities';
44
48 public $table_element = 'bookcal_availabilities';
49
54 public $ismultientitymanaged = 0;
55
59 public $isextrafieldmanaged = 1;
60
64 public $picto = 'fa-file';
65
66
67 const STATUS_DRAFT = 0;
68 const STATUS_VALIDATED = 1;
69 const STATUS_CANCELED = 9;
70
71
111 // BEGIN MODULEBUILDER PROPERTIES
115 public $fields=array(
116 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>2, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"),
117 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>20, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'csslist'=>'tdoverflowmax150', 'cssview'=>'wordbreak', 'help'=>"BookcalLabelAvailabilityHelp", 'showoncombobox'=>'2', 'validate'=>'1',),
118 'fk_bookcal_calendar' => array('type'=>'integer:Calendar:bookcal/class/calendar.class.php:1', 'label'=>'Calendar', 'enabled'=>'1', 'position'=>25, 'notnull'=>1, 'visible'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax100'),
119 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>3, 'validate'=>'1',),
120 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0, 'cssview'=>'wordbreak', 'validate'=>'1',),
121 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0, 'cssview'=>'wordbreak', 'validate'=>'1',),
122 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,),
123 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,),
124 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'picto'=>'user', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'),
125 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'picto'=>'user', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'),
126 'last_main_doc' => array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>'1', 'position'=>600, 'notnull'=>0, 'visible'=>0,),
127 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,),
128 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,),
129 'start' => array('type'=>'date', 'label'=>'Start Date', 'enabled'=>'1', 'position'=>40, 'notnull'=>1, 'visible'=>1, 'searchall'=>1,),
130 'end' => array('type'=>'date', 'label'=>'End Date', 'enabled'=>'1', 'position'=>45, 'notnull'=>1, 'visible'=>1, 'searchall'=>1,),
131 'duration' => array('type'=>'integer', 'label'=>'DurationOfRange', 'enabled'=>'1', 'position'=>47, 'notnull'=>1, 'visible'=>1, 'default'=>'30', 'css'=>'width50 right'),
132 'startHour' => array('type'=>'integer', 'label'=>'Start Hour', 'enabled'=>'1', 'position'=>46, 'notnull'=>1, 'visible'=>1,),
133 'endHour' => array('type'=>'integer', 'label'=>'End Hour', 'enabled'=>'1', 'position'=>46.5, 'notnull'=>1, 'visible'=>1,),
134 'status' => array('type'=>'integer', 'label'=>'Status', 'enabled'=>'1', 'position'=>2000, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '9'=>'Closed'), 'default'=>1, 'validate'=>'1'),
135 );
136 public $rowid;
137 public $label;
138 public $description;
139 public $note_public;
140 public $note_private;
141 public $date_creation;
142 public $tms;
143 public $fk_user_creat;
144 public $fk_user_modif;
145 public $last_main_doc;
146 public $import_key;
147 public $model_pdf;
148 public $status;
149 public $start;
150 public $end;
151 public $duration;
152 public $startHour;
153 public $endHour;
154 public $fk_bookcal_calendar;
155 // END MODULEBUILDER PROPERTIES
156
157
158 // If this object has a subtable with lines
159
160 // /**
161 // * @var string Name of subtable line
162 // */
163 // public $table_element_line = 'bookcal_availabilitiesline';
164
165 // /**
166 // * @var string Field with ID of parent key if this object has a parent
167 // */
168 // public $fk_element = 'fk_availabilities';
169
170 // /**
171 // * @var string Name of subtable class that manage subtable lines
172 // */
173 // public $class_element_line = 'Availabilitiesline';
174
175 // /**
176 // * @var array List of child tables. To test if we can delete object.
177 // */
178 // protected $childtables = array();
179
180 // /**
181 // * @var array List of child tables. To know object to delete on cascade.
182 // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
183 // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
184 // */
185 // protected $childtablesoncascade = array('bookcal_availabilitiesdet');
186
187 // /**
188 // * @var AvailabilitiesLine[] Array of subtable lines
189 // */
190 // public $lines = array();
191
192
193
199 public function __construct(DoliDB $db)
200 {
201 global $conf, $langs;
202
203 $this->db = $db;
204
205 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid']) && !empty($this->fields['ref'])) {
206 $this->fields['rowid']['visible'] = 0;
207 }
208 if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) {
209 $this->fields['entity']['enabled'] = 0;
210 }
211
212 // Example to show how to set values of fields definition dynamically
213 /*if ($user->hasRight('bookcal', 'availabilities', 'read')) {
214 $this->fields['myfield']['visible'] = 1;
215 $this->fields['myfield']['noteditable'] = 0;
216 }*/
217
218 // Unset fields that are disabled
219 foreach ($this->fields as $key => $val) {
220 if (isset($val['enabled']) && empty($val['enabled'])) {
221 unset($this->fields[$key]);
222 }
223 }
224
225 // Translate some data of arrayofkeyval
226 if (is_object($langs)) {
227 foreach ($this->fields as $key => $val) {
228 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
229 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
230 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
231 }
232 }
233 }
234 }
235 }
236
244 public function create(User $user, $notrigger = false)
245 {
246 $resultcreate = $this->createCommon($user, $notrigger);
247
248 //$resultvalidate = $this->validate($user, $notrigger);
249
250 return $resultcreate;
251 }
252
260 public function createFromClone(User $user, $fromid)
261 {
262 global $langs, $extrafields;
263 $error = 0;
264
265 dol_syslog(__METHOD__, LOG_DEBUG);
266
267 $object = new self($this->db);
268
269 $this->db->begin();
270
271 // Load source object
272 $result = $object->fetchCommon($fromid);
273 if ($result > 0 && !empty($object->table_element_line)) {
274 $object->fetchLines();
275 }
276
277 // get lines so they will be clone
278 //foreach($this->lines as $line)
279 // $line->fetch_optionals();
280
281 // Reset some properties
282 unset($object->id);
283 unset($object->fk_user_creat);
284 unset($object->import_key);
285
286 // Clear fields
287 if (property_exists($object, 'ref')) {
288 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
289 }
290 if (property_exists($object, 'label')) {
291 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
292 }
293 if (property_exists($object, 'status')) {
294 $object->status = self::STATUS_DRAFT;
295 }
296 if (property_exists($object, 'date_creation')) {
297 $object->date_creation = dol_now();
298 }
299 if (property_exists($object, 'date_modification')) {
300 $object->date_modification = null;
301 }
302 // ...
303 // Clear extrafields that are unique
304 if (is_array($object->array_options) && count($object->array_options) > 0) {
305 $extrafields->fetch_name_optionals_label($this->table_element);
306 foreach ($object->array_options as $key => $option) {
307 $shortkey = preg_replace('/options_/', '', $key);
308 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
309 //var_dump($key);
310 //var_dump($clonedObj->array_options[$key]); exit;
311 unset($object->array_options[$key]);
312 }
313 }
314 }
315
316 // Create clone
317 $object->context['createfromclone'] = 'createfromclone';
318 $result = $object->createCommon($user);
319 if ($result < 0) {
320 $error++;
321 $this->error = $object->error;
322 $this->errors = $object->errors;
323 }
324
325 if (!$error) {
326 // copy internal contacts
327 if ($this->copy_linked_contact($object, 'internal') < 0) {
328 $error++;
329 }
330 }
331
332 if (!$error) {
333 // copy external contacts if same company
334 if (!empty($object->socid) && property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
335 if ($this->copy_linked_contact($object, 'external') < 0) {
336 $error++;
337 }
338 }
339 }
340
341 unset($object->context['createfromclone']);
342
343 // End
344 if (!$error) {
345 $this->db->commit();
346 return $object;
347 } else {
348 $this->db->rollback();
349 return -1;
350 }
351 }
352
360 public function fetch($id, $ref = null)
361 {
362 $result = $this->fetchCommon($id, $ref);
363 if ($result > 0 && !empty($this->table_element_line)) {
364 $this->fetchLines();
365 }
366 return $result;
367 }
368
374 public function fetchLines()
375 {
376 $this->lines = array();
377
378 $result = $this->fetchLinesCommon();
379 return $result;
380 }
381
382
394 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
395 {
396 global $conf;
397
398 dol_syslog(__METHOD__, LOG_DEBUG);
399
400 $records = array();
401
402 $sql = "SELECT ";
403 $sql .= $this->getFieldList('t');
404 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
405 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
406 $sql .= " WHERE t.entity IN (".getEntity($this->element).")";
407 } else {
408 $sql .= " WHERE 1 = 1";
409 }
410 // Manage filter
411 $sqlwhere = array();
412 if (count($filter) > 0) {
413 foreach ($filter as $key => $value) {
414 if ($key == 't.rowid') {
415 $sqlwhere[] = $key." = ".((int) $value);
416 } elseif (array_key_exists($key, $this->fields) && in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) {
417 $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
418 } elseif ($key == 'customsql') {
419 $sqlwhere[] = $value;
420 } elseif (strpos($value, '%') === false) {
421 $sqlwhere[] = $key." IN (".$this->db->sanitize($this->db->escape($value)).")";
422 } else {
423 $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
424 }
425 }
426 }
427 if (count($sqlwhere) > 0) {
428 $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
429 }
430
431 if (!empty($sortfield)) {
432 $sql .= $this->db->order($sortfield, $sortorder);
433 }
434 if (!empty($limit)) {
435 $sql .= $this->db->plimit($limit, $offset);
436 }
437
438 $resql = $this->db->query($sql);
439 if ($resql) {
440 $num = $this->db->num_rows($resql);
441 $i = 0;
442 while ($i < ($limit ? min($limit, $num) : $num)) {
443 $obj = $this->db->fetch_object($resql);
444
445 $record = new self($this->db);
446 $record->setVarsFromFetchObj($obj);
447
448 $records[$record->id] = $record;
449
450 $i++;
451 }
452 $this->db->free($resql);
453
454 return $records;
455 } else {
456 $this->errors[] = 'Error '.$this->db->lasterror();
457 dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
458
459 return -1;
460 }
461 }
462
470 public function update(User $user, $notrigger = false)
471 {
472 return $this->updateCommon($user, $notrigger);
473 }
474
482 public function delete(User $user, $notrigger = false)
483 {
484 return $this->deleteCommon($user, $notrigger);
485 //return $this->deleteCommon($user, $notrigger, 1);
486 }
487
496 public function deleteLine(User $user, $idline, $notrigger = false)
497 {
498 if ($this->status < 0) {
499 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
500 return -2;
501 }
502
503 return $this->deleteLineCommon($user, $idline, $notrigger);
504 }
505
506
514 public function validate($user, $notrigger = 0)
515 {
516 global $conf, $langs;
517
518 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
519
520 $error = 0;
521
522 // Protection
523 if ($this->status == self::STATUS_VALIDATED) {
524 dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
525 return 0;
526 }
527
528 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->hasRight('bookcal', 'availabilities', 'write'))
529 || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bookcal->availabilities->availabilities_advance->validate))))
530 {
531 $this->error='NotEnoughPermissions';
532 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
533 return -1;
534 }*/
535
536 $now = dol_now();
537
538 $this->db->begin();
539
540 // Define new ref
541 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
542 $num = $this->getNextNumRef();
543 } else {
544 $num = $this->ref;
545 }
546 $this->newref = $num;
547
548 if (!empty($num)) {
549 // Validate
550 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
551 $sql .= " SET ref = '".$this->db->escape($num)."',";
552 $sql .= " status = ".self::STATUS_VALIDATED;
553 if (!empty($this->fields['date_validation'])) {
554 $sql .= ", date_validation = '".$this->db->idate($now)."'";
555 }
556 if (!empty($this->fields['fk_user_valid'])) {
557 $sql .= ", fk_user_valid = ".((int) $user->id);
558 }
559 $sql .= " WHERE rowid = ".((int) $this->id);
560
561 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
562 $resql = $this->db->query($sql);
563 if (!$resql) {
564 dol_print_error($this->db);
565 $this->error = $this->db->lasterror();
566 $error++;
567 }
568
569 if (!$error && !$notrigger) {
570 // Call trigger
571 $result = $this->call_trigger('AVAILABILITIES_VALIDATE', $user);
572 if ($result < 0) {
573 $error++;
574 }
575 // End call triggers
576 }
577 }
578
579 if (!$error) {
580 $this->oldref = $this->ref;
581
582 // Rename directory if dir was a temporary ref
583 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
584 // Now we rename also files into index
585 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'availabilities/".$this->db->escape($this->newref)."'";
586 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'availabilities/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
587 $resql = $this->db->query($sql);
588 if (!$resql) {
589 $error++;
590 $this->error = $this->db->lasterror();
591 }
592 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'availabilities/".$this->db->escape($this->newref)."'";
593 $sql .= " WHERE filepath = 'availabilities/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
594 $resql = $this->db->query($sql);
595 if (!$resql) {
596 $error++;
597 $this->error = $this->db->lasterror();
598 }
599
600 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
601 $oldref = dol_sanitizeFileName($this->ref);
602 $newref = dol_sanitizeFileName($num);
603 $dirsource = $conf->bookcal->dir_output.'/availabilities/'.$oldref;
604 $dirdest = $conf->bookcal->dir_output.'/availabilities/'.$newref;
605 if (!$error && file_exists($dirsource)) {
606 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
607
608 if (@rename($dirsource, $dirdest)) {
609 dol_syslog("Rename ok");
610 // Rename docs starting with $oldref with $newref
611 $listoffiles = dol_dir_list($conf->bookcal->dir_output.'/availabilities/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
612 foreach ($listoffiles as $fileentry) {
613 $dirsource = $fileentry['name'];
614 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
615 $dirsource = $fileentry['path'].'/'.$dirsource;
616 $dirdest = $fileentry['path'].'/'.$dirdest;
617 @rename($dirsource, $dirdest);
618 }
619 }
620 }
621 }
622 }
623
624 // Set new ref and current status
625 if (!$error) {
626 $this->ref = $num;
627 $this->status = self::STATUS_VALIDATED;
628 }
629
630 if (!$error) {
631 $this->db->commit();
632 return 1;
633 } else {
634 $this->db->rollback();
635 return -1;
636 }
637 }
638
639
647 public function setDraft($user, $notrigger = 0)
648 {
649 // Protection
650 if ($this->status <= self::STATUS_DRAFT) {
651 return 0;
652 }
653
654 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bookcal->write))
655 || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bookcal->bookcal_advance->validate))))
656 {
657 $this->error='Permission denied';
658 return -1;
659 }*/
660
661 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'AVAILABILITIES_UNVALIDATE');
662 }
663
671 public function cancel($user, $notrigger = 0)
672 {
673 // Protection
674 if ($this->status != self::STATUS_VALIDATED) {
675 return 0;
676 }
677
678 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bookcal->write))
679 || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bookcal->bookcal_advance->validate))))
680 {
681 $this->error='Permission denied';
682 return -1;
683 }*/
684
685 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'AVAILABILITIES_CANCEL');
686 }
687
695 public function reopen($user, $notrigger = 0)
696 {
697 // Protection
698 if ($this->status != self::STATUS_CANCELED) {
699 return 0;
700 }
701
702 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bookcal->write))
703 || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->bookcal->bookcal_advance->validate))))
704 {
705 $this->error='Permission denied';
706 return -1;
707 }*/
708
709 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'AVAILABILITIES_REOPEN');
710 }
711
722 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
723 {
724 global $conf, $langs, $hookmanager;
725
726 if (!empty($conf->dol_no_mouse_hover)) {
727 $notooltip = 1; // Force disable tooltips
728 }
729
730 $result = '';
731
732 $label = img_picto('', $this->picto).' <u>'.$langs->trans("Availabilities").'</u>';
733 if (isset($this->status)) {
734 $label .= ' '.$this->getLibStatut(5);
735 }
736 $label .= '<br>';
737 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
738
739 $url = dol_buildpath('/bookcal/availabilities_card.php', 1).'?id='.$this->id;
740
741 if ($option != 'nolink') {
742 // Add param to save lastsearch_values or not
743 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
744 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
745 $add_save_lastsearch_values = 1;
746 }
747 if ($url && $add_save_lastsearch_values) {
748 $url .= '&save_lastsearch_values=1';
749 }
750 }
751
752 $linkclose = '';
753 if (empty($notooltip)) {
754 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
755 $label = $langs->trans("ShowAvailabilities");
756 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
757 }
758 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
759 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
760 } else {
761 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
762 }
763
764 if ($option == 'nolink' || empty($url)) {
765 $linkstart = '<span';
766 } else {
767 $linkstart = '<a href="'.$url.'"';
768 }
769 $linkstart .= $linkclose.'>';
770 if ($option == 'nolink' || empty($url)) {
771 $linkend = '</span>';
772 } else {
773 $linkend = '</a>';
774 }
775
776 $result .= $linkstart;
777
778 if (empty($this->showphoto_on_popup)) {
779 if ($withpicto) {
780 $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);
781 }
782 } else {
783 if ($withpicto) {
784 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
785
786 list($class, $module) = explode('@', $this->picto);
787 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
788 $filearray = dol_dir_list($upload_dir, "files");
789 $filename = $filearray[0]['name'];
790 if (!empty($filename)) {
791 $pospoint = strpos($filearray[0]['name'], '.');
792
793 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
794 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
795 $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>';
796 } else {
797 $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>';
798 }
799
800 $result .= '</div>';
801 } else {
802 $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);
803 }
804 }
805 }
806
807 if ($withpicto != 2) {
808 $result .= $this->ref;
809 }
810
811 $result .= $linkend;
812 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
813
814 global $action, $hookmanager;
815 $hookmanager->initHooks(array('availabilitiesdao'));
816 $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
817 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
818 if ($reshook > 0) {
819 $result = $hookmanager->resPrint;
820 } else {
821 $result .= $hookmanager->resPrint;
822 }
823
824 return $result;
825 }
826
834 public function getKanbanView($option = '', $arraydata = null)
835 {
836 global $conf, $langs;
837
838 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
839
840 $return = '<div class="box-flex-item box-flex-grow-zero">';
841 $return .= '<div class="info-box info-box-sm">';
842 $return .= '<span class="info-box-icon bg-infobox-action">';
843 $return .= img_picto('', $this->picto);
844 $return .= '</span>';
845 $return .= '<div class="info-box-content">';
846 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
847 if ($selected >= 0) {
848 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
849 }
850 if (property_exists($this, 'label')) {
851 $return .= ' <div class="inline-block opacitymedium valignmiddle tdoverflowmax100">'.$this->label.'</div>';
852 }
853 if (property_exists($this, 'amount')) {
854 $return .= '<br>';
855 $return .= '<span class="info-box-label amount">'.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency).'</span>';
856 }
857 if (method_exists($this, 'getLibStatut')) {
858 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
859 }
860 $return .= '</div>';
861 $return .= '</div>';
862 $return .= '</div>';
863
864 return $return;
865 }
866
873 public function getLabelStatus($mode = 0)
874 {
875 return $this->LibStatut($this->status, $mode);
876 }
877
884 public function getLibStatut($mode = 0)
885 {
886 return $this->LibStatut($this->status, $mode);
887 }
888
889 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
897 public function LibStatut($status, $mode = 0)
898 {
899 // phpcs:enable
900 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
901 global $langs;
902 //$langs->load("agenda");
903 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
904 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
905 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
906 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
907 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
908 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
909 }
910
911 $statusType = 'status'.$status;
912 if ($status == self::STATUS_VALIDATED) {
913 $statusType = 'status4';
914 }
915 if ($status == self::STATUS_CANCELED) {
916 $statusType = 'status6';
917 }
918
919 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
920 }
921
928 public function info($id)
929 {
930 $sql = "SELECT rowid,";
931 $sql .= " date_creation as datec, tms as datem,";
932 $sql .= " fk_user_creat, fk_user_modif";
933 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
934 $sql .= " WHERE t.rowid = ".((int) $id);
935
936 $result = $this->db->query($sql);
937 if ($result) {
938 if ($this->db->num_rows($result)) {
939 $obj = $this->db->fetch_object($result);
940
941 $this->id = $obj->rowid;
942
943 $this->user_creation_id = $obj->fk_user_creat;
944 $this->user_modification_id = $obj->fk_user_modif;
945 $this->date_creation = $this->db->jdate($obj->datec);
946 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
947 }
948
949 $this->db->free($result);
950 } else {
951 dol_print_error($this->db);
952 }
953 }
954
961 public function initAsSpecimen()
962 {
963 // Set here init that are not commonf fields
964 // $this->property1 = ...
965 // $this->property2 = ...
966
967 $this->initAsSpecimenCommon();
968 }
969
975 public function getLinesArray()
976 {
977 $this->lines = array();
978
979 $objectline = new AvailabilitiesLine($this->db);
980 $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_availabilities = '.((int) $this->id)));
981
982 if (is_numeric($result)) {
983 $this->error = $objectline->error;
984 $this->errors = $objectline->errors;
985 return $result;
986 } else {
987 $this->lines = $result;
988 return $this->lines;
989 }
990 }
991
997 public function getNextNumRef()
998 {
999 global $langs, $conf;
1000 $langs->load("agenda");
1001
1002 if (!getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON')) {
1003 $conf->global->BOOKCAL_AVAILABILITIES_ADDON = 'mod_availabilities_standard';
1004 }
1005
1006 if (getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON')) {
1007 $mybool = false;
1008
1009 $file = getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON') . ".php";
1010 $classname = $conf->global->BOOKCAL_AVAILABILITIES_ADDON;
1011
1012 // Include file with class
1013 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1014 foreach ($dirmodels as $reldir) {
1015 $dir = dol_buildpath($reldir."core/modules/bookcal/");
1016
1017 // Load file with numbering class (if found)
1018 $mybool |= @include_once $dir.$file;
1019 }
1020
1021 if ($mybool === false) {
1022 dol_print_error('', "Failed to include file ".$file);
1023 return '';
1024 }
1025
1026 if (class_exists($classname)) {
1027 $obj = new $classname();
1028 $numref = $obj->getNextValue($this);
1029
1030 if ($numref != '' && $numref != '-1') {
1031 return $numref;
1032 } else {
1033 $this->error = $obj->error;
1034 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1035 return "";
1036 }
1037 } else {
1038 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
1039 return "";
1040 }
1041 } else {
1042 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1043 return "";
1044 }
1045 }
1046
1058 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1059 {
1060 global $conf, $langs;
1061
1062 $result = 0;
1063 $includedocgeneration = 0;
1064
1065 $langs->load("agenda");
1066
1067 if (!dol_strlen($modele)) {
1068 $modele = 'standard_availabilities';
1069
1070 if (!empty($this->model_pdf)) {
1071 $modele = $this->model_pdf;
1072 } elseif (getDolGlobalString('AVAILABILITIES_ADDON_PDF')) {
1073 $modele = $conf->global->AVAILABILITIES_ADDON_PDF;
1074 }
1075 }
1076
1077 $modelpath = "core/modules/bookcal/doc/";
1078
1079 if ($includedocgeneration && !empty($modele)) {
1080 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1081 }
1082
1083 return $result;
1084 }
1085
1093 public function doScheduledJob()
1094 {
1095 global $conf, $langs;
1096
1097 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1098
1099 $error = 0;
1100 $this->output = '';
1101 $this->error = '';
1102
1103 dol_syslog(__METHOD__, LOG_DEBUG);
1104
1105 $now = dol_now();
1106
1107 $this->db->begin();
1108
1109 // ...
1110
1111 $this->db->commit();
1112
1113 return $error;
1114 }
1115}
1116
1117
1118require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1119
1124{
1125 // To complete with content of an object AvailabilitiesLine
1126 // We should have a field rowid, fk_availabilities and position
1127
1131 public $isextrafieldmanaged = 0;
1132
1138 public function __construct(DoliDB $db)
1139 {
1140 $this->db = $db;
1141 }
1142}
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Definition security.php:604
$object ref
Definition info.php:79
Class for Availabilities.
getLabelStatus($mode=0)
Return the label of the status.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
fetch($id, $ref=null)
Load object in memory from the database.
fetchLines()
Load object lines in memory from the database.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
create(User $user, $notrigger=false)
Create object into database.
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
update(User $user, $notrigger=false)
Update object into database.
getLibStatut($mode=0)
Return the label of the status.
__construct(DoliDB $db)
Constructor.
LibStatut($status, $mode=0)
Return the status.
createFromClone(User $user, $fromid)
Clone an object into another one.
info($id)
Load the info information in the object.
setDraft($user, $notrigger=0)
Set draft status.
validate($user, $notrigger=0)
Validate object.
getKanbanView($option='', $arraydata=null)
Return a thumb for kanban views.
getLinesArray()
Create an array of lines.
cancel($user, $notrigger=0)
Set cancel status.
reopen($user, $notrigger=0)
Set back to validated status.
Class AvailabilitiesLine.
__construct(DoliDB $db)
Constructor.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
createCommon(User $user, $notrigger=false)
Create object into database.
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
updateCommon(User $user, $notrigger=false)
Update object into database.
fetchLinesCommon($morewhere='', $noextrafields=0)
Load object in memory from the database.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
Class to manage Dolibarr users.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:62
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_now($mode='auto')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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.
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.