dolibarr 24.0.0-beta
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-2026 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-2026 William Mead <william@m34d.com>
11 * Copyright (C) 2024-2026 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,";
513 $sql .= " f.date_valid as datev,";
514 $sql .= " f.tms as datem,";
515 $sql .= " f.fk_user_author, f.fk_user_modif,";
516 $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";
517 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
518 $sql .= " WHERE f.entity IN (".getEntity('intervention').")";
519 if ($ref) {
520 $sql .= " AND f.ref = '".$this->db->escape($ref)."'";
521 } elseif ($ref_ext) {
522 $sql .= " AND f.ref_ext = '".$this->db->escape($ref_ext)."'";
523 } else {
524 $sql .= " AND f.rowid = ".((int) $rowid);
525 }
526
527 $resql = $this->db->query($sql);
528 if ($resql) {
529 if ($this->db->num_rows($resql)) {
530 $obj = $this->db->fetch_object($resql);
531
532 $this->id = $obj->rowid;
533 $this->ref = $obj->ref;
534 $this->ref_client = $obj->ref_client;
535 $this->description = $obj->description;
536 $this->socid = $obj->fk_soc;
537 $this->status = $obj->status;
538 $this->statut = $obj->status; // deprecated
539 $this->signed_status = $obj->signed_status;
540 $this->duration = $obj->duree;
541 $this->datec = $this->db->jdate($obj->datec);
542 $this->dateo = $this->db->jdate($obj->dateo);
543 $this->datee = $this->db->jdate($obj->datee);
544 $this->datet = $this->db->jdate($obj->datet);
545 $this->datev = $this->db->jdate($obj->datev);
546 $this->datem = $this->db->jdate($obj->datem);
547 $this->fk_project = $obj->fk_project;
548 $this->note_public = $obj->note_public;
549 $this->note_private = $obj->note_private;
550 $this->model_pdf = $obj->model_pdf;
551 $this->fk_contrat = $obj->fk_contrat;
552 $this->entity = $obj->entity;
553
554 $this->user_author_id = $this->user_creation_id = $obj->fk_user_author;
555 $this->user_modification_id = $obj->fk_user_modif;
556
557 $this->extraparams = is_null($obj->extraparams) ? [] : (array) json_decode($obj->extraparams, true);
558
559 $this->last_main_doc = $obj->last_main_doc;
560
561 // Retrieve extrafields
562 $this->fetch_optionals();
563
564 /*
565 * Lines
566 */
567 $result = $this->fetch_lines();
568 if ($result < 0) {
569 return -3;
570 }
571 $this->db->free($resql);
572 return 1;
573 }
574
575 return 0;
576 } else {
577 $this->error = $this->db->lasterror();
578 return -1;
579 }
580 }
581
588 public function setDraft($user)
589 {
590 $error = 0;
591
592 // Protection
593 if ($this->status <= self::STATUS_DRAFT) {
594 return 0;
595 }
596
597 dol_syslog(get_class($this)."::setDraft", LOG_DEBUG);
598
599 $this->oldcopy = dol_clone($this, 2);
600
601 $this->db->begin();
602
603 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
604 $sql .= " SET fk_statut = ".self::STATUS_DRAFT;
605 $sql .= " WHERE rowid = ".((int) $this->id);
606
607 $resql = $this->db->query($sql);
608 if ($resql) {
609 // Call trigger
610 $result = $this->call_trigger('FICHINTER_UNVALIDATE', $user);
611 if ($result < 0) {
612 $error++;
613 }
614
615 if (!$error) {
616 $this->status = self::STATUS_DRAFT;
617 $this->statut = self::STATUS_DRAFT; // deprecated
618 $this->db->commit();
619 return 1;
620 } else {
621 $this->db->rollback();
622 return -1;
623 }
624 } else {
625 $this->db->rollback();
626 $this->error = $this->db->lasterror();
627 return -1;
628 }
629 }
630
638 public function setValid($user, $notrigger = 0)
639 {
640 global $conf;
641 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
642
643 $error = 0;
644
645 if ($this->status != self::STATUS_VALIDATED) {
646 $this->db->begin();
647
648 $now = dol_now();
649
650 // Define new ref
651 if ((preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
652 $num = $this->getNextNumRef($this->thirdparty);
653 } else {
654 $num = (string) $this->ref;
655 }
656 $this->newref = dol_sanitizeFileName($num);
657
658 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
659 $sql .= " SET fk_statut = 1";
660 $sql .= ", ref = '".$this->db->escape($num)."'";
661 $sql .= ", date_valid = '".$this->db->idate($now)."'";
662 $sql .= ", fk_user_valid = ".($user->id > 0 ? (int) $user->id : "null");
663 $sql .= " WHERE rowid = ".((int) $this->id);
664 $sql .= " AND entity = ".((int) $this->entity);
665
666 $sql .= " AND fk_statut = 0";
667
668 dol_syslog(get_class($this)."::setValid", LOG_DEBUG);
669 $resql = $this->db->query($sql);
670 if (!$resql) {
671 dol_print_error($this->db);
672 $error++;
673 }
674
675 if (!$error && !$notrigger) {
676 // Call trigger
677 $result = $this->call_trigger('FICHINTER_VALIDATE', $user);
678 if ($result < 0) {
679 $error++;
680 }
681 // End call triggers
682 }
683
684 if (!$error) {
685 $this->oldref = $this->ref;
686
687 // Rename directory if dir was a temporary ref
688 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
689 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
690
691 // Now we rename also files into index
692 $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)."'";
693 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".((int) $this->entity);
694 $resql = $this->db->query($sql);
695 if (!$resql) {
696 $error++;
697 $this->error = $this->db->lasterror();
698 }
699 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'ficheinter/".$this->db->escape($this->newref)."'";
700 $sql .= " WHERE filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
701 $resql = $this->db->query($sql);
702 if (!$resql) {
703 $error++;
704 $this->error = $this->db->lasterror();
705 }
706
707 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
708 $oldref = dol_sanitizeFileName($this->ref);
709 $newref = dol_sanitizeFileName($num);
710 $dirsource = $conf->ficheinter->dir_output.'/'.$oldref;
711 $dirdest = $conf->ficheinter->dir_output.'/'.$newref;
712 if (!$error && file_exists($dirsource)) {
713 dol_syslog(get_class($this)."::setValid rename dir ".$dirsource." into ".$dirdest);
714
715 if (@rename($dirsource, $dirdest)) {
716 dol_syslog("Rename ok");
717 // Rename docs starting with $oldref with $newref
718 $listoffiles = dol_dir_list($conf->ficheinter->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
719 foreach ($listoffiles as $fileentry) {
720 $dirsource = $fileentry['name'];
721 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
722 $dirsource = $fileentry['path'].'/'.$dirsource;
723 $dirdest = $fileentry['path'].'/'.$dirdest;
724 @rename($dirsource, $dirdest);
725 }
726 }
727 }
728 }
729 }
730
731 // Set new ref and define current status
732 if (!$error) {
733 $this->ref = $num;
735 $this->statut = self::STATUS_VALIDATED; // deprecated
736 $this->date_validation = $now;
737 $this->db->commit();
738 return 1;
739 } else {
740 $this->db->rollback();
741 dol_syslog(get_class($this)."::setValid ".$this->error, LOG_ERR);
742 return -1;
743 }
744 }
745
746 return 0;
747 }
748
756 public function setClose($user, $notrigger = 0)
757 {
758 global $conf;
759
760 $error = 0;
761
762 if ($this->status == self::STATUS_CLOSED) {
763 return 0;
764 } else {
765 $this->db->begin();
766
767 $now = dol_now();
768
769 $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element;
770 $sql .= ' SET fk_statut = ' . self::STATUS_CLOSED . ',';
771 $sql .= " datet = '" . $this->db->idate($now) . "',";
772 $sql .= " fk_user_modif = " . ((int) $user->id);
773 $sql .= " WHERE rowid = " . ((int) $this->id);
774 $sql .= " AND fk_statut > " . self::STATUS_DRAFT;
775 $sql .= " AND entity = " . ((int) $conf->entity);
776
777 if ($this->db->query($sql)) {
778 if (!$notrigger) {
779 // Call trigger
780 $result = $this->call_trigger('FICHINTER_CLOSE', $user);
781 if ($result < 0) {
782 $error++;
783 }
784 // End call triggers
785 }
786
787 if (!$error) {
789 $this->statut = self::STATUS_CLOSED; // deprecated
790 $this->db->commit();
791 return 1;
792 } else {
793 $this->db->rollback();
794 return -1;
795 }
796 } else {
797 $this->error = $this->db->lasterror();
798 $this->db->rollback();
799 return -1;
800 }
801 }
802 }
803
809 public function getAmount()
810 {
811 $amount = 0;
812
813 $this->author = new User($this->db);
814 $this->author->fetch($this->user_creation_id);
815
816 $thm = $this->author->thm;
817
818 foreach ($this->lines as $line) {
819 $amount += ($line->duration / 60 / 60 * (float) $thm);
820 }
821
822 return (float) price2num($amount, 'MT');
823 }
824
825
837 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
838 {
839 global $conf;
840
841 $outputlangs->load("interventions");
842
843 if (!dol_strlen($modele)) {
844 $modele = 'soleil';
845
846 if (!empty($this->model_pdf)) {
847 $modele = $this->model_pdf;
848 } elseif (getDolGlobalString('FICHEINTER_ADDON_PDF')) {
849 $modele = getDolGlobalString('FICHEINTER_ADDON_PDF');
850 }
851 }
852
853 $modelpath = "core/modules/fichinter/doc/";
854
855 return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
856 }
857
864 public function getLibStatut($mode = 0)
865 {
866 return $this->LibStatut((isset($this->statut) ? $this->statut : $this->status), $mode);
867 }
868
869 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
877 public function LibStatut($status, $mode = 0)
878 {
879 // phpcs:enable
880 global $langs;
881 // Init/load array of translation of status
882 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
883 $langs->load("interventions");
884 $langs->load("propal");
885
886 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
887 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
888 $this->labelStatus[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
889 $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
890 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
891 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
892 $this->labelStatusShort[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
893 $this->labelStatusShort[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
894 }
895
896 $statuscode = 'status'.$status;
897 if ($status == self::STATUS_BILLED || $status == self::STATUS_CLOSED) {
898 $statuscode = 'status6';
899 }
900
901 $signed_label = ' (' . $this->getLibSignedStatus() . ')';
902 $status_label = $this->signed_status ? $this->labelStatus[$status] . $signed_label : $this->labelStatus[$status];
903 $status_label_short = $this->signed_status ? $this->labelStatusShort[$status] . $signed_label : $this->labelStatusShort[$status];
904
905 return dolGetStatus($status_label, $status_label_short, '', $statuscode, $mode);
906 }
907
914 public function getTooltipContentArray($params)
915 {
916 global $langs;
917
918 $langs->load('interventions');
919
920 $datas = [];
921 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("ShowIntervention").'</u>';
922 $datas['picto'] .= ' '.$this->getLibStatut(5);
923 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
924
925 return $datas;
926 }
927
938 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $save_lastsearch_value = -1, $morecss = '')
939 {
940 global $conf, $langs, $hookmanager;
941
942 if (!empty($conf->dol_no_mouse_hover)) {
943 $notooltip = 1; // Force disable tooltips
944 }
945
946 $result = '';
947 $params = [
948 'id' => $this->id,
949 'objecttype' => $this->element,
950 'option' => $option,
951 ];
952 $classfortooltip = 'classfortooltip';
953 $dataparams = '';
954 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
955 $classfortooltip = 'classforajaxtooltip';
956 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
957 $label = '';
958 } else {
959 $label = implode($this->getTooltipContentArray($params));
960 }
961
962 $url = DOL_URL_ROOT.'/fichinter/card.php?id='.$this->id;
963
964 if ($option !== 'nolink') {
965 // Add param to save lastsearch_values or not
966 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
967 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
968 $add_save_lastsearch_values = 1;
969 }
970 if ($add_save_lastsearch_values) {
971 $url .= '&save_lastsearch_values=1';
972 }
973 }
974
975 $linkclose = '';
976 if (empty($notooltip)) {
977 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
978 $label = $langs->trans("ShowIntervention");
979 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
980 }
981 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
982 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
983 } else {
984 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
985 }
986
987 if ($option == 'nolink') {
988 $linkstart = '<span';
989 } else {
990 $linkstart = '<a href="'.$url.'"';
991 }
992 $linkstart .= $linkclose.'>';
993 if ($option == 'nolink') {
994 $linkend = '</span>';
995 } else {
996 $linkend = '</a>';
997 }
998
999 $result .= $linkstart;
1000 if ($withpicto) {
1001 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1002 }
1003
1004 if ($withpicto != 2) {
1005 $result .= $this->ref;
1006 }
1007
1008 $result .= $linkend;
1009
1010 global $action;
1011 $hookmanager->initHooks(array('interventiondao'));
1012 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1013 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1014 if ($reshook > 0) {
1015 $result = $hookmanager->resPrint;
1016 } else {
1017 $result .= $hookmanager->resPrint;
1018 }
1019
1020 return $result;
1021 }
1022
1023
1031 public function getNextNumRef($soc)
1032 {
1033 global $conf, $db, $langs;
1034 $langs->load("interventions");
1035
1036 if (getDolGlobalString('FICHEINTER_ADDON')) {
1037 $mybool = false;
1038
1039 $file = "mod_" . getDolGlobalString('FICHEINTER_ADDON').".php";
1040 $classname = "mod_" . getDolGlobalString('FICHEINTER_ADDON');
1041
1042 // Include file with class
1043 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1044
1045 foreach ($dirmodels as $reldir) {
1046 $dir = dol_buildpath($reldir."core/modules/fichinter/");
1047
1048 // Load file with numbering class (if found)
1049 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1050 }
1051
1052 if (!$mybool) {
1053 dol_print_error(null, "Failed to include file ".$file);
1054 return '';
1055 }
1056
1057 $obj = new $classname();
1058 '@phan-var-force ModeleNumRefFicheinter $obj';
1059 $numref = "";
1060 $numref = $obj->getNextValue($soc, $this);
1061
1062 if ($numref != "") {
1063 return $numref;
1064 } else {
1065 dol_print_error($db, "Fichinter::getNextNumRef ".$obj->error);
1066 return "";
1067 }
1068 } else {
1069 $langs->load("errors");
1070 print $langs->trans("Error")." ".$langs->trans("Error_FICHEINTER_ADDON_NotDefined");
1071 return "";
1072 }
1073 }
1074
1081 public function info($id)
1082 {
1083 $sql = "SELECT f.rowid,";
1084 $sql .= " f.datec,";
1085 $sql .= " f.tms as date_modification,";
1086 $sql .= " f.date_valid as datev,";
1087 $sql .= " f.fk_user_author,";
1088 $sql .= " f.fk_user_modif as fk_user_modification,";
1089 $sql .= " f.fk_user_valid";
1090 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
1091 $sql .= " WHERE f.rowid = ".((int) $id);
1092
1093 $resql = $this->db->query($sql);
1094 if ($resql) {
1095 if ($this->db->num_rows($resql)) {
1096 $obj = $this->db->fetch_object($resql);
1097
1098 $this->id = $obj->rowid;
1099
1100 $this->date_creation = $this->db->jdate($obj->datec);
1101 $this->date_modification = $this->db->jdate($obj->date_modification);
1102 $this->date_validation = $this->db->jdate($obj->datev);
1103
1104 $this->user_creation_id = $obj->fk_user_author;
1105 $this->user_validation_id = $obj->fk_user_valid;
1106 $this->user_modification_id = $obj->fk_user_modification;
1107 }
1108 $this->db->free($resql);
1109 } else {
1110 dol_print_error($this->db);
1111 }
1112 }
1113
1121 public function delete(User $user, $notrigger = 0)
1122 {
1123 global $conf, $langs;
1124 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1125
1126 $error = 0;
1127
1128 $this->db->begin();
1129
1130 if (!$notrigger) {
1131 // Call trigger
1132 $result = $this->call_trigger('FICHINTER_DELETE', $user);
1133 if ($result < 0) {
1134 $error++;
1135 $this->db->rollback();
1136 return -1;
1137 }
1138 // End call triggers
1139 }
1140
1141 // Delete linked object
1142 $res = $this->deleteObjectLinked();
1143 if ($res < 0) {
1144 $error++;
1145 }
1146
1147 // Delete linked contacts
1148 if (!$error) {
1149 $res = $this->delete_linked_contact();
1150 if ($res < 0) {
1151 $this->error = 'ErrorFailToDeleteLinkedContact';
1152 $error++;
1153 }
1154 }
1155
1156 if (!$error) {
1157 $main = MAIN_DB_PREFIX.'fichinterdet';
1158 $ef = $main."_extrafields";
1159 $sql = "DELETE FROM ".$this->db->sanitize($ef)." WHERE fk_object IN (SELECT rowid FROM ".$this->db->sanitize($main)." WHERE fk_fichinter = ".((int) $this->id).")";
1160
1161 $resql = $this->db->query($sql);
1162 if (!$resql) {
1163 $error++;
1164 }
1165 }
1166
1167 if (!$error) {
1168 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet";
1169 $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1170
1171 $resql = $this->db->query($sql);
1172 if (!$resql) {
1173 $error++;
1174 }
1175 }
1176
1177 if (!$error) {
1178 // Remove extrafields
1179 $res = $this->deleteExtraFields();
1180 if ($res < 0) {
1181 $error++;
1182 }
1183 }
1184
1185 if (!$error) {
1186 // Delete object
1187 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinter";
1188 $sql .= " WHERE rowid = ".((int) $this->id);
1189
1190 dol_syslog("Fichinter::delete", LOG_DEBUG);
1191 $resql = $this->db->query($sql);
1192 if (!$resql) {
1193 $error++;
1194 }
1195 }
1196
1197 if (!$error) {
1198 // Delete record into ECM index (Note that delete is also done when deleting files with the dol_delete_dir_recursive
1199 $this->deleteEcmFiles(0); // Deleting files physically is done later with the dol_delete_dir_recursive
1200 $this->deleteEcmFiles(1); // Deleting files physically is done later with the dol_delete_dir_recursive
1201
1202 // Remove directory with files
1203 $fichinterref = dol_sanitizeFileName($this->ref);
1204 if ($conf->ficheinter->dir_output) {
1205 $dir = $conf->ficheinter->dir_output."/".$fichinterref;
1206 $file = $conf->ficheinter->dir_output."/".$fichinterref."/".$fichinterref.".pdf";
1207 if (file_exists($file)) {
1208 dol_delete_preview($this);
1209
1210 if (!dol_delete_file($file, 0, 0, 0, $this)) { // For triggers
1211 $langs->load("errors");
1212 $this->error = $langs->trans("ErrorFailToDeleteFile", $file);
1213 return 0;
1214 }
1215 }
1216 if (file_exists($dir)) {
1217 if (!dol_delete_dir_recursive($dir)) {
1218 $langs->load("errors");
1219 $this->error = $langs->trans("ErrorFailToDeleteDir", $dir);
1220 return 0;
1221 }
1222 }
1223 }
1224 }
1225
1226 if (!$error) {
1227 $this->db->commit();
1228 return 1;
1229 } else {
1230 $this->db->rollback();
1231 return -1;
1232 }
1233 }
1234
1235 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1243 public function set_date_delivery($user, $delivery_date_receipt)
1244 {
1245 // phpcs:enable
1246 if ($user->hasRight('ficheinter', 'creer')) {
1247 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
1248 $sql .= " SET datei = '".$this->db->idate($delivery_date_receipt)."'";
1249 $sql .= " WHERE rowid = ".((int) $this->id);
1250 $sql .= " AND fk_statut = 0";
1251
1252 if ($this->db->query($sql)) {
1253 $this->date_delivery = $delivery_date_receipt;
1254 $this->delivery_date_receipt = $delivery_date_receipt;
1255 return 1;
1256 } else {
1257 $this->error = $this->db->error();
1258 dol_syslog("Fichinter::set_date_delivery Erreur SQL");
1259 return -1;
1260 }
1261 }
1262
1263 return 0;
1264 }
1265
1266 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1274 public function set_description($user, $description)
1275 {
1276 // phpcs:enable
1277 if ($user->hasRight('ficheinter', 'creer')) {
1278 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1279 $sql .= " SET description = '".$this->db->escape($description)."',";
1280 $sql .= " fk_user_modif = ".((int) $user->id);
1281 $sql .= " WHERE rowid = ".((int) $this->id);
1282
1283 if ($this->db->query($sql)) {
1284 $this->description = $description;
1285 return 1;
1286 } else {
1287 $this->error = $this->db->error();
1288 dol_syslog("Fichinter::set_description Erreur SQL");
1289 return -1;
1290 }
1291 }
1292
1293 return 0;
1294 }
1295
1296
1297 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1305 public function set_contrat($user, $contractid)
1306 {
1307 // phpcs:enable
1308 if ($user->hasRight('ficheinter', 'creer')) {
1309 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1310 $sql .= " SET fk_contrat = ".((int) $contractid);
1311 $sql .= " WHERE rowid = ".((int) $this->id);
1312
1313 if ($this->db->query($sql)) {
1314 $this->fk_contrat = $contractid;
1315 return 1;
1316 } else {
1317 $this->error = $this->db->error();
1318 return -1;
1319 }
1320 }
1321
1322 return -2;
1323 }
1324
1325
1326
1336 public function createFromClone(User $user, $socid = 0, $clone_contacts = false, $clone_notes = false)
1337 {
1338 global $hookmanager, $langs;
1339 $langs->load("errors");
1340
1341 $error = 0;
1342
1343 $this->db->begin();
1344
1345 // get extrafields so they will be clone
1346 foreach ($this->lines as $line) {
1347 $line->fetch_optionals();
1348 }
1349
1350 // Load source object
1351 $objFrom = clone $this;
1352
1353 // Change socid if needed
1354 if (!empty($socid) && $socid != $this->socid) {
1355 $objsoc = new Societe($this->db);
1356
1357 if ($objsoc->fetch($socid) > 0) {
1358 $this->socid = $objsoc->id;
1359 //$this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1360 //$this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1361 $this->fk_project = 0;
1362 $this->fk_delivery_address = 0;
1363 }
1364
1365 // TODO Change product price if multi-prices
1366 }
1367
1368 $this->id = 0;
1369 $this->ref = '';
1370 $this->status = self::STATUS_DRAFT;
1371 $this->statut = self::STATUS_DRAFT; // deprecated
1372
1373 // Clear fields
1374 $this->user_author_id = $user->id;
1375 $this->user_validation_id = 0;
1376 $this->date_creation = '';
1377 $this->date_validation = '';
1378 $this->signed_status = 0;
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 // Insert line
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
1625 public function setCategories($categories)
1626 {
1627 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1628 return parent::setCategoriesCommon($categories, Categorie::TYPE_FICHINTER);
1629 }
1630
1639 public function setRefClient($user, $ref_client, $notrigger = 0)
1640 {
1641 // phpcs:enable
1642 if ($user->hasRight('ficheinter', 'creer')) {
1643 $error = 0;
1644
1645 $this->db->begin();
1646
1647 $this->oldcopy = dol_clone($this, 2);
1648
1649 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET ref_client = ".(empty($ref_client) ? 'NULL' : "'".$this->db->escape($ref_client)."'");
1650 $sql .= " WHERE rowid = ".((int) $this->id);
1651
1652 dol_syslog(__METHOD__.' $this->id='.$this->id.', ref_client='.$ref_client, LOG_DEBUG);
1653 $resql = $this->db->query($sql);
1654 if (!$resql) {
1655 $this->errors[] = $this->db->error();
1656 $error++;
1657 }
1658
1659 if (!$error) {
1660 $this->ref_client = $ref_client;
1661 }
1662
1663 if (!$notrigger && empty($error)) {
1664 // Call trigger
1665 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
1666 if ($result < 0) {
1667 $error++;
1668 }
1669 // End call triggers
1670 }
1671
1672 if (!$error) {
1673 $this->db->commit();
1674 return 1;
1675 } else {
1676 foreach ($this->errors as $errmsg) {
1677 dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
1678 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1679 }
1680 $this->db->rollback();
1681 return -1 * $error;
1682 }
1683 } else {
1684 return -1;
1685 }
1686 }
1687
1695 public function getKanbanView($option = '', $arraydata = null)
1696 {
1697 global $langs;
1698
1699 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1700
1701 $return = '<div class="box-flex-item box-flex-grow-zero">';
1702 $return .= '<div class="info-box info-box-sm">';
1703 $return .= '<span class="info-box-icon bg-infobox-action">';
1704 $return .= img_picto('', $this->picto);
1705 $return .= '</span>';
1706 $return .= '<div class="info-box-content">';
1707 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . $this->getNomUrl() . '</span>';
1708 if ($selected >= 0) {
1709 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1710 }
1711 if (!empty($arraydata['thirdparty'])) {
1712 $tmpthirdparty = $arraydata['thirdparty'];
1713 '@phan-var-force Societe $tmpthirdparty';
1715 $return .= '<br><span class="info-box-label">'.$tmpthirdparty->getNomUrl(1).'</span>';
1716 }
1717 if (!empty($this->duration)) {
1718 $return .= '<br><span class="info-box-label ">'.$langs->trans("Duration").' : '.convertSecondToTime($this->duration, 'allhourmin').'</span>';
1719 }
1720 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1721 $return .= '</div>';
1722 $return .= '</div>';
1723 $return .= '</div>';
1724 return $return;
1725 }
1726}
$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.
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.
setCategories($categories)
Sets object to given categories.
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:168
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:248
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.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
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.
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.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php