dolibarr 19.0.3
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-2020 Frédéric France <frederic.france@netlogic.fr>
10 * Copyright (C) 2023 William Mead <william.mead@manchenumerique.fr>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
31require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
32require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
33
34
39{
40 public $fields = array(
41 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
42 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'isModEnabled("societe")', 'visible'=>-1, 'notnull'=>1, 'position'=>15),
43 '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),
44 'fk_contrat' =>array('type'=>'integer', 'label'=>'Fk contrat', 'enabled'=>'$conf->contrat->enabled', 'visible'=>-1, 'position'=>25),
45 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>30),
46 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>35),
47 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'RefCustomer', 'enabled'=>1, 'visible'=>-1, 'position'=>36),
48 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>40, 'index'=>1),
49 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>45),
50 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>50),
51 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>55),
52 'datei' =>array('type'=>'date', 'label'=>'Datei', 'enabled'=>1, 'visible'=>-1, 'position'=>60),
53 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>65),
54 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>70),
55 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>75),
56 'dateo' =>array('type'=>'date', 'label'=>'Dateo', 'enabled'=>1, 'visible'=>-1, 'position'=>85),
57 'datee' =>array('type'=>'date', 'label'=>'Datee', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
58 'datet' =>array('type'=>'date', 'label'=>'Datet', 'enabled'=>1, 'visible'=>-1, 'position'=>95),
59 'duree' =>array('type'=>'double', 'label'=>'Duree', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
60 'description' =>array('type'=>'html', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>105, 'showoncombobox'=>2),
61 'note_private' =>array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>110),
62 'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>115),
63 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>120),
64 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
65 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>130),
66 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>135),
67 'fk_statut' =>array('type'=>'integer', 'label'=>'Fk statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500),
68 );
69
73 public $element = 'fichinter';
74
78 public $table_element = 'fichinter';
79
83 public $fk_element = 'fk_fichinter';
84
88 public $table_element_line = 'fichinterdet';
89
93 public $picto = 'intervention';
94
98 protected $table_ref_field = 'ref';
99
103 public $socid;
104
105 public $author;
106
112 public $datec;
113
114 public $datev;
115 public $dateo;
116 public $datee;
117 public $datet;
118
124 public $datem;
125
129 public $duration;
130
134 public $statut = 0; // 0=draft, 1=validated, 2=invoiced, 3=Terminate
135
139 public $description;
140
144 public $fk_contrat = 0;
145
149 public $fk_project = 0;
150
155 public $ref_client;
156
160 public $extraparams = array();
161
165 public $lines = array();
166
170 const STATUS_DRAFT = 0;
171
176
180 const STATUS_BILLED = 2;
181
185 const STATUS_CLOSED = 3;
186
191 public $date_delivery;
192
197 public $user_author_id;
198
199
205 public function __construct($db)
206 {
207 $this->db = $db;
208 }
209
210 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
216 public function load_state_board()
217 {
218 // phpcs:enable
219 global $user;
220
221 $this->nb = array();
222 $clause = "WHERE";
223
224 $sql = "SELECT count(fi.rowid) as nb";
225 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as fi";
226 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON fi.fk_soc = s.rowid";
227 if (!$user->hasRight('societe', 'client', 'voir') && !$user->socid) {
228 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
229 $sql .= " WHERE sc.fk_user = ".((int) $user->id);
230 $clause = "AND";
231 }
232 $sql .= " ".$clause." fi.entity IN (".getEntity('intervention').")";
233
234 $resql = $this->db->query($sql);
235 if ($resql) {
236 while ($obj = $this->db->fetch_object($resql)) {
237 $this->nb["interventions"] = $obj->nb;
238 }
239 $this->db->free($resql);
240 return 1;
241 } else {
242 dol_print_error($this->db);
243 $this->error = $this->db->error();
244 return -1;
245 }
246 }
247
255 public function create($user, $notrigger = 0)
256 {
257 global $conf, $langs;
258
259 $error = 0;
260
261 dol_syslog(get_class($this)."::create ref=".$this->ref);
262
263 // Check parameters
264 if (!empty($this->ref)) { // We check that ref is not already used
265 $result = self::isExistingObject($this->element, 0, $this->ref); // Check ref is not yet used
266 if ($result > 0) {
267 $this->error = 'ErrorRefAlreadyExists';
268 dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING);
269 $this->db->rollback();
270 return -1;
271 }
272 }
273 if (!is_numeric($this->duration)) {
274 $this->duration = 0;
275 }
276 if (isset($this->ref_client)) {
277 $this->ref_client = trim($this->ref_client);
278 }
279
280 if ($this->socid <= 0) {
281 $this->error = 'ErrorFicheinterCompanyDoesNotExist';
282 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
283 return -1;
284 }
285
286 $soc = new Societe($this->db);
287 $result = $soc->fetch($this->socid);
288
289 $now = dol_now();
290
291 $this->db->begin();
292
293 $sql = "INSERT INTO ".MAIN_DB_PREFIX."fichinter (";
294 $sql .= "fk_soc";
295 $sql .= ", datec";
296 $sql .= ", ref";
297 $sql .= ", ref_client";
298 $sql .= ", entity";
299 $sql .= ", fk_user_author";
300 $sql .= ", fk_user_modif";
301 $sql .= ", description";
302 $sql .= ", model_pdf";
303 $sql .= ", fk_projet";
304 $sql .= ", fk_contrat";
305 $sql .= ", fk_statut";
306 $sql .= ", note_private";
307 $sql .= ", note_public";
308 $sql .= ") ";
309 $sql .= " VALUES (";
310 $sql .= $this->socid;
311 $sql .= ", '".$this->db->idate($now)."'";
312 $sql .= ", '".$this->db->escape($this->ref)."'";
313 $sql .= ", ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
314 $sql .= ", ".((int) $conf->entity);
315 $sql .= ", ".((int) $user->id);
316 $sql .= ", ".((int) $user->id);
317 $sql .= ", ".($this->description ? "'".$this->db->escape($this->description)."'" : "null");
318 $sql .= ", '".$this->db->escape($this->model_pdf)."'";
319 $sql .= ", ".($this->fk_project ? ((int) $this->fk_project) : 0);
320 $sql .= ", ".($this->fk_contrat ? ((int) $this->fk_contrat) : 0);
321 $sql .= ", ".((int) $this->statut);
322 $sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
323 $sql .= ", ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
324 $sql .= ")";
325
326 dol_syslog(get_class($this)."::create", LOG_DEBUG);
327 $result = $this->db->query($sql);
328 if ($result) {
329 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."fichinter");
330
331 if ($this->id) {
332 $this->ref = '(PROV'.$this->id.')';
333 $sql = 'UPDATE '.MAIN_DB_PREFIX."fichinter SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".((int) $this->id);
334
335 dol_syslog(get_class($this)."::create", LOG_DEBUG);
336 $resql = $this->db->query($sql);
337 if (!$resql) {
338 $error++;
339 }
340 }
341
342 if (!$error) {
343 $result = $this->insertExtraFields();
344 if ($result < 0) {
345 $error++;
346 }
347 }
348
349 // Add linked object
350 if (!$error && $this->origin && $this->origin_id) {
351 $ret = $this->add_object_linked();
352 if (!$ret) {
353 dol_print_error($this->db);
354 }
355 }
356
357
358 if (!$error && !$notrigger) {
359 // Call trigger
360 $result = $this->call_trigger('FICHINTER_CREATE', $user);
361 if ($result < 0) {
362 $error++;
363 }
364 // End call triggers
365 }
366
367 if (!$error) {
368 $this->db->commit();
369 return $this->id;
370 } else {
371 $this->db->rollback();
372 $this->error = join(',', $this->errors);
373 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
374 return -1;
375 }
376 } else {
377 $this->error = $this->db->error();
378 $this->db->rollback();
379 return -1;
380 }
381 }
382
390 public function update($user, $notrigger = 0)
391 {
392 global $conf;
393
394 if (!is_numeric($this->duration)) {
395 $this->duration = 0;
396 }
397 if (!dol_strlen($this->fk_project)) {
398 $this->fk_project = 0;
399 }
400 if (isset($this->ref_client)) {
401 $this->ref_client = trim($this->ref_client);
402 }
403
404 $error = 0;
405
406 $this->db->begin();
407
408 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter SET ";
409 $sql .= "description = '".$this->db->escape($this->description)."'";
410 $sql .= ", duree = ".((int) $this->duration);
411 $sql .= ", ref_client = ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null");
412 $sql .= ", fk_projet = ".((int) $this->fk_project);
413 $sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
414 $sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
415 $sql .= ", fk_user_modif = ".((int) $user->id);
416 $sql .= " WHERE rowid = ".((int) $this->id);
417
418 dol_syslog(get_class($this)."::update", LOG_DEBUG);
419 if ($this->db->query($sql)) {
420 if (!$error) {
421 $result = $this->insertExtraFields();
422 if ($result < 0) {
423 $error++;
424 }
425 }
426
427 if (!$error && !$notrigger) {
428 // Call trigger
429 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
430 if ($result < 0) {
431 $error++;
432 $this->db->rollback();
433 return -1;
434 }
435 // End call triggers
436 }
437
438 $this->db->commit();
439 return 1;
440 } else {
441 $this->error = $this->db->error();
442 $this->db->rollback();
443 return -1;
444 }
445 }
446
454 public function fetch($rowid, $ref = '')
455 {
456 $sql = "SELECT f.rowid, f.ref, f.ref_client, f.description, f.fk_soc, f.fk_statut as status,";
457 $sql .= " f.datec, f.dateo, f.datee, f.datet, f.fk_user_author,";
458 $sql .= " f.date_valid as datev,";
459 $sql .= " f.tms as datem,";
460 $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";
461 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
462 if ($ref) {
463 $sql .= " WHERE f.entity IN (".getEntity('intervention').")";
464 $sql .= " AND f.ref = '".$this->db->escape($ref)."'";
465 } else {
466 $sql .= " WHERE f.rowid = ".((int) $rowid);
467 }
468
469 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
470 $resql = $this->db->query($sql);
471 if ($resql) {
472 if ($this->db->num_rows($resql)) {
473 $obj = $this->db->fetch_object($resql);
474
475 $this->id = $obj->rowid;
476 $this->ref = $obj->ref;
477 $this->ref_client = $obj->ref_client;
478 $this->description = $obj->description;
479 $this->socid = $obj->fk_soc;
480 $this->status = $obj->status;
481 $this->statut = $obj->status; // deprecated
482 $this->duration = $obj->duree;
483 $this->datec = $this->db->jdate($obj->datec);
484 $this->dateo = $this->db->jdate($obj->dateo);
485 $this->datee = $this->db->jdate($obj->datee);
486 $this->datet = $this->db->jdate($obj->datet);
487 $this->datev = $this->db->jdate($obj->datev);
488 $this->datem = $this->db->jdate($obj->datem);
489 $this->fk_project = $obj->fk_project;
490 $this->note_public = $obj->note_public;
491 $this->note_private = $obj->note_private;
492 $this->model_pdf = $obj->model_pdf;
493 $this->fk_contrat = $obj->fk_contrat;
494 $this->entity = $obj->entity;
495
496 $this->user_creation_id = $obj->fk_user_author;
497
498 $this->extraparams = (array) json_decode($obj->extraparams, true);
499
500 $this->last_main_doc = $obj->last_main_doc;
501
502 // Retrieve extrafields
503 $this->fetch_optionals();
504
505 /*
506 * Lines
507 */
508 $result = $this->fetch_lines();
509 if ($result < 0) {
510 return -3;
511 }
512 $this->db->free($resql);
513 return 1;
514 }
515
516 return 0;
517 } else {
518 $this->error = $this->db->lasterror();
519 return -1;
520 }
521 }
522
529 public function setDraft($user)
530 {
531 $error = 0;
532
533 // Protection
534 if ($this->statut <= self::STATUS_DRAFT) {
535 return 0;
536 }
537
538 dol_syslog(get_class($this)."::setDraft", LOG_DEBUG);
539
540 $this->oldcopy = dol_clone($this, 2);
541
542 $this->db->begin();
543
544 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
545 $sql .= " SET fk_statut = ".self::STATUS_DRAFT;
546 $sql .= " WHERE rowid = ".((int) $this->id);
547
548 $resql = $this->db->query($sql);
549 if ($resql) {
550 if (!$error) {
551 // Call trigger
552 $result = $this->call_trigger('FICHINTER_UNVALIDATE', $user);
553 if ($result < 0) {
554 $error++;
555 }
556 }
557
558 if (!$error) {
559 $this->statut = self::STATUS_DRAFT;
560 $this->db->commit();
561 return 1;
562 } else {
563 $this->db->rollback();
564 return -1;
565 }
566 } else {
567 $this->db->rollback();
568 $this->error = $this->db->lasterror();
569 return -1;
570 }
571 }
572
580 public function setValid($user, $notrigger = 0)
581 {
582 global $conf;
583 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
584
585 $error = 0;
586
587 if ($this->status != self::STATUS_VALIDATED) {
588 $this->db->begin();
589
590 $now = dol_now();
591
592 // Define new ref
593 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
594 $num = $this->getNextNumRef($this->thirdparty);
595 } else {
596 $num = $this->ref;
597 }
598 $this->newref = dol_sanitizeFileName($num);
599
600 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
601 $sql .= " SET fk_statut = 1";
602 $sql .= ", ref = '".$this->db->escape($num)."'";
603 $sql .= ", date_valid = '".$this->db->idate($now)."'";
604 $sql .= ", fk_user_valid = ".($user->id > 0 ? (int) $user->id : "null");
605 $sql .= " WHERE rowid = ".((int) $this->id);
606 $sql .= " AND entity = ".((int) $this->entity);
607
608 $sql .= " AND fk_statut = 0";
609
610 dol_syslog(get_class($this)."::setValid", LOG_DEBUG);
611 $resql = $this->db->query($sql);
612 if (!$resql) {
613 dol_print_error($this->db);
614 $error++;
615 }
616
617 if (!$error && !$notrigger) {
618 // Call trigger
619 $result = $this->call_trigger('FICHINTER_VALIDATE', $user);
620 if ($result < 0) {
621 $error++;
622 }
623 // End call triggers
624 }
625
626 if (!$error) {
627 $this->oldref = $this->ref;
628
629 // Rename directory if dir was a temporary ref
630 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
631 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
632
633 // Now we rename also files into index
634 $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)."'";
635 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".((int) $this->entity);
636 $resql = $this->db->query($sql);
637 if (!$resql) {
638 $error++;
639 $this->error = $this->db->lasterror();
640 }
641 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'ficheinter/".$this->db->escape($this->newref)."'";
642 $sql .= " WHERE filepath = 'ficheinter/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
643 $resql = $this->db->query($sql);
644 if (!$resql) {
645 $error++;
646 $this->error = $this->db->lasterror();
647 }
648
649 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
650 $oldref = dol_sanitizeFileName($this->ref);
651 $newref = dol_sanitizeFileName($num);
652 $dirsource = $conf->ficheinter->dir_output.'/'.$oldref;
653 $dirdest = $conf->ficheinter->dir_output.'/'.$newref;
654 if (!$error && file_exists($dirsource)) {
655 dol_syslog(get_class($this)."::setValid rename dir ".$dirsource." into ".$dirdest);
656
657 if (@rename($dirsource, $dirdest)) {
658 dol_syslog("Rename ok");
659 // Rename docs starting with $oldref with $newref
660 $listoffiles = dol_dir_list($conf->ficheinter->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
661 foreach ($listoffiles as $fileentry) {
662 $dirsource = $fileentry['name'];
663 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
664 $dirsource = $fileentry['path'].'/'.$dirsource;
665 $dirdest = $fileentry['path'].'/'.$dirdest;
666 @rename($dirsource, $dirdest);
667 }
668 }
669 }
670 }
671 }
672
673 // Set new ref and define current statut
674 if (!$error) {
675 $this->ref = $num;
677 $this->statut = self::STATUS_VALIDATED; // deprecated
678 $this->date_validation = $now;
679 $this->db->commit();
680 return 1;
681 } else {
682 $this->db->rollback();
683 dol_syslog(get_class($this)."::setValid ".$this->error, LOG_ERR);
684 return -1;
685 }
686 }
687
688 return 0;
689 }
690
698 public function setClose($user, $notrigger = 0)
699 {
700 global $conf;
701
702 $error = 0;
703
704 if ($this->statut == self::STATUS_CLOSED) {
705 return 0;
706 } else {
707 $this->db->begin();
708
709 $now = dol_now();
710
711 $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element;
712 $sql .= ' SET fk_statut = ' . self::STATUS_CLOSED . ',';
713 $sql .= " datet = '" . $this->db->idate($now) . "',";
714 $sql .= " fk_user_modif = " . ((int) $user->id);
715 $sql .= " WHERE rowid = " . ((int) $this->id);
716 $sql .= " AND fk_statut > " . self::STATUS_DRAFT;
717 $sql .= " AND entity = " . ((int) $conf->entity);
718
719 if ($this->db->query($sql)) {
720 if (!$notrigger) {
721 // Call trigger
722 $result = $this->call_trigger('FICHINTER_CLOSE', $user);
723 if ($result < 0) {
724 $error++;
725 }
726 // End call triggers
727 }
728
729 if (!$error) {
731 $this->db->commit();
732 return 1;
733 } else {
734 $this->db->rollback();
735 return -1;
736 }
737 } else {
738 $this->error = $this->db->lasterror();
739 $this->db->rollback();
740 return -1;
741 }
742 }
743 }
744
750 public function getAmount()
751 {
752 $amount = 0;
753
754 $this->author = new User($this->db);
755 $this->author->fetch($this->user_creation_id);
756
757 $thm = $this->author->thm;
758
759 foreach ($this->lines as $line) {
760 $amount += ($line->duration / 60 / 60 * $thm);
761 }
762
763 return price2num($amount, 'MT');
764 }
765
766
778 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
779 {
780 global $conf;
781
782 $outputlangs->load("interventions");
783
784 if (!dol_strlen($modele)) {
785 $modele = 'soleil';
786
787 if (!empty($this->model_pdf)) {
788 $modele = $this->model_pdf;
789 } elseif (getDolGlobalString('FICHEINTER_ADDON_PDF')) {
790 $modele = $conf->global->FICHEINTER_ADDON_PDF;
791 }
792 }
793
794 $modelpath = "core/modules/fichinter/doc/";
795
796 return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
797 }
798
805 public function getLibStatut($mode = 0)
806 {
807 return $this->LibStatut((isset($this->statut) ? $this->statut : $this->status), $mode);
808 }
809
810 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
818 public function LibStatut($status, $mode = 0)
819 {
820 // phpcs:enable
821 // Init/load array of translation of status
822 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
823 global $langs;
824 $langs->load("fichinter");
825
826 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
827 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
828 $this->labelStatus[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
829 $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
830 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
831 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
832 $this->labelStatusShort[self::STATUS_BILLED] = $langs->transnoentitiesnoconv('StatusInterInvoiced');
833 $this->labelStatusShort[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Done');
834 }
835
836 $statuscode = 'status'.$status;
837 if ($status == self::STATUS_BILLED || $status == self::STATUS_CLOSED) {
838 $statuscode = 'status6';
839 }
840 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statuscode, $mode);
841 }
842
850 public function getTooltipContentArray($params)
851 {
852 global $conf, $langs;
853
854 $langs->load('fichinter');
855
856 $datas = [];
857 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Intervention").'</u>';
858 if (isset($this->status)) {
859 $datas['picto'] .= ' '.$this->getLibStatut(5);
860 }
861 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
862
863 return $datas;
864 }
865
876 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $save_lastsearch_value = -1, $morecss = '')
877 {
878 global $conf, $langs, $hookmanager;
879
880 if (!empty($conf->dol_no_mouse_hover)) {
881 $notooltip = 1; // Force disable tooltips
882 }
883
884 $result = '';
885 $params = [
886 'id' => $this->id,
887 'objecttype' => $this->element,
888 'option' => $option,
889 ];
890 $classfortooltip = 'classfortooltip';
891 $dataparams = '';
892 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
893 $classfortooltip = 'classforajaxtooltip';
894 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
895 $label = '';
896 } else {
897 $label = implode($this->getTooltipContentArray($params));
898 }
899
900 $url = DOL_URL_ROOT.'/fichinter/card.php?id='.$this->id;
901
902 if ($option !== 'nolink') {
903 // Add param to save lastsearch_values or not
904 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
905 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
906 $add_save_lastsearch_values = 1;
907 }
908 if ($add_save_lastsearch_values) {
909 $url .= '&save_lastsearch_values=1';
910 }
911 }
912
913 $linkclose = '';
914 if (empty($notooltip)) {
915 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
916 $label = $langs->trans("ShowIntervention");
917 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
918 }
919 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
920 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
921 } else {
922 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
923 }
924
925 if ($option == 'nolink' || empty($url)) {
926 $linkstart = '<span';
927 } else {
928 $linkstart = '<a href="'.$url.'"';
929 }
930 $linkstart .= $linkclose.'>';
931 if ($option == 'nolink' || empty($url)) {
932 $linkend = '</span>';
933 } else {
934 $linkend = '</a>';
935 }
936
937 $result .= $linkstart;
938 if ($withpicto) {
939 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
940 }
941
942 if ($withpicto != 2) {
943 $result .= $this->ref;
944 }
945
946 $result .= $linkend;
947
948 global $action;
949 $hookmanager->initHooks(array('interventiondao'));
950 $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
951 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
952 if ($reshook > 0) {
953 $result = $hookmanager->resPrint;
954 } else {
955 $result .= $hookmanager->resPrint;
956 }
957
958 return $result;
959 }
960
961
969 public function getNextNumRef($soc)
970 {
971 global $conf, $db, $langs;
972 $langs->load("interventions");
973
974 if (getDolGlobalString('FICHEINTER_ADDON')) {
975 $mybool = false;
976
977 $file = "mod_" . getDolGlobalString('FICHEINTER_ADDON').".php";
978 $classname = "mod_" . getDolGlobalString('FICHEINTER_ADDON');
979
980 // Include file with class
981 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
982
983 foreach ($dirmodels as $reldir) {
984 $dir = dol_buildpath($reldir."core/modules/fichinter/");
985
986 // Load file with numbering class (if found)
987 $mybool |= @include_once $dir.$file;
988 }
989
990 if ($mybool === false) {
991 dol_print_error('', "Failed to include file ".$file);
992 return '';
993 }
994
995 $obj = new $classname();
996 $numref = "";
997 $numref = $obj->getNextValue($soc, $this);
998
999 if ($numref != "") {
1000 return $numref;
1001 } else {
1002 dol_print_error($db, "Fichinter::getNextNumRef ".$obj->error);
1003 return "";
1004 }
1005 } else {
1006 $langs->load("errors");
1007 print $langs->trans("Error")." ".$langs->trans("Error_FICHEINTER_ADDON_NotDefined");
1008 return "";
1009 }
1010 }
1011
1018 public function info($id)
1019 {
1020 $sql = "SELECT f.rowid,";
1021 $sql .= " f.datec,";
1022 $sql .= " f.tms as date_modification,";
1023 $sql .= " f.date_valid as datev,";
1024 $sql .= " f.fk_user_author,";
1025 $sql .= " f.fk_user_modif as fk_user_modification,";
1026 $sql .= " f.fk_user_valid";
1027 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f";
1028 $sql .= " WHERE f.rowid = ".((int) $id);
1029
1030 $resql = $this->db->query($sql);
1031 if ($resql) {
1032 if ($this->db->num_rows($resql)) {
1033 $obj = $this->db->fetch_object($resql);
1034
1035 $this->id = $obj->rowid;
1036
1037 $this->date_creation = $this->db->jdate($obj->datec);
1038 $this->date_modification = $this->db->jdate($obj->date_modification);
1039 $this->date_validation = $this->db->jdate($obj->datev);
1040
1041 $this->user_creation_id = $obj->fk_user_author;
1042 $this->user_validation_id = $obj->fk_user_valid;
1043 $this->user_modification_id = $obj->fk_user_modification;
1044 }
1045 $this->db->free($resql);
1046 } else {
1047 dol_print_error($this->db);
1048 }
1049 }
1050
1058 public function delete(User $user, $notrigger = 0)
1059 {
1060 global $conf, $langs;
1061 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1062
1063 $error = 0;
1064
1065 $this->db->begin();
1066
1067 if (!$error && !$notrigger) {
1068 // Call trigger
1069 $result = $this->call_trigger('FICHINTER_DELETE', $user);
1070 if ($result < 0) {
1071 $error++;
1072 $this->db->rollback();
1073 return -1;
1074 }
1075 // End call triggers
1076 }
1077
1078 // Delete linked object
1079 if (!$error) {
1080 $res = $this->deleteObjectLinked();
1081 if ($res < 0) {
1082 $error++;
1083 }
1084 }
1085
1086 // Delete linked contacts
1087 if (!$error) {
1088 $res = $this->delete_linked_contact();
1089 if ($res < 0) {
1090 $this->error = 'ErrorFailToDeleteLinkedContact';
1091 $error++;
1092 }
1093 }
1094
1095 if (!$error) {
1096 $main = MAIN_DB_PREFIX.'fichinterdet';
1097 $ef = $main."_extrafields";
1098 $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_fichinter = ".((int) $this->id).")";
1099
1100 $resql = $this->db->query($sql);
1101 if (!$resql) {
1102 $error++;
1103 }
1104 }
1105
1106 if (!$error) {
1107 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet";
1108 $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1109
1110 $resql = $this->db->query($sql);
1111 if (!$resql) {
1112 $error++;
1113 }
1114 }
1115
1116 if (!$error) {
1117 // Remove extrafields
1118 $res = $this->deleteExtraFields();
1119 if ($res < 0) {
1120 $error++;
1121 }
1122 }
1123
1124 if (!$error) {
1125 // Delete object
1126 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinter";
1127 $sql .= " WHERE rowid = ".((int) $this->id);
1128
1129 dol_syslog("Fichinter::delete", LOG_DEBUG);
1130 $resql = $this->db->query($sql);
1131 if (!$resql) {
1132 $error++;
1133 }
1134 }
1135
1136 if (!$error) {
1137 // Delete record into ECM index (Note that delete is also done when deleting files with the dol_delete_dir_recursive
1138 $this->deleteEcmFiles(0); // Deleting files physically is done later with the dol_delete_dir_recursive
1139 $this->deleteEcmFiles(1); // Deleting files physically is done later with the dol_delete_dir_recursive
1140
1141 // Remove directory with files
1142 $fichinterref = dol_sanitizeFileName($this->ref);
1143 if ($conf->ficheinter->dir_output) {
1144 $dir = $conf->ficheinter->dir_output."/".$fichinterref;
1145 $file = $conf->ficheinter->dir_output."/".$fichinterref."/".$fichinterref.".pdf";
1146 if (file_exists($file)) {
1147 dol_delete_preview($this);
1148
1149 if (!dol_delete_file($file, 0, 0, 0, $this)) { // For triggers
1150 $langs->load("errors");
1151 $this->error = $langs->trans("ErrorFailToDeleteFile", $file);
1152 return 0;
1153 }
1154 }
1155 if (file_exists($dir)) {
1156 if (!dol_delete_dir_recursive($dir)) {
1157 $langs->load("errors");
1158 $this->error = $langs->trans("ErrorFailToDeleteDir", $dir);
1159 return 0;
1160 }
1161 }
1162 }
1163 }
1164
1165 if (!$error) {
1166 $this->db->commit();
1167 return 1;
1168 } else {
1169 $this->db->rollback();
1170 return -1;
1171 }
1172 }
1173
1174 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1182 public function set_date_delivery($user, $date_delivery)
1183 {
1184 // phpcs:enable
1185 if ($user->hasRight('ficheinter', 'creer')) {
1186 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1187 $sql .= " SET datei = '".$this->db->idate($date_delivery)."'";
1188 $sql .= " WHERE rowid = ".((int) $this->id);
1189 $sql .= " AND fk_statut = 0";
1190
1191 if ($this->db->query($sql)) {
1192 $this->date_delivery = $date_delivery;
1193 return 1;
1194 } else {
1195 $this->error = $this->db->error();
1196 dol_syslog("Fichinter::set_date_delivery Erreur SQL");
1197 return -1;
1198 }
1199 }
1200
1201 return 0;
1202 }
1203
1204 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1212 public function set_description($user, $description)
1213 {
1214 // phpcs:enable
1215 if ($user->hasRight('ficheinter', 'creer')) {
1216 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1217 $sql .= " SET description = '".$this->db->escape($description)."',";
1218 $sql .= " fk_user_modif = ".$user->id;
1219 $sql .= " WHERE rowid = ".((int) $this->id);
1220
1221 if ($this->db->query($sql)) {
1222 $this->description = $description;
1223 return 1;
1224 } else {
1225 $this->error = $this->db->error();
1226 dol_syslog("Fichinter::set_description Erreur SQL");
1227 return -1;
1228 }
1229 }
1230
1231 return 0;
1232 }
1233
1234
1235 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1243 public function set_contrat($user, $contractid)
1244 {
1245 // phpcs:enable
1246 if ($user->hasRight('ficheinter', 'creer')) {
1247 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter ";
1248 $sql .= " SET fk_contrat = ".((int) $contractid);
1249 $sql .= " WHERE rowid = ".((int) $this->id);
1250
1251 if ($this->db->query($sql)) {
1252 $this->fk_contrat = $contractid;
1253 return 1;
1254 } else {
1255 $this->error = $this->db->error();
1256 return -1;
1257 }
1258 }
1259
1260 return -2;
1261 }
1262
1263
1264
1272 public function createFromClone(User $user, $socid = 0)
1273 {
1274 global $hookmanager;
1275
1276 $error = 0;
1277
1278 $this->db->begin();
1279
1280 // get extrafields so they will be clone
1281 foreach ($this->lines as $line) {
1282 $line->fetch_optionals();
1283 }
1284
1285 // Load source object
1286 $objFrom = clone $this;
1287
1288 // Change socid if needed
1289 if (!empty($socid) && $socid != $this->socid) {
1290 $objsoc = new Societe($this->db);
1291
1292 if ($objsoc->fetch($socid) > 0) {
1293 $this->socid = $objsoc->id;
1294 //$this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1295 //$this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1296 $this->fk_project = '';
1297 $this->fk_delivery_address = '';
1298 }
1299
1300 // TODO Change product price if multi-prices
1301 }
1302
1303 $this->id = 0;
1304 $this->ref = '';
1305 $this->status = self::STATUS_DRAFT;
1306 $this->statut = self::STATUS_DRAFT; // deprecated
1307
1308 // Clear fields
1309 $this->user_author_id = $user->id;
1310 $this->user_validation_id = 0;
1311 $this->date_creation = '';
1312 $this->date_validation = '';
1313
1314 $this->ref_client = '';
1315
1316 // Create clone
1317 $this->context['createfromclone'] = 'createfromclone';
1318 $result = $this->create($user);
1319 if ($result < 0) {
1320 $error++;
1321 }
1322
1323 if (!$error) {
1324 // Add lines because it is not included into create function
1325 foreach ($this->lines as $line) {
1326 $this->addline($user, $this->id, $line->desc, $line->datei, $line->duration, $line->array_options);
1327 }
1328
1329 // Hook of thirdparty module
1330 if (is_object($hookmanager)) {
1331 $parameters = array('objFrom'=>$objFrom);
1332 $action = '';
1333 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1334 if ($reshook < 0) {
1335 $this->setErrorsFromObject($hookmanager);
1336 $error++;
1337 }
1338 }
1339 }
1340
1341 unset($this->context['createfromclone']);
1342
1343 // End
1344 if (!$error) {
1345 $this->db->commit();
1346 return $this->id;
1347 } else {
1348 $this->db->rollback();
1349 return -1;
1350 }
1351 }
1352
1353
1365 public function addline($user, $fichinterid, $desc, $date_intervention, $duration, $array_options = [])
1366 {
1367 dol_syslog(get_class($this)."::addline $fichinterid, $desc, $date_intervention, $duration");
1368
1369 if ($this->status == self::STATUS_DRAFT) {
1370 $this->db->begin();
1371
1372 // Insertion ligne
1373 $line = new FichinterLigne($this->db);
1374
1375 $line->fk_fichinter = $fichinterid;
1376 $line->desc = $desc;
1377 $line->date = $date_intervention;
1378 $line->datei = $date_intervention; // For backward compatibility
1379 $line->duration = $duration;
1380
1381 if (is_array($array_options) && count($array_options) > 0) {
1382 $line->array_options = $array_options;
1383 }
1384
1385 $result = $line->insert($user);
1386
1387 if ($result >= 0) {
1388 $this->db->commit();
1389 return 1;
1390 } else {
1391 $this->error = $this->db->error();
1392 $this->db->rollback();
1393 return -1;
1394 }
1395 }
1396
1397 return 0;
1398 }
1399
1400
1408 public function initAsSpecimen()
1409 {
1410 global $langs;
1411
1412 $now = dol_now();
1413
1414 // Initialise parametres
1415 $this->id = 0;
1416 $this->ref = 'SPECIMEN';
1417 $this->ref_client = 'SPECIMEN CLIENT';
1418 $this->specimen = 1;
1419 $this->socid = 1;
1420 $this->datec = $now;
1421 $this->note_private = 'Private note';
1422 $this->note_public = 'SPECIMEN';
1423 $this->duration = 0;
1424 $nbp = 25;
1425 $xnbp = 0;
1426 while ($xnbp < $nbp) {
1427 $line = new FichinterLigne($this->db);
1428 $line->desc = $langs->trans("Description")." ".$xnbp;
1429 $line->date = ($now - 3600 * (1 + $xnbp));
1430 $line->datei = ($now - 3600 * (1 + $xnbp)); // For backward compatibility
1431 $line->duration = 600;
1432 $line->fk_fichinter = 0;
1433 $this->lines[$xnbp] = $line;
1434 $xnbp++;
1435
1436 $this->duration += $line->duration;
1437 }
1438 }
1439
1440 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1446 public function fetch_lines()
1447 {
1448 // phpcs:enable
1449 $this->lines = array();
1450
1451 $sql = "SELECT rowid, fk_fichinter, description, duree, date, rang";
1452 $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet";
1453 $sql .= " WHERE fk_fichinter = ".((int) $this->id);
1454 $sql .= " ORDER BY rang ASC, date ASC";
1455
1456 dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG);
1457
1458 $resql = $this->db->query($sql);
1459 if ($resql) {
1460 $num = $this->db->num_rows($resql);
1461 $i = 0;
1462 while ($i < $num) {
1463 $objp = $this->db->fetch_object($resql);
1464
1465 $line = new FichinterLigne($this->db);
1466 $line->id = $objp->rowid;
1467 $line->fk_fichinter = $objp->fk_fichinter;
1468 $line->desc = $objp->description;
1469 $line->duration = $objp->duree;
1470 //For invoicing we calculing hours
1471 $line->qty = round($objp->duree / 3600, 2);
1472 $line->date = $this->db->jdate($objp->date);
1473 $line->datei = $this->db->jdate($objp->date); // For backward compatibility
1474 $line->rang = $objp->rang;
1475 $line->product_type = 1;
1476 $line->fetch_optionals();
1477
1478 $this->lines[$i] = $line;
1479 $i++;
1480 }
1481 $this->db->free($resql);
1482
1483 return 1;
1484 } else {
1485 $this->error = $this->db->error();
1486 return -1;
1487 }
1488 }
1489
1498 public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1499 {
1500 $tables = array(
1501 'fichinter'
1502 );
1503
1504 return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1505 }
1506
1515 public function setRefClient($user, $ref_client, $notrigger = 0)
1516 {
1517 // phpcs:enable
1518 if ($user->hasRight('ficheinter', 'creer')) {
1519 $error = 0;
1520
1521 $this->db->begin();
1522
1523 $this->oldcopy = dol_clone($this);
1524
1525 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET ref_client = ".(empty($ref_client) ? 'NULL' : "'".$this->db->escape($ref_client)."'");
1526 $sql .= " WHERE rowid = ".((int) $this->id);
1527
1528 dol_syslog(__METHOD__.' $this->id='.$this->id.', ref_client='.$ref_client, LOG_DEBUG);
1529 $resql = $this->db->query($sql);
1530 if (!$resql) {
1531 $this->errors[] = $this->db->error();
1532 $error++;
1533 }
1534
1535 if (!$error) {
1536 $this->ref_client = $ref_client;
1537 }
1538
1539 if (!$notrigger && empty($error)) {
1540 // Call trigger
1541 $result = $this->call_trigger('FICHINTER_MODIFY', $user);
1542 if ($result < 0) {
1543 $error++;
1544 }
1545 // End call triggers
1546 }
1547
1548 if (!$error) {
1549 $this->db->commit();
1550 return 1;
1551 } else {
1552 foreach ($this->errors as $errmsg) {
1553 dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
1554 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1555 }
1556 $this->db->rollback();
1557 return -1 * $error;
1558 }
1559 } else {
1560 return -1;
1561 }
1562 }
1563
1571 public function getKanbanView($option = '', $arraydata = null)
1572 {
1573 global $langs;
1574
1575 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1576
1577 $return = '<div class="box-flex-item box-flex-grow-zero">';
1578 $return .= '<div class="info-box info-box-sm">';
1579 $return .= '<span class="info-box-icon bg-infobox-action">';
1580 $return .= img_picto('', $this->picto);
1581 $return .= '</span>';
1582 $return .= '<div class="info-box-content">';
1583 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
1584 if ($selected >= 0) {
1585 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1586 }
1587 if (!empty($arraydata['thirdparty'])) {
1588 $tmpthirdparty = $arraydata['thirdparty'];
1589 $return .= '<br><span class="info-box-label">'.$tmpthirdparty->getNomUrl(1).'</span>';
1590 }
1591 if (property_exists($this, 'duration')) {
1592 $return .= '<br><span class="info-box-label ">'.$langs->trans("Duration").' : '.convertSecondToTime($this->duration, 'allhourmin').'</span>';
1593 }
1594 if (method_exists($this, 'getLibStatut')) {
1595 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1596 }
1597 $return .= '</div>';
1598 $return .= '</div>';
1599 $return .= '</div>';
1600 return $return;
1601 }
1602}
1603
1608{
1612 public $db;
1613
1617 public $error = '';
1618
1619 // From llx_fichinterdet
1623 public $fk_fichinter;
1624
1625 public $desc; // Description ligne
1626
1630 public $date; // Date intervention
1635 public $datei; // Date intervention
1636
1637 public $duration; // Duration of intervention
1638 public $rang = 0;
1639 public $tva_tx;
1640 public $subprice;
1641
1645 public $element = 'fichinterdet';
1646
1650 public $table_element = 'fichinterdet';
1651
1655 public $fk_element = 'fk_fichinter';
1656
1657
1658
1664 public function __construct($db)
1665 {
1666 $this->db = $db;
1667 }
1668
1675 public function fetch($rowid)
1676 {
1677 dol_syslog("FichinterLigne::fetch", LOG_DEBUG);
1678
1679 $sql = 'SELECT ft.rowid, ft.fk_fichinter, ft.description, ft.duree, ft.rang, ft.date';
1680 $sql .= ' FROM '.MAIN_DB_PREFIX.'fichinterdet as ft';
1681 $sql .= ' WHERE ft.rowid = '.((int) $rowid);
1682
1683 $resql = $this->db->query($sql);
1684 if ($resql) {
1685 $objp = $this->db->fetch_object($resql);
1686 $this->rowid = $objp->rowid;
1687 $this->id = $objp->rowid;
1688 $this->fk_fichinter = $objp->fk_fichinter;
1689 $this->date = $this->db->jdate($objp->date);
1690 $this->datei = $this->db->jdate($objp->date); // For backward compatibility
1691 $this->desc = $objp->description;
1692 $this->duration = $objp->duree;
1693 $this->rang = $objp->rang;
1694
1695 $this->db->free($resql);
1696
1697 $this->fetch_optionals();
1698
1699 return 1;
1700 } else {
1701 $this->error = $this->db->error().' sql='.$sql;
1702 return -1;
1703 }
1704 }
1705
1713 public function insert($user, $notrigger = 0)
1714 {
1715 $error = 0;
1716
1717 dol_syslog("FichinterLigne::insert rang=".$this->rang);
1718
1719 if (empty($this->date) && !empty($this->datei)) { // For backward compatibility
1720 $this->date = $this->datei;
1721 }
1722
1723 $this->db->begin();
1724
1725 $rangToUse = $this->rang;
1726 if ($rangToUse == -1) {
1727 // Recupere rang max de la ligne d'intervention dans $rangmax
1728 $sql = 'SELECT max(rang) as max FROM '.MAIN_DB_PREFIX.'fichinterdet';
1729 $sql .= ' WHERE fk_fichinter = '.((int) $this->fk_fichinter);
1730 $resql = $this->db->query($sql);
1731 if ($resql) {
1732 $obj = $this->db->fetch_object($resql);
1733 $rangToUse = $obj->max + 1;
1734 } else {
1735 dol_print_error($this->db);
1736 $this->db->rollback();
1737 return -1;
1738 }
1739 }
1740
1741 // Insertion dans base de la ligne
1742 $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'fichinterdet';
1743 $sql .= ' (fk_fichinter, description, date, duree, rang)';
1744 $sql .= " VALUES (".((int) $this->fk_fichinter).",";
1745 $sql .= " '".$this->db->escape($this->desc)."',";
1746 $sql .= " '".$this->db->idate($this->date)."',";
1747 $sql .= " ".((int) $this->duration).",";
1748 $sql .= ' '.((int) $rangToUse);
1749 $sql .= ')';
1750
1751 dol_syslog("FichinterLigne::insert", LOG_DEBUG);
1752 $resql = $this->db->query($sql);
1753 if ($resql) {
1754 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'fichinterdet');
1755 $this->rowid = $this->id;
1756
1757 if (!$error) {
1758 $result = $this->insertExtraFields();
1759 if ($result < 0) {
1760 $error++;
1761 }
1762 }
1763
1764
1765 $result = $this->update_total();
1766
1767 if ($result > 0) {
1768 $this->rang = $rangToUse;
1769
1770 if (!$notrigger) {
1771 // Call trigger
1772 $result = $this->call_trigger('LINEFICHINTER_CREATE', $user);
1773 if ($result < 0) {
1774 $error++;
1775 }
1776 // End call triggers
1777 }
1778 }
1779
1780 if (!$error) {
1781 $this->db->commit();
1782 return $result;
1783 } else {
1784 $this->db->rollback();
1785 return -1;
1786 }
1787 } else {
1788 $this->error = $this->db->error()." sql=".$sql;
1789 $this->db->rollback();
1790 return -1;
1791 }
1792 }
1793
1794
1802 public function update($user, $notrigger = 0)
1803 {
1804 $error = 0;
1805
1806 if (empty($this->date) && !empty($this->datei)) { // For backward compatibility
1807 $this->date = $this->datei;
1808 }
1809
1810 $this->db->begin();
1811
1812 // Mise a jour ligne en base
1813 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinterdet SET";
1814 $sql .= " description = '".$this->db->escape($this->desc)."',";
1815 $sql .= " date = '".$this->db->idate($this->date)."',";
1816 $sql .= " duree = ".((int) $this->duration).",";
1817 $sql .= " rang = ".((int) $this->rang);
1818 $sql .= " WHERE rowid = ".((int) $this->id);
1819
1820 dol_syslog("FichinterLigne::update", LOG_DEBUG);
1821 $resql = $this->db->query($sql);
1822 if ($resql) {
1823 if (!$error) {
1824 $result = $this->insertExtraFields();
1825 if ($result < 0) {
1826 $error++;
1827 }
1828 }
1829
1830 $result = $this->update_total();
1831 if ($result > 0) {
1832 if (!$notrigger) {
1833 // Call trigger
1834 $result = $this->call_trigger('LINEFICHINTER_MODIFY', $user);
1835 if ($result < 0) {
1836 $error++;
1837 }
1838 // End call triggers
1839 }
1840 }
1841
1842 if (!$error) {
1843 $this->db->commit();
1844 return $result;
1845 } else {
1846 $this->error = $this->db->lasterror();
1847 $this->db->rollback();
1848 return -1;
1849 }
1850 } else {
1851 $this->error = $this->db->lasterror();
1852 $this->db->rollback();
1853 return -1;
1854 }
1855 }
1856
1857 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1863 public function update_total()
1864 {
1865 // phpcs:enable
1866 global $conf;
1867
1868 $this->db->begin();
1869
1870 $sql = "SELECT SUM(duree) as total_duration, min(date) as dateo, max(date) as datee ";
1871 $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet";
1872 $sql .= " WHERE fk_fichinter=".((int) $this->fk_fichinter);
1873
1874 dol_syslog("FichinterLigne::update_total", LOG_DEBUG);
1875 $resql = $this->db->query($sql);
1876 if ($resql) {
1877 $obj = $this->db->fetch_object($resql);
1878 $total_duration = 0;
1879 if (!empty($obj->total_duration)) {
1880 $total_duration = $obj->total_duration;
1881 }
1882
1883 $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
1884 $sql .= " SET duree = ".((int) $total_duration);
1885 $sql .= " , dateo = ".(!empty($obj->dateo) ? "'".$this->db->escape($obj->dateo)."'" : "null");
1886 $sql .= " , datee = ".(!empty($obj->datee) ? "'".$this->db->escape($obj->datee)."'" : "null");
1887 $sql .= " WHERE rowid = ".((int) $this->fk_fichinter);
1888
1889 dol_syslog("FichinterLigne::update_total", LOG_DEBUG);
1890 $resql = $this->db->query($sql);
1891 if ($resql) {
1892 $this->db->commit();
1893 return 1;
1894 } else {
1895 $this->error = $this->db->error();
1896 $this->db->rollback();
1897 return -2;
1898 }
1899 } else {
1900 $this->error = $this->db->error();
1901 $this->db->rollback();
1902 return -1;
1903 }
1904 }
1905
1913 public function deleteline($user, $notrigger = 0)
1914 {
1915 $error = 0;
1916
1917 dol_syslog(get_class($this)."::deleteline lineid=".$this->id);
1918
1919 $this->db->begin();
1920
1921 $result = $this->deleteExtraFields();
1922 if ($result < 0) {
1923 $error++;
1924 $this->db->rollback();
1925 return -1;
1926 }
1927
1928 $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet WHERE rowid = ".((int) $this->id);
1929 $resql = $this->db->query($sql);
1930
1931 if ($resql) {
1932 $result = $this->update_total();
1933 if ($result > 0) {
1934 if (!$notrigger) {
1935 // Call trigger
1936 $result = $this->call_trigger('LINEFICHINTER_DELETE', $user);
1937 if ($result < 0) {
1938 $error++;
1939 $this->db->rollback();
1940 return -1;
1941 }
1942 // End call triggers
1943 }
1944
1945 $this->db->commit();
1946 return $result;
1947 } else {
1948 $this->db->rollback();
1949 return -1;
1950 }
1951 } else {
1952 $this->error = $this->db->error()." sql=".$sql;
1953 $this->db->rollback();
1954 return -1;
1955 }
1956 }
1957}
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Definition security.php:604
$object ref
Definition info.php:79
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
deleteEcmFiles($mode=0)
Delete related files of object in database.
add_object_linked($origin=null, $origin_id=null, $f_user=null, $notrigger=0)
Add an object link into llx_element_element.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid=0, $f_user=null, $notrigger=0)
Delete all links between an object $this.
setErrorsFromObject($object)
setErrorsFromObject
static isExistingObject($element, $id, $ref='', $ref_ext='')
Check an object id/ref exists If you don't need/want to instantiate object and just need to know if o...
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.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
Class to manage interventions.
const STATUS_BILLED
Billed.
initAsSpecimen()
Initialise an instance with random values.
getLibStatut($mode=0)
Returns the label status.
update($user, $notrigger=0)
Update an intervention.
createFromClone(User $user, $socid=0)
Load an object from its id and create a new one in database.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
setClose($user, $notrigger=0)
Close intervention.
set_date_delivery($user, $date_delivery)
Defines a delivery date of 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 clicable link of object (with eventually picto)
addline($user, $fichinterid, $desc, $date_intervention, $duration, $array_options=[])
Adding a line of intervention into data base.
const STATUS_VALIDATED
Validated status.
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.
fetch($rowid, $ref='')
Fetch a intervention.
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.
getNomUrl($withpicto=0, $option='', $notooltip=0, $save_lastsearch_value=-1, $morecss='')
Return clicable name (with picto eventually)
load_state_board()
Load indicators into this->nb for board.
__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.
fetch($rowid)
Retrieve the line of intervention.
update_total()
Update total duration into llx_fichinter.
update($user, $notrigger=0)
Update intervention into database.
deleteline($user, $notrigger=0)
Delete a intervention line.
__construct($db)
Constructor.
insert($user, $notrigger=0)
Insert the line into database.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
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:243
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_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
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_dir_list($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:62
dol_delete_preview($object)
Delete all preview files linked to object instance.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
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.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return 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.
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e rowid
Definition invoice.php:1926
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e e e e e statut
Definition invoice.php:1926