dolibarr 24.0.2
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 if (empty($this->thirdparty)) { // Not loaded when validated by the API or on closing a ticket
654 $this->fetch_thirdparty();
655 }
656 $num = $this->getNextNumRef($this->thirdparty);
657 } else {
658 $num = (string) $this->ref;
659 }
660 $this->newref = dol_sanitizeFileName($num);
661
662 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
663 $sql .= " SET fk_statut = 1";
664 $sql .= ", ref = '".$this->db->escape($num)."'";
665 $sql .= ", date_valid = '".$this->db->idate($now)."'";
666 $sql .= ", fk_user_valid = ".($user->id > 0 ? (int) $user->id : "null");
667 $sql .= " WHERE rowid = ".((int) $this->id);
668 $sql .= " AND entity IN (".getEntity('intervention').")";
669
670 $sql .= " AND fk_statut = 0";
671
672 dol_syslog(get_class($this)."::setValid", LOG_DEBUG);
673 $resql = $this->db->query($sql);
674 if (!$resql) {
675 dol_print_error($this->db);
676 $error++;
677 }
678
679 if (!$error && !$notrigger) {
680 // Call trigger
681 $result = $this->call_trigger('FICHINTER_VALIDATE', $user);
682 if ($result < 0) {
683 $error++;
684 }
685 // End call triggers
686 }
687
688 if (!$error) {
689 $this->oldref = $this->ref;
690
691 // Rename directory if dir was a temporary ref
692 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
693 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
694
695 // Now we rename also files into index
696 $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)."'";
697 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".((int) $this->entity);
698 $resql = $this->db->query($sql);
699 if (!$resql) {
700 $error++;
701 $this->error = $this->db->lasterror();
702 }
703 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'ficheinter/".$this->db->escape($this->newref)."'";
704 $sql .= " WHERE filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity);
705 $resql = $this->db->query($sql);
706 if (!$resql) {
707 $error++;
708 $this->error = $this->db->lasterror();
709 }
710
711 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
712 $oldref = dol_sanitizeFileName($this->ref);
713 $newref = dol_sanitizeFileName($num);
714 $dirsource = $conf->ficheinter->dir_output.'/'.$oldref;
715 $dirdest = $conf->ficheinter->dir_output.'/'.$newref;
716 if (!$error && file_exists($dirsource)) {
717 dol_syslog(get_class($this)."::setValid rename dir ".$dirsource." into ".$dirdest);
718
719 if (@rename($dirsource, $dirdest)) {
720 dol_syslog("Rename ok");
721 // Rename docs starting with $oldref with $newref
722 $listoffiles = dol_dir_list($conf->ficheinter->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
723 foreach ($listoffiles as $fileentry) {
724 $dirsource = $fileentry['name'];
725 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
726 $dirsource = $fileentry['path'].'/'.$dirsource;
727 $dirdest = $fileentry['path'].'/'.$dirdest;
728 @rename($dirsource, $dirdest);
729 }
730 }
731 }
732 }
733 }
734
735 // Set new ref and define current status
736 if (!$error) {
737 $this->ref = $num;
739 $this->statut = self::STATUS_VALIDATED; // deprecated
740 $this->date_validation = $now;
741 $this->db->commit();
742 return 1;
743 } else {
744 $this->db->rollback();
745 dol_syslog(get_class($this)."::setValid ".$this->error, LOG_ERR);
746 return -1;
747 }
748 }
749
750 return 0;
751 }
752
760 public function setClose($user, $notrigger = 0)
761 {
762 global $conf;
763
764 $error = 0;
765
766 if ($this->status == self::STATUS_CLOSED) {
767 return 0;
768 } else {
769 $this->db->begin();
770
771 $now = dol_now();
772
773 $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element;
774 $sql .= ' SET fk_statut = ' . self::STATUS_CLOSED . ',';
775 $sql .= " datet = '" . $this->db->idate($now) . "',";
776 $sql .= " fk_user_modif = " . ((int) $user->id);
777 $sql .= " WHERE rowid = " . ((int) $this->id);
778 $sql .= " AND fk_statut > " . self::STATUS_DRAFT;
779 $sql .= " AND entity IN (".getEntity('intervention').")";
780
781 if ($this->db->query($sql)) {
782 if (!$notrigger) {
783 // Call trigger
784 $result = $this->call_trigger('FICHINTER_CLOSE', $user);
785 if ($result < 0) {
786 $error++;
787 }
788 // End call triggers
789 }
790
791 if (!$error) {
793 $this->statut = self::STATUS_CLOSED; // deprecated
794 $this->db->commit();
795 return 1;
796 } else {
797 $this->db->rollback();
798 return -1;
799 }
800 } else {
801 $this->error = $this->db->lasterror();
802 $this->db->rollback();
803 return -1;
804 }
805 }
806 }
807
813 public function getAmount()
814 {
815 $amount = 0;
816
817 $this->author = new User($this->db);
818 $this->author->fetch($this->user_creation_id);
819
820 $thm = $this->author->thm;
821
822 foreach ($this->lines as $line) {
823 $amount += ($line->duration / 60 / 60 * (float) $thm);
824 }
825
826 return (float) price2num($amount, 'MT');
827 }
828
829
841 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
842 {
843 global $conf;
844
845 $outputlangs->load("interventions");
846
847 if (!dol_strlen($modele)) {
848 $modele = 'soleil';
849
850 if (!empty($this->model_pdf)) {
851 $modele = $this->model_pdf;
852 } elseif (getDolGlobalString('FICHEINTER_ADDON_PDF')) {
853 $modele = getDolGlobalString('FICHEINTER_ADDON_PDF');
854 }
855 }
856
857 $modelpath = "core/modules/fichinter/doc/";
858
859 return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
860 }
861
868 public function getLibStatut($mode = 0)
869 {
870 return $this->LibStatut((isset($this->statut) ? $this->statut : $this->status), $mode);
871 }
872
873 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
881 public function LibStatut($status, $mode = 0)
882 {
883 // phpcs:enable
884 global $langs;
885 // Init/load array of translation of status
886 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
887 $langs->load("interventions");
888 $langs->load("propal");
889
890 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
891 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
892 $this->labelStatus[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
893 $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
894 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
895 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
896 $this->labelStatusShort[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
897 $this->labelStatusShort[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
898 }
899
900 $statuscode = 'status'.$status;
901 if ($status == self::STATUS_BILLED || $status == self::STATUS_CLOSED) {
902 $statuscode = 'status6';
903 }
904
905 $signed_label = ' (' . $this->getLibSignedStatus() . ')';
906 $status_label = $this->signed_status ? $this->labelStatus[$status] . $signed_label : $this->labelStatus[$status];
907 $status_label_short = $this->signed_status ? $this->labelStatusShort[$status] . $signed_label : $this->labelStatusShort[$status];
908
909 return dolGetStatus($status_label, $status_label_short, '', $statuscode, $mode);
910 }
911
918 public function getTooltipContentArray($params)
919 {
920 global $langs;
921
922 $langs->load('interventions');
923
924 $datas = [];
925 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("ShowIntervention").'</u>';
926 $datas['picto'] .= ' '.$this->getLibStatut(5);
927 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
928
929 return $datas;
930 }
931
942 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $save_lastsearch_value = -1, $morecss = '')
943 {
944 global $conf, $langs, $hookmanager;
945
946 if (!empty($conf->dol_no_mouse_hover)) {
947 $notooltip = 1; // Force disable tooltips
948 }
949
950 $result = '';
951 $params = [
952 'id' => $this->id,
953 'objecttype' => $this->element,
954 'option' => $option,
955 ];
956 $classfortooltip = 'classfortooltip';
957 $dataparams = '';
958 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
959 $classfortooltip = 'classforajaxtooltip';
960 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
961 $label = '';
962 } else {
963 $label = implode($this->getTooltipContentArray($params));
964 }
965
966 $url = DOL_URL_ROOT.'/fichinter/card.php?id='.$this->id;
967
968 if ($option !== 'nolink') {
969 // Add param to save lastsearch_values or not
970 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
971 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
972 $add_save_lastsearch_values = 1;
973 }
974 if ($add_save_lastsearch_values) {
975 $url .= '&save_lastsearch_values=1';
976 }
977 }
978
979 $linkclose = '';
980 if (empty($notooltip)) {
981 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
982 $label = $langs->trans("ShowIntervention");
983 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
984 }
985 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
986 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
987 } else {
988 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
989 }
990
991 if ($option == 'nolink') {
992 $linkstart = '<span';
993 } else {
994 $linkstart = '<a href="'.$url.'"';
995 }
996 $linkstart .= $linkclose.'>';
997 if ($option == 'nolink') {
998 $linkend = '</span>';
999 } else {
1000 $linkend = '</a>';
1001 }
1002
1003 $result .= $linkstart;
1004 if ($withpicto) {
1005 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1006 }
1007
1008 if ($withpicto != 2) {
1009 $result .= $this->ref;
1010 }
1011
1012 $result .= $linkend;
1013
1014 global $action;
1015 $hookmanager->initHooks(array('interventiondao'));
1016 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1017 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1018 if ($reshook > 0) {
1019 $result = $hookmanager->resPrint;
1020 } else {
1021 $result .= $hookmanager->resPrint;
1022 }
1023
1024 return $result;
1025 }
1026
1027
1035 public function getNextNumRef($soc)
1036 {
1037 global $conf, $db, $langs;
1038 $langs->load("interventions");
1039
1040 if (getDolGlobalString('FICHEINTER_ADDON')) {
1041 $mybool = false;
1042
1043 $file = "mod_" . getDolGlobalString('FICHEINTER_ADDON').".php";
1044 $classname = "mod_" . getDolGlobalString('FICHEINTER_ADDON');
1045
1046 // Include file with class
1047 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1048
1049 foreach ($dirmodels as $reldir) {
1050 $dir = dol_buildpath($reldir."core/modules/fichinter/");
1051
1052 // Load file with numbering class (if found)
1053 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1054 }
1055
1056 if (!$mybool) {
1057 dol_print_error(null, "Failed to include file ".$file);
1058 return '';
1059 }
1060
1061 $obj = new $classname();
1062 '@phan-var-force ModeleNumRefFicheinter $obj';
1063 $numref = "";
1064 $numref = $obj->getNextValue($soc, $this);
1065
1066 if ($numref != "") {
1067 return $numref;
1068 } else {
1069 dol_print_error($db, "Fichinter::getNextNumRef ".$obj->error);
1070 return "";
1071 }
1072 } else {
1073 $langs->load("errors");
1074 print $langs->trans("Error")." ".$langs->trans("Error_FICHEINTER_ADDON_NotDefined");
1075 return "";
1076 }
1077 }
1078
1085 public function info($id)
1086 {
1087 $sql = "SELECT f.rowid,";
1088 $sql .= " f.datec,";
1089 $sql .= " f.tms as date_modification,";
1090 $sql .= " f.date_valid as datev,";
1091 $sql .= " f.fk_user_author,";
1092 $sql .= " f.fk_user_modif as fk_user_modification,";
1093 $sql .= " f.fk_user_valid";
1094 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
1095 $sql .= " WHERE f.rowid = ".((int) $id);
1096
1097 $resql = $this->db->query($sql);
1098 if ($resql) {
1099 if ($this->db->num_rows($resql)) {
1100 $obj = $this->db->fetch_object($resql);
1101
1102 $this->id = $obj->rowid;
1103
1104 $this->date_creation = $this->db->jdate($obj->datec);
1105 $this->date_modification = $this->db->jdate($obj->date_modification);
1106 $this->date_validation = $this->db->jdate($obj->datev);
1107
1108 $this->user_creation_id = $obj->fk_user_author;
1109 $this->user_validation_id = $obj->fk_user_valid;
1110 $this->user_modification_id = $obj->fk_user_modification;
1111 }
1112 $this->db->free($resql);
1113 } else {
1114 dol_print_error($this->db);
1115 }
1116 }
1117
1125 public function delete(User $user, $notrigger = 0)
1126 {
1127 global $conf, $langs;
1128 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1129
1130 $error = 0;
1131
1132 $this->db->begin();
1133
1134 if (!$notrigger) {
1135 // Call trigger
1136 $result = $this->call_trigger('FICHINTER_DELETE', $user);
1137 if ($result < 0) {
1138 $error++;
1139 $this->db->rollback();
1140 return -1;
1141 }
1142 // End call triggers
1143 }
1144
1145 // Delete linked object
1146 $res = $this->deleteObjectLinked();
1147 if ($res < 0) {
1148 $error++;
1149 }
1150
1151 // Delete linked contacts
1152 if (!$error) {
1153 $res = $this->delete_linked_contact();
1154 if ($res < 0) {
1155 $this->error = 'ErrorFailToDeleteLinkedContact';
1156 $error++;
1157 }
1158 }
1159
1160 if (!$error) {
1161 $main = MAIN_DB_PREFIX.'fichinterdet';
1162 $ef = $main."_extrafields";
1163 $sql = "DELETE FROM ".$this->db->sanitize($ef)." WHERE fk_object IN (SELECT rowid FROM ".$this->db->sanitize($main)." WHERE fk_fichinter = ".((int) $this->id).")";
1164
1165 $resql = $this->db->query($sql);
1166 if (!$resql) {
1167 $error++;
1168 }
1169 }
1170
1171 if (!$error) {
1172 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet";
1173 $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1174
1175 $resql = $this->db->query($sql);
1176 if (!$resql) {
1177 $error++;
1178 }
1179 }
1180
1181 if (!$error) {
1182 // Remove extrafields
1183 $res = $this->deleteExtraFields();
1184 if ($res < 0) {
1185 $error++;
1186 }
1187 }
1188
1189 if (!$error) {
1190 // Delete object
1191 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinter";
1192 $sql .= " WHERE rowid = ".((int) $this->id);
1193
1194 dol_syslog("Fichinter::delete", LOG_DEBUG);
1195 $resql = $this->db->query($sql);
1196 if (!$resql) {
1197 $error++;
1198 }
1199 }
1200
1201 if (!$error) {
1202 // Delete record into ECM index (Note that delete is also done when deleting files with the dol_delete_dir_recursive
1203 $this->deleteEcmFiles(0); // Deleting files physically is done later with the dol_delete_dir_recursive
1204 $this->deleteEcmFiles(1); // Deleting files physically is done later with the dol_delete_dir_recursive
1205
1206 // Remove directory with files
1207 $fichinterref = dol_sanitizeFileName($this->ref);
1208 if ($conf->ficheinter->dir_output && !empty($fichinterref)) {
1209 $dir = $conf->ficheinter->dir_output."/".$fichinterref;
1210 $file = $conf->ficheinter->dir_output."/".$fichinterref."/".$fichinterref.".pdf";
1211 if (file_exists($file)) {
1212 dol_delete_preview($this);
1213
1214 if (!dol_delete_file($file, 0, 0, 0, $this)) { // For triggers
1215 $langs->load("errors");
1216 $this->error = $langs->trans("ErrorFailToDeleteFile", $file);
1217 return 0;
1218 }
1219 }
1220 if (file_exists($dir)) {
1221 if (!dol_delete_dir_recursive($dir)) {
1222 $langs->load("errors");
1223 $this->error = $langs->trans("ErrorFailToDeleteDir", $dir);
1224 return 0;
1225 }
1226 }
1227 }
1228 }
1229
1230 if (!$error) {
1231 $this->db->commit();
1232 return 1;
1233 } else {
1234 $this->db->rollback();
1235 return -1;
1236 }
1237 }
1238
1239 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1247 public function set_date_delivery($user, $delivery_date_receipt)
1248 {
1249 // phpcs:enable
1250 if ($user->hasRight('ficheinter', 'creer')) {
1251 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
1252 $sql .= " SET datei = '".$this->db->idate($delivery_date_receipt)."'";
1253 $sql .= " WHERE rowid = ".((int) $this->id);
1254 $sql .= " AND fk_statut = 0";
1255
1256 if ($this->db->query($sql)) {
1257 $this->date_delivery = $delivery_date_receipt;
1258 $this->delivery_date_receipt = $delivery_date_receipt;
1259 return 1;
1260 } else {
1261 $this->error = $this->db->error();
1262 dol_syslog("Fichinter::set_date_delivery Erreur SQL");
1263 return -1;
1264 }
1265 }
1266
1267 return 0;
1268 }
1269
1270 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1278 public function set_description($user, $description)
1279 {
1280 // phpcs:enable
1281 if ($user->hasRight('ficheinter', 'creer')) {
1282 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1283 $sql .= " SET description = '".$this->db->escape($description)."',";
1284 $sql .= " fk_user_modif = ".((int) $user->id);
1285 $sql .= " WHERE rowid = ".((int) $this->id);
1286
1287 if ($this->db->query($sql)) {
1288 $this->description = $description;
1289 return 1;
1290 } else {
1291 $this->error = $this->db->error();
1292 dol_syslog("Fichinter::set_description Erreur SQL");
1293 return -1;
1294 }
1295 }
1296
1297 return 0;
1298 }
1299
1300
1301 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1309 public function set_contrat($user, $contractid)
1310 {
1311 // phpcs:enable
1312 if ($user->hasRight('ficheinter', 'creer')) {
1313 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1314 $sql .= " SET fk_contrat = ".((int) $contractid);
1315 $sql .= " WHERE rowid = ".((int) $this->id);
1316
1317 if ($this->db->query($sql)) {
1318 $this->fk_contrat = $contractid;
1319 return 1;
1320 } else {
1321 $this->error = $this->db->error();
1322 return -1;
1323 }
1324 }
1325
1326 return -2;
1327 }
1328
1329
1330
1340 public function createFromClone(User $user, $socid = 0, $clone_contacts = false, $clone_notes = false)
1341 {
1342 global $hookmanager, $langs;
1343 $langs->load("errors");
1344
1345 $error = 0;
1346
1347 $this->db->begin();
1348
1349 // get extrafields so they will be clone
1350 foreach ($this->lines as $line) {
1351 $line->fetch_optionals();
1352 }
1353
1354 // Load source object
1355 $objFrom = clone $this;
1356
1357 // Change socid if needed
1358 if (!empty($socid) && $socid != $this->socid) {
1359 $objsoc = new Societe($this->db);
1360
1361 if ($objsoc->fetch($socid) > 0) {
1362 $this->socid = $objsoc->id;
1363 //$this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1364 //$this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1365 $this->fk_project = 0;
1366 $this->fk_delivery_address = 0;
1367 }
1368
1369 // TODO Change product price if multi-prices
1370 }
1371
1372 $this->id = 0;
1373 $this->ref = '';
1374 $this->status = self::STATUS_DRAFT;
1375 $this->statut = self::STATUS_DRAFT; // deprecated
1376
1377 // Clear fields
1378 $this->user_author_id = $user->id;
1379 $this->user_validation_id = 0;
1380 $this->date_creation = '';
1381 $this->date_validation = '';
1382 $this->signed_status = 0;
1383
1384 $this->ref_client = '';
1385
1386 if (!$clone_notes) {
1387 $this->note_private = '';
1388 $this->note_public = '';
1389 }
1390
1391 // Create clone
1392 $this->context['createfromclone'] = 'createfromclone';
1393 $result = $this->create($user);
1394 if ($result < 0) {
1395 $error++;
1396 }
1397
1398 if (!$error) {
1399 // Add lines because it is not included into create function
1400 foreach ($this->lines as $line) {
1401 $this->addline($user, $this->id, $line->desc, $line->datei, $line->duration, $line->array_options);
1402 }
1403
1404 // Hook of thirdparty module
1405 if (is_object($hookmanager)) {
1406 $parameters = array('objFrom' => $objFrom);
1407 $action = '';
1408 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1409 if ($reshook < 0) {
1410 $this->setErrorsFromObject($hookmanager);
1411 $error++;
1412 }
1413 }
1414 }
1415
1416 //Duplicate contact
1417 if ($clone_contacts) {
1418 foreach (array('internal', 'external') as $source) {
1419 $tab = $objFrom->liste_contact(-1, $source);
1420 if (is_array($tab) && count($tab) > 0) {
1421 foreach ($tab as $contacttoadd) {
1422 $retAddContact = $this->add_contact(
1423 $contacttoadd['id'],
1424 $contacttoadd['code'],
1425 $contacttoadd['source']
1426 );
1427 if ($this->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1428 $this->error .= $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType");
1429 $error++;
1430 } elseif ($retAddContact < 0) {
1431 $error++;
1432 }
1433 }
1434 } elseif ($tab < 0) {
1435 $this->error .= $objFrom->error;
1436 $error++;
1437 }
1438 }
1439 }
1440
1441 unset($this->context['createfromclone']);
1442
1443 // End
1444 if (!$error) {
1445 $this->db->commit();
1446 return $this->id;
1447 } else {
1448 $this->db->rollback();
1449 return -1;
1450 }
1451 }
1452
1453
1468 public function addline($user, $fichinterid, $desc, $date_intervention, $duration, $array_options = [], $type = 0, $rang = -1, $special_code = 0)
1469 {
1470 dol_syslog(get_class($this)."::addline $fichinterid, $desc, $date_intervention, $duration, $type, $rang, $special_code");
1471
1472 if ($this->status == self::STATUS_DRAFT) {
1473 $this->db->begin();
1474
1475 // Insert line
1476 $line = new FichinterLigne($this->db);
1477
1478 $line->fk_fichinter = $fichinterid;
1479 $line->desc = $desc;
1480 $line->date = $date_intervention;
1481 $line->datei = $date_intervention; // For backward compatibility
1482 $line->duration = $duration;
1483 $line->product_type = $type;
1484 $line->rang = $rang;
1485 $line->special_code = $special_code;
1486
1487
1488 if (is_array($array_options) && count($array_options) > 0) {
1489 $line->array_options = $array_options;
1490 }
1491
1492 $result = $line->insert($user);
1493
1494 if ($result >= 0) {
1495 $this->db->commit();
1496 return $line->id;
1497 } else {
1498 $this->error = $this->db->error();
1499 $this->db->rollback();
1500 return -1;
1501 }
1502 }
1503
1504 return 0;
1505 }
1506
1507
1515 public function initAsSpecimen()
1516 {
1517 global $langs;
1518
1519 $now = dol_now();
1520
1521 // Initialise parameters
1522 $this->id = 0;
1523 $this->ref = 'SPECIMEN';
1524 $this->ref_client = 'SPECIMEN CLIENT';
1525 $this->specimen = 1;
1526 $this->socid = 1;
1527 $this->datec = $now;
1528 $this->note_private = 'Private note';
1529 $this->note_public = 'SPECIMEN';
1530 $this->duration = 0;
1531 $this->user_creation_id = 1;
1532 $nbp = 25;
1533 $xnbp = 0;
1534 while ($xnbp < $nbp) {
1535 $line = new FichinterLigne($this->db);
1536 $line->desc = $langs->trans("Description")." ".$xnbp;
1537 $line->date = ($now - 3600 * (1 + $xnbp));
1538 $line->datei = ($now - 3600 * (1 + $xnbp)); // For backward compatibility
1539 $line->duration = 600;
1540 $line->fk_fichinter = 0;
1541 $this->lines[$xnbp] = $line;
1542 $xnbp++;
1543
1544 $this->duration += $line->duration;
1545 }
1546
1547 return 1;
1548 }
1549
1550 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1556 public function fetch_lines()
1557 {
1558 // phpcs:enable
1559 $this->lines = array();
1560
1561 $sql = "SELECT rowid, fk_fichinter, description, duree, date, rang, extraparams";
1562 $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet";
1563 $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1564 $sql .= " ORDER BY rang ASC, date ASC";
1565
1566 dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG);
1567
1568 $resql = $this->db->query($sql);
1569 if ($resql) {
1570 $num = $this->db->num_rows($resql);
1571 $i = 0;
1572 while ($i < $num) {
1573 $objp = $this->db->fetch_object($resql);
1574
1575 $line = new FichinterLigne($this->db);
1576 $line->id = $objp->rowid;
1577 $line->fk_fichinter = $objp->fk_fichinter;
1578 $line->desc = $objp->description;
1579 $line->duration = $objp->duree;
1580 //For invoicing we calculing hours
1581 $line->qty = round($objp->duree / 3600, 2);
1582 $line->date = $this->db->jdate($objp->date);
1583 $line->datei = $this->db->jdate($objp->date); // For backward compatibility
1584 $line->rang = $objp->rang;
1585 $line->product_type = 1;
1586 $line->fetch_optionals();
1587
1588 $line->extraparams = !empty($objp->extraparams) ? (array) json_decode($objp->extraparams, true) : array();
1589
1590 $this->lines[$i] = $line;
1591 $i++;
1592 }
1593 $this->db->free($resql);
1594
1595 return 1;
1596 } else {
1597 $this->error = $this->db->error();
1598 return -1;
1599 }
1600 }
1601
1610 public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1611 {
1612 $tables = array(
1613 'fichinter'
1614 );
1615
1616 return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1617 }
1618
1629 public function setCategories($categories)
1630 {
1631 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1632 return parent::setCategoriesCommon($categories, Categorie::TYPE_FICHINTER);
1633 }
1634
1643 public function setRefClient($user, $ref_client, $notrigger = 0)
1644 {
1645 // phpcs:enable
1646 if ($user->hasRight('ficheinter', 'creer')) {
1647 $error = 0;
1648
1649 $this->db->begin();
1650
1651 $this->oldcopy = dol_clone($this, 2);
1652
1653 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET ref_client = ".(empty($ref_client) ? 'NULL' : "'".$this->db->escape($ref_client)."'");
1654 $sql .= " WHERE rowid = ".((int) $this->id);
1655
1656 dol_syslog(__METHOD__.' $this->id='.$this->id.', ref_client='.$ref_client, LOG_DEBUG);
1657 $resql = $this->db->query($sql);
1658 if (!$resql) {
1659 $this->errors[] = $this->db->error();
1660 $error++;
1661 }
1662
1663 if (!$error) {
1664 $this->ref_client = $ref_client;
1665 }
1666
1667 if (!$notrigger && empty($error)) {
1668 // Call trigger
1669 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
1670 if ($result < 0) {
1671 $error++;
1672 }
1673 // End call triggers
1674 }
1675
1676 if (!$error) {
1677 $this->db->commit();
1678 return 1;
1679 } else {
1680 foreach ($this->errors as $errmsg) {
1681 dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
1682 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1683 }
1684 $this->db->rollback();
1685 return -1 * $error;
1686 }
1687 } else {
1688 return -1;
1689 }
1690 }
1691
1699 public function getKanbanView($option = '', $arraydata = null)
1700 {
1701 global $langs;
1702
1703 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1704
1705 $return = '<div class="box-flex-item box-flex-grow-zero">';
1706 $return .= '<div class="info-box info-box-sm">';
1707 $return .= '<span class="info-box-icon bg-infobox-action">';
1708 $return .= img_picto('', $this->picto);
1709 $return .= '</span>';
1710 $return .= '<div class="info-box-content">';
1711 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . $this->getNomUrl() . '</span>';
1712 if ($selected >= 0) {
1713 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1714 }
1715 if (!empty($arraydata['thirdparty'])) {
1716 $tmpthirdparty = $arraydata['thirdparty'];
1717 '@phan-var-force Societe $tmpthirdparty';
1719 $return .= '<br><span class="info-box-label">'.$tmpthirdparty->getNomUrl(1).'</span>';
1720 }
1721 if (!empty($this->duration)) {
1722 $return .= '<br><span class="info-box-label ">'.$langs->trans("Duration").' : '.convertSecondToTime($this->duration, 'allhourmin').'</span>';
1723 }
1724 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1725 $return .= '</div>';
1726 $return .= '</div>';
1727 $return .= '</div>';
1728 return $return;
1729 }
1730}
$object ref
Definition info.php:90
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
deleteEcmFiles($mode=0)
Delete related files of object in database.
add_object_linked($origin=null, $origin_id=null, $f_user=null, $notrigger=0)
Add an object link into llx_element_element.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty.
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid=0, $f_user=null, $notrigger=0)
Delete all links between an object $this.
setErrorsFromObject($object)
setErrorsFromObject
static isExistingObject($element, $id, $ref='', $ref_ext='')
Check if an object id or ref exists If you don't need or want to instantiate the object and just need...
deleteExtraFields()
Delete all extra fields values for the current object.
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
delete_linked_contact($source='', $code='')
Delete all links between an object $this and all its contacts in llx_element_contact.
add_contact($fk_socpeople, $type_contact, $source='external', $notrigger=0)
Add a link between element $this->element and a contact.
Class to manage Dolibarr database access.
const STATUS_BILLED
Billed.
initAsSpecimen()
Initialise an instance with random values.
createFromClone(User $user, $socid=0, $clone_contacts=false, $clone_notes=false)
Load an object from its id and create a new one in database.
getLibStatut($mode=0)
Returns the label status.
update($user, $notrigger=0)
Update an intervention.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
setClose($user, $notrigger=0)
Close intervention.
const STATUS_DRAFT
Draft status.
create($user, $notrigger=0)
Create an intervention into data base.
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:263
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