dolibarr 21.0.0-alpha
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 * 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 = 'bookcal';
41
45 public $element = 'availabilities';
46
50 public $table_element = 'bookcal_availabilities';
51
55 public $picto = 'fa-calendar-check';
56
57
58 const STATUS_DRAFT = 0;
59 const STATUS_VALIDATED = 1;
60 const STATUS_CANCELED = 9;
61
62
102 // BEGIN MODULEBUILDER PROPERTIES
106 public $fields = array(
107 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 2, 'noteditable' => 1, 'index' => 1, 'css' => 'left', 'comment' => "Id"),
108 '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,),
109 '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'),
110 'description' => array('type' => 'text', 'label' => 'Description', 'enabled' => 1, 'position' => 60, 'notnull' => 0, 'visible' => 3, 'validate' => 1,),
111 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 61, 'notnull' => 0, 'visible' => 0, 'cssview' => 'wordbreak', 'validate' => 1,),
112 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 62, 'notnull' => 0, 'visible' => 0, 'cssview' => 'wordbreak', 'validate' => 1,),
113 'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -2,),
114 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2,),
115 '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'),
116 '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'),
117 'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'LastMainDoc', 'enabled' => 1, 'position' => 600, 'notnull' => 0, 'visible' => 0,),
118 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => -2,),
119 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'position' => 1010, 'notnull' => -1, 'visible' => 0,),
120 'start' => array('type' => 'date', 'label' => 'Start Date', 'enabled' => 1, 'position' => 40, 'notnull' => 1, 'visible' => 1, 'searchall' => 1,),
121 'end' => array('type' => 'date', 'label' => 'End Date', 'enabled' => 1, 'position' => 45, 'notnull' => 1, 'visible' => 1, 'searchall' => 1,),
122 'duration' => array('type' => 'integer', 'label' => 'DurationOfRange', 'enabled' => 1, 'position' => 47, 'notnull' => 1, 'visible' => 1, 'default' => '30', 'css' => 'width50 right'),
123 'startHour' => array('type' => 'integer', 'label' => 'Start Hour', 'enabled' => 1, 'position' => 46, 'notnull' => 1, 'visible' => 1,),
124 'endHour' => array('type' => 'integer', 'label' => 'End Hour', 'enabled' => 1, 'position' => 46.5, 'notnull' => 1, 'visible' => 1,),
125 '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),
126 );
130 public $rowid;
134 public $label;
138 public $description;
142 public $note_public;
146 public $note_private;
150 public $fk_user_creat;
154 public $fk_user_modif;
158 public $last_main_doc;
162 public $import_key;
166 public $model_pdf;
170 public $status;
174 public $start;
178 public $end;
182 public $duration;
186 public $startHour;
190 public $endHour;
194 public $fk_bookcal_calendar;
195 // END MODULEBUILDER PROPERTIES
196
197
198 // If this object has a subtable with lines
199
200 // /**
201 // * @var string Name of subtable line
202 // */
203 // public $table_element_line = 'bookcal_availabilitiesline';
204
205 // /**
206 // * @var string Field with ID of parent key if this object has a parent
207 // */
208 // public $fk_element = 'fk_availabilities';
209
210 // /**
211 // * @var string Name of subtable class that manage subtable lines
212 // */
213 // public $class_element_line = 'Availabilitiesline';
214
215 // /**
216 // * @var array List of child tables. To test if we can delete object.
217 // */
218 // protected $childtables = array();
219
220 // /**
221 // * @var array List of child tables. To know object to delete on cascade.
222 // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
223 // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
224 // */
225 // protected $childtablesoncascade = array('bookcal_availabilitiesdet');
226
227 // /**
228 // * @var AvailabilitiesLine[] Array of subtable lines
229 // */
230 // public $lines = array();
231
232
233
239 public function __construct(DoliDB $db)
240 {
241 global $conf, $langs;
242
243 $this->db = $db;
244
245 $this->ismultientitymanaged = 'fk_bookcal_calendar@bookcal_calendar';
246 $this->isextrafieldmanaged = 1;
247
248 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid']) && !empty($this->fields['ref'])) { // @phan-suppress-current-line PhanTypeMismatchProperty
249 $this->fields['rowid']['visible'] = 0;
250 }
251 if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) {
252 $this->fields['entity']['enabled'] = 0;
253 }
254
255 // Example to show how to set values of fields definition dynamically
256 /*if ($user->hasRight('bookcal', 'availabilities', 'read')) {
257 $this->fields['myfield']['visible'] = 1;
258 $this->fields['myfield']['noteditable'] = 0;
259 }*/
260
261 // Unset fields that are disabled
262 foreach ($this->fields as $key => $val) {
263 if (isset($val['enabled']) && empty($val['enabled'])) {
264 unset($this->fields[$key]);
265 }
266 }
267
268 // Translate some data of arrayofkeyval
269 if (is_object($langs)) {
270 foreach ($this->fields as $key => $val) {
271 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
272 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
273 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
274 }
275 }
276 }
277 }
278 }
279
287 public function create(User $user, $notrigger = 0)
288 {
289 $resultcreate = $this->createCommon($user, $notrigger);
290
291 //$resultvalidate = $this->validate($user, $notrigger);
292
293 return $resultcreate;
294 }
295
303 public function createFromClone(User $user, $fromid)
304 {
305 global $langs, $extrafields;
306 $error = 0;
307
308 dol_syslog(__METHOD__, LOG_DEBUG);
309
310 $object = new self($this->db);
311
312 $this->db->begin();
313
314 // Load source object
315 $result = $object->fetchCommon($fromid);
316 if ($result > 0 && !empty($object->table_element_line)) {
317 $object->fetchLines();
318 }
319
320 // get lines so they will be clone
321 //foreach($this->lines as $line)
322 // $line->fetch_optionals();
323
324 // Reset some properties
325 unset($object->id);
326 unset($object->fk_user_creat);
327 unset($object->import_key);
328
329 // Clear fields
330 if (property_exists($object, 'ref')) {
331 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
332 }
333 if (property_exists($object, 'label')) {
334 // @phan-suppress-next-line PhanTypeInvalidDimOffset
335 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
336 }
337 if (property_exists($object, 'status')) {
338 $object->status = self::STATUS_DRAFT;
339 }
340 if (property_exists($object, 'date_creation')) {
341 $object->date_creation = dol_now();
342 }
343 if (property_exists($object, 'date_modification')) {
344 $object->date_modification = null;
345 }
346 // ...
347 // Clear extrafields that are unique
348 if (is_array($object->array_options) && count($object->array_options) > 0) {
349 $extrafields->fetch_name_optionals_label($this->table_element);
350 foreach ($object->array_options as $key => $option) {
351 $shortkey = preg_replace('/options_/', '', $key);
352 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
353 //var_dump($key);
354 //var_dump($clonedObj->array_options[$key]); exit;
355 unset($object->array_options[$key]);
356 }
357 }
358 }
359
360 // Create clone
361 $object->context['createfromclone'] = 'createfromclone';
362 $result = $object->createCommon($user);
363 if ($result < 0) {
364 $error++;
365 $this->error = $object->error;
366 $this->errors = $object->errors;
367 }
368
369 if (!$error) {
370 // copy internal contacts
371 if ($this->copy_linked_contact($object, 'internal') < 0) {
372 $error++;
373 }
374 }
375
376 if (!$error) {
377 // copy external contacts if same company
378 if (!empty($object->socid) && property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
379 if ($this->copy_linked_contact($object, 'external') < 0) {
380 $error++;
381 }
382 }
383 }
384
385 unset($object->context['createfromclone']);
386
387 // End
388 if (!$error) {
389 $this->db->commit();
390 return $object;
391 } else {
392 $this->db->rollback();
393 return -1;
394 }
395 }
396
404 public function fetch($id, $ref = null)
405 {
406 $result = $this->fetchCommon($id, $ref);
407 if ($result > 0 && !empty($this->table_element_line)) {
408 $this->fetchLines();
409 }
410 return $result;
411 }
412
418 public function fetchLines()
419 {
420 $this->lines = array();
421
422 $result = $this->fetchLinesCommon();
423 return $result;
424 }
425
426
439 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
440 {
441 dol_syslog(__METHOD__, LOG_DEBUG);
442
443 $records = array();
444
445 $sql = "SELECT ";
446 $sql .= $this->getFieldList('t');
447 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
448 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
449 $sql .= " WHERE t.entity IN (".getEntity($this->element).")";
450 } else {
451 $sql .= " WHERE 1 = 1";
452 }
453
454 // Manage filter
455 $errormessage = '';
456 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
457 if ($errormessage) {
458 $this->errors[] = $errormessage;
459 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
460 return -1;
461 }
462
463 if (!empty($sortfield)) {
464 $sql .= $this->db->order($sortfield, $sortorder);
465 }
466 if (!empty($limit)) {
467 $sql .= $this->db->plimit($limit, $offset);
468 }
469
470 $resql = $this->db->query($sql);
471 if ($resql) {
472 $num = $this->db->num_rows($resql);
473 $i = 0;
474 while ($i < ($limit ? min($limit, $num) : $num)) {
475 $obj = $this->db->fetch_object($resql);
476
477 $record = new self($this->db);
478 $record->setVarsFromFetchObj($obj);
479
480 $records[$record->id] = $record;
481
482 $i++;
483 }
484 $this->db->free($resql);
485
486 return $records;
487 } else {
488 $this->errors[] = 'Error '.$this->db->lasterror();
489 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
490
491 return -1;
492 }
493 }
494
502 public function update(User $user, $notrigger = 0)
503 {
504 return $this->updateCommon($user, $notrigger);
505 }
506
514 public function delete(User $user, $notrigger = 0)
515 {
516 return $this->deleteCommon($user, $notrigger);
517 //return $this->deleteCommon($user, $notrigger, 1);
518 }
519
528 public function deleteLine(User $user, $idline, $notrigger = 0)
529 {
530 if ($this->status < 0) {
531 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
532 return -2;
533 }
534
535 return $this->deleteLineCommon($user, $idline, $notrigger);
536 }
537
538
546 public function validate($user, $notrigger = 0)
547 {
548 global $conf, $langs;
549
550 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
551
552 $error = 0;
553
554 // Protection
555 if ($this->status == self::STATUS_VALIDATED) {
556 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
557 return 0;
558 }
559
560 $now = dol_now();
561
562 $this->db->begin();
563
564 // Define new ref
565 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
566 $num = $this->getNextNumRef();
567 } else {
568 $num = $this->ref;
569 }
570 $this->newref = $num;
571
572 if (!empty($num)) {
573 // Validate
574 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
575 $sql .= " SET label = '".$this->db->escape($num)."',";
576 $sql .= " status = ".self::STATUS_VALIDATED;
577 if (!empty($this->fields['date_validation'])) { // @phan-suppress-current-line PhanTypeMismatchProperty
578 $sql .= ", date_validation = '".$this->db->idate($now)."'";
579 }
580 if (!empty($this->fields['fk_user_valid'])) { // @phan-suppress-current-line PhanTypeMismatchProperty
581 $sql .= ", fk_user_valid = ".((int) $user->id);
582 }
583 $sql .= " WHERE rowid = ".((int) $this->id);
584
585 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
586 $resql = $this->db->query($sql);
587 if (!$resql) {
588 dol_print_error($this->db);
589 $this->error = $this->db->lasterror();
590 $error++;
591 }
592
593 if (!$error && !$notrigger) {
594 // Call trigger
595 $result = $this->call_trigger('AVAILABILITIES_VALIDATE', $user);
596 if ($result < 0) {
597 $error++;
598 }
599 // End call triggers
600 }
601 }
602
603 if (!$error) {
604 $this->oldref = $this->ref;
605
606 // Rename directory if dir was a temporary ref
607 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
608 // Now we rename also files into index
609 $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)."'";
610 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'availabilities/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
611 $resql = $this->db->query($sql);
612 if (!$resql) {
613 $error++;
614 $this->error = $this->db->lasterror();
615 }
616 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'availabilities/".$this->db->escape($this->newref)."'";
617 $sql .= " WHERE filepath = 'availabilities/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
618 $resql = $this->db->query($sql);
619 if (!$resql) {
620 $error++;
621 $this->error = $this->db->lasterror();
622 }
623
624 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
625 $oldref = dol_sanitizeFileName($this->ref);
626 $newref = dol_sanitizeFileName($num);
627 $dirsource = $conf->bookcal->dir_output.'/availabilities/'.$oldref;
628 $dirdest = $conf->bookcal->dir_output.'/availabilities/'.$newref;
629 if (!$error && file_exists($dirsource)) {
630 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
631
632 if (@rename($dirsource, $dirdest)) {
633 dol_syslog("Rename ok");
634 // Rename docs starting with $oldref with $newref
635 $listoffiles = dol_dir_list($conf->bookcal->dir_output.'/availabilities/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
636 foreach ($listoffiles as $fileentry) {
637 $dirsource = $fileentry['name'];
638 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
639 $dirsource = $fileentry['path'].'/'.$dirsource;
640 $dirdest = $fileentry['path'].'/'.$dirdest;
641 @rename($dirsource, $dirdest);
642 }
643 }
644 }
645 }
646 }
647
648 // Set new ref and current status
649 if (!$error) {
650 $this->ref = $num;
651 $this->status = self::STATUS_VALIDATED;
652 }
653
654 if (!$error) {
655 $this->db->commit();
656 return 1;
657 } else {
658 $this->db->rollback();
659 return -1;
660 }
661 }
662
663
671 public function setDraft($user, $notrigger = 0)
672 {
673 // Protection
674 if ($this->status <= self::STATUS_DRAFT) {
675 return 0;
676 }
677
678 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'AVAILABILITIES_UNVALIDATE');
679 }
680
688 public function cancel($user, $notrigger = 0)
689 {
690 // Protection
691 if ($this->status != self::STATUS_VALIDATED) {
692 return 0;
693 }
694
695 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'AVAILABILITIES_CANCEL');
696 }
697
705 public function reopen($user, $notrigger = 0)
706 {
707 // Protection
708 if ($this->status != self::STATUS_CANCELED) {
709 return 0;
710 }
711
712 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'AVAILABILITIES_REOPEN');
713 }
714
725 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
726 {
727 global $conf, $langs, $hookmanager;
728
729 if (!empty($conf->dol_no_mouse_hover)) {
730 $notooltip = 1; // Force disable tooltips
731 }
732
733 $result = '';
734
735 $label = img_picto('', $this->picto).' <u>'.$langs->trans("Availabilities").'</u>';
736 if (isset($this->status)) {
737 $label .= ' '.$this->getLibStatut(5);
738 }
739 $label .= '<br>';
740 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
741
742 $url = dol_buildpath('/bookcal/availabilities_card.php', 1).'?id='.$this->id;
743
744 if ($option != 'nolink') {
745 // Add param to save lastsearch_values or not
746 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
747 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
748 $add_save_lastsearch_values = 1;
749 }
750 if ($url && $add_save_lastsearch_values) {
751 $url .= '&save_lastsearch_values=1';
752 }
753 }
754
755 $linkclose = '';
756 if (empty($notooltip)) {
757 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
758 $label = $langs->trans("ShowAvailabilities");
759 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
760 }
761 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
762 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
763 } else {
764 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
765 }
766
767 if ($option == 'nolink' || empty($url)) {
768 $linkstart = '<span';
769 } else {
770 $linkstart = '<a href="'.$url.'"';
771 }
772 $linkstart .= $linkclose.'>';
773 if ($option == 'nolink' || empty($url)) {
774 $linkend = '</span>';
775 } else {
776 $linkend = '</a>';
777 }
778
779 $result .= $linkstart;
780
781 if (empty($this->showphoto_on_popup)) {
782 if ($withpicto) {
783 $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);
784 }
785 } else {
786 if ($withpicto) {
787 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
788
789 list($class, $module) = explode('@', $this->picto);
790 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
791 $filearray = dol_dir_list($upload_dir, "files");
792 $filename = $filearray[0]['name'];
793 if (!empty($filename)) {
794 $pospoint = strpos($filearray[0]['name'], '.');
795
796 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
797 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
798 $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>';
799 } else {
800 $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>';
801 }
802
803 $result .= '</div>';
804 } else {
805 $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);
806 }
807 }
808 }
809
810 if ($withpicto != 2) {
811 $result .= $this->ref;
812 }
813
814 $result .= $linkend;
815 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
816
817 global $action, $hookmanager;
818 $hookmanager->initHooks(array('availabilitiesdao'));
819 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
820 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
821 if ($reshook > 0) {
822 $result = $hookmanager->resPrint;
823 } else {
824 $result .= $hookmanager->resPrint;
825 }
826
827 return $result;
828 }
829
837 public function getKanbanView($option = '', $arraydata = null)
838 {
839 global $conf, $langs;
840
841 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
842
843 $return = '<div class="box-flex-item box-flex-grow-zero">';
844 $return .= '<div class="info-box info-box-sm">';
845 $return .= '<span class="info-box-icon bg-infobox-action">';
846 $return .= img_picto('', $this->picto);
847 $return .= '</span>';
848 $return .= '<div class="info-box-content">';
849 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
850 if ($selected >= 0) {
851 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
852 }
853 if (property_exists($this, 'label')) {
854 $return .= ' <div class="inline-block opacitymedium valignmiddle tdoverflowmax100">'.$this->label.'</div>';
855 }
856 if (property_exists($this, 'amount')) {
857 $return .= '<br>';
858 $return .= '<span class="info-box-label amount">'.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency).'</span>';
859 }
860 if (method_exists($this, 'getLibStatut')) {
861 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
862 }
863 $return .= '</div>';
864 $return .= '</div>';
865 $return .= '</div>';
866
867 return $return;
868 }
869
876 public function getLabelStatus($mode = 0)
877 {
878 return $this->LibStatut($this->status, $mode);
879 }
880
887 public function getLibStatut($mode = 0)
888 {
889 return $this->LibStatut($this->status, $mode);
890 }
891
892 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
900 public function LibStatut($status, $mode = 0)
901 {
902 // phpcs:enable
903 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
904 global $langs;
905 //$langs->load("agenda");
906 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
907 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
908 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
909 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
910 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
911 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
912 }
913
914 $statusType = 'status'.$status;
915 if ($status == self::STATUS_VALIDATED) {
916 $statusType = 'status4';
917 }
918 if ($status == self::STATUS_CANCELED) {
919 $statusType = 'status6';
920 }
921
922 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
923 }
924
931 public function info($id)
932 {
933 $sql = "SELECT rowid,";
934 $sql .= " date_creation as datec, tms as datem,";
935 $sql .= " fk_user_creat, fk_user_modif";
936 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
937 $sql .= " WHERE t.rowid = ".((int) $id);
938
939 $result = $this->db->query($sql);
940 if ($result) {
941 if ($this->db->num_rows($result)) {
942 $obj = $this->db->fetch_object($result);
943
944 $this->id = $obj->rowid;
945
946 $this->user_creation_id = $obj->fk_user_creat;
947 $this->user_modification_id = $obj->fk_user_modif;
948 $this->date_creation = $this->db->jdate($obj->datec);
949 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
950 }
951
952 $this->db->free($result);
953 } else {
954 dol_print_error($this->db);
955 }
956 }
957
964 public function initAsSpecimen()
965 {
966 // Set here init that are not commonf fields
967 // $this->property1 = ...
968 // $this->property2 = ...
969
970 return $this->initAsSpecimenCommon();
971 }
972
978 public function getLinesArray()
979 {
980 $this->lines = array();
981
982 $objectline = new AvailabilitiesLine($this->db);
983 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_availabilities:=:'.((int) $this->id).')');
984
985 if (is_numeric($result)) {
986 $this->error = $objectline->error;
987 $this->errors = $objectline->errors;
988 return $result;
989 } else {
990 $this->lines = $result;
991 return $this->lines;
992 }
993 }
994
1000 public function getNextNumRef()
1001 {
1002 global $langs, $conf;
1003 $langs->load("agenda");
1004
1005 if (!getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON')) {
1006 $conf->global->BOOKCAL_AVAILABILITIES_ADDON = 'mod_availabilities_standard';
1007 }
1008
1009 if (getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON')) {
1010 $mybool = false;
1011
1012 $file = getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON') . ".php";
1013 $classname = getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON');
1014
1015 // Include file with class
1016 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1017 foreach ($dirmodels as $reldir) {
1018 $dir = dol_buildpath($reldir."core/modules/bookcal/");
1019
1020 // Load file with numbering class (if found)
1021 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1022 }
1023
1024 if (!$mybool) {
1025 dol_print_error(null, "Failed to include file ".$file);
1026 return '';
1027 }
1028
1029 if (class_exists($classname)) {
1030 $obj = new $classname();
1031 '@phan-var-force CommonNumRefGenerator $obj';
1032
1033 $numref = $obj->getNextValue($this);
1034
1035 if ($numref != '' && $numref != '-1') {
1036 return $numref;
1037 } else {
1038 $this->error = $obj->error;
1039 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1040 return "";
1041 }
1042 } else {
1043 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
1044 return "";
1045 }
1046 } else {
1047 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1048 return "";
1049 }
1050 }
1051
1063 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1064 {
1065 global $conf, $langs;
1066
1067 $result = 0;
1068 $includedocgeneration = 0;
1069
1070 $langs->load("agenda");
1071
1072 if (!dol_strlen($modele)) {
1073 $modele = 'standard_availabilities';
1074
1075 if (!empty($this->model_pdf)) {
1076 $modele = $this->model_pdf;
1077 } elseif (getDolGlobalString('AVAILABILITIES_ADDON_PDF')) {
1078 $modele = getDolGlobalString('AVAILABILITIES_ADDON_PDF');
1079 }
1080 }
1081
1082 $modelpath = "core/modules/bookcal/doc/";
1083
1084 if ($includedocgeneration && !empty($modele)) {
1085 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1086 }
1087
1088 return $result;
1089 }
1090
1098 public function doScheduledJob()
1099 {
1100 global $conf, $langs;
1101
1102 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1103
1104 $error = 0;
1105 $this->output = '';
1106 $this->error = '';
1107
1108 dol_syslog(__METHOD__, LOG_DEBUG);
1109
1110 $now = dol_now();
1111
1112 $this->db->begin();
1113
1114 // ...
1115
1116 $this->db->commit();
1117
1118 return $error;
1119 }
1120}
1121
1122
1123require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1124
1129{
1130 // To complete with content of an object AvailabilitiesLine
1131 // We should have a field rowid, fk_availabilities and position
1132
1138 public function __construct(DoliDB $db)
1139 {
1140 $this->db = $db;
1141 $this->isextrafieldmanaged = 0;
1142 }
1143}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
$object ref
Definition info.php:79
Class for Availabilities.
create(User $user, $notrigger=0)
Create object into database.
getLabelStatus($mode=0)
Return the label of the status.
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.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
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 optionally the picto)
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.
deleteLine(User $user, $idline, $notrigger=0)
Delete a line of object in database.
update(User $user, $notrigger=0)
Update object into database.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load list of objects in memory from the database.
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,...
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.
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.
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:162
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.
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.