dolibarr  20.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
28 require_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 
56  public $ismultientitymanaged = 'fk_bookcal_calendar@bookcal_calendar';
57 
61  public $isextrafieldmanaged = 1;
62 
66  public $picto = 'fa-calendar-check';
67 
68 
69  const STATUS_DRAFT = 0;
70  const STATUS_VALIDATED = 1;
71  const STATUS_CANCELED = 9;
72 
73 
113  // BEGIN MODULEBUILDER PROPERTIES
117  public $fields = array(
118  'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 2, 'noteditable' => 1, 'index' => 1, 'css' => 'left', 'comment' => "Id"),
119  '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,),
120  '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'),
121  'description' => array('type' => 'text', 'label' => 'Description', 'enabled' => 1, 'position' => 60, 'notnull' => 0, 'visible' => 3, 'validate' => 1,),
122  'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 61, 'notnull' => 0, 'visible' => 0, 'cssview' => 'wordbreak', 'validate' => 1,),
123  'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 62, 'notnull' => 0, 'visible' => 0, 'cssview' => 'wordbreak', 'validate' => 1,),
124  'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -2,),
125  'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2,),
126  'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'picto' => 'user', 'enabled' => 1, 'position' => 510, 'notnull' => 1, 'visible' => -2, 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax150'),
127  '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'),
128  'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'LastMainDoc', 'enabled' => 1, 'position' => 600, 'notnull' => 0, 'visible' => 0,),
129  'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => -2,),
130  'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'position' => 1010, 'notnull' => -1, 'visible' => 0,),
131  'start' => array('type' => 'date', 'label' => 'Start Date', 'enabled' => 1, 'position' => 40, 'notnull' => 1, 'visible' => 1, 'searchall' => 1,),
132  'end' => array('type' => 'date', 'label' => 'End Date', 'enabled' => 1, 'position' => 45, 'notnull' => 1, 'visible' => 1, 'searchall' => 1,),
133  'duration' => array('type' => 'integer', 'label' => 'DurationOfRange', 'enabled' => 1, 'position' => 47, 'notnull' => 1, 'visible' => 1, 'default' => '30', 'css' => 'width50 right'),
134  'startHour' => array('type' => 'integer', 'label' => 'Start Hour', 'enabled' => 1, 'position' => 46, 'notnull' => 1, 'visible' => 1,),
135  'endHour' => array('type' => 'integer', 'label' => 'End Hour', 'enabled' => 1, 'position' => 46.5, 'notnull' => 1, 'visible' => 1,),
136  '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),
137  );
138  public $rowid;
139  public $label;
140  public $description;
141  public $note_public;
142  public $note_private;
143  public $date_creation;
144  public $fk_user_creat;
145  public $fk_user_modif;
146  public $last_main_doc;
147  public $import_key;
148  public $model_pdf;
149  public $status;
150  public $start;
151  public $end;
152  public $duration;
153  public $startHour;
154  public $endHour;
155  public $fk_bookcal_calendar;
156  // END MODULEBUILDER PROPERTIES
157 
158 
159  // If this object has a subtable with lines
160 
161  // /**
162  // * @var string Name of subtable line
163  // */
164  // public $table_element_line = 'bookcal_availabilitiesline';
165 
166  // /**
167  // * @var string Field with ID of parent key if this object has a parent
168  // */
169  // public $fk_element = 'fk_availabilities';
170 
171  // /**
172  // * @var string Name of subtable class that manage subtable lines
173  // */
174  // public $class_element_line = 'Availabilitiesline';
175 
176  // /**
177  // * @var array List of child tables. To test if we can delete object.
178  // */
179  // protected $childtables = array();
180 
181  // /**
182  // * @var array List of child tables. To know object to delete on cascade.
183  // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
184  // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
185  // */
186  // protected $childtablesoncascade = array('bookcal_availabilitiesdet');
187 
188  // /**
189  // * @var AvailabilitiesLine[] Array of subtable lines
190  // */
191  // public $lines = array();
192 
193 
194 
200  public function __construct(DoliDB $db)
201  {
202  global $conf, $langs;
203 
204  $this->db = $db;
205 
206  if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid']) && !empty($this->fields['ref'])) {
207  $this->fields['rowid']['visible'] = 0;
208  }
209  if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) {
210  $this->fields['entity']['enabled'] = 0;
211  }
212 
213  // Example to show how to set values of fields definition dynamically
214  /*if ($user->hasRight('bookcal', 'availabilities', 'read')) {
215  $this->fields['myfield']['visible'] = 1;
216  $this->fields['myfield']['noteditable'] = 0;
217  }*/
218 
219  // Unset fields that are disabled
220  foreach ($this->fields as $key => $val) {
221  if (isset($val['enabled']) && empty($val['enabled'])) {
222  unset($this->fields[$key]);
223  }
224  }
225 
226  // Translate some data of arrayofkeyval
227  if (is_object($langs)) {
228  foreach ($this->fields as $key => $val) {
229  if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
230  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
231  $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
232  }
233  }
234  }
235  }
236  }
237 
245  public function create(User $user, $notrigger = 0)
246  {
247  $resultcreate = $this->createCommon($user, $notrigger);
248 
249  //$resultvalidate = $this->validate($user, $notrigger);
250 
251  return $resultcreate;
252  }
253 
261  public function createFromClone(User $user, $fromid)
262  {
263  global $langs, $extrafields;
264  $error = 0;
265 
266  dol_syslog(__METHOD__, LOG_DEBUG);
267 
268  $object = new self($this->db);
269 
270  $this->db->begin();
271 
272  // Load source object
273  $result = $object->fetchCommon($fromid);
274  if ($result > 0 && !empty($object->table_element_line)) {
275  $object->fetchLines();
276  }
277 
278  // get lines so they will be clone
279  //foreach($this->lines as $line)
280  // $line->fetch_optionals();
281 
282  // Reset some properties
283  unset($object->id);
284  unset($object->fk_user_creat);
285  unset($object->import_key);
286 
287  // Clear fields
288  if (property_exists($object, 'ref')) {
289  $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
290  }
291  if (property_exists($object, 'label')) {
292  $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
293  }
294  if (property_exists($object, 'status')) {
295  $object->status = self::STATUS_DRAFT;
296  }
297  if (property_exists($object, 'date_creation')) {
298  $object->date_creation = dol_now();
299  }
300  if (property_exists($object, 'date_modification')) {
301  $object->date_modification = null;
302  }
303  // ...
304  // Clear extrafields that are unique
305  if (is_array($object->array_options) && count($object->array_options) > 0) {
306  $extrafields->fetch_name_optionals_label($this->table_element);
307  foreach ($object->array_options as $key => $option) {
308  $shortkey = preg_replace('/options_/', '', $key);
309  if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
310  //var_dump($key);
311  //var_dump($clonedObj->array_options[$key]); exit;
312  unset($object->array_options[$key]);
313  }
314  }
315  }
316 
317  // Create clone
318  $object->context['createfromclone'] = 'createfromclone';
319  $result = $object->createCommon($user);
320  if ($result < 0) {
321  $error++;
322  $this->error = $object->error;
323  $this->errors = $object->errors;
324  }
325 
326  if (!$error) {
327  // copy internal contacts
328  if ($this->copy_linked_contact($object, 'internal') < 0) {
329  $error++;
330  }
331  }
332 
333  if (!$error) {
334  // copy external contacts if same company
335  if (!empty($object->socid) && property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
336  if ($this->copy_linked_contact($object, 'external') < 0) {
337  $error++;
338  }
339  }
340  }
341 
342  unset($object->context['createfromclone']);
343 
344  // End
345  if (!$error) {
346  $this->db->commit();
347  return $object;
348  } else {
349  $this->db->rollback();
350  return -1;
351  }
352  }
353 
361  public function fetch($id, $ref = null)
362  {
363  $result = $this->fetchCommon($id, $ref);
364  if ($result > 0 && !empty($this->table_element_line)) {
365  $this->fetchLines();
366  }
367  return $result;
368  }
369 
375  public function fetchLines()
376  {
377  $this->lines = array();
378 
379  $result = $this->fetchLinesCommon();
380  return $result;
381  }
382 
383 
396  public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
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 
411  // Manage filter
412  $errormessage = '';
413  $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
414  if ($errormessage) {
415  $this->errors[] = $errormessage;
416  dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
417  return -1;
418  }
419 
420  if (!empty($sortfield)) {
421  $sql .= $this->db->order($sortfield, $sortorder);
422  }
423  if (!empty($limit)) {
424  $sql .= $this->db->plimit($limit, $offset);
425  }
426 
427  $resql = $this->db->query($sql);
428  if ($resql) {
429  $num = $this->db->num_rows($resql);
430  $i = 0;
431  while ($i < ($limit ? min($limit, $num) : $num)) {
432  $obj = $this->db->fetch_object($resql);
433 
434  $record = new self($this->db);
435  $record->setVarsFromFetchObj($obj);
436 
437  $records[$record->id] = $record;
438 
439  $i++;
440  }
441  $this->db->free($resql);
442 
443  return $records;
444  } else {
445  $this->errors[] = 'Error '.$this->db->lasterror();
446  dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
447 
448  return -1;
449  }
450  }
451 
459  public function update(User $user, $notrigger = 0)
460  {
461  return $this->updateCommon($user, $notrigger);
462  }
463 
471  public function delete(User $user, $notrigger = 0)
472  {
473  return $this->deleteCommon($user, $notrigger);
474  //return $this->deleteCommon($user, $notrigger, 1);
475  }
476 
485  public function deleteLine(User $user, $idline, $notrigger = 0)
486  {
487  if ($this->status < 0) {
488  $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
489  return -2;
490  }
491 
492  return $this->deleteLineCommon($user, $idline, $notrigger);
493  }
494 
495 
503  public function validate($user, $notrigger = 0)
504  {
505  global $conf, $langs;
506 
507  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
508 
509  $error = 0;
510 
511  // Protection
512  if ($this->status == self::STATUS_VALIDATED) {
513  dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
514  return 0;
515  }
516 
517  $now = dol_now();
518 
519  $this->db->begin();
520 
521  // Define new ref
522  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
523  $num = $this->getNextNumRef();
524  } else {
525  $num = $this->ref;
526  }
527  $this->newref = $num;
528 
529  if (!empty($num)) {
530  // Validate
531  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
532  $sql .= " SET label = '".$this->db->escape($num)."',";
533  $sql .= " status = ".self::STATUS_VALIDATED;
534  if (!empty($this->fields['date_validation'])) {
535  $sql .= ", date_validation = '".$this->db->idate($now)."'";
536  }
537  if (!empty($this->fields['fk_user_valid'])) {
538  $sql .= ", fk_user_valid = ".((int) $user->id);
539  }
540  $sql .= " WHERE rowid = ".((int) $this->id);
541 
542  dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
543  $resql = $this->db->query($sql);
544  if (!$resql) {
545  dol_print_error($this->db);
546  $this->error = $this->db->lasterror();
547  $error++;
548  }
549 
550  if (!$error && !$notrigger) {
551  // Call trigger
552  $result = $this->call_trigger('AVAILABILITIES_VALIDATE', $user);
553  if ($result < 0) {
554  $error++;
555  }
556  // End call triggers
557  }
558  }
559 
560  if (!$error) {
561  $this->oldref = $this->ref;
562 
563  // Rename directory if dir was a temporary ref
564  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
565  // Now we rename also files into index
566  $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)."'";
567  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'availabilities/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
568  $resql = $this->db->query($sql);
569  if (!$resql) {
570  $error++;
571  $this->error = $this->db->lasterror();
572  }
573  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'availabilities/".$this->db->escape($this->newref)."'";
574  $sql .= " WHERE filepath = 'availabilities/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
575  $resql = $this->db->query($sql);
576  if (!$resql) {
577  $error++;
578  $this->error = $this->db->lasterror();
579  }
580 
581  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
582  $oldref = dol_sanitizeFileName($this->ref);
583  $newref = dol_sanitizeFileName($num);
584  $dirsource = $conf->bookcal->dir_output.'/availabilities/'.$oldref;
585  $dirdest = $conf->bookcal->dir_output.'/availabilities/'.$newref;
586  if (!$error && file_exists($dirsource)) {
587  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
588 
589  if (@rename($dirsource, $dirdest)) {
590  dol_syslog("Rename ok");
591  // Rename docs starting with $oldref with $newref
592  $listoffiles = dol_dir_list($conf->bookcal->dir_output.'/availabilities/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
593  foreach ($listoffiles as $fileentry) {
594  $dirsource = $fileentry['name'];
595  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
596  $dirsource = $fileentry['path'].'/'.$dirsource;
597  $dirdest = $fileentry['path'].'/'.$dirdest;
598  @rename($dirsource, $dirdest);
599  }
600  }
601  }
602  }
603  }
604 
605  // Set new ref and current status
606  if (!$error) {
607  $this->ref = $num;
608  $this->status = self::STATUS_VALIDATED;
609  }
610 
611  if (!$error) {
612  $this->db->commit();
613  return 1;
614  } else {
615  $this->db->rollback();
616  return -1;
617  }
618  }
619 
620 
628  public function setDraft($user, $notrigger = 0)
629  {
630  // Protection
631  if ($this->status <= self::STATUS_DRAFT) {
632  return 0;
633  }
634 
635  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'AVAILABILITIES_UNVALIDATE');
636  }
637 
645  public function cancel($user, $notrigger = 0)
646  {
647  // Protection
648  if ($this->status != self::STATUS_VALIDATED) {
649  return 0;
650  }
651 
652  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'AVAILABILITIES_CANCEL');
653  }
654 
662  public function reopen($user, $notrigger = 0)
663  {
664  // Protection
665  if ($this->status != self::STATUS_CANCELED) {
666  return 0;
667  }
668 
669  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'AVAILABILITIES_REOPEN');
670  }
671 
682  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
683  {
684  global $conf, $langs, $hookmanager;
685 
686  if (!empty($conf->dol_no_mouse_hover)) {
687  $notooltip = 1; // Force disable tooltips
688  }
689 
690  $result = '';
691 
692  $label = img_picto('', $this->picto).' <u>'.$langs->trans("Availabilities").'</u>';
693  if (isset($this->status)) {
694  $label .= ' '.$this->getLibStatut(5);
695  }
696  $label .= '<br>';
697  $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
698 
699  $url = dol_buildpath('/bookcal/availabilities_card.php', 1).'?id='.$this->id;
700 
701  if ($option != 'nolink') {
702  // Add param to save lastsearch_values or not
703  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
704  if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
705  $add_save_lastsearch_values = 1;
706  }
707  if ($url && $add_save_lastsearch_values) {
708  $url .= '&save_lastsearch_values=1';
709  }
710  }
711 
712  $linkclose = '';
713  if (empty($notooltip)) {
714  if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
715  $label = $langs->trans("ShowAvailabilities");
716  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
717  }
718  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
719  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
720  } else {
721  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
722  }
723 
724  if ($option == 'nolink' || empty($url)) {
725  $linkstart = '<span';
726  } else {
727  $linkstart = '<a href="'.$url.'"';
728  }
729  $linkstart .= $linkclose.'>';
730  if ($option == 'nolink' || empty($url)) {
731  $linkend = '</span>';
732  } else {
733  $linkend = '</a>';
734  }
735 
736  $result .= $linkstart;
737 
738  if (empty($this->showphoto_on_popup)) {
739  if ($withpicto) {
740  $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);
741  }
742  } else {
743  if ($withpicto) {
744  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
745 
746  list($class, $module) = explode('@', $this->picto);
747  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
748  $filearray = dol_dir_list($upload_dir, "files");
749  $filename = $filearray[0]['name'];
750  if (!empty($filename)) {
751  $pospoint = strpos($filearray[0]['name'], '.');
752 
753  $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
754  if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
755  $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>';
756  } else {
757  $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>';
758  }
759 
760  $result .= '</div>';
761  } else {
762  $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);
763  }
764  }
765  }
766 
767  if ($withpicto != 2) {
768  $result .= $this->ref;
769  }
770 
771  $result .= $linkend;
772  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
773 
774  global $action, $hookmanager;
775  $hookmanager->initHooks(array('availabilitiesdao'));
776  $parameters = array('id' => $this->id, 'getnomurl' => &$result);
777  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
778  if ($reshook > 0) {
779  $result = $hookmanager->resPrint;
780  } else {
781  $result .= $hookmanager->resPrint;
782  }
783 
784  return $result;
785  }
786 
794  public function getKanbanView($option = '', $arraydata = null)
795  {
796  global $conf, $langs;
797 
798  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
799 
800  $return = '<div class="box-flex-item box-flex-grow-zero">';
801  $return .= '<div class="info-box info-box-sm">';
802  $return .= '<span class="info-box-icon bg-infobox-action">';
803  $return .= img_picto('', $this->picto);
804  $return .= '</span>';
805  $return .= '<div class="info-box-content">';
806  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
807  if ($selected >= 0) {
808  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
809  }
810  if (property_exists($this, 'label')) {
811  $return .= ' <div class="inline-block opacitymedium valignmiddle tdoverflowmax100">'.$this->label.'</div>';
812  }
813  if (property_exists($this, 'amount')) {
814  $return .= '<br>';
815  $return .= '<span class="info-box-label amount">'.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency).'</span>';
816  }
817  if (method_exists($this, 'getLibStatut')) {
818  $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
819  }
820  $return .= '</div>';
821  $return .= '</div>';
822  $return .= '</div>';
823 
824  return $return;
825  }
826 
833  public function getLabelStatus($mode = 0)
834  {
835  return $this->LibStatut($this->status, $mode);
836  }
837 
844  public function getLibStatut($mode = 0)
845  {
846  return $this->LibStatut($this->status, $mode);
847  }
848 
849  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
857  public function LibStatut($status, $mode = 0)
858  {
859  // phpcs:enable
860  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
861  global $langs;
862  //$langs->load("agenda");
863  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
864  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
865  $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
866  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
867  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
868  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
869  }
870 
871  $statusType = 'status'.$status;
872  if ($status == self::STATUS_VALIDATED) {
873  $statusType = 'status4';
874  }
875  if ($status == self::STATUS_CANCELED) {
876  $statusType = 'status6';
877  }
878 
879  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
880  }
881 
888  public function info($id)
889  {
890  $sql = "SELECT rowid,";
891  $sql .= " date_creation as datec, tms as datem,";
892  $sql .= " fk_user_creat, fk_user_modif";
893  $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
894  $sql .= " WHERE t.rowid = ".((int) $id);
895 
896  $result = $this->db->query($sql);
897  if ($result) {
898  if ($this->db->num_rows($result)) {
899  $obj = $this->db->fetch_object($result);
900 
901  $this->id = $obj->rowid;
902 
903  $this->user_creation_id = $obj->fk_user_creat;
904  $this->user_modification_id = $obj->fk_user_modif;
905  $this->date_creation = $this->db->jdate($obj->datec);
906  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
907  }
908 
909  $this->db->free($result);
910  } else {
911  dol_print_error($this->db);
912  }
913  }
914 
921  public function initAsSpecimen()
922  {
923  // Set here init that are not commonf fields
924  // $this->property1 = ...
925  // $this->property2 = ...
926 
927  return $this->initAsSpecimenCommon();
928  }
929 
935  public function getLinesArray()
936  {
937  $this->lines = array();
938 
939  $objectline = new AvailabilitiesLine($this->db);
940  $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_availabilities:=:'.((int) $this->id).')');
941 
942  if (is_numeric($result)) {
943  $this->error = $objectline->error;
944  $this->errors = $objectline->errors;
945  return $result;
946  } else {
947  $this->lines = $result;
948  return $this->lines;
949  }
950  }
951 
957  public function getNextNumRef()
958  {
959  global $langs, $conf;
960  $langs->load("agenda");
961 
962  if (!getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON')) {
963  $conf->global->BOOKCAL_AVAILABILITIES_ADDON = 'mod_availabilities_standard';
964  }
965 
966  if (getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON')) {
967  $mybool = false;
968 
969  $file = getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON') . ".php";
970  $classname = getDolGlobalString('BOOKCAL_AVAILABILITIES_ADDON');
971 
972  // Include file with class
973  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
974  foreach ($dirmodels as $reldir) {
975  $dir = dol_buildpath($reldir."core/modules/bookcal/");
976 
977  // Load file with numbering class (if found)
978  $mybool = ((bool) @include_once $dir.$file) || $mybool;
979  }
980 
981  if ($mybool === false) {
982  dol_print_error(null, "Failed to include file ".$file);
983  return '';
984  }
985 
986  if (class_exists($classname)) {
987  $obj = new $classname();
988  $numref = $obj->getNextValue($this);
989 
990  if ($numref != '' && $numref != '-1') {
991  return $numref;
992  } else {
993  $this->error = $obj->error;
994  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
995  return "";
996  }
997  } else {
998  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
999  return "";
1000  }
1001  } else {
1002  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1003  return "";
1004  }
1005  }
1006 
1018  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1019  {
1020  global $conf, $langs;
1021 
1022  $result = 0;
1023  $includedocgeneration = 0;
1024 
1025  $langs->load("agenda");
1026 
1027  if (!dol_strlen($modele)) {
1028  $modele = 'standard_availabilities';
1029 
1030  if (!empty($this->model_pdf)) {
1031  $modele = $this->model_pdf;
1032  } elseif (getDolGlobalString('AVAILABILITIES_ADDON_PDF')) {
1033  $modele = getDolGlobalString('AVAILABILITIES_ADDON_PDF');
1034  }
1035  }
1036 
1037  $modelpath = "core/modules/bookcal/doc/";
1038 
1039  if ($includedocgeneration && !empty($modele)) {
1040  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1041  }
1042 
1043  return $result;
1044  }
1045 
1053  public function doScheduledJob()
1054  {
1055  global $conf, $langs;
1056 
1057  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1058 
1059  $error = 0;
1060  $this->output = '';
1061  $this->error = '';
1062 
1063  dol_syslog(__METHOD__, LOG_DEBUG);
1064 
1065  $now = dol_now();
1066 
1067  $this->db->begin();
1068 
1069  // ...
1070 
1071  $this->db->commit();
1072 
1073  return $error;
1074  }
1075 }
1076 
1077 
1078 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1079 
1084 {
1085  // To complete with content of an object AvailabilitiesLine
1086  // We should have a field rowid, fk_availabilities and position
1087 
1091  public $isextrafieldmanaged = 0;
1092 
1098  public function __construct(DoliDB $db)
1099  {
1100  $this->db = $db;
1101  }
1102 }
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:604
$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 into 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.
Definition: user.class.php:50
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:744
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.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
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.
td amount
Definition: global.inc.php:554