dolibarr 21.0.0-alpha
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 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
203 public $remise;
204
208 public $fk_remise_except;
209
214 public $subprice;
215
221 public $price;
222
226 public $price_ht;
227
231 public $total_ht;
232
236 public $total_tva;
237
241 public $total_localtax1;
242
246 public $total_localtax2;
247
251 public $total_ttc;
252
256 public $fk_fournprice;
257
261 public $pa_ht;
262
266 public $info_bits;
267
271 public $fk_user_author;
272
276 public $fk_user_ouverture;
277
281 public $fk_user_cloture;
282
286 public $commentaire;
287
288
292 public $rang = 0;
293
294
295 const STATUS_INITIAL = 0;
296 const STATUS_OPEN = 4;
297 const STATUS_CLOSED = 5;
298
299
300 // BEGIN MODULEBUILDER PROPERTIES
304 public $fields = array(
305 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
306 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 30, 'index' => 1),
307 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 35),
308 'qty' => array('type' => 'integer', 'label' => 'Quantity', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 35, 'isameasure' => 1),
309 'total_ht' => array('type' => 'integer', 'label' => 'AmountHT', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 36, 'isameasure' => 1),
310 'total_tva' => array('type' => 'integer', 'label' => 'AmountVAT', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 37, 'isameasure' => 1),
311 'total_ttc' => array('type' => 'integer', 'label' => 'AmountTTC', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 38, 'isameasure' => 1),
312 //'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>40),
313 //'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>70),
314 'fk_contrat' => array('type' => 'integer:Contrat:contrat/class/contrat.class.php', 'label' => 'Contract', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 70),
315 'fk_product' => array('type' => 'integer:Product:product/class/product.class.php:1', 'label' => 'Product', 'enabled' => 1, 'visible' => -1, 'position' => 75),
316 //'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>90),
317 'note_private' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 105),
318 'note_public' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 110),
319 //'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>115),
320 //'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>120),
321 //'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
322 'fk_user_ouverture' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserStartingService', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 135),
323 'fk_user_cloture' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserClosingService', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 135),
324 'statut' => array('type' => 'smallint(6)', 'label' => 'Statut', 'enabled' => 1, 'visible' => -1, 'position' => 500, 'arrayofkeyval' => array(0 => 'Draft', 4 => 'Open', 5 => 'Closed')),
325 'rang' => array('type' => 'integer', 'label' => 'Rank', 'enabled' => 1, 'visible' => 0, 'position' => 500, 'default' => '0')
326 );
327 // END MODULEBUILDER PROPERTIES
328
329
335 public function __construct($db)
336 {
337 $this->db = $db;
338 }
339
340
347 public function getLibStatut($mode)
348 {
349 return $this->LibStatut($this->statut, $mode, ((!empty($this->date_end)) ? ($this->date_end < dol_now() ? 1 : 0) : -1));
350 }
351
352 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
363 public static function LibStatut($status, $mode, $expired = -1, $moreatt = '', $morelabel = '')
364 {
365 // phpcs:enable
366 global $langs;
367 $langs->load("contracts");
368
369 if ($status == self::STATUS_INITIAL) {
370 $labelStatus = $langs->transnoentities("ServiceStatusInitial");
371 $labelStatusShort = $langs->transnoentities("ServiceStatusInitial");
372 } elseif ($status == self::STATUS_OPEN && $expired == -1) {
373 $labelStatus = $langs->transnoentities("ServiceStatusRunning");
374 $labelStatusShort = $langs->transnoentities("ServiceStatusRunning");
375 } elseif ($status == self::STATUS_OPEN && $expired == 0) {
376 $labelStatus = $langs->transnoentities("ServiceStatusNotLate");
377 $labelStatusShort = $langs->transnoentities("ServiceStatusNotLateShort");
378 } elseif ($status == self::STATUS_OPEN && $expired == 1) {
379 $labelStatus = $langs->transnoentities("ServiceStatusLate");
380 $labelStatusShort = $langs->transnoentities("ServiceStatusLateShort");
381 } elseif ($status == self::STATUS_CLOSED) {
382 $labelStatus = $langs->transnoentities("ServiceStatusClosed");
383 $labelStatusShort = $langs->transnoentities("ServiceStatusClosed");
384 } else {
385 $labelStatus = '';
386 $labelStatusShort = '';
387 }
388
389 $statusType = 'status'.$status;
390 if ($status == self::STATUS_OPEN && $expired == 1) {
391 $statusType = 'status1';
392 }
393 if ($status == self::STATUS_CLOSED) {
394 $statusType = 'status6';
395 }
396
397 $params = array();
398 $reg = array();
399 if (preg_match('/class="(.*)"/', $moreatt, $reg)) {
400 $params = array('badgeParams' => array('css' => $reg[1]));
401 }
402 return dolGetStatus($labelStatus.($morelabel ? ' '.$morelabel : ''), $labelStatusShort.($morelabel ? ' '.$morelabel : ''), '', $statusType, $mode, '', $params);
403 }
404
411 public function getTooltipContentArray($params)
412 {
413 global $conf, $langs, $user;
414
415 $datas = [];
416 $datas['label'] = $langs->trans("ShowContractOfService").': '.$this->label;
417 if (empty($datas['label'])) {
418 $datas['label'] = $this->description;
419 }
420
421 return $datas;
422 }
423
431 public function getNomUrl($withpicto = 0, $maxlength = 0)
432 {
433 global $langs;
434
435 $result = '';
436 $label = $langs->trans("ShowContractOfService").': '.$this->label;
437 if (empty($label)) {
438 $label = $this->description;
439 }
440 $classfortooltip = 'classfortooltip';
441 $dataparams = '';
442 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
443 $params = [
444 'id' => $this->fk_contrat,
445 'objecttype' => $this->element,
446 ];
447 $classfortooltip = 'classforajaxtooltip';
448 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
449 $label = '';
450 }
451
452 $link = '<a href="'.DOL_URL_ROOT.'/contrat/card.php?id='.$this->fk_contrat.'"';
453 $link .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
454 $link .= $dataparams.' class="'.$classfortooltip.'">';
455 $linkend = '</a>';
456
457 $picto = 'service';
458 if ($this->type == 0) {
459 $picto = 'product';
460 }
461
462 if ($withpicto) {
463 $result .= ($link.img_object($label, $picto, $dataparams.' class="'.$classfortooltip.'"').$linkend);
464 }
465 if ($withpicto && $withpicto != 2) {
466 $result .= ' ';
467 }
468 if ($withpicto != 2) {
469 $result .= $link.($this->product_ref ? $this->product_ref.' ' : '').($this->label ? $this->label : $this->description).$linkend;
470 }
471 return $result;
472 }
473
481 public function fetch($id, $ref = '')
482 {
483 // Check parameters
484 if (empty($id) && empty($ref)) {
485 return -1;
486 }
487
488 $sql = "SELECT";
489 $sql .= " t.rowid,";
490 $sql .= " t.tms,";
491 $sql .= " t.fk_contrat,";
492 $sql .= " t.fk_product,";
493 $sql .= " t.statut,";
494 $sql .= " t.label,"; // This field is not used. Only label of product
495 $sql .= " p.ref as product_ref,";
496 $sql .= " p.label as product_label,";
497 $sql .= " p.description as product_desc,";
498 $sql .= " p.fk_product_type as product_type,";
499 $sql .= " t.description,";
500 $sql .= " t.date_commande,";
501 $sql .= " t.date_ouverture_prevue as date_start,";
502 $sql .= " t.date_ouverture as date_start_real,";
503 $sql .= " t.date_fin_validite as date_end,";
504 $sql .= " t.date_cloture as date_end_real,";
505 $sql .= " t.tva_tx,";
506 $sql .= " t.vat_src_code,";
507 $sql .= " t.localtax1_tx,";
508 $sql .= " t.localtax2_tx,";
509 $sql .= " t.localtax1_type,";
510 $sql .= " t.localtax2_type,";
511 $sql .= " t.qty,";
512 $sql .= " t.remise_percent,";
513 $sql .= " t.remise,";
514 $sql .= " t.fk_remise_except,";
515 $sql .= " t.subprice,";
516 $sql .= " t.price_ht,";
517 $sql .= " t.total_ht,";
518 $sql .= " t.total_tva,";
519 $sql .= " t.total_localtax1,";
520 $sql .= " t.total_localtax2,";
521 $sql .= " t.total_ttc,";
522 $sql .= " t.fk_product_fournisseur_price as fk_fournprice,";
523 $sql .= " t.buy_price_ht as pa_ht,";
524 $sql .= " t.info_bits,";
525 $sql .= " t.fk_user_author,";
526 $sql .= " t.fk_user_ouverture,";
527 $sql .= " t.fk_user_cloture,";
528 $sql .= " t.commentaire,";
529 $sql .= " t.fk_unit,";
530 $sql .= " t.rang";
531 $sql .= " FROM ".MAIN_DB_PREFIX."contratdet as t LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = t.fk_product";
532 if ($id) {
533 $sql .= " WHERE t.rowid = ".((int) $id);
534 }
535 if ($ref) {
536 $sql .= " WHERE t.rowid = '".$this->db->escape($ref)."'";
537 }
538
539 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
540 $resql = $this->db->query($sql);
541 if ($resql) {
542 if ($this->db->num_rows($resql)) {
543 $obj = $this->db->fetch_object($resql);
544
545 $this->id = $obj->rowid;
546 $this->ref = $obj->rowid;
547
548 $this->tms = $this->db->jdate($obj->tms);
549 $this->fk_contrat = $obj->fk_contrat;
550 $this->fk_product = $obj->fk_product;
551 $this->statut = $obj->statut;
552 $this->product_ref = $obj->product_ref;
553 $this->product_label = $obj->product_label;
554 $this->product_type = $obj->product_type;
555 $this->label = $obj->label; // deprecated. We do not use this field. Only ref and label of product, and description of contract line
556 $this->description = $obj->description;
557 $this->date_commande = $this->db->jdate($obj->date_commande);
558
559 $this->date_start = $this->db->jdate($obj->date_start);
560 $this->date_start_real = $this->db->jdate($obj->date_start_real);
561 $this->date_end = $this->db->jdate($obj->date_end);
562 $this->date_end_real = $this->db->jdate($obj->date_end_real);
563 // For backward compatibility
564 //$this->date_ouverture_prevue = $this->db->jdate($obj->date_ouverture_prevue);
565 //$this->date_ouverture = $this->db->jdate($obj->date_ouverture);
566 //$this->date_fin_validite = $this->db->jdate($obj->date_fin_validite);
567 //$this->date_cloture = $this->db->jdate($obj->date_cloture);
568
569 $this->tva_tx = $obj->tva_tx;
570 $this->vat_src_code = $obj->vat_src_code;
571 $this->localtax1_tx = $obj->localtax1_tx;
572 $this->localtax2_tx = $obj->localtax2_tx;
573 $this->localtax1_type = $obj->localtax1_type;
574 $this->localtax2_type = $obj->localtax2_type;
575 $this->qty = $obj->qty;
576 $this->remise_percent = $obj->remise_percent;
577 $this->fk_remise_except = $obj->fk_remise_except;
578 $this->subprice = $obj->subprice;
579 $this->price_ht = $obj->price_ht;
580 $this->total_ht = $obj->total_ht;
581 $this->total_tva = $obj->total_tva;
582 $this->total_localtax1 = $obj->total_localtax1;
583 $this->total_localtax2 = $obj->total_localtax2;
584 $this->total_ttc = $obj->total_ttc;
585 $this->info_bits = $obj->info_bits;
586 $this->fk_user_author = $obj->fk_user_author;
587 $this->fk_user_ouverture = $obj->fk_user_ouverture;
588 $this->fk_user_cloture = $obj->fk_user_cloture;
589 $this->commentaire = $obj->commentaire;
590 $this->fk_fournprice = $obj->fk_fournprice;
591
592 $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->fk_fournprice, $obj->pa_ht);
593 $this->pa_ht = $marginInfos[0];
594 $this->fk_unit = $obj->fk_unit;
595
596 $this->rang = $obj->rang;
597
598 $this->fetch_optionals();
599 }
600
601 $this->db->free($resql);
602
603 return 1;
604 } else {
605 $this->error = "Error ".$this->db->lasterror();
606 return -1;
607 }
608 }
609
610
618 public function update($user, $notrigger = 0)
619 {
620 global $mysoc;
621
622 $error = 0;
623
624 // Clean parameters
625 $this->fk_contrat = (int) $this->fk_contrat;
626 $this->fk_product = (int) $this->fk_product;
627 $this->statut = (int) $this->statut;
628 $this->label = trim($this->label);
629 $this->description = trim($this->description);
630 $this->vat_src_code = trim($this->vat_src_code);
631 $this->tva_tx = trim((string) $this->tva_tx);
632 $this->localtax1_tx = trim($this->localtax1_tx);
633 $this->localtax2_tx = trim($this->localtax2_tx);
634 $this->qty = (float) $this->qty;
635 $this->remise_percent = trim((string) $this->remise_percent);
636 $this->fk_remise_except = (int) $this->fk_remise_except;
637 $this->subprice = (float) price2num($this->subprice);
638 $this->price_ht = (float) price2num($this->price_ht);
639 $this->info_bits = (int) $this->info_bits;
640 $this->fk_user_author = (int) $this->fk_user_author;
641 $this->fk_user_ouverture = (int) $this->fk_user_ouverture;
642 $this->fk_user_cloture = (int) $this->fk_user_cloture;
643 $this->commentaire = trim($this->commentaire);
644 $this->rang = (int) $this->rang;
645 //if (empty($this->subprice)) $this->subprice = 0;
646 if (empty($this->price_ht)) {
647 $this->price_ht = 0;
648 }
649 if (empty($this->total_ht)) {
650 $this->total_ht = 0;
651 }
652 if (empty($this->total_tva)) {
653 $this->total_tva = 0;
654 }
655 if (empty($this->total_ttc)) {
656 $this->total_ttc = 0;
657 }
658 if (empty($this->localtax1_tx)) {
659 $this->localtax1_tx = 0;
660 }
661 if (empty($this->localtax2_tx)) {
662 $this->localtax2_tx = 0;
663 }
664 if (empty($this->remise_percent)) {
665 $this->remise_percent = 0;
666 }
667
668 // Calcul du total TTC et de la TVA pour la ligne a partir de
669 // qty, pu, remise_percent et txtva
670 // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
671 // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
672 $localtaxes_type = getLocalTaxesFromRate($this->tva_tx, 0, $this->thirdparty, $mysoc);
673
674 $tabprice = calcul_price_total($this->qty, $this->price_ht, $this->remise_percent, $this->tva_tx, $this->localtax1_tx, $this->localtax2_tx, 0, 'HT', 0, 1, $mysoc, $localtaxes_type);
675 $this->total_ht = $tabprice[0];
676 $this->total_tva = $tabprice[1];
677 $this->total_ttc = $tabprice[2];
678 $this->total_localtax1 = $tabprice[9];
679 $this->total_localtax2 = $tabprice[10];
680
681 if (empty($this->pa_ht)) {
682 $this->pa_ht = 0;
683 }
684
685 // if buy price not defined, define buyprice as configured in margin admin
686 if ($this->pa_ht == 0) {
687 $result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product);
688 if ($result < 0) {
689 return -1;
690 } else {
691 $this->pa_ht = $result;
692 }
693 }
694
695 // $this->oldcopy should have been set by the caller of update (here properties were already modified)
696 if (empty($this->oldcopy)) {
697 dol_syslog("this->oldcopy should have been set by the caller of update (here properties were already modified)", LOG_WARNING);
698 $this->oldcopy = dol_clone($this, 2);
699 }
700
701 $this->db->begin();
702
703 // Update request
704 $sql = "UPDATE ".MAIN_DB_PREFIX."contratdet SET";
705 $sql .= " fk_contrat = ".((int) $this->fk_contrat).",";
706 $sql .= " fk_product = ".($this->fk_product ? ((int) $this->fk_product) : 'null').",";
707 $sql .= " statut = ".((int) $this->statut).",";
708 $sql .= " label = '".$this->db->escape($this->label)."',";
709 $sql .= " description = '".$this->db->escape($this->description)."',";
710 $sql .= " date_commande = ".($this->date_commande != '' ? "'".$this->db->idate($this->date_commande)."'" : "null").",";
711 $sql .= " date_ouverture_prevue = ".($this->date_start != '' ? "'".$this->db->idate($this->date_start)."'" : "null").",";
712 $sql .= " date_ouverture = ".($this->date_start_real != '' ? "'".$this->db->idate($this->date_start_real)."'" : "null").",";
713 $sql .= " date_fin_validite = ".($this->date_end != '' ? "'".$this->db->idate($this->date_end)."'" : "null").",";
714 $sql .= " date_cloture = ".($this->date_end_real != '' ? "'".$this->db->idate($this->date_end_real)."'" : "null").",";
715 $sql .= " vat_src_code = '".$this->db->escape($this->vat_src_code)."',";
716 $sql .= " tva_tx = ".price2num($this->tva_tx).",";
717 $sql .= " localtax1_tx = ".price2num($this->localtax1_tx).",";
718 $sql .= " localtax2_tx = ".price2num($this->localtax2_tx).",";
719 $sql .= " qty = ".price2num($this->qty).",";
720 $sql .= " remise_percent = ".price2num($this->remise_percent).",";
721 $sql .= " remise = ".($this->remise ? price2num($this->remise) : "null").",";
722 $sql .= " fk_remise_except = ".($this->fk_remise_except > 0 ? $this->fk_remise_except : "null").",";
723 $sql .= " subprice = ".($this->subprice != '' ? $this->subprice : "null").",";
724 $sql .= " price_ht = ".($this->price_ht != '' ? $this->price_ht : "null").",";
725 $sql .= " total_ht = ".((float) $this->total_ht).",";
726 $sql .= " total_tva = ".((float) $this->total_tva).",";
727 $sql .= " total_localtax1 = ".((float) $this->total_localtax1).",";
728 $sql .= " total_localtax2 = ".((float) $this->total_localtax2).",";
729 $sql .= " total_ttc = ".((float) $this->total_ttc).",";
730 $sql .= " fk_product_fournisseur_price = ".(!empty($this->fk_fournprice) ? $this->fk_fournprice : "NULL").",";
731 $sql .= " buy_price_ht = '".price2num($this->pa_ht)."',";
732 $sql .= " info_bits = '".$this->db->escape($this->info_bits)."',";
733 $sql .= " fk_user_author = ".($this->fk_user_author >= 0 ? $this->fk_user_author : "NULL").",";
734 $sql .= " fk_user_ouverture = ".($this->fk_user_ouverture > 0 ? $this->fk_user_ouverture : "NULL").",";
735 $sql .= " fk_user_cloture = ".($this->fk_user_cloture > 0 ? $this->fk_user_cloture : "NULL").",";
736 $sql .= " commentaire = '".$this->db->escape($this->commentaire)."',";
737 $sql .= " fk_unit = ".(!$this->fk_unit ? 'NULL' : $this->fk_unit).",";
738 $sql .= " rang = ".(empty($this->rang) ? '0' : (int) $this->rang);
739 $sql .= " WHERE rowid = ".((int) $this->id);
740
741 dol_syslog(get_class($this)."::update", LOG_DEBUG);
742 $resql = $this->db->query($sql);
743 if (!$resql) {
744 $this->error = "Error ".$this->db->lasterror();
745 $error++;
746 }
747
748 if (!$error) { // For avoid conflicts if trigger used
749 $result = $this->insertExtraFields();
750 if ($result < 0) {
751 $error++;
752 }
753 }
754
755 // If we change a planned date (start or end) of one contract line, sync dates for all other services too
756 if (!$error && getDolGlobalString('CONTRACT_SYNC_PLANNED_DATE_OF_SERVICES')) {
757 dol_syslog(get_class($this)."::update CONTRACT_SYNC_PLANNED_DATE_OF_SERVICES is on so we update date for all lines", LOG_DEBUG);
758
759 if ($this->date_start != $this->oldcopy->date_start) {
760 $sql = 'UPDATE '.MAIN_DB_PREFIX.'contratdet SET';
761 $sql .= " date_ouverture_prevue = ".($this->date_start != '' ? "'".$this->db->idate($this->date_start)."'" : "null");
762 $sql .= " WHERE fk_contrat = ".((int) $this->fk_contrat);
763
764 $resql = $this->db->query($sql);
765 if (!$resql) {
766 $error++;
767 $this->error = "Error ".$this->db->lasterror();
768 }
769 }
770 if ($this->date_end != $this->oldcopy->date_end) {
771 $sql = 'UPDATE '.MAIN_DB_PREFIX.'contratdet SET';
772 $sql .= " date_fin_validite = ".($this->date_end != '' ? "'".$this->db->idate($this->date_end)."'" : "null");
773 $sql .= " WHERE fk_contrat = ".((int) $this->fk_contrat);
774
775 $resql = $this->db->query($sql);
776 if (!$resql) {
777 $error++;
778 $this->error = "Error ".$this->db->lasterror();
779 }
780 }
781 }
782
783 if (!$error && !$notrigger) {
784 // Call trigger
785 $result = $this->call_trigger('LINECONTRACT_MODIFY', $user);
786 if ($result < 0) {
787 $error++;
788 $this->db->rollback();
789 }
790 // End call triggers
791 }
792
793 if (!$error) {
794 $this->db->commit();
795 return 1;
796 } else {
797 $this->db->rollback();
798 $this->errors[] = $this->error;
799 return -1;
800 }
801 }
802
803
804 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
811 public function update_total()
812 {
813 // phpcs:enable
814 $this->db->begin();
815
816 // Mise a jour ligne en base
817 $sql = "UPDATE ".MAIN_DB_PREFIX."contratdet SET";
818 $sql .= " total_ht=".price2num($this->total_ht, 'MT');
819 $sql .= ",total_tva=".price2num($this->total_tva, 'MT');
820 $sql .= ",total_localtax1=".price2num($this->total_localtax1, 'MT');
821 $sql .= ",total_localtax2=".price2num($this->total_localtax2, 'MT');
822 $sql .= ",total_ttc=".price2num($this->total_ttc, 'MT');
823 $sql .= " WHERE rowid = ".((int) $this->id);
824
825 dol_syslog(get_class($this)."::update_total", LOG_DEBUG);
826
827 $resql = $this->db->query($sql);
828 if ($resql) {
829 $this->db->commit();
830 return 1;
831 } else {
832 $this->error = $this->db->error();
833 $this->db->rollback();
834 return -2;
835 }
836 }
837
838
845 public function insert($notrigger = 0)
846 {
847 global $user;
848
849 $error = 0;
850
851 // Insertion dans la base
852 $sql = "INSERT INTO ".MAIN_DB_PREFIX."contratdet";
853 $sql .= " (fk_contrat, label, description, fk_product, qty, vat_src_code, tva_tx,";
854 $sql .= " localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, remise_percent, subprice,";
855 $sql .= " total_ht, total_tva, total_localtax1, total_localtax2, total_ttc,";
856 $sql .= " info_bits,";
857 $sql .= " rang,";
858 $sql .= " price_ht, remise, fk_product_fournisseur_price, buy_price_ht";
859 if ($this->date_start > 0) {
860 $sql .= ",date_ouverture_prevue";
861 }
862 if ($this->date_end > 0) {
863 $sql .= ",date_fin_validite";
864 }
865 $sql .= ") VALUES ($this->fk_contrat, '', '".$this->db->escape($this->description)."',";
866 $sql .= ($this->fk_product > 0 ? $this->fk_product : "null").",";
867 $sql .= " '".$this->db->escape($this->qty)."',";
868 $sql .= " '".$this->db->escape($this->vat_src_code)."',";
869 $sql .= " '".$this->db->escape($this->tva_tx)."',";
870 $sql .= " '".$this->db->escape($this->localtax1_tx)."',";
871 $sql .= " '".$this->db->escape($this->localtax2_tx)."',";
872 $sql .= " '".$this->db->escape($this->localtax1_type)."',";
873 $sql .= " '".$this->db->escape($this->localtax2_type)."',";
874 $sql .= " ".price2num($this->remise_percent).",".price2num($this->subprice).",";
875 $sql .= " ".price2num($this->total_ht).",".price2num($this->total_tva).",".price2num($this->total_localtax1).",".price2num($this->total_localtax2).",".price2num($this->total_ttc).",";
876 $sql .= " '".$this->db->escape($this->info_bits)."',";
877 $sql .= " ".(empty($this->rang) ? '0' : (int) $this->rang).",";
878 $sql .= " ".price2num($this->price_ht).",".price2num($this->remise).",";
879 if ($this->fk_fournprice > 0) {
880 $sql .= ' '.((int) $this->fk_fournprice).',';
881 } else {
882 $sql .= ' null,';
883 }
884 if ($this->pa_ht > 0) {
885 $sql .= ' '.((float) price2num($this->pa_ht));
886 } else {
887 $sql .= ' null';
888 }
889 if ($this->date_start > 0) {
890 $sql .= ",'".$this->db->idate($this->date_start)."'";
891 }
892 if ($this->date_end > 0) {
893 $sql .= ",'".$this->db->idate($this->date_end)."'";
894 }
895 $sql .= ")";
896
897 dol_syslog(get_class($this)."::insert", LOG_DEBUG);
898
899 $resql = $this->db->query($sql);
900 if ($resql) {
901 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'contratdet');
902
903 // Insert of extrafields
904 if (!$error) {
905 $result = $this->insertExtraFields();
906 if ($result < 0) {
907 $this->db->rollback();
908 return -1;
909 }
910 }
911
912 if (!$notrigger) {
913 // Call trigger
914 $result = $this->call_trigger('LINECONTRACT_INSERT', $user);
915 if ($result < 0) {
916 $this->db->rollback();
917 return -1;
918 }
919 // End call triggers
920 }
921
922 $this->db->commit();
923 return 1;
924 } else {
925 $this->db->rollback();
926 $this->error = $this->db->error()." sql=".$sql;
927 return -1;
928 }
929 }
930
931 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
941 public function active_line($user, $date, $date_end = '', $comment = '')
942 {
943 // phpcs:enable
944 $error = 0;
945
946 $this->db->begin();
947
948 $this->statut = ContratLigne::STATUS_OPEN;
949 $this->date_start_real = $date;
950 $this->date_end = $date_end;
951 $this->fk_user_ouverture = $user->id;
952 $this->date_end_real = null;
953 $this->commentaire = $comment;
954
955 $sql = "UPDATE ".MAIN_DB_PREFIX."contratdet SET statut = ".((int) $this->statut).",";
956 $sql .= " date_ouverture = ".(dol_strlen((string) $this->date_start_real) != 0 ? "'".$this->db->idate($this->date_start_real)."'" : "null").",";
957 if ($date_end >= 0) {
958 $sql .= " date_fin_validite = ".(dol_strlen($this->date_end) != 0 ? "'".$this->db->idate($this->date_end)."'" : "null").",";
959 }
960 $sql .= " fk_user_ouverture = ".((int) $this->fk_user_ouverture).",";
961 $sql .= " date_cloture = null,";
962 $sql .= " commentaire = '".$this->db->escape($comment)."'";
963 $sql .= " WHERE rowid = ".((int) $this->id)." AND (statut = ".ContratLigne::STATUS_INITIAL." OR statut = ".ContratLigne::STATUS_CLOSED.")";
964
965 dol_syslog(get_class($this)."::active_line", LOG_DEBUG);
966 $resql = $this->db->query($sql);
967 if ($resql) {
968 // Call trigger
969 $result = $this->call_trigger('LINECONTRACT_ACTIVATE', $user);
970 if ($result < 0) {
971 $error++;
972 }
973 // End call triggers
974
975 if (!$error) {
976 $this->db->commit();
977 return 1;
978 } else {
979 $this->db->rollback();
980 return -1;
981 }
982 } else {
983 $this->error = $this->db->lasterror();
984 $this->db->rollback();
985 return -1;
986 }
987 }
988
989 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
999 public function close_line($user, $date_end_real, $comment = '', $notrigger = 0)
1000 {
1001 // phpcs:enable
1002 $this->date_cloture = $date_end_real;
1003 $this->date_end_real = $date_end_real;
1004 $this->user_closing_id = $user->id;
1005 $this->commentaire = $comment;
1006
1007 $error = 0;
1008
1009 // statut actif : 4
1010
1011 $this->db->begin();
1012
1013 $sql = "UPDATE ".MAIN_DB_PREFIX."contratdet SET statut = ".((int) ContratLigne::STATUS_CLOSED).",";
1014 $sql .= " date_cloture = '".$this->db->idate($date_end_real)."',";
1015 $sql .= " fk_user_cloture = ".((int) $user->id).",";
1016 $sql .= " commentaire = '".$this->db->escape($comment)."'";
1017 $sql .= " WHERE rowid = ".((int) $this->id)." AND statut = ".((int) ContratLigne::STATUS_OPEN);
1018
1019 $resql = $this->db->query($sql);
1020 if ($resql) {
1021 if (!$notrigger) {
1022 // Call trigger
1023 $result = $this->call_trigger('LINECONTRACT_CLOSE', $user);
1024 if ($result < 0) {
1025 $error++;
1026 $this->db->rollback();
1027 return -1;
1028 }
1029 // End call triggers
1030 }
1031
1032 $this->db->commit();
1033 return 1;
1034 } else {
1035 $this->error = $this->db->lasterror();
1036 $this->db->rollback();
1037 return -1;
1038 }
1039 }
1040}
$object ref
Definition info.php:79
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.
dol_clone($object, $native=0)
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.
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller='', $localtaxes_array=[], $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code='')
Calculate totals (net, vat, ...) of a line.
Definition price.lib.php:88
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:137