dolibarr 21.0.0-alpha
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
112 public $datec;
113
117 public $datev;
121 public $dateo;
125 public $datee;
126
130 public $datet;
131
137 public $datem;
138
142 public $duration;
143
147 public $statut = 0; // 0=draft, 1=validated, 2=invoiced, 3=Terminate
148
153 public $signed_status = 0;
154
158 public $description;
159
163 public $fk_contrat = 0;
164
168 public $fk_project = 0;
169
174 public $ref_client;
175
179 public $extraparams = array();
180
184 public $lines = array();
185
189 const STATUS_DRAFT = 0;
190
195
199 const STATUS_BILLED = 2;
200
204 const STATUS_CLOSED = 3;
205
206
211
216
221
225 const STATUS_SIGNED_ALL = 9; // To handle future kind of signature (ex: tripartite contract)
226
227
232 public $date_delivery;
233
238 public $user_author_id;
239
240
246 public function __construct($db)
247 {
248 $this->db = $db;
249 }
250
256 public function loadStateBoard()
257 {
258 global $user;
259
260 $this->nb = array();
261 $clause = "WHERE";
262
263 $sql = "SELECT count(fi.rowid) as nb";
264 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as fi";
265 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON fi.fk_soc = s.rowid";
266 if (!$user->hasRight('societe', 'client', 'voir')) {
267 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
268 $sql .= " WHERE sc.fk_user = ".((int) $user->id);
269 $clause = "AND";
270 }
271 $sql .= " ".$clause." fi.entity IN (".getEntity('intervention').")";
272
273 $resql = $this->db->query($sql);
274 if ($resql) {
275 while ($obj = $this->db->fetch_object($resql)) {
276 $this->nb["interventions"] = $obj->nb;
277 }
278 $this->db->free($resql);
279 return 1;
280 } else {
281 dol_print_error($this->db);
282 $this->error = $this->db->error();
283 return -1;
284 }
285 }
286
294 public function create($user, $notrigger = 0)
295 {
296 global $conf, $langs;
297
298 $error = 0;
299
300 dol_syslog(get_class($this)."::create ref=".$this->ref);
301
302 // Check parameters
303 if (!empty($this->ref)) { // We check that ref is not already used
304 $result = self::isExistingObject($this->element, 0, $this->ref); // Check ref is not yet used
305 if ($result > 0) {
306 $this->error = 'ErrorRefAlreadyExists';
307 dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING);
308 $this->db->rollback();
309 return -1;
310 }
311 }
312 if (!is_numeric($this->duration)) {
313 $this->duration = 0;
314 }
315 if (isset($this->ref_client)) {
316 $this->ref_client = trim($this->ref_client);
317 }
318
319 if ($this->socid <= 0) {
320 $this->error = 'ErrorFicheinterCompanyDoesNotExist';
321 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
322 return -1;
323 }
324
325 $soc = new Societe($this->db);
326 $result = $soc->fetch($this->socid);
327
328 $now = dol_now();
329
330 $this->db->begin();
331
332 $sql = "INSERT INTO ".MAIN_DB_PREFIX."fichinter (";
333 $sql .= "fk_soc";
334 $sql .= ", datec";
335 $sql .= ", ref";
336 $sql .= ", ref_client";
337 $sql .= ", entity";
338 $sql .= ", fk_user_author";
339 $sql .= ", fk_user_modif";
340 $sql .= ", description";
341 $sql .= ", model_pdf";
342 $sql .= ", fk_projet";
343 $sql .= ", fk_contrat";
344 $sql .= ", fk_statut";
345 $sql .= ", note_private";
346 $sql .= ", note_public";
347 $sql .= ") ";
348 $sql .= " VALUES (";
349 $sql .= $this->socid;
350 $sql .= ", '".$this->db->idate($now)."'";
351 $sql .= ", '".$this->db->escape($this->ref)."'";
352 $sql .= ", ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
353 $sql .= ", ".((int) $conf->entity);
354 $sql .= ", ".((int) $user->id);
355 $sql .= ", ".((int) $user->id);
356 $sql .= ", ".($this->description ? "'".$this->db->escape($this->description)."'" : "null");
357 $sql .= ", '".$this->db->escape($this->model_pdf)."'";
358 $sql .= ", ".($this->fk_project ? ((int) $this->fk_project) : 0);
359 $sql .= ", ".($this->fk_contrat ? ((int) $this->fk_contrat) : 0);
360 $sql .= ", ".((int) $this->statut);
361 $sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
362 $sql .= ", ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
363 $sql .= ")";
364
365 dol_syslog(get_class($this)."::create", LOG_DEBUG);
366 $result = $this->db->query($sql);
367 if ($result) {
368 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."fichinter");
369
370 if ($this->id) {
371 $this->ref = '(PROV'.$this->id.')';
372 $sql = 'UPDATE '.MAIN_DB_PREFIX."fichinter SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".((int) $this->id);
373
374 dol_syslog(get_class($this)."::create", LOG_DEBUG);
375 $resql = $this->db->query($sql);
376 if (!$resql) {
377 $error++;
378 }
379 }
380
381 if (!$error) {
382 $result = $this->insertExtraFields();
383 if ($result < 0) {
384 $error++;
385 }
386 }
387
388 // Add linked object
389 if (!$error && $this->origin && $this->origin_id) {
390 $ret = $this->add_object_linked();
391 if (!$ret) {
392 dol_print_error($this->db);
393 }
394 }
395
396
397 if (!$error && !$notrigger) {
398 // Call trigger
399 $result = $this->call_trigger('FICHINTER_CREATE', $user);
400 if ($result < 0) {
401 $error++;
402 }
403 // End call triggers
404 }
405
406 if (!$error) {
407 $this->db->commit();
408 return $this->id;
409 } else {
410 $this->db->rollback();
411 $this->error = implode(',', $this->errors);
412 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
413 return -1;
414 }
415 } else {
416 $this->error = $this->db->error();
417 $this->db->rollback();
418 return -1;
419 }
420 }
421
429 public function update($user, $notrigger = 0)
430 {
431 global $conf;
432
433 if (!is_numeric($this->duration)) {
434 $this->duration = 0;
435 }
436 if (!dol_strlen($this->fk_project)) {
437 $this->fk_project = 0;
438 }
439 if (isset($this->ref_client)) {
440 $this->ref_client = trim($this->ref_client);
441 }
442
443 $error = 0;
444
445 $this->db->begin();
446
447 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter SET ";
448 $sql .= "description = '".$this->db->escape($this->description)."'";
449 $sql .= ", duree = ".((int) $this->duration);
450 $sql .= ", ref_client = ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
451 $sql .= ", fk_projet = ".((int) $this->fk_project);
452 $sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
453 $sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
454 $sql .= ", fk_user_modif = ".((int) $user->id);
455 $sql .= " WHERE rowid = ".((int) $this->id);
456
457 dol_syslog(get_class($this)."::update", LOG_DEBUG);
458 if ($this->db->query($sql)) {
459 if (!$error) {
460 $result = $this->insertExtraFields();
461 if ($result < 0) {
462 $error++;
463 }
464 }
465
466 if (!$error && !$notrigger) {
467 // Call trigger
468 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
469 if ($result < 0) {
470 $error++;
471 $this->db->rollback();
472 return -1;
473 }
474 // End call triggers
475 }
476
477 $this->db->commit();
478 return 1;
479 } else {
480 $this->error = $this->db->error();
481 $this->db->rollback();
482 return -1;
483 }
484 }
485
493 public function fetch($rowid, $ref = '')
494 {
495 $sql = "SELECT f.rowid, f.ref, f.ref_client, f.description, f.fk_soc, f.fk_statut as status,";
496 $sql .= " f.datec, f.dateo, f.datee, f.datet, f.fk_user_author,";
497 $sql .= " f.date_valid as datev,";
498 $sql .= " f.tms as datem,";
499 $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";
500 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
501 if ($ref) {
502 $sql .= " WHERE f.entity IN (".getEntity('intervention').")";
503 $sql .= " AND f.ref = '".$this->db->escape($ref)."'";
504 } else {
505 $sql .= " WHERE f.rowid = ".((int) $rowid);
506 }
507
508 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
509 $resql = $this->db->query($sql);
510 if ($resql) {
511 if ($this->db->num_rows($resql)) {
512 $obj = $this->db->fetch_object($resql);
513
514 $this->id = $obj->rowid;
515 $this->ref = $obj->ref;
516 $this->ref_client = $obj->ref_client;
517 $this->description = $obj->description;
518 $this->socid = $obj->fk_soc;
519 $this->status = $obj->status;
520 $this->statut = $obj->status; // deprecated
521 $this->duration = $obj->duree;
522 $this->datec = $this->db->jdate($obj->datec);
523 $this->dateo = $this->db->jdate($obj->dateo);
524 $this->datee = $this->db->jdate($obj->datee);
525 $this->datet = $this->db->jdate($obj->datet);
526 $this->datev = $this->db->jdate($obj->datev);
527 $this->datem = $this->db->jdate($obj->datem);
528 $this->fk_project = $obj->fk_project;
529 $this->note_public = $obj->note_public;
530 $this->note_private = $obj->note_private;
531 $this->model_pdf = $obj->model_pdf;
532 $this->fk_contrat = $obj->fk_contrat;
533 $this->entity = $obj->entity;
534
535 $this->user_creation_id = $obj->fk_user_author;
536
537 $this->extraparams = (array) json_decode($obj->extraparams, true);
538
539 $this->last_main_doc = $obj->last_main_doc;
540
541 // Retrieve extrafields
542 $this->fetch_optionals();
543
544 /*
545 * Lines
546 */
547 $result = $this->fetch_lines();
548 if ($result < 0) {
549 return -3;
550 }
551 $this->db->free($resql);
552 return 1;
553 }
554
555 return 0;
556 } else {
557 $this->error = $this->db->lasterror();
558 return -1;
559 }
560 }
561
568 public function setDraft($user)
569 {
570 $error = 0;
571
572 // Protection
573 if ($this->statut <= self::STATUS_DRAFT) {
574 return 0;
575 }
576
577 dol_syslog(get_class($this)."::setDraft", LOG_DEBUG);
578
579 $this->oldcopy = dol_clone($this, 2);
580
581 $this->db->begin();
582
583 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
584 $sql .= " SET fk_statut = ".self::STATUS_DRAFT;
585 $sql .= " WHERE rowid = ".((int) $this->id);
586
587 $resql = $this->db->query($sql);
588 if ($resql) {
589 if (!$error) {
590 // Call trigger
591 $result = $this->call_trigger('FICHINTER_UNVALIDATE', $user);
592 if ($result < 0) {
593 $error++;
594 }
595 }
596
597 if (!$error) {
598 $this->statut = self::STATUS_DRAFT;
599 $this->db->commit();
600 return 1;
601 } else {
602 $this->db->rollback();
603 return -1;
604 }
605 } else {
606 $this->db->rollback();
607 $this->error = $this->db->lasterror();
608 return -1;
609 }
610 }
611
619 public function setValid($user, $notrigger = 0)
620 {
621 global $conf;
622 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
623
624 $error = 0;
625
626 if ($this->status != self::STATUS_VALIDATED) {
627 $this->db->begin();
628
629 $now = dol_now();
630
631 // Define new ref
632 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
633 $num = $this->getNextNumRef($this->thirdparty);
634 } else {
635 $num = $this->ref;
636 }
637 $this->newref = dol_sanitizeFileName($num);
638
639 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
640 $sql .= " SET fk_statut = 1";
641 $sql .= ", ref = '".$this->db->escape($num)."'";
642 $sql .= ", date_valid = '".$this->db->idate($now)."'";
643 $sql .= ", fk_user_valid = ".($user->id > 0 ? (int) $user->id : "null");
644 $sql .= " WHERE rowid = ".((int) $this->id);
645 $sql .= " AND entity = ".((int) $this->entity);
646
647 $sql .= " AND fk_statut = 0";
648
649 dol_syslog(get_class($this)."::setValid", LOG_DEBUG);
650 $resql = $this->db->query($sql);
651 if (!$resql) {
652 dol_print_error($this->db);
653 $error++;
654 }
655
656 if (!$error && !$notrigger) {
657 // Call trigger
658 $result = $this->call_trigger('FICHINTER_VALIDATE', $user);
659 if ($result < 0) {
660 $error++;
661 }
662 // End call triggers
663 }
664
665 if (!$error) {
666 $this->oldref = $this->ref;
667
668 // Rename directory if dir was a temporary ref
669 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
670 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
671
672 // Now we rename also files into index
673 $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)."'";
674 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".((int) $this->entity);
675 $resql = $this->db->query($sql);
676 if (!$resql) {
677 $error++;
678 $this->error = $this->db->lasterror();
679 }
680 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'ficheinter/".$this->db->escape($this->newref)."'";
681 $sql .= " WHERE filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
682 $resql = $this->db->query($sql);
683 if (!$resql) {
684 $error++;
685 $this->error = $this->db->lasterror();
686 }
687
688 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
689 $oldref = dol_sanitizeFileName($this->ref);
690 $newref = dol_sanitizeFileName($num);
691 $dirsource = $conf->ficheinter->dir_output.'/'.$oldref;
692 $dirdest = $conf->ficheinter->dir_output.'/'.$newref;
693 if (!$error && file_exists($dirsource)) {
694 dol_syslog(get_class($this)."::setValid rename dir ".$dirsource." into ".$dirdest);
695
696 if (@rename($dirsource, $dirdest)) {
697 dol_syslog("Rename ok");
698 // Rename docs starting with $oldref with $newref
699 $listoffiles = dol_dir_list($conf->ficheinter->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
700 foreach ($listoffiles as $fileentry) {
701 $dirsource = $fileentry['name'];
702 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
703 $dirsource = $fileentry['path'].'/'.$dirsource;
704 $dirdest = $fileentry['path'].'/'.$dirdest;
705 @rename($dirsource, $dirdest);
706 }
707 }
708 }
709 }
710 }
711
712 // Set new ref and define current statut
713 if (!$error) {
714 $this->ref = $num;
716 $this->statut = self::STATUS_VALIDATED; // deprecated
717 $this->date_validation = $now;
718 $this->db->commit();
719 return 1;
720 } else {
721 $this->db->rollback();
722 dol_syslog(get_class($this)."::setValid ".$this->error, LOG_ERR);
723 return -1;
724 }
725 }
726
727 return 0;
728 }
729
737 public function setClose($user, $notrigger = 0)
738 {
739 global $conf;
740
741 $error = 0;
742
743 if ($this->statut == self::STATUS_CLOSED) {
744 return 0;
745 } else {
746 $this->db->begin();
747
748 $now = dol_now();
749
750 $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element;
751 $sql .= ' SET fk_statut = ' . self::STATUS_CLOSED . ',';
752 $sql .= " datet = '" . $this->db->idate($now) . "',";
753 $sql .= " fk_user_modif = " . ((int) $user->id);
754 $sql .= " WHERE rowid = " . ((int) $this->id);
755 $sql .= " AND fk_statut > " . self::STATUS_DRAFT;
756 $sql .= " AND entity = " . ((int) $conf->entity);
757
758 if ($this->db->query($sql)) {
759 if (!$notrigger) {
760 // Call trigger
761 $result = $this->call_trigger('FICHINTER_CLOSE', $user);
762 if ($result < 0) {
763 $error++;
764 }
765 // End call triggers
766 }
767
768 if (!$error) {
770 $this->db->commit();
771 return 1;
772 } else {
773 $this->db->rollback();
774 return -1;
775 }
776 } else {
777 $this->error = $this->db->lasterror();
778 $this->db->rollback();
779 return -1;
780 }
781 }
782 }
783
789 public function getAmount()
790 {
791 $amount = 0;
792
793 $this->author = new User($this->db);
794 $this->author->fetch($this->user_creation_id);
795
796 $thm = $this->author->thm;
797
798 foreach ($this->lines as $line) {
799 $amount += ($line->duration / 60 / 60 * (float) $thm);
800 }
801
802 return (float) price2num($amount, 'MT');
803 }
804
805
817 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
818 {
819 global $conf;
820
821 $outputlangs->load("interventions");
822
823 if (!dol_strlen($modele)) {
824 $modele = 'soleil';
825
826 if (!empty($this->model_pdf)) {
827 $modele = $this->model_pdf;
828 } elseif (getDolGlobalString('FICHEINTER_ADDON_PDF')) {
829 $modele = getDolGlobalString('FICHEINTER_ADDON_PDF');
830 }
831 }
832
833 $modelpath = "core/modules/fichinter/doc/";
834
835 return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
836 }
837
844 public function getLibStatut($mode = 0)
845 {
846 return $this->LibStatut((isset($this->statut) ? $this->statut : $this->status), $mode);
847 }
848
849 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
857 public function LibStatut($status, $mode = 0)
858 {
859 // phpcs:enable
860 // Init/load array of translation of status
861 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
862 global $langs;
863 $langs->load("fichinter");
864
865 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
866 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
867 $this->labelStatus[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
868 $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
869 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
870 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
871 $this->labelStatusShort[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
872 $this->labelStatusShort[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
873 }
874
875 $statuscode = 'status'.$status;
876 if ($status == self::STATUS_BILLED || $status == self::STATUS_CLOSED) {
877 $statuscode = 'status6';
878 }
879 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statuscode, $mode);
880 }
881
889 public function getTooltipContentArray($params)
890 {
891 global $conf, $langs;
892
893 $langs->load('fichinter');
894
895 $datas = [];
896 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Intervention").'</u>';
897 if (isset($this->status)) {
898 $datas['picto'] .= ' '.$this->getLibStatut(5);
899 }
900 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
901
902 return $datas;
903 }
904
915 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $save_lastsearch_value = -1, $morecss = '')
916 {
917 global $conf, $langs, $hookmanager;
918
919 if (!empty($conf->dol_no_mouse_hover)) {
920 $notooltip = 1; // Force disable tooltips
921 }
922
923 $result = '';
924 $params = [
925 'id' => $this->id,
926 'objecttype' => $this->element,
927 'option' => $option,
928 ];
929 $classfortooltip = 'classfortooltip';
930 $dataparams = '';
931 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
932 $classfortooltip = 'classforajaxtooltip';
933 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
934 $label = '';
935 } else {
936 $label = implode($this->getTooltipContentArray($params));
937 }
938
939 $url = DOL_URL_ROOT.'/fichinter/card.php?id='.$this->id;
940
941 if ($option !== 'nolink') {
942 // Add param to save lastsearch_values or not
943 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
944 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
945 $add_save_lastsearch_values = 1;
946 }
947 if ($add_save_lastsearch_values) {
948 $url .= '&save_lastsearch_values=1';
949 }
950 }
951
952 $linkclose = '';
953 if (empty($notooltip)) {
954 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
955 $label = $langs->trans("ShowIntervention");
956 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
957 }
958 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
959 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
960 } else {
961 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
962 }
963
964 if ($option == 'nolink' || empty($url)) {
965 $linkstart = '<span';
966 } else {
967 $linkstart = '<a href="'.$url.'"';
968 }
969 $linkstart .= $linkclose.'>';
970 if ($option == 'nolink' || empty($url)) {
971 $linkend = '</span>';
972 } else {
973 $linkend = '</a>';
974 }
975
976 $result .= $linkstart;
977 if ($withpicto) {
978 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
979 }
980
981 if ($withpicto != 2) {
982 $result .= $this->ref;
983 }
984
985 $result .= $linkend;
986
987 global $action;
988 $hookmanager->initHooks(array('interventiondao'));
989 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
990 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
991 if ($reshook > 0) {
992 $result = $hookmanager->resPrint;
993 } else {
994 $result .= $hookmanager->resPrint;
995 }
996
997 return $result;
998 }
999
1000
1008 public function getNextNumRef($soc)
1009 {
1010 global $conf, $db, $langs;
1011 $langs->load("interventions");
1012
1013 if (getDolGlobalString('FICHEINTER_ADDON')) {
1014 $mybool = false;
1015
1016 $file = "mod_" . getDolGlobalString('FICHEINTER_ADDON').".php";
1017 $classname = "mod_" . getDolGlobalString('FICHEINTER_ADDON');
1018
1019 // Include file with class
1020 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1021
1022 foreach ($dirmodels as $reldir) {
1023 $dir = dol_buildpath($reldir."core/modules/fichinter/");
1024
1025 // Load file with numbering class (if found)
1026 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1027 }
1028
1029 if ($mybool === false) {
1030 dol_print_error(null, "Failed to include file ".$file);
1031 return '';
1032 }
1033
1034 $obj = new $classname();
1035 $numref = "";
1036 $numref = $obj->getNextValue($soc, $this);
1037
1038 if ($numref != "") {
1039 return $numref;
1040 } else {
1041 dol_print_error($db, "Fichinter::getNextNumRef ".$obj->error);
1042 return "";
1043 }
1044 } else {
1045 $langs->load("errors");
1046 print $langs->trans("Error")." ".$langs->trans("Error_FICHEINTER_ADDON_NotDefined");
1047 return "";
1048 }
1049 }
1050
1057 public function info($id)
1058 {
1059 $sql = "SELECT f.rowid,";
1060 $sql .= " f.datec,";
1061 $sql .= " f.tms as date_modification,";
1062 $sql .= " f.date_valid as datev,";
1063 $sql .= " f.fk_user_author,";
1064 $sql .= " f.fk_user_modif as fk_user_modification,";
1065 $sql .= " f.fk_user_valid";
1066 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
1067 $sql .= " WHERE f.rowid = ".((int) $id);
1068
1069 $resql = $this->db->query($sql);
1070 if ($resql) {
1071 if ($this->db->num_rows($resql)) {
1072 $obj = $this->db->fetch_object($resql);
1073
1074 $this->id = $obj->rowid;
1075
1076 $this->date_creation = $this->db->jdate($obj->datec);
1077 $this->date_modification = $this->db->jdate($obj->date_modification);
1078 $this->date_validation = $this->db->jdate($obj->datev);
1079
1080 $this->user_creation_id = $obj->fk_user_author;
1081 $this->user_validation_id = $obj->fk_user_valid;
1082 $this->user_modification_id = $obj->fk_user_modification;
1083 }
1084 $this->db->free($resql);
1085 } else {
1086 dol_print_error($this->db);
1087 }
1088 }
1089
1097 public function delete(User $user, $notrigger = 0)
1098 {
1099 global $conf, $langs;
1100 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1101
1102 $error = 0;
1103
1104 $this->db->begin();
1105
1106 if (!$error && !$notrigger) {
1107 // Call trigger
1108 $result = $this->call_trigger('FICHINTER_DELETE', $user);
1109 if ($result < 0) {
1110 $error++;
1111 $this->db->rollback();
1112 return -1;
1113 }
1114 // End call triggers
1115 }
1116
1117 // Delete linked object
1118 if (!$error) {
1119 $res = $this->deleteObjectLinked();
1120 if ($res < 0) {
1121 $error++;
1122 }
1123 }
1124
1125 // Delete linked contacts
1126 if (!$error) {
1127 $res = $this->delete_linked_contact();
1128 if ($res < 0) {
1129 $this->error = 'ErrorFailToDeleteLinkedContact';
1130 $error++;
1131 }
1132 }
1133
1134 if (!$error) {
1135 $main = MAIN_DB_PREFIX.'fichinterdet';
1136 $ef = $main."_extrafields";
1137 $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_fichinter = ".((int) $this->id).")";
1138
1139 $resql = $this->db->query($sql);
1140 if (!$resql) {
1141 $error++;
1142 }
1143 }
1144
1145 if (!$error) {
1146 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet";
1147 $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1148
1149 $resql = $this->db->query($sql);
1150 if (!$resql) {
1151 $error++;
1152 }
1153 }
1154
1155 if (!$error) {
1156 // Remove extrafields
1157 $res = $this->deleteExtraFields();
1158 if ($res < 0) {
1159 $error++;
1160 }
1161 }
1162
1163 if (!$error) {
1164 // Delete object
1165 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinter";
1166 $sql .= " WHERE rowid = ".((int) $this->id);
1167
1168 dol_syslog("Fichinter::delete", LOG_DEBUG);
1169 $resql = $this->db->query($sql);
1170 if (!$resql) {
1171 $error++;
1172 }
1173 }
1174
1175 if (!$error) {
1176 // Delete record into ECM index (Note that delete is also done when deleting files with the dol_delete_dir_recursive
1177 $this->deleteEcmFiles(0); // Deleting files physically is done later with the dol_delete_dir_recursive
1178 $this->deleteEcmFiles(1); // Deleting files physically is done later with the dol_delete_dir_recursive
1179
1180 // Remove directory with files
1181 $fichinterref = dol_sanitizeFileName($this->ref);
1182 if ($conf->ficheinter->dir_output) {
1183 $dir = $conf->ficheinter->dir_output."/".$fichinterref;
1184 $file = $conf->ficheinter->dir_output."/".$fichinterref."/".$fichinterref.".pdf";
1185 if (file_exists($file)) {
1186 dol_delete_preview($this);
1187
1188 if (!dol_delete_file($file, 0, 0, 0, $this)) { // For triggers
1189 $langs->load("errors");
1190 $this->error = $langs->trans("ErrorFailToDeleteFile", $file);
1191 return 0;
1192 }
1193 }
1194 if (file_exists($dir)) {
1195 if (!dol_delete_dir_recursive($dir)) {
1196 $langs->load("errors");
1197 $this->error = $langs->trans("ErrorFailToDeleteDir", $dir);
1198 return 0;
1199 }
1200 }
1201 }
1202 }
1203
1204 if (!$error) {
1205 $this->db->commit();
1206 return 1;
1207 } else {
1208 $this->db->rollback();
1209 return -1;
1210 }
1211 }
1212
1213 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1221 public function set_date_delivery($user, $date_delivery)
1222 {
1223 // phpcs:enable
1224 if ($user->hasRight('ficheinter', 'creer')) {
1225 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1226 $sql .= " SET datei = '".$this->db->idate($date_delivery)."'";
1227 $sql .= " WHERE rowid = ".((int) $this->id);
1228 $sql .= " AND fk_statut = 0";
1229
1230 if ($this->db->query($sql)) {
1231 $this->date_delivery = $date_delivery;
1232 return 1;
1233 } else {
1234 $this->error = $this->db->error();
1235 dol_syslog("Fichinter::set_date_delivery Erreur SQL");
1236 return -1;
1237 }
1238 }
1239
1240 return 0;
1241 }
1242
1243 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1251 public function set_description($user, $description)
1252 {
1253 // phpcs:enable
1254 if ($user->hasRight('ficheinter', 'creer')) {
1255 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1256 $sql .= " SET description = '".$this->db->escape($description)."',";
1257 $sql .= " fk_user_modif = ".$user->id;
1258 $sql .= " WHERE rowid = ".((int) $this->id);
1259
1260 if ($this->db->query($sql)) {
1261 $this->description = $description;
1262 return 1;
1263 } else {
1264 $this->error = $this->db->error();
1265 dol_syslog("Fichinter::set_description Erreur SQL");
1266 return -1;
1267 }
1268 }
1269
1270 return 0;
1271 }
1272
1273
1274 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1282 public function set_contrat($user, $contractid)
1283 {
1284 // phpcs:enable
1285 if ($user->hasRight('ficheinter', 'creer')) {
1286 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1287 $sql .= " SET fk_contrat = ".((int) $contractid);
1288 $sql .= " WHERE rowid = ".((int) $this->id);
1289
1290 if ($this->db->query($sql)) {
1291 $this->fk_contrat = $contractid;
1292 return 1;
1293 } else {
1294 $this->error = $this->db->error();
1295 return -1;
1296 }
1297 }
1298
1299 return -2;
1300 }
1301
1302
1303
1311 public function createFromClone(User $user, $socid = 0)
1312 {
1313 global $hookmanager;
1314
1315 $error = 0;
1316
1317 $this->db->begin();
1318
1319 // get extrafields so they will be clone
1320 foreach ($this->lines as $line) {
1321 $line->fetch_optionals();
1322 }
1323
1324 // Load source object
1325 $objFrom = clone $this;
1326
1327 // Change socid if needed
1328 if (!empty($socid) && $socid != $this->socid) {
1329 $objsoc = new Societe($this->db);
1330
1331 if ($objsoc->fetch($socid) > 0) {
1332 $this->socid = $objsoc->id;
1333 //$this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1334 //$this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1335 $this->fk_project = 0;
1336 $this->fk_delivery_address = 0;
1337 }
1338
1339 // TODO Change product price if multi-prices
1340 }
1341
1342 $this->id = 0;
1343 $this->ref = '';
1344 $this->status = self::STATUS_DRAFT;
1345 $this->statut = self::STATUS_DRAFT; // deprecated
1346
1347 // Clear fields
1348 $this->user_author_id = $user->id;
1349 $this->user_validation_id = 0;
1350 $this->date_creation = '';
1351 $this->date_validation = '';
1352
1353 $this->ref_client = '';
1354
1355 // Create clone
1356 $this->context['createfromclone'] = 'createfromclone';
1357 $result = $this->create($user);
1358 if ($result < 0) {
1359 $error++;
1360 }
1361
1362 if (!$error) {
1363 // Add lines because it is not included into create function
1364 foreach ($this->lines as $line) {
1365 $this->addline($user, $this->id, $line->desc, $line->datei, $line->duration, $line->array_options);
1366 }
1367
1368 // Hook of thirdparty module
1369 if (is_object($hookmanager)) {
1370 $parameters = array('objFrom' => $objFrom);
1371 $action = '';
1372 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1373 if ($reshook < 0) {
1374 $this->setErrorsFromObject($hookmanager);
1375 $error++;
1376 }
1377 }
1378 }
1379
1380 unset($this->context['createfromclone']);
1381
1382 // End
1383 if (!$error) {
1384 $this->db->commit();
1385 return $this->id;
1386 } else {
1387 $this->db->rollback();
1388 return -1;
1389 }
1390 }
1391
1392
1404 public function addline($user, $fichinterid, $desc, $date_intervention, $duration, $array_options = [])
1405 {
1406 dol_syslog(get_class($this)."::addline $fichinterid, $desc, $date_intervention, $duration");
1407
1408 if ($this->status == self::STATUS_DRAFT) {
1409 $this->db->begin();
1410
1411 // Insertion ligne
1412 $line = new FichinterLigne($this->db);
1413
1414 $line->fk_fichinter = $fichinterid;
1415 $line->desc = $desc;
1416 $line->date = $date_intervention;
1417 $line->datei = $date_intervention; // For backward compatibility
1418 $line->duration = $duration;
1419
1420 if (is_array($array_options) && count($array_options) > 0) {
1421 $line->array_options = $array_options;
1422 }
1423
1424 $result = $line->insert($user);
1425
1426 if ($result >= 0) {
1427 $this->db->commit();
1428 return 1;
1429 } else {
1430 $this->error = $this->db->error();
1431 $this->db->rollback();
1432 return -1;
1433 }
1434 }
1435
1436 return 0;
1437 }
1438
1439
1447 public function initAsSpecimen()
1448 {
1449 global $langs;
1450
1451 $now = dol_now();
1452
1453 // Initialise parameters
1454 $this->id = 0;
1455 $this->ref = 'SPECIMEN';
1456 $this->ref_client = 'SPECIMEN CLIENT';
1457 $this->specimen = 1;
1458 $this->socid = 1;
1459 $this->datec = $now;
1460 $this->note_private = 'Private note';
1461 $this->note_public = 'SPECIMEN';
1462 $this->duration = 0;
1463 $nbp = 25;
1464 $xnbp = 0;
1465 while ($xnbp < $nbp) {
1466 $line = new FichinterLigne($this->db);
1467 $line->desc = $langs->trans("Description")." ".$xnbp;
1468 $line->date = ($now - 3600 * (1 + $xnbp));
1469 $line->datei = ($now - 3600 * (1 + $xnbp)); // For backward compatibility
1470 $line->duration = 600;
1471 $line->fk_fichinter = 0;
1472 $this->lines[$xnbp] = $line;
1473 $xnbp++;
1474
1475 $this->duration += $line->duration;
1476 }
1477
1478 return 1;
1479 }
1480
1481 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1487 public function fetch_lines()
1488 {
1489 // phpcs:enable
1490 $this->lines = array();
1491
1492 $sql = "SELECT rowid, fk_fichinter, description, duree, date, rang";
1493 $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet";
1494 $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1495 $sql .= " ORDER BY rang ASC, date ASC";
1496
1497 dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG);
1498
1499 $resql = $this->db->query($sql);
1500 if ($resql) {
1501 $num = $this->db->num_rows($resql);
1502 $i = 0;
1503 while ($i < $num) {
1504 $objp = $this->db->fetch_object($resql);
1505
1506 $line = new FichinterLigne($this->db);
1507 $line->id = $objp->rowid;
1508 $line->fk_fichinter = $objp->fk_fichinter;
1509 $line->desc = $objp->description;
1510 $line->duration = $objp->duree;
1511 //For invoicing we calculing hours
1512 $line->qty = round($objp->duree / 3600, 2);
1513 $line->date = $this->db->jdate($objp->date);
1514 $line->datei = $this->db->jdate($objp->date); // For backward compatibility
1515 $line->rang = $objp->rang;
1516 $line->product_type = 1;
1517 $line->fetch_optionals();
1518
1519 $this->lines[$i] = $line;
1520 $i++;
1521 }
1522 $this->db->free($resql);
1523
1524 return 1;
1525 } else {
1526 $this->error = $this->db->error();
1527 return -1;
1528 }
1529 }
1530
1539 public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1540 {
1541 $tables = array(
1542 'fichinter'
1543 );
1544
1545 return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1546 }
1547
1556 public function setRefClient($user, $ref_client, $notrigger = 0)
1557 {
1558 // phpcs:enable
1559 if ($user->hasRight('ficheinter', 'creer')) {
1560 $error = 0;
1561
1562 $this->db->begin();
1563
1564 $this->oldcopy = dol_clone($this, 2);
1565
1566 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET ref_client = ".(empty($ref_client) ? 'NULL' : "'".$this->db->escape($ref_client)."'");
1567 $sql .= " WHERE rowid = ".((int) $this->id);
1568
1569 dol_syslog(__METHOD__.' $this->id='.$this->id.', ref_client='.$ref_client, LOG_DEBUG);
1570 $resql = $this->db->query($sql);
1571 if (!$resql) {
1572 $this->errors[] = $this->db->error();
1573 $error++;
1574 }
1575
1576 if (!$error) {
1577 $this->ref_client = $ref_client;
1578 }
1579
1580 if (!$notrigger && empty($error)) {
1581 // Call trigger
1582 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
1583 if ($result < 0) {
1584 $error++;
1585 }
1586 // End call triggers
1587 }
1588
1589 if (!$error) {
1590 $this->db->commit();
1591 return 1;
1592 } else {
1593 foreach ($this->errors as $errmsg) {
1594 dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
1595 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1596 }
1597 $this->db->rollback();
1598 return -1 * $error;
1599 }
1600 } else {
1601 return -1;
1602 }
1603 }
1604
1612 public function getKanbanView($option = '', $arraydata = null)
1613 {
1614 global $langs;
1615
1616 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1617
1618 $return = '<div class="box-flex-item box-flex-grow-zero">';
1619 $return .= '<div class="info-box info-box-sm">';
1620 $return .= '<span class="info-box-icon bg-infobox-action">';
1621 $return .= img_picto('', $this->picto);
1622 $return .= '</span>';
1623 $return .= '<div class="info-box-content">';
1624 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
1625 if ($selected >= 0) {
1626 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1627 }
1628 if (!empty($arraydata['thirdparty'])) {
1629 $tmpthirdparty = $arraydata['thirdparty'];
1630 $return .= '<br><span class="info-box-label">'.$tmpthirdparty->getNomUrl(1).'</span>';
1631 }
1632 if (property_exists($this, 'duration')) {
1633 $return .= '<br><span class="info-box-label ">'.$langs->trans("Duration").' : '.convertSecondToTime($this->duration, 'allhourmin').'</span>';
1634 }
1635 if (method_exists($this, 'getLibStatut')) {
1636 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1637 }
1638 $return .= '</div>';
1639 $return .= '</div>';
1640 $return .= '</div>';
1641 return $return;
1642 }
1643
1653 public function setSignedStatus(User $user, int $status = 0, int $notrigger = 0, $triggercode = ''): int
1654 {
1655 return $this->setSignedStatusCommon($user, $status, $notrigger, $triggercode);
1656 }
1657}
1658
1663{
1667 public $db;
1668
1672 public $error = '';
1673
1674 // From llx_fichinterdet
1678 public $fk_fichinter;
1679
1680 public $desc; // Description ligne
1681
1685 public $date; // Date intervention
1690 public $datei; // Date intervention
1691
1692 public $duration; // Duration of intervention
1693 public $rang = 0;
1694 public $tva_tx;
1695
1700 public $subprice;
1701
1705 public $element = 'fichinterdet';
1706
1710 public $table_element = 'fichinterdet';
1711
1715 public $fk_element = 'fk_fichinter';
1716
1717
1718
1724 public function __construct($db)
1725 {
1726 $this->db = $db;
1727 }
1728
1735 public function fetch($rowid)
1736 {
1737 dol_syslog("FichinterLigne::fetch", LOG_DEBUG);
1738
1739 $sql = 'SELECT ft.rowid, ft.fk_fichinter, ft.description, ft.duree, ft.rang, ft.date';
1740 $sql .= ' FROM '.MAIN_DB_PREFIX.'fichinterdet as ft';
1741 $sql .= ' WHERE ft.rowid = '.((int) $rowid);
1742
1743 $resql = $this->db->query($sql);
1744 if ($resql) {
1745 $objp = $this->db->fetch_object($resql);
1746 $this->rowid = $objp->rowid;
1747 $this->id = $objp->rowid;
1748 $this->fk_fichinter = $objp->fk_fichinter;
1749 $this->date = $this->db->jdate($objp->date);
1750 $this->datei = $this->db->jdate($objp->date); // For backward compatibility
1751 $this->desc = $objp->description;
1752 $this->duration = $objp->duree;
1753 $this->rang = $objp->rang;
1754
1755 $this->db->free($resql);
1756
1757 $this->fetch_optionals();
1758
1759 return 1;
1760 } else {
1761 $this->error = $this->db->error().' sql='.$sql;
1762 return -1;
1763 }
1764 }
1765
1773 public function insert($user, $notrigger = 0)
1774 {
1775 $error = 0;
1776
1777 dol_syslog("FichinterLigne::insert rang=".$this->rang);
1778
1779 if (empty($this->date) && !empty($this->datei)) { // For backward compatibility
1780 $this->date = $this->datei;
1781 }
1782
1783 $this->db->begin();
1784
1785 $rangToUse = $this->rang;
1786 if ($rangToUse == -1) {
1787 // Recupere rang max de la ligne d'intervention dans $rangmax
1788 $sql = 'SELECT max(rang) as max FROM '.MAIN_DB_PREFIX.'fichinterdet';
1789 $sql .= ' WHERE fk_fichinter = '.((int) $this->fk_fichinter);
1790 $resql = $this->db->query($sql);
1791 if ($resql) {
1792 $obj = $this->db->fetch_object($resql);
1793 $rangToUse = $obj->max + 1;
1794 } else {
1795 dol_print_error($this->db);
1796 $this->db->rollback();
1797 return -1;
1798 }
1799 }
1800
1801 // Insertion dans base de la ligne
1802 $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'fichinterdet';
1803 $sql .= ' (fk_fichinter, description, date, duree, rang)';
1804 $sql .= " VALUES (".((int) $this->fk_fichinter).",";
1805 $sql .= " '".$this->db->escape($this->desc)."',";
1806 $sql .= " '".$this->db->idate($this->date)."',";
1807 $sql .= " ".((int) $this->duration).",";
1808 $sql .= ' '.((int) $rangToUse);
1809 $sql .= ')';
1810
1811 dol_syslog("FichinterLigne::insert", LOG_DEBUG);
1812 $resql = $this->db->query($sql);
1813 if ($resql) {
1814 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'fichinterdet');
1815 $this->rowid = $this->id;
1816
1817 if (!$error) {
1818 $result = $this->insertExtraFields();
1819 if ($result < 0) {
1820 $error++;
1821 }
1822 }
1823
1824
1825 $result = $this->update_total();
1826
1827 if ($result > 0) {
1828 $this->rang = $rangToUse;
1829
1830 if (!$notrigger) {
1831 // Call trigger
1832 $result = $this->call_trigger('LINEFICHINTER_CREATE', $user);
1833 if ($result < 0) {
1834 $error++;
1835 }
1836 // End call triggers
1837 }
1838 }
1839
1840 if (!$error) {
1841 $this->db->commit();
1842 return $result;
1843 } else {
1844 $this->db->rollback();
1845 return -1;
1846 }
1847 } else {
1848 $this->error = $this->db->error()." sql=".$sql;
1849 $this->db->rollback();
1850 return -1;
1851 }
1852 }
1853
1854
1862 public function update($user, $notrigger = 0)
1863 {
1864 $error = 0;
1865
1866 if (empty($this->date) && !empty($this->datei)) { // For backward compatibility
1867 $this->date = $this->datei;
1868 }
1869
1870 $this->db->begin();
1871
1872 // Mise a jour ligne en base
1873 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinterdet SET";
1874 $sql .= " description = '".$this->db->escape($this->desc)."',";
1875 $sql .= " date = '".$this->db->idate($this->date)."',";
1876 $sql .= " duree = ".((int) $this->duration).",";
1877 $sql .= " rang = ".((int) $this->rang);
1878 $sql .= " WHERE rowid = ".((int) $this->id);
1879
1880 dol_syslog("FichinterLigne::update", LOG_DEBUG);
1881 $resql = $this->db->query($sql);
1882 if ($resql) {
1883 if (!$error) {
1884 $result = $this->insertExtraFields();
1885 if ($result < 0) {
1886 $error++;
1887 }
1888 }
1889
1890 $result = $this->update_total();
1891 if ($result > 0) {
1892 if (!$notrigger) {
1893 // Call trigger
1894 $result = $this->call_trigger('LINEFICHINTER_MODIFY', $user);
1895 if ($result < 0) {
1896 $error++;
1897 }
1898 // End call triggers
1899 }
1900 }
1901
1902 if (!$error) {
1903 $this->db->commit();
1904 return $result;
1905 } else {
1906 $this->error = $this->db->lasterror();
1907 $this->db->rollback();
1908 return -1;
1909 }
1910 } else {
1911 $this->error = $this->db->lasterror();
1912 $this->db->rollback();
1913 return -1;
1914 }
1915 }
1916
1917 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1923 public function update_total()
1924 {
1925 // phpcs:enable
1926 global $conf;
1927
1928 $this->db->begin();
1929
1930 $sql = "SELECT SUM(duree) as total_duration, min(date) as dateo, max(date) as datee ";
1931 $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet";
1932 $sql .= " WHERE fk_fichinter=".((int) $this->fk_fichinter);
1933
1934 dol_syslog("FichinterLigne::update_total", LOG_DEBUG);
1935 $resql = $this->db->query($sql);
1936 if ($resql) {
1937 $obj = $this->db->fetch_object($resql);
1938 $total_duration = 0;
1939 if (!empty($obj->total_duration)) {
1940 $total_duration = $obj->total_duration;
1941 }
1942
1943 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
1944 $sql .= " SET duree = ".((int) $total_duration);
1945 $sql .= " , dateo = ".(!empty($obj->dateo) ? "'".$this->db->escape($obj->dateo)."'" : "null");
1946 $sql .= " , datee = ".(!empty($obj->datee) ? "'".$this->db->escape($obj->datee)."'" : "null");
1947 $sql .= " WHERE rowid = ".((int) $this->fk_fichinter);
1948
1949 dol_syslog("FichinterLigne::update_total", LOG_DEBUG);
1950 $resql = $this->db->query($sql);
1951 if ($resql) {
1952 $this->db->commit();
1953 return 1;
1954 } else {
1955 $this->error = $this->db->error();
1956 $this->db->rollback();
1957 return -2;
1958 }
1959 } else {
1960 $this->error = $this->db->error();
1961 $this->db->rollback();
1962 return -1;
1963 }
1964 }
1965
1973 public function deleteLine($user, $notrigger = 0)
1974 {
1975 $error = 0;
1976
1977 dol_syslog(get_class($this)."::deleteline lineid=".$this->id);
1978
1979 $this->db->begin();
1980
1981 $result = $this->deleteExtraFields();
1982 if ($result < 0) {
1983 $error++;
1984 $this->db->rollback();
1985 return -1;
1986 }
1987
1988 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet WHERE rowid = ".((int) $this->id);
1989 $resql = $this->db->query($sql);
1990
1991 if ($resql) {
1992 $result = $this->update_total();
1993 if ($result > 0) {
1994 if (!$notrigger) {
1995 // Call trigger
1996 $result = $this->call_trigger('LINEFICHINTER_DELETE', $user);
1997 if ($result < 0) {
1998 $error++;
1999 $this->db->rollback();
2000 return -1;
2001 }
2002 // End call triggers
2003 }
2004
2005 $this->db->commit();
2006 return $result;
2007 } else {
2008 $this->db->rollback();
2009 return -1;
2010 }
2011 } else {
2012 $this->error = $this->db->error()." sql=".$sql;
2013 $this->db->rollback();
2014 return -1;
2015 }
2016 }
2017}
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:626
$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:1929
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:1929