dolibarr 22.0.5
fichinter.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2014 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2011-2020 Juanjo Menent <jmenent@2byte.es>
6 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
7 * Copyright (C) 2015-2020 Charlene Benke <charlie@patas-monkey.com>
8 * Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
9 * Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
10 * Copyright (C) 2023-2024 William Mead <william.mead@manchenumerique.fr>
11 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 */
26
32require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
33require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinterligne.class.php';
34require_once DOL_DOCUMENT_ROOT.'/core/class/commonsignedobject.class.php';
35
42{
43 use CommonSignedObject;
44
45 public $fields = array(
46 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
47 'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 'isModEnabled("societe")', 'visible' => -1, 'notnull' => 1, 'position' => 15),
48 'fk_projet' => array('type' => 'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label' => 'Fk projet', 'enabled' => 'isModEnabled("project")', 'visible' => -1, 'position' => 20),
49 'fk_contrat' => array('type' => 'integer:Contrat:contrat/class/contrat.class.php', 'label' => 'Fk contrat', 'enabled' => '$conf->contrat->enabled', 'visible' => -1, 'position' => 25),
50 'ref' => array('type' => 'varchar(30)', 'label' => 'Ref', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'showoncombobox' => 1, 'position' => 30),
51 'ref_ext' => array('type' => 'varchar(255)', 'label' => 'RefExt', 'enabled' => 1, 'visible' => 0, 'position' => 35),
52 'ref_client' => array('type' => 'varchar(255)', 'label' => 'RefCustomer', 'enabled' => 1, 'visible' => -1, 'position' => 36),
53 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 40, 'index' => 1),
54 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 45),
55 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 50),
56 'date_valid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 55),
57 'datei' => array('type' => 'date', 'label' => 'Datei', 'enabled' => 1, 'visible' => -1, 'position' => 60),
58 'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user author', 'enabled' => 1, 'visible' => -1, 'position' => 65),
59 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 70),
60 'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => -1, 'position' => 75),
61 'dateo' => array('type' => 'date', 'label' => 'Dateo', 'enabled' => 1, 'visible' => -1, 'position' => 85),
62 'datee' => array('type' => 'date', 'label' => 'Datee', 'enabled' => 1, 'visible' => -1, 'position' => 90),
63 'datet' => array('type' => 'date', 'label' => 'Datet', 'enabled' => 1, 'visible' => -1, 'position' => 95),
64 'duree' => array('type' => 'integer', 'label' => 'Duree', 'enabled' => 1, 'visible' => -1, 'position' => 100),
65 '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')),
66 'description' => array('type' => 'html', 'label' => 'Description', 'enabled' => 1, 'visible' => -1, 'position' => 105, 'showoncombobox' => 2),
67 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 110),
68 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 115),
69 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 120),
70 'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'Last main doc', 'enabled' => 1, 'visible' => -1, 'position' => 125),
71 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 130),
72 'extraparams' => array('type' => 'varchar(255)', 'label' => 'Extraparams', 'enabled' => 1, 'visible' => -1, 'position' => 135),
73 'fk_statut' => array('type' => 'integer', 'label' => 'Fk statut', 'enabled' => 1, 'visible' => -1, 'position' => 500),
74 );
75
79 public $element = 'fichinter';
80
84 public $table_element = 'fichinter';
85
89 public $table_element_line = 'fichinterdet';
90
94 public $picto = 'intervention';
95
99 protected $table_ref_field = 'ref';
100
104 public $socid;
105
109 public $author;
110
114 public $datec;
115
119 public $datev;
123 public $dateo;
127 public $datee;
128
132 public $datet;
133
139 public $datem;
140
144 public $duration;
145
150 public $statut = 0; // 0=draft, 1=validated, 2=invoiced, 3=Terminate
151
155 public $status = 0; // 0=draft, 1=validated, 2=invoiced, 3=Terminate
156
160 public $description;
161
165 public $fk_contrat = 0;
166
170 public $fk_project;
171
176 public $ref_client;
177
181 public $extraparams = array();
182
186 public $lines = array();
187
191 const STATUS_DRAFT = 0;
192
197
201 const STATUS_BILLED = 2;
202
206 const STATUS_CLOSED = 3;
207
213 public $date_delivery;
214
219 public $delivery_date_receipt;
220
225 public $user_author_id;
226
227
233 public function __construct($db)
234 {
235 $this->db = $db;
236 }
237
243 public function loadStateBoard()
244 {
245 global $user;
246
247 $this->nb = array();
248 $clause = "WHERE";
249
250 $sql = "SELECT count(fi.rowid) as nb";
251 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as fi";
252 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON fi.fk_soc = s.rowid";
253 if (!$user->hasRight('societe', 'client', 'voir')) {
254 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
255 $sql .= " WHERE sc.fk_user = ".((int) $user->id);
256 $clause = "AND";
257 }
258 $sql .= " ".$clause." fi.entity IN (".getEntity('intervention').")";
259
260 $resql = $this->db->query($sql);
261 if ($resql) {
262 while ($obj = $this->db->fetch_object($resql)) {
263 $this->nb["interventions"] = $obj->nb;
264 }
265 $this->db->free($resql);
266 return 1;
267 } else {
268 dol_print_error($this->db);
269 $this->error = $this->db->error();
270 return -1;
271 }
272 }
273
281 public function create($user, $notrigger = 0)
282 {
283 global $conf, $langs;
284
285 $error = 0;
286
287 dol_syslog(get_class($this)."::create ref=".$this->ref);
288
289 // Check parameters
290 if (!empty($this->ref)) { // We check that ref is not already used
291 $result = self::isExistingObject($this->element, 0, $this->ref); // Check ref is not yet used
292 if ($result > 0) {
293 $this->error = 'ErrorRefAlreadyExists';
294 dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING);
295 $this->db->rollback();
296 return -1;
297 }
298 }
299 if (!is_numeric($this->duration)) {
300 $this->duration = 0;
301 }
302 if (isset($this->ref_client)) {
303 $this->ref_client = trim($this->ref_client);
304 }
305
306 if ($this->socid <= 0) {
307 $this->error = 'ErrorFicheinterCompanyDoesNotExist';
308 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
309 return -1;
310 }
311 $this->entity = setEntity($this);
312
313 $soc = new Societe($this->db);
314 $result = $soc->fetch($this->socid);
315
316 $now = dol_now();
317
318 $this->db->begin();
319
320 $sql = "INSERT INTO ".MAIN_DB_PREFIX."fichinter (";
321 $sql .= "fk_soc";
322 $sql .= ", datec";
323 $sql .= ", ref";
324 $sql .= ", ref_client";
325 $sql .= ", entity";
326 $sql .= ", fk_user_author";
327 $sql .= ", fk_user_modif";
328 $sql .= ", description";
329 $sql .= ", model_pdf";
330 $sql .= ", fk_projet";
331 $sql .= ", fk_contrat";
332 $sql .= ", fk_statut";
333 $sql .= ", signed_status";
334 $sql .= ", note_private";
335 $sql .= ", note_public";
336 $sql .= ") ";
337 $sql .= " VALUES (";
338 $sql .= $this->socid;
339 $sql .= ", '".$this->db->idate($now)."'";
340 $sql .= ", '".$this->db->escape($this->ref)."'";
341 $sql .= ", ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
342 $sql .= ", ".((int) $this->entity);
343 $sql .= ", ".((int) $user->id);
344 $sql .= ", ".((int) $user->id);
345 $sql .= ", ".($this->description ? "'".$this->db->escape($this->description)."'" : "null");
346 $sql .= ", '".$this->db->escape($this->model_pdf)."'";
347 $sql .= ", ".((int) $this->fk_project > 0 ? ((int) $this->fk_project) : 0);
348 $sql .= ", ".((int) $this->fk_contrat > 0 ? ((int) $this->fk_contrat) : 0);
349 $sql .= ", ".((int) $this->status);
350 $sql .= ", ".((int) $this->signed_status);
351 $sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
352 $sql .= ", ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
353 $sql .= ")";
354
355 dol_syslog(get_class($this)."::create", LOG_DEBUG);
356 $result = $this->db->query($sql);
357 if ($result) {
358 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."fichinter");
359
360 if ($this->id) {
361 $this->ref = '(PROV'.$this->id.')';
362 $sql = 'UPDATE '.MAIN_DB_PREFIX."fichinter SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".((int) $this->id);
363
364 dol_syslog(get_class($this)."::create", LOG_DEBUG);
365 $resql = $this->db->query($sql);
366 if (!$resql) {
367 $error++;
368 }
369 }
370
371 if (!$error) {
372 $result = $this->insertExtraFields();
373 if ($result < 0) {
374 $error++;
375 }
376 }
377
378 // Add linked object
379 if (!$error && $this->origin && $this->origin_id) {
380 $ret = $this->add_object_linked();
381 if (!$ret) {
382 dol_print_error($this->db);
383 }
384 }
385
386
387 if (!$error && !$notrigger) {
388 // Call trigger
389 $result = $this->call_trigger('FICHINTER_CREATE', $user);
390 if ($result < 0) {
391 $error++;
392 }
393 // End call triggers
394 }
395
396 if (!$error) {
397 $this->db->commit();
398 return $this->id;
399 } else {
400 $this->db->rollback();
401 $this->error = implode(',', $this->errors);
402 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
403 return -1;
404 }
405 } else {
406 $this->error = $this->db->error();
407 $this->db->rollback();
408 return -1;
409 }
410 }
411
419 public function update($user, $notrigger = 0)
420 {
421 global $conf;
422
423 if (!is_numeric($this->duration)) {
424 $this->duration = 0;
425 }
426 if (!dol_strlen((string) $this->fk_project)) {
427 $this->fk_project = 0;
428 }
429 if (isset($this->ref_client)) {
430 $this->ref_client = trim($this->ref_client);
431 }
432
433 $error = 0;
434
435 $this->db->begin();
436
437 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter SET ";
438 $sql .= "description = '".$this->db->escape($this->description)."'";
439 $sql .= ", duree = ".((int) $this->duration);
440 $sql .= ", ref_client = ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
441 if ((int) $this->fk_project > 0) {
442 $sql .= ", fk_projet = ".((int) $this->fk_project);
443 }
444 if (isset($this->datec)) {
445 $sql .= ", datec = ".($this->datec ? "'".$this->db->idate($this->datec)."'" : "null");
446 }
447 if (isset($this->datev)) {
448 $sql .= ", date_valid = ".($this->datev ? "'".$this->db->idate($this->datev)."'" : "null");
449 }
450 if (isset($this->datet)) {
451 $sql .= ", datet = ".($this->datet ? "'".$this->db->idate($this->datet)."'" : "null");
452 }
453 $sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
454 $sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
455 $sql .= ", fk_user_modif = ".((int) $user->id);
456 $sql .= " WHERE rowid = ".((int) $this->id);
457
458 dol_syslog(get_class($this)."::update", LOG_DEBUG);
459 if ($this->db->query($sql)) {
460 if (!$error) {
461 $result = $this->insertExtraFields();
462 if ($result < 0) {
463 $error++;
464 }
465 }
466
467 if (!$error && !$notrigger) {
468 // Call trigger
469 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
470 if ($result < 0) {
471 $error++;
472 $this->db->rollback();
473 return -1;
474 }
475 // End call triggers
476 }
477
478 $this->db->commit();
479 return 1;
480 } else {
481 $this->error = $this->db->error();
482 $this->db->rollback();
483 return -1;
484 }
485 }
486
495 public function fetch($rowid, $ref = '', $ref_ext = '')
496 {
497 $sql = "SELECT f.rowid, f.ref, f.ref_client, f.description, f.fk_soc, f.fk_statut as status, f.signed_status,";
498 $sql .= " f.datec, f.dateo, f.datee, f.datet, f.fk_user_author,";
499 $sql .= " f.date_valid as datev,";
500 $sql .= " f.tms as datem,";
501 $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";
502 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
503 $sql .= " WHERE f.entity IN (".getEntity('intervention').")";
504 if ($ref) {
505 $sql .= " AND f.ref = '".$this->db->escape($ref)."'";
506 } elseif ($ref_ext) {
507 $sql .= " AND f.ref_ext = '".$this->db->escape($ref_ext)."'";
508 } else {
509 $sql .= " AND f.rowid = ".((int) $rowid);
510 }
511
512 $resql = $this->db->query($sql);
513 if ($resql) {
514 if ($this->db->num_rows($resql)) {
515 $obj = $this->db->fetch_object($resql);
516
517 $this->id = $obj->rowid;
518 $this->ref = $obj->ref;
519 $this->ref_client = $obj->ref_client;
520 $this->description = $obj->description;
521 $this->socid = $obj->fk_soc;
522 $this->status = $obj->status;
523 $this->statut = $obj->status; // deprecated
524 $this->signed_status = $obj->signed_status;
525 $this->duration = $obj->duree;
526 $this->datec = $this->db->jdate($obj->datec);
527 $this->dateo = $this->db->jdate($obj->dateo);
528 $this->datee = $this->db->jdate($obj->datee);
529 $this->datet = $this->db->jdate($obj->datet);
530 $this->datev = $this->db->jdate($obj->datev);
531 $this->datem = $this->db->jdate($obj->datem);
532 $this->fk_project = $obj->fk_project;
533 $this->note_public = $obj->note_public;
534 $this->note_private = $obj->note_private;
535 $this->model_pdf = $obj->model_pdf;
536 $this->fk_contrat = $obj->fk_contrat;
537 $this->entity = $obj->entity;
538
539 $this->user_creation_id = $obj->fk_user_author;
540
541 $this->extraparams = is_null($obj->extraparams) ? [] : (array) json_decode($obj->extraparams, true);
542
543 $this->last_main_doc = $obj->last_main_doc;
544
545 // Retrieve extrafields
546 $this->fetch_optionals();
547
548 /*
549 * Lines
550 */
551 $result = $this->fetch_lines();
552 if ($result < 0) {
553 return -3;
554 }
555 $this->db->free($resql);
556 return 1;
557 }
558
559 return 0;
560 } else {
561 $this->error = $this->db->lasterror();
562 return -1;
563 }
564 }
565
572 public function setDraft($user)
573 {
574 $error = 0;
575
576 // Protection
577 if ($this->status <= self::STATUS_DRAFT) {
578 return 0;
579 }
580
581 dol_syslog(get_class($this)."::setDraft", LOG_DEBUG);
582
583 $this->oldcopy = dol_clone($this, 2);
584
585 $this->db->begin();
586
587 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
588 $sql .= " SET fk_statut = ".self::STATUS_DRAFT;
589 $sql .= " WHERE rowid = ".((int) $this->id);
590
591 $resql = $this->db->query($sql);
592 if ($resql) {
593 if (!$error) {
594 // Call trigger
595 $result = $this->call_trigger('FICHINTER_UNVALIDATE', $user);
596 if ($result < 0) {
597 $error++;
598 }
599 }
600
601 if (!$error) {
602 $this->status = self::STATUS_DRAFT;
603 $this->statut = self::STATUS_DRAFT; // deprecated
604 $this->db->commit();
605 return 1;
606 } else {
607 $this->db->rollback();
608 return -1;
609 }
610 } else {
611 $this->db->rollback();
612 $this->error = $this->db->lasterror();
613 return -1;
614 }
615 }
616
624 public function setValid($user, $notrigger = 0)
625 {
626 global $conf;
627 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
628
629 $error = 0;
630
631 if ($this->status != self::STATUS_VALIDATED) {
632 $this->db->begin();
633
634 $now = dol_now();
635
636 // Define new ref
637 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
638 if (empty($this->thirdparty)) { // Not loaded when validated by the API or on closing a ticket
639 $this->fetch_thirdparty();
640 }
641 $num = $this->getNextNumRef($this->thirdparty);
642 } else {
643 $num = $this->ref;
644 }
645 $this->newref = dol_sanitizeFileName($num);
646
647 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
648 $sql .= " SET fk_statut = 1";
649 $sql .= ", ref = '".$this->db->escape($num)."'";
650 $sql .= ", date_valid = '".$this->db->idate($now)."'";
651 $sql .= ", fk_user_valid = ".($user->id > 0 ? (int) $user->id : "null");
652 $sql .= " WHERE rowid = ".((int) $this->id);
653 $sql .= " AND entity IN (".getEntity('intervention').")";
654
655 $sql .= " AND fk_statut = 0";
656
657 dol_syslog(get_class($this)."::setValid", LOG_DEBUG);
658 $resql = $this->db->query($sql);
659 if (!$resql) {
660 dol_print_error($this->db);
661 $error++;
662 }
663
664 if (!$error && !$notrigger) {
665 // Call trigger
666 $result = $this->call_trigger('FICHINTER_VALIDATE', $user);
667 if ($result < 0) {
668 $error++;
669 }
670 // End call triggers
671 }
672
673 if (!$error) {
674 $this->oldref = $this->ref;
675
676 // Rename directory if dir was a temporary ref
677 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
678 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
679
680 // Now we rename also files into index
681 $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)."'";
682 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".((int) $this->entity);
683 $resql = $this->db->query($sql);
684 if (!$resql) {
685 $error++;
686 $this->error = $this->db->lasterror();
687 }
688 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'ficheinter/".$this->db->escape($this->newref)."'";
689 $sql .= " WHERE filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
690 $resql = $this->db->query($sql);
691 if (!$resql) {
692 $error++;
693 $this->error = $this->db->lasterror();
694 }
695
696 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
697 $oldref = dol_sanitizeFileName($this->ref);
698 $newref = dol_sanitizeFileName($num);
699 $dirsource = $conf->ficheinter->dir_output.'/'.$oldref;
700 $dirdest = $conf->ficheinter->dir_output.'/'.$newref;
701 if (!$error && file_exists($dirsource)) {
702 dol_syslog(get_class($this)."::setValid rename dir ".$dirsource." into ".$dirdest);
703
704 if (@rename($dirsource, $dirdest)) {
705 dol_syslog("Rename ok");
706 // Rename docs starting with $oldref with $newref
707 $listoffiles = dol_dir_list($conf->ficheinter->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
708 foreach ($listoffiles as $fileentry) {
709 $dirsource = $fileentry['name'];
710 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
711 $dirsource = $fileentry['path'].'/'.$dirsource;
712 $dirdest = $fileentry['path'].'/'.$dirdest;
713 @rename($dirsource, $dirdest);
714 }
715 }
716 }
717 }
718 }
719
720 // Set new ref and define current status
721 if (!$error) {
722 $this->ref = $num;
724 $this->statut = self::STATUS_VALIDATED; // deprecated
725 $this->date_validation = $now;
726 $this->db->commit();
727 return 1;
728 } else {
729 $this->db->rollback();
730 dol_syslog(get_class($this)."::setValid ".$this->error, LOG_ERR);
731 return -1;
732 }
733 }
734
735 return 0;
736 }
737
745 public function setClose($user, $notrigger = 0)
746 {
747 global $conf;
748
749 $error = 0;
750
751 if ($this->status == self::STATUS_CLOSED) {
752 return 0;
753 } else {
754 $this->db->begin();
755
756 $now = dol_now();
757
758 $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element;
759 $sql .= ' SET fk_statut = ' . self::STATUS_CLOSED . ',';
760 $sql .= " datet = '" . $this->db->idate($now) . "',";
761 $sql .= " fk_user_modif = " . ((int) $user->id);
762 $sql .= " WHERE rowid = " . ((int) $this->id);
763 $sql .= " AND fk_statut > " . self::STATUS_DRAFT;
764 $sql .= " AND entity IN (".getEntity('intervention').")";
765
766 if ($this->db->query($sql)) {
767 if (!$notrigger) {
768 // Call trigger
769 $result = $this->call_trigger('FICHINTER_CLOSE', $user);
770 if ($result < 0) {
771 $error++;
772 }
773 // End call triggers
774 }
775
776 if (!$error) {
778 $this->statut = self::STATUS_CLOSED; // deprecated
779 $this->db->commit();
780 return 1;
781 } else {
782 $this->db->rollback();
783 return -1;
784 }
785 } else {
786 $this->error = $this->db->lasterror();
787 $this->db->rollback();
788 return -1;
789 }
790 }
791 }
792
798 public function getAmount()
799 {
800 $amount = 0;
801
802 $this->author = new User($this->db);
803 $this->author->fetch($this->user_creation_id);
804
805 $thm = $this->author->thm;
806
807 foreach ($this->lines as $line) {
808 $amount += ($line->duration / 60 / 60 * (float) $thm);
809 }
810
811 return (float) price2num($amount, 'MT');
812 }
813
814
826 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
827 {
828 global $conf;
829
830 $outputlangs->load("interventions");
831
832 if (!dol_strlen($modele)) {
833 $modele = 'soleil';
834
835 if (!empty($this->model_pdf)) {
836 $modele = $this->model_pdf;
837 } elseif (getDolGlobalString('FICHEINTER_ADDON_PDF')) {
838 $modele = getDolGlobalString('FICHEINTER_ADDON_PDF');
839 }
840 }
841
842 $modelpath = "core/modules/fichinter/doc/";
843
844 return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
845 }
846
853 public function getLibStatut($mode = 0)
854 {
855 return $this->LibStatut((isset($this->statut) ? $this->statut : $this->status), $mode);
856 }
857
858 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
866 public function LibStatut($status, $mode = 0)
867 {
868 // phpcs:enable
869 global $langs;
870 // Init/load array of translation of status
871 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
872 $langs->load("interventions");
873 $langs->load("propal");
874
875 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
876 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
877 $this->labelStatus[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
878 $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
879 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
880 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
881 $this->labelStatusShort[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
882 $this->labelStatusShort[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
883 }
884
885 $statuscode = 'status'.$status;
886 if ($status == self::STATUS_BILLED || $status == self::STATUS_CLOSED) {
887 $statuscode = 'status6';
888 }
889
890 $signed_label = ' (' . $this->getLibSignedStatus() . ')';
891 $status_label = $this->signed_status ? $this->labelStatus[$status] . $signed_label : $this->labelStatus[$status];
892 $status_label_short = $this->signed_status ? $this->labelStatusShort[$status] . $signed_label : $this->labelStatusShort[$status];
893
894 return dolGetStatus($status_label, $status_label_short, '', $statuscode, $mode);
895 }
896
903 public function getTooltipContentArray($params)
904 {
905 global $langs;
906
907 $langs->load('interventions');
908
909 $datas = [];
910 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("ShowIntervention").'</u>';
911 $datas['picto'] .= ' '.$this->getLibStatut(5);
912 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
913
914 return $datas;
915 }
916
927 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $save_lastsearch_value = -1, $morecss = '')
928 {
929 global $conf, $langs, $hookmanager;
930
931 if (!empty($conf->dol_no_mouse_hover)) {
932 $notooltip = 1; // Force disable tooltips
933 }
934
935 $result = '';
936 $params = [
937 'id' => $this->id,
938 'objecttype' => $this->element,
939 'option' => $option,
940 ];
941 $classfortooltip = 'classfortooltip';
942 $dataparams = '';
943 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
944 $classfortooltip = 'classforajaxtooltip';
945 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
946 $label = '';
947 } else {
948 $label = implode($this->getTooltipContentArray($params));
949 }
950
951 $url = DOL_URL_ROOT.'/fichinter/card.php?id='.$this->id;
952
953 if ($option !== 'nolink') {
954 // Add param to save lastsearch_values or not
955 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
956 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
957 $add_save_lastsearch_values = 1;
958 }
959 if ($add_save_lastsearch_values) {
960 $url .= '&save_lastsearch_values=1';
961 }
962 }
963
964 $linkclose = '';
965 if (empty($notooltip)) {
966 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
967 $label = $langs->trans("ShowIntervention");
968 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
969 }
970 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
971 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
972 } else {
973 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
974 }
975
976 if ($option == 'nolink' || empty($url)) {
977 $linkstart = '<span';
978 } else {
979 $linkstart = '<a href="'.$url.'"';
980 }
981 $linkstart .= $linkclose.'>';
982 if ($option == 'nolink' || empty($url)) {
983 $linkend = '</span>';
984 } else {
985 $linkend = '</a>';
986 }
987
988 $result .= $linkstart;
989 if ($withpicto) {
990 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
991 }
992
993 if ($withpicto != 2) {
994 $result .= $this->ref;
995 }
996
997 $result .= $linkend;
998
999 global $action;
1000 $hookmanager->initHooks(array('interventiondao'));
1001 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1002 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1003 if ($reshook > 0) {
1004 $result = $hookmanager->resPrint;
1005 } else {
1006 $result .= $hookmanager->resPrint;
1007 }
1008
1009 return $result;
1010 }
1011
1012
1020 public function getNextNumRef($soc)
1021 {
1022 global $conf, $db, $langs;
1023 $langs->load("interventions");
1024
1025 if (getDolGlobalString('FICHEINTER_ADDON')) {
1026 $mybool = false;
1027
1028 $file = "mod_" . getDolGlobalString('FICHEINTER_ADDON').".php";
1029 $classname = "mod_" . getDolGlobalString('FICHEINTER_ADDON');
1030
1031 // Include file with class
1032 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1033
1034 foreach ($dirmodels as $reldir) {
1035 $dir = dol_buildpath($reldir."core/modules/fichinter/");
1036
1037 // Load file with numbering class (if found)
1038 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1039 }
1040
1041 if (!$mybool) {
1042 dol_print_error(null, "Failed to include file ".$file);
1043 return '';
1044 }
1045
1046 $obj = new $classname();
1047 '@phan-var-force ModeleNumRefFicheinter $obj';
1048 $numref = "";
1049 $numref = $obj->getNextValue($soc, $this);
1050
1051 if ($numref != "") {
1052 return $numref;
1053 } else {
1054 dol_print_error($db, "Fichinter::getNextNumRef ".$obj->error);
1055 return "";
1056 }
1057 } else {
1058 $langs->load("errors");
1059 print $langs->trans("Error")." ".$langs->trans("Error_FICHEINTER_ADDON_NotDefined");
1060 return "";
1061 }
1062 }
1063
1070 public function info($id)
1071 {
1072 $sql = "SELECT f.rowid,";
1073 $sql .= " f.datec,";
1074 $sql .= " f.tms as date_modification,";
1075 $sql .= " f.date_valid as datev,";
1076 $sql .= " f.fk_user_author,";
1077 $sql .= " f.fk_user_modif as fk_user_modification,";
1078 $sql .= " f.fk_user_valid";
1079 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
1080 $sql .= " WHERE f.rowid = ".((int) $id);
1081
1082 $resql = $this->db->query($sql);
1083 if ($resql) {
1084 if ($this->db->num_rows($resql)) {
1085 $obj = $this->db->fetch_object($resql);
1086
1087 $this->id = $obj->rowid;
1088
1089 $this->date_creation = $this->db->jdate($obj->datec);
1090 $this->date_modification = $this->db->jdate($obj->date_modification);
1091 $this->date_validation = $this->db->jdate($obj->datev);
1092
1093 $this->user_creation_id = $obj->fk_user_author;
1094 $this->user_validation_id = $obj->fk_user_valid;
1095 $this->user_modification_id = $obj->fk_user_modification;
1096 }
1097 $this->db->free($resql);
1098 } else {
1099 dol_print_error($this->db);
1100 }
1101 }
1102
1110 public function delete(User $user, $notrigger = 0)
1111 {
1112 global $conf, $langs;
1113 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1114
1115 $error = 0;
1116
1117 $this->db->begin();
1118
1119 if (!$error && !$notrigger) {
1120 // Call trigger
1121 $result = $this->call_trigger('FICHINTER_DELETE', $user);
1122 if ($result < 0) {
1123 $error++;
1124 $this->db->rollback();
1125 return -1;
1126 }
1127 // End call triggers
1128 }
1129
1130 // Delete linked object
1131 if (!$error) {
1132 $res = $this->deleteObjectLinked();
1133 if ($res < 0) {
1134 $error++;
1135 }
1136 }
1137
1138 // Delete linked contacts
1139 if (!$error) {
1140 $res = $this->delete_linked_contact();
1141 if ($res < 0) {
1142 $this->error = 'ErrorFailToDeleteLinkedContact';
1143 $error++;
1144 }
1145 }
1146
1147 if (!$error) {
1148 $main = MAIN_DB_PREFIX.'fichinterdet';
1149 $ef = $main."_extrafields";
1150 $sql = "DELETE FROM ".$this->db->sanitize($ef)." WHERE fk_object IN (SELECT rowid FROM ".$this->db->sanitize($main)." WHERE fk_fichinter = ".((int) $this->id).")";
1151
1152 $resql = $this->db->query($sql);
1153 if (!$resql) {
1154 $error++;
1155 }
1156 }
1157
1158 if (!$error) {
1159 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet";
1160 $sql .= " 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 // Remove extrafields
1170 $res = $this->deleteExtraFields();
1171 if ($res < 0) {
1172 $error++;
1173 }
1174 }
1175
1176 if (!$error) {
1177 // Delete object
1178 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinter";
1179 $sql .= " WHERE rowid = ".((int) $this->id);
1180
1181 dol_syslog("Fichinter::delete", LOG_DEBUG);
1182 $resql = $this->db->query($sql);
1183 if (!$resql) {
1184 $error++;
1185 }
1186 }
1187
1188 if (!$error) {
1189 // Delete record into ECM index (Note that delete is also done when deleting files with the dol_delete_dir_recursive
1190 $this->deleteEcmFiles(0); // Deleting files physically is done later with the dol_delete_dir_recursive
1191 $this->deleteEcmFiles(1); // Deleting files physically is done later with the dol_delete_dir_recursive
1192
1193 // Remove directory with files
1194 $fichinterref = dol_sanitizeFileName($this->ref);
1195 if ($conf->ficheinter->dir_output && !empty($fichinterref)) {
1196 $dir = $conf->ficheinter->dir_output."/".$fichinterref;
1197 $file = $conf->ficheinter->dir_output."/".$fichinterref."/".$fichinterref.".pdf";
1198 if (file_exists($file)) {
1199 dol_delete_preview($this);
1200
1201 if (!dol_delete_file($file, 0, 0, 0, $this)) { // For triggers
1202 $langs->load("errors");
1203 $this->error = $langs->trans("ErrorFailToDeleteFile", $file);
1204 return 0;
1205 }
1206 }
1207 if (file_exists($dir)) {
1208 if (!dol_delete_dir_recursive($dir)) {
1209 $langs->load("errors");
1210 $this->error = $langs->trans("ErrorFailToDeleteDir", $dir);
1211 return 0;
1212 }
1213 }
1214 }
1215 }
1216
1217 if (!$error) {
1218 $this->db->commit();
1219 return 1;
1220 } else {
1221 $this->db->rollback();
1222 return -1;
1223 }
1224 }
1225
1226 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1234 public function set_date_delivery($user, $delivery_date_receipt)
1235 {
1236 // phpcs:enable
1237 if ($user->hasRight('ficheinter', 'creer')) {
1238 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
1239 $sql .= " SET datei = '".$this->db->idate($delivery_date_receipt)."'";
1240 $sql .= " WHERE rowid = ".((int) $this->id);
1241 $sql .= " AND fk_statut = 0";
1242
1243 if ($this->db->query($sql)) {
1244 $this->date_delivery = $delivery_date_receipt;
1245 $this->delivery_date_receipt = $delivery_date_receipt;
1246 return 1;
1247 } else {
1248 $this->error = $this->db->error();
1249 dol_syslog("Fichinter::set_date_delivery Erreur SQL");
1250 return -1;
1251 }
1252 }
1253
1254 return 0;
1255 }
1256
1257 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1265 public function set_description($user, $description)
1266 {
1267 // phpcs:enable
1268 if ($user->hasRight('ficheinter', 'creer')) {
1269 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1270 $sql .= " SET description = '".$this->db->escape($description)."',";
1271 $sql .= " fk_user_modif = ".((int) $user->id);
1272 $sql .= " WHERE rowid = ".((int) $this->id);
1273
1274 if ($this->db->query($sql)) {
1275 $this->description = $description;
1276 return 1;
1277 } else {
1278 $this->error = $this->db->error();
1279 dol_syslog("Fichinter::set_description Erreur SQL");
1280 return -1;
1281 }
1282 }
1283
1284 return 0;
1285 }
1286
1287
1288 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1296 public function set_contrat($user, $contractid)
1297 {
1298 // phpcs:enable
1299 if ($user->hasRight('ficheinter', 'creer')) {
1300 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1301 $sql .= " SET fk_contrat = ".((int) $contractid);
1302 $sql .= " WHERE rowid = ".((int) $this->id);
1303
1304 if ($this->db->query($sql)) {
1305 $this->fk_contrat = $contractid;
1306 return 1;
1307 } else {
1308 $this->error = $this->db->error();
1309 return -1;
1310 }
1311 }
1312
1313 return -2;
1314 }
1315
1316
1317
1327 public function createFromClone(User $user, $socid = 0, $clone_contacts = false, $clone_notes = false)
1328 {
1329 global $hookmanager, $langs;
1330 $langs->load("errors");
1331
1332 $error = 0;
1333
1334 $this->db->begin();
1335
1336 // get extrafields so they will be clone
1337 foreach ($this->lines as $line) {
1338 $line->fetch_optionals();
1339 }
1340
1341 // Load source object
1342 $objFrom = clone $this;
1343
1344 // Change socid if needed
1345 if (!empty($socid) && $socid != $this->socid) {
1346 $objsoc = new Societe($this->db);
1347
1348 if ($objsoc->fetch($socid) > 0) {
1349 $this->socid = $objsoc->id;
1350 //$this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1351 //$this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1352 $this->fk_project = 0;
1353 $this->fk_delivery_address = 0;
1354 }
1355
1356 // TODO Change product price if multi-prices
1357 }
1358
1359 $this->id = 0;
1360 $this->ref = '';
1361 $this->status = self::STATUS_DRAFT;
1362 $this->statut = self::STATUS_DRAFT; // deprecated
1363
1364 // Clear fields
1365 $this->user_author_id = $user->id;
1366 $this->user_validation_id = 0;
1367 $this->date_creation = '';
1368 $this->date_validation = '';
1369
1370 $this->ref_client = '';
1371
1372 if (!$clone_notes) {
1373 $this->note_private = '';
1374 $this->note_public = '';
1375 }
1376
1377 // Create clone
1378 $this->context['createfromclone'] = 'createfromclone';
1379 $result = $this->create($user);
1380 if ($result < 0) {
1381 $error++;
1382 }
1383
1384 if (!$error) {
1385 // Add lines because it is not included into create function
1386 foreach ($this->lines as $line) {
1387 $this->addline($user, $this->id, $line->desc, $line->datei, $line->duration, $line->array_options);
1388 }
1389
1390 // Hook of thirdparty module
1391 if (is_object($hookmanager)) {
1392 $parameters = array('objFrom' => $objFrom);
1393 $action = '';
1394 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1395 if ($reshook < 0) {
1396 $this->setErrorsFromObject($hookmanager);
1397 $error++;
1398 }
1399 }
1400 }
1401
1402 //Duplicate contact
1403 if ($clone_contacts) {
1404 foreach (array('internal', 'external') as $source) {
1405 $tab = $objFrom->liste_contact(-1, $source);
1406 if (is_array($tab) && count($tab) > 0) {
1407 foreach ($tab as $contacttoadd) {
1408 $retAddContact = $this->add_contact(
1409 $contacttoadd['id'],
1410 $contacttoadd['code'],
1411 $contacttoadd['source']
1412 );
1413 if ($this->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1414 $this->error .= $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType");
1415 $error++;
1416 } elseif ($retAddContact < 0) {
1417 $error++;
1418 }
1419 }
1420 } elseif ($tab < 0) {
1421 $this->error .= $objFrom->error;
1422 $error++;
1423 }
1424 }
1425 }
1426
1427 unset($this->context['createfromclone']);
1428
1429 // End
1430 if (!$error) {
1431 $this->db->commit();
1432 return $this->id;
1433 } else {
1434 $this->db->rollback();
1435 return -1;
1436 }
1437 }
1438
1439
1451 public function addline($user, $fichinterid, $desc, $date_intervention, $duration, $array_options = [])
1452 {
1453 dol_syslog(get_class($this)."::addline $fichinterid, $desc, $date_intervention, $duration");
1454
1455 if ($this->status == self::STATUS_DRAFT) {
1456 $this->db->begin();
1457
1458 // Insertion ligne
1459 $line = new FichinterLigne($this->db);
1460
1461 $line->fk_fichinter = $fichinterid;
1462 $line->desc = $desc;
1463 $line->date = $date_intervention;
1464 $line->datei = $date_intervention; // For backward compatibility
1465 $line->duration = $duration;
1466
1467 if (is_array($array_options) && count($array_options) > 0) {
1468 $line->array_options = $array_options;
1469 }
1470
1471 $result = $line->insert($user);
1472
1473 if ($result >= 0) {
1474 $this->db->commit();
1475 return $line->id;
1476 } else {
1477 $this->error = $this->db->error();
1478 $this->db->rollback();
1479 return -1;
1480 }
1481 }
1482
1483 return 0;
1484 }
1485
1486
1494 public function initAsSpecimen()
1495 {
1496 global $langs;
1497
1498 $now = dol_now();
1499
1500 // Initialise parameters
1501 $this->id = 0;
1502 $this->ref = 'SPECIMEN';
1503 $this->ref_client = 'SPECIMEN CLIENT';
1504 $this->specimen = 1;
1505 $this->socid = 1;
1506 $this->datec = $now;
1507 $this->note_private = 'Private note';
1508 $this->note_public = 'SPECIMEN';
1509 $this->duration = 0;
1510 $nbp = 25;
1511 $xnbp = 0;
1512 while ($xnbp < $nbp) {
1513 $line = new FichinterLigne($this->db);
1514 $line->desc = $langs->trans("Description")." ".$xnbp;
1515 $line->date = ($now - 3600 * (1 + $xnbp));
1516 $line->datei = ($now - 3600 * (1 + $xnbp)); // For backward compatibility
1517 $line->duration = 600;
1518 $line->fk_fichinter = 0;
1519 $this->lines[$xnbp] = $line;
1520 $xnbp++;
1521
1522 $this->duration += $line->duration;
1523 }
1524
1525 return 1;
1526 }
1527
1528 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1534 public function fetch_lines()
1535 {
1536 // phpcs:enable
1537 $this->lines = array();
1538
1539 $sql = "SELECT rowid, fk_fichinter, description, duree, date, rang, extraparams";
1540 $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet";
1541 $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1542 $sql .= " ORDER BY rang ASC, date ASC";
1543
1544 dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG);
1545
1546 $resql = $this->db->query($sql);
1547 if ($resql) {
1548 $num = $this->db->num_rows($resql);
1549 $i = 0;
1550 while ($i < $num) {
1551 $objp = $this->db->fetch_object($resql);
1552
1553 $line = new FichinterLigne($this->db);
1554 $line->id = $objp->rowid;
1555 $line->fk_fichinter = $objp->fk_fichinter;
1556 $line->desc = $objp->description;
1557 $line->duration = $objp->duree;
1558 //For invoicing we calculing hours
1559 $line->qty = round($objp->duree / 3600, 2);
1560 $line->date = $this->db->jdate($objp->date);
1561 $line->datei = $this->db->jdate($objp->date); // For backward compatibility
1562 $line->rang = $objp->rang;
1563 $line->product_type = 1;
1564 $line->fetch_optionals();
1565
1566 $line->extraparams = !empty($objp->extraparams) ? (array) json_decode($objp->extraparams, true) : array();
1567
1568 $this->lines[$i] = $line;
1569 $i++;
1570 }
1571 $this->db->free($resql);
1572
1573 return 1;
1574 } else {
1575 $this->error = $this->db->error();
1576 return -1;
1577 }
1578 }
1579
1588 public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1589 {
1590 $tables = array(
1591 'fichinter'
1592 );
1593
1594 return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1595 }
1596
1605 public function setRefClient($user, $ref_client, $notrigger = 0)
1606 {
1607 // phpcs:enable
1608 if ($user->hasRight('ficheinter', 'creer')) {
1609 $error = 0;
1610
1611 $this->db->begin();
1612
1613 $this->oldcopy = dol_clone($this, 2);
1614
1615 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET ref_client = ".(empty($ref_client) ? 'NULL' : "'".$this->db->escape($ref_client)."'");
1616 $sql .= " WHERE rowid = ".((int) $this->id);
1617
1618 dol_syslog(__METHOD__.' $this->id='.$this->id.', ref_client='.$ref_client, LOG_DEBUG);
1619 $resql = $this->db->query($sql);
1620 if (!$resql) {
1621 $this->errors[] = $this->db->error();
1622 $error++;
1623 }
1624
1625 if (!$error) {
1626 $this->ref_client = $ref_client;
1627 }
1628
1629 if (!$notrigger && empty($error)) {
1630 // Call trigger
1631 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
1632 if ($result < 0) {
1633 $error++;
1634 }
1635 // End call triggers
1636 }
1637
1638 if (!$error) {
1639 $this->db->commit();
1640 return 1;
1641 } else {
1642 foreach ($this->errors as $errmsg) {
1643 dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
1644 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1645 }
1646 $this->db->rollback();
1647 return -1 * $error;
1648 }
1649 } else {
1650 return -1;
1651 }
1652 }
1653
1661 public function getKanbanView($option = '', $arraydata = null)
1662 {
1663 global $langs;
1664
1665 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1666
1667 $return = '<div class="box-flex-item box-flex-grow-zero">';
1668 $return .= '<div class="info-box info-box-sm">';
1669 $return .= '<span class="info-box-icon bg-infobox-action">';
1670 $return .= img_picto('', $this->picto);
1671 $return .= '</span>';
1672 $return .= '<div class="info-box-content">';
1673 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
1674 if ($selected >= 0) {
1675 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1676 }
1677 if (!empty($arraydata['thirdparty'])) {
1678 $tmpthirdparty = $arraydata['thirdparty'];
1679 '@phan-var-force Societe $tmpthirdparty';
1680 $return .= '<br><span class="info-box-label">'.$tmpthirdparty->getNomUrl(1).'</span>';
1681 }
1682 if (property_exists($this, 'duration')) {
1683 $return .= '<br><span class="info-box-label ">'.$langs->trans("Duration").' : '.convertSecondToTime($this->duration, 'allhourmin').'</span>';
1684 }
1685 if (method_exists($this, 'getLibStatut')) {
1686 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1687 }
1688 $return .= '</div>';
1689 $return .= '</div>';
1690 $return .= '</div>';
1691 return $return;
1692 }
1693}
$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.
call_trigger($triggerName, $user)
Call trigger based on this instance.
add_contact($fk_socpeople, $type_contact, $source='external', $notrigger=0)
Add a link between element $this->element and a contact.
Class to manage Dolibarr database access.
const STATUS_BILLED
Billed.
initAsSpecimen()
Initialise an instance with random values.
createFromClone(User $user, $socid=0, $clone_contacts=false, $clone_notes=false)
Load an object from its id and create a new one in database.
getLibStatut($mode=0)
Returns the label status.
update($user, $notrigger=0)
Update an intervention.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
setClose($user, $notrigger=0)
Close intervention.
const STATUS_DRAFT
Draft status.
create($user, $notrigger=0)
Create an intervention into data base.
set_description($user, $description)
Define the label of the intervention.
getTooltipContentArray($params)
getTooltipContentArray
getKanbanView($option='', $arraydata=null)
Return clickable link of object (with eventually picto)
set_date_delivery($user, $delivery_date_receipt)
Defines a delivery date of the receipt of intervention.
addline($user, $fichinterid, $desc, $date_intervention, $duration, $array_options=[])
Adding a line of intervention into data base.
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.
setRefClient($user, $ref_client, $notrigger=0)
Set customer reference number.
set_contrat($user, $contractid)
Link intervention to a contract.
LibStatut($status, $mode=0)
Returns the label of a status.
setValid($user, $notrigger=0)
Validate a intervention.
loadStateBoard()
Load indicators into this->nb for board.
getNomUrl($withpicto=0, $option='', $notooltip=0, $save_lastsearch_value=-1, $morecss='')
Return clickable name (with picto eventually)
__construct($db)
Constructor.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
info($id)
Load information on object.
fetch_lines()
Load array lines ->lines.
Class to manage intervention lines.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:171
getLibSignedStatus(int $mode=0)
Returns the label for signed status.
convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengthOfWeek=7)
Return, in clear text, value of a number of seconds in days, hours and minutes.
Definition date.lib.php:244
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:63
dol_delete_preview($object)
Delete all preview files linked to object instance.
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_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
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($object, $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...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
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.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79