dolibarr 20.0.0
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-2024 Frédéric France <frederic.france@free.fr>
10 * Copyright (C) 2023-2024 William Mead <william.mead@manchenumerique.fr>
11 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 */
26
32require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
33require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
34
35
40{
41 public $fields = array(
42 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
43 'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 'isModEnabled("societe")', 'visible' => -1, 'notnull' => 1, 'position' => 15),
44 '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),
45 'fk_contrat' => array('type' => 'integer', 'label' => 'Fk contrat', 'enabled' => '$conf->contrat->enabled', 'visible' => -1, 'position' => 25),
46 'ref' => array('type' => 'varchar(30)', 'label' => 'Ref', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'showoncombobox' => 1, 'position' => 30),
47 'ref_ext' => array('type' => 'varchar(255)', 'label' => 'Ref ext', 'enabled' => 1, 'visible' => 0, 'position' => 35),
48 'ref_client' => array('type' => 'varchar(255)', 'label' => 'RefCustomer', 'enabled' => 1, 'visible' => -1, 'position' => 36),
49 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 40, 'index' => 1),
50 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 45),
51 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 50),
52 'date_valid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 55),
53 'datei' => array('type' => 'date', 'label' => 'Datei', 'enabled' => 1, 'visible' => -1, 'position' => 60),
54 'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user author', 'enabled' => 1, 'visible' => -1, 'position' => 65),
55 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 70),
56 'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => -1, 'position' => 75),
57 'dateo' => array('type' => 'date', 'label' => 'Dateo', 'enabled' => 1, 'visible' => -1, 'position' => 85),
58 'datee' => array('type' => 'date', 'label' => 'Datee', 'enabled' => 1, 'visible' => -1, 'position' => 90),
59 'datet' => array('type' => 'date', 'label' => 'Datet', 'enabled' => 1, 'visible' => -1, 'position' => 95),
60 'duree' => array('type' => 'double', 'label' => 'Duree', 'enabled' => 1, 'visible' => -1, 'position' => 100),
61 'signed_status' => array('type' => 'smallint(6)', 'label' => 'SignedStatus', 'enabled' => 1, 'visible' => -1, 'position' => 101, 'arrayofkeyval' => array(0 => 'NoSignature', 1 => 'SignedSender', 2 => 'SignedReceiver', 9 => 'SignedAll')),
62 'description' => array('type' => 'html', 'label' => 'Description', 'enabled' => 1, 'visible' => -1, 'position' => 105, 'showoncombobox' => 2),
63 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 110),
64 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 115),
65 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 120),
66 'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'Last main doc', 'enabled' => 1, 'visible' => -1, 'position' => 125),
67 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 130),
68 'extraparams' => array('type' => 'varchar(255)', 'label' => 'Extraparams', 'enabled' => 1, 'visible' => -1, 'position' => 135),
69 'fk_statut' => array('type' => 'integer', 'label' => 'Fk statut', 'enabled' => 1, 'visible' => -1, 'position' => 500),
70 );
71
75 public $element = 'fichinter';
76
80 public $table_element = 'fichinter';
81
85 public $fk_element = 'fk_fichinter';
86
90 public $table_element_line = 'fichinterdet';
91
95 public $picto = 'intervention';
96
100 protected $table_ref_field = 'ref';
101
105 public $socid;
106
107 public $author;
108
114 public $datec;
115
116 public $datev;
117 public $dateo;
118 public $datee;
119 public $datet;
120
126 public $datem;
127
131 public $duration;
132
136 public $statut = 0; // 0=draft, 1=validated, 2=invoiced, 3=Terminate
137
142 public $signed_status = 0;
143
147 public $description;
148
152 public $fk_contrat = 0;
153
157 public $fk_project = 0;
158
163 public $ref_client;
164
168 public $extraparams = array();
169
173 public $lines = array();
174
178 const STATUS_DRAFT = 0;
179
184
188 const STATUS_BILLED = 2;
189
193 const STATUS_CLOSED = 3;
194
195
200
205
210
214 const STATUS_SIGNED_ALL = 9; // To handle future kind of signature (ex: tripartite contract)
215
216
221 public $date_delivery;
222
227 public $user_author_id;
228
229
235 public function __construct($db)
236 {
237 $this->db = $db;
238 }
239
245 public function loadStateBoard()
246 {
247 global $user;
248
249 $this->nb = array();
250 $clause = "WHERE";
251
252 $sql = "SELECT count(fi.rowid) as nb";
253 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as fi";
254 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON fi.fk_soc = s.rowid";
255 if (!$user->hasRight('societe', 'client', 'voir')) {
256 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
257 $sql .= " WHERE sc.fk_user = ".((int) $user->id);
258 $clause = "AND";
259 }
260 $sql .= " ".$clause." fi.entity IN (".getEntity('intervention').")";
261
262 $resql = $this->db->query($sql);
263 if ($resql) {
264 while ($obj = $this->db->fetch_object($resql)) {
265 $this->nb["interventions"] = $obj->nb;
266 }
267 $this->db->free($resql);
268 return 1;
269 } else {
270 dol_print_error($this->db);
271 $this->error = $this->db->error();
272 return -1;
273 }
274 }
275
283 public function create($user, $notrigger = 0)
284 {
285 global $conf, $langs;
286
287 $error = 0;
288
289 dol_syslog(get_class($this)."::create ref=".$this->ref);
290
291 // Check parameters
292 if (!empty($this->ref)) { // We check that ref is not already used
293 $result = self::isExistingObject($this->element, 0, $this->ref); // Check ref is not yet used
294 if ($result > 0) {
295 $this->error = 'ErrorRefAlreadyExists';
296 dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING);
297 $this->db->rollback();
298 return -1;
299 }
300 }
301 if (!is_numeric($this->duration)) {
302 $this->duration = 0;
303 }
304 if (isset($this->ref_client)) {
305 $this->ref_client = trim($this->ref_client);
306 }
307
308 if ($this->socid <= 0) {
309 $this->error = 'ErrorFicheinterCompanyDoesNotExist';
310 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
311 return -1;
312 }
313
314 $soc = new Societe($this->db);
315 $result = $soc->fetch($this->socid);
316
317 $now = dol_now();
318
319 $this->db->begin();
320
321 $sql = "INSERT INTO ".MAIN_DB_PREFIX."fichinter (";
322 $sql .= "fk_soc";
323 $sql .= ", datec";
324 $sql .= ", ref";
325 $sql .= ", ref_client";
326 $sql .= ", entity";
327 $sql .= ", fk_user_author";
328 $sql .= ", fk_user_modif";
329 $sql .= ", description";
330 $sql .= ", model_pdf";
331 $sql .= ", fk_projet";
332 $sql .= ", fk_contrat";
333 $sql .= ", fk_statut";
334 $sql .= ", note_private";
335 $sql .= ", note_public";
336 $sql .= ") ";
337 $sql .= " VALUES (";
338 $sql .= $this->socid;
339 $sql .= ", '".$this->db->idate($now)."'";
340 $sql .= ", '".$this->db->escape($this->ref)."'";
341 $sql .= ", ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
342 $sql .= ", ".((int) $conf->entity);
343 $sql .= ", ".((int) $user->id);
344 $sql .= ", ".((int) $user->id);
345 $sql .= ", ".($this->description ? "'".$this->db->escape($this->description)."'" : "null");
346 $sql .= ", '".$this->db->escape($this->model_pdf)."'";
347 $sql .= ", ".($this->fk_project ? ((int) $this->fk_project) : 0);
348 $sql .= ", ".($this->fk_contrat ? ((int) $this->fk_contrat) : 0);
349 $sql .= ", ".((int) $this->statut);
350 $sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
351 $sql .= ", ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
352 $sql .= ")";
353
354 dol_syslog(get_class($this)."::create", LOG_DEBUG);
355 $result = $this->db->query($sql);
356 if ($result) {
357 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."fichinter");
358
359 if ($this->id) {
360 $this->ref = '(PROV'.$this->id.')';
361 $sql = 'UPDATE '.MAIN_DB_PREFIX."fichinter SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".((int) $this->id);
362
363 dol_syslog(get_class($this)."::create", LOG_DEBUG);
364 $resql = $this->db->query($sql);
365 if (!$resql) {
366 $error++;
367 }
368 }
369
370 if (!$error) {
371 $result = $this->insertExtraFields();
372 if ($result < 0) {
373 $error++;
374 }
375 }
376
377 // Add linked object
378 if (!$error && $this->origin && $this->origin_id) {
379 $ret = $this->add_object_linked();
380 if (!$ret) {
381 dol_print_error($this->db);
382 }
383 }
384
385
386 if (!$error && !$notrigger) {
387 // Call trigger
388 $result = $this->call_trigger('FICHINTER_CREATE', $user);
389 if ($result < 0) {
390 $error++;
391 }
392 // End call triggers
393 }
394
395 if (!$error) {
396 $this->db->commit();
397 return $this->id;
398 } else {
399 $this->db->rollback();
400 $this->error = implode(',', $this->errors);
401 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
402 return -1;
403 }
404 } else {
405 $this->error = $this->db->error();
406 $this->db->rollback();
407 return -1;
408 }
409 }
410
418 public function update($user, $notrigger = 0)
419 {
420 global $conf;
421
422 if (!is_numeric($this->duration)) {
423 $this->duration = 0;
424 }
425 if (!dol_strlen($this->fk_project)) {
426 $this->fk_project = 0;
427 }
428 if (isset($this->ref_client)) {
429 $this->ref_client = trim($this->ref_client);
430 }
431
432 $error = 0;
433
434 $this->db->begin();
435
436 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter SET ";
437 $sql .= "description = '".$this->db->escape($this->description)."'";
438 $sql .= ", duree = ".((int) $this->duration);
439 $sql .= ", ref_client = ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
440 $sql .= ", fk_projet = ".((int) $this->fk_project);
441 $sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
442 $sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
443 $sql .= ", fk_user_modif = ".((int) $user->id);
444 $sql .= " WHERE rowid = ".((int) $this->id);
445
446 dol_syslog(get_class($this)."::update", LOG_DEBUG);
447 if ($this->db->query($sql)) {
448 if (!$error) {
449 $result = $this->insertExtraFields();
450 if ($result < 0) {
451 $error++;
452 }
453 }
454
455 if (!$error && !$notrigger) {
456 // Call trigger
457 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
458 if ($result < 0) {
459 $error++;
460 $this->db->rollback();
461 return -1;
462 }
463 // End call triggers
464 }
465
466 $this->db->commit();
467 return 1;
468 } else {
469 $this->error = $this->db->error();
470 $this->db->rollback();
471 return -1;
472 }
473 }
474
482 public function fetch($rowid, $ref = '')
483 {
484 $sql = "SELECT f.rowid, f.ref, f.ref_client, f.description, f.fk_soc, f.fk_statut as status,";
485 $sql .= " f.datec, f.dateo, f.datee, f.datet, f.fk_user_author,";
486 $sql .= " f.date_valid as datev,";
487 $sql .= " f.tms as datem,";
488 $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";
489 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
490 if ($ref) {
491 $sql .= " WHERE f.entity IN (".getEntity('intervention').")";
492 $sql .= " AND f.ref = '".$this->db->escape($ref)."'";
493 } else {
494 $sql .= " WHERE f.rowid = ".((int) $rowid);
495 }
496
497 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
498 $resql = $this->db->query($sql);
499 if ($resql) {
500 if ($this->db->num_rows($resql)) {
501 $obj = $this->db->fetch_object($resql);
502
503 $this->id = $obj->rowid;
504 $this->ref = $obj->ref;
505 $this->ref_client = $obj->ref_client;
506 $this->description = $obj->description;
507 $this->socid = $obj->fk_soc;
508 $this->status = $obj->status;
509 $this->statut = $obj->status; // deprecated
510 $this->duration = $obj->duree;
511 $this->datec = $this->db->jdate($obj->datec);
512 $this->dateo = $this->db->jdate($obj->dateo);
513 $this->datee = $this->db->jdate($obj->datee);
514 $this->datet = $this->db->jdate($obj->datet);
515 $this->datev = $this->db->jdate($obj->datev);
516 $this->datem = $this->db->jdate($obj->datem);
517 $this->fk_project = $obj->fk_project;
518 $this->note_public = $obj->note_public;
519 $this->note_private = $obj->note_private;
520 $this->model_pdf = $obj->model_pdf;
521 $this->fk_contrat = $obj->fk_contrat;
522 $this->entity = $obj->entity;
523
524 $this->user_creation_id = $obj->fk_user_author;
525
526 $this->extraparams = (array) json_decode($obj->extraparams, true);
527
528 $this->last_main_doc = $obj->last_main_doc;
529
530 // Retrieve extrafields
531 $this->fetch_optionals();
532
533 /*
534 * Lines
535 */
536 $result = $this->fetch_lines();
537 if ($result < 0) {
538 return -3;
539 }
540 $this->db->free($resql);
541 return 1;
542 }
543
544 return 0;
545 } else {
546 $this->error = $this->db->lasterror();
547 return -1;
548 }
549 }
550
557 public function setDraft($user)
558 {
559 $error = 0;
560
561 // Protection
562 if ($this->statut <= self::STATUS_DRAFT) {
563 return 0;
564 }
565
566 dol_syslog(get_class($this)."::setDraft", LOG_DEBUG);
567
568 $this->oldcopy = dol_clone($this, 2);
569
570 $this->db->begin();
571
572 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
573 $sql .= " SET fk_statut = ".self::STATUS_DRAFT;
574 $sql .= " WHERE rowid = ".((int) $this->id);
575
576 $resql = $this->db->query($sql);
577 if ($resql) {
578 if (!$error) {
579 // Call trigger
580 $result = $this->call_trigger('FICHINTER_UNVALIDATE', $user);
581 if ($result < 0) {
582 $error++;
583 }
584 }
585
586 if (!$error) {
587 $this->statut = self::STATUS_DRAFT;
588 $this->db->commit();
589 return 1;
590 } else {
591 $this->db->rollback();
592 return -1;
593 }
594 } else {
595 $this->db->rollback();
596 $this->error = $this->db->lasterror();
597 return -1;
598 }
599 }
600
608 public function setValid($user, $notrigger = 0)
609 {
610 global $conf;
611 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
612
613 $error = 0;
614
615 if ($this->status != self::STATUS_VALIDATED) {
616 $this->db->begin();
617
618 $now = dol_now();
619
620 // Define new ref
621 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
622 $num = $this->getNextNumRef($this->thirdparty);
623 } else {
624 $num = $this->ref;
625 }
626 $this->newref = dol_sanitizeFileName($num);
627
628 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
629 $sql .= " SET fk_statut = 1";
630 $sql .= ", ref = '".$this->db->escape($num)."'";
631 $sql .= ", date_valid = '".$this->db->idate($now)."'";
632 $sql .= ", fk_user_valid = ".($user->id > 0 ? (int) $user->id : "null");
633 $sql .= " WHERE rowid = ".((int) $this->id);
634 $sql .= " AND entity = ".((int) $this->entity);
635
636 $sql .= " AND fk_statut = 0";
637
638 dol_syslog(get_class($this)."::setValid", LOG_DEBUG);
639 $resql = $this->db->query($sql);
640 if (!$resql) {
641 dol_print_error($this->db);
642 $error++;
643 }
644
645 if (!$error && !$notrigger) {
646 // Call trigger
647 $result = $this->call_trigger('FICHINTER_VALIDATE', $user);
648 if ($result < 0) {
649 $error++;
650 }
651 // End call triggers
652 }
653
654 if (!$error) {
655 $this->oldref = $this->ref;
656
657 // Rename directory if dir was a temporary ref
658 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
659 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
660
661 // Now we rename also files into index
662 $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)."'";
663 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".((int) $this->entity);
664 $resql = $this->db->query($sql);
665 if (!$resql) {
666 $error++;
667 $this->error = $this->db->lasterror();
668 }
669 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'ficheinter/".$this->db->escape($this->newref)."'";
670 $sql .= " WHERE filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
671 $resql = $this->db->query($sql);
672 if (!$resql) {
673 $error++;
674 $this->error = $this->db->lasterror();
675 }
676
677 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
678 $oldref = dol_sanitizeFileName($this->ref);
679 $newref = dol_sanitizeFileName($num);
680 $dirsource = $conf->ficheinter->dir_output.'/'.$oldref;
681 $dirdest = $conf->ficheinter->dir_output.'/'.$newref;
682 if (!$error && file_exists($dirsource)) {
683 dol_syslog(get_class($this)."::setValid rename dir ".$dirsource." into ".$dirdest);
684
685 if (@rename($dirsource, $dirdest)) {
686 dol_syslog("Rename ok");
687 // Rename docs starting with $oldref with $newref
688 $listoffiles = dol_dir_list($conf->ficheinter->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
689 foreach ($listoffiles as $fileentry) {
690 $dirsource = $fileentry['name'];
691 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
692 $dirsource = $fileentry['path'].'/'.$dirsource;
693 $dirdest = $fileentry['path'].'/'.$dirdest;
694 @rename($dirsource, $dirdest);
695 }
696 }
697 }
698 }
699 }
700
701 // Set new ref and define current statut
702 if (!$error) {
703 $this->ref = $num;
705 $this->statut = self::STATUS_VALIDATED; // deprecated
706 $this->date_validation = $now;
707 $this->db->commit();
708 return 1;
709 } else {
710 $this->db->rollback();
711 dol_syslog(get_class($this)."::setValid ".$this->error, LOG_ERR);
712 return -1;
713 }
714 }
715
716 return 0;
717 }
718
726 public function setClose($user, $notrigger = 0)
727 {
728 global $conf;
729
730 $error = 0;
731
732 if ($this->statut == self::STATUS_CLOSED) {
733 return 0;
734 } else {
735 $this->db->begin();
736
737 $now = dol_now();
738
739 $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element;
740 $sql .= ' SET fk_statut = ' . self::STATUS_CLOSED . ',';
741 $sql .= " datet = '" . $this->db->idate($now) . "',";
742 $sql .= " fk_user_modif = " . ((int) $user->id);
743 $sql .= " WHERE rowid = " . ((int) $this->id);
744 $sql .= " AND fk_statut > " . self::STATUS_DRAFT;
745 $sql .= " AND entity = " . ((int) $conf->entity);
746
747 if ($this->db->query($sql)) {
748 if (!$notrigger) {
749 // Call trigger
750 $result = $this->call_trigger('FICHINTER_CLOSE', $user);
751 if ($result < 0) {
752 $error++;
753 }
754 // End call triggers
755 }
756
757 if (!$error) {
759 $this->db->commit();
760 return 1;
761 } else {
762 $this->db->rollback();
763 return -1;
764 }
765 } else {
766 $this->error = $this->db->lasterror();
767 $this->db->rollback();
768 return -1;
769 }
770 }
771 }
772
778 public function getAmount()
779 {
780 $amount = 0;
781
782 $this->author = new User($this->db);
783 $this->author->fetch($this->user_creation_id);
784
785 $thm = $this->author->thm;
786
787 foreach ($this->lines as $line) {
788 $amount += ($line->duration / 60 / 60 * (float) $thm);
789 }
790
791 return (float) price2num($amount, 'MT');
792 }
793
794
806 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
807 {
808 global $conf;
809
810 $outputlangs->load("interventions");
811
812 if (!dol_strlen($modele)) {
813 $modele = 'soleil';
814
815 if (!empty($this->model_pdf)) {
816 $modele = $this->model_pdf;
817 } elseif (getDolGlobalString('FICHEINTER_ADDON_PDF')) {
818 $modele = getDolGlobalString('FICHEINTER_ADDON_PDF');
819 }
820 }
821
822 $modelpath = "core/modules/fichinter/doc/";
823
824 return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
825 }
826
833 public function getLibStatut($mode = 0)
834 {
835 return $this->LibStatut((isset($this->statut) ? $this->statut : $this->status), $mode);
836 }
837
838 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
846 public function LibStatut($status, $mode = 0)
847 {
848 // phpcs:enable
849 // Init/load array of translation of status
850 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
851 global $langs;
852 $langs->load("fichinter");
853
854 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
855 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
856 $this->labelStatus[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
857 $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
858 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
859 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
860 $this->labelStatusShort[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
861 $this->labelStatusShort[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
862 }
863
864 $statuscode = 'status'.$status;
865 if ($status == self::STATUS_BILLED || $status == self::STATUS_CLOSED) {
866 $statuscode = 'status6';
867 }
868 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statuscode, $mode);
869 }
870
878 public function getTooltipContentArray($params)
879 {
880 global $conf, $langs;
881
882 $langs->load('fichinter');
883
884 $datas = [];
885 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Intervention").'</u>';
886 if (isset($this->status)) {
887 $datas['picto'] .= ' '.$this->getLibStatut(5);
888 }
889 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
890
891 return $datas;
892 }
893
904 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $save_lastsearch_value = -1, $morecss = '')
905 {
906 global $conf, $langs, $hookmanager;
907
908 if (!empty($conf->dol_no_mouse_hover)) {
909 $notooltip = 1; // Force disable tooltips
910 }
911
912 $result = '';
913 $params = [
914 'id' => $this->id,
915 'objecttype' => $this->element,
916 'option' => $option,
917 ];
918 $classfortooltip = 'classfortooltip';
919 $dataparams = '';
920 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
921 $classfortooltip = 'classforajaxtooltip';
922 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
923 $label = '';
924 } else {
925 $label = implode($this->getTooltipContentArray($params));
926 }
927
928 $url = DOL_URL_ROOT.'/fichinter/card.php?id='.$this->id;
929
930 if ($option !== 'nolink') {
931 // Add param to save lastsearch_values or not
932 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
933 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
934 $add_save_lastsearch_values = 1;
935 }
936 if ($add_save_lastsearch_values) {
937 $url .= '&save_lastsearch_values=1';
938 }
939 }
940
941 $linkclose = '';
942 if (empty($notooltip)) {
943 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
944 $label = $langs->trans("ShowIntervention");
945 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
946 }
947 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
948 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
949 } else {
950 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
951 }
952
953 if ($option == 'nolink' || empty($url)) {
954 $linkstart = '<span';
955 } else {
956 $linkstart = '<a href="'.$url.'"';
957 }
958 $linkstart .= $linkclose.'>';
959 if ($option == 'nolink' || empty($url)) {
960 $linkend = '</span>';
961 } else {
962 $linkend = '</a>';
963 }
964
965 $result .= $linkstart;
966 if ($withpicto) {
967 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
968 }
969
970 if ($withpicto != 2) {
971 $result .= $this->ref;
972 }
973
974 $result .= $linkend;
975
976 global $action;
977 $hookmanager->initHooks(array('interventiondao'));
978 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
979 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
980 if ($reshook > 0) {
981 $result = $hookmanager->resPrint;
982 } else {
983 $result .= $hookmanager->resPrint;
984 }
985
986 return $result;
987 }
988
989
997 public function getNextNumRef($soc)
998 {
999 global $conf, $db, $langs;
1000 $langs->load("interventions");
1001
1002 if (getDolGlobalString('FICHEINTER_ADDON')) {
1003 $mybool = false;
1004
1005 $file = "mod_" . getDolGlobalString('FICHEINTER_ADDON').".php";
1006 $classname = "mod_" . getDolGlobalString('FICHEINTER_ADDON');
1007
1008 // Include file with class
1009 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1010
1011 foreach ($dirmodels as $reldir) {
1012 $dir = dol_buildpath($reldir."core/modules/fichinter/");
1013
1014 // Load file with numbering class (if found)
1015 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1016 }
1017
1018 if ($mybool === false) {
1019 dol_print_error(null, "Failed to include file ".$file);
1020 return '';
1021 }
1022
1023 $obj = new $classname();
1024 $numref = "";
1025 $numref = $obj->getNextValue($soc, $this);
1026
1027 if ($numref != "") {
1028 return $numref;
1029 } else {
1030 dol_print_error($db, "Fichinter::getNextNumRef ".$obj->error);
1031 return "";
1032 }
1033 } else {
1034 $langs->load("errors");
1035 print $langs->trans("Error")." ".$langs->trans("Error_FICHEINTER_ADDON_NotDefined");
1036 return "";
1037 }
1038 }
1039
1046 public function info($id)
1047 {
1048 $sql = "SELECT f.rowid,";
1049 $sql .= " f.datec,";
1050 $sql .= " f.tms as date_modification,";
1051 $sql .= " f.date_valid as datev,";
1052 $sql .= " f.fk_user_author,";
1053 $sql .= " f.fk_user_modif as fk_user_modification,";
1054 $sql .= " f.fk_user_valid";
1055 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
1056 $sql .= " WHERE f.rowid = ".((int) $id);
1057
1058 $resql = $this->db->query($sql);
1059 if ($resql) {
1060 if ($this->db->num_rows($resql)) {
1061 $obj = $this->db->fetch_object($resql);
1062
1063 $this->id = $obj->rowid;
1064
1065 $this->date_creation = $this->db->jdate($obj->datec);
1066 $this->date_modification = $this->db->jdate($obj->date_modification);
1067 $this->date_validation = $this->db->jdate($obj->datev);
1068
1069 $this->user_creation_id = $obj->fk_user_author;
1070 $this->user_validation_id = $obj->fk_user_valid;
1071 $this->user_modification_id = $obj->fk_user_modification;
1072 }
1073 $this->db->free($resql);
1074 } else {
1075 dol_print_error($this->db);
1076 }
1077 }
1078
1086 public function delete(User $user, $notrigger = 0)
1087 {
1088 global $conf, $langs;
1089 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1090
1091 $error = 0;
1092
1093 $this->db->begin();
1094
1095 if (!$error && !$notrigger) {
1096 // Call trigger
1097 $result = $this->call_trigger('FICHINTER_DELETE', $user);
1098 if ($result < 0) {
1099 $error++;
1100 $this->db->rollback();
1101 return -1;
1102 }
1103 // End call triggers
1104 }
1105
1106 // Delete linked object
1107 if (!$error) {
1108 $res = $this->deleteObjectLinked();
1109 if ($res < 0) {
1110 $error++;
1111 }
1112 }
1113
1114 // Delete linked contacts
1115 if (!$error) {
1116 $res = $this->delete_linked_contact();
1117 if ($res < 0) {
1118 $this->error = 'ErrorFailToDeleteLinkedContact';
1119 $error++;
1120 }
1121 }
1122
1123 if (!$error) {
1124 $main = MAIN_DB_PREFIX.'fichinterdet';
1125 $ef = $main."_extrafields";
1126 $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_fichinter = ".((int) $this->id).")";
1127
1128 $resql = $this->db->query($sql);
1129 if (!$resql) {
1130 $error++;
1131 }
1132 }
1133
1134 if (!$error) {
1135 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet";
1136 $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1137
1138 $resql = $this->db->query($sql);
1139 if (!$resql) {
1140 $error++;
1141 }
1142 }
1143
1144 if (!$error) {
1145 // Remove extrafields
1146 $res = $this->deleteExtraFields();
1147 if ($res < 0) {
1148 $error++;
1149 }
1150 }
1151
1152 if (!$error) {
1153 // Delete object
1154 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinter";
1155 $sql .= " WHERE rowid = ".((int) $this->id);
1156
1157 dol_syslog("Fichinter::delete", LOG_DEBUG);
1158 $resql = $this->db->query($sql);
1159 if (!$resql) {
1160 $error++;
1161 }
1162 }
1163
1164 if (!$error) {
1165 // Delete record into ECM index (Note that delete is also done when deleting files with the dol_delete_dir_recursive
1166 $this->deleteEcmFiles(0); // Deleting files physically is done later with the dol_delete_dir_recursive
1167 $this->deleteEcmFiles(1); // Deleting files physically is done later with the dol_delete_dir_recursive
1168
1169 // Remove directory with files
1170 $fichinterref = dol_sanitizeFileName($this->ref);
1171 if ($conf->ficheinter->dir_output) {
1172 $dir = $conf->ficheinter->dir_output."/".$fichinterref;
1173 $file = $conf->ficheinter->dir_output."/".$fichinterref."/".$fichinterref.".pdf";
1174 if (file_exists($file)) {
1175 dol_delete_preview($this);
1176
1177 if (!dol_delete_file($file, 0, 0, 0, $this)) { // For triggers
1178 $langs->load("errors");
1179 $this->error = $langs->trans("ErrorFailToDeleteFile", $file);
1180 return 0;
1181 }
1182 }
1183 if (file_exists($dir)) {
1184 if (!dol_delete_dir_recursive($dir)) {
1185 $langs->load("errors");
1186 $this->error = $langs->trans("ErrorFailToDeleteDir", $dir);
1187 return 0;
1188 }
1189 }
1190 }
1191 }
1192
1193 if (!$error) {
1194 $this->db->commit();
1195 return 1;
1196 } else {
1197 $this->db->rollback();
1198 return -1;
1199 }
1200 }
1201
1202 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1210 public function set_date_delivery($user, $date_delivery)
1211 {
1212 // phpcs:enable
1213 if ($user->hasRight('ficheinter', 'creer')) {
1214 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1215 $sql .= " SET datei = '".$this->db->idate($date_delivery)."'";
1216 $sql .= " WHERE rowid = ".((int) $this->id);
1217 $sql .= " AND fk_statut = 0";
1218
1219 if ($this->db->query($sql)) {
1220 $this->date_delivery = $date_delivery;
1221 return 1;
1222 } else {
1223 $this->error = $this->db->error();
1224 dol_syslog("Fichinter::set_date_delivery Erreur SQL");
1225 return -1;
1226 }
1227 }
1228
1229 return 0;
1230 }
1231
1232 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1240 public function set_description($user, $description)
1241 {
1242 // phpcs:enable
1243 if ($user->hasRight('ficheinter', 'creer')) {
1244 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1245 $sql .= " SET description = '".$this->db->escape($description)."',";
1246 $sql .= " fk_user_modif = ".$user->id;
1247 $sql .= " WHERE rowid = ".((int) $this->id);
1248
1249 if ($this->db->query($sql)) {
1250 $this->description = $description;
1251 return 1;
1252 } else {
1253 $this->error = $this->db->error();
1254 dol_syslog("Fichinter::set_description Erreur SQL");
1255 return -1;
1256 }
1257 }
1258
1259 return 0;
1260 }
1261
1262
1263 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1271 public function set_contrat($user, $contractid)
1272 {
1273 // phpcs:enable
1274 if ($user->hasRight('ficheinter', 'creer')) {
1275 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1276 $sql .= " SET fk_contrat = ".((int) $contractid);
1277 $sql .= " WHERE rowid = ".((int) $this->id);
1278
1279 if ($this->db->query($sql)) {
1280 $this->fk_contrat = $contractid;
1281 return 1;
1282 } else {
1283 $this->error = $this->db->error();
1284 return -1;
1285 }
1286 }
1287
1288 return -2;
1289 }
1290
1291
1292
1300 public function createFromClone(User $user, $socid = 0)
1301 {
1302 global $hookmanager;
1303
1304 $error = 0;
1305
1306 $this->db->begin();
1307
1308 // get extrafields so they will be clone
1309 foreach ($this->lines as $line) {
1310 $line->fetch_optionals();
1311 }
1312
1313 // Load source object
1314 $objFrom = clone $this;
1315
1316 // Change socid if needed
1317 if (!empty($socid) && $socid != $this->socid) {
1318 $objsoc = new Societe($this->db);
1319
1320 if ($objsoc->fetch($socid) > 0) {
1321 $this->socid = $objsoc->id;
1322 //$this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1323 //$this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1324 $this->fk_project = 0;
1325 $this->fk_delivery_address = 0;
1326 }
1327
1328 // TODO Change product price if multi-prices
1329 }
1330
1331 $this->id = 0;
1332 $this->ref = '';
1333 $this->status = self::STATUS_DRAFT;
1334 $this->statut = self::STATUS_DRAFT; // deprecated
1335
1336 // Clear fields
1337 $this->user_author_id = $user->id;
1338 $this->user_validation_id = 0;
1339 $this->date_creation = '';
1340 $this->date_validation = '';
1341
1342 $this->ref_client = '';
1343
1344 // Create clone
1345 $this->context['createfromclone'] = 'createfromclone';
1346 $result = $this->create($user);
1347 if ($result < 0) {
1348 $error++;
1349 }
1350
1351 if (!$error) {
1352 // Add lines because it is not included into create function
1353 foreach ($this->lines as $line) {
1354 $this->addline($user, $this->id, $line->desc, $line->datei, $line->duration, $line->array_options);
1355 }
1356
1357 // Hook of thirdparty module
1358 if (is_object($hookmanager)) {
1359 $parameters = array('objFrom' => $objFrom);
1360 $action = '';
1361 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1362 if ($reshook < 0) {
1363 $this->setErrorsFromObject($hookmanager);
1364 $error++;
1365 }
1366 }
1367 }
1368
1369 unset($this->context['createfromclone']);
1370
1371 // End
1372 if (!$error) {
1373 $this->db->commit();
1374 return $this->id;
1375 } else {
1376 $this->db->rollback();
1377 return -1;
1378 }
1379 }
1380
1381
1393 public function addline($user, $fichinterid, $desc, $date_intervention, $duration, $array_options = [])
1394 {
1395 dol_syslog(get_class($this)."::addline $fichinterid, $desc, $date_intervention, $duration");
1396
1397 if ($this->status == self::STATUS_DRAFT) {
1398 $this->db->begin();
1399
1400 // Insertion ligne
1401 $line = new FichinterLigne($this->db);
1402
1403 $line->fk_fichinter = $fichinterid;
1404 $line->desc = $desc;
1405 $line->date = $date_intervention;
1406 $line->datei = $date_intervention; // For backward compatibility
1407 $line->duration = $duration;
1408
1409 if (is_array($array_options) && count($array_options) > 0) {
1410 $line->array_options = $array_options;
1411 }
1412
1413 $result = $line->insert($user);
1414
1415 if ($result >= 0) {
1416 $this->db->commit();
1417 return 1;
1418 } else {
1419 $this->error = $this->db->error();
1420 $this->db->rollback();
1421 return -1;
1422 }
1423 }
1424
1425 return 0;
1426 }
1427
1428
1436 public function initAsSpecimen()
1437 {
1438 global $langs;
1439
1440 $now = dol_now();
1441
1442 // Initialise parameters
1443 $this->id = 0;
1444 $this->ref = 'SPECIMEN';
1445 $this->ref_client = 'SPECIMEN CLIENT';
1446 $this->specimen = 1;
1447 $this->socid = 1;
1448 $this->datec = $now;
1449 $this->note_private = 'Private note';
1450 $this->note_public = 'SPECIMEN';
1451 $this->duration = 0;
1452 $nbp = 25;
1453 $xnbp = 0;
1454 while ($xnbp < $nbp) {
1455 $line = new FichinterLigne($this->db);
1456 $line->desc = $langs->trans("Description")." ".$xnbp;
1457 $line->date = ($now - 3600 * (1 + $xnbp));
1458 $line->datei = ($now - 3600 * (1 + $xnbp)); // For backward compatibility
1459 $line->duration = 600;
1460 $line->fk_fichinter = 0;
1461 $this->lines[$xnbp] = $line;
1462 $xnbp++;
1463
1464 $this->duration += $line->duration;
1465 }
1466
1467 return 1;
1468 }
1469
1470 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1476 public function fetch_lines()
1477 {
1478 // phpcs:enable
1479 $this->lines = array();
1480
1481 $sql = "SELECT rowid, fk_fichinter, description, duree, date, rang";
1482 $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet";
1483 $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1484 $sql .= " ORDER BY rang ASC, date ASC";
1485
1486 dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG);
1487
1488 $resql = $this->db->query($sql);
1489 if ($resql) {
1490 $num = $this->db->num_rows($resql);
1491 $i = 0;
1492 while ($i < $num) {
1493 $objp = $this->db->fetch_object($resql);
1494
1495 $line = new FichinterLigne($this->db);
1496 $line->id = $objp->rowid;
1497 $line->fk_fichinter = $objp->fk_fichinter;
1498 $line->desc = $objp->description;
1499 $line->duration = $objp->duree;
1500 //For invoicing we calculing hours
1501 $line->qty = round($objp->duree / 3600, 2);
1502 $line->date = $this->db->jdate($objp->date);
1503 $line->datei = $this->db->jdate($objp->date); // For backward compatibility
1504 $line->rang = $objp->rang;
1505 $line->product_type = 1;
1506 $line->fetch_optionals();
1507
1508 $this->lines[$i] = $line;
1509 $i++;
1510 }
1511 $this->db->free($resql);
1512
1513 return 1;
1514 } else {
1515 $this->error = $this->db->error();
1516 return -1;
1517 }
1518 }
1519
1528 public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1529 {
1530 $tables = array(
1531 'fichinter'
1532 );
1533
1534 return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1535 }
1536
1545 public function setRefClient($user, $ref_client, $notrigger = 0)
1546 {
1547 // phpcs:enable
1548 if ($user->hasRight('ficheinter', 'creer')) {
1549 $error = 0;
1550
1551 $this->db->begin();
1552
1553 $this->oldcopy = dol_clone($this, 2);
1554
1555 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET ref_client = ".(empty($ref_client) ? 'NULL' : "'".$this->db->escape($ref_client)."'");
1556 $sql .= " WHERE rowid = ".((int) $this->id);
1557
1558 dol_syslog(__METHOD__.' $this->id='.$this->id.', ref_client='.$ref_client, LOG_DEBUG);
1559 $resql = $this->db->query($sql);
1560 if (!$resql) {
1561 $this->errors[] = $this->db->error();
1562 $error++;
1563 }
1564
1565 if (!$error) {
1566 $this->ref_client = $ref_client;
1567 }
1568
1569 if (!$notrigger && empty($error)) {
1570 // Call trigger
1571 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
1572 if ($result < 0) {
1573 $error++;
1574 }
1575 // End call triggers
1576 }
1577
1578 if (!$error) {
1579 $this->db->commit();
1580 return 1;
1581 } else {
1582 foreach ($this->errors as $errmsg) {
1583 dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
1584 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1585 }
1586 $this->db->rollback();
1587 return -1 * $error;
1588 }
1589 } else {
1590 return -1;
1591 }
1592 }
1593
1601 public function getKanbanView($option = '', $arraydata = null)
1602 {
1603 global $langs;
1604
1605 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1606
1607 $return = '<div class="box-flex-item box-flex-grow-zero">';
1608 $return .= '<div class="info-box info-box-sm">';
1609 $return .= '<span class="info-box-icon bg-infobox-action">';
1610 $return .= img_picto('', $this->picto);
1611 $return .= '</span>';
1612 $return .= '<div class="info-box-content">';
1613 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
1614 if ($selected >= 0) {
1615 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1616 }
1617 if (!empty($arraydata['thirdparty'])) {
1618 $tmpthirdparty = $arraydata['thirdparty'];
1619 $return .= '<br><span class="info-box-label">'.$tmpthirdparty->getNomUrl(1).'</span>';
1620 }
1621 if (property_exists($this, 'duration')) {
1622 $return .= '<br><span class="info-box-label ">'.$langs->trans("Duration").' : '.convertSecondToTime($this->duration, 'allhourmin').'</span>';
1623 }
1624 if (method_exists($this, 'getLibStatut')) {
1625 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1626 }
1627 $return .= '</div>';
1628 $return .= '</div>';
1629 $return .= '</div>';
1630 return $return;
1631 }
1632
1642 public function setSignedStatus(User $user, int $status = 0, int $notrigger = 0, $triggercode = ''): int
1643 {
1644 return $this->setSignedStatusCommon($user, $status, $notrigger, $triggercode);
1645 }
1646}
1647
1652{
1656 public $db;
1657
1661 public $error = '';
1662
1663 // From llx_fichinterdet
1667 public $fk_fichinter;
1668
1669 public $desc; // Description ligne
1670
1674 public $date; // Date intervention
1679 public $datei; // Date intervention
1680
1681 public $duration; // Duration of intervention
1682 public $rang = 0;
1683 public $tva_tx;
1684
1689 public $subprice;
1690
1694 public $element = 'fichinterdet';
1695
1699 public $table_element = 'fichinterdet';
1700
1704 public $fk_element = 'fk_fichinter';
1705
1706
1707
1713 public function __construct($db)
1714 {
1715 $this->db = $db;
1716 }
1717
1724 public function fetch($rowid)
1725 {
1726 dol_syslog("FichinterLigne::fetch", LOG_DEBUG);
1727
1728 $sql = 'SELECT ft.rowid, ft.fk_fichinter, ft.description, ft.duree, ft.rang, ft.date';
1729 $sql .= ' FROM '.MAIN_DB_PREFIX.'fichinterdet as ft';
1730 $sql .= ' WHERE ft.rowid = '.((int) $rowid);
1731
1732 $resql = $this->db->query($sql);
1733 if ($resql) {
1734 $objp = $this->db->fetch_object($resql);
1735 $this->rowid = $objp->rowid;
1736 $this->id = $objp->rowid;
1737 $this->fk_fichinter = $objp->fk_fichinter;
1738 $this->date = $this->db->jdate($objp->date);
1739 $this->datei = $this->db->jdate($objp->date); // For backward compatibility
1740 $this->desc = $objp->description;
1741 $this->duration = $objp->duree;
1742 $this->rang = $objp->rang;
1743
1744 $this->db->free($resql);
1745
1746 $this->fetch_optionals();
1747
1748 return 1;
1749 } else {
1750 $this->error = $this->db->error().' sql='.$sql;
1751 return -1;
1752 }
1753 }
1754
1762 public function insert($user, $notrigger = 0)
1763 {
1764 $error = 0;
1765
1766 dol_syslog("FichinterLigne::insert rang=".$this->rang);
1767
1768 if (empty($this->date) && !empty($this->datei)) { // For backward compatibility
1769 $this->date = $this->datei;
1770 }
1771
1772 $this->db->begin();
1773
1774 $rangToUse = $this->rang;
1775 if ($rangToUse == -1) {
1776 // Recupere rang max de la ligne d'intervention dans $rangmax
1777 $sql = 'SELECT max(rang) as max FROM '.MAIN_DB_PREFIX.'fichinterdet';
1778 $sql .= ' WHERE fk_fichinter = '.((int) $this->fk_fichinter);
1779 $resql = $this->db->query($sql);
1780 if ($resql) {
1781 $obj = $this->db->fetch_object($resql);
1782 $rangToUse = $obj->max + 1;
1783 } else {
1784 dol_print_error($this->db);
1785 $this->db->rollback();
1786 return -1;
1787 }
1788 }
1789
1790 // Insertion dans base de la ligne
1791 $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'fichinterdet';
1792 $sql .= ' (fk_fichinter, description, date, duree, rang)';
1793 $sql .= " VALUES (".((int) $this->fk_fichinter).",";
1794 $sql .= " '".$this->db->escape($this->desc)."',";
1795 $sql .= " '".$this->db->idate($this->date)."',";
1796 $sql .= " ".((int) $this->duration).",";
1797 $sql .= ' '.((int) $rangToUse);
1798 $sql .= ')';
1799
1800 dol_syslog("FichinterLigne::insert", LOG_DEBUG);
1801 $resql = $this->db->query($sql);
1802 if ($resql) {
1803 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'fichinterdet');
1804 $this->rowid = $this->id;
1805
1806 if (!$error) {
1807 $result = $this->insertExtraFields();
1808 if ($result < 0) {
1809 $error++;
1810 }
1811 }
1812
1813
1814 $result = $this->update_total();
1815
1816 if ($result > 0) {
1817 $this->rang = $rangToUse;
1818
1819 if (!$notrigger) {
1820 // Call trigger
1821 $result = $this->call_trigger('LINEFICHINTER_CREATE', $user);
1822 if ($result < 0) {
1823 $error++;
1824 }
1825 // End call triggers
1826 }
1827 }
1828
1829 if (!$error) {
1830 $this->db->commit();
1831 return $result;
1832 } else {
1833 $this->db->rollback();
1834 return -1;
1835 }
1836 } else {
1837 $this->error = $this->db->error()." sql=".$sql;
1838 $this->db->rollback();
1839 return -1;
1840 }
1841 }
1842
1843
1851 public function update($user, $notrigger = 0)
1852 {
1853 $error = 0;
1854
1855 if (empty($this->date) && !empty($this->datei)) { // For backward compatibility
1856 $this->date = $this->datei;
1857 }
1858
1859 $this->db->begin();
1860
1861 // Mise a jour ligne en base
1862 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinterdet SET";
1863 $sql .= " description = '".$this->db->escape($this->desc)."',";
1864 $sql .= " date = '".$this->db->idate($this->date)."',";
1865 $sql .= " duree = ".((int) $this->duration).",";
1866 $sql .= " rang = ".((int) $this->rang);
1867 $sql .= " WHERE rowid = ".((int) $this->id);
1868
1869 dol_syslog("FichinterLigne::update", LOG_DEBUG);
1870 $resql = $this->db->query($sql);
1871 if ($resql) {
1872 if (!$error) {
1873 $result = $this->insertExtraFields();
1874 if ($result < 0) {
1875 $error++;
1876 }
1877 }
1878
1879 $result = $this->update_total();
1880 if ($result > 0) {
1881 if (!$notrigger) {
1882 // Call trigger
1883 $result = $this->call_trigger('LINEFICHINTER_MODIFY', $user);
1884 if ($result < 0) {
1885 $error++;
1886 }
1887 // End call triggers
1888 }
1889 }
1890
1891 if (!$error) {
1892 $this->db->commit();
1893 return $result;
1894 } else {
1895 $this->error = $this->db->lasterror();
1896 $this->db->rollback();
1897 return -1;
1898 }
1899 } else {
1900 $this->error = $this->db->lasterror();
1901 $this->db->rollback();
1902 return -1;
1903 }
1904 }
1905
1906 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1912 public function update_total()
1913 {
1914 // phpcs:enable
1915 global $conf;
1916
1917 $this->db->begin();
1918
1919 $sql = "SELECT SUM(duree) as total_duration, min(date) as dateo, max(date) as datee ";
1920 $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet";
1921 $sql .= " WHERE fk_fichinter=".((int) $this->fk_fichinter);
1922
1923 dol_syslog("FichinterLigne::update_total", LOG_DEBUG);
1924 $resql = $this->db->query($sql);
1925 if ($resql) {
1926 $obj = $this->db->fetch_object($resql);
1927 $total_duration = 0;
1928 if (!empty($obj->total_duration)) {
1929 $total_duration = $obj->total_duration;
1930 }
1931
1932 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
1933 $sql .= " SET duree = ".((int) $total_duration);
1934 $sql .= " , dateo = ".(!empty($obj->dateo) ? "'".$this->db->escape($obj->dateo)."'" : "null");
1935 $sql .= " , datee = ".(!empty($obj->datee) ? "'".$this->db->escape($obj->datee)."'" : "null");
1936 $sql .= " WHERE rowid = ".((int) $this->fk_fichinter);
1937
1938 dol_syslog("FichinterLigne::update_total", LOG_DEBUG);
1939 $resql = $this->db->query($sql);
1940 if ($resql) {
1941 $this->db->commit();
1942 return 1;
1943 } else {
1944 $this->error = $this->db->error();
1945 $this->db->rollback();
1946 return -2;
1947 }
1948 } else {
1949 $this->error = $this->db->error();
1950 $this->db->rollback();
1951 return -1;
1952 }
1953 }
1954
1962 public function deleteLine($user, $notrigger = 0)
1963 {
1964 $error = 0;
1965
1966 dol_syslog(get_class($this)."::deleteline lineid=".$this->id);
1967
1968 $this->db->begin();
1969
1970 $result = $this->deleteExtraFields();
1971 if ($result < 0) {
1972 $error++;
1973 $this->db->rollback();
1974 return -1;
1975 }
1976
1977 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet WHERE rowid = ".((int) $this->id);
1978 $resql = $this->db->query($sql);
1979
1980 if ($resql) {
1981 $result = $this->update_total();
1982 if ($result > 0) {
1983 if (!$notrigger) {
1984 // Call trigger
1985 $result = $this->call_trigger('LINEFICHINTER_DELETE', $user);
1986 if ($result < 0) {
1987 $error++;
1988 $this->db->rollback();
1989 return -1;
1990 }
1991 // End call triggers
1992 }
1993
1994 $this->db->commit();
1995 return $result;
1996 } else {
1997 $this->db->rollback();
1998 return -1;
1999 }
2000 } else {
2001 $this->error = $this->db->error()." sql=".$sql;
2002 $this->db->rollback();
2003 return -1;
2004 }
2005 }
2006}
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition security.php:636
$object ref
Definition info.php:79
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.
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid=0, $f_user=null, $notrigger=0)
Delete all links between an object $this.
setErrorsFromObject($object)
setErrorsFromObject
static isExistingObject($element, $id, $ref='', $ref_ext='')
Check if an object id or ref exists If you don't need or want to instantiate the object and just need...
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.
setSignedStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a signed status.
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.
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.
const STATUS_SIGNED_RECEIVER
Signed by receiver.
const STATUS_SIGNED_ALL
Signed by all.
setClose($user, $notrigger=0)
Close intervention.
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)
setSignedStatus(User $user, int $status=0, int $notrigger=0, $triggercode='')
Set signed status.
addline($user, $fichinterid, $desc, $date_intervention, $duration, $array_options=[])
Adding a line of intervention into data base.
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.
loadStateBoard()
Load indicators into this->nb for board.
getNomUrl($withpicto=0, $option='', $notooltip=0, $save_lastsearch_value=-1, $morecss='')
Return clicable name (with picto eventually)
const STATUS_SIGNED_SENDER
Signed by sender.
__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.
const STATUS_NO_SIGNATURE
No signature.
Class to manage intervention lines.
deleteLine($user, $notrigger=0)
Delete a intervention line.
fetch($rowid)
Retrieve the line of intervention.
update_total()
Update total duration into llx_fichinter.
update($user, $notrigger=0)
Update intervention into database.
__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.
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:241
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
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)
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.
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
dol_delete_preview($object)
Delete all preview files linked to object instance.
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)
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for each properties) With native =...
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.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall TAKEPOS_SHOW_SUBPRICE right right right takeposterminal SELECT e e e e e statut
Definition invoice.php:1991
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall TAKEPOS_SHOW_SUBPRICE right right right takeposterminal SELECT e rowid
Definition invoice.php:1991