dolibarr 22.0.5
contratligne.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2012 Destailleur Laurent <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2014 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
6 * Copyright (C) 2008 Raphael Bertrand <raphael.bertrand@resultic.fr>
7 * Copyright (C) 2010-2016 Juanjo Menent <jmenent@2byte.es>
8 * Copyright (C) 2013 Christophe Battarel <christophe.battarel@altairis.fr>
9 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
10 * Copyright (C) 2014-2015 Marcos García <marcosgdf@gmail.com>
11 * Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
12 * Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
13 * Copyright (C) 2015-2018 Ferran Marcet <fmarcet@2byte.es>
14 * Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr>
15 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <https://www.gnu.org/licenses/>.
29 */
30
37require_once DOL_DOCUMENT_ROOT."/core/class/commonobjectline.class.php";
38require_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/margin/lib/margins.lib.php';
40
45{
49 public $element = 'contratdet';
50
54 public $table_element = 'contratdet';
55
59 public $parent_element = 'contrat';
60
64 public $fk_parent_attribute = 'fk_contrat';
65
70 public $element_for_permission = 'contrat';
71
75 public $id;
76
80 public $ref;
81
85 public $fk_contrat;
86
90 public $fk_product;
91
95 public $statut;
96
100 public $type;
101
106 public $label;
107
112 public $libelle;
113
117 public $description;
118
122 public $product_type;
123
127 public $product_ref;
128
132 public $product_label;
133
137 public $date_commande;
138
142 public $date_start;
143
147 public $date_start_real;
148
152 public $date_end;
153
157 public $date_end_real;
158
162 public $tva_tx;
163
167 public $vat_src_code;
168
172 public $localtax1_tx;
173
177 public $localtax2_tx;
178
182 public $localtax1_type;
183
187 public $localtax2_type;
188
192 public $qty;
193
197 public $remise_percent;
198
202 public $fk_remise_except;
203
207 public $subprice;
208
212 public $total_ht;
213
217 public $total_tva;
218
222 public $total_localtax1;
223
227 public $total_localtax2;
228
232 public $total_ttc;
233
237 public $fk_fournprice;
238
242 public $pa_ht;
243
247 public $info_bits;
248
252 public $fk_user_author;
253
257 public $fk_user_ouverture;
258
262 public $fk_user_cloture;
263
267 public $commentaire;
268
269
273 public $rang = 0;
274
275
276 const STATUS_INITIAL = 0;
277 const STATUS_OPEN = 4;
278 const STATUS_CLOSED = 5;
279
280
281 // BEGIN MODULEBUILDER PROPERTIES
285 public $fields = array(
286 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
287 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 30, 'index' => 1),
288 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 35),
289 'qty' => array('type' => 'integer', 'label' => 'Quantity', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 35, 'isameasure' => 1),
290 'total_ht' => array('type' => 'integer', 'label' => 'AmountHT', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 36, 'isameasure' => 1),
291 'total_tva' => array('type' => 'integer', 'label' => 'AmountVAT', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 37, 'isameasure' => 1),
292 'total_ttc' => array('type' => 'integer', 'label' => 'AmountTTC', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 38, 'isameasure' => 1),
293 //'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>40),
294 //'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>70),
295 'fk_contrat' => array('type' => 'integer:Contrat:contrat/class/contrat.class.php', 'label' => 'Contract', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 70),
296 'fk_product' => array('type' => 'integer:Product:product/class/product.class.php:1', 'label' => 'Product', 'enabled' => 1, 'visible' => -1, 'position' => 75),
297 //'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>90),
298 'note_private' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 105),
299 'note_public' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 110),
300 //'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>115),
301 //'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>120),
302 //'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
303 'fk_user_ouverture' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserStartingService', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 135),
304 'fk_user_cloture' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserClosingService', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 135),
305 'statut' => array('type' => 'smallint(6)', 'label' => 'Statut', 'enabled' => 1, 'visible' => -1, 'position' => 500, 'arrayofkeyval' => array(0 => 'Draft', 4 => 'Open', 5 => 'Closed')),
306 'rang' => array('type' => 'integer', 'label' => 'Rank', 'enabled' => 1, 'visible' => 0, 'position' => 500, 'default' => '0')
307 );
308 // END MODULEBUILDER PROPERTIES
309
310
316 public function __construct($db)
317 {
318 $this->db = $db;
319 }
320
321
328 public function getLibStatut($mode)
329 {
330 return $this->LibStatut($this->statut, $mode, ((!empty($this->date_end)) ? ($this->date_end < dol_now() ? 1 : 0) : -1));
331 }
332
333 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
344 public static function LibStatut($status, $mode, $expired = -1, $moreatt = '', $morelabel = '')
345 {
346 // phpcs:enable
347 global $langs;
348 $langs->load("contracts");
349
350 if ($status == self::STATUS_INITIAL) {
351 $labelStatus = $langs->transnoentities("ServiceStatusInitial");
352 $labelStatusShort = $langs->transnoentities("ServiceStatusInitial");
353 } elseif ($status == self::STATUS_OPEN && $expired == -1) {
354 $labelStatus = $langs->transnoentities("ServiceStatusRunning");
355 $labelStatusShort = $langs->transnoentities("ServiceStatusRunning");
356 } elseif ($status == self::STATUS_OPEN && $expired == 0) {
357 $labelStatus = $langs->transnoentities("ServiceStatusNotLate");
358 $labelStatusShort = $langs->transnoentities("ServiceStatusNotLateShort");
359 } elseif ($status == self::STATUS_OPEN && $expired == 1) {
360 $labelStatus = $langs->transnoentities("ServiceStatusLate");
361 $labelStatusShort = $langs->transnoentities("ServiceStatusLateShort");
362 } elseif ($status == self::STATUS_CLOSED) {
363 $labelStatus = $langs->transnoentities("ServiceStatusClosed");
364 $labelStatusShort = $langs->transnoentities("ServiceStatusClosed");
365 } else {
366 $labelStatus = '';
367 $labelStatusShort = '';
368 }
369
370 $statusType = 'status'.$status;
371 if ($status == self::STATUS_OPEN && $expired == 1) {
372 $statusType = 'status1';
373 }
374 if ($status == self::STATUS_CLOSED) {
375 $statusType = 'status6';
376 }
377
378 $params = array();
379 $reg = array();
380 if (preg_match('/class="(.*)"/', $moreatt, $reg)) {
381 $params = array('badgeParams' => array('css' => $reg[1]));
382 }
383 return dolGetStatus($labelStatus.($morelabel ? ' '.$morelabel : ''), $labelStatusShort.($morelabel ? ' '.$morelabel : ''), '', $statusType, $mode, '', $params);
384 }
385
392 public function getTooltipContentArray($params)
393 {
394 global $conf, $langs, $user;
395
396 $datas = [];
397 $datas['label'] = $langs->trans("ShowContractOfService").': '.$this->label;
398 if (empty($datas['label'])) {
399 $datas['label'] = $this->description;
400 }
401
402 return $datas;
403 }
404
412 public function getNomUrl($withpicto = 0, $maxlength = 0)
413 {
414 global $langs;
415
416 $result = '';
417 $label = $langs->trans("ShowContractOfService").': '.$this->label;
418 if (empty($label)) {
419 $label = $this->description;
420 }
421 $classfortooltip = 'classfortooltip';
422 $dataparams = '';
423 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
424 $params = [
425 'id' => $this->fk_contrat,
426 'objecttype' => $this->element,
427 ];
428 $classfortooltip = 'classforajaxtooltip';
429 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
430 $label = '';
431 }
432
433 $link = '<a href="'.DOL_URL_ROOT.'/contrat/card.php?id='.$this->fk_contrat.'"';
434 $link .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
435 $link .= $dataparams.' class="'.$classfortooltip.'">';
436 $linkend = '</a>';
437
438 $picto = 'service';
439 if ($this->type == 0) {
440 $picto = 'product';
441 }
442
443 if ($withpicto) {
444 $result .= ($link.img_object($label, $picto, $dataparams.' class="'.$classfortooltip.'"').$linkend);
445 }
446 if ($withpicto && $withpicto != 2) {
447 $result .= ' ';
448 }
449 if ($withpicto != 2) {
450 $result .= $link.($this->product_ref ? $this->product_ref.' ' : '').($this->label ? $this->label : $this->description).$linkend;
451 }
452 return $result;
453 }
454
462 public function fetch($id, $ref = '')
463 {
464 // Check parameters
465 if (empty($id) && empty($ref)) {
466 return -1;
467 }
468
469 $sql = "SELECT";
470 $sql .= " t.rowid,";
471 $sql .= " t.tms,";
472 $sql .= " t.fk_contrat,";
473 $sql .= " t.fk_product,";
474 $sql .= " t.statut,";
475 $sql .= " t.label,"; // This field is not used. Only label of product
476 $sql .= " p.ref as product_ref,";
477 $sql .= " p.label as product_label,";
478 $sql .= " p.description as product_description,";
479 $sql .= " p.fk_product_type as product_type,";
480 $sql .= " t.description,";
481 $sql .= " t.date_commande,";
482 $sql .= " t.date_ouverture_prevue as date_start,";
483 $sql .= " t.date_ouverture as date_start_real,";
484 $sql .= " t.date_fin_validite as date_end,";
485 $sql .= " t.date_cloture as date_end_real,";
486 $sql .= " t.tva_tx,";
487 $sql .= " t.vat_src_code,";
488 $sql .= " t.localtax1_tx,";
489 $sql .= " t.localtax2_tx,";
490 $sql .= " t.localtax1_type,";
491 $sql .= " t.localtax2_type,";
492 $sql .= " t.qty,";
493 $sql .= " t.remise_percent,";
494 $sql .= " t.fk_remise_except,";
495 $sql .= " t.subprice,";
496 $sql .= " t.total_ht,";
497 $sql .= " t.total_tva,";
498 $sql .= " t.total_localtax1,";
499 $sql .= " t.total_localtax2,";
500 $sql .= " t.total_ttc,";
501 $sql .= " t.fk_product_fournisseur_price as fk_fournprice,";
502 $sql .= " t.buy_price_ht as pa_ht,";
503 $sql .= " t.info_bits,";
504 $sql .= " t.fk_user_author,";
505 $sql .= " t.fk_user_ouverture,";
506 $sql .= " t.fk_user_cloture,";
507 $sql .= " t.commentaire,";
508 $sql .= " t.fk_unit,";
509 $sql .= " t.extraparams,";
510 $sql .= " t.rang";
511 $sql .= " FROM ".MAIN_DB_PREFIX."contratdet as t LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = t.fk_product";
512 if ($id) {
513 $sql .= " WHERE t.rowid = ".((int) $id);
514 }
515 if ($ref) {
516 $sql .= " WHERE t.rowid = '".$this->db->escape($ref)."'";
517 }
518
519 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
520 $resql = $this->db->query($sql);
521 if ($resql) {
522 if ($this->db->num_rows($resql)) {
523 $obj = $this->db->fetch_object($resql);
524
525 $this->id = $obj->rowid;
526 $this->ref = $obj->rowid;
527
528 $this->tms = $this->db->jdate($obj->tms);
529 $this->fk_contrat = $obj->fk_contrat;
530 $this->fk_product = $obj->fk_product;
531 $this->statut = $obj->statut;
532 $this->product_ref = $obj->product_ref;
533 $this->product_label = $obj->product_label;
534 $this->product_type = $obj->product_type;
535 $this->label = $obj->label; // deprecated. We do not use this field. Only ref and label of product, and description of contract line
536 $this->description = $obj->description;
537 $this->date_commande = $this->db->jdate($obj->date_commande);
538
539 $this->date_start = $this->db->jdate($obj->date_start);
540 $this->date_start_real = $this->db->jdate($obj->date_start_real);
541 $this->date_end = $this->db->jdate($obj->date_end);
542 $this->date_end_real = $this->db->jdate($obj->date_end_real);
543 // For backward compatibility
544 //$this->date_ouverture_prevue = $this->db->jdate($obj->date_ouverture_prevue);
545 //$this->date_ouverture = $this->db->jdate($obj->date_ouverture);
546 //$this->date_fin_validite = $this->db->jdate($obj->date_fin_validite);
547 //$this->date_cloture = $this->db->jdate($obj->date_cloture);
548
549 $this->tva_tx = $obj->tva_tx;
550 $this->vat_src_code = $obj->vat_src_code;
551 $this->localtax1_tx = $obj->localtax1_tx;
552 $this->localtax2_tx = $obj->localtax2_tx;
553 $this->localtax1_type = $obj->localtax1_type;
554 $this->localtax2_type = $obj->localtax2_type;
555 $this->qty = $obj->qty;
556 $this->remise_percent = $obj->remise_percent;
557 $this->fk_remise_except = $obj->fk_remise_except;
558 $this->subprice = $obj->subprice;
559 $this->total_ht = $obj->total_ht;
560 $this->total_tva = $obj->total_tva;
561 $this->total_localtax1 = $obj->total_localtax1;
562 $this->total_localtax2 = $obj->total_localtax2;
563 $this->total_ttc = $obj->total_ttc;
564 $this->info_bits = $obj->info_bits;
565 $this->fk_user_author = $obj->fk_user_author;
566 $this->fk_user_ouverture = $obj->fk_user_ouverture;
567 $this->fk_user_cloture = $obj->fk_user_cloture;
568 $this->commentaire = $obj->commentaire;
569 $this->fk_fournprice = $obj->fk_fournprice;
570
571 $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->fk_fournprice, $obj->pa_ht);
572 $this->pa_ht = $marginInfos[0];
573 $this->fk_unit = $obj->fk_unit;
574
575 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams, true) : array();
576
577 $this->rang = $obj->rang;
578
579 $this->fetch_optionals();
580 }
581
582 $this->db->free($resql);
583
584 return 1;
585 } else {
586 $this->error = "Error ".$this->db->lasterror();
587 return -1;
588 }
589 }
590
591
599 public function update($user, $notrigger = 0)
600 {
601 global $mysoc;
602
603 $error = 0;
604
605 // Clean parameters
606 $this->fk_contrat = (int) $this->fk_contrat;
607 $this->fk_product = (int) $this->fk_product;
608 $this->statut = (int) $this->statut;
609 $this->label = trim($this->label);
610 $this->description = trim($this->description);
611 $this->vat_src_code = trim($this->vat_src_code);
612 $this->tva_tx = trim((string) $this->tva_tx);
613 $this->localtax1_tx = trim($this->localtax1_tx);
614 $this->localtax2_tx = trim($this->localtax2_tx);
615 $this->qty = (float) $this->qty;
616 $this->remise_percent = trim((string) $this->remise_percent);
617 $this->fk_remise_except = (int) $this->fk_remise_except;
618 $this->subprice = (float) price2num($this->subprice);
619 $this->info_bits = (int) $this->info_bits;
620 $this->fk_user_author = (int) $this->fk_user_author;
621 $this->fk_user_ouverture = (int) $this->fk_user_ouverture;
622 $this->fk_user_cloture = (int) $this->fk_user_cloture;
623 $this->commentaire = trim($this->commentaire);
624 $this->rang = (int) $this->rang;
625 if (empty($this->subprice)) {
626 $this->subprice = 0;
627 }
628 if (empty($this->total_ht)) {
629 $this->total_ht = 0;
630 }
631 if (empty($this->total_tva)) {
632 $this->total_tva = 0;
633 }
634 if (empty($this->total_ttc)) {
635 $this->total_ttc = 0;
636 }
637 if (empty($this->localtax1_tx)) {
638 $this->localtax1_tx = 0;
639 }
640 if (empty($this->localtax2_tx)) {
641 $this->localtax2_tx = 0;
642 }
643 if (empty($this->remise_percent)) {
644 $this->remise_percent = 0;
645 }
646
647 // Calcul du total TTC et de la TVA pour la ligne a partir de
648 // qty, pu, remise_percent et txtva
649 // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
650 // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
651 $localtaxes_type = getLocalTaxesFromRate($this->tva_tx, 0, $this->thirdparty, $mysoc);
652
653 $tabprice = calcul_price_total($this->qty, $this->subprice, $this->remise_percent, (float) $this->tva_tx, $this->localtax1_tx, $this->localtax2_tx, 0, 'HT', 0, 1, $mysoc, $localtaxes_type);
654 $this->total_ht = (float) $tabprice[0];
655 $this->total_tva = (float) $tabprice[1];
656 $this->total_ttc = (float) $tabprice[2];
657 $this->total_localtax1 = (float) $tabprice[9];
658 $this->total_localtax2 = (float) $tabprice[10];
659
660 if (empty($this->pa_ht)) {
661 $this->pa_ht = 0;
662 }
663
664 // if buy price not defined, define buyprice as configured in margin admin
665 if ($this->pa_ht == 0) {
666 $result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product);
667 if ($result < 0) {
668 return -1;
669 } else {
670 $this->pa_ht = $result;
671 }
672 }
673
674 // $this->oldcopy should have been set by the caller of update (here properties were already modified)
675 if (empty($this->oldcopy)) {
676 dol_syslog("this->oldcopy should have been set by the caller of update (here properties were already modified)", LOG_WARNING);
677 $this->oldcopy = dol_clone($this, 2);
678 }
679
680 $this->db->begin();
681
682 // Update request
683 $sql = "UPDATE ".MAIN_DB_PREFIX."contratdet SET";
684 $sql .= " fk_contrat = ".((int) $this->fk_contrat).",";
685 $sql .= " fk_product = ".($this->fk_product ? ((int) $this->fk_product) : 'null').",";
686 $sql .= " statut = ".((int) $this->statut).",";
687 $sql .= " label = '".$this->db->escape($this->label)."',";
688 $sql .= " description = '".$this->db->escape($this->description)."',";
689 $sql .= " date_commande = ".($this->date_commande != '' ? "'".$this->db->idate($this->date_commande)."'" : "null").",";
690 $sql .= " date_ouverture_prevue = ".($this->date_start != '' ? "'".$this->db->idate($this->date_start)."'" : "null").",";
691 $sql .= " date_ouverture = ".($this->date_start_real != '' ? "'".$this->db->idate($this->date_start_real)."'" : "null").",";
692 $sql .= " date_fin_validite = ".($this->date_end != '' ? "'".$this->db->idate($this->date_end)."'" : "null").",";
693 $sql .= " date_cloture = ".($this->date_end_real != '' ? "'".$this->db->idate($this->date_end_real)."'" : "null").",";
694 $sql .= " vat_src_code = '".$this->db->escape($this->vat_src_code)."',";
695 $sql .= " tva_tx = ".price2num($this->tva_tx).",";
696 $sql .= " localtax1_tx = ".price2num($this->localtax1_tx).",";
697 $sql .= " localtax2_tx = ".price2num($this->localtax2_tx).",";
698 $sql .= " qty = ".price2num($this->qty).",";
699 $sql .= " remise_percent = ".price2num($this->remise_percent).",";
700 $sql .= " fk_remise_except = ".($this->fk_remise_except > 0 ? $this->fk_remise_except : "null").",";
701 $sql .= " subprice = ".($this->subprice != '' ? $this->subprice : "null").",";
702 $sql .= " total_ht = ".((float) $this->total_ht).",";
703 $sql .= " total_tva = ".((float) $this->total_tva).",";
704 $sql .= " total_localtax1 = ".((float) $this->total_localtax1).",";
705 $sql .= " total_localtax2 = ".((float) $this->total_localtax2).",";
706 $sql .= " total_ttc = ".((float) $this->total_ttc).",";
707 $sql .= " fk_product_fournisseur_price = ".(!empty($this->fk_fournprice) ? $this->fk_fournprice : "NULL").",";
708 $sql .= " buy_price_ht = '".price2num($this->pa_ht)."',";
709 $sql .= " info_bits = '".$this->db->escape((string) $this->info_bits)."',";
710 $sql .= " fk_user_author = ".($this->fk_user_author >= 0 ? $this->fk_user_author : "NULL").",";
711 $sql .= " fk_user_ouverture = ".($this->fk_user_ouverture > 0 ? $this->fk_user_ouverture : "NULL").",";
712 $sql .= " fk_user_cloture = ".($this->fk_user_cloture > 0 ? $this->fk_user_cloture : "NULL").",";
713 $sql .= " commentaire = '".$this->db->escape($this->commentaire)."',";
714 $sql .= " fk_unit = ".(!$this->fk_unit ? 'NULL' : $this->fk_unit).",";
715 $sql .= " rang = ".(empty($this->rang) ? '0' : (int) $this->rang);
716 $sql .= " WHERE rowid = ".((int) $this->id);
717
718 dol_syslog(get_class($this)."::update", LOG_DEBUG);
719 $resql = $this->db->query($sql);
720 if (!$resql) {
721 $this->error = "Error ".$this->db->lasterror();
722 $error++;
723 }
724
725 if (!$error) { // For avoid conflicts if trigger used
726 $result = $this->insertExtraFields();
727 if ($result < 0) {
728 $error++;
729 }
730 }
731
732 // If we change a planned date (start or end) of one contract line, sync dates for all other services too
733 if (!$error && getDolGlobalString('CONTRACT_SYNC_PLANNED_DATE_OF_SERVICES')) {
734 dol_syslog(get_class($this)."::update CONTRACT_SYNC_PLANNED_DATE_OF_SERVICES is on so we update date for all lines", LOG_DEBUG);
735
736 if ($this->date_start != $this->oldcopy->date_start) {
737 $sql = 'UPDATE '.MAIN_DB_PREFIX.'contratdet SET';
738 $sql .= " date_ouverture_prevue = ".($this->date_start != '' ? "'".$this->db->idate($this->date_start)."'" : "null");
739 $sql .= " WHERE fk_contrat = ".((int) $this->fk_contrat);
740
741 $resql = $this->db->query($sql);
742 if (!$resql) {
743 $error++;
744 $this->error = "Error ".$this->db->lasterror();
745 }
746 }
747 if ($this->date_end != $this->oldcopy->date_end) {
748 $sql = 'UPDATE '.MAIN_DB_PREFIX.'contratdet SET';
749 $sql .= " date_fin_validite = ".($this->date_end != '' ? "'".$this->db->idate($this->date_end)."'" : "null");
750 $sql .= " WHERE fk_contrat = ".((int) $this->fk_contrat);
751
752 $resql = $this->db->query($sql);
753 if (!$resql) {
754 $error++;
755 $this->error = "Error ".$this->db->lasterror();
756 }
757 }
758 }
759
760 if (!$error && !$notrigger) {
761 // Call trigger
762 $result = $this->call_trigger('LINECONTRACT_MODIFY', $user);
763 if ($result < 0) {
764 $error++;
765 $this->db->rollback();
766 }
767 // End call triggers
768 }
769
770 if (!$error) {
771 $this->db->commit();
772 return 1;
773 } else {
774 $this->db->rollback();
775 $this->errors[] = $this->error;
776 return -1;
777 }
778 }
779
780
781 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
788 public function update_total()
789 {
790 // phpcs:enable
791 $this->db->begin();
792
793 // Mise a jour ligne en base
794 $sql = "UPDATE ".MAIN_DB_PREFIX."contratdet SET";
795 $sql .= " total_ht=".price2num($this->total_ht, 'MT');
796 $sql .= ",total_tva=".price2num($this->total_tva, 'MT');
797 $sql .= ",total_localtax1=".price2num($this->total_localtax1, 'MT');
798 $sql .= ",total_localtax2=".price2num($this->total_localtax2, 'MT');
799 $sql .= ",total_ttc=".price2num($this->total_ttc, 'MT');
800 $sql .= " WHERE rowid = ".((int) $this->id);
801
802 dol_syslog(get_class($this)."::update_total", LOG_DEBUG);
803
804 $resql = $this->db->query($sql);
805 if ($resql) {
806 $this->db->commit();
807 return 1;
808 } else {
809 $this->error = $this->db->error();
810 $this->db->rollback();
811 return -2;
812 }
813 }
814
815
822 public function insert($notrigger = 0)
823 {
824 global $user;
825
826 $error = 0;
827
828 // Insertion dans la base
829 $sql = "INSERT INTO ".MAIN_DB_PREFIX."contratdet";
830 $sql .= " (fk_contrat, label, description, fk_product, qty, vat_src_code, tva_tx,";
831 $sql .= " localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, remise_percent, subprice,";
832 $sql .= " total_ht, total_tva, total_localtax1, total_localtax2, total_ttc,";
833 $sql .= " info_bits,";
834 $sql .= " rang,";
835 $sql .= " fk_product_fournisseur_price, buy_price_ht";
836 if ($this->date_start > 0) {
837 $sql .= ",date_ouverture_prevue";
838 }
839 if ($this->date_end > 0) {
840 $sql .= ",date_fin_validite";
841 }
842 $sql .= ") VALUES ($this->fk_contrat, '', '".$this->db->escape($this->description)."',";
843 $sql .= ($this->fk_product > 0 ? $this->fk_product : "null").",";
844 $sql .= " '".$this->db->escape((string) $this->qty)."',";
845 $sql .= " '".$this->db->escape($this->vat_src_code)."',";
846 $sql .= " '".$this->db->escape($this->tva_tx)."',";
847 $sql .= " '".$this->db->escape($this->localtax1_tx)."',";
848 $sql .= " '".$this->db->escape($this->localtax2_tx)."',";
849 $sql .= " '".$this->db->escape($this->localtax1_type)."',";
850 $sql .= " '".$this->db->escape($this->localtax2_type)."',";
851 $sql .= " ".price2num($this->remise_percent).",".price2num($this->subprice).",";
852 $sql .= " ".price2num($this->total_ht).",".price2num($this->total_tva).",".price2num($this->total_localtax1).",".price2num($this->total_localtax2).",".price2num($this->total_ttc).",";
853 $sql .= " '".$this->db->escape((string) $this->info_bits)."',";
854 $sql .= " ".(empty($this->rang) ? '0' : (int) $this->rang).",";
855 if ($this->fk_fournprice > 0) {
856 $sql .= ' '.((int) $this->fk_fournprice).',';
857 } else {
858 $sql .= ' null,';
859 }
860 if ($this->pa_ht > 0) {
861 $sql .= ' '.((float) price2num($this->pa_ht));
862 } else {
863 $sql .= ' null';
864 }
865 if ($this->date_start > 0) {
866 $sql .= ",'".$this->db->idate($this->date_start)."'";
867 }
868 if ($this->date_end > 0) {
869 $sql .= ",'".$this->db->idate($this->date_end)."'";
870 }
871 $sql .= ")";
872
873 dol_syslog(get_class($this)."::insert", LOG_DEBUG);
874
875 $resql = $this->db->query($sql);
876 if ($resql) {
877 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'contratdet');
878
879 // Insert of extrafields
880 if (!$error) {
881 $result = $this->insertExtraFields();
882 if ($result < 0) {
883 $this->db->rollback();
884 return -1;
885 }
886 }
887
888 if (!$notrigger) {
889 // Call trigger
890 $result = $this->call_trigger('LINECONTRACT_INSERT', $user);
891 if ($result < 0) {
892 $this->db->rollback();
893 return -1;
894 }
895 // End call triggers
896 }
897
898 $this->db->commit();
899 return 1;
900 } else {
901 $this->db->rollback();
902 $this->error = $this->db->error()." sql=".$sql;
903 return -1;
904 }
905 }
906
907 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
917 public function active_line($user, $date, $date_end = '', $comment = '')
918 {
919 // phpcs:enable
920 $error = 0;
921
922 $this->db->begin();
923
924 $this->statut = ContratLigne::STATUS_OPEN;
925 $this->date_start_real = $date;
926 $this->date_end = $date_end;
927 $this->fk_user_ouverture = $user->id;
928 $this->date_end_real = null;
929 $this->commentaire = $comment;
930
931 $sql = "UPDATE ".MAIN_DB_PREFIX."contratdet SET statut = ".((int) $this->statut).",";
932 $sql .= " date_ouverture = ".(dol_strlen((string) $this->date_start_real) != 0 ? "'".$this->db->idate($this->date_start_real)."'" : "null").",";
933 if ($date_end >= 0) {
934 $sql .= " date_fin_validite = ".(dol_strlen($this->date_end) != 0 ? "'".$this->db->idate($this->date_end)."'" : "null").",";
935 }
936 $sql .= " fk_user_ouverture = ".((int) $this->fk_user_ouverture).",";
937 $sql .= " date_cloture = null,";
938 $sql .= " commentaire = '".$this->db->escape($comment)."'";
939 $sql .= " WHERE rowid = ".((int) $this->id)." AND (statut = ".ContratLigne::STATUS_INITIAL." OR statut = ".ContratLigne::STATUS_CLOSED.")";
940
941 dol_syslog(get_class($this)."::active_line", LOG_DEBUG);
942 $resql = $this->db->query($sql);
943 if ($resql) {
944 // Call trigger
945 $result = $this->call_trigger('LINECONTRACT_ACTIVATE', $user);
946 if ($result < 0) {
947 $error++;
948 }
949 // End call triggers
950
951 if (!$error) {
952 $this->db->commit();
953 return 1;
954 } else {
955 $this->db->rollback();
956 return -1;
957 }
958 } else {
959 $this->error = $this->db->lasterror();
960 $this->db->rollback();
961 return -1;
962 }
963 }
964
965 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
975 public function close_line($user, $date_end_real, $comment = '', $notrigger = 0)
976 {
977 // phpcs:enable
978 $this->date_cloture = $date_end_real;
979 $this->date_end_real = $date_end_real;
980 $this->user_closing_id = $user->id;
981 $this->commentaire = $comment;
982
983 $error = 0;
984
985 // statut actif : 4
986
987 $this->db->begin();
988
989 $sql = "UPDATE ".MAIN_DB_PREFIX."contratdet SET statut = ".((int) ContratLigne::STATUS_CLOSED).",";
990 $sql .= " date_cloture = '".$this->db->idate($date_end_real)."',";
991 $sql .= " fk_user_cloture = ".((int) $user->id).",";
992 $sql .= " commentaire = '".$this->db->escape($comment)."'";
993 $sql .= " WHERE rowid = ".((int) $this->id)." AND statut <> ".((int) ContratLigne::STATUS_CLOSED);
994
995 $resql = $this->db->query($sql);
996 if ($resql) {
997 if (!$notrigger) {
998 // Call trigger
999 $result = $this->call_trigger('LINECONTRACT_CLOSE', $user);
1000 if ($result < 0) {
1001 $error++;
1002 $this->db->rollback();
1003 return -1;
1004 }
1005 // End call triggers
1006 }
1007
1008 $this->db->commit();
1009 return 1;
1010 } else {
1011 $this->error = $this->db->lasterror();
1012 $this->db->rollback();
1013 return -1;
1014 }
1015 }
1016}
$object ref
Definition info.php:90
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...
defineBuyPrice($unitPrice=0.0, $discountPercent=0.0, $fk_product=0)
Get buy price to use for margin calculation.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
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 lines of contracts.
active_line($user, $date, $date_end='', $comment='')
Activate a contract line.
getLibStatut($mode)
Return label of this contract line status.
insert($notrigger=0)
Inserts a contrat line into database.
fetch($id, $ref='')
Load object in memory from database.
close_line($user, $date_end_real, $comment='', $notrigger=0)
Close a contract line.
static LibStatut($status, $mode, $expired=-1, $moreatt='', $morelabel='')
Return label of a contract line status.
update($user, $notrigger=0)
Update database for contract line.
update_total()
Update in database the fields total_xxx of lines Used by migration process.
__construct($db)
Constructor.
getTooltipContentArray($params)
getTooltipContentArray
getNomUrl($withpicto=0, $maxlength=0)
Return clickable name (with picto eventually) for ContratLigne.
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.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
dol_clone($object, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
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.
getMarginInfos($pv_ht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $pa_ht)
Return an array with margins information of a line.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller=null, $localtaxes_array=[], $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code='')
Calculate totals (net, vat, ...) of a line.
Definition price.lib.php:90
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:158