dolibarr 23.0.4
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-2025 Charlene Benke <charlene@patas-monkey.com>
8 * Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
9 * Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
10 * Copyright (C) 2023-2024 William Mead <william.mead@manchenumerique.fr>
11 * Copyright (C) 2024-2025 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.'/fichinter/class/fichinterligne.class.php';
34require_once DOL_DOCUMENT_ROOT.'/core/class/commonsignedobject.class.php';
35require_once DOL_DOCUMENT_ROOT.'/subtotals/class/commonsubtotal.class.php';
36
37
44{
45 use CommonSignedObject, CommonSubtotal;
46
51 public $TRIGGER_PREFIX = 'FICHINTER';
52
53 public $fields = array(
54 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
55 'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 'isModEnabled("societe")', 'visible' => -1, 'notnull' => 1, 'position' => 15),
56 'fk_projet' => array('type' => 'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label' => 'Project', 'enabled' => 'isModEnabled("project")', 'visible' => -1, 'position' => 20),
57 'fk_contrat' => array('type' => 'integer:Contrat:contrat/class/contrat.class.php', 'label' => 'Contract', 'enabled' => 'isModEnabled("contract")', 'visible' => -1, 'position' => 25),
58 'ref' => array('type' => 'varchar(30)', 'label' => 'Ref', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'showoncombobox' => 1, 'position' => 30),
59 'ref_ext' => array('type' => 'varchar(255)', 'label' => 'RefExt', 'enabled' => 1, 'visible' => 0, 'position' => 35),
60 'ref_client' => array('type' => 'varchar(255)', 'label' => 'RefCustomer', 'enabled' => 1, 'visible' => -1, 'position' => 36),
61 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 40, 'index' => 1),
62 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 45),
63 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 50),
64 'date_valid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 55),
65 'datei' => array('type' => 'date', 'label' => 'Datei', 'enabled' => 1, 'visible' => -1, 'position' => 60),
66 'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => -1, 'position' => 65),
67 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 70),
68 'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => -1, 'position' => 75),
69 'dateo' => array('type' => 'date', 'label' => 'Dateo', 'enabled' => 1, 'visible' => -1, 'position' => 85),
70 'datee' => array('type' => 'date', 'label' => 'Datee', 'enabled' => 1, 'visible' => -1, 'position' => 90),
71 'datet' => array('type' => 'date', 'label' => 'Datet', 'enabled' => 1, 'visible' => -1, 'position' => 95),
72 'duree' => array('type' => 'integer', 'label' => 'Duree', 'enabled' => 1, 'visible' => -1, 'position' => 100),
73 'signed_status' => array('type' => 'smallint(6)', 'label' => 'SignedStatus', 'enabled' => 1, 'visible' => -1, 'position' => 101, 'arrayofkeyval' => array(0 => 'NoSignature', 1 => 'SignedSender', 2 => 'SignedReceiver', 3 => 'SignedReceiverOnline', 9 => 'SignedAll')),
74 'description' => array('type' => 'html', 'label' => 'Description', 'enabled' => 1, 'visible' => -1, 'position' => 105, 'showoncombobox' => 2),
75 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 110),
76 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 115),
77 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'PDFTemplate', 'enabled' => 1, 'visible' => 0, 'position' => 120),
78 'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'LastMainDoc', 'enabled' => 1, 'visible' => -1, 'position' => 125),
79 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 130),
80 'extraparams' => array('type' => 'varchar(255)', 'label' => 'Extraparams', 'enabled' => 1, 'visible' => -1, 'position' => 135),
81 'fk_statut' => array('type' => 'integer', 'label' => 'Status', 'enabled' => 1, 'visible' => -1, 'position' => 500),
82 );
83
87 public $element = 'fichinter';
88
92 public $fk_element = 'fk_fichinter';
93
97 public $table_element = 'fichinter';
98
102 public $table_element_line = 'fichinterdet';
103
107 public $class_element_line = 'FichinterLigne';
108
112 public $picto = 'intervention';
113
117 protected $table_ref_field = 'ref';
118
122 public $socid;
123
127 public $author;
128
132 public $datec;
133
137 public $datev;
141 public $dateo;
145 public $datee;
146
150 public $datet;
151
157 public $datem;
158
162 public $duration;
163
168 public $statut = 0; // 0=draft, 1=validated, 2=invoiced, 3=Terminate
169
173 public $status = 0; // 0=draft, 1=validated, 2=invoiced, 3=Terminate
174
178 public $description;
179
183 public $fk_contrat = 0;
184
188 public $fk_project;
189
194 public $ref_client;
195
199 public $extraparams = array();
200
204 public $lines = array();
205
209 const STATUS_DRAFT = 0;
210
215
219 const STATUS_BILLED = 2;
220
224 const STATUS_CLOSED = 3;
225
231 public $date_delivery;
232
237 public $delivery_date_receipt;
238
243 public $user_author_id;
244
245
251 public function __construct($db)
252 {
253 $this->db = $db;
254 }
255
261 public function loadStateBoard()
262 {
263 global $user;
264
265 $this->nb = array();
266 $clause = "WHERE";
267
268 $sql = "SELECT count(fi.rowid) as nb";
269 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as fi";
270 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON fi.fk_soc = s.rowid";
271 if (!$user->hasRight('societe', 'client', 'voir')) {
272 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
273 $sql .= " WHERE sc.fk_user = ".((int) $user->id);
274 $clause = "AND";
275 }
276 $sql .= " ".$clause." fi.entity IN (".getEntity('intervention').")";
277
278 $resql = $this->db->query($sql);
279 if ($resql) {
280 while ($obj = $this->db->fetch_object($resql)) {
281 $this->nb["interventions"] = $obj->nb;
282 }
283 $this->db->free($resql);
284 return 1;
285 } else {
286 dol_print_error($this->db);
287 $this->error = $this->db->error();
288 return -1;
289 }
290 }
291
299 public function create($user, $notrigger = 0)
300 {
301 $error = 0;
302
303 dol_syslog(get_class($this)."::create ref=".$this->ref);
304
305 // Check parameters
306 if (!empty($this->ref)) { // We check that ref is not already used
307 $result = self::isExistingObject($this->element, 0, $this->ref); // Check ref is not yet used
308 if ($result > 0) {
309 $this->error = 'ErrorRefAlreadyExists';
310 dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING);
311 $this->db->rollback();
312 return -1;
313 }
314 }
315 if (!is_numeric($this->duration)) {
316 $this->duration = 0;
317 }
318 if (!empty($this->ref_client)) {
319 $this->ref_client = trim($this->ref_client);
320 }
321
322 if ($this->socid <= 0) {
323 $this->error = 'ErrorFicheinterCompanyDoesNotExist';
324 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
325 return -1;
326 }
327 $this->entity = setEntity($this);
328
329 $soc = new Societe($this->db);
330 $result = $soc->fetch($this->socid);
331
332 $now = dol_now();
333
334 $this->db->begin();
335
336 $sql = "INSERT INTO ".MAIN_DB_PREFIX."fichinter (";
337 $sql .= "fk_soc";
338 $sql .= ", datec";
339 $sql .= ", ref";
340 $sql .= ", ref_client";
341 $sql .= ", entity";
342 $sql .= ", fk_user_author";
343 $sql .= ", fk_user_modif";
344 $sql .= ", description";
345 $sql .= ", model_pdf";
346 $sql .= ", fk_projet";
347 $sql .= ", fk_contrat";
348 $sql .= ", fk_statut";
349 $sql .= ", signed_status";
350 $sql .= ", note_private";
351 $sql .= ", note_public";
352 $sql .= ") ";
353 $sql .= " VALUES (";
354 $sql .= $this->socid;
355 $sql .= ", '".$this->db->idate($now)."'";
356 $sql .= ", '".$this->db->escape($this->ref)."'";
357 $sql .= ", ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
358 $sql .= ", ".((int) $this->entity);
359 $sql .= ", ".((int) $user->id);
360 $sql .= ", ".((int) $user->id);
361 $sql .= ", ".($this->description ? "'".$this->db->escape($this->description)."'" : "null");
362 $sql .= ", '".$this->db->escape($this->model_pdf)."'";
363 $sql .= ", ".((int) $this->fk_project > 0 ? ((int) $this->fk_project) : 0);
364 $sql .= ", ".((int) $this->fk_contrat > 0 ? ((int) $this->fk_contrat) : 0);
365 $sql .= ", ".((int) $this->status);
366 $sql .= ", ".((int) $this->signed_status);
367 $sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
368 $sql .= ", ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
369 $sql .= ")";
370
371 dol_syslog(get_class($this)."::create", LOG_DEBUG);
372 $result = $this->db->query($sql);
373 if ($result) {
374 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."fichinter");
375
376 if ($this->id) {
377 $this->ref = '(PROV'.$this->id.')';
378 $sql = 'UPDATE '.MAIN_DB_PREFIX."fichinter SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".((int) $this->id);
379
380 dol_syslog(get_class($this)."::create", LOG_DEBUG);
381 $resql = $this->db->query($sql);
382 if (!$resql) {
383 $error++;
384 }
385 }
386
387 if (!$error) {
388 $result = $this->insertExtraFields();
389 if ($result < 0) {
390 $error++;
391 }
392 }
393
394 // Add linked object
395 if (!$error && $this->origin && $this->origin_id) {
396 $ret = $this->add_object_linked();
397 if (!$ret) {
398 dol_print_error($this->db);
399 }
400 }
401
402
403 if (!$error && !$notrigger) {
404 // Call trigger
405 $result = $this->call_trigger('FICHINTER_CREATE', $user);
406 if ($result < 0) {
407 $error++;
408 }
409 // End call triggers
410 }
411
412 if (!$error) {
413 $this->db->commit();
414 return $this->id;
415 } else {
416 $this->db->rollback();
417 $this->error = implode(',', $this->errors);
418 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
419 return -1;
420 }
421 } else {
422 $this->error = $this->db->error();
423 $this->db->rollback();
424 return -1;
425 }
426 }
427
435 public function update($user, $notrigger = 0)
436 {
437 global $conf;
438
439 if (!is_numeric($this->duration)) {
440 $this->duration = 0;
441 }
442 if (!dol_strlen((string) $this->fk_project)) {
443 $this->fk_project = 0;
444 }
445 if (!empty($this->ref_client)) {
446 $this->ref_client = trim($this->ref_client);
447 }
448
449 $error = 0;
450
451 $this->db->begin();
452
453 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter SET ";
454 $sql .= "description = '".$this->db->escape($this->description)."'";
455 $sql .= ", duree = ".((int) $this->duration);
456 $sql .= ", ref_client = ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
457 if ((int) $this->fk_project > 0) {
458 $sql .= ", fk_projet = ".((int) $this->fk_project);
459 }
460 if (isset($this->datec)) {
461 $sql .= ", datec = ".($this->datec ? "'".$this->db->idate($this->datec)."'" : "null");
462 }
463 if (isset($this->datev)) {
464 $sql .= ", date_valid = ".($this->datev ? "'".$this->db->idate($this->datev)."'" : "null");
465 }
466 if (isset($this->datet)) {
467 $sql .= ", datet = ".($this->datet ? "'".$this->db->idate($this->datet)."'" : "null");
468 }
469 $sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
470 $sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
471 $sql .= ", fk_user_modif = ".((int) $user->id);
472 $sql .= " WHERE rowid = ".((int) $this->id);
473
474 dol_syslog(get_class($this)."::update", LOG_DEBUG);
475 if ($this->db->query($sql)) {
476 $result = $this->insertExtraFields();
477 if ($result < 0) {
478 $error++;
479 }
480
481 if (!$error && !$notrigger) {
482 // Call trigger
483 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
484 if ($result < 0) {
485 $error++;
486 $this->db->rollback();
487 return -1;
488 }
489 // End call triggers
490 }
491
492 $this->db->commit();
493 return 1;
494 } else {
495 $this->error = $this->db->error();
496 $this->db->rollback();
497 return -1;
498 }
499 }
500
509 public function fetch($rowid, $ref = '', $ref_ext = '')
510 {
511 $sql = "SELECT f.rowid, f.ref, f.ref_client, f.description, f.fk_soc, f.fk_statut as status, f.signed_status,";
512 $sql .= " f.datec, f.dateo, f.datee, f.datet, f.fk_user_author,";
513 $sql .= " f.date_valid as datev,";
514 $sql .= " f.tms as datem,";
515 $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";
516 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
517 $sql .= " WHERE f.entity IN (".getEntity('intervention').")";
518 if ($ref) {
519 $sql .= " AND f.ref = '".$this->db->escape($ref)."'";
520 } elseif ($ref_ext) {
521 $sql .= " AND f.ref_ext = '".$this->db->escape($ref_ext)."'";
522 } else {
523 $sql .= " AND f.rowid = ".((int) $rowid);
524 }
525
526 $resql = $this->db->query($sql);
527 if ($resql) {
528 if ($this->db->num_rows($resql)) {
529 $obj = $this->db->fetch_object($resql);
530
531 $this->id = $obj->rowid;
532 $this->ref = $obj->ref;
533 $this->ref_client = $obj->ref_client;
534 $this->description = $obj->description;
535 $this->socid = $obj->fk_soc;
536 $this->status = $obj->status;
537 $this->statut = $obj->status; // deprecated
538 $this->signed_status = $obj->signed_status;
539 $this->duration = $obj->duree;
540 $this->datec = $this->db->jdate($obj->datec);
541 $this->dateo = $this->db->jdate($obj->dateo);
542 $this->datee = $this->db->jdate($obj->datee);
543 $this->datet = $this->db->jdate($obj->datet);
544 $this->datev = $this->db->jdate($obj->datev);
545 $this->datem = $this->db->jdate($obj->datem);
546 $this->fk_project = $obj->fk_project;
547 $this->note_public = $obj->note_public;
548 $this->note_private = $obj->note_private;
549 $this->model_pdf = $obj->model_pdf;
550 $this->fk_contrat = $obj->fk_contrat;
551 $this->entity = $obj->entity;
552
553 $this->user_creation_id = $obj->fk_user_author;
554
555 $this->extraparams = is_null($obj->extraparams) ? [] : (array) json_decode($obj->extraparams, true);
556
557 $this->last_main_doc = $obj->last_main_doc;
558
559 // Retrieve extrafields
560 $this->fetch_optionals();
561
562 /*
563 * Lines
564 */
565 $result = $this->fetch_lines();
566 if ($result < 0) {
567 return -3;
568 }
569 $this->db->free($resql);
570 return 1;
571 }
572
573 return 0;
574 } else {
575 $this->error = $this->db->lasterror();
576 return -1;
577 }
578 }
579
586 public function setDraft($user)
587 {
588 $error = 0;
589
590 // Protection
591 if ($this->status <= self::STATUS_DRAFT) {
592 return 0;
593 }
594
595 dol_syslog(get_class($this)."::setDraft", LOG_DEBUG);
596
597 $this->oldcopy = dol_clone($this, 2);
598
599 $this->db->begin();
600
601 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
602 $sql .= " SET fk_statut = ".self::STATUS_DRAFT;
603 $sql .= " WHERE rowid = ".((int) $this->id);
604
605 $resql = $this->db->query($sql);
606 if ($resql) {
607 // Call trigger
608 $result = $this->call_trigger('FICHINTER_UNVALIDATE', $user);
609 if ($result < 0) {
610 $error++;
611 }
612
613 if (!$error) {
614 $this->status = self::STATUS_DRAFT;
615 $this->statut = self::STATUS_DRAFT; // deprecated
616 $this->db->commit();
617 return 1;
618 } else {
619 $this->db->rollback();
620 return -1;
621 }
622 } else {
623 $this->db->rollback();
624 $this->error = $this->db->lasterror();
625 return -1;
626 }
627 }
628
636 public function setValid($user, $notrigger = 0)
637 {
638 global $conf;
639 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
640
641 $error = 0;
642
643 if ($this->status != self::STATUS_VALIDATED) {
644 $this->db->begin();
645
646 $now = dol_now();
647
648 // Define new ref
649 if ((preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
650 if (empty($this->thirdparty)) { // Not loaded when validated by the API or on closing a ticket
651 $this->fetch_thirdparty();
652 }
653 $num = $this->getNextNumRef($this->thirdparty);
654 } else {
655 $num = (string) $this->ref;
656 }
657 $this->newref = dol_sanitizeFileName($num);
658
659 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
660 $sql .= " SET fk_statut = 1";
661 $sql .= ", ref = '".$this->db->escape($num)."'";
662 $sql .= ", date_valid = '".$this->db->idate($now)."'";
663 $sql .= ", fk_user_valid = ".($user->id > 0 ? (int) $user->id : "null");
664 $sql .= " WHERE rowid = ".((int) $this->id);
665 $sql .= " AND entity IN (".getEntity('intervention').")";
666
667 $sql .= " AND fk_statut = 0";
668
669 dol_syslog(get_class($this)."::setValid", LOG_DEBUG);
670 $resql = $this->db->query($sql);
671 if (!$resql) {
672 dol_print_error($this->db);
673 $error++;
674 }
675
676 if (!$error && !$notrigger) {
677 // Call trigger
678 $result = $this->call_trigger('FICHINTER_VALIDATE', $user);
679 if ($result < 0) {
680 $error++;
681 }
682 // End call triggers
683 }
684
685 if (!$error) {
686 $this->oldref = $this->ref;
687
688 // Rename directory if dir was a temporary ref
689 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
690 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
691
692 // Now we rename also files into index
693 $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)."'";
694 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".((int) $this->entity);
695 $resql = $this->db->query($sql);
696 if (!$resql) {
697 $error++;
698 $this->error = $this->db->lasterror();
699 }
700 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'ficheinter/".$this->db->escape($this->newref)."'";
701 $sql .= " WHERE filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
702 $resql = $this->db->query($sql);
703 if (!$resql) {
704 $error++;
705 $this->error = $this->db->lasterror();
706 }
707
708 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
709 $oldref = dol_sanitizeFileName($this->ref);
710 $newref = dol_sanitizeFileName($num);
711 $dirsource = $conf->ficheinter->dir_output.'/'.$oldref;
712 $dirdest = $conf->ficheinter->dir_output.'/'.$newref;
713 if (!$error && file_exists($dirsource)) {
714 dol_syslog(get_class($this)."::setValid rename dir ".$dirsource." into ".$dirdest);
715
716 if (@rename($dirsource, $dirdest)) {
717 dol_syslog("Rename ok");
718 // Rename docs starting with $oldref with $newref
719 $listoffiles = dol_dir_list($conf->ficheinter->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
720 foreach ($listoffiles as $fileentry) {
721 $dirsource = $fileentry['name'];
722 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
723 $dirsource = $fileentry['path'].'/'.$dirsource;
724 $dirdest = $fileentry['path'].'/'.$dirdest;
725 @rename($dirsource, $dirdest);
726 }
727 }
728 }
729 }
730 }
731
732 // Set new ref and define current status
733 if (!$error) {
734 $this->ref = $num;
736 $this->statut = self::STATUS_VALIDATED; // deprecated
737 $this->date_validation = $now;
738 $this->db->commit();
739 return 1;
740 } else {
741 $this->db->rollback();
742 dol_syslog(get_class($this)."::setValid ".$this->error, LOG_ERR);
743 return -1;
744 }
745 }
746
747 return 0;
748 }
749
757 public function setClose($user, $notrigger = 0)
758 {
759 global $conf;
760
761 $error = 0;
762
763 if ($this->status == self::STATUS_CLOSED) {
764 return 0;
765 } else {
766 $this->db->begin();
767
768 $now = dol_now();
769
770 $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element;
771 $sql .= ' SET fk_statut = ' . self::STATUS_CLOSED . ',';
772 $sql .= " datet = '" . $this->db->idate($now) . "',";
773 $sql .= " fk_user_modif = " . ((int) $user->id);
774 $sql .= " WHERE rowid = " . ((int) $this->id);
775 $sql .= " AND fk_statut > " . self::STATUS_DRAFT;
776 $sql .= " AND entity IN (".getEntity('intervention').")";
777
778 if ($this->db->query($sql)) {
779 if (!$notrigger) {
780 // Call trigger
781 $result = $this->call_trigger('FICHINTER_CLOSE', $user);
782 if ($result < 0) {
783 $error++;
784 }
785 // End call triggers
786 }
787
788 if (!$error) {
790 $this->statut = self::STATUS_CLOSED; // deprecated
791 $this->db->commit();
792 return 1;
793 } else {
794 $this->db->rollback();
795 return -1;
796 }
797 } else {
798 $this->error = $this->db->lasterror();
799 $this->db->rollback();
800 return -1;
801 }
802 }
803 }
804
810 public function getAmount()
811 {
812 $amount = 0;
813
814 $this->author = new User($this->db);
815 $this->author->fetch($this->user_creation_id);
816
817 $thm = $this->author->thm;
818
819 foreach ($this->lines as $line) {
820 $amount += ($line->duration / 60 / 60 * (float) $thm);
821 }
822
823 return (float) price2num($amount, 'MT');
824 }
825
826
838 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
839 {
840 global $conf;
841
842 $outputlangs->load("interventions");
843
844 if (!dol_strlen($modele)) {
845 $modele = 'soleil';
846
847 if (!empty($this->model_pdf)) {
848 $modele = $this->model_pdf;
849 } elseif (getDolGlobalString('FICHEINTER_ADDON_PDF')) {
850 $modele = getDolGlobalString('FICHEINTER_ADDON_PDF');
851 }
852 }
853
854 $modelpath = "core/modules/fichinter/doc/";
855
856 return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
857 }
858
865 public function getLibStatut($mode = 0)
866 {
867 return $this->LibStatut((isset($this->statut) ? $this->statut : $this->status), $mode);
868 }
869
870 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
878 public function LibStatut($status, $mode = 0)
879 {
880 // phpcs:enable
881 global $langs;
882 // Init/load array of translation of status
883 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
884 $langs->load("interventions");
885 $langs->load("propal");
886
887 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
888 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
889 $this->labelStatus[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
890 $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
891 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
892 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
893 $this->labelStatusShort[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
894 $this->labelStatusShort[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
895 }
896
897 $statuscode = 'status'.$status;
898 if ($status == self::STATUS_BILLED || $status == self::STATUS_CLOSED) {
899 $statuscode = 'status6';
900 }
901
902 $signed_label = ' (' . $this->getLibSignedStatus() . ')';
903 $status_label = $this->signed_status ? $this->labelStatus[$status] . $signed_label : $this->labelStatus[$status];
904 $status_label_short = $this->signed_status ? $this->labelStatusShort[$status] . $signed_label : $this->labelStatusShort[$status];
905
906 return dolGetStatus($status_label, $status_label_short, '', $statuscode, $mode);
907 }
908
915 public function getTooltipContentArray($params)
916 {
917 global $langs;
918
919 $langs->load('interventions');
920
921 $datas = [];
922 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("ShowIntervention").'</u>';
923 $datas['picto'] .= ' '.$this->getLibStatut(5);
924 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
925
926 return $datas;
927 }
928
939 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $save_lastsearch_value = -1, $morecss = '')
940 {
941 global $conf, $langs, $hookmanager;
942
943 if (!empty($conf->dol_no_mouse_hover)) {
944 $notooltip = 1; // Force disable tooltips
945 }
946
947 $result = '';
948 $params = [
949 'id' => $this->id,
950 'objecttype' => $this->element,
951 'option' => $option,
952 ];
953 $classfortooltip = 'classfortooltip';
954 $dataparams = '';
955 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
956 $classfortooltip = 'classforajaxtooltip';
957 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
958 $label = '';
959 } else {
960 $label = implode($this->getTooltipContentArray($params));
961 }
962
963 $url = DOL_URL_ROOT.'/fichinter/card.php?id='.$this->id;
964
965 if ($option !== 'nolink') {
966 // Add param to save lastsearch_values or not
967 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
968 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
969 $add_save_lastsearch_values = 1;
970 }
971 if ($add_save_lastsearch_values) {
972 $url .= '&save_lastsearch_values=1';
973 }
974 }
975
976 $linkclose = '';
977 if (empty($notooltip)) {
978 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
979 $label = $langs->trans("ShowIntervention");
980 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
981 }
982 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
983 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
984 } else {
985 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
986 }
987
988 if ($option == 'nolink') {
989 $linkstart = '<span';
990 } else {
991 $linkstart = '<a href="'.$url.'"';
992 }
993 $linkstart .= $linkclose.'>';
994 if ($option == 'nolink') {
995 $linkend = '</span>';
996 } else {
997 $linkend = '</a>';
998 }
999
1000 $result .= $linkstart;
1001 if ($withpicto) {
1002 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1003 }
1004
1005 if ($withpicto != 2) {
1006 $result .= $this->ref;
1007 }
1008
1009 $result .= $linkend;
1010
1011 global $action;
1012 $hookmanager->initHooks(array('interventiondao'));
1013 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1014 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1015 if ($reshook > 0) {
1016 $result = $hookmanager->resPrint;
1017 } else {
1018 $result .= $hookmanager->resPrint;
1019 }
1020
1021 return $result;
1022 }
1023
1024
1032 public function getNextNumRef($soc)
1033 {
1034 global $conf, $db, $langs;
1035 $langs->load("interventions");
1036
1037 if (getDolGlobalString('FICHEINTER_ADDON')) {
1038 $mybool = false;
1039
1040 $file = "mod_" . getDolGlobalString('FICHEINTER_ADDON').".php";
1041 $classname = "mod_" . getDolGlobalString('FICHEINTER_ADDON');
1042
1043 // Include file with class
1044 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1045
1046 foreach ($dirmodels as $reldir) {
1047 $dir = dol_buildpath($reldir."core/modules/fichinter/");
1048
1049 // Load file with numbering class (if found)
1050 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1051 }
1052
1053 if (!$mybool) {
1054 dol_print_error(null, "Failed to include file ".$file);
1055 return '';
1056 }
1057
1058 $obj = new $classname();
1059 '@phan-var-force ModeleNumRefFicheinter $obj';
1060 $numref = "";
1061 $numref = $obj->getNextValue($soc, $this);
1062
1063 if ($numref != "") {
1064 return $numref;
1065 } else {
1066 dol_print_error($db, "Fichinter::getNextNumRef ".$obj->error);
1067 return "";
1068 }
1069 } else {
1070 $langs->load("errors");
1071 print $langs->trans("Error")." ".$langs->trans("Error_FICHEINTER_ADDON_NotDefined");
1072 return "";
1073 }
1074 }
1075
1082 public function info($id)
1083 {
1084 $sql = "SELECT f.rowid,";
1085 $sql .= " f.datec,";
1086 $sql .= " f.tms as date_modification,";
1087 $sql .= " f.date_valid as datev,";
1088 $sql .= " f.fk_user_author,";
1089 $sql .= " f.fk_user_modif as fk_user_modification,";
1090 $sql .= " f.fk_user_valid";
1091 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
1092 $sql .= " WHERE f.rowid = ".((int) $id);
1093
1094 $resql = $this->db->query($sql);
1095 if ($resql) {
1096 if ($this->db->num_rows($resql)) {
1097 $obj = $this->db->fetch_object($resql);
1098
1099 $this->id = $obj->rowid;
1100
1101 $this->date_creation = $this->db->jdate($obj->datec);
1102 $this->date_modification = $this->db->jdate($obj->date_modification);
1103 $this->date_validation = $this->db->jdate($obj->datev);
1104
1105 $this->user_creation_id = $obj->fk_user_author;
1106 $this->user_validation_id = $obj->fk_user_valid;
1107 $this->user_modification_id = $obj->fk_user_modification;
1108 }
1109 $this->db->free($resql);
1110 } else {
1111 dol_print_error($this->db);
1112 }
1113 }
1114
1122 public function delete(User $user, $notrigger = 0)
1123 {
1124 global $conf, $langs;
1125 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1126
1127 $error = 0;
1128
1129 $this->db->begin();
1130
1131 if (!$notrigger) {
1132 // Call trigger
1133 $result = $this->call_trigger('FICHINTER_DELETE', $user);
1134 if ($result < 0) {
1135 $error++;
1136 $this->db->rollback();
1137 return -1;
1138 }
1139 // End call triggers
1140 }
1141
1142 // Delete linked object
1143 $res = $this->deleteObjectLinked();
1144 if ($res < 0) {
1145 $error++;
1146 }
1147
1148 // Delete linked contacts
1149 if (!$error) {
1150 $res = $this->delete_linked_contact();
1151 if ($res < 0) {
1152 $this->error = 'ErrorFailToDeleteLinkedContact';
1153 $error++;
1154 }
1155 }
1156
1157 if (!$error) {
1158 $main = MAIN_DB_PREFIX.'fichinterdet';
1159 $ef = $main."_extrafields";
1160 $sql = "DELETE FROM ".$this->db->sanitize($ef)." WHERE fk_object IN (SELECT rowid FROM ".$this->db->sanitize($main)." WHERE fk_fichinter = ".((int) $this->id).")";
1161
1162 $resql = $this->db->query($sql);
1163 if (!$resql) {
1164 $error++;
1165 }
1166 }
1167
1168 if (!$error) {
1169 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet";
1170 $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1171
1172 $resql = $this->db->query($sql);
1173 if (!$resql) {
1174 $error++;
1175 }
1176 }
1177
1178 if (!$error) {
1179 // Remove extrafields
1180 $res = $this->deleteExtraFields();
1181 if ($res < 0) {
1182 $error++;
1183 }
1184 }
1185
1186 if (!$error) {
1187 // Delete object
1188 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinter";
1189 $sql .= " WHERE rowid = ".((int) $this->id);
1190
1191 dol_syslog("Fichinter::delete", LOG_DEBUG);
1192 $resql = $this->db->query($sql);
1193 if (!$resql) {
1194 $error++;
1195 }
1196 }
1197
1198 if (!$error) {
1199 // Delete record into ECM index (Note that delete is also done when deleting files with the dol_delete_dir_recursive
1200 $this->deleteEcmFiles(0); // Deleting files physically is done later with the dol_delete_dir_recursive
1201 $this->deleteEcmFiles(1); // Deleting files physically is done later with the dol_delete_dir_recursive
1202
1203 // Remove directory with files
1204 $fichinterref = dol_sanitizeFileName($this->ref);
1205 if ($conf->ficheinter->dir_output && !empty($fichinterref)) {
1206 $dir = $conf->ficheinter->dir_output."/".$fichinterref;
1207 $file = $conf->ficheinter->dir_output."/".$fichinterref."/".$fichinterref.".pdf";
1208 if (file_exists($file)) {
1209 dol_delete_preview($this);
1210
1211 if (!dol_delete_file($file, 0, 0, 0, $this)) { // For triggers
1212 $langs->load("errors");
1213 $this->error = $langs->trans("ErrorFailToDeleteFile", $file);
1214 return 0;
1215 }
1216 }
1217 if (file_exists($dir)) {
1218 if (!dol_delete_dir_recursive($dir)) {
1219 $langs->load("errors");
1220 $this->error = $langs->trans("ErrorFailToDeleteDir", $dir);
1221 return 0;
1222 }
1223 }
1224 }
1225 }
1226
1227 if (!$error) {
1228 $this->db->commit();
1229 return 1;
1230 } else {
1231 $this->db->rollback();
1232 return -1;
1233 }
1234 }
1235
1236 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1244 public function set_date_delivery($user, $delivery_date_receipt)
1245 {
1246 // phpcs:enable
1247 if ($user->hasRight('ficheinter', 'creer')) {
1248 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
1249 $sql .= " SET datei = '".$this->db->idate($delivery_date_receipt)."'";
1250 $sql .= " WHERE rowid = ".((int) $this->id);
1251 $sql .= " AND fk_statut = 0";
1252
1253 if ($this->db->query($sql)) {
1254 $this->date_delivery = $delivery_date_receipt;
1255 $this->delivery_date_receipt = $delivery_date_receipt;
1256 return 1;
1257 } else {
1258 $this->error = $this->db->error();
1259 dol_syslog("Fichinter::set_date_delivery Erreur SQL");
1260 return -1;
1261 }
1262 }
1263
1264 return 0;
1265 }
1266
1267 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1275 public function set_description($user, $description)
1276 {
1277 // phpcs:enable
1278 if ($user->hasRight('ficheinter', 'creer')) {
1279 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1280 $sql .= " SET description = '".$this->db->escape($description)."',";
1281 $sql .= " fk_user_modif = ".((int) $user->id);
1282 $sql .= " WHERE rowid = ".((int) $this->id);
1283
1284 if ($this->db->query($sql)) {
1285 $this->description = $description;
1286 return 1;
1287 } else {
1288 $this->error = $this->db->error();
1289 dol_syslog("Fichinter::set_description Erreur SQL");
1290 return -1;
1291 }
1292 }
1293
1294 return 0;
1295 }
1296
1297
1298 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1306 public function set_contrat($user, $contractid)
1307 {
1308 // phpcs:enable
1309 if ($user->hasRight('ficheinter', 'creer')) {
1310 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1311 $sql .= " SET fk_contrat = ".((int) $contractid);
1312 $sql .= " WHERE rowid = ".((int) $this->id);
1313
1314 if ($this->db->query($sql)) {
1315 $this->fk_contrat = $contractid;
1316 return 1;
1317 } else {
1318 $this->error = $this->db->error();
1319 return -1;
1320 }
1321 }
1322
1323 return -2;
1324 }
1325
1326
1327
1337 public function createFromClone(User $user, $socid = 0, $clone_contacts = false, $clone_notes = false)
1338 {
1339 global $hookmanager, $langs;
1340 $langs->load("errors");
1341
1342 $error = 0;
1343
1344 $this->db->begin();
1345
1346 // get extrafields so they will be clone
1347 foreach ($this->lines as $line) {
1348 $line->fetch_optionals();
1349 }
1350
1351 // Load source object
1352 $objFrom = clone $this;
1353
1354 // Change socid if needed
1355 if (!empty($socid) && $socid != $this->socid) {
1356 $objsoc = new Societe($this->db);
1357
1358 if ($objsoc->fetch($socid) > 0) {
1359 $this->socid = $objsoc->id;
1360 //$this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1361 //$this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1362 $this->fk_project = 0;
1363 $this->fk_delivery_address = 0;
1364 }
1365
1366 // TODO Change product price if multi-prices
1367 }
1368
1369 $this->id = 0;
1370 $this->ref = '';
1371 $this->status = self::STATUS_DRAFT;
1372 $this->statut = self::STATUS_DRAFT; // deprecated
1373
1374 // Clear fields
1375 $this->user_author_id = $user->id;
1376 $this->user_validation_id = 0;
1377 $this->date_creation = '';
1378 $this->date_validation = '';
1379
1380 $this->ref_client = '';
1381
1382 if (!$clone_notes) {
1383 $this->note_private = '';
1384 $this->note_public = '';
1385 }
1386
1387 // Create clone
1388 $this->context['createfromclone'] = 'createfromclone';
1389 $result = $this->create($user);
1390 if ($result < 0) {
1391 $error++;
1392 }
1393
1394 if (!$error) {
1395 // Add lines because it is not included into create function
1396 foreach ($this->lines as $line) {
1397 $this->addline($user, $this->id, $line->desc, $line->datei, $line->duration, $line->array_options);
1398 }
1399
1400 // Hook of thirdparty module
1401 if (is_object($hookmanager)) {
1402 $parameters = array('objFrom' => $objFrom);
1403 $action = '';
1404 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1405 if ($reshook < 0) {
1406 $this->setErrorsFromObject($hookmanager);
1407 $error++;
1408 }
1409 }
1410 }
1411
1412 //Duplicate contact
1413 if ($clone_contacts) {
1414 foreach (array('internal', 'external') as $source) {
1415 $tab = $objFrom->liste_contact(-1, $source);
1416 if (is_array($tab) && count($tab) > 0) {
1417 foreach ($tab as $contacttoadd) {
1418 $retAddContact = $this->add_contact(
1419 $contacttoadd['id'],
1420 $contacttoadd['code'],
1421 $contacttoadd['source']
1422 );
1423 if ($this->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1424 $this->error .= $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType");
1425 $error++;
1426 } elseif ($retAddContact < 0) {
1427 $error++;
1428 }
1429 }
1430 } elseif ($tab < 0) {
1431 $this->error .= $objFrom->error;
1432 $error++;
1433 }
1434 }
1435 }
1436
1437 unset($this->context['createfromclone']);
1438
1439 // End
1440 if (!$error) {
1441 $this->db->commit();
1442 return $this->id;
1443 } else {
1444 $this->db->rollback();
1445 return -1;
1446 }
1447 }
1448
1449
1464 public function addline($user, $fichinterid, $desc, $date_intervention, $duration, $array_options = [], $type = 0, $rang = -1, $special_code = 0)
1465 {
1466 dol_syslog(get_class($this)."::addline $fichinterid, $desc, $date_intervention, $duration, $type, $rang, $special_code");
1467
1468 if ($this->status == self::STATUS_DRAFT) {
1469 $this->db->begin();
1470
1471 // Insertion ligne
1472 $line = new FichinterLigne($this->db);
1473
1474 $line->fk_fichinter = $fichinterid;
1475 $line->desc = $desc;
1476 $line->date = $date_intervention;
1477 $line->datei = $date_intervention; // For backward compatibility
1478 $line->duration = $duration;
1479 $line->product_type = $type;
1480 $line->rang = $rang;
1481 $line->special_code = $special_code;
1482
1483
1484 if (is_array($array_options) && count($array_options) > 0) {
1485 $line->array_options = $array_options;
1486 }
1487
1488 $result = $line->insert($user);
1489
1490 if ($result >= 0) {
1491 $this->db->commit();
1492 return $line->id;
1493 } else {
1494 $this->error = $this->db->error();
1495 $this->db->rollback();
1496 return -1;
1497 }
1498 }
1499
1500 return 0;
1501 }
1502
1503
1511 public function initAsSpecimen()
1512 {
1513 global $langs;
1514
1515 $now = dol_now();
1516
1517 // Initialise parameters
1518 $this->id = 0;
1519 $this->ref = 'SPECIMEN';
1520 $this->ref_client = 'SPECIMEN CLIENT';
1521 $this->specimen = 1;
1522 $this->socid = 1;
1523 $this->datec = $now;
1524 $this->note_private = 'Private note';
1525 $this->note_public = 'SPECIMEN';
1526 $this->duration = 0;
1527 $this->user_creation_id = 1;
1528 $nbp = 25;
1529 $xnbp = 0;
1530 while ($xnbp < $nbp) {
1531 $line = new FichinterLigne($this->db);
1532 $line->desc = $langs->trans("Description")." ".$xnbp;
1533 $line->date = ($now - 3600 * (1 + $xnbp));
1534 $line->datei = ($now - 3600 * (1 + $xnbp)); // For backward compatibility
1535 $line->duration = 600;
1536 $line->fk_fichinter = 0;
1537 $this->lines[$xnbp] = $line;
1538 $xnbp++;
1539
1540 $this->duration += $line->duration;
1541 }
1542
1543 return 1;
1544 }
1545
1546 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1552 public function fetch_lines()
1553 {
1554 // phpcs:enable
1555 $this->lines = array();
1556
1557 $sql = "SELECT rowid, fk_fichinter, description, duree, date, rang, extraparams";
1558 $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet";
1559 $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1560 $sql .= " ORDER BY rang ASC, date ASC";
1561
1562 dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG);
1563
1564 $resql = $this->db->query($sql);
1565 if ($resql) {
1566 $num = $this->db->num_rows($resql);
1567 $i = 0;
1568 while ($i < $num) {
1569 $objp = $this->db->fetch_object($resql);
1570
1571 $line = new FichinterLigne($this->db);
1572 $line->id = $objp->rowid;
1573 $line->fk_fichinter = $objp->fk_fichinter;
1574 $line->desc = $objp->description;
1575 $line->duration = $objp->duree;
1576 //For invoicing we calculing hours
1577 $line->qty = round($objp->duree / 3600, 2);
1578 $line->date = $this->db->jdate($objp->date);
1579 $line->datei = $this->db->jdate($objp->date); // For backward compatibility
1580 $line->rang = $objp->rang;
1581 $line->product_type = 1;
1582 $line->fetch_optionals();
1583
1584 $line->extraparams = !empty($objp->extraparams) ? (array) json_decode($objp->extraparams, true) : array();
1585
1586 $this->lines[$i] = $line;
1587 $i++;
1588 }
1589 $this->db->free($resql);
1590
1591 return 1;
1592 } else {
1593 $this->error = $this->db->error();
1594 return -1;
1595 }
1596 }
1597
1606 public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1607 {
1608 $tables = array(
1609 'fichinter'
1610 );
1611
1612 return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1613 }
1614
1623 public function setRefClient($user, $ref_client, $notrigger = 0)
1624 {
1625 // phpcs:enable
1626 if ($user->hasRight('ficheinter', 'creer')) {
1627 $error = 0;
1628
1629 $this->db->begin();
1630
1631 $this->oldcopy = dol_clone($this, 2);
1632
1633 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET ref_client = ".(empty($ref_client) ? 'NULL' : "'".$this->db->escape($ref_client)."'");
1634 $sql .= " WHERE rowid = ".((int) $this->id);
1635
1636 dol_syslog(__METHOD__.' $this->id='.$this->id.', ref_client='.$ref_client, LOG_DEBUG);
1637 $resql = $this->db->query($sql);
1638 if (!$resql) {
1639 $this->errors[] = $this->db->error();
1640 $error++;
1641 }
1642
1643 if (!$error) {
1644 $this->ref_client = $ref_client;
1645 }
1646
1647 if (!$notrigger && empty($error)) {
1648 // Call trigger
1649 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
1650 if ($result < 0) {
1651 $error++;
1652 }
1653 // End call triggers
1654 }
1655
1656 if (!$error) {
1657 $this->db->commit();
1658 return 1;
1659 } else {
1660 foreach ($this->errors as $errmsg) {
1661 dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
1662 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1663 }
1664 $this->db->rollback();
1665 return -1 * $error;
1666 }
1667 } else {
1668 return -1;
1669 }
1670 }
1671
1679 public function getKanbanView($option = '', $arraydata = null)
1680 {
1681 global $langs;
1682
1683 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1684
1685 $return = '<div class="box-flex-item box-flex-grow-zero">';
1686 $return .= '<div class="info-box info-box-sm">';
1687 $return .= '<span class="info-box-icon bg-infobox-action">';
1688 $return .= img_picto('', $this->picto);
1689 $return .= '</span>';
1690 $return .= '<div class="info-box-content">';
1691 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . $this->getNomUrl() . '</span>';
1692 if ($selected >= 0) {
1693 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1694 }
1695 if (!empty($arraydata['thirdparty'])) {
1696 $tmpthirdparty = $arraydata['thirdparty'];
1697 '@phan-var-force Societe $tmpthirdparty';
1699 $return .= '<br><span class="info-box-label">'.$tmpthirdparty->getNomUrl(1).'</span>';
1700 }
1701 if (!empty($this->duration)) {
1702 $return .= '<br><span class="info-box-label ">'.$langs->trans("Duration").' : '.convertSecondToTime($this->duration, 'allhourmin').'</span>';
1703 }
1704 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1705 $return .= '</div>';
1706 $return .= '</div>';
1707 $return .= '</div>';
1708 return $return;
1709 }
1710}
$object ref
Definition info.php:90
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.
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty.
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.
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.
add_contact($fk_socpeople, $type_contact, $source='external', $notrigger=0)
Add a link between element $this->element and a contact.
Class to manage Dolibarr database access.
const STATUS_BILLED
Billed.
initAsSpecimen()
Initialise an instance with random values.
createFromClone(User $user, $socid=0, $clone_contacts=false, $clone_notes=false)
Load an object from its id and create a new one in database.
getLibStatut($mode=0)
Returns the label status.
update($user, $notrigger=0)
Update an intervention.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
setClose($user, $notrigger=0)
Close 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
set_date_delivery($user, $delivery_date_receipt)
Defines a delivery date of the receipt of intervention.
const STATUS_VALIDATED
Validated status.
fetch($rowid, $ref='', $ref_ext='')
Fetch a intervention.
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.
addline($user, $fichinterid, $desc, $date_intervention, $duration, $array_options=[], $type=0, $rang=-1, $special_code=0)
Adding a line of intervention into data base.
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 clickable name (with picto eventually)
__construct($db)
Constructor.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
info($id)
Load information on object.
fetch_lines()
Load array lines ->lines.
Class to manage intervention lines.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:171
getLibSignedStatus(int $mode=0)
Returns the label for signed status.
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:262
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_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_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
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:64
dol_delete_preview($object)
Delete all preview files linked to object instance.
dol_now($mode='gmt')
Return date for now.
setEntity($currentobject)
Set entity id to use when to create an object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
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 '.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
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 a 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.