dolibarr  18.0.6
fichinter.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2014 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2011-2020 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
7  * Copyright (C) 2015-2020 Charlene Benke <charlie@patas-monkey.com>
8  * Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
9  * Copyright (C) 2018-2020 Frédéric France <frederic.france@netlogic.fr>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
23  */
24 
30 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
32 
33 
37 class Fichinter extends CommonObject
38 {
39  public $fields = array(
40  'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
41  'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'isModEnabled("societe")', 'visible'=>-1, 'notnull'=>1, 'position'=>15),
42  'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Fk projet', 'enabled'=>'isModEnabled("project")', 'visible'=>-1, 'position'=>20),
43  'fk_contrat' =>array('type'=>'integer', 'label'=>'Fk contrat', 'enabled'=>'$conf->contrat->enabled', 'visible'=>-1, 'position'=>25),
44  'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>30),
45  'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>35),
46  'ref_client' =>array('type'=>'varchar(255)', 'label'=>'RefCustomer', 'enabled'=>1, 'visible'=>-1, 'position'=>36),
47  'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>40, 'index'=>1),
48  'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>45),
49  'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>50),
50  'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>55),
51  'datei' =>array('type'=>'date', 'label'=>'Datei', 'enabled'=>1, 'visible'=>-1, 'position'=>60),
52  'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>65),
53  'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>70),
54  'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>75),
55  'dateo' =>array('type'=>'date', 'label'=>'Dateo', 'enabled'=>1, 'visible'=>-1, 'position'=>85),
56  'datee' =>array('type'=>'date', 'label'=>'Datee', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
57  'datet' =>array('type'=>'date', 'label'=>'Datet', 'enabled'=>1, 'visible'=>-1, 'position'=>95),
58  'duree' =>array('type'=>'double', 'label'=>'Duree', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
59  'description' =>array('type'=>'html', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>105, 'showoncombobox'=>2),
60  'note_private' =>array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>110),
61  'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>115),
62  'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>120),
63  'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
64  'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>130),
65  'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>135),
66  'fk_statut' =>array('type'=>'integer', 'label'=>'Fk statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500),
67  );
68 
72  public $element = 'fichinter';
73 
77  public $table_element = 'fichinter';
78 
82  public $fk_element = 'fk_fichinter';
83 
87  public $table_element_line = 'fichinterdet';
88 
92  public $picto = 'intervention';
93 
97  protected $table_ref_field = 'ref';
98 
102  public $socid;
103 
104  public $author;
105 
111  public $datec;
112 
113  public $datev;
114  public $dateo;
115  public $datee;
116  public $datet;
117 
123  public $datem;
124 
128  public $duration;
129 
133  public $statut = 0; // 0=draft, 1=validated, 2=invoiced, 3=Terminate
134 
138  public $description;
139 
143  public $fk_contrat = 0;
144 
148  public $fk_project = 0;
149 
154  public $ref_client;
155 
159  public $extraparams = array();
160 
164  public $lines = array();
165 
169  const STATUS_DRAFT = 0;
170 
174  const STATUS_VALIDATED = 1;
175 
179  const STATUS_BILLED = 2;
180 
184  const STATUS_CLOSED = 3;
185 
186 
192  public function __construct($db)
193  {
194  $this->db = $db;
195  }
196 
197  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
203  public function load_state_board()
204  {
205  // phpcs:enable
206  global $user;
207 
208  $this->nb = array();
209  $clause = "WHERE";
210 
211  $sql = "SELECT count(fi.rowid) as nb";
212  $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as fi";
213  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON fi.fk_soc = s.rowid";
214  if (empty($user->rights->societe->client->voir) && !$user->socid) {
215  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
216  $sql .= " WHERE sc.fk_user = ".((int) $user->id);
217  $clause = "AND";
218  }
219  $sql .= " ".$clause." fi.entity IN (".getEntity('intervention').")";
220 
221  $resql = $this->db->query($sql);
222  if ($resql) {
223  while ($obj = $this->db->fetch_object($resql)) {
224  $this->nb["interventions"] = $obj->nb;
225  }
226  $this->db->free($resql);
227  return 1;
228  } else {
229  dol_print_error($this->db);
230  $this->error = $this->db->error();
231  return -1;
232  }
233  }
234 
242  public function create($user, $notrigger = 0)
243  {
244  global $conf, $langs;
245 
246  $error = 0;
247 
248  dol_syslog(get_class($this)."::create ref=".$this->ref);
249 
250  // Check parameters
251  if (!empty($this->ref)) { // We check that ref is not already used
252  $result = self::isExistingObject($this->element, 0, $this->ref); // Check ref is not yet used
253  if ($result > 0) {
254  $this->error = 'ErrorRefAlreadyExists';
255  dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING);
256  $this->db->rollback();
257  return -1;
258  }
259  }
260  if (!is_numeric($this->duration)) {
261  $this->duration = 0;
262  }
263  if (isset($this->ref_client)) {
264  $this->ref_client = trim($this->ref_client);
265  }
266 
267  if ($this->socid <= 0) {
268  $this->error = 'ErrorFicheinterCompanyDoesNotExist';
269  dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
270  return -1;
271  }
272 
273  $soc = new Societe($this->db);
274  $result = $soc->fetch($this->socid);
275 
276  $now = dol_now();
277 
278  $this->db->begin();
279 
280  $sql = "INSERT INTO ".MAIN_DB_PREFIX."fichinter (";
281  $sql .= "fk_soc";
282  $sql .= ", datec";
283  $sql .= ", ref";
284  $sql .= ", ref_client";
285  $sql .= ", entity";
286  $sql .= ", fk_user_author";
287  $sql .= ", fk_user_modif";
288  $sql .= ", description";
289  $sql .= ", model_pdf";
290  $sql .= ", fk_projet";
291  $sql .= ", fk_contrat";
292  $sql .= ", fk_statut";
293  $sql .= ", note_private";
294  $sql .= ", note_public";
295  $sql .= ") ";
296  $sql .= " VALUES (";
297  $sql .= $this->socid;
298  $sql .= ", '".$this->db->idate($now)."'";
299  $sql .= ", '".$this->db->escape($this->ref)."'";
300  $sql .= ", ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
301  $sql .= ", ".((int) $conf->entity);
302  $sql .= ", ".((int) $user->id);
303  $sql .= ", ".((int) $user->id);
304  $sql .= ", ".($this->description ? "'".$this->db->escape($this->description)."'" : "null");
305  $sql .= ", '".$this->db->escape($this->model_pdf)."'";
306  $sql .= ", ".($this->fk_project ? ((int) $this->fk_project) : 0);
307  $sql .= ", ".($this->fk_contrat ? ((int) $this->fk_contrat) : 0);
308  $sql .= ", ".((int) $this->statut);
309  $sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
310  $sql .= ", ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
311  $sql .= ")";
312 
313  dol_syslog(get_class($this)."::create", LOG_DEBUG);
314  $result = $this->db->query($sql);
315  if ($result) {
316  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."fichinter");
317 
318  if ($this->id) {
319  $this->ref = '(PROV'.$this->id.')';
320  $sql = 'UPDATE '.MAIN_DB_PREFIX."fichinter SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".((int) $this->id);
321 
322  dol_syslog(get_class($this)."::create", LOG_DEBUG);
323  $resql = $this->db->query($sql);
324  if (!$resql) {
325  $error++;
326  }
327  }
328 
329  if (!$error) {
330  $result = $this->insertExtraFields();
331  if ($result < 0) {
332  $error++;
333  }
334  }
335 
336  // Add linked object
337  if (!$error && $this->origin && $this->origin_id) {
338  $ret = $this->add_object_linked();
339  if (!$ret) {
340  dol_print_error($this->db);
341  }
342  }
343 
344 
345  if (!$error && !$notrigger) {
346  // Call trigger
347  $result = $this->call_trigger('FICHINTER_CREATE', $user);
348  if ($result < 0) {
349  $error++;
350  }
351  // End call triggers
352  }
353 
354  if (!$error) {
355  $this->db->commit();
356  return $this->id;
357  } else {
358  $this->db->rollback();
359  $this->error = join(',', $this->errors);
360  dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
361  return -1;
362  }
363  } else {
364  $this->error = $this->db->error();
365  $this->db->rollback();
366  return -1;
367  }
368  }
369 
377  public function update($user, $notrigger = 0)
378  {
379  global $conf;
380 
381  if (!is_numeric($this->duration)) {
382  $this->duration = 0;
383  }
384  if (!dol_strlen($this->fk_project)) {
385  $this->fk_project = 0;
386  }
387  if (isset($this->ref_client)) {
388  $this->ref_client = trim($this->ref_client);
389  }
390 
391  $error = 0;
392 
393  $this->db->begin();
394 
395  $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter SET ";
396  $sql .= "description = '".$this->db->escape($this->description)."'";
397  $sql .= ", duree = ".((int) $this->duration);
398  $sql .= ", ref_client = ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
399  $sql .= ", fk_projet = ".((int) $this->fk_project);
400  $sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
401  $sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
402  $sql .= ", fk_user_modif = ".((int) $user->id);
403  $sql .= " WHERE rowid = ".((int) $this->id);
404 
405  dol_syslog(get_class($this)."::update", LOG_DEBUG);
406  if ($this->db->query($sql)) {
407  if (!$error) {
408  $result = $this->insertExtraFields();
409  if ($result < 0) {
410  $error++;
411  }
412  }
413 
414  if (!$error && !$notrigger) {
415  // Call trigger
416  $result = $this->call_trigger('FICHINTER_MODIFY', $user);
417  if ($result < 0) {
418  $error++; $this->db->rollback(); return -1;
419  }
420  // End call triggers
421  }
422 
423  $this->db->commit();
424  return 1;
425  } else {
426  $this->error = $this->db->error();
427  $this->db->rollback();
428  return -1;
429  }
430  }
431 
439  public function fetch($rowid, $ref = '')
440  {
441  $sql = "SELECT f.rowid, f.ref, f.ref_client, f.description, f.fk_soc, f.fk_statut,";
442  $sql .= " f.datec, f.dateo, f.datee, f.datet, f.fk_user_author,";
443  $sql .= " f.date_valid as datev,";
444  $sql .= " f.tms as datem,";
445  $sql .= " f.duree, f.fk_projet as fk_project, f.note_public, f.note_private, f.model_pdf, f.last_main_doc, f.extraparams, fk_contrat, f.entity as entity";
446  $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
447  if ($ref) {
448  $sql .= " WHERE f.entity IN (".getEntity('intervention').")";
449  $sql .= " AND f.ref = '".$this->db->escape($ref)."'";
450  } else {
451  $sql .= " WHERE f.rowid = ".((int) $rowid);
452  }
453 
454  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
455  $resql = $this->db->query($sql);
456  if ($resql) {
457  if ($this->db->num_rows($resql)) {
458  $obj = $this->db->fetch_object($resql);
459 
460  $this->id = $obj->rowid;
461  $this->ref = $obj->ref;
462  $this->ref_client = $obj->ref_client;
463  $this->description = $obj->description;
464  $this->socid = $obj->fk_soc;
465  $this->statut = $obj->fk_statut;
466  $this->duration = $obj->duree;
467  $this->datec = $this->db->jdate($obj->datec);
468  $this->dateo = $this->db->jdate($obj->dateo);
469  $this->datee = $this->db->jdate($obj->datee);
470  $this->datet = $this->db->jdate($obj->datet);
471  $this->datev = $this->db->jdate($obj->datev);
472  $this->datem = $this->db->jdate($obj->datem);
473  $this->fk_project = $obj->fk_project;
474  $this->note_public = $obj->note_public;
475  $this->note_private = $obj->note_private;
476  $this->model_pdf = $obj->model_pdf;
477  $this->modelpdf = $obj->model_pdf; // deprecated
478  $this->fk_contrat = $obj->fk_contrat;
479  $this->entity = $obj->entity;
480 
481  $this->user_creation = $obj->fk_user_author;
482 
483  $this->extraparams = (array) json_decode($obj->extraparams, true);
484 
485  $this->last_main_doc = $obj->last_main_doc;
486 
487  if ($this->statut == 0) {
488  $this->brouillon = 1;
489  }
490 
491  // Retrieve extrafields
492  $this->fetch_optionals();
493 
494  /*
495  * Lines
496  */
497  $result = $this->fetch_lines();
498  if ($result < 0) {
499  return -3;
500  }
501  $this->db->free($resql);
502  return 1;
503  }
504 
505  return 0;
506  } else {
507  $this->error = $this->db->lasterror();
508  return -1;
509  }
510  }
511 
518  public function setDraft($user)
519  {
520  $error = 0;
521 
522  // Protection
523  if ($this->statut <= self::STATUS_DRAFT) {
524  return 0;
525  }
526 
527  dol_syslog(get_class($this)."::setDraft", LOG_DEBUG);
528 
529  $this->oldcopy = dol_clone($this, 2);
530 
531  $this->db->begin();
532 
533  $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
534  $sql .= " SET fk_statut = ".self::STATUS_DRAFT;
535  $sql .= " WHERE rowid = ".((int) $this->id);
536 
537  $resql = $this->db->query($sql);
538  if ($resql) {
539  if (!$error) {
540  // Call trigger
541  $result = $this->call_trigger('FICHINTER_UNVALIDATE', $user);
542  if ($result < 0) {
543  $error++;
544  }
545  }
546 
547  if (!$error) {
548  $this->statut = self::STATUS_DRAFT;
549  $this->db->commit();
550  return 1;
551  } else {
552  $this->db->rollback();
553  return -1;
554  }
555  } else {
556  $this->db->rollback();
557  $this->error = $this->db->lasterror();
558  return -1;
559  }
560  }
561 
569  public function setValid($user, $notrigger = 0)
570  {
571  global $conf;
572  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
573 
574  $error = 0;
575 
576  if ($this->statut != 1) {
577  $this->db->begin();
578 
579  $now = dol_now();
580 
581  // Define new ref
582  if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
583  $num = $this->getNextNumRef($this->thirdparty);
584  } else {
585  $num = $this->ref;
586  }
587  $this->newref = dol_sanitizeFileName($num);
588 
589  $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
590  $sql .= " SET fk_statut = 1";
591  $sql .= ", ref = '".$this->db->escape($num)."'";
592  $sql .= ", date_valid = '".$this->db->idate($now)."'";
593  $sql .= ", fk_user_valid = ".($user->id > 0 ? (int) $user->id : "null");
594  $sql .= " WHERE rowid = ".((int) $this->id);
595  $sql .= " AND entity = ".((int) $this->entity);
596 
597  $sql .= " AND fk_statut = 0";
598 
599  dol_syslog(get_class($this)."::setValid", LOG_DEBUG);
600  $resql = $this->db->query($sql);
601  if (!$resql) {
602  dol_print_error($this->db);
603  $error++;
604  }
605 
606  if (!$error && !$notrigger) {
607  // Call trigger
608  $result = $this->call_trigger('FICHINTER_VALIDATE', $user);
609  if ($result < 0) {
610  $error++;
611  }
612  // End call triggers
613  }
614 
615  if (!$error) {
616  $this->oldref = $this->ref;
617 
618  // Rename directory if dir was a temporary ref
619  if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
620  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
621 
622  // Now we rename also files into index
623  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'ficheinter/".$this->db->escape($this->newref)."'";
624  $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".((int) $this->entity);
625  $resql = $this->db->query($sql);
626  if (!$resql) {
627  $error++; $this->error = $this->db->lasterror();
628  }
629  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'ficheinter/".$this->db->escape($this->newref)."'";
630  $sql .= " WHERE filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
631  $resql = $this->db->query($sql);
632  if (!$resql) {
633  $error++; $this->error = $this->db->lasterror();
634  }
635 
636  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
637  $oldref = dol_sanitizeFileName($this->ref);
638  $newref = dol_sanitizeFileName($num);
639  $dirsource = $conf->ficheinter->dir_output.'/'.$oldref;
640  $dirdest = $conf->ficheinter->dir_output.'/'.$newref;
641  if (!$error && file_exists($dirsource)) {
642  dol_syslog(get_class($this)."::setValid rename dir ".$dirsource." into ".$dirdest);
643 
644  if (@rename($dirsource, $dirdest)) {
645  dol_syslog("Rename ok");
646  // Rename docs starting with $oldref with $newref
647  $listoffiles = dol_dir_list($conf->ficheinter->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
648  foreach ($listoffiles as $fileentry) {
649  $dirsource = $fileentry['name'];
650  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
651  $dirsource = $fileentry['path'].'/'.$dirsource;
652  $dirdest = $fileentry['path'].'/'.$dirdest;
653  @rename($dirsource, $dirdest);
654  }
655  }
656  }
657  }
658  }
659 
660  // Set new ref and define current statut
661  if (!$error) {
662  $this->ref = $num;
663  $this->statut = 1;
664  $this->brouillon = 0;
665  $this->date_validation = $now;
666  $this->db->commit();
667  return 1;
668  } else {
669  $this->db->rollback();
670  dol_syslog(get_class($this)."::setValid ".$this->error, LOG_ERR);
671  return -1;
672  }
673  }
674 
675  return 0;
676  }
677 
683  public function getAmount()
684  {
685  global $db;
686 
687  $amount = 0;
688 
689  $this->author = new User($db);
690  $this->author->fetch($this->user_creation);
691 
692  $thm = $this->author->thm;
693 
694  foreach ($this->lines as $line) {
695  $amount += ($line->duration / 60 / 60 * $thm);
696  }
697 
698  return price2num($amount, 'MT');
699  }
700 
701 
713  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
714  {
715  global $conf;
716 
717  $outputlangs->load("interventions");
718 
719  if (!dol_strlen($modele)) {
720  $modele = 'soleil';
721 
722  if (!empty($this->model_pdf)) {
723  $modele = $this->model_pdf;
724  } elseif (!empty($this->modelpdf)) { // deprecated
725  $modele = $this->modelpdf;
726  } elseif (!empty($conf->global->FICHEINTER_ADDON_PDF)) {
727  $modele = $conf->global->FICHEINTER_ADDON_PDF;
728  }
729  }
730 
731  $modelpath = "core/modules/fichinter/doc/";
732 
733  return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
734  }
735 
742  public function getLibStatut($mode = 0)
743  {
744  return $this->LibStatut((isset($this->statut) ? $this->statut : $this->status), $mode);
745  }
746 
747  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
755  public function LibStatut($status, $mode = 0)
756  {
757  // phpcs:enable
758  // Init/load array of translation of status
759  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
760  global $langs;
761  $langs->load("fichinter");
762 
763  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
764  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
765  $this->labelStatus[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
766  $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
767  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
768  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
769  $this->labelStatusShort[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
770  $this->labelStatusShort[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
771  }
772 
773  $statuscode = 'status'.$status;
774  if ($status == self::STATUS_BILLED || $status == self::STATUS_CLOSED) {
775  $statuscode = 'status6';
776  }
777  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statuscode, $mode);
778  }
779 
787  public function getTooltipContentArray($params)
788  {
789  global $conf, $langs;
790 
791  $langs->load('fichinter');
792 
793  $datas = [];
794  $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Intervention").'</u>';
795  if (isset($this->status)) {
796  $datas['picto'] .= ' '.$this->getLibStatut(5);
797  }
798  $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
799 
800  return $datas;
801  }
802 
813  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $save_lastsearch_value = -1, $morecss = '')
814  {
815  global $conf, $langs, $hookmanager;
816 
817  if (!empty($conf->dol_no_mouse_hover)) {
818  $notooltip = 1; // Force disable tooltips
819  }
820 
821  $result = '';
822  $params = [
823  'id' => $this->id,
824  'objecttype' => $this->element,
825  'option' => $option,
826  ];
827  $classfortooltip = 'classfortooltip';
828  $dataparams = '';
829  if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
830  $classfortooltip = 'classforajaxtooltip';
831  $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
832  $label = '';
833  } else {
834  $label = implode($this->getTooltipContentArray($params));
835  }
836 
837  $url = DOL_URL_ROOT.'/fichinter/card.php?id='.$this->id;
838 
839  if ($option !== 'nolink') {
840  // Add param to save lastsearch_values or not
841  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
842  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
843  $add_save_lastsearch_values = 1;
844  }
845  if ($add_save_lastsearch_values) {
846  $url .= '&save_lastsearch_values=1';
847  }
848  }
849 
850  $linkclose = '';
851  if (empty($notooltip)) {
852  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
853  $label = $langs->trans("ShowIntervention");
854  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
855  }
856  $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
857  $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
858  } else {
859  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
860  }
861 
862  if ($option == 'nolink' || empty($url)) {
863  $linkstart = '<span';
864  } else {
865  $linkstart = '<a href="'.$url.'"';
866  }
867  $linkstart .= $linkclose.'>';
868  if ($option == 'nolink' || empty($url)) {
869  $linkend = '</span>';
870  } else {
871  $linkend = '</a>';
872  }
873 
874  $result .= $linkstart;
875  if ($withpicto) {
876  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
877  }
878 
879  if ($withpicto != 2) {
880  $result .= $this->ref;
881  }
882 
883  $result .= $linkend;
884 
885  global $action;
886  $hookmanager->initHooks(array('interventiondao'));
887  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
888  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
889  if ($reshook > 0) {
890  $result = $hookmanager->resPrint;
891  } else {
892  $result .= $hookmanager->resPrint;
893  }
894 
895  return $result;
896  }
897 
898 
906  public function getNextNumRef($soc)
907  {
908  global $conf, $db, $langs;
909  $langs->load("interventions");
910 
911  if (!empty($conf->global->FICHEINTER_ADDON)) {
912  $mybool = false;
913 
914  $file = "mod_".$conf->global->FICHEINTER_ADDON.".php";
915  $classname = "mod_".$conf->global->FICHEINTER_ADDON;
916 
917  // Include file with class
918  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
919 
920  foreach ($dirmodels as $reldir) {
921  $dir = dol_buildpath($reldir."core/modules/fichinter/");
922 
923  // Load file with numbering class (if found)
924  $mybool |= @include_once $dir.$file;
925  }
926 
927  if ($mybool === false) {
928  dol_print_error('', "Failed to include file ".$file);
929  return '';
930  }
931 
932  $obj = new $classname();
933  $numref = "";
934  $numref = $obj->getNextValue($soc, $this);
935 
936  if ($numref != "") {
937  return $numref;
938  } else {
939  dol_print_error($db, "Fichinter::getNextNumRef ".$obj->error);
940  return "";
941  }
942  } else {
943  $langs->load("errors");
944  print $langs->trans("Error")." ".$langs->trans("Error_FICHEINTER_ADDON_NotDefined");
945  return "";
946  }
947  }
948 
955  public function info($id)
956  {
957  $sql = "SELECT f.rowid,";
958  $sql .= " f.datec,";
959  $sql .= " f.tms as date_modification,";
960  $sql .= " f.date_valid as datev,";
961  $sql .= " f.fk_user_author,";
962  $sql .= " f.fk_user_modif as fk_user_modification,";
963  $sql .= " f.fk_user_valid";
964  $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
965  $sql .= " WHERE f.rowid = ".((int) $id);
966 
967  $resql = $this->db->query($sql);
968  if ($resql) {
969  if ($this->db->num_rows($resql)) {
970  $obj = $this->db->fetch_object($resql);
971 
972  $this->id = $obj->rowid;
973 
974  $this->date_creation = $this->db->jdate($obj->datec);
975  $this->date_modification = $this->db->jdate($obj->date_modification);
976  $this->date_validation = $this->db->jdate($obj->datev);
977 
978  $cuser = new User($this->db);
979  $cuser->fetch($obj->fk_user_author);
980  $this->user_creation = $cuser;
981 
982  if ($obj->fk_user_valid) {
983  $vuser = new User($this->db);
984  $vuser->fetch($obj->fk_user_valid);
985  $this->user_validation = $vuser;
986  }
987  if ($obj->fk_user_modification) {
988  $muser = new User($this->db);
989  $muser->fetch($obj->fk_user_modification);
990  $this->user_modification = $muser;
991  }
992  }
993  $this->db->free($resql);
994  } else {
995  dol_print_error($this->db);
996  }
997  }
998 
1006  public function delete(User $user, $notrigger = 0)
1007  {
1008  global $conf, $langs;
1009  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1010 
1011  $error = 0;
1012 
1013  $this->db->begin();
1014 
1015  if (!$error && !$notrigger) {
1016  // Call trigger
1017  $result = $this->call_trigger('FICHINTER_DELETE', $user);
1018  if ($result < 0) {
1019  $error++; $this->db->rollback(); return -1;
1020  }
1021  // End call triggers
1022  }
1023 
1024  // Delete linked object
1025  if (!$error) {
1026  $res = $this->deleteObjectLinked();
1027  if ($res < 0) {
1028  $error++;
1029  }
1030  }
1031 
1032  // Delete linked contacts
1033  if (!$error) {
1034  $res = $this->delete_linked_contact();
1035  if ($res < 0) {
1036  $this->error = 'ErrorFailToDeleteLinkedContact';
1037  $error++;
1038  }
1039  }
1040 
1041  if (!$error) {
1042  $main = MAIN_DB_PREFIX.'fichinterdet';
1043  $ef = $main."_extrafields";
1044  $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_fichinter = ".((int) $this->id).")";
1045 
1046  $resql = $this->db->query($sql);
1047  if (!$resql) {
1048  $error++;
1049  }
1050  }
1051 
1052  if (!$error) {
1053  $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet";
1054  $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1055 
1056  $resql = $this->db->query($sql);
1057  if (!$resql) {
1058  $error++;
1059  }
1060  }
1061 
1062  if (!$error) {
1063  // Remove extrafields
1064  $res = $this->deleteExtraFields();
1065  if ($res < 0) {
1066  $error++;
1067  }
1068  }
1069 
1070  if (!$error) {
1071  // Delete object
1072  $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinter";
1073  $sql .= " WHERE rowid = ".((int) $this->id);
1074 
1075  dol_syslog("Fichinter::delete", LOG_DEBUG);
1076  $resql = $this->db->query($sql);
1077  if (!$resql) {
1078  $error++;
1079  }
1080  }
1081 
1082  if (!$error) {
1083  // Delete record into ECM index (Note that delete is also done when deleting files with the dol_delete_dir_recursive
1084  $this->deleteEcmFiles();
1085 
1086  // Remove directory with files
1087  $fichinterref = dol_sanitizeFileName($this->ref);
1088  if ($conf->ficheinter->dir_output) {
1089  $dir = $conf->ficheinter->dir_output."/".$fichinterref;
1090  $file = $conf->ficheinter->dir_output."/".$fichinterref."/".$fichinterref.".pdf";
1091  if (file_exists($file)) {
1092  dol_delete_preview($this);
1093 
1094  if (!dol_delete_file($file, 0, 0, 0, $this)) { // For triggers
1095  $langs->load("errors");
1096  $this->error = $langs->trans("ErrorFailToDeleteFile", $file);
1097  return 0;
1098  }
1099  }
1100  if (file_exists($dir)) {
1101  if (!dol_delete_dir_recursive($dir)) {
1102  $langs->load("errors");
1103  $this->error = $langs->trans("ErrorFailToDeleteDir", $dir);
1104  return 0;
1105  }
1106  }
1107  }
1108  }
1109 
1110  if (!$error) {
1111  $this->db->commit();
1112  return 1;
1113  } else {
1114  $this->db->rollback();
1115  return -1;
1116  }
1117  }
1118 
1119  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1127  public function set_date_delivery($user, $date_delivery)
1128  {
1129  // phpcs:enable
1130  if ($user->rights->ficheinter->creer) {
1131  $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1132  $sql .= " SET datei = '".$this->db->idate($date_delivery)."'";
1133  $sql .= " WHERE rowid = ".((int) $this->id);
1134  $sql .= " AND fk_statut = 0";
1135 
1136  if ($this->db->query($sql)) {
1137  $this->date_delivery = $date_delivery;
1138  return 1;
1139  } else {
1140  $this->error = $this->db->error();
1141  dol_syslog("Fichinter::set_date_delivery Erreur SQL");
1142  return -1;
1143  }
1144  }
1145 
1146  return 0;
1147  }
1148 
1149  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1157  public function set_description($user, $description)
1158  {
1159  // phpcs:enable
1160  if ($user->rights->ficheinter->creer) {
1161  $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1162  $sql .= " SET description = '".$this->db->escape($description)."',";
1163  $sql .= " fk_user_modif = ".$user->id;
1164  $sql .= " WHERE rowid = ".((int) $this->id);
1165 
1166  if ($this->db->query($sql)) {
1167  $this->description = $description;
1168  return 1;
1169  } else {
1170  $this->error = $this->db->error();
1171  dol_syslog("Fichinter::set_description Erreur SQL");
1172  return -1;
1173  }
1174  }
1175 
1176  return 0;
1177  }
1178 
1179 
1180  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1188  public function set_contrat($user, $contractid)
1189  {
1190  // phpcs:enable
1191  if ($user->rights->ficheinter->creer) {
1192  $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1193  $sql .= " SET fk_contrat = ".((int) $contractid);
1194  $sql .= " WHERE rowid = ".((int) $this->id);
1195 
1196  if ($this->db->query($sql)) {
1197  $this->fk_contrat = $contractid;
1198  return 1;
1199  } else {
1200  $this->error = $this->db->error();
1201  return -1;
1202  }
1203  }
1204 
1205  return -2;
1206  }
1207 
1208 
1209 
1217  public function createFromClone(User $user, $socid = 0)
1218  {
1219  global $hookmanager;
1220 
1221  $error = 0;
1222 
1223  $this->db->begin();
1224 
1225  // get extrafields so they will be clone
1226  foreach ($this->lines as $line) {
1227  $line->fetch_optionals();
1228  }
1229 
1230  // Load source object
1231  $objFrom = clone $this;
1232 
1233  // Change socid if needed
1234  if (!empty($socid) && $socid != $this->socid) {
1235  $objsoc = new Societe($this->db);
1236 
1237  if ($objsoc->fetch($socid) > 0) {
1238  $this->socid = $objsoc->id;
1239  //$this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1240  //$this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1241  $this->fk_project = '';
1242  $this->fk_delivery_address = '';
1243  }
1244 
1245  // TODO Change product price if multi-prices
1246  }
1247 
1248  $this->id = 0;
1249  $this->ref = '';
1250  $this->statut = 0;
1251 
1252  // Clear fields
1253  $this->user_author_id = $user->id;
1254  $this->user_valid = 0;
1255  $this->date_creation = '';
1256  $this->date_validation = '';
1257  $this->ref_client = '';
1258 
1259  // Create clone
1260  $this->context['createfromclone'] = 'createfromclone';
1261  $result = $this->create($user);
1262  if ($result < 0) {
1263  $error++;
1264  }
1265 
1266  if (!$error) {
1267  // Add lines because it is not included into create function
1268  foreach ($this->lines as $line) {
1269  $this->addline($user, $this->id, $line->desc, $line->datei, $line->duration, $line->array_options);
1270  }
1271 
1272  // Hook of thirdparty module
1273  if (is_object($hookmanager)) {
1274  $parameters = array('objFrom'=>$objFrom);
1275  $action = '';
1276  $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1277  if ($reshook < 0) {
1278  $this->setErrorsFromObject($hookmanager);
1279  $error++;
1280  }
1281  }
1282  }
1283 
1284  unset($this->context['createfromclone']);
1285 
1286  // End
1287  if (!$error) {
1288  $this->db->commit();
1289  return $this->id;
1290  } else {
1291  $this->db->rollback();
1292  return -1;
1293  }
1294  }
1295 
1296 
1308  public function addline($user, $fichinterid, $desc, $date_intervention, $duration, $array_options = '')
1309  {
1310  dol_syslog(get_class($this)."::addline $fichinterid, $desc, $date_intervention, $duration");
1311 
1312  if ($this->statut == self::STATUS_DRAFT) {
1313  $this->db->begin();
1314 
1315  // Insertion ligne
1316  $line = new FichinterLigne($this->db);
1317 
1318  $line->fk_fichinter = $fichinterid;
1319  $line->desc = $desc;
1320  $line->date = $date_intervention;
1321  $line->datei = $date_intervention; // For backward compatibility
1322  $line->duration = $duration;
1323 
1324  if (is_array($array_options) && count($array_options) > 0) {
1325  $line->array_options = $array_options;
1326  }
1327 
1328  $result = $line->insert($user);
1329 
1330  if ($result >= 0) {
1331  $this->db->commit();
1332  return 1;
1333  } else {
1334  $this->error = $this->db->error();
1335  $this->db->rollback();
1336  return -1;
1337  }
1338  }
1339 
1340  return 0;
1341  }
1342 
1343 
1351  public function initAsSpecimen()
1352  {
1353  global $langs;
1354 
1355  $now = dol_now();
1356 
1357  // Initialise parametres
1358  $this->id = 0;
1359  $this->ref = 'SPECIMEN';
1360  $this->ref_client = 'SPECIMEN CLIENT';
1361  $this->specimen = 1;
1362  $this->socid = 1;
1363  $this->datec = $now;
1364  $this->note_private = 'Private note';
1365  $this->note_public = 'SPECIMEN';
1366  $this->duration = 0;
1367  $nbp = 25;
1368  $xnbp = 0;
1369  while ($xnbp < $nbp) {
1370  $line = new FichinterLigne($this->db);
1371  $line->desc = $langs->trans("Description")." ".$xnbp;
1372  $line->date = ($now - 3600 * (1 + $xnbp));
1373  $line->datei = ($now - 3600 * (1 + $xnbp)); // For backward compatibility
1374  $line->duration = 600;
1375  $line->fk_fichinter = 0;
1376  $this->lines[$xnbp] = $line;
1377  $xnbp++;
1378 
1379  $this->duration += $line->duration;
1380  }
1381  }
1382 
1383  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1389  public function fetch_lines()
1390  {
1391  // phpcs:enable
1392  $this->lines = array();
1393 
1394  $sql = "SELECT rowid, fk_fichinter, description, duree, date, rang";
1395  $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet";
1396  $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1397  $sql .= " ORDER BY rang ASC, date ASC";
1398 
1399  dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG);
1400 
1401  $resql = $this->db->query($sql);
1402  if ($resql) {
1403  $num = $this->db->num_rows($resql);
1404  $i = 0;
1405  while ($i < $num) {
1406  $objp = $this->db->fetch_object($resql);
1407 
1408  $line = new FichinterLigne($this->db);
1409  $line->id = $objp->rowid;
1410  $line->fk_fichinter = $objp->fk_fichinter;
1411  $line->desc = $objp->description;
1412  $line->duration = $objp->duree;
1413  //For invoicing we calculing hours
1414  $line->qty = round($objp->duree / 3600, 2);
1415  $line->date = $this->db->jdate($objp->date);
1416  $line->datei = $this->db->jdate($objp->date); // For backward compatibility
1417  $line->rang = $objp->rang;
1418  $line->product_type = 1;
1419  $line->fetch_optionals();
1420 
1421  $this->lines[$i] = $line;
1422  $i++;
1423  }
1424  $this->db->free($resql);
1425 
1426  return 1;
1427  } else {
1428  $this->error = $this->db->error();
1429  return -1;
1430  }
1431  }
1432 
1441  public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1442  {
1443  $tables = array(
1444  'fichinter'
1445  );
1446 
1447  return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1448  }
1449 
1458  public function setRefClient($user, $ref_client, $notrigger = 0)
1459  {
1460  // phpcs:enable
1461  if (!empty($user->rights->ficheinter->creer)) {
1462  $error = 0;
1463 
1464  $this->db->begin();
1465 
1466  $this->oldcopy = dol_clone($this);
1467 
1468  $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET ref_client = ".(empty($ref_client) ? 'NULL' : "'".$this->db->escape($ref_client)."'");
1469  $sql .= " WHERE rowid = ".((int) $this->id);
1470 
1471  dol_syslog(__METHOD__.' $this->id='.$this->id.', ref_client='.$ref_client, LOG_DEBUG);
1472  $resql = $this->db->query($sql);
1473  if (!$resql) {
1474  $this->errors[] = $this->db->error();
1475  $error++;
1476  }
1477 
1478  if (!$error) {
1479  $this->ref_client = $ref_client;
1480  }
1481 
1482  if (!$notrigger && empty($error)) {
1483  // Call trigger
1484  $result = $this->call_trigger('FICHINTER_MODIFY', $user);
1485  if ($result < 0) {
1486  $error++;
1487  }
1488  // End call triggers
1489  }
1490 
1491  if (!$error) {
1492  $this->db->commit();
1493  return 1;
1494  } else {
1495  foreach ($this->errors as $errmsg) {
1496  dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
1497  $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1498  }
1499  $this->db->rollback();
1500  return -1 * $error;
1501  }
1502  } else {
1503  return -1;
1504  }
1505  }
1506 
1514  public function getKanbanView($option = '', $arraydata = null)
1515  {
1516  global $langs;
1517 
1518  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1519 
1520  $return = '<div class="box-flex-item box-flex-grow-zero">';
1521  $return .= '<div class="info-box info-box-sm">';
1522  $return .= '<span class="info-box-icon bg-infobox-action">';
1523  $return .= img_picto('', $this->picto);
1524  $return .= '</span>';
1525  $return .= '<div class="info-box-content">';
1526  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
1527  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1528  if (!empty($arraydata['thirdparty'])) {
1529  $tmpthirdparty = $arraydata['thirdparty'];
1530  $return .= '<br><span class="info-box-label">'.$tmpthirdparty->getNomUrl(1).'</span>';
1531  }
1532  if (property_exists($this, 'duration')) {
1533  $return .= '<br><span class="info-box-label ">'.$langs->trans("Duration").' : '.convertSecondToTime($this->duration, 'allhourmin').'</span>';
1534  }
1535  if (method_exists($this, 'getLibStatut')) {
1536  $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).'</div>';
1537  }
1538  $return .= '</div>';
1539  $return .= '</div>';
1540  $return .= '</div>';
1541  return $return;
1542  }
1543 }
1544 
1549 {
1553  public $db;
1554 
1558  public $error = '';
1559 
1560  // From llx_fichinterdet
1564  public $fk_fichinter;
1565 
1566  public $desc; // Description ligne
1567 
1571  public $date; // Date intervention
1576  public $datei; // Date intervention
1577 
1578  public $duration; // Duration of intervention
1579  public $rang = 0;
1580  public $tva_tx;
1581  public $subprice;
1582 
1586  public $element = 'fichinterdet';
1587 
1591  public $table_element = 'fichinterdet';
1592 
1596  public $fk_element = 'fk_fichinter';
1597 
1598 
1599 
1605  public function __construct($db)
1606  {
1607  $this->db = $db;
1608  }
1609 
1616  public function fetch($rowid)
1617  {
1618  dol_syslog("FichinterLigne::fetch", LOG_DEBUG);
1619 
1620  $sql = 'SELECT ft.rowid, ft.fk_fichinter, ft.description, ft.duree, ft.rang, ft.date';
1621  $sql .= ' FROM '.MAIN_DB_PREFIX.'fichinterdet as ft';
1622  $sql .= ' WHERE ft.rowid = '.((int) $rowid);
1623 
1624  $resql = $this->db->query($sql);
1625  if ($resql) {
1626  $objp = $this->db->fetch_object($resql);
1627  $this->rowid = $objp->rowid;
1628  $this->id = $objp->rowid;
1629  $this->fk_fichinter = $objp->fk_fichinter;
1630  $this->date = $this->db->jdate($objp->date);
1631  $this->datei = $this->db->jdate($objp->date); // For backward compatibility
1632  $this->desc = $objp->description;
1633  $this->duration = $objp->duree;
1634  $this->rang = $objp->rang;
1635 
1636  $this->db->free($resql);
1637 
1638  $this->fetch_optionals();
1639 
1640  return 1;
1641  } else {
1642  $this->error = $this->db->error().' sql='.$sql;
1643  return -1;
1644  }
1645  }
1646 
1654  public function insert($user, $notrigger = 0)
1655  {
1656  $error = 0;
1657 
1658  dol_syslog("FichinterLigne::insert rang=".$this->rang);
1659 
1660  if (empty($this->date) && !empty($this->datei)) { // For backward compatibility
1661  $this->date = $this->datei;
1662  }
1663 
1664  $this->db->begin();
1665 
1666  $rangToUse = $this->rang;
1667  if ($rangToUse == -1) {
1668  // Recupere rang max de la ligne d'intervention dans $rangmax
1669  $sql = 'SELECT max(rang) as max FROM '.MAIN_DB_PREFIX.'fichinterdet';
1670  $sql .= ' WHERE fk_fichinter = '.((int) $this->fk_fichinter);
1671  $resql = $this->db->query($sql);
1672  if ($resql) {
1673  $obj = $this->db->fetch_object($resql);
1674  $rangToUse = $obj->max + 1;
1675  } else {
1676  dol_print_error($this->db);
1677  $this->db->rollback();
1678  return -1;
1679  }
1680  }
1681 
1682  // Insertion dans base de la ligne
1683  $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'fichinterdet';
1684  $sql .= ' (fk_fichinter, description, date, duree, rang)';
1685  $sql .= " VALUES (".((int) $this->fk_fichinter).",";
1686  $sql .= " '".$this->db->escape($this->desc)."',";
1687  $sql .= " '".$this->db->idate($this->date)."',";
1688  $sql .= " ".((int) $this->duration).",";
1689  $sql .= ' '.((int) $rangToUse);
1690  $sql .= ')';
1691 
1692  dol_syslog("FichinterLigne::insert", LOG_DEBUG);
1693  $resql = $this->db->query($sql);
1694  if ($resql) {
1695  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'fichinterdet');
1696  $this->rowid = $this->id;
1697 
1698  if (!$error) {
1699  $result = $this->insertExtraFields();
1700  if ($result < 0) {
1701  $error++;
1702  }
1703  }
1704 
1705 
1706  $result = $this->update_total();
1707 
1708  if ($result > 0) {
1709  $this->rang = $rangToUse;
1710 
1711  if (!$notrigger) {
1712  // Call trigger
1713  $result = $this->call_trigger('LINEFICHINTER_CREATE', $user);
1714  if ($result < 0) {
1715  $error++;
1716  }
1717  // End call triggers
1718  }
1719  }
1720 
1721  if (!$error) {
1722  $this->db->commit();
1723  return $result;
1724  } else {
1725  $this->db->rollback();
1726  return -1;
1727  }
1728  } else {
1729  $this->error = $this->db->error()." sql=".$sql;
1730  $this->db->rollback();
1731  return -1;
1732  }
1733  }
1734 
1735 
1743  public function update($user, $notrigger = 0)
1744  {
1745  $error = 0;
1746 
1747  if (empty($this->date) && !empty($this->datei)) { // For backward compatibility
1748  $this->date = $this->datei;
1749  }
1750 
1751  $this->db->begin();
1752 
1753  // Mise a jour ligne en base
1754  $sql = "UPDATE ".MAIN_DB_PREFIX."fichinterdet SET";
1755  $sql .= " description = '".$this->db->escape($this->desc)."',";
1756  $sql .= " date = '".$this->db->idate($this->date)."',";
1757  $sql .= " duree = ".((int) $this->duration).",";
1758  $sql .= " rang = ".((int) $this->rang);
1759  $sql .= " WHERE rowid = ".((int) $this->id);
1760 
1761  dol_syslog("FichinterLigne::update", LOG_DEBUG);
1762  $resql = $this->db->query($sql);
1763  if ($resql) {
1764  if (!$error) {
1765  $result = $this->insertExtraFields();
1766  if ($result < 0) {
1767  $error++;
1768  }
1769  }
1770 
1771  $result = $this->update_total();
1772  if ($result > 0) {
1773  if (!$notrigger) {
1774  // Call trigger
1775  $result = $this->call_trigger('LINEFICHINTER_MODIFY', $user);
1776  if ($result < 0) {
1777  $error++;
1778  }
1779  // End call triggers
1780  }
1781  }
1782 
1783  if (!$error) {
1784  $this->db->commit();
1785  return $result;
1786  } else {
1787  $this->error = $this->db->lasterror();
1788  $this->db->rollback();
1789  return -1;
1790  }
1791  } else {
1792  $this->error = $this->db->lasterror();
1793  $this->db->rollback();
1794  return -1;
1795  }
1796  }
1797 
1798  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1804  public function update_total()
1805  {
1806  // phpcs:enable
1807  global $conf;
1808 
1809  $this->db->begin();
1810 
1811  $sql = "SELECT SUM(duree) as total_duration, min(date) as dateo, max(date) as datee ";
1812  $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet";
1813  $sql .= " WHERE fk_fichinter=".((int) $this->fk_fichinter);
1814 
1815  dol_syslog("FichinterLigne::update_total", LOG_DEBUG);
1816  $resql = $this->db->query($sql);
1817  if ($resql) {
1818  $obj = $this->db->fetch_object($resql);
1819  $total_duration = 0;
1820  if (!empty($obj->total_duration)) {
1821  $total_duration = $obj->total_duration;
1822  }
1823 
1824  $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
1825  $sql .= " SET duree = ".((int) $total_duration);
1826  $sql .= " , dateo = ".(!empty($obj->dateo) ? "'".$this->db->escape($obj->dateo)."'" : "null");
1827  $sql .= " , datee = ".(!empty($obj->datee) ? "'".$this->db->escape($obj->datee)."'" : "null");
1828  $sql .= " WHERE rowid = ".((int) $this->fk_fichinter);
1829 
1830  dol_syslog("FichinterLigne::update_total", LOG_DEBUG);
1831  $resql = $this->db->query($sql);
1832  if ($resql) {
1833  $this->db->commit();
1834  return 1;
1835  } else {
1836  $this->error = $this->db->error();
1837  $this->db->rollback();
1838  return -2;
1839  }
1840  } else {
1841  $this->error = $this->db->error();
1842  $this->db->rollback();
1843  return -1;
1844  }
1845  }
1846 
1854  public function deleteline($user, $notrigger = 0)
1855  {
1856  global $langs, $conf;
1857 
1858  $error = 0;
1859 
1860  if ($this->statut == 0) {
1861  dol_syslog(get_class($this)."::deleteline lineid=".$this->id);
1862  $this->db->begin();
1863 
1864  $result = $this->deleteExtraFields();
1865  if ($result < 0) {
1866  $error++;
1867  $this->db->rollback();
1868  return -1;
1869  }
1870 
1871  $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet WHERE rowid = ".((int) $this->id);
1872  $resql = $this->db->query($sql);
1873 
1874  if ($resql) {
1875  $result = $this->update_total();
1876  if ($result > 0) {
1877  if (!$notrigger) {
1878  // Call trigger
1879  $result = $this->call_trigger('LINEFICHINTER_DELETE', $user);
1880  if ($result < 0) {
1881  $error++; $this->db->rollback(); return -1;
1882  }
1883  // End call triggers
1884  }
1885 
1886  $this->db->commit();
1887  return $result;
1888  } else {
1889  $this->db->rollback();
1890  return -1;
1891  }
1892  } else {
1893  $this->error = $this->db->error()." sql=".$sql;
1894  $this->db->rollback();
1895  return -1;
1896  }
1897  } else {
1898  return -2;
1899  }
1900  }
1901 }
$object ref
Definition: info.php:78
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
deleteEcmFiles($mode=0)
Delete related files of object in database.
add_object_linked($origin=null, $origin_id=null, $f_user=null, $notrigger=0)
Add an object link into llx_element_element.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
setErrorsFromObject($object)
setErrorsFromObject
static isExistingObject($element, $id, $ref='', $ref_ext='')
Check an object id/ref exists If you don't need/want to instantiate object and just need to know if o...
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid='', $f_user=null, $notrigger=0)
Delete all links between an object $this.
deleteExtraFields()
Delete all extra fields values for the current object.
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
delete_linked_contact($source='', $code='')
Delete all links between an object $this and all its contacts in llx_element_contact.
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 interventions.
const STATUS_BILLED
Billed.
addline($user, $fichinterid, $desc, $date_intervention, $duration, $array_options='')
Adding a line of intervention into data base.
initAsSpecimen()
Initialise an instance with random values.
getLibStatut($mode=0)
Returns the label status.
update($user, $notrigger=0)
Update an intervention.
createFromClone(User $user, $socid=0)
Load an object from its id and create a new one in database.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
set_date_delivery($user, $date_delivery)
Defines a delivery date of intervention.
const STATUS_DRAFT
Draft status.
create($user, $notrigger=0)
Create an intervention into data base.
set_description($user, $description)
Define the label of the intervention.
getTooltipContentArray($params)
getTooltipContentArray
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
const STATUS_VALIDATED
Validated status.
const STATUS_CLOSED
Closed.
setDraft($user)
Set status to draft.
getNextNumRef($soc)
Returns the next non used reference of intervention depending on the module numbering assets within F...
getAmount()
Returns amount based on user thm.
fetch($rowid, $ref='')
Fetch a intervention.
setRefClient($user, $ref_client, $notrigger=0)
Set customer reference number.
set_contrat($user, $contractid)
Link intervention to a contract.
LibStatut($status, $mode=0)
Returns the label of a status.
setValid($user, $notrigger=0)
Validate a intervention.
getNomUrl($withpicto=0, $option='', $notooltip=0, $save_lastsearch_value=-1, $morecss='')
Return clicable name (with picto eventually)
load_state_board()
Load indicators into this->nb for board.
__construct($db)
Constructor.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
info($id)
Load information on object.
fetch_lines()
Load array lines ->lines.
Class to manage intervention lines.
fetch($rowid)
Retrieve the line of intervention.
update_total()
Update total duration into llx_fichinter.
update($user, $notrigger=0)
Update intervention into database.
deleteline($user, $notrigger=0)
Delete a intervention line.
__construct($db)
Constructor.
insert($user, $notrigger=0)
Insert the line into database.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
Definition: user.class.php:48
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->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') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengthOfWeek=7)
Return, in clear text, value of a number of seconds in days, hours and minutes.
Definition: date.lib.php:240
print *****$script_file(".$version.") pid cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
print *****$script_file(".$version.") pid c cd cd cd description as p label as s rowid
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
Definition: files.lib.php:1507
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
Definition: files.lib.php:1356
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:62
dol_delete_preview($object)
Delete all preview files linked to object instance.
Definition: files.lib.php:1559
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for each properties) With native =...
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_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.