dolibarr 20.0.0
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 );
127 public $rowid;
128 public $label;
129 public $description;
130 public $note_public;
131 public $note_private;
132 public $date_creation;
133 public $fk_user_creat;
134 public $fk_user_modif;
135 public $last_main_doc;
136 public $import_key;
137 public $model_pdf;
138 public $status;
139 public $start;
140 public $end;
141 public $duration;
142 public $startHour;
143 public $endHour;
144 public $fk_bookcal_calendar;
145 // END MODULEBUILDER PROPERTIES
146
147
148 // If this object has a subtable with lines
149
150 // /**
151 // * @var string Name of subtable line
152 // */
153 // public $table_element_line = 'bookcal_availabilitiesline';
154
155 // /**
156 // * @var string Field with ID of parent key if this object has a parent
157 // */
158 // public $fk_element = 'fk_availabilities';
159
160 // /**
161 // * @var string Name of subtable class that manage subtable lines
162 // */
163 // public $class_element_line = 'Availabilitiesline';
164
165 // /**
166 // * @var array List of child tables. To test if we can delete object.
167 // */
168 // protected $childtables = array();
169
170 // /**
171 // * @var array List of child tables. To know object to delete on cascade.
172 // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
173 // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
174 // */
175 // protected $childtablesoncascade = array('bookcal_availabilitiesdet');
176
177 // /**
178 // * @var AvailabilitiesLine[] Array of subtable lines
179 // */
180 // public $lines = array();
181
182
183
189 public function __construct(DoliDB $db)
190 {
191 global $conf, $langs;
192
193 $this->db = $db;
194
195 $this->ismultientitymanaged = 'fk_bookcal_calendar@bookcal_calendar';
196 $this->isextrafieldmanaged = 1;
197
198 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid']) && !empty($this->fields['ref'])) {
199 $this->fields['rowid']['visible'] = 0;
200 }
201 if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) {
202 $this->fields['entity']['enabled'] = 0;
203 }
204
205 // Example to show how to set values of fields definition dynamically
206 /*if ($user->hasRight('bookcal', 'availabilities', 'read')) {
207 $this->fields['myfield']['visible'] = 1;
208 $this->fields['myfield']['noteditable'] = 0;
209 }*/
210
211 // Unset fields that are disabled
212 foreach ($this->fields as $key => $val) {
213 if (isset($val['enabled']) && empty($val['enabled'])) {
214 unset($this->fields[$key]);
215 }
216 }
217
218 // Translate some data of arrayofkeyval
219 if (is_object($langs)) {
220 foreach ($this->fields as $key => $val) {
221 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
222 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
223 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
224 }
225 }
226 }
227 }
228 }
229
237 public function create(User $user, $notrigger = 0)
238 {
239 $resultcreate = $this->createCommon($user, $notrigger);
240
241 //$resultvalidate = $this->validate($user, $notrigger);
242
243 return $resultcreate;
244 }
245
253 public function createFromClone(User $user, $fromid)
254 {
255 global $langs, $extrafields;
256 $error = 0;
257
258 dol_syslog(__METHOD__, LOG_DEBUG);
259
260 $object = new self($this->db);
261
262 $this->db->begin();
263
264 // Load source object
265 $result = $object->fetchCommon($fromid);
266 if ($result > 0 && !empty($object->table_element_line)) {
267 $object->fetchLines();
268 }
269
270 // get lines so they will be clone
271 //foreach($this->lines as $line)
272 // $line->fetch_optionals();
273
274 // Reset some properties
275 unset($object->id);
276 unset($object->fk_user_creat);
277 unset($object->import_key);
278
279 // Clear fields
280 if (property_exists($object, 'ref')) {
281 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
282 }
283 if (property_exists($object, 'label')) {
284 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
285 }
286 if (property_exists($object, 'status')) {
287 $object->status = self::STATUS_DRAFT;
288 }
289 if (property_exists($object, 'date_creation')) {
290 $object->date_creation = dol_now();
291 }
292 if (property_exists($object, 'date_modification')) {
293 $object->date_modification = null;
294 }
295 // ...
296 // Clear extrafields that are unique
297 if (is_array($object->array_options) && count($object->array_options) > 0) {
298 $extrafields->fetch_name_optionals_label($this->table_element);
299 foreach ($object->array_options as $key => $option) {
300 $shortkey = preg_replace('/options_/', '', $key);
301 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
302 //var_dump($key);
303 //var_dump($clonedObj->array_options[$key]); exit;
304 unset($object->array_options[$key]);
305 }
306 }
307 }
308
309 // Create clone
310 $object->context['createfromclone'] = 'createfromclone';
311 $result = $object->createCommon($user);
312 if ($result < 0) {
313 $error++;
314 $this->error = $object->error;
315 $this->errors = $object->errors;
316 }
317
318 if (!$error) {
319 // copy internal contacts
320 if ($this->copy_linked_contact($object, 'internal') < 0) {
321 $error++;
322 }
323 }
324
325 if (!$error) {
326 // copy external contacts if same company
327 if (!empty($object->socid) && property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
328 if ($this->copy_linked_contact($object, 'external') < 0) {
329 $error++;
330 }
331 }
332 }
333
334 unset($object->context['createfromclone']);
335
336 // End
337 if (!$error) {
338 $this->db->commit();
339 return $object;
340 } else {
341 $this->db->rollback();
342 return -1;
343 }
344 }
345
353 public function fetch($id, $ref = null)
354 {
355 $result = $this->fetchCommon($id, $ref);
356 if ($result > 0 && !empty($this->table_element_line)) {
357 $this->fetchLines();
358 }
359 return $result;
360 }
361
367 public function fetchLines()
368 {
369 $this->lines = array();
370
371 $result = $this->fetchLinesCommon();
372 return $result;
373 }
374
375
388 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
389 {
390 dol_syslog(__METHOD__, LOG_DEBUG);
391
392 $records = array();
393
394 $sql = "SELECT ";
395 $sql .= $this->getFieldList('t');
396 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
397 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
398 $sql .= " WHERE t.entity IN (".getEntity($this->element).")";
399 } else {
400 $sql .= " WHERE 1 = 1";
401 }
402
403 // Manage filter
404 $errormessage = '';
405 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
406 if ($errormessage) {
407 $this->errors[] = $errormessage;
408 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
409 return -1;
410 }
411
412 if (!empty($sortfield)) {
413 $sql .= $this->db->order($sortfield, $sortorder);
414 }
415 if (!empty($limit)) {
416 $sql .= $this->db->plimit($limit, $offset);
417 }
418
419 $resql = $this->db->query($sql);
420 if ($resql) {
421 $num = $this->db->num_rows($resql);
422 $i = 0;
423 while ($i < ($limit ? min($limit, $num) : $num)) {
424 $obj = $this->db->fetch_object($resql);
425
426 $record = new self($this->db);
427 $record->setVarsFromFetchObj($obj);
428
429 $records[$record->id] = $record;
430
431 $i++;
432 }
433 $this->db->free($resql);
434
435 return $records;
436 } else {
437 $this->errors[] = 'Error '.$this->db->lasterror();
438 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
439
440 return -1;
441 }
442 }
443
451 public function update(User $user, $notrigger = 0)
452 {
453 return $this->updateCommon($user, $notrigger);
454 }
455
463 public function delete(User $user, $notrigger = 0)
464 {
465 return $this->deleteCommon($user, $notrigger);
466 //return $this->deleteCommon($user, $notrigger, 1);
467 }
468
477 public function deleteLine(User $user, $idline, $notrigger = 0)
478 {
479 if ($this->status < 0) {
480 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
481 return -2;
482 }
483
484 return $this->deleteLineCommon($user, $idline, $notrigger);
485 }
486
487
495 public function validate($user, $notrigger = 0)
496 {
497 global $conf, $langs;
498
499 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
500
501 $error = 0;
502
503 // Protection
504 if ($this->status == self::STATUS_VALIDATED) {
505 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
506 return 0;
507 }
508
509 $now = dol_now();
510
511 $this->db->begin();
512
513 // Define new ref
514 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
515 $num = $this->getNextNumRef();
516 } else {
517 $num = $this->ref;
518 }
519 $this->newref = $num;
520
521 if (!empty($num)) {
522 // Validate
523 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
524 $sql .= " SET label = '".$this->db->escape($num)."',";
525 $sql .= " status = ".self::STATUS_VALIDATED;
526 if (!empty($this->fields['date_validation'])) {
527 $sql .= ", date_validation = '".$this->db->idate($now)."'";
528 }
529 if (!empty($this->fields['fk_user_valid'])) {
530 $sql .= ", fk_user_valid = ".((int) $user->id);
531 }
532 $sql .= " WHERE rowid = ".((int) $this->id);
533
534 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
535 $resql = $this->db->query($sql);
536 if (!$resql) {
537 dol_print_error($this->db);
538 $this->error = $this->db->lasterror();
539 $error++;
540 }
541
542 if (!$error && !$notrigger) {
543 // Call trigger
544 $result = $this->call_trigger('AVAILABILITIES_VALIDATE', $user);
545 if ($result < 0) {
546 $error++;
547 }
548 // End call triggers
549 }
550 }
551
552 if (!$error) {
553 $this->oldref = $this->ref;
554
555 // Rename directory if dir was a temporary ref
556 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
557 // Now we rename also files into index
558 $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)."'";
559 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'availabilities/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
560 $resql = $this->db->query($sql);
561 if (!$resql) {
562 $error++;
563 $this->error = $this->db->lasterror();
564 }
565 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'availabilities/".$this->db->escape($this->newref)."'";
566 $sql .= " WHERE filepath = 'availabilities/".$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
573 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
574 $oldref = dol_sanitizeFileName($this->ref);
575 $newref = dol_sanitizeFileName($num);
576 $dirsource = $conf->bookcal->dir_output.'/availabilities/'.$oldref;
577 $dirdest = $conf->bookcal->dir_output.'/availabilities/'.$newref;
578 if (!$error && file_exists($dirsource)) {
579 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
580
581 if (@rename($dirsource, $dirdest)) {
582 dol_syslog("Rename ok");
583 // Rename docs starting with $oldref with $newref
584 $listoffiles = dol_dir_list($conf->bookcal->dir_output.'/availabilities/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
585 foreach ($listoffiles as $fileentry) {
586 $dirsource = $fileentry['name'];
587 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
588 $dirsource = $fileentry['path'].'/'.$dirsource;
589 $dirdest = $fileentry['path'].'/'.$dirdest;
590 @rename($dirsource, $dirdest);
591 }
592 }
593 }
594 }
595 }
596
597 // Set new ref and current status
598 if (!$error) {
599 $this->ref = $num;
600 $this->status = self::STATUS_VALIDATED;
601 }
602
603 if (!$error) {
604 $this->db->commit();
605 return 1;
606 } else {
607 $this->db->rollback();
608 return -1;
609 }
610 }
611
612
620 public function setDraft($user, $notrigger = 0)
621 {
622 // Protection
623 if ($this->status <= self::STATUS_DRAFT) {
624 return 0;
625 }
626
627 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'AVAILABILITIES_UNVALIDATE');
628 }
629
637 public function cancel($user, $notrigger = 0)
638 {
639 // Protection
640 if ($this->status != self::STATUS_VALIDATED) {
641 return 0;
642 }
643
644 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'AVAILABILITIES_CANCEL');
645 }
646
654 public function reopen($user, $notrigger = 0)
655 {
656 // Protection
657 if ($this->status != self::STATUS_CANCELED) {
658 return 0;
659 }
660
661 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'AVAILABILITIES_REOPEN');
662 }
663
674 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
675 {
676 global $conf, $langs, $hookmanager;
677
678 if (!empty($conf->dol_no_mouse_hover)) {
679 $notooltip = 1; // Force disable tooltips
680 }
681
682 $result = '';
683
684 $label = img_picto('', $this->picto).' <u>'.$langs->trans("Availabilities").'</u>';
685 if (isset($this->status)) {
686 $label .= ' '.$this->getLibStatut(5);
687 }
688 $label .= '<br>';
689 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
690
691 $url = dol_buildpath('/bookcal/availabilities_card.php', 1).'?id='.$this->id;
692
693 if ($option != 'nolink') {
694 // Add param to save lastsearch_values or not
695 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
696 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
697 $add_save_lastsearch_values = 1;
698 }
699 if ($url && $add_save_lastsearch_values) {
700 $url .= '&save_lastsearch_values=1';
701 }
702 }
703
704 $linkclose = '';
705 if (empty($notooltip)) {
706 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
707 $label = $langs->trans("ShowAvailabilities");
708 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
709 }
710 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
711 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
712 } else {
713 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
714 }
715
716 if ($option == 'nolink' || empty($url)) {
717 $linkstart = '<span';
718 } else {
719 $linkstart = '<a href="'.$url.'"';
720 }
721 $linkstart .= $linkclose.'>';
722 if ($option == 'nolink' || empty($url)) {
723 $linkend = '</span>';
724 } else {
725 $linkend = '</a>';
726 }
727
728 $result .= $linkstart;
729
730 if (empty($this->showphoto_on_popup)) {
731 if ($withpicto) {
732 $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);
733 }
734 } else {
735 if ($withpicto) {
736 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
737
738 list($class, $module) = explode('@', $this->picto);
739 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
740 $filearray = dol_dir_list($upload_dir, "files");
741 $filename = $filearray[0]['name'];
742 if (!empty($filename)) {
743 $pospoint = strpos($filearray[0]['name'], '.');
744
745 $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
746 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
747 $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>';
748 } else {
749 $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>';
750 }
751
752 $result .= '</div>';
753 } else {
754 $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);
755 }
756 }
757 }
758
759 if ($withpicto != 2) {
760 $result .= $this->ref;
761 }
762
763 $result .= $linkend;
764 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
765
766 global $action, $hookmanager;
767 $hookmanager->initHooks(array('availabilitiesdao'));
768 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
769 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
770 if ($reshook > 0) {
771 $result = $hookmanager->resPrint;
772 } else {
773 $result .= $hookmanager->resPrint;
774 }
775
776 return $result;
777 }
778
786 public function getKanbanView($option = '', $arraydata = null)
787 {
788 global $conf, $langs;
789
790 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
791
792 $return = '<div class="box-flex-item box-flex-grow-zero">';
793 $return .= '<div class="info-box info-box-sm">';
794 $return .= '<span class="info-box-icon bg-infobox-action">';
795 $return .= img_picto('', $this->picto);
796 $return .= '</span>';
797 $return .= '<div class="info-box-content">';
798 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
799 if ($selected >= 0) {
800 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
801 }
802 if (property_exists($this, 'label')) {
803 $return .= ' <div class="inline-block opacitymedium valignmiddle tdoverflowmax100">'.$this->label.'</div>';
804 }
805 if (property_exists($this, 'amount')) {
806 $return .= '<br>';
807 $return .= '<span class="info-box-label amount">'.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency).'</span>';
808 }
809 if (method_exists($this, 'getLibStatut')) {
810 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
811 }
812 $return .= '</div>';
813 $return .= '</div>';
814 $return .= '</div>';
815
816 return $return;
817 }
818
825 public function getLabelStatus($mode = 0)
826 {
827 return $this->LibStatut($this->status, $mode);
828 }
829
836 public function getLibStatut($mode = 0)
837 {
838 return $this->LibStatut($this->status, $mode);
839 }
840
841 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
849 public function LibStatut($status, $mode = 0)
850 {
851 // phpcs:enable
852 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
853 global $langs;
854 //$langs->load("agenda");
855 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
856 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
857 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
858 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
859 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
860 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
861 }
862
863 $statusType = 'status'.$status;
864 if ($status == self::STATUS_VALIDATED) {
865 $statusType = 'status4';
866 }
867 if ($status == self::STATUS_CANCELED) {
868 $statusType = 'status6';
869 }
870
871 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
872 }
873
880 public function info($id)
881 {
882 $sql = "SELECT rowid,";
883 $sql .= " date_creation as datec, tms as datem,";
884 $sql .= " fk_user_creat, fk_user_modif";
885 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
886 $sql .= " WHERE t.rowid = ".((int) $id);
887
888 $result = $this->db->query($sql);
889 if ($result) {
890 if ($this->db->num_rows($result)) {
891 $obj = $this->db->fetch_object($result);
892
893 $this->id = $obj->rowid;
894
895 $this->user_creation_id = $obj->fk_user_creat;
896 $this->user_modification_id = $obj->fk_user_modif;
897 $this->date_creation = $this->db->jdate($obj->datec);
898 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
899 }
900
901 $this->db->free($result);
902 } else {
903 dol_print_error($this->db);
904 }
905 }
906
913 public function initAsSpecimen()
914 {
915 // Set here init that are not commonf fields
916 // $this->property1 = ...
917 // $this->property2 = ...
918
919 return $this->initAsSpecimenCommon();
920 }
921
927 public function getLinesArray()
928 {
929 $this->lines = array();
930
931 $objectline = new AvailabilitiesLine($this->db);
932 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_availabilities:=:'.((int) $this->id).')');
933
934 if (is_numeric($result)) {
935 $this->error = $objectline->error;
936 $this->errors = $objectline->errors;
937 return $result;
938 } else {
939 $this->lines = $result;
940 return $this->lines;
941 }
942 }
943
949 public function getNextNumRef()
950 {
951 global $langs, $conf;
952 $langs->load("agenda");
953
954 if (!getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON')) {
955 $conf->global->BOOKCAL_AVAILABILITIES_ADDON = 'mod_availabilities_standard';
956 }
957
958 if (getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON')) {
959 $mybool = false;
960
961 $file = getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON') . ".php";
962 $classname = getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON');
963
964 // Include file with class
965 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
966 foreach ($dirmodels as $reldir) {
967 $dir = dol_buildpath($reldir."core/modules/bookcal/");
968
969 // Load file with numbering class (if found)
970 $mybool = ((bool) @include_once $dir.$file) || $mybool;
971 }
972
973 if ($mybool === false) {
974 dol_print_error(null, "Failed to include file ".$file);
975 return '';
976 }
977
978 if (class_exists($classname)) {
979 $obj = new $classname();
980 $numref = $obj->getNextValue($this);
981
982 if ($numref != '' && $numref != '-1') {
983 return $numref;
984 } else {
985 $this->error = $obj->error;
986 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
987 return "";
988 }
989 } else {
990 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
991 return "";
992 }
993 } else {
994 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
995 return "";
996 }
997 }
998
1010 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1011 {
1012 global $conf, $langs;
1013
1014 $result = 0;
1015 $includedocgeneration = 0;
1016
1017 $langs->load("agenda");
1018
1019 if (!dol_strlen($modele)) {
1020 $modele = 'standard_availabilities';
1021
1022 if (!empty($this->model_pdf)) {
1023 $modele = $this->model_pdf;
1024 } elseif (getDolGlobalString('AVAILABILITIES_ADDON_PDF')) {
1025 $modele = getDolGlobalString('AVAILABILITIES_ADDON_PDF');
1026 }
1027 }
1028
1029 $modelpath = "core/modules/bookcal/doc/";
1030
1031 if ($includedocgeneration && !empty($modele)) {
1032 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1033 }
1034
1035 return $result;
1036 }
1037
1045 public function doScheduledJob()
1046 {
1047 global $conf, $langs;
1048
1049 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1050
1051 $error = 0;
1052 $this->output = '';
1053 $this->error = '';
1054
1055 dol_syslog(__METHOD__, LOG_DEBUG);
1056
1057 $now = dol_now();
1058
1059 $this->db->begin();
1060
1061 // ...
1062
1063 $this->db->commit();
1064
1065 return $error;
1066 }
1067}
1068
1069
1070require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1071
1076{
1077 // To complete with content of an object AvailabilitiesLine
1078 // We should have a field rowid, fk_availabilities and position
1079
1085 public function __construct(DoliDB $db)
1086 {
1087 $this->db = $db;
1088 $this->isextrafieldmanaged = 0;
1089 }
1090}
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:636
$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.
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 dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.