dolibarr 25.0.0-alpha
fichinter.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2014 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2011-2020 Juanjo Menent <jmenent@2byte.es>
6 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
7 * Copyright (C) 2015-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;
46 use CommonSubtotal;
47
52 public $TRIGGER_PREFIX = 'FICHINTER';
53
54 public $fields = array(
55 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
56 'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 'isModEnabled("societe")', 'visible' => -1, 'notnull' => 1, 'position' => 15),
57 'fk_projet' => array('type' => 'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label' => 'Project', 'enabled' => 'isModEnabled("project")', 'visible' => -1, 'position' => 20),
58 'fk_contrat' => array('type' => 'integer:Contrat:contrat/class/contrat.class.php', 'label' => 'Contract', 'enabled' => 'isModEnabled("contract")', 'visible' => -1, 'position' => 25),
59 'ref' => array('type' => 'varchar(30)', 'label' => 'Ref', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'showoncombobox' => 1, 'position' => 30),
60 'ref_ext' => array('type' => 'varchar(255)', 'label' => 'RefExt', 'enabled' => 1, 'visible' => 0, 'position' => 35),
61 'ref_client' => array('type' => 'varchar(255)', 'label' => 'RefCustomer', 'enabled' => 1, 'visible' => -1, 'position' => 36),
62 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 40, 'index' => 1),
63 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 45),
64 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 50),
65 'date_valid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 55),
66 'datei' => array('type' => 'date', 'label' => 'Datei', 'enabled' => 1, 'visible' => -1, 'position' => 60),
67 'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => -1, 'position' => 65),
68 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 70),
69 'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => -1, 'position' => 75),
70 'dateo' => array('type' => 'date', 'label' => 'Dateo', 'enabled' => 1, 'visible' => -1, 'position' => 85),
71 'datee' => array('type' => 'date', 'label' => 'Datee', 'enabled' => 1, 'visible' => -1, 'position' => 90),
72 'datet' => array('type' => 'date', 'label' => 'Datet', 'enabled' => 1, 'visible' => -1, 'position' => 95),
73 'duree' => array('type' => 'integer', 'label' => 'Duree', 'enabled' => 1, 'visible' => -1, 'position' => 100),
74 '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')),
75 'description' => array('type' => 'html', 'label' => 'Description', 'enabled' => 1, 'visible' => -1, 'position' => 105, 'showoncombobox' => 2),
76 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 110),
77 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 115),
78 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'PDFTemplate', 'enabled' => 1, 'visible' => 0, 'position' => 120),
79 'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'LastMainDoc', 'enabled' => 1, 'visible' => -1, 'position' => 125),
80 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 130),
81 'extraparams' => array('type' => 'varchar(255)', 'label' => 'Extraparams', 'enabled' => 1, 'visible' => -1, 'position' => 135),
82 'fk_statut' => array('type' => 'integer', 'label' => 'Status', 'enabled' => 1, 'visible' => -1, 'position' => 500),
83 );
84
88 public $element = 'fichinter';
89
93 public $fk_element = 'fk_fichinter';
94
98 public $table_element = 'fichinter';
99
103 public $table_element_line = 'fichinterdet';
104
108 public $class_element_line = 'FichinterLigne';
109
113 public $picto = 'intervention';
114
118 protected $table_ref_field = 'ref';
119
123 public $socid;
124
128 public $author;
129
133 public $datec;
134
138 public $datev;
142 public $dateo;
146 public $datee;
147
151 public $datet;
152
158 public $datem;
159
163 public $duration;
164
169 public $statut = 0; // 0=draft, 1=validated, 2=invoiced, 3=Terminate
170
174 public $status = 0; // 0=draft, 1=validated, 2=invoiced, 3=Terminate
175
179 public $description;
180
184 public $fk_contrat = 0;
185
189 public $fk_project;
190
195 public $ref_client;
196
200 public $extraparams = array();
201
205 public $lines = array();
206
210 const STATUS_DRAFT = 0;
211
216
220 const STATUS_BILLED = 2;
221
225 const STATUS_CLOSED = 3;
226
232 public $date_delivery;
233
238 public $delivery_date_receipt;
239
244 public $user_author_id;
245
246
252 public function __construct($db)
253 {
254 $this->db = $db;
255 }
256
262 public function loadStateBoard()
263 {
264 global $user;
265
266 $this->nb = array();
267 $clause = "WHERE";
268
269 $sql = "SELECT count(fi.rowid) as nb";
270 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as fi";
271 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON fi.fk_soc = s.rowid";
272 if (!$user->hasRight('societe', 'client', 'voir')) {
273 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
274 $sql .= " WHERE sc.fk_user = ".((int) $user->id);
275 $clause = "AND";
276 }
277 $sql .= " ".$clause." fi.entity IN (".getEntity('intervention').")";
278
279 $resql = $this->db->query($sql);
280 if ($resql) {
281 while ($obj = $this->db->fetch_object($resql)) {
282 $this->nb["interventions"] = $obj->nb;
283 }
284 $this->db->free($resql);
285 return 1;
286 } else {
287 dol_print_error($this->db);
288 $this->error = $this->db->error();
289 return -1;
290 }
291 }
292
300 public function create($user, $notrigger = 0)
301 {
302 $error = 0;
303
304 dol_syslog(get_class($this)."::create ref=".$this->ref);
305
306 // Check parameters
307 if (!empty($this->ref)) { // We check that ref is not already used
308 $result = self::isExistingObject($this->element, 0, $this->ref); // Check ref is not yet used
309 if ($result > 0) {
310 $this->error = 'ErrorRefAlreadyExists';
311 dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING);
312 $this->db->rollback();
313 return -1;
314 }
315 }
316 if (!is_numeric($this->duration)) {
317 $this->duration = 0;
318 }
319 if (!empty($this->ref_client)) {
320 $this->ref_client = trim($this->ref_client);
321 }
322
323 if ($this->socid <= 0) {
324 $this->error = 'ErrorFicheinterCompanyDoesNotExist';
325 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
326 return -1;
327 }
328 $this->entity = setEntity($this);
329
330 $soc = new Societe($this->db);
331 $result = $soc->fetch($this->socid);
332
333 $now = dol_now();
334
335 $this->db->begin();
336
337 $sql = "INSERT INTO ".MAIN_DB_PREFIX."fichinter (";
338 $sql .= "fk_soc";
339 $sql .= ", datec";
340 $sql .= ", ref";
341 $sql .= ", ref_client";
342 $sql .= ", entity";
343 $sql .= ", fk_user_author";
344 $sql .= ", fk_user_modif";
345 $sql .= ", description";
346 $sql .= ", model_pdf";
347 $sql .= ", fk_projet";
348 $sql .= ", fk_contrat";
349 $sql .= ", fk_statut";
350 $sql .= ", signed_status";
351 $sql .= ", note_private";
352 $sql .= ", note_public";
353 $sql .= ") ";
354 $sql .= " VALUES (";
355 $sql .= ((int) $this->socid);
356 $sql .= ", '".$this->db->idate($now)."'";
357 $sql .= ", '".$this->db->escape($this->ref)."'";
358 $sql .= ", ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
359 $sql .= ", ".((int) $this->entity);
360 $sql .= ", ".((int) $user->id);
361 $sql .= ", ".((int) $user->id);
362 $sql .= ", ".($this->description ? "'".$this->db->escape($this->description)."'" : "null");
363 $sql .= ", '".$this->db->escape($this->model_pdf)."'";
364 $sql .= ", ".((int) $this->fk_project > 0 ? ((int) $this->fk_project) : 0);
365 $sql .= ", ".((int) $this->fk_contrat > 0 ? ((int) $this->fk_contrat) : 0);
366 $sql .= ", ".((int) $this->status);
367 $sql .= ", ".((int) $this->signed_status);
368 $sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
369 $sql .= ", ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
370 $sql .= ")";
371
372 dol_syslog(get_class($this)."::create", LOG_DEBUG);
373 $result = $this->db->query($sql);
374 if ($result) {
375 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."fichinter");
376
377 if ($this->id) {
378 $this->ref = '(PROV'.$this->id.')';
379 $sql = 'UPDATE '.MAIN_DB_PREFIX."fichinter SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".((int) $this->id);
380
381 dol_syslog(get_class($this)."::create", LOG_DEBUG);
382 $resql = $this->db->query($sql);
383 if (!$resql) {
384 $error++;
385 }
386 }
387
388 if (!$error) {
389 $result = $this->insertExtraFields();
390 if ($result < 0) {
391 $error++;
392 }
393 }
394
395 // Add linked object
396 if (!$error && $this->origin && $this->origin_id) {
397 $ret = $this->add_object_linked();
398 if (!$ret) {
399 dol_print_error($this->db);
400 }
401 }
402
403
404 if (!$error && !$notrigger) {
405 // Call trigger
406 $result = $this->call_trigger('FICHINTER_CREATE', $user);
407 if ($result < 0) {
408 $error++;
409 }
410 // End call triggers
411 }
412
413 if (!$error) {
414 $this->db->commit();
415 return $this->id;
416 } else {
417 $this->db->rollback();
418 $this->error = implode(',', $this->errors);
419 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
420 return -1;
421 }
422 } else {
423 $this->error = $this->db->error();
424 $this->db->rollback();
425 return -1;
426 }
427 }
428
436 public function update($user, $notrigger = 0)
437 {
438 global $conf;
439
440 if (!is_numeric($this->duration)) {
441 $this->duration = 0;
442 }
443 if (!dol_strlen((string) $this->fk_project)) {
444 $this->fk_project = 0;
445 }
446 if (!empty($this->ref_client)) {
447 $this->ref_client = trim($this->ref_client);
448 }
449
450 $error = 0;
451
452 $this->db->begin();
453
454 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter SET ";
455 $sql .= "description = '".$this->db->escape($this->description)."'";
456 $sql .= ", duree = ".((int) $this->duration);
457 $sql .= ", ref_client = ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
458 if ((int) $this->fk_project > 0) {
459 $sql .= ", fk_projet = ".((int) $this->fk_project);
460 }
461 if (isset($this->datec)) {
462 $sql .= ", datec = ".($this->datec ? "'".$this->db->idate($this->datec)."'" : "null");
463 }
464 if (isset($this->datev)) {
465 $sql .= ", date_valid = ".($this->datev ? "'".$this->db->idate($this->datev)."'" : "null");
466 }
467 if (isset($this->datet)) {
468 $sql .= ", datet = ".($this->datet ? "'".$this->db->idate($this->datet)."'" : "null");
469 }
470 $sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
471 $sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
472 $sql .= ", fk_user_modif = ".((int) $user->id);
473 $sql .= " WHERE rowid = ".((int) $this->id);
474
475 dol_syslog(get_class($this)."::update", LOG_DEBUG);
476 if ($this->db->query($sql)) {
477 $result = $this->insertExtraFields();
478 if ($result < 0) {
479 $error++;
480 }
481
482 if (!$error && !$notrigger) {
483 // Call trigger
484 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
485 if ($result < 0) {
486 $error++;
487 $this->db->rollback();
488 return -1;
489 }
490 // End call triggers
491 }
492
493 $this->db->commit();
494 return 1;
495 } else {
496 $this->error = $this->db->error();
497 $this->db->rollback();
498 return -1;
499 }
500 }
501
510 public function fetch($rowid, $ref = '', $ref_ext = '')
511 {
512 $sql = "SELECT f.rowid, f.ref, f.ref_client, f.description, f.fk_soc, f.fk_statut as status, f.signed_status,";
513 $sql .= " f.datec, f.dateo, f.datee, f.datet,";
514 $sql .= " f.date_valid as datev,";
515 $sql .= " f.tms as datem,";
516 $sql .= " f.fk_user_author, f.fk_user_modif,";
517 $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";
518 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
519 $sql .= " WHERE f.entity IN (".getEntity('intervention').")";
520 if ($ref) {
521 $sql .= " AND f.ref = '".$this->db->escape($ref)."'";
522 } elseif ($ref_ext) {
523 $sql .= " AND f.ref_ext = '".$this->db->escape($ref_ext)."'";
524 } else {
525 $sql .= " AND f.rowid = ".((int) $rowid);
526 }
527
528 $resql = $this->db->query($sql);
529 if ($resql) {
530 if ($this->db->num_rows($resql)) {
531 $obj = $this->db->fetch_object($resql);
532
533 $this->id = $obj->rowid;
534 $this->ref = $obj->ref;
535 $this->ref_client = $obj->ref_client;
536 $this->description = $obj->description;
537 $this->socid = $obj->fk_soc;
538 $this->status = $obj->status;
539 $this->statut = $obj->status; // deprecated
540 $this->signed_status = $obj->signed_status;
541 $this->duration = $obj->duree;
542 $this->datec = $this->db->jdate($obj->datec);
543 $this->dateo = $this->db->jdate($obj->dateo);
544 $this->datee = $this->db->jdate($obj->datee);
545 $this->datet = $this->db->jdate($obj->datet);
546 $this->datev = $this->db->jdate($obj->datev);
547 $this->datem = $this->db->jdate($obj->datem);
548 $this->fk_project = $obj->fk_project;
549 $this->note_public = $obj->note_public;
550 $this->note_private = $obj->note_private;
551 $this->model_pdf = $obj->model_pdf;
552 $this->fk_contrat = $obj->fk_contrat;
553 $this->entity = $obj->entity;
554
555 $this->user_author_id = $this->user_creation_id = $obj->fk_user_author;
556 $this->user_modification_id = $obj->fk_user_modif;
557
558 $this->extraparams = is_null($obj->extraparams) ? [] : (array) json_decode($obj->extraparams, true);
559
560 $this->last_main_doc = $obj->last_main_doc;
561
562 // Retrieve extrafields
563 $this->fetch_optionals();
564
565 /*
566 * Lines
567 */
568 $result = $this->fetch_lines();
569 if ($result < 0) {
570 return -3;
571 }
572 $this->db->free($resql);
573 return 1;
574 }
575
576 return 0;
577 } else {
578 $this->error = $this->db->lasterror();
579 return -1;
580 }
581 }
582
589 public function setDraft($user)
590 {
591 $error = 0;
592
593 // Protection
594 if ($this->status <= self::STATUS_DRAFT) {
595 return 0;
596 }
597
598 dol_syslog(get_class($this)."::setDraft", LOG_DEBUG);
599
600 $this->oldcopy = dol_clone($this, 2);
601
602 $this->db->begin();
603
604 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
605 $sql .= " SET fk_statut = ".self::STATUS_DRAFT;
606 $sql .= " WHERE rowid = ".((int) $this->id);
607
608 $resql = $this->db->query($sql);
609 if ($resql) {
610 // Call trigger
611 $result = $this->call_trigger('FICHINTER_UNVALIDATE', $user);
612 if ($result < 0) {
613 $error++;
614 }
615
616 if (!$error) {
617 $this->status = self::STATUS_DRAFT;
618 $this->statut = self::STATUS_DRAFT; // deprecated
619 $this->db->commit();
620 return 1;
621 } else {
622 $this->db->rollback();
623 return -1;
624 }
625 } else {
626 $this->db->rollback();
627 $this->error = $this->db->lasterror();
628 return -1;
629 }
630 }
631
639 public function setValid($user, $notrigger = 0)
640 {
641 global $conf;
642 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
643
644 $error = 0;
645
646 if ($this->status != self::STATUS_VALIDATED) {
647 $this->db->begin();
648
649 $now = dol_now();
650
651 // Define new ref
652 if ((preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
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 = ".((int) $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) {
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 $this->signed_status = 0;
1380
1381 $this->ref_client = '';
1382
1383 if (!$clone_notes) {
1384 $this->note_private = '';
1385 $this->note_public = '';
1386 }
1387
1388 // Create clone
1389 $this->context['createfromclone'] = 'createfromclone';
1390 $result = $this->create($user);
1391 if ($result < 0) {
1392 $error++;
1393 }
1394
1395 if (!$error) {
1396 // Add lines because it is not included into create function
1397 foreach ($this->lines as $line) {
1398 $this->addline($user, $this->id, $line->desc, $line->datei, $line->duration, $line->array_options);
1399 }
1400
1401 // Hook of thirdparty module
1402 if (is_object($hookmanager)) {
1403 $parameters = array('objFrom' => $objFrom);
1404 $action = '';
1405 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1406 if ($reshook < 0) {
1407 $this->setErrorsFromObject($hookmanager);
1408 $error++;
1409 }
1410 }
1411 }
1412
1413 //Duplicate contact
1414 if ($clone_contacts) {
1415 foreach (array('internal', 'external') as $source) {
1416 $tab = $objFrom->liste_contact(-1, $source);
1417 if (is_array($tab) && count($tab) > 0) {
1418 foreach ($tab as $contacttoadd) {
1419 $retAddContact = $this->add_contact(
1420 $contacttoadd['id'],
1421 $contacttoadd['code'],
1422 $contacttoadd['source']
1423 );
1424 if ($this->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1425 $this->error .= $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType");
1426 $error++;
1427 } elseif ($retAddContact < 0) {
1428 $error++;
1429 }
1430 }
1431 } elseif ($tab < 0) {
1432 $this->error .= $objFrom->error;
1433 $error++;
1434 }
1435 }
1436 }
1437
1438 unset($this->context['createfromclone']);
1439
1440 // End
1441 if (!$error) {
1442 $this->db->commit();
1443 return $this->id;
1444 } else {
1445 $this->db->rollback();
1446 return -1;
1447 }
1448 }
1449
1450
1465 public function addline($user, $fichinterid, $desc, $date_intervention, $duration, $array_options = [], $type = 0, $rang = -1, $special_code = 0)
1466 {
1467 dol_syslog(get_class($this)."::addline $fichinterid, $desc, $date_intervention, $duration, $type, $rang, $special_code");
1468
1469 if ($this->status == self::STATUS_DRAFT) {
1470 $this->db->begin();
1471
1472 // Insert line
1473 $line = new FichinterLigne($this->db);
1474
1475 $line->fk_fichinter = $fichinterid;
1476 $line->desc = $desc;
1477 $line->date = $date_intervention;
1478 $line->datei = $date_intervention; // For backward compatibility
1479 $line->duration = $duration;
1480 $line->product_type = $type;
1481 $line->rang = $rang;
1482 $line->special_code = $special_code;
1483
1484
1485 if (is_array($array_options) && count($array_options) > 0) {
1486 $line->array_options = $array_options;
1487 }
1488
1489 $result = $line->insert($user);
1490
1491 if ($result >= 0) {
1492 $this->db->commit();
1493 return $line->id;
1494 } else {
1495 $this->error = $this->db->error();
1496 $this->db->rollback();
1497 return -1;
1498 }
1499 }
1500
1501 return 0;
1502 }
1503
1504
1512 public function initAsSpecimen()
1513 {
1514 global $langs;
1515
1516 $now = dol_now();
1517
1518 // Initialise parameters
1519 $this->id = 0;
1520 $this->ref = 'SPECIMEN';
1521 $this->ref_client = 'SPECIMEN CLIENT';
1522 $this->specimen = 1;
1523 $this->socid = 1;
1524 $this->datec = $now;
1525 $this->note_private = 'Private note';
1526 $this->note_public = 'SPECIMEN';
1527 $this->duration = 0;
1528 $this->user_creation_id = 1;
1529 $nbp = 25;
1530 $xnbp = 0;
1531 while ($xnbp < $nbp) {
1532 $line = new FichinterLigne($this->db);
1533 $line->desc = $langs->trans("Description")." ".$xnbp;
1534 $line->date = ($now - 3600 * (1 + $xnbp));
1535 $line->datei = ($now - 3600 * (1 + $xnbp)); // For backward compatibility
1536 $line->duration = 600;
1537 $line->fk_fichinter = 0;
1538 $this->lines[$xnbp] = $line;
1539 $xnbp++;
1540
1541 $this->duration += $line->duration;
1542 }
1543
1544 return 1;
1545 }
1546
1547 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1553 public function fetch_lines()
1554 {
1555 // phpcs:enable
1556 $this->lines = array();
1557
1558 $sql = "SELECT rowid, fk_fichinter, description, duree, date, rang, extraparams";
1559 $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet";
1560 $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1561 $sql .= " ORDER BY rang ASC, date ASC";
1562
1563 dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG);
1564
1565 $resql = $this->db->query($sql);
1566 if ($resql) {
1567 $num = $this->db->num_rows($resql);
1568 $i = 0;
1569 while ($i < $num) {
1570 $objp = $this->db->fetch_object($resql);
1571
1572 $line = new FichinterLigne($this->db);
1573 $line->id = $objp->rowid;
1574 $line->fk_fichinter = $objp->fk_fichinter;
1575 $line->desc = $objp->description;
1576 $line->duration = $objp->duree;
1577 //For invoicing we calculing hours
1578 $line->qty = round($objp->duree / 3600, 2);
1579 $line->date = $this->db->jdate($objp->date);
1580 $line->datei = $this->db->jdate($objp->date); // For backward compatibility
1581 $line->rang = $objp->rang;
1582 $line->product_type = 1;
1583 $line->fetch_optionals();
1584
1585 $line->extraparams = !empty($objp->extraparams) ? (array) json_decode($objp->extraparams, true) : array();
1586
1587 $this->lines[$i] = $line;
1588 $i++;
1589 }
1590 $this->db->free($resql);
1591
1592 return 1;
1593 } else {
1594 $this->error = $this->db->error();
1595 return -1;
1596 }
1597 }
1598
1607 public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1608 {
1609 $tables = array(
1610 'fichinter'
1611 );
1612
1613 return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1614 }
1615
1626 public function setCategories($categories)
1627 {
1628 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1629 return parent::setCategoriesCommon($categories, Categorie::TYPE_FICHINTER);
1630 }
1631
1640 public function setRefClient($user, $ref_client, $notrigger = 0)
1641 {
1642 // phpcs:enable
1643 if ($user->hasRight('ficheinter', 'creer')) {
1644 $error = 0;
1645
1646 $this->db->begin();
1647
1648 $this->oldcopy = dol_clone($this, 2);
1649
1650 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET ref_client = ".(empty($ref_client) ? 'NULL' : "'".$this->db->escape($ref_client)."'");
1651 $sql .= " WHERE rowid = ".((int) $this->id);
1652
1653 dol_syslog(__METHOD__.' $this->id='.$this->id.', ref_client='.$ref_client, LOG_DEBUG);
1654 $resql = $this->db->query($sql);
1655 if (!$resql) {
1656 $this->errors[] = $this->db->error();
1657 $error++;
1658 }
1659
1660 if (!$error) {
1661 $this->ref_client = $ref_client;
1662 }
1663
1664 if (!$notrigger && empty($error)) {
1665 // Call trigger
1666 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
1667 if ($result < 0) {
1668 $error++;
1669 }
1670 // End call triggers
1671 }
1672
1673 if (!$error) {
1674 $this->db->commit();
1675 return 1;
1676 } else {
1677 foreach ($this->errors as $errmsg) {
1678 dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
1679 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1680 }
1681 $this->db->rollback();
1682 return -1 * $error;
1683 }
1684 } else {
1685 return -1;
1686 }
1687 }
1688
1696 public function getKanbanView($option = '', $arraydata = null)
1697 {
1698 global $langs;
1699
1700 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1701
1702 $return = '<div class="box-flex-item box-flex-grow-zero">';
1703 $return .= '<div class="info-box info-box-sm">';
1704 $return .= '<span class="info-box-icon bg-infobox-action">';
1705 $return .= img_picto('', $this->picto);
1706 $return .= '</span>';
1707 $return .= '<div class="info-box-content">';
1708 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . $this->getNomUrl() . '</span>';
1709 if ($selected >= 0) {
1710 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1711 }
1712 if (!empty($arraydata['thirdparty'])) {
1713 $tmpthirdparty = $arraydata['thirdparty'];
1714 '@phan-var-force Societe $tmpthirdparty';
1716 $return .= '<br><span class="info-box-label">'.$tmpthirdparty->getNomUrl(1).'</span>';
1717 }
1718 if (!empty($this->duration)) {
1719 $return .= '<br><span class="info-box-label ">'.$langs->trans("Duration").' : '.convertSecondToTime($this->duration, 'allhourmin').'</span>';
1720 }
1721 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1722 $return .= '</div>';
1723 $return .= '</div>';
1724 $return .= '</div>';
1725 return $return;
1726 }
1727}
$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:169
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.
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.
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