| [ Index ] |
|
Code source de Dolibarr 2.0.1 |
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 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Mon Nov 26 12:29:37 2007 | par Balluche grâce à PHPXref 0.7 |
|