[ Index ]
 

Code source de Dolibarr 2.0.1

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/htdocs/ -> facture.class.php (source)

   1  <?php
   2  /* Copyright (C) 2002-2005 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
   3   * Copyright (C) 2004-2005 Laurent Destailleur   <eldy@users.sourceforge.net>
   4   * Copyright (C) 2004      Sebastien Di Cintio   <sdicintio@ressource-toi.org>
   5   * Copyright (C) 2004      Benoit Mortier        <benoit.mortier@opensides.be>
   6   * Copyright (C)      2005 Marc Barilley / Ocebo <marc@ocebo.com>
   7   *
   8   * This program is free software; you can redistribute it and/or modify
   9   * it under the terms of the GNU General Public License as published by
  10   * the Free Software Foundation; either version 2 of the License, or
  11   * (at your option) any later version.
  12   *
  13   * This program is distributed in the hope that it will be useful,
  14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16   * GNU General Public License for more details.
  17   *
  18   * You should have received a copy of the GNU General Public License
  19   * along with this program; if not, write to the Free Software
  20   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21   *
  22   * $Id: facture.class.php,v 1.136 2005/12/17 14:28:56 eldy Exp $
  23   * $Source: /cvsroot/dolibarr/dolibarr/htdocs/facture.class.php,v $
  24   */
  25  
  26  /**
  27          \file       htdocs/facture.class.php
  28          \ingroup    facture
  29          \brief      Fichier de la classe des factures clients
  30          \version    $Revision: 1.136 $
  31  */
  32  
  33  require_once (DOL_DOCUMENT_ROOT .'/notify.class.php');
  34  require_once (DOL_DOCUMENT_ROOT ."/product.class.php");
  35  
  36  
  37  /**
  38      \class      Facture
  39      \brief      Classe permettant la gestion des factures clients
  40  */
  41  
  42  class Facture
  43  {
  44      var $id;
  45      var $db;
  46      var $socidp;
  47      var $number;
  48      var $author;
  49      var $date;
  50      var $ref;
  51      var $amount;
  52      var $remise;
  53      var $tva;
  54      var $total;
  55      var $note;
  56      var $paye;
  57      var $propalid;
  58      var $projetid;
  59      var $cond_reglement_id;
  60      var $cond_reglement_code;
  61      var $mode_reglement_id;
  62      var $mode_reglement_code;
  63  
  64      /**
  65      *    \brief  Constructeur de la classe
  66      *    \param  DB          handler accès base de données
  67      *    \param  soc_idp     id societe ('' par defaut)
  68      *    \param  facid       id facture ('' par defaut)
  69      */
  70  	function Facture($DB, $soc_idp='', $facid='')
  71      {
  72          $this->db = $DB ;
  73  
  74          $this->id = $facid;
  75          $this->socidp = $soc_idp;
  76  
  77          $this->amount = 0;
  78          $this->remise = 0;
  79          $this->remise_percent = 0;
  80          $this->tva = 0;
  81          $this->total = 0;
  82          $this->propalid = 0;
  83          $this->projetid = 0;
  84          $this->remise_exceptionnelle = 0;
  85  
  86          $this->products = array();        // Tableau de lignes de factures
  87      }
  88  
  89      /**
  90       *    \brief      Création de la facture en base
  91       *    \param      user       object utilisateur qui crée
  92       */
  93  	function create($user)
  94      {
  95          global $langs,$conf;
  96          $this->db->begin();
  97  
  98          /* On positionne en mode brouillon la facture */
  99          $this->brouillon = 1;
 100  
 101          /* Facture récurrente */
 102          if ($this->fac_rec > 0)
 103          {
 104              require_once  DOL_DOCUMENT_ROOT . '/compta/facture/facture-rec.class.php';
 105              $_facrec = new FactureRec($this->db, $this->fac_rec);
 106              $_facrec->fetch($this->fac_rec);
 107  
 108              $this->projetid          = $_facrec->projetid;
 109              $this->cond_reglement    = $_facrec->cond_reglement_id;
 110              $this->cond_reglement_id = $_facrec->cond_reglement_id;
 111              $this->mode_reglement    = $_facrec->mode_reglement_id;
 112              $this->mode_reglement_id = $_facrec->mode_reglement_id;
 113              $this->amount            = $_facrec->amount;
 114              $this->remise            = $_facrec->remise;
 115              $this->remise_percent    = $_facrec->remise_percent;
 116          }
 117  
 118          // Definition de la date limite
 119          $datelim=$this->calculate_date_lim_reglement();
 120  
 121          /*
 122           *  Insertion dans la base
 123           */
 124          $socid = $this->socidp;
 125          $number = $this->number;
 126          $amount = $this->amount;
 127          $remise = $this->remise;
 128  
 129          if (! $remise) $remise = 0 ;
 130          if (strlen($this->mode_reglement_id)==0) $this->mode_reglement_id = 0;
 131          if (! $this->projetid) $this->projetid = 'NULL';
 132  
 133          $totalht = ($amount - $remise);
 134  // NE ME SEMBLE PLUS JUSTIFIE ICI
 135  //         $tva = tva($totalht);
 136  //         $total = $totalht + $tva;
 137  
 138          $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facture (facnumber, fk_soc, datec, amount, remise, remise_percent';
 139          $sql .= ', datef, note, fk_user_author, fk_projet';
 140          $sql .= ', fk_cond_reglement, fk_mode_reglement, date_lim_reglement, ref_client) ';
 141          $sql .= " VALUES ('$number','$socid', now(), '$totalht', '$remise'";
 142          $sql .= ",'$this->remise_percent', ".$this->db->idate($this->date);
 143          $sql .= ",'".addslashes($this->note)."',$user->id, $this->projetid";
 144          $sql .= ','.$this->cond_reglement_id.','.$this->mode_reglement_id.','.$this->db->idate($datelim).', \''.$this->ref_client.'\')';
 145          if ( $this->db->query($sql) )
 146          {
 147              $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture');
 148  
 149              $sql = 'UPDATE '.MAIN_DB_PREFIX."facture SET facnumber='(PROV".$this->id.")' WHERE rowid=".$this->id;
 150              $this->db->query($sql);
 151  
 152              if ($this->id && $this->propalid)
 153              {
 154                  $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'fa_pr (fk_facture, fk_propal) VALUES ('.$this->id.','.$this->propalid.')';
 155                  $this->db->query($sql);
 156              }
 157              if ($this->id && $this->commandeid)
 158              {
 159                  $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'co_fa (fk_facture, fk_commande) VALUES ('.$this->id.','.$this->commandeid.')';
 160                  $this->db->query($sql);
 161              }
 162  
 163              /*
 164              * Produits/services
 165              *
 166              */
 167              for ($i = 0 ; $i < sizeof($this->products) ; $i++)
 168              {
 169                  $prod = new Product($this->db, $this->products[$i]);
 170                  $prod->fetch($this->products[$i]);
 171  
 172                  $result_insert = $this->addline($this->id,
 173                      $prod->libelle,
 174                      $prod->price,
 175                      $this->products_qty[$i],
 176                      $prod->tva_tx,
 177                      $this->products[$i],
 178                      $this->products_remise_percent[$i],
 179                      $this->products_date_start[$i],
 180                      $this->products_date_end[$i]
 181                  );
 182  
 183                  if ( $result_insert < 0)
 184                  {
 185                      dolibarr_print_error($this->db);
 186                  }
 187              }
 188  
 189              /*
 190              * Produits de la facture récurrente
 191              *
 192              */
 193              if ($this->fac_rec > 0)
 194              {
 195                  for ($i = 0 ; $i < sizeof($_facrec->lignes) ; $i++)
 196                  {
 197                      if ($_facrec->lignes[$i]->produit_id)
 198                      {
 199                          $prod = new Product($this->db, $_facrec->lignes[$i]->produit_id);
 200                          $prod->fetch($_facrec->lignes[$i]->produit_id);
 201                      }
 202  
 203                      $result_insert = $this->addline($this->id,
 204                      addslashes($_facrec->lignes[$i]->desc),
 205                      $_facrec->lignes[$i]->subprice,
 206                      $_facrec->lignes[$i]->qty,
 207                      $_facrec->lignes[$i]->tva_taux,
 208                      $_facrec->lignes[$i]->produit_id,
 209                      $_facrec->lignes[$i]->remise_percent);
 210  
 211                      if ( $result_insert < 0)
 212                      {
 213                          dolibarr_print_error($this->db);
 214                      }
 215                  }
 216              }
 217  
 218              $resql=$this->updateprice($this->id);
 219              if ($resql)
 220              {
 221                  // Appel des triggers
 222                  include_once (DOL_DOCUMENT_ROOT . "/interfaces.class.php");
 223                  $interface=new Interfaces($this->db);
 224                  $result=$interface->run_triggers('BILL_CREATE',$this,$user,$langs,$conf);
 225                  // Fin appel triggers
 226      
 227                  $this->db->commit();
 228                  return $this->id;
 229              }
 230              else
 231              {
 232                  $this->db->rollback();
 233                  return -2;
 234              }
 235          }
 236          else
 237          {
 238              $this->db->rollback();
 239              return -1;
 240          }
 241      }
 242  
 243  
 244      /*
 245       *       \brief      Affecte la remise exceptionnelle
 246       */
 247  	function _affect_remise_exceptionnelle()
 248      {
 249          $error = 0;
 250  
 251          $this->db->begin();
 252  
 253          if ($this->remise_exceptionnelle[1] > 0)
 254          {
 255              // Calcul valeur de remise a appliquer (remise) et reliquat
 256              if ($this->remise_exceptionnelle[1] > ($this->total_ht * 0.9))
 257              {
 258                  $remise = floor($this->total_ht * 0.9);
 259                  $reliquat = $this->remise_exceptionnelle[1] - $remise;
 260              }
 261              else
 262              {
 263                  $remise = $this->remise_exceptionnelle[1];
 264                  $reliquat=0;
 265              }
 266  
 267              $result_insert = $this->addline($this->id,
 268                  addslashes('Remise exceptionnelle'),
 269                  (0 - $remise),
 270                  1,
 271                  '0');   // Une remise est un négatif sur le TTC, on ne doit pas appliquer de TVA,
 272                          // sinon on impute une TVA négative.
 273  
 274              if ($result_insert < 0)
 275              {
 276                  $error++;
 277              }
 278  
 279              $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
 280              $sql .= ' SET fk_facture = '.$this->id;
 281              $sql .= " ,amount_ht = '".ereg_replace(',','.',$remise)."'";
 282              $sql .= ' WHERE rowid ='.$this->remise_exceptionnelle[0];
 283              $sql .= ' AND fk_soc ='. $this->socidp;
 284  
 285              if (! $this->db->query( $sql))
 286              {
 287                  $error++;
 288              }
 289  
 290              if ($reliquat > 0)
 291              {
 292                  $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'societe_remise_except';
 293                  $sql .= ' (fk_soc, datec, amount_ht, fk_user) ';
 294                  $sql .= ' VALUES ';
 295                  $sql .= ' ('.$this->socidp;
 296                  $sql .= ' ,now()';
 297                  $sql .= " ,'".ereg_replace(',','.',$reliquat)."'";
 298                  $sql .= ' ,'.$this->remise_exceptionnelle[3];
 299                  $sql .= ')';
 300  
 301                  if (! $this->db->query( $sql) )
 302                  {
 303                      $error++;
 304                  }
 305              }
 306          }
 307  
 308          if (! $error)
 309          {
 310              $this->db->commit();
 311          }
 312          else
 313          {
 314              $this->db->rollback();
 315          }
 316  
 317          return $error;
 318      }
 319  
 320      /**
 321      *    \brief      Recupére l'objet facture et ses lignes de factures
 322      *    \param      rowid       id de la facture a récupérer
 323      *    \param      societe_id  id de societe
 324      *    \return     int         1 si ok, < 0 si erreur
 325      */
 326  	function fetch($rowid, $societe_id=0)
 327      {
 328          //dolibarr_syslog("Facture::Fetch rowid : $rowid, societe_id : $societe_id");
 329  
 330          $sql = 'SELECT f.fk_soc,f.facnumber,f.amount,f.tva,f.total,f.total_ttc,f.remise,f.remise_percent';
 331          $sql .= ','.$this->db->pdate('f.datef').' as df, f.fk_projet';
 332          $sql .= ','.$this->db->pdate('f.date_lim_reglement').' as dlr';
 333          $sql .= ', f.note, f.paye, f.fk_statut, f.fk_user_author';
 334          $sql .= ', f.fk_mode_reglement, f.ref_client, p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
 335          $sql .= ', f.fk_cond_reglement, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_facture';
 336          $sql .= ' FROM '.MAIN_DB_PREFIX.'cond_reglement as c, '.MAIN_DB_PREFIX.'facture as f';
 337          $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id';
 338          $sql .= ' WHERE f.rowid='.$rowid.' AND c.rowid = f.fk_cond_reglement';
 339          if ($societe_id > 0)
 340          {
 341              $sql .= ' AND f.fk_soc = '.$societe_id;
 342          }
 343          $result = $this->db->query($sql);
 344  
 345          if ($result)
 346          {
 347              if ($this->db->num_rows($result))
 348              {
 349                  $obj = $this->db->fetch_object($result);
 350                  //print strftime('%Y%m%d%H%M%S',$obj->df).' '.$obj->df.' '.dolibarr_print_date($obj->df);
 351  
 352                  $this->id                     = $rowid;
 353                  $this->datep                  = $obj->dp;
 354                  $this->date                   = $obj->df;
 355                  $this->ref                    = $obj->facnumber;
 356                  $this->ref_client             = $obj->ref_client;
 357                  $this->amount                 = $obj->amount;
 358                  $this->remise                 = $obj->remise;
 359                  $this->total_ht               = $obj->total;
 360                  $this->total_tva              = $obj->tva;
 361                  $this->total_ttc              = $obj->total_ttc;
 362                  $this->paye                   = $obj->paye;
 363                  $this->remise_percent         = $obj->remise_percent;
 364                  $this->socidp                 = $obj->fk_soc;
 365                  $this->statut                 = $obj->fk_statut;
 366                  $this->date_lim_reglement     = $obj->dlr;
 367                  $this->mode_reglement_id      = $obj->fk_mode_reglement;
 368                  $this->mode_reglement_code    = $obj->mode_reglement_code;
 369                  $this->mode_reglement         = $obj->mode_reglement_libelle;
 370                  $this->cond_reglement_id      = $obj->fk_cond_reglement;
 371                  $this->cond_reglement         = $obj->cond_reglement_libelle;
 372                  $this->cond_reglement_facture = $obj->cond_reglement_libelle_facture;
 373                  $this->projetid               = $obj->fk_projet;
 374                  $this->note                   = stripslashes($obj->note);
 375                  $this->user_author            = $obj->fk_user_author;
 376                  $this->lignes                 = array();
 377  
 378                  if ($this->statut == 0)
 379                  {
 380                      $this->brouillon = 1;
 381                  }
 382  
 383                  /*
 384                   * Lignes
 385                   */
 386                  $sql = 'SELECT l.fk_product, l.description, l.price, l.qty, l.rowid, l.tva_taux, l.remise, l.remise_percent, l.subprice, '.$this->db->pdate('l.date_start').' as date_start,'.$this->db->pdate('l.date_end').' as date_end,';
 387                  $sql.= ' p.label as label, p.description as product_desc';
 388                  $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l';
 389                  $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
 390                  $sql.= ' WHERE l.fk_facture = '.$this->id;
 391                  $sql.= ' ORDER BY l.rang';
 392                  $result2 = $this->db->query($sql);
 393                  if ($result2)
 394                  {
 395                      $num = $this->db->num_rows($result2);
 396                      $i = 0; $total = 0;
 397                      while ($i < $num)
 398                      {
 399                          $objp = $this->db->fetch_object($result2);
 400                          $faclig = new FactureLigne($this->db);
 401                          $faclig->desc           = stripslashes($objp->description);     // Description ligne
 402                          $faclig->libelle        = stripslashes($objp->label);           // Label produit
 403                          $faclig->product_desc   = stripslashes($objp->product_desc);    // Description produit
 404                          $faclig->qty            = $objp->qty;
 405                          $faclig->price          = $objp->price;
 406                          $faclig->subprice       = $objp->subprice;
 407                          $faclig->tva_taux       = $objp->tva_taux;
 408                          $faclig->remise         = $objp->remise;
 409                          $faclig->remise_percent = $objp->remise_percent;
 410                          $faclig->produit_id     = $objp->fk_product;
 411                          $faclig->date_start     = $objp->date_start;
 412                          $faclig->date_end       = $objp->date_end;
 413                          $this->lignes[$i] = $faclig;
 414                          $i++;
 415                      }
 416                      $this->db->free($result2);
 417                      $this->db->free($result);
 418                      return 1;
 419                  }
 420                  else
 421                  {
 422                      dolibarr_syslog('Erreur Facture::Fetch rowid='.$rowid.', Erreur dans fetch des lignes');
 423                      $this->error=$this->db->error();
 424                      return -3;
 425                  }
 426              }
 427              else
 428              {
 429                  dolibarr_syslog('Erreur Facture::Fetch rowid='.$rowid.' numrows=0 sql='.$sql);
 430                  $this->error='Bill with id '.$rowid.' not found sql='.$sql;
 431                  return -2;
 432              }
 433              $this->db->free($result);
 434          }
 435          else
 436          {
 437              dolibarr_syslog('Erreur Facture::Fetch rowid='.$rowid.' Erreur dans fetch de la facture');
 438              $this->error=$this->db->error();
 439              return -1;
 440          }
 441      }
 442  
 443      /**
 444      * \brief     Recupére l'objet client lié à la facture
 445      *
 446      */
 447  	function fetch_client()
 448      {
 449          $client = new Societe($this->db);
 450          $client->fetch($this->socidp);
 451          $this->client = $client;
 452      }
 453  
 454      /**
 455      * \brief     Valide la facture
 456      * \param     userid      id de l'utilisateur qui valide
 457      */
 458  	function valid($userid)
 459      {
 460          $error = 0;
 461  
 462          if ($this->db->begin())
 463          {
 464              /*
 465              * Lecture de la remise exceptionnelle
 466              *
 467              */
 468              $sql  = 'SELECT rowid, rc.amount_ht, fk_soc, fk_user';
 469              $sql .= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc';
 470              $sql .= ' WHERE rc.fk_soc ='. $this->socidp;
 471              $sql .= ' AND fk_facture IS NULL';
 472              $resql = $this->db->query($sql) ;
 473              if ( $resql)
 474              {
 475                  $nurmx = $this->db->num_rows($resql);
 476                  if ($nurmx > 0)
 477                  {
 478                      $row = $this->db->fetch_row($resql);
 479                      $this->remise_exceptionnelle = $row;
 480                  }
 481                  $this->db->free($resql);
 482              }
 483              else
 484              {
 485                  dolibarr_syslog('Facture::Valide Erreur lecture Remise');
 486                  $error++;
 487              }
 488  
 489              /*
 490              * Affectation de la remise exceptionnelle
 491              */
 492              if ( $this->_affect_remise_exceptionnelle() <> 0)
 493              {
 494                  $error++;
 495              }
 496              else
 497              {
 498                  $this->updateprice($this->id);
 499                  $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET fk_statut = 1, date_valid=now(), fk_user_valid='.$userid;
 500                  $sql .= ' WHERE rowid = '.$this->id.' AND fk_statut = 0 ;';
 501                  if (! $this->db->query($sql) )
 502                  {
 503                      $error++;
 504                      dolibarr_syslog('Facture::Valide Erreur ');
 505                  }
 506              }
 507  
 508              if ($error == 0)
 509              {
 510                  $this->db->commit();
 511              }
 512              else
 513              {
 514                  $this->db->rollback();
 515              }
 516          }
 517          else
 518          {
 519              $error++;
 520          }
 521  
 522          if ($error > 0)
 523          {
 524              return 0;
 525          }
 526          else
 527          {
 528              return 1;
 529          }
 530      }
 531  
 532      /**
 533       *      \brief     Classe la facture dans un projet
 534       *      \param     projid       Id du projet dans lequel classer la facture
 535       */
 536  	function classin($projid)
 537      {
 538          $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
 539          if ($projid) $sql.= ' SET fk_projet = '.$projid;
 540          else $sql.= ' SET fk_projet = NULL';
 541          $sql.= ' WHERE rowid = '.$this->id;
 542          if ($this->db->query($sql))
 543          {
 544              return 1;
 545          }
 546          else
 547          {
 548              dolibarr_print_error($this->db);
 549              return -1;
 550          }
 551      }
 552  
 553  	function set_ref_client($ref_client)
 554      {
 555          $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
 556          if (empty($ref_client))
 557              $sql .= ' SET ref_client = NULL';
 558          else
 559              $sql .= ' SET ref_client = \''.$ref_client.'\'';
 560          $sql .= ' WHERE rowid = '.$this->id;
 561          if ($this->db->query($sql))
 562          {
 563              $this->ref_client = $ref_client;
 564              return 1;
 565          }
 566          else
 567          {
 568              dolibarr_print_error($this->db);
 569              return -1;
 570          }
 571      }
 572  
 573      /**
 574      * \brief     Supprime la facture
 575      * \param     rowid      id de la facture à supprimer
 576      */
 577  	function delete($rowid)
 578      {
 579          global $user,$langs,$conf;
 580          
 581          $this->db->begin();
 582          $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_tva_sum WHERE fk_facture = '.$rowid;
 583  
 584          if ( $this->db->query( $sql) )
 585          {
 586              $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'fa_pr WHERE fk_facture = '.$rowid;
 587              if ($this->db->query( $sql) )
 588              {
 589                  $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'co_fa WHERE fk_facture = '.$rowid;
 590                  if ($this->db->query( $sql) )
 591                  {
 592                      $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.$rowid;
 593                      if ($this->db->query( $sql) )
 594                      {
 595                          /*
 596                          * On repositionne la remise
 597                          */
 598                          $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
 599                          $sql .= ' SET fk_facture = NULL WHERE fk_facture = '.$rowid;
 600                          if ($this->db->query( $sql) )
 601                          {
 602                              $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture WHERE rowid = '.$rowid.' AND fk_statut = 0';
 603                              $resql=$this->db->query($sql) ;
 604  
 605                              if ($resql)
 606                              {
 607                                  // Appel des triggers
 608                                  include_once (DOL_DOCUMENT_ROOT . "/interfaces.class.php");
 609                                  $interface=new Interfaces($this->db);
 610                                  $result=$interface->run_triggers('BILL_DELETE',$this,$user,$langs,$conf);
 611                                  // Fin appel triggers
 612                  
 613                                  $this->db->commit();
 614                                  return 1;
 615                              }
 616                              else
 617                              {
 618                                  $this->db->rollback();
 619                                  return -6;
 620                              }
 621                          }
 622                          else
 623                          {
 624                              $this->db->rollback();
 625                              return -5;
 626                          }
 627                      }
 628                      else
 629                      {
 630                          $this->db->rollback();
 631                          return -4;
 632                      }
 633                  }
 634                  else
 635                  {
 636                      $this->db->rollback();
 637                      return -3;
 638                  }
 639              }
 640              else
 641              {
 642                  $this->db->rollback();
 643                  return -2;
 644              }
 645          }
 646          else
 647          {
 648              $this->db->rollback();
 649              return -1;
 650          }
 651      }
 652  
 653  
 654      /**
 655       *      \brief      Renvoi une date limite de reglement de facture en fonction des
 656       *                  conditions de reglements de la facture et date de facturation
 657       *      \param      cond_reglement_id   Condition de reglement à utiliser, 0=Condition actuelle de la facture
 658       *      \return     date                Date limite de réglement si ok, <0 si ko
 659       */
 660  	function calculate_date_lim_reglement($cond_reglement_id=0)
 661      {
 662          if (! $cond_reglement_id)
 663              $cond_reglement_id=$this->cond_reglement_id;
 664          $sqltemp = 'SELECT c.fdm,c.nbjour';
 665          $sqltemp.= ' FROM '.MAIN_DB_PREFIX.'cond_reglement as c';
 666          $sqltemp.= ' WHERE c.rowid='.$cond_reglement_id;
 667          $resqltemp=$this->db->query($sqltemp);
 668          if ($resqltemp)
 669          {
 670              if ($this->db->num_rows($resqltemp))
 671              {
 672                  $obj = $this->db->fetch_object($resqltemp);
 673                  $cdr_nbjour = $obj->nbjour;
 674                  $cdr_fdm = $obj->fdm;
 675              }
 676          }
 677          else
 678          {
 679              $this->error=$this->db->error();
 680              return -1;
 681          }
 682          $this->db->free($resqltemp);
 683          // Definition de la date limite
 684          $datelim = $this->date + ( $cdr_nbjour * 3600 * 24 );
 685          if ($cdr_fdm)
 686          {
 687              $mois=date('m', $datelim);
 688              $annee=date('Y', $datelim);
 689              $fins=array(31,28,31,30,31,30,31,31,30,31,30,31);
 690              $datelim=mktime(12,0,0,$mois,$fins[$mois-1],$annee);
 691          }
 692          return $datelim;
 693      }
 694  
 695      /**
 696       *      \brief      Tag la facture comme payée complètement + appel trigger BILL_PAYED
 697       *      \param      user        Objet utilisateur qui modifie 
 698        *      \return     int         <0 si ok, >0 si ok
 699       */
 700  	function set_payed($user)
 701      {
 702          global $conf,$langs;
 703          
 704          dolibarr_syslog("Facture.class.php::set_payed rowid=".$this->id);
 705          $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
 706          $sql.= ' SET paye=1 WHERE rowid = '.$this->id ;
 707          $resql = $this->db->query($sql);
 708  
 709          if ($resql)
 710          {
 711              $this->use_webcal=($conf->global->PHPWEBCALENDAR_BILLSTATUS=='always'?1:0);
 712      
 713              // Appel des triggers
 714              include_once (DOL_DOCUMENT_ROOT . "/interfaces.class.php");
 715              $interface=new Interfaces($this->db);
 716              $result=$interface->run_triggers('BILL_PAYED',$this,$user,$langs,$conf);
 717              // Fin appel triggers
 718          }
 719          
 720          return 1;
 721      }
 722      
 723      /**
 724       *      \brief      Tag la facture comme non payée complètement + appel trigger BILL_UNPAYED
 725       *      \param      user        Objet utilisateur qui modifie 
 726        *      \return     int         <0 si ok, >0 si ok
 727        */
 728  	function set_unpayed($user)
 729      {
 730          global $conf,$langs;
 731  
 732          dolibarr_syslog("Facture.class.php::set_unpayed rowid=".$this->id);
 733          $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
 734          $sql.= ' SET paye=0 WHERE rowid = '.$this->id;
 735          $resql = $this->db->query($sql);
 736  
 737          if ($resql)
 738          {
 739              $this->use_webcal=($conf->global->PHPWEBCALENDAR_BILLSTATUS=='always'?1:0);
 740      
 741              // Appel des triggers
 742              include_once (DOL_DOCUMENT_ROOT . "/interfaces.class.php");
 743              $interface=new Interfaces($this->db);
 744              $result=$interface->run_triggers('BILL_UNPAYED',$this,$user,$langs,$conf);
 745              // Fin appel triggers
 746          }
 747          
 748          return 1;
 749      }
 750      
 751      /**
 752      *    \brief     Tag la facture comme payer partiellement
 753      *    \param     rowid       id de la facture à modifier
 754      */
 755  	function set_paiement_started($rowid)
 756      {
 757          $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture set fk_statut=2 WHERE rowid = '.$rowid;
 758          $return = $this->db->query( $sql);
 759      }
 760  
 761      /**
 762        *      \brief      Tag la facture comme abandonnée + appel trigger BILL_CANCEL
 763       *      \param      user        Objet utilisateur qui modifie 
 764        *      \return     int         <0 si ok, >0 si ok
 765       */
 766  	function set_canceled($user)
 767      {
 768          global $conf,$langs;
 769  
 770          dolibarr_syslog("Facture.class.php::set_canceled rowid=".$this->id);
 771          $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
 772          $sql.= ' SET fk_statut=3 WHERE rowid = '.$this->id;
 773          $resql = $this->db->query($sql);
 774  
 775          if ($resql)
 776          {
 777              $this->use_webcal=($conf->global->PHPWEBCALENDAR_BILLSTATUS=='always'?1:0);
 778  
 779              // Appel des triggers
 780              include_once (DOL_DOCUMENT_ROOT . "/interfaces.class.php");
 781              $interface=new Interfaces($this->db);
 782              $result=$interface->run_triggers('BILL_CANCEL',$this,$user,$langs,$conf);
 783              // Fin appel triggers
 784          }
 785  
 786          return 1;
 787      }
 788  
 789      /**
 790       *      \brief     Tag la facture comme validée + appel trigger BILL_VALIDATE
 791       *      \param     rowid            Id de la facture à valider
 792       *      \param     user             Utilisateur qui valide la facture
 793       *      \param     soc              Objet societe
 794       *      \param     force_number     Référence à forcer de la facture
 795       */
 796  	function set_valid($rowid, $user, $soc, $force_number='')
 797      {
 798          global $conf,$langs;
 799          
 800          $error = 0;
 801          if ($this->brouillon)
 802          {
 803              $action_notify = 2; // ne pas modifier cette valeur
 804              if ($force_number)
 805              {
 806                  $numfa=$force_number;
 807              }
 808              else
 809              {
 810                  $numfa = $this->getNextNumRef($soc);
 811              }
 812  
 813              $this->db->begin();
 814              
 815              /*
 816               * Affectation de la remise exceptionnelle
 817               *
 818               * \todo    Appliquer la remise avoir dans les lignes quand brouillon plutot
 819               *          qu'au moment de la validation
 820               */
 821              $sql  = 'SELECT rowid, rc.amount_ht, fk_soc, fk_user';
 822              $sql .= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc';
 823              $sql .= ' WHERE rc.fk_soc ='. $this->socidp;
 824              $sql .= ' AND fk_facture IS NULL';
 825              $resql = $this->db->query($sql) ;
 826              if ($resql)
 827              {
 828                  $nurmx = $this->db->num_rows($resql);
 829                  if ($nurmx > 0)
 830                  {
 831                      $row = $this->db->fetch_row($resql);
 832                      $this->remise_exceptionnelle = $row;
 833                  }
 834                  $this->db->free($resql);
 835              }
 836              else
 837              {
 838                  dolibarr_syslog('Facture::Valide Erreur lecture Remise');
 839                  $error++;
 840              }
 841              if ( $this->_affect_remise_exceptionnelle() <> 0)
 842              {
 843                  $error++;
 844              }
 845              else
 846              {
 847                  $this->updateprice($this->id);
 848              }
 849  
 850              /* Validation de la facture */
 851              $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture ';
 852              $sql.= " SET facnumber='".$numfa."', fk_statut = 1, fk_user_valid = ".$user->id;
 853  
 854              /* Si l'option est activée on force la date de facture */
 855              if ($conf->global->FAC_FORCE_DATE_VALIDATION)
 856              {
 857                  $this->date=time();
 858                  $datelim=$this->calculate_date_lim_reglement();
 859                  $sql .= ', datef='.$this->db->idate($this->date);
 860                  $sql .= ', date_lim_reglement='.$this->db->idate($datelim);
 861              }
 862              $sql .= ' WHERE rowid = '.$rowid;
 863              $resql = $this->db->query($sql);
 864              if ($resql)
 865              {
 866                  $this->facnumber=$numfa;
 867              }
 868              else
 869              {
 870                  dolibarr_syslog("Facture::set_valid() Echec - 10");
 871                  dolibarr_print_error($this->db);
 872                  $error++;
 873              }
 874                  
 875              /*
 876               * Pour chaque produit, on met a jour indicateur nbvente
 877               * On crée ici une dénormalisation des données pas forcément utilisée.
 878               */
 879              $sql = 'SELECT fk_product FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.$this->id;
 880              $sql .= ' AND fk_product > 0';
 881  
 882              $resql = $this->db->query($sql);
 883              if ($resql)
 884              {
 885                  $num = $this->db->num_rows($resql);
 886                  $i = 0;
 887                  while ($i < $num)
 888                  {
 889                      $obj = $this->db->fetch_object($resql);
 890                      $sql = 'UPDATE '.MAIN_DB_PREFIX.'product SET nbvente=nbvente+1 WHERE rowid = '.$obj->fk_product;
 891                      $resql2 = $this->db->query($sql);
 892                      $i++;
 893                  }
 894              }
 895              else
 896              {
 897                  $error++;
 898              }
 899  
 900              if ($error == 0)
 901              {
 902                  $this->use_webcal=($conf->global->PHPWEBCALENDAR_BILLSTATUS=='always'?1:0);
 903  
 904                  // Appel des triggers
 905                  include_once (DOL_DOCUMENT_ROOT . "/interfaces.class.php");
 906                  $interface=new Interfaces($this->db);
 907                  $result=$interface->run_triggers('BILL_VALIDATE',$this,$user,$langs,$conf);
 908                  // Fin appel triggers
 909  
 910                  $this->db->commit();
 911  
 912                  /*
 913                   * Notify
 914                   */
 915                  $facref = sanitize_string($this->ref);
 916                  $filepdf = $conf->facture->dir_output . '/' . $facref . '/' . $facref . '.pdf';
 917                  $mesg = 'La facture '.$this->ref." a été validée.\n";
 918  
 919                  $notify = New Notify($this->db);
 920                  $notify->send($action_notify, $this->socidp, $mesg, 'facture', $rowid, $filepdf);
 921  
 922                  return 1;
 923              }
 924              else
 925              {
 926                  $this->db->rollback();
 927                  $this->error=$this->db->error();
 928                  return -1;
 929              }
 930          }
 931      }
 932  
 933      /**
 934      * \brief     Ajoute un produit dans l'objet facture
 935      * \param     idproduct
 936      * \param     qty
 937      * \param     remise_percent
 938      * \param     datestart
 939      * \param     dateend
 940      */
 941  	function add_product($idproduct, $qty, $remise_percent, $datestart='', $dateend='')
 942      {
 943          if ($idproduct > 0)
 944          {
 945              $i = sizeof($this->products);     // On recupere nb de produit deja dans tableau products
 946              $this->products[$i] = $idproduct; // On ajoute a la suite
 947              if (!$qty)
 948              {
 949                  $qty = 1 ;
 950              }
 951              $this->products_qty[$i] = $qty;
 952              $this->products_remise_percent[$i] = $remise_percent;
 953              if ($datestart) { $this->products_date_start[$i] = $datestart; }
 954              if ($dateend)   { $this->products_date_end[$i] = $dateend; }
 955          }
 956      }
 957  
 958      /**
 959      * \brief     Ajoute une ligne de facture (associé à un produit/service prédéfini ou non)
 960      * \param     facid           id de la facture
 961      * \param     desc            description de la ligne
 962      * \param     pu              prix unitaire
 963      * \param     qty             quantit
 964      * \param     txtva           taux de tva
 965      * \param     fk_product      id du produit/service predéfini
 966      * \param     remise_percent  pourcentage de remise de la ligne
 967      * \param     datestart       date de debut de validité du service
 968      * \param     dateend         date de fin de validité du service
 969      * \param     ventil          code de ventilation comptable
 970      */
 971  	function addline($facid, $desc, $pu, $qty, $txtva, $fk_product=0, $remise_percent=0, $datestart='', $dateend='', $ventil = 0)
 972      {
 973          dolibarr_syslog("facture.class.php::addline($facid,$desc,$pu,$qty,$txtva,$fk_product,$remise_percent,$datestart,$dateend,$ventil)");
 974          if ($this->brouillon)
 975          {
 976              // Nettoyage paramètres
 977              $remise_percent=price2num($remise_percent);
 978              $qty=price2num($qty);
 979              if (strlen(trim($qty))==0) $qty=1;
 980  
 981              if ($fk_product && ! $pu)
 982              {
 983                  $prod = new Product($this->db, $fk_product);
 984                  $prod->fetch($fk_product);
 985                  $pu=$prod->price;
 986                  $txtva=$prod->tva_tx;
 987              }
 988              $price = $pu;
 989              $subprice = $pu;
 990  
 991              // Calcul remise et nouveau prix
 992              $remise = 0;
 993              if ($this->socidp)
 994              {
 995                  $soc = new Societe($this->db);
 996                  $soc->fetch($this->socidp);
 997                  $remise_client = $soc->remise_client;
 998                  if ($remise_client > $remise_percent)
 999                  {
1000                      $remise_percent = $remise_client ;
1001                  }
1002              }
1003  
1004              if ($remise_percent > 0)
1005              {
1006                  $remise = round(($pu * $remise_percent / 100),2);
1007                  $price = ($pu - $remise);
1008              }
1009  
1010              // Stockage du rang max de la facture dans rangmax
1011              $sql = 'SELECT max(rang) FROM '.MAIN_DB_PREFIX.'facturedet';
1012              $sql .= ' WHERE fk_facture ='.$facid;
1013              $resql = $this->db->query($sql);
1014              if ($resql)
1015              {
1016                  $row = $this->db->fetch_row($resql);
1017                  $rangmax = $row[0];
1018              }
1019  
1020              // Formatage des prix
1021              $price    = price2num($price);
1022              $subprice  = price2num($subprice);
1023  
1024              $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facturedet ';
1025              $sql.= ' (fk_facture, description, price, qty, tva_taux, fk_product, remise_percent, subprice, remise, date_start, date_end, fk_code_ventilation, rang)';
1026              $sql.= " VALUES ($facid, '".addslashes($desc)."','$price','$qty','$txtva',";
1027              if ($fk_product) { $sql.= "'$fk_product',"; }
1028              else { $sql.='0,'; }
1029              $sql.= " '$remise_percent','$subprice','$remise',";
1030              if ($datestart) { $sql.= "'$datestart',"; }
1031              else { $sql.='null,'; }
1032              if ($dateend) { $sql.= "'$dateend'"; }
1033              else { $sql.='null'; }
1034              $sql.= ','.$ventil;
1035              $sql.= ','.($rangmax + 1).')';
1036              if ( $this->db->query( $sql) )
1037              {
1038                  $this->updateprice($facid);
1039                  return 1;
1040              }
1041              else
1042              {
1043                  dolibarr_print_error($this->db);
1044              }
1045          }
1046      }
1047  
1048      /**
1049       *      \brief     Mets à jour une ligne de facture
1050       *      \param     rowid            Id de la ligne de facture
1051       *      \param     desc             Description de la ligne
1052       *      \param     pu               Prix unitaire
1053       *      \param     qty              Quantité
1054       *      \param     remise_percent   Pourcentage de remise de la ligne
1055       *      \param     datestart        Date de debut de validité du service
1056       *      \param     dateend          Date de fin de validité du service
1057       *      \param     tva_tx           Taux TVA
1058       *      \return    int              < 0 si erreur, > 0 si ok
1059       */
1060  	function updateline($rowid, $desc, $pu, $qty, $remise_percent=0, $datestart, $dateend, $tva_tx)
1061      {
1062          dolibarr_syslog('Facture::UpdateLine');
1063  
1064          if ($this->brouillon)
1065          {
1066              $this->db->begin();
1067              if (strlen(trim($qty))==0)
1068              {
1069                  $qty=1;
1070              }
1071              $remise = 0;
1072              $price = ereg_replace(',','.',$pu);
1073              $subprice = $price;
1074              if (trim(strlen($remise_percent)) > 0)
1075              {
1076                  $remise = round(($pu * $remise_percent / 100), 2);
1077                  $price = $pu - $remise;
1078              }
1079              else
1080              {
1081                  $remise_percent=0;
1082              }
1083  
1084              $sql = 'UPDATE '.MAIN_DB_PREFIX.'facturedet set description=\''.addslashes($desc).'\'';
1085              $sql .= ",price='"    .     ereg_replace(',','.',$price)."'";
1086              $sql .= ",subprice='" .     ereg_replace(',','.',$subprice)."'";
1087              $sql .= ",remise='".        ereg_replace(',','.',$remise)."'";
1088              $sql .= ",remise_percent='".ereg_replace(',','.',$remise_percent)."'";
1089              $sql .= ",tva_taux='".      ereg_replace(',','.',$tva_tx)."'";
1090              $sql .= ",qty='$qty'";
1091              if ($datestart) { $sql.= ",date_start='$datestart'"; }
1092              else { $sql.=',date_start=null'; }
1093              if ($dateend) { $sql.= ",date_end='$dateend'"; }
1094              else { $sql.=',date_end=null'; }
1095              $sql .= ' WHERE rowid = '.$rowid;
1096              $result = $this->db->query( $sql);
1097              if ($result)
1098              {
1099                  $this->updateprice($this->id);
1100                  $this->db->commit();
1101                  return $result;
1102              }
1103              else
1104              {
1105                  $this->db->rollback();
1106                  dolibarr_print_error($this->db);
1107                  return -1;
1108              }
1109          }
1110          else
1111          {
1112              return -2;
1113          }
1114      }
1115  
1116      /**
1117      * \brief     Supprime une ligne facture de la base
1118      * \param     rowid      id de la ligne de facture a supprimer
1119      */
1120  	function deleteline($rowid)
1121      {
1122          if ($this->brouillon)
1123          {
1124              $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE rowid = '.$rowid;
1125              $result = $this->db->query( $sql);
1126              $this->updateprice($this->id);
1127          }
1128      }
1129  
1130      /**
1131      * \brief     Mise à jour des sommes de la facture
1132      * \param     facid      id de la facture a modifier
1133      */
1134  	function updateprice($facid)
1135      {
1136          include_once  DOL_DOCUMENT_ROOT . '/lib/price.lib.php';
1137          $err=0;
1138          $sql = 'SELECT price, qty, tva_taux FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.$facid;
1139          $result = $this->db->query($sql);
1140          if ($result)
1141          {
1142              $num = $this->db->num_rows($result);
1143              $i = 0;
1144              while ($i < $num)
1145              {
1146                  $obj = $this->db->fetch_object($result);
1147                  $products[$i][0] = $obj->price;
1148                  $products[$i][1] = $obj->qty;
1149                  $products[$i][2] = $obj->tva_taux;
1150                  $i++;
1151              }
1152  
1153              $this->db->free($result);
1154              /*
1155              *
1156              */
1157              $calculs = calcul_price($products, $this->remise_percent);
1158              $this->total_remise   = $calculs[3];
1159              $this->amount_ht      = $calculs[4];
1160              $this->total_ht       = $calculs[0];
1161              $this->total_tva      = $calculs[1];
1162              $this->total_ttc      = $calculs[2];
1163              $tvas                 = $calculs[5];
1164  
1165              /*
1166              *
1167              */
1168  
1169              $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture ';
1170              $sql .= "SET amount ='".ereg_replace(',','.',$this->amount_ht)."'";
1171              $sql .= ", remise='".   ereg_replace(',','.',$this->total_remise)."'";
1172              $sql .= ", total='".    ereg_replace(',','.',$this->total_ht)."'";
1173              $sql .= ", tva='".      ereg_replace(',','.',$this->total_tva)."'";
1174              $sql .= ", total_ttc='".ereg_replace(',','.',$this->total_ttc)."'";
1175              $sql .= ' WHERE rowid = '.$facid;
1176              if ( $this->db->query($sql) )
1177              {
1178                  $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_tva_sum WHERE fk_facture='.$this->id;
1179                  if ( $this->db->query($sql) )
1180                  {
1181                      foreach ($tvas as $key => $value)
1182                      {
1183                          $sql_del = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_tva_sum where fk_facture ='.$this->id;
1184                          $this->db->query($sql_del);
1185                          $sql = 'INSERT INTO '.MAIN_DB_PREFIX."facture_tva_sum (fk_facture,amount,tva_tx) values ($this->id,'".ereg_replace(',','.',$tvas[$key])."','".ereg_replace(',','.',$key)."');";
1186                          //  $sql = "REPLACE INTO ".MAIN_DB_PREFIX."facture_tva_sum SET fk_facture=".$this->id;
1187                          //              $sql .= ", amount = '".$tvas[$key]."'";
1188                          //          $sql .= ", tva_tx='".$key."'";
1189                          if (! $this->db->query($sql) )
1190                          {
1191                              dolibarr_print_error($this->db);
1192                              $err++;
1193                          }
1194                      }
1195                  }
1196                  else
1197                  {
1198                      $err++;
1199                  }
1200  
1201                  if ($err == 0)
1202                  {
1203                      return 1;
1204                  }
1205                  else
1206                  {
1207                      return -3;
1208                  }
1209              }
1210              else
1211              {
1212                  dolibarr_print_error($this->db);
1213              }
1214          }
1215          else
1216          {
1217              dolibarr_print_error($this->db);
1218          }
1219      }
1220  
1221      /**
1222      * \brief     Applique une remise
1223      * \param     user
1224      * \param     remise
1225      */
1226  	function set_remise($user, $remise)
1227      {
1228          if ($user->rights->facture->creer)
1229          {
1230              $this->remise_percent = $remise ;
1231              $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET remise_percent = '.ereg_replace(',','.',$remise);
1232              $sql .= ' WHERE rowid = '.$this->id.' AND fk_statut = 0 ;';
1233  
1234              if ($this->db->query($sql) )
1235              {
1236                  $this->updateprice($this->id);
1237                  return 1;
1238              }
1239              else
1240              {
1241                  dolibarr_print_error($this->db);
1242              }
1243          }
1244      }
1245  
1246  
1247      /**
1248      * \brief     Renvoie la liste des sommes de tva
1249      */
1250  	function getSumTva()
1251      {
1252          $sql = 'SELECT amount, tva_tx FROM '.MAIN_DB_PREFIX.'facture_tva_sum WHERE fk_facture = '.$this->id;
1253          if ($this->db->query($sql))
1254          {
1255              $num = $this->db->num_rows();
1256              $i = 0;
1257              while ($i < $num)
1258              {
1259                  $row = $this->db->fetch_row($i);
1260                  $tvs[$row[1]] = $row[0];
1261                  $i++;
1262              }
1263              return $tvs;
1264          }
1265          else
1266          {
1267              return -1;
1268          }
1269      }
1270  
1271      /**
1272      * \brief     Renvoie la sommes des paiements deja effectués
1273      * \remarks   Utilisé entre autre par certains modèles de factures
1274      */
1275  	function getSommePaiement()
1276      {
1277          $sql = 'SELECT sum(amount) FROM '.MAIN_DB_PREFIX.'paiement_facture WHERE fk_facture = '.$this->id;
1278          if ($this->db->query($sql))
1279          {
1280              $row = $this->db->fetch_row(0);
1281              return $row[0];
1282          }
1283          else
1284          {
1285              return -1;
1286          }
1287      }
1288  
1289      /**
1290       *    \brief      Retourne le libellé du statut d'une facture (brouillon, validée, abandonnée, payée)
1291       *    \param      mode          0=libellé long, 1=libellé court
1292       *    \return     string        Libelle
1293       */
1294  	function getLibStatut($mode=0)
1295      {
1296          return $this->LibStatut($this->paye,$this->statut,$mode);
1297      }
1298  
1299      /**
1300       *    \brief      Renvoi le libellé d'un statut donn
1301       *    \param      paye          Etat paye
1302       *    \param      statut        Id statut
1303       *    \param      mode          0=libellé long, 1=libellé court
1304       *    \return     string        Libellé du statut
1305       */
1306  	function LibStatut($paye,$statut,$mode=0)
1307      {
1308          global $langs;
1309          $langs->load('bills');
1310  
1311          $prefix='';
1312          if ($mode == 1)
1313              $prefix='Short';
1314          if (! $paye)
1315          {
1316              if ($statut == 0) return $langs->trans('Bill'.$prefix.'StatusDraft');
1317              if ($statut == 3) return $langs->trans('Bill'.$prefix.'StatusCanceled');
1318              return $langs->trans('Bill'.$prefix.'StatusValidated');
1319          }
1320          else
1321          {
1322              return $langs->trans('Bill'.$prefix.'StatusPayed');
1323          }
1324      }
1325  
1326      /**
1327      *    \brief      Renvoi le libellé court d'un statut donné
1328      *    \param      paye        etat paye
1329      *    \param      statut      id statut
1330      *    \param      amount      amount already payed
1331      *    \return     string      Libellé court du statut
1332      */
1333  	function PayedLibStatut($paye,$statut,$amount=0)
1334      {
1335          global $langs;
1336          $langs->load('bills');
1337          if (! $paye)
1338          {
1339              if ($statut == 0) return $langs->trans('BillShortStatusDraft');
1340              if ($statut == 3) return $langs->trans('BillStatusCanceled');
1341              if ($amount) return $langs->trans('BillStatusStarted');
1342              return $langs->trans('BillStatusNotPayed');
1343          }
1344          else
1345          {
1346              return $langs->trans('BillStatusPayed');
1347          }
1348      }
1349  
1350  
1351      /**
1352       *      \brief      Renvoie la référence de facture suivante non utilisée en fonction du module
1353       *                  de numérotation actif défini dans FACTURE_ADDON
1354       *      \param        soc                      objet societe
1355       *      \return     string                  reference libre pour la facture
1356       */
1357      function getNextNumRef($soc)
1358      {
1359          global $db, $langs;
1360          $langs->load("bills");
1361      
1362          $dir = DOL_DOCUMENT_ROOT . "/includes/modules/facture/";
1363      
1364          if (defined("FACTURE_ADDON") && FACTURE_ADDON)
1365          {
1366              $file = FACTURE_ADDON."/".FACTURE_ADDON.".modules.php";
1367      
1368              // Chargement de la classe de numérotation
1369              $classname = "mod_facture_".FACTURE_ADDON;
1370              require_once($dir.$file);
1371      
1372              $obj = new $classname();
1373      
1374              $numref = "";
1375              $numref = $obj->getNumRef($soc,$this);
1376      
1377              if ( $numref != "")
1378              {
1379                  return $numref;
1380              }
1381              else
1382              {
1383                  dolibarr_print_error($db,"Facture::getNextNumRef ".$obj->error);
1384                  return "";
1385              }
1386          }
1387          else
1388          {
1389              print $langs->trans("Error")." ".$langs->trans("Error_FACTURE_ADDON_NotDefined");
1390              return "";
1391          }
1392      }
1393      
1394      /**
1395        *    \brief      Mets à jour les commentaires
1396       *    \param      note        note
1397       *    \return     int         <0 si erreur, >0 si ok
1398       */
1399  	function update_note($note)
1400      {
1401          $sql = 'UPDATE '.MAIN_DB_PREFIX."facture SET note = '".addslashes($note)."'";
1402          $sql .= ' WHERE rowid ='. $this->id;
1403  
1404          if ($this->db->query($sql) )
1405          {
1406              $this->note = $note;
1407              return 1;
1408          }
1409          else
1410          {
1411              return -1;
1412          }
1413      }
1414  
1415      /**
1416       *      \brief     Charge les informations d'ordre info dans l'objet facture
1417       *      \param     id       Id de la facture a charger
1418       */
1419  	function info($id)
1420      {
1421          $sql = 'SELECT c.rowid, '.$this->db->pdate('datec').' as datec';
1422          $sql .= ', fk_user_author, fk_user_valid';
1423          $sql .= ' FROM '.MAIN_DB_PREFIX.'facture as c';
1424          $sql .= ' WHERE c.rowid = '.$id;
1425  
1426          $result=$this->db->query($sql);
1427          if ($result)
1428          {
1429              if ($this->db->num_rows($result))
1430              {
1431                  $obj = $this->db->fetch_object($result);
1432                  $this->id = $obj->rowid;
1433                  if ($obj->fk_user_author)
1434                  {
1435                      $cuser = new User($this->db, $obj->fk_user_author);
1436                      $cuser->fetch();
1437                      $this->user_creation     = $cuser;
1438                  }
1439                  if ($obj->fk_user_valid)
1440                  {
1441                      $vuser = new User($this->db, $obj->fk_user_valid);
1442                      $vuser->fetch();
1443                      $this->user_validation = $vuser;
1444                  }
1445                  $this->date_creation     = $obj->datec;
1446                  //$this->date_validation   = $obj->datev; \todo La date de validation n'est pas encore gérée
1447              }
1448              $this->db->free($result);
1449          }
1450          else
1451          {
1452              dolibarr_print_error($this->db);
1453          }
1454      }
1455  
1456      /**
1457       *   \brief      Change les conditions de réglement de la facture
1458       *   \param      cond_reglement_id      Id de la nouvelle condition de réglement
1459       *   \return     int                    >0 si ok, <0 si ko
1460       */
1461  	function cond_reglement($cond_reglement_id)
1462      {
1463          dolibarr_syslog('Facture::cond_reglement('.$cond_reglement_id.')');
1464          if ($this->statut >= 0 && $this->paye == 0)
1465          {
1466              $datelim=$this->calculate_date_lim_reglement($cond_reglement_id);
1467              $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
1468              $sql .= ' SET fk_cond_reglement = '.$cond_reglement_id;
1469              $sql .= ', date_lim_reglement='.$this->db->idate($datelim);
1470              $sql .= ' WHERE rowid='.$this->id;
1471              if ( $this->db->query($sql) )
1472              {
1473                  $this->cond_reglement_id = $cond_reglement_id;
1474                  return 1;
1475              }
1476              else
1477              {
1478                  dolibarr_syslog('Facture::cond_reglement Erreur '.$sql.' - '.$this->db->error());
1479                  $this->error=$this->db->error();
1480                  return -1;
1481              }
1482          }
1483          else
1484          {
1485              dolibarr_syslog('Facture::cond_reglement, etat facture incompatible');
1486              $this->error='Etat facture incompatible '.$this->statut.' '.$this->paye;
1487              return -2;
1488          }
1489      }
1490  
1491  
1492      /**
1493       *   \brief      Change le mode de réglement
1494       *   \param      mode        Id du nouveau mode
1495       *   \return     int         >0 si ok, <0 si ko
1496       */
1497  	function mode_reglement($mode_reglement_id)
1498      {
1499          dolibarr_syslog('Facture::mode_reglement('.$mode_reglement_id.')');
1500          if ($this->statut >= 0 && $this->paye == 0)
1501          {
1502              $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture';
1503              $sql .= ' SET fk_mode_reglement = '.$mode_reglement_id;
1504              $sql .= ' WHERE rowid='.$this->id;
1505              if ( $this->db->query($sql) )
1506              {
1507                  $this->mode_reglement_id = $mode_reglement_id;
1508                  return 1;
1509              }
1510              else
1511              {
1512                  dolibarr_syslog('Facture::mode_reglement Erreur '.$sql.' - '.$this->db->error());
1513                  $this->error=$this->db->error();
1514                  return -1;
1515              }
1516          }
1517          else
1518          {
1519              dolibarr_syslog('Facture::mode_reglement, etat facture incompatible');
1520              $this->error='Etat facture incompatible '.$this->statut.' '.$this->paye;
1521              return -2;
1522          }
1523      }
1524  
1525  
1526     /**
1527      *   \brief      Créé une demande de prélèvement
1528      *   \param      user        Utilisateur créant la demande
1529      *   \return     int         <0 si ko, >0 si ok 
1530      */
1531  	function demande_prelevement($user)
1532      {
1533          dolibarr_syslog("Facture::demande_prelevement $this->statut $this->paye $this->mode_reglement_id");
1534  
1535          $soc = new Societe($this->db);
1536          $soc->id = $this->socidp;
1537          $soc->rib();
1538          if ($this->statut > 0 && $this->paye == 0 && $this->mode_reglement_id == 3)
1539          {
1540              $sql = 'SELECT count(*) FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande';
1541              $sql .= ' WHERE fk_facture='.$this->id;
1542              $sql .= ' AND traite = 0';
1543              if ( $this->db->query( $sql) )
1544              {
1545                  $row = $this->db->fetch_row();
1546                  if ($row[0] == 0)
1547                  {
1548                      $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'prelevement_facture_demande';
1549                      $sql .= ' (fk_facture, amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib)';
1550                      $sql .= ' VALUES ('.$this->id;
1551                      $sql .= ",'".ereg_replace(',','.',$this->total_ttc)."'";
1552                      $sql .= ',now(),'.$user->id;
1553                      $sql .= ",'".$soc->bank_account->code_banque."'";
1554                      $sql .= ",'".$soc->bank_account->code_guichet."'";
1555                      $sql .= ",'".$soc->bank_account->number."'";
1556                      $sql .= ",'".$soc->bank_account->cle_rib."')";
1557                      if ( $this->db->query( $sql) )
1558                      {
1559                          return 1;
1560                      }
1561                      else
1562                      {
1563                          $this->error=$this->db->error();
1564                          dolibarr_syslog('Facture::DemandePrelevement Erreur');
1565                          return -1;
1566                      }
1567                  }
1568                  else
1569                  {
1570                      $this->error="Une demande existe déjà";
1571                      dolibarr_syslog('Facture::DemandePrelevement Impossible de créer une demande, demande déja en cours');
1572                  }
1573              }
1574              else
1575              {
1576                  $this->error=$this->db->error();
1577                  dolibarr_syslog('Facture::DemandePrelevement Erreur -2');
1578                  return -2;
1579              }
1580          }
1581          else
1582          {
1583              $this->error="Etat facture incompatible avec l'action";
1584              dolibarr_syslog("Facture::DemandePrelevement Etat facture incompatible $this->statut, $this->paye, $this->mode_reglement_id");
1585              return -3;
1586          }
1587      }
1588  
1589      /**
1590      * \brief     Supprime une demande de prélèvement
1591      * \param     user         utilisateur créant la demande
1592      * \param     did          id de la demande a supprimer
1593      */
1594  	function demande_prelevement_delete($user, $did)
1595      {
1596          $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande';
1597          $sql .= ' WHERE rowid = '.$did;
1598          $sql .= ' AND traite = 0';
1599          if ( $this->db->query( $sql) )
1600          {
1601              return 0;
1602          }
1603          else
1604          {
1605              dolibarr_syslog('Facture::DemandePrelevement Erreur');
1606              return -1;
1607          }
1608      }
1609  
1610      /**
1611       *      \brief      Stocke un numéro de rand pour toutes les lignes de
1612       *                  detail d'une facture qui n'en ont pas.
1613       */
1614  	function line_order()
1615      {
1616          $sql = 'SELECT count(rowid) FROM '.MAIN_DB_PREFIX.'facturedet';
1617          $sql .= ' WHERE fk_facture='.$this->id;
1618          $sql .= ' AND rang = 0';
1619          $resql = $this->db->query($sql);
1620          if ($resql)
1621          {
1622              $row = $this->db->fetch_row($resql);
1623              $nl = $row[0];
1624          }
1625          if ($nl > 0)
1626          {
1627              $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'facturedet';
1628              $sql .= ' WHERE fk_facture='.$this->id;
1629              $sql .= ' ORDER BY rang ASC, rowid ASC';
1630              $resql = $this->db->query($sql);
1631              if ($resql)
1632              {
1633                  $num = $this->db->num_rows($resql);
1634                  $i = 0;
1635                  while ($i < $num)
1636                  {
1637                      $row = $this->db->fetch_row($resql);
1638                      $li[$i] = $row[0];
1639                      $i++;
1640                  }
1641              }
1642              for ($i = 0 ; $i < sizeof($li) ; $i++)
1643              {
1644                  $sql = 'UPDATE '.MAIN_DB_PREFIX.'facturedet SET rang = '.($i+1);
1645                  $sql .= ' WHERE rowid = '.$li[$i];
1646                  if (!$this->db->query($sql) )
1647                  {
1648                      dolibarr_syslog($this->db->error());
1649                  }
1650              }
1651          }
1652      }
1653  
1654  	function line_up($rowid)
1655      {
1656          $this->line_order();
1657  
1658          /* Lecture du rang de la ligne */
1659          $sql = 'SELECT rang FROM '.MAIN_DB_PREFIX.'facturedet';
1660          $sql .= ' WHERE rowid ='.$rowid;
1661          $resql = $this->db->query($sql);
1662          if ($resql)
1663          {
1664              $row = $this->db->fetch_row($resql);
1665              $rang = $row[0];
1666          }
1667  
1668          if ($rang > 1 )
1669          {
1670              $sql = 'UPDATE '.MAIN_DB_PREFIX.'facturedet SET rang = '.$rang ;
1671              $sql .= ' WHERE fk_facture  = '.$this->id;
1672              $sql .= ' AND rang = '.($rang - 1);
1673              if ($this->db->query($sql) )
1674              {
1675                  $sql = 'UPDATE '.MAIN_DB_PREFIX.'facturedet SET rang  = '.($rang - 1);
1676                  $sql .= ' WHERE rowid = '.$rowid;
1677                  if (! $this->db->query($sql) )
1678                  {
1679                      dolibarr_print_error($this->db);
1680                  }
1681              }
1682              else
1683              {
1684                  dolibarr_print_error($this->db);
1685              }
1686          }
1687      }
1688  
1689  	function line_down($rowid)
1690      {
1691          $this->line_order();
1692  
1693          /* Lecture du rang de la ligne */
1694          $sql = 'SELECT rang FROM '.MAIN_DB_PREFIX.'facturedet';
1695          $sql .= ' WHERE rowid ='.$rowid;
1696          $resql = $this->db->query($sql);
1697          if ($resql)
1698          {
1699              $row = $this->db->fetch_row($resql);
1700              $rang = $row[0];
1701          }
1702  
1703          /* Lecture du rang max de la facture */
1704          $sql = 'SELECT max(rang) FROM '.MAIN_DB_PREFIX.'facturedet';
1705          $sql .= ' WHERE fk_facture ='.$this->id;
1706          $resql = $this->db->query($sql);
1707          if ($resql)
1708          {
1709              $row = $this->db->fetch_row($resql);
1710              $max = $row[0];
1711          }
1712  
1713          if ($rang < $max )
1714          {
1715              $sql = 'UPDATE '.MAIN_DB_PREFIX.'facturedet SET rang = '.$rang;
1716              $sql .= ' WHERE fk_facture  = '.$this->id;
1717              $sql .= ' AND rang = '.($rang+1);
1718              if ($this->db->query($sql) )
1719              {
1720                  $sql = 'UPDATE '.MAIN_DB_PREFIX.'facturedet SET rang = '.($rang+1);
1721                  $sql .= ' WHERE rowid = '.$rowid;
1722                  if (! $this->db->query($sql) )
1723                  {
1724                      dolibarr_print_error($this->db);
1725                  }
1726              }
1727              else
1728              {
1729                  dolibarr_print_error($this->db);
1730              }
1731          }
1732      }
1733  
1734      /**
1735       *      \brief      Charge indicateurs this->nbtodo et this->nbtodolate de tableau de bord
1736       *      \param      user        Objet user
1737       *      \return     int         <0 si ko, >0 si ok
1738       */
1739  	function load_board($user)
1740      {
1741          global $conf;
1742  
1743          $this->nbtodo=$this->nbtodolate=0;
1744          $sql = 'SELECT f.rowid,'.$this->db->pdate('f.date_lim_reglement').' as datefin';
1745          $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f';
1746          $sql.= ' WHERE f.paye=0 AND f.fk_statut = 1';
1747          if ($user->societe_id) $sql.=' AND fk_soc = '.$user->societe_id;
1748          $resql=$this->db->query($sql);
1749          if ($resql)
1750          {
1751              while ($obj=$this->db->fetch_object($resql))
1752              {
1753                  $this->nbtodo++;
1754                  if ($obj->datefin < (time() - $conf->facture->client->warning_delay)) $this->nbtodolate++;
1755              }
1756              return 1;
1757          }
1758          else
1759          {
1760              dolibarr_print_error($this->db);
1761              $this->error=$this->db->error();
1762              return -1;
1763          }
1764      }
1765  
1766  
1767      /**
1768         *      \brief      Ajoute un contact associé une facture
1769       *      \param      fk_socpeople        Id du contact a ajouter.
1770       *      \param      type_contact        Type de contact
1771       *      \param      source              extern=Contact externe (llx_socpeople), intern=Contact interne (llx_user)
1772       *      \return     int                 <0 si erreur, >0 si ok
1773       */
1774  	function add_contact($fk_socpeople, $type_contact, $source='extern')
1775      {
1776          dolibarr_syslog("Facture::add_contact $fk_socpeople, $type_contact, $source");
1777  
1778          if ($fk_socpeople <= 0) return -1;
1779  
1780          // Verifie type_contact
1781          if (! $type_contact || ! is_numeric($type_contact)) 
1782          {
1783              $this->error="Valeur pour type_contact incorrect";
1784              return -3;  
1785          }
1786          
1787          $datecreate = time();
1788          
1789          // Insertion dans la base
1790          $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_contact";
1791          $sql.= " (element_id, fk_socpeople, datecreate, statut, fk_c_type_contact) ";
1792          $sql.= " VALUES (".$this->id.", ".$fk_socpeople." , " ;
1793                  $sql.= $this->db->idate($datecreate);
1794                  $sql.= ", 4, '". $type_contact . "' ";
1795          $sql.= ")";
1796          
1797          // Retour
1798          if ( $this->db->query($sql) )
1799          {
1800              return 1;
1801          }
1802          else
1803          {
1804              $this->error=$this->db->error()." - $sql";
1805              return -1;
1806          }
1807      }    
1808  
1809      /**
1810       *      \brief      Mise a jour du contact associé une facture
1811       *      \param      rowid               La reference du lien facture-contact
1812       *         \param        statut                Le nouveau statut
1813       *      \param      type_contact_id     Description du type de contact
1814       *      \return     int                 <0 si erreur, =0 si ok
1815       */
1816  	function update_contact($rowid, $statut, $type_contact_id)
1817      {
1818          // Insertion dans la base
1819          $sql = "UPDATE ".MAIN_DB_PREFIX."element_contact set";
1820          $sql.= " statut = $statut,";
1821          $sql.= " fk_c_type_contact = '".$type_contact_id ."'";
1822          $sql.= " where rowid = ".$rowid;
1823          // Retour
1824          if (  $this->db->query($sql) )
1825          {
1826              return 0;
1827          }
1828          else
1829          {
1830              dolibarr_print_error($this->db);
1831              return -1;
1832          }
1833       }    
1834  
1835      /** 
1836       *    \brief      Supprime une ligne de contact
1837       *    \param      rowid        La reference du contact
1838       *    \return     statur        >0 si ok, <0 si ko
1839       */
1840      function delete_contact($rowid)
1841      {
1842      
1843          $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_contact";
1844          $sql.= " WHERE rowid =".$rowid;
1845          if ($this->db->query($sql))
1846          {
1847              return 1;
1848          }
1849          else
1850          {
1851              return -1;
1852          }
1853      }
1854  
1855      /** 
1856       *    \brief      Récupère les lignes de contact de l'objet
1857       *    \param      statut        Statut des lignes detail à récupérer
1858       *    \param      source        Source du contact external (llx_socpeople) ou internal (llx_user)
1859       *    \return     array         Tableau des rowid des contacts
1860       */
1861      function liste_contact($statut=-1,$source='external')
1862      {
1863          global $langs;
1864          
1865            $element='facture';
1866  
1867          $tab=array();
1868       
1869          $sql = "SELECT ec.rowid, ec.statut, ec.fk_socpeople as id,";
1870          if ($source == 'internal') $sql.=" '-1' as socid,";
1871          if ($source == 'external') $sql.=" t.fk_soc as socid,";
1872          if ($source == 'internal') $sql.=" t.name as nom,";
1873          if ($source == 'external') $sql.=" t.name as nom,";
1874          $sql.= "tc.source, tc.element, tc.code, tc.libelle";
1875          $sql.= " FROM ".MAIN_DB_PREFIX."element_contact ec,";
1876          if ($source == 'internal') $sql.=" ".MAIN_DB_PREFIX."user t,";
1877          if ($source == 'external') $sql.=" ".MAIN_DB_PREFIX."socpeople t,";
1878          $sql.= " ".MAIN_DB_PREFIX."c_type_contact tc";
1879          $sql.= " WHERE element_id =".$this->id;
1880          $sql.= " AND ec.fk_c_type_contact=tc.rowid";
1881          $sql.= " AND tc.element='".$element."'";
1882          if ($source == 'internal') $sql.= " AND tc.source = 'internal'";
1883          if ($source == 'external') $sql.= " AND tc.source = 'external'";
1884          $sql.= " AND tc.active=1";
1885          if ($source == 'internal') $sql.= " AND ec.fk_socpeople = t.rowid";
1886          if ($source == 'external') $sql.= " AND ec.fk_socpeople = t.idp";
1887          if ($statut >= 0) $sql.= " AND statut = '$statut'";
1888          $sql.=" ORDER BY t.name ASC";
1889          
1890          $resql=$this->db->query($sql);
1891          if ($resql)
1892          {
1893              $num=$this->db->num_rows($resql);
1894              $i=0;
1895              while ($i < $num)
1896              {
1897                  $obj = $this->db->fetch_object($resql);
1898                  
1899                  $transkey="TypeContact_".$obj->element."_".$obj->source."_".$obj->code;
1900                  $libelle_type=($langs->trans($transkey)!=$transkey ? $langs->trans($transkey) : $obj->libelle);
1901                  $tab[$i]=array('source'=>$obj->source,'socid'=>$obj->socid,'id'=>$obj->id,'nom'=>$obj->nom,
1902                                 'rowid'=>$obj->rowid,'code'=>$obj->code,'libelle'=>$libelle_type,'status'=>$obj->statut);
1903                  $i++;
1904              }
1905              return $tab;
1906          }
1907          else
1908          {
1909              $this->error=$this->db->error();
1910              dolibarr_print_error($this->db);
1911              return -1;
1912          }
1913      }
1914  
1915      /** 
1916       *    \brief      Le détail d'un contact
1917       *    \param      rowid      L'identifiant du contact
1918       *    \return     object     L'objet construit par DoliDb.fetch_object
1919       */
1920   	function detail_contact($rowid)
1921      {
1922            $element='facture';
1923  
1924          $sql = "SELECT ec.datecreate, ec.statut, ec.fk_socpeople, ec.fk_c_type_contact,";
1925          $sql.= " tc.code, tc.libelle, s.fk_soc";
1926          $sql.= " FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as tc, ";
1927          $sql.= " ".MAIN_DB_PREFIX."socpeople as s";
1928          $sql.= " WHERE ec.rowid =".$rowid;
1929          $sql.= " AND ec.fk_socpeople=s.idp";
1930          $sql.= " AND ec.fk_c_type_contact=tc.rowid";
1931          $sql.= " AND tc.element = '".$element."'";
1932  
1933          $resql=$this->db->query($sql);
1934          if ($resql)
1935          {
1936              $obj = $this->db->fetch_object($resql);
1937              return $obj;
1938          }
1939          else
1940          {
1941              $this->error=$this->db->error();
1942              dolibarr_print_error($this->db);
1943              return null;
1944          }
1945      }    
1946  
1947      /** 
1948       *      \brief      Liste les valeurs possibles de type de contacts pour les factures
1949       *      \param      source      'internal' ou 'external'
1950       *      \return     array       Tableau des types de contacts
1951       */
1952   	function liste_type_contact($source)
1953      {
1954          global $langs;
1955          
1956            $element='facture';
1957            
1958            $tab = array();
1959            
1960          $sql = "SELECT distinct tc.rowid, tc.code, tc.libelle";
1961          $sql.= " FROM ".MAIN_DB_PREFIX."c_type_contact as tc";
1962          $sql.= " WHERE element='".$element."'";
1963          $sql.= " AND source='".$source."'";
1964          $sql.= " ORDER by tc.code";
1965  
1966          $resql=$this->db->query($sql);
1967          if ($resql)
1968          {
1969              $num=$this->db->num_rows($resql);
1970              $i=0;
1971              while ($i < $num)
1972              {
1973                  $obj = $this->db->fetch_object($resql);
1974  
1975                  $transkey="TypeContact_".$element."_".$source."_".$obj->code;
1976                  $libelle_type=($langs->trans($transkey)!=$transkey ? $langs->trans($transkey) : $obj->libelle);
1977                  $tab[$obj->rowid]=$libelle_type;
1978                  $i++;
1979              }
1980              return $tab;
1981          }
1982          else
1983          {
1984              $this->error=$this->db->error();
1985              return null;
1986          }
1987      }                     
1988  
1989      /**
1990       *      \brief      Retourne id des contacts d'une source et d'un type donné
1991       *                  Exemple: contact client de facturation ('external', 'BILLING')
1992       *                  Exemple: contact client de livraison ('external', 'SHIPPING')
1993       *                  Exemple: contact interne suivi paiement ('internal', 'SALESREPFOLL')
1994       *      \return     array       Liste des id contacts
1995       */   
1996      function getIdContact($source,$code)
1997      {
1998            $element='facture';     // Contact sur la facture
1999          
2000          $result=array();
2001          $i=0;
2002          
2003          $sql = "SELECT ec.fk_socpeople";
2004          $sql.= " FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as tc";
2005          $sql.= " WHERE ec.element_id = ".$this->id;
2006          $sql.= " AND ec.fk_c_type_contact=tc.rowid";
2007          $sql.= " AND tc.element = '".$element."'";
2008          $sql.= " AND tc.source = '".$source."'";
2009          $sql.= " AND tc.code = '".$code."'";
2010  
2011          $resql=$this->db->query($sql);
2012          if ($resql)
2013          {
2014              while ($obj = $this->db->fetch_object($resql))
2015              {
2016                  $result[$i]=$obj->fk_socpeople;
2017                  $i++;
2018              }
2019          }
2020          else
2021          {
2022              $this->error=$this->db->error();
2023              return null;
2024          }
2025          
2026          return $result;
2027      }    
2028  
2029      /**
2030       *      \brief      Retourne id des contacts clients de facturation
2031       *      \return     array       Liste des id contacts facturation
2032       */   
2033      function getIdBillingContact()
2034      {
2035          return $this->getIdContact('external','BILLING');
2036      }
2037  
2038      /**
2039       *      \brief      Retourne id des contacts clients de livraison
2040       *      \return     array       Liste des id contacts livraison
2041       */   
2042      function getIdShippingContact()
2043      {
2044          return $this->getIdContact('external','SHIPPING');
2045      }
2046  
2047  }
2048  
2049  
2050  
2051  /**
2052          \class      FactureLigne
2053          \brief      Classe permettant la gestion des lignes de factures
2054  */
2055  
2056  class FactureLigne
2057  {
2058      var $subprice;  // Prix unitaire HT
2059      var $price;     // Prix HT apres remise %
2060  
2061      /**
2062       *      \brief     Constructeur d'objets ligne de facture
2063       *      \param     DB      handler d'accès base de donnée
2064       */
2065  	function FactureLigne($DB)
2066      {
2067          $this->db= $DB ;
2068      }
2069  
2070  
2071      /**
2072       *      \brief     Recupére l'objet ligne de facture
2073       *      \param     rowid           id de la ligne de facture
2074       *      \param     societe_id      id de la societe
2075       */
2076  	function fetch($rowid, $societe_id=0)
2077      {
2078          $sql = 'SELECT fk_product, description, price, qty, rowid, tva_taux, remise, remise_percent,';
2079          $sql.= ' subprice, '.$this->db->pdate('date_start').' as date_start,'.$this->db->pdate('date_end').' as date_end';
2080          $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet WHERE rowid = '.$rowid;
2081          $result = $this->db->query($sql);
2082          if ($result)
2083          {
2084              $objp = $this->db->fetch_object($result);
2085              $this->desc           = stripslashes($objp->description);
2086              $this->qty            = $objp->qty;
2087              $this->price          = $objp->price;
2088              $this->price_ttc      = $objp->price_ttc;
2089              $this->subprice       = $objp->subprice;
2090              $this->tva_taux       = $objp->tva_taux;
2091              $this->remise         = $objp->remise;
2092              $this->remise_percent = $objp->remise_percent;
2093              $this->produit_id     = $objp->fk_product;
2094              $this->date_start     = $objp->date_start;
2095              $this->date_end       = $objp->date_end;
2096  //            $i++; //modification suite à la tache 4984
2097              $this->db->free($result);
2098          }
2099          else
2100          {
2101              dolibarr_print_error($this->db);
2102          }
2103      }
2104  
2105  }
2106  
2107  ?>


Généré le : Mon Nov 26 12:29:37 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics