2006-02-09 13:25:34 +01:00
< ? php
2007-01-05 10:21:34 +01:00
/* Copyright ( C ) 2002 - 2007 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
2006-03-14 22:49:07 +01:00
* Copyright ( C ) 2004 - 2006 Laurent Destailleur < eldy @ users . sourceforge . net >
2006-02-09 13:25:34 +01:00
* Copyright ( C ) 2004 Sebastien Di Cintio < sdicintio @ ressource - toi . org >
* Copyright ( C ) 2004 Benoit Mortier < benoit . mortier @ opensides . be >
* Copyright ( C ) 2005 Marc Barilley / Ocebo < marc @ ocebo . com >
2007-01-05 13:35:29 +01:00
* Copyright ( C ) 2005 - 2007 Regis Houssin < regis . houssin @ cap - networks . com >
2006-02-09 13:25:34 +01:00
* Copyright ( C ) 2006 Andre Cianfarani < acianfa @ free . fr >
2007-01-04 21:57:11 +01:00
* Copyright ( C ) 2007 Franky Van Liedekerke < franky . van . liedekerke @ telenet . be >
2006-02-09 13:25:34 +01:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*
* $Id $
* $Source $
*/
/**
2006-12-09 15:28:43 +01:00
\file htdocs / facture . class . php
\ingroup facture
\brief Fichier de la classe des factures clients
\version $Revision $
2006-02-09 13:25:34 +01:00
*/
2006-06-18 16:18:41 +02:00
require_once ( DOL_DOCUMENT_ROOT . " /commonobject.class.php " );
2006-02-09 13:25:34 +01:00
require_once ( DOL_DOCUMENT_ROOT . " /product.class.php " );
2006-06-03 14:38:57 +02:00
require_once ( DOL_DOCUMENT_ROOT . " /client.class.php " );
2006-02-09 13:25:34 +01:00
/**
2006-12-09 15:28:43 +01:00
\class Facture
\brief Classe permettant la gestion des factures clients
2006-02-09 13:25:34 +01:00
*/
2006-06-18 16:18:41 +02:00
class Facture extends CommonObject
2006-02-09 13:25:34 +01:00
{
2006-12-09 15:28:43 +01:00
var $db ;
var $element = 'facture' ;
var $table ;
2007-01-05 10:21:34 +01:00
var $tabledetail ;
2006-12-09 15:28:43 +01:00
var $id ;
2007-01-05 10:21:34 +01:00
//! Id client
var $socid ;
//! Objet societe client (<28> charger par fetch_client)
var $client ;
2006-12-09 15:28:43 +01:00
var $number ;
var $author ;
var $date ;
var $ref ;
var $ref_client ;
2007-01-05 10:21:34 +01:00
//! 0=Facture normale, 1=Facture remplacement, 2=Facture avoir, 3=Facture r<> currente
var $type ;
2006-12-09 15:28:43 +01:00
var $amount ;
var $remise ;
var $tva ;
var $total ;
var $note ;
var $note_public ;
2007-03-06 17:14:14 +01:00
//! 0=brouillon,
//! 1=valid<69> e,
//! 2=class<73> e pay<61> e partiellement (close_code='discount_vat','bad_customer') ou compl<70> tement (close_code=null),
//! 3=class<73> e abandonn<6E> e (close_code='abandon')
2007-01-05 10:21:34 +01:00
var $statut ;
2007-02-20 16:22:41 +01:00
//! 1 si facture pay<61> e COMPLETEMENT, 0 sinon (ce champ ne devrait plus servir car insuffisant)
2007-01-05 10:21:34 +01:00
var $paye ;
//! id facture source si facture de remplacement ou avoir
var $fk_facture_source ;
2007-02-20 16:22:41 +01:00
//! Fermeture partielle: discount_vat, bad_customer, abandon
//! Fermeture car abandon suite a remplacement: replaced
2007-01-05 10:21:34 +01:00
var $close_code ;
//! Commentaire si mis a paye sans paiement complet
var $close_note ;
2006-12-09 15:28:43 +01:00
var $propalid ;
var $projetid ;
var $date_lim_reglement ;
var $cond_reglement_id ;
var $cond_reglement_code ;
var $mode_reglement_id ;
var $mode_reglement_code ;
var $modelpdf ;
var $products = array ();
2007-01-05 10:21:34 +01:00
var $lignes = array ();
//! Pour board
2006-12-09 15:28:43 +01:00
var $nbtodo ;
var $nbtodolate ;
var $specimen ;
var $error ;
2007-01-05 10:21:34 +01:00
//! Numero d'erreur de 512 <20> 1023
var $errno = 0 ;
2006-12-09 15:28:43 +01:00
/**
2007-01-05 10:21:34 +01:00
\brief Constructeur de la classe
\param DB handler acc<EFBFBD> s base de donn<EFBFBD> es
\param socid id societe ( '' par defaut )
\param facid id facture ( '' par defaut )
2006-12-09 15:28:43 +01:00
*/
function Facture ( $DB , $socid = '' , $facid = '' )
{
$this -> db = $DB ;
$this -> table = 'facture' ;
$this -> tabledetail = 'facturedet' ;
$this -> id = $facid ;
$this -> socid = $socid ;
$this -> amount = 0 ;
$this -> remise = 0 ;
$this -> remise_percent = 0 ;
$this -> tva = 0 ;
$this -> total = 0 ;
$this -> propalid = 0 ;
$this -> projetid = 0 ;
$this -> remise_exceptionnelle = 0 ;
}
/**
2007-01-05 10:21:34 +01:00
\brief Cr<EFBFBD> ation de la facture en base
\param user Object utilisateur qui cr<EFBFBD> e
\return int < 0 si ko , > 0 si ok
2006-12-09 15:28:43 +01:00
*/
2007-03-06 17:14:14 +01:00
function create ( $user )
2006-12-09 15:28:43 +01:00
{
global $langs , $conf , $mysoc ;
// Nettoyage param<61> tres
if ( ! $this -> type ) $this -> type = 0 ;
$this -> ref_client = trim ( $this -> ref_client );
$this -> note = trim ( $this -> note );
$this -> note_public = trim ( $this -> note_public );
if ( ! $this -> remise ) $this -> remise = 0 ;
if ( ! $this -> mode_reglement_id ) $this -> mode_reglement_id = 0 ;
$this -> brouillon = 1 ;
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( " Facture::Create " );
2006-12-09 15:28:43 +01:00
$soc = new Societe ( $this -> db );
$soc -> fetch ( $this -> socid );
$this -> db -> begin ();
// Facture r<> currente
if ( $this -> fac_rec > 0 )
{
require_once DOL_DOCUMENT_ROOT . '/compta/facture/facture-rec.class.php' ;
$_facrec = new FactureRec ( $this -> db , $this -> fac_rec );
$_facrec -> fetch ( $this -> fac_rec );
$this -> projetid = $_facrec -> projetid ;
$this -> cond_reglement = $_facrec -> cond_reglement_id ;
$this -> cond_reglement_id = $_facrec -> cond_reglement_id ;
$this -> mode_reglement = $_facrec -> mode_reglement_id ;
$this -> mode_reglement_id = $_facrec -> mode_reglement_id ;
$this -> amount = $_facrec -> amount ;
$this -> remise_absolue = $_facrec -> remise_absolue ;
$this -> remise_percent = $_facrec -> remise_percent ;
2006-12-15 13:00:18 +01:00
$this -> remise = $_facrec -> remise ;
2006-12-09 15:28:43 +01:00
}
// Definition de la date limite
$datelim = $this -> calculate_date_lim_reglement ();
// Insertion dans la base
$socid = $this -> socid ;
$amount = $this -> amount ;
$remise = $this -> remise ;
$totalht = ( $amount - $remise );
$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'facture (' ;
$sql .= ' facnumber, type, fk_soc, datec, amount, remise_absolue, remise_percent,' ;
$sql .= ' datef,' ;
$sql .= ' note,' ;
$sql .= ' note_public,' ;
$sql .= ' ref_client,' ;
$sql .= ' fk_facture_source, fk_user_author, fk_projet,' ;
$sql .= ' fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf)' ;
$sql .= ' VALUES (' ;
$sql .= " ' $number ', ' " . $this -> type . " ', ' $socid ', now(), ' $totalht ', ' " . $this -> remise_absolue . " ' " ;
$sql .= " ,' " . $this -> remise_percent . " ', " . $this -> db -> idate ( $this -> date );
$sql .= " , " . ( $this -> note ? " ' " . addslashes ( $this -> note ) . " ' " : " null " );
$sql .= " , " . ( $this -> note_public ? " ' " . addslashes ( $this -> note_public ) . " ' " : " null " );
$sql .= " , " . ( $this -> ref_client ? " ' " . addslashes ( $this -> ref_client ) . " ' " : " null " );
$sql .= " , " . ( $this -> fk_facture_source ? " ' " . addslashes ( $this -> fk_facture_source ) . " ' " : " null " );
$sql .= " , " . $user -> id ;
$sql .= " , " . ( $this -> projetid ? $this -> projetid : " null " );
$sql .= ',' . $this -> cond_reglement_id ;
$sql .= " , " . $this -> mode_reglement_id ;
$sql .= " , " . $this -> db -> idate ( $datelim ) . " , ' " . $this -> modelpdf . " ') " ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$this -> id = $this -> db -> last_insert_id ( MAIN_DB_PREFIX . 'facture' );
$sql = 'UPDATE ' . MAIN_DB_PREFIX . " facture SET facnumber='(PROV " . $this -> id . " )' WHERE rowid= " . $this -> id ;
$resql = $this -> db -> query ( $sql );
// Mise a jour lien avec propal ou commande
if ( $resql && $this -> id && $this -> propalid )
{
$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'fa_pr (fk_facture, fk_propal) VALUES (' . $this -> id . ',' . $this -> propalid . ')' ;
$resql = $this -> db -> query ( $sql );
}
if ( $resql && $this -> id && $this -> commandeid )
{
$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'co_fa (fk_facture, fk_commande) VALUES (' . $this -> id . ',' . $this -> commandeid . ')' ;
$resql = $this -> db -> query ( $sql );
}
2006-02-09 13:25:34 +01:00
2006-12-09 15:28:43 +01:00
/*
* Insertion du detail des produits dans la base
*/
for ( $i = 0 ; $i < sizeof ( $this -> products ) ; $i ++ )
{
$resql = $this -> addline (
$this -> id ,
$this -> products [ $i ] -> desc ,
$this -> products [ $i ] -> subprice ,
$this -> products [ $i ] -> qty ,
$this -> products [ $i ] -> tva_tx ,
$this -> products [ $i ] -> fk_product ,
$this -> products [ $i ] -> remise_percent ,
$this -> products [ $i ] -> date_start ,
$this -> products [ $i ] -> date_end
);
if ( $resql < 0 )
{
$this -> error = $this -> db -> error ;
dolibarr_print_error ( $this -> db );
break ;
}
}
/*
* Produits de la facture r<EFBFBD> currente
*/
if ( $resql && $this -> fac_rec > 0 )
{
for ( $i = 0 ; $i < sizeof ( $_facrec -> lignes ) ; $i ++ )
{
if ( $_facrec -> lignes [ $i ] -> produit_id )
{
$prod = new Product ( $this -> db , $_facrec -> lignes [ $i ] -> produit_id );
$res = $prod -> fetch ( $_facrec -> lignes [ $i ] -> produit_id );
}
$tva_tx = get_default_tva ( $mysoc , $soc , $prod -> tva_tx );
$result_insert = $this -> addline (
2006-02-12 16:54:21 +01:00
$this -> id ,
$_facrec -> lignes [ $i ] -> desc ,
$_facrec -> lignes [ $i ] -> subprice ,
$_facrec -> lignes [ $i ] -> qty ,
2006-02-21 14:27:07 +01:00
$tva_tx ,
2006-02-12 16:54:21 +01:00
$_facrec -> lignes [ $i ] -> produit_id ,
$_facrec -> lignes [ $i ] -> remise_percent );
2006-02-09 13:25:34 +01:00
2006-12-09 15:28:43 +01:00
if ( $result_insert < 0 )
{
dolibarr_print_error ( $this -> db );
}
}
}
if ( $resql )
{
$resql = $this -> update_price ( $this -> id );
if ( $resql )
{
// Appel des triggers
include_once ( DOL_DOCUMENT_ROOT . " /interfaces.class.php " );
$interface = new Interfaces ( $this -> db );
$result = $interface -> run_triggers ( 'BILL_CREATE' , $this , $user , $langs , $conf );
// Fin appel triggers
$this -> db -> commit ();
return $this -> id ;
}
else
{
$this -> db -> rollback ();
return - 3 ;
}
}
else
{
$this -> db -> rollback ();
return - 2 ;
}
}
else
{
$this -> error = $this -> db -> error ();
dolibarr_syslog ( " Facture::create error " . $this -> error . " sql= " . $sql );
$this -> db -> rollback ();
return - 1 ;
}
}
/**
2007-01-05 10:21:34 +01:00
\brief Cr<EFBFBD> ation de la facture en base depuis une autre
\param user Object utilisateur qui cr<EFBFBD> e
\return int < 0 si ko , > 0 si ok
*/
2006-12-09 15:28:43 +01:00
function create_clone ( $user , $invertdetail = 0 )
{
// Charge facture source
$facture = new Facture ( $this -> db );
$facture -> fk_facture_source = $this -> fk_facture_source ;
$facture -> type = $this -> type ;
$facture -> socid = $this -> socid ;
$facture -> date = $this -> date ;
$facture -> note_public = $this -> note_public ;
$facture -> note = $this -> note ;
$facture -> ref_client = $this -> ref_client ;
$facture -> modelpdf = $this -> modelpdf ;
$facture -> projetid = $this -> projetid ;
$facture -> cond_reglement_id = $this -> cond_reglement_id ;
$facture -> mode_reglement_id = $this -> mode_reglement_id ;
$facture -> amount = $this -> amount ;
$facture -> remise_absolue = $this -> remise_absolue ;
$facture -> remise_percent = $this -> remise_percent ;
$facture -> lignes = $this -> lignes ; // Tableau des lignes de factures
$facture -> products = $this -> lignes ; // Tant que products encore utilis<69>
if ( $invertdetail )
{
foreach ( $facture -> lignes as $i => $line )
{
$facture -> lignes [ $i ] -> subprice = - $facture -> lignes [ $i ] -> subprice ;
$facture -> lignes [ $i ] -> price = - $facture -> lignes [ $i ] -> price ;
$facture -> lignes [ $i ] -> total_ht = - $facture -> lignes [ $i ] -> total_ht ;
$facture -> lignes [ $i ] -> total_tva = - $facture -> lignes [ $i ] -> total_tva ;
$facture -> lignes [ $i ] -> total_ttc = - $facture -> lignes [ $i ] -> total_ttc ;
}
}
2006-09-09 14:41:13 +02:00
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( " Facture::create_clone invertdetail= " . $invertdetail . " socid= " . $this -> socid . " nboflines= " . sizeof ( $facture -> lignes ));
2006-09-09 14:41:13 +02:00
2006-09-07 23:23:13 +02:00
2006-12-09 15:28:43 +01:00
$facid = $facture -> create ( $user );
2006-09-07 23:23:13 +02:00
2006-12-09 15:28:43 +01:00
return $facid ;
}
2006-09-07 23:23:13 +02:00
2006-12-09 15:28:43 +01:00
/**
2007-01-05 10:21:34 +01:00
\brief Renvoie nom clicable ( avec eventuellement le picto )
\param withpicto 0 = Pas de picto , 1 = Inclut le picto dans le lien , 2 = Picto seul
\param option Sur quoi pointe le lien
\return string Chaine avec URL
2006-12-09 15:28:43 +01:00
*/
function getNomUrl ( $withpicto = 0 , $option = '' )
{
global $langs ;
2006-08-27 00:45:32 +02:00
2006-12-09 15:28:43 +01:00
$result = '' ;
2006-08-27 00:45:32 +02:00
2006-12-09 15:28:43 +01:00
$lien = '<a href="' . DOL_URL_ROOT . '/compta/facture.php?facid=' . $this -> id . '">' ;
$lienfin = '</a>' ;
2006-10-20 23:20:42 +02:00
2006-12-09 15:28:43 +01:00
$picto = 'bill' ;
if ( $this -> type == 1 ) $picto .= 'r' ;
if ( $this -> type == 2 ) $picto .= 'a' ;
2006-08-27 00:45:32 +02:00
2006-12-09 15:28:43 +01:00
$label = $langs -> trans ( " ShowInvoice " );
if ( $this -> type == 1 ) $label = $langs -> trans ( " ShowInvoiceReplace " );
if ( $this -> type == 2 ) $label = $langs -> trans ( " ShowInvoiceAvoir " );
2006-10-20 23:20:42 +02:00
2006-12-09 15:28:43 +01:00
if ( $withpicto ) $result .= ( $lien . img_object ( $label , $picto ) . $lienfin );
if ( $withpicto && $withpicto != 2 ) $result .= ' ' ;
$result .= $lien . $this -> ref . $lienfin ;
return $result ;
}
2006-08-27 00:45:32 +02:00
2006-12-09 15:28:43 +01:00
/**
2007-01-05 10:21:34 +01:00
\brief Recup<EFBFBD> re l ' objet facture et ses lignes de factures
\param rowid id de la facture a r<EFBFBD> cup<EFBFBD> rer
\param societe_id id de societe
\return int > 0 si ok , < 0 si ko
2006-12-09 15:28:43 +01:00
*/
2007-03-06 17:14:14 +01:00
function fetch ( $rowid , $societe_id = 0 )
2006-12-09 15:28:43 +01:00
{
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( " Facture::Fetch rowid= " . $rowid . " , societe_id= " . $societe_id , LOG_DEBUG );
2006-12-09 15:28:43 +01:00
$sql = 'SELECT f.facnumber,f.ref_client,f.type,f.fk_soc,f.amount,f.tva,f.total,f.total_ttc,f.remise_percent,f.remise_absolue,f.remise' ;
$sql .= ',' . $this -> db -> pdate ( 'f.datef' ) . ' as df, f.fk_projet' ;
$sql .= ',' . $this -> db -> pdate ( 'f.date_lim_reglement' ) . ' as dlr' ;
$sql .= ', f.note, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.model_pdf' ;
$sql .= ', f.fk_facture_source' ;
$sql .= ', f.fk_mode_reglement, f.fk_cond_reglement' ;
$sql .= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle' ;
$sql .= ', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_facture' ;
$sql .= ', cf.fk_commande' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'facture as f' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'cond_reglement as c ON f.fk_cond_reglement = c.rowid' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_paiement as p ON f.fk_mode_reglement = p.id' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'co_fa as cf ON cf.fk_facture = f.rowid' ;
$sql .= ' WHERE f.rowid=' . $rowid ;
if ( $societe_id > 0 )
{
$sql .= ' AND f.fk_soc = ' . $societe_id ;
}
$result = $this -> db -> query ( $sql );
if ( $result )
{
if ( $this -> db -> num_rows ( $result ))
{
$obj = $this -> db -> fetch_object ( $result );
//print strftime('%Y%m%d%H%M%S',$obj->df).' '.$obj->df.' '.dolibarr_print_date($obj->df);
$this -> id = $rowid ;
$this -> ref = $obj -> facnumber ;
$this -> ref_client = $obj -> ref_client ;
$this -> type = $obj -> type ;
$this -> datep = $obj -> dp ;
$this -> date = $obj -> df ;
$this -> amount = $obj -> amount ;
$this -> remise_percent = $obj -> remise_percent ;
$this -> remise_absolue = $obj -> remise_absolue ;
$this -> remise = $obj -> remise ;
$this -> total_ht = $obj -> total ;
$this -> total_tva = $obj -> tva ;
$this -> total_ttc = $obj -> total_ttc ;
$this -> paye = $obj -> paye ;
$this -> close_code = $obj -> close_code ;
$this -> close_note = $obj -> close_note ;
2007-03-21 00:08:26 +01:00
$this -> socid = $obj -> fk_soc ;
2006-12-09 15:28:43 +01:00
$this -> statut = $obj -> fk_statut ;
$this -> date_lim_reglement = $obj -> dlr ;
$this -> mode_reglement_id = $obj -> fk_mode_reglement ;
$this -> mode_reglement_code = $obj -> mode_reglement_code ;
$this -> mode_reglement = $obj -> mode_reglement_libelle ;
$this -> cond_reglement_id = $obj -> fk_cond_reglement ;
$this -> cond_reglement_code = $obj -> cond_reglement_code ;
$this -> cond_reglement = $obj -> cond_reglement_libelle ;
$this -> cond_reglement_facture = $obj -> cond_reglement_libelle_facture ;
$this -> projetid = $obj -> fk_projet ;
$this -> fk_facture_source = $obj -> fk_facture_source ;
$this -> note = $obj -> note ;
$this -> note_public = $obj -> note_public ;
$this -> user_author = $obj -> fk_user_author ;
$this -> modelpdf = $obj -> model_pdf ;
$this -> commande_id = $obj -> fk_commande ;
$this -> lignes = array ();
if ( $this -> commande_id )
{
$sql = " SELECT ref " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " commande " ;
$sql .= " WHERE rowid = " . $this -> commande_id ;
$resqlcomm = $this -> db -> query ( $sql );
if ( $resqlcomm )
{
$objc = $this -> db -> fetch_object ( $resqlcomm );
2007-01-05 10:21:34 +01:00
$this -> commande_ref = $objc -> ref ;
$this -> db -> free ( $resqlcomm );
2006-12-09 15:28:43 +01:00
}
}
if ( $this -> statut == 0 )
{
$this -> brouillon = 1 ;
}
/*
* Lignes
*/
$result = $this -> fetch_lines ();
if ( $result < 0 )
{
return - 3 ;
}
return 1 ;
}
else
{
dolibarr_syslog ( 'Facture::Fetch Error rowid=' . $rowid . ' numrows=0 sql=' . $sql );
$this -> error = 'Bill with id ' . $rowid . ' not found sql=' . $sql ;
return - 2 ;
}
}
else
{
dolibarr_syslog ( 'Facture::Fetch Error rowid=' . $rowid . ' Erreur dans fetch de la facture' );
$this -> error = $this -> db -> error ();
return - 1 ;
}
}
/**
2007-03-21 00:08:26 +01:00
\brief Recup<EFBFBD> re les lignes de factures dans this -> lignes
2007-01-05 10:21:34 +01:00
\return int 1 si ok , < 0 si erreur
2006-12-09 15:28:43 +01:00
*/
function fetch_lines ()
{
$sql = 'SELECT l.rowid, l.fk_product, l.description, l.price, l.qty, l.tva_taux, ' ;
$sql .= ' l.remise, l.remise_percent, l.fk_remise_except, l.subprice,' ;
$sql .= ' ' . $this -> db -> pdate ( 'l.date_start' ) . ' as date_start,' . $this -> db -> pdate ( 'l.date_end' ) . ' as date_end,' ;
$sql .= ' l.info_bits, l.total_ht, l.total_tva, l.total_ttc, l.fk_code_ventilation, l.fk_export_compta,' ;
$sql .= ' p.label as label, p.description as product_desc' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'facturedet as l' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'product as p ON l.fk_product = p.rowid' ;
$sql .= ' WHERE l.fk_facture = ' . $this -> id ;
$sql .= ' ORDER BY l.rang' ;
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( 'Facture::fetch_lines' , LOG_DEBUG );
2006-12-09 15:28:43 +01:00
$result = $this -> db -> query ( $sql );
if ( $result )
{
$num = $this -> db -> num_rows ( $result );
$i = 0 ;
while ( $i < $num )
{
$objp = $this -> db -> fetch_object ( $result );
$faclig = new FactureLigne ( $this -> db );
2007-03-21 00:08:26 +01:00
$faclig -> rowid = $objp -> rowid ;
2006-12-09 15:28:43 +01:00
$faclig -> desc = $objp -> description ; // Description ligne
$faclig -> libelle = $objp -> label ; // Label produit
$faclig -> product_desc = $objp -> product_desc ; // Description produit
$faclig -> qty = $objp -> qty ;
$faclig -> subprice = $objp -> subprice ;
$faclig -> tva_tx = $objp -> tva_taux ;
$faclig -> remise_percent = $objp -> remise_percent ;
$faclig -> fk_remise_except = $objp -> fk_remise_except ;
$faclig -> produit_id = $objp -> fk_product ;
$faclig -> fk_product = $objp -> fk_product ;
$faclig -> date_start = $objp -> date_start ;
$faclig -> date_end = $objp -> date_end ;
$faclig -> date_start = $objp -> date_start ;
$faclig -> date_end = $objp -> date_end ;
$faclig -> info_bits = $objp -> info_bits ;
$faclig -> total_ht = $objp -> total_ht ;
$faclig -> total_tva = $objp -> total_tva ;
$faclig -> total_ttc = $objp -> total_ttc ;
$faclig -> export_compta = $objp -> fk_export_compta ;
$faclig -> code_ventilation = $objp -> fk_code_ventilation ;
// Ne plus utiliser
$faclig -> price = $objp -> price ;
$faclig -> remise = $objp -> remise ;
$this -> lignes [ $i ] = $faclig ;
$i ++ ;
}
$this -> db -> free ( $result );
return 1 ;
}
else
{
$this -> error = $this -> db -> error ();
dolibarr_syslog ( 'Facture::fetch_lines: Error ' . $this -> error );
return - 3 ;
}
}
/**
* \brief Ajout en base d ' une ligne remise fixe en ligne de facture
* \param idremise Id de la remise fixe
* \return int > 0 si ok , < 0 si ko
*/
function insert_discount ( $idremise )
{
global $langs ;
include_once ( DOL_DOCUMENT_ROOT . '/lib/price.lib.php' );
include_once ( DOL_DOCUMENT_ROOT . '/discount.class.php' );
$this -> db -> begin ();
$remise = new DiscountAbsolute ( $this -> db );
$result = $remise -> fetch ( $idremise );
if ( $result > 0 )
{
if ( $remise -> fk_facture )
{
$this -> error = $langs -> trans ( " ErrorDiscountAlreadyUsed " );
$this -> db -> rollback ();
return - 5 ;
}
2006-08-27 00:45:32 +02:00
2006-12-09 15:28:43 +01:00
$facligne = new FactureLigne ( $this -> db );
$facligne -> fk_facture = $this -> id ;
$facligne -> fk_remise_except = $remise -> id ;
$facligne -> desc = $remise -> description ; // Description ligne
$facligne -> tva_tx = $remise -> tva_tx ;
$facligne -> subprice =- $remise -> amount_ht ;
$facligne -> fk_product = 0 ; // Id produit pr<70> d<EFBFBD> fini
$facligne -> qty = 1 ;
$facligne -> remise_percent = 0 ;
$facligne -> rang =- 1 ;
$facligne -> info_bits = 2 ;
2006-08-27 00:45:32 +02:00
2006-12-09 15:28:43 +01:00
// Ne plus utiliser
$facligne -> price =- $remise -> amount_ht ;
$facligne -> remise = 0 ;
2006-06-13 00:20:24 +02:00
2006-12-09 15:28:43 +01:00
$tabprice = calcul_price_total ( $facligne -> qty , $facligne -> subprice , 0 , $facligne -> tva_tx );
$facligne -> total_ht = $tabprice [ 0 ];
$facligne -> total_tva = $tabprice [ 1 ];
$facligne -> total_ttc = $tabprice [ 2 ];
2006-09-10 15:10:39 +02:00
2006-12-09 15:28:43 +01:00
$lineid = $facligne -> insert ();
if ( $lineid > 0 )
{
$result = $this -> update_price ( $this -> id );
if ( $result > 0 )
{
// Cr<43> e lien entre remise et ligne de facture
$result = $remise -> link_to_invoice ( $lineid );
if ( $result < 0 )
{
$this -> error = $remise -> error ;
$this -> db -> rollback ();
return - 4 ;
}
$this -> db -> commit ();
return 1 ;
}
else
{
$this -> error = $facligne -> error ;
$this -> db -> rollback ();
return - 1 ;
}
}
else
{
$this -> error = $facligne -> error ;
$this -> db -> rollback ();
return - 2 ;
}
}
else
{
$this -> db -> rollback ();
return - 3 ;
}
}
/**
* \brief Classe la facture dans un projet
* \param projid Id du projet dans lequel classer la facture
*/
function classin ( $projid )
{
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture' ;
if ( $projid ) $sql .= ' SET fk_projet = ' . $projid ;
else $sql .= ' SET fk_projet = NULL' ;
$sql .= ' WHERE rowid = ' . $this -> id ;
if ( $this -> db -> query ( $sql ))
{
return 1 ;
}
else
{
dolibarr_print_error ( $this -> db );
return - 1 ;
}
}
function set_ref_client ( $ref_client )
{
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture' ;
if ( empty ( $ref_client ))
$sql .= ' SET ref_client = NULL' ;
else
$sql .= ' SET ref_client = \'' . addslashes ( $ref_client ) . '\'' ;
$sql .= ' WHERE rowid = ' . $this -> id ;
if ( $this -> db -> query ( $sql ))
{
$this -> ref_client = $ref_client ;
return 1 ;
}
else
{
dolibarr_print_error ( $this -> db );
return - 1 ;
}
}
/**
2007-01-05 10:21:34 +01:00
\brief Supprime la facture
\param rowid Id de la facture <EFBFBD> supprimer
\return int < 0 si ko , > 0 si ok
2006-12-09 15:28:43 +01:00
*/
function delete ( $rowid = 0 )
{
global $user , $langs , $conf ;
if ( ! $rowid ) $rowid = $this -> id ;
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( " Facture::Delete rowid= " . $rowid , LOG_DEBUG );
2006-08-27 00:45:32 +02:00
2006-12-09 15:28:43 +01:00
$this -> db -> begin ();
2006-02-09 13:25:34 +01:00
2006-12-09 15:28:43 +01:00
$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'facture_tva_sum WHERE fk_facture = ' . $rowid ;
if ( $this -> db -> query ( $sql ))
{
$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'fa_pr WHERE fk_facture = ' . $rowid ;
if ( $this -> db -> query ( $sql ))
{
$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'co_fa WHERE fk_facture = ' . $rowid ;
if ( $this -> db -> query ( $sql ))
{
// On d<> saffecte de la facture les remises li<6C> es
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe_remise_except as re,' ;
$sql .= ' ' . MAIN_DB_PREFIX . 'facturedet as fd' ;
$sql .= ' SET re.fk_facture = NULL' ;
$sql .= ' WHERE fd.rowid=re.fk_facture AND fd.fk_facture = ' . $rowid ;
2006-08-27 00:45:32 +02:00
2006-12-09 15:28:43 +01:00
if ( $this -> db -> query ( $sql ))
{
$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'facturedet WHERE fk_facture = ' . $rowid ;
if ( $this -> db -> query ( $sql ))
{
$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'facture WHERE rowid = ' . $rowid ;
2006-08-27 00:45:32 +02:00
$resql = $this -> db -> query ( $sql );
if ( $resql )
2006-12-09 15:28:43 +01:00
{
// Appel des triggers
include_once ( DOL_DOCUMENT_ROOT . " /interfaces.class.php " );
$interface = new Interfaces ( $this -> db );
$result = $interface -> run_triggers ( 'BILL_DELETE' , $this , $user , $langs , $conf );
// Fin appel triggers
2006-08-27 00:45:32 +02:00
2006-12-09 15:28:43 +01:00
$this -> db -> commit ();
return 1 ;
}
2006-08-27 00:45:32 +02:00
else
2006-12-09 15:28:43 +01:00
{
$this -> error = $this -> db -> error () . " sql= " . $sql ;
dolibarr_syslog ( " Facture.class::delete " . $this -> error );
$this -> db -> rollback ();
return - 6 ;
}
}
else
{
2006-08-27 00:45:32 +02:00
$this -> error = $this -> db -> error () . " sql= " . $sql ;
2006-12-09 15:28:43 +01:00
dolibarr_syslog ( " Facture.class::delete " . $this -> error );
2006-08-27 00:45:32 +02:00
$this -> db -> rollback ();
2006-12-09 15:28:43 +01:00
return - 4 ;
}
}
else
{
$this -> error = $this -> db -> error () . " sql= " . $sql ;
dolibarr_syslog ( " Facture.class::delete " . $this -> error );
$this -> db -> rollback ();
return - 5 ;
}
}
else
{
$this -> error = $this -> db -> error () . " sql= " . $sql ;
dolibarr_syslog ( " Facture.class::delete " . $this -> error );
$this -> db -> rollback ();
return - 3 ;
}
}
else
{
$this -> error = $this -> db -> error () . " sql= " . $sql ;
dolibarr_syslog ( " Facture.class::delete " . $this -> error );
$this -> db -> rollback ();
return - 2 ;
}
}
else
{
$this -> error = $this -> db -> error () . " sql= " . $sql ;
dolibarr_syslog ( " Facture.class::delete " . $this -> error );
$this -> db -> rollback ();
return - 1 ;
}
}
/**
2007-01-05 10:21:34 +01:00
\brief Renvoi une date limite de reglement de facture en fonction des
conditions de reglements de la facture et date de facturation
\param cond_reglement_id Condition de reglement <EFBFBD> utiliser , 0 = Condition actuelle de la facture
\return date Date limite de r<EFBFBD> glement si ok , < 0 si ko
2006-12-09 15:28:43 +01:00
*/
function calculate_date_lim_reglement ( $cond_reglement_id = 0 )
{
if ( ! $cond_reglement_id )
$cond_reglement_id = $this -> cond_reglement_id ;
$sqltemp = 'SELECT c.fdm,c.nbjour,c.decalage' ;
$sqltemp .= ' FROM ' . MAIN_DB_PREFIX . 'cond_reglement as c' ;
$sqltemp .= ' WHERE c.rowid=' . $cond_reglement_id ;
$resqltemp = $this -> db -> query ( $sqltemp );
if ( $resqltemp )
{
if ( $this -> db -> num_rows ( $resqltemp ))
{
$obj = $this -> db -> fetch_object ( $resqltemp );
$cdr_nbjour = $obj -> nbjour ;
$cdr_fdm = $obj -> fdm ;
$cdr_decalage = $obj -> decalage ;
}
}
else
{
$this -> error = $this -> db -> error ();
return - 1 ;
}
$this -> db -> free ( $resqltemp );
/* Definition de la date limite */
// 1 : ajout du nombre de jours
$datelim = $this -> date + ( $cdr_nbjour * 3600 * 24 );
// 2 : application de la r<> gle "fin de mois"
if ( $cdr_fdm )
{
$mois = date ( 'm' , $datelim );
$annee = date ( 'Y' , $datelim );
if ( $mois == 12 )
{
$mois = 1 ;
$annee += 1 ;
}
else
{
$mois += 1 ;
}
// On se d<> place au d<> but du mois suivant, et on retire un jour
$datelim = mktime ( 12 , 0 , 0 , $mois , 1 , $annee );
$datelim -= ( 3600 * 24 );
}
// 3 : application du d<> calage
$datelim += ( $cdr_decalage * 3600 * 24 );
return $datelim ;
}
2007-02-20 16:22:41 +01:00
/**
* \brief Tag la facture comme pay<EFBFBD> e compl<EFBFBD> tement ( close_code non renseign<EFBFBD> ) ou partiellement ( close_code renseign<EFBFBD> ) + appel trigger BILL_PAYED
* \param user Objet utilisateur qui modifie
* \param close_code Code renseign<EFBFBD> si on classe <EFBFBD> pay<EFBFBD> e compl<EFBFBD> tement alors que paiement incomplet ( cas ecompte par exemple )
* \param close_note Commentaire renseign<EFBFBD> si on classe <EFBFBD> pay<EFBFBD> e alors que paiement incomplet ( cas ecompte par exemple )
* \return int < 0 si ok , > 0 si ok
*/
function set_payed ( $user , $close_code = '' , $close_note = '' )
{
global $conf , $langs ;
dolibarr_syslog ( " Facture::set_payed rowid= " . $this -> id , LOG_DEBUG );
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture SET' ;
$sql .= ' fk_statut=2' ;
if ( ! $close_code ) $sql .= ', paye=1' ;
if ( $close_code ) $sql .= " , close_code=' " . addslashes ( $close_code ) . " ' " ;
if ( $close_note ) $sql .= " , close_note=' " . addslashes ( $close_note ) . " ' " ;
$sql .= ' WHERE rowid = ' . $this -> id ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$this -> use_webcal = ( $conf -> global -> PHPWEBCALENDAR_BILLSTATUS == 'always' ? 1 : 0 );
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
// Appel des triggers
include_once ( DOL_DOCUMENT_ROOT . " /interfaces.class.php " );
$interface = new Interfaces ( $this -> db );
$result = $interface -> run_triggers ( 'BILL_PAYED' , $this , $user , $langs , $conf );
// Fin appel triggers
}
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
return 1 ;
}
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
/**
* \brief Tag la facture comme non pay<EFBFBD> e compl<EFBFBD> tement + appel trigger BILL_UNPAYED
* Fonction utilis<EFBFBD> e quand un paiement pr<EFBFBD> levement est refus<EFBFBD> .
* \param user Objet utilisateur qui modifie
* \return int < 0 si ok , > 0 si ok
*/
function set_unpayed ( $user )
{
global $conf , $langs ;
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
dolibarr_syslog ( " Facture::set_unpayed rowid= " . $this -> id , LOG_DEBUG );
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture' ;
$sql .= ' SET paye=0, fk_statut=1' ;
$sql .= ' WHERE rowid = ' . $this -> id ;
$resql = $this -> db -> query ( $sql );
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
if ( $resql )
{
$this -> use_webcal = ( $conf -> global -> PHPWEBCALENDAR_BILLSTATUS == 'always' ? 1 : 0 );
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
// Appel des triggers
include_once ( DOL_DOCUMENT_ROOT . " /interfaces.class.php " );
$interface = new Interfaces ( $this -> db );
$result = $interface -> run_triggers ( 'BILL_UNPAYED' , $this , $user , $langs , $conf );
// Fin appel triggers
}
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
return 1 ;
}
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
/**
\brief Tag la facture comme abandonn<EFBFBD> e , sans paiement dessus ( exemple car facture de remplacement ) + appel trigger BILL_CANCEL
\param user Objet utilisateur qui modifie
\param close_code Code de fermeture
\param close_note Commentaire de fermeture
\return int < 0 si ok , > 0 si ok
*/
function set_canceled ( $user , $close_code = '' , $close_note = '' )
{
global $conf , $langs ;
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
dolibarr_syslog ( " Facture::set_canceled rowid= " . $this -> id , LOG_DEBUG );
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
$this -> db -> begin ();
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture SET' ;
$sql .= ' fk_statut=3' ;
if ( $close_code ) $sql .= " , close_code=' " . addslashes ( $close_code ) . " ' " ;
if ( $close_note ) $sql .= " , close_note=' " . addslashes ( $close_note ) . " ' " ;
$sql .= ' WHERE rowid = ' . $this -> id ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
// On d<> saffecte de la facture les remises li<6C> es
// car elles n'ont pas <20> t<EFBFBD> utilis<69> es vu que la facture est abandonn<6E> e.
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe_remise_except' ;
$sql .= ' SET fk_facture = NULL WHERE fk_facture = ' . $this -> id ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$this -> use_webcal = ( $conf -> global -> PHPWEBCALENDAR_BILLSTATUS == 'always' ? 1 : 0 );
// Appel des triggers
include_once ( DOL_DOCUMENT_ROOT . " /interfaces.class.php " );
$interface = new Interfaces ( $this -> db );
$result = $interface -> run_triggers ( 'BILL_CANCEL' , $this , $user , $langs , $conf );
// Fin appel triggers
$this -> db -> commit ();
return 1 ;
}
else
{
$this -> error = $this -> db -> error () . " sql= " . $sql ;
$this -> db -> rollback ();
return - 1 ;
}
}
else
{
$this -> error = $this -> db -> error () . " sql= " . $sql ;
$this -> db -> rollback ();
return - 2 ;
}
}
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
/**
* \brief Tag la facture comme valid<EFBFBD> e + appel trigger BILL_VALIDATE
* \param rowid Id de la facture <EFBFBD> valider
* \param user Utilisateur qui valide la facture
* \param soc Objet societe
* \param force_number R<EFBFBD> f<EFBFBD> rence <EFBFBD> forcer de la facture
* \return int < 0 si ko , > 0 si ok
*/
function set_valid ( $rowid , $user , $soc , $force_number = '' )
{
global $conf , $langs ;
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
$error = 0 ;
if ( $this -> brouillon )
{
$this -> db -> begin ();
// Verification param<61> tres
if ( $this -> type == 1 ) // si facture de remplacement
{
// Controle que facture source connue
if ( $this -> fk_facture_source <= 0 )
{
$this -> error = $langs -> trans ( " ErrorFieldRequired " , $langs -> trans ( " InvoiceReplacement " ));
$this -> db -> rollback ();
return - 10 ;
}
2006-09-10 15:10:39 +02:00
2007-02-20 16:22:41 +01:00
// Charge la facture source a remplacer
$facreplaced = new Facture ( $this -> db );
$result = $facreplaced -> fetch ( $this -> fk_facture_source );
if ( $result <= 0 )
{
$this -> error = $langs -> trans ( " ErrorBadInvoice " );
$this -> db -> rollback ();
return - 11 ;
}
2006-09-10 15:10:39 +02:00
2007-02-20 16:22:41 +01:00
// Controle que facture source non deja remplacee par une autre
$idreplacement = $facreplaced -> getIdReplacingInvoice ( 'validated' );
if ( $idreplacement && $idreplacement != $rowid )
{
$facreplacement = new Facture ( $this -> db );
$facreplacement -> fetch ( $idreplacement );
$this -> error = $langs -> trans ( " ErrorInvoiceAlreadyReplaced " , $facreplaced -> ref , $facreplacement -> ref );
$this -> db -> rollback ();
return - 12 ;
}
2006-09-10 15:10:39 +02:00
2007-02-20 16:22:41 +01:00
$result = $facreplaced -> set_canceled ( $user , 'replaced' , '' );
if ( $result < 0 )
{
$this -> error = $facreplaced -> error . " sql= " . $sql ;
$this -> db -> rollback ();
return - 13 ;
}
}
// on v<> rifie si la facture est en num<75> rotation provisoire
$facref = substr ( $this -> ref , 1 , 4 );
if ( $force_number )
{
$numfa = $force_number ;
}
else if ( $facref == 'PROV' )
{
$numfa = $this -> getNextNumRef ( $soc );
}
else
{
$numfa = $this -> ref ;
}
$this -> update_price ( $this -> id );
// Validation de la facture
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture ' ;
$sql .= " SET facnumber=' " . $numfa . " ', fk_statut = 1, fk_user_valid = " . $user -> id ;
if ( $conf -> global -> FAC_FORCE_DATE_VALIDATION )
{
// Si l'option est activ<69> e, on force la date de facture
$this -> date = time ();
$datelim = $this -> calculate_date_lim_reglement ();
$sql .= ', datef=' . $this -> db -> idate ( $this -> date );
$sql .= ', date_lim_reglement=' . $this -> db -> idate ( $datelim );
}
$sql .= ' WHERE rowid = ' . $rowid ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$this -> facnumber = $numfa ;
dolibarr_syslog ( " Facture::set_valid() sql= $sql " );
}
else
{
dolibarr_syslog ( " Facture::set_valid() Echec update - 10 - sql= $sql " );
dolibarr_print_error ( $this -> db );
$error ++ ;
}
// On v<> rifie si la facture <20> tait une provisoire
if ( $facref == 'PROV' )
{
// On renomme repertoire facture ($this->ref = ancienne ref, $numfa = nouvelle ref)
// afin de ne pas perdre les fichiers attach<63> s
$facref = sanitize_string ( $this -> ref );
$snumfa = sanitize_string ( $numfa );
$dirsource = $conf -> facture -> dir_output . '/' . $facref ;
$dirdest = $conf -> facture -> dir_output . '/' . $snumfa ;
if ( file_exists ( $dirsource ))
{
dolibarr_syslog ( " Facture::set_valid() renommage rep " . $dirsource . " en " . $dirdest );
if ( @ rename ( $dirsource , $dirdest ))
{
dolibarr_syslog ( " Renommage ok " );
// Suppression ancien fichier PDF dans nouveau rep
dol_delete_file ( $conf -> facture -> dir_output . '/' . $snumfa . '/' . $facref . '.*' );
}
}
}
/*
* Tope les lignes de remises fixes avec id des lignes de facture de remise
*/
// Plus necessaire car deja top<6F> des <20> tat brouillon
/*
foreach ( $this -> lignes as $i => $line )
{
if (( $this -> lignes [ $i ] -> info_bits & 2 ) == 2 && $this -> lignes [ $i ] -> fk_remise_except )
{
// Ligne de remise
dolibarr_syslog ( " Facture.class::set_valid: recherche si remise " . $this -> lignes [ $i ] -> fk_remise_except . " toujours dispo " );
// On recherche si ligne de remise pas deja attribu<62> e
$sql = 'SELECT fk_facture' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'societe_remise_except' ;
$sql .= ' WHERE fk_facture IS NULL AND rowid =' . $this -> lignes [ $i ] -> fk_remise_except ;
$sql .= ' FOR UPDATE' ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$num = $this -> db -> num_rows ( $resql );
if ( $num >= 1 )
{
dolibarr_syslog ( " Facture.class::set_valid: top ligne de remise " . $this -> lignes [ $i ] -> fk_remise_except . " pour ligne de facture " . $this -> lignes [ $i ] -> rowid );
// On met <20> jour ligne de remise comme utilis<69> e
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe_remise_except' ;
$sql .= ' SET fk_facture = ' . $this -> lignes [ $i ] -> rowid ;
$sql .= ' WHERE fk_facture IS NULL AND rowid =' . $this -> lignes [ $i ] -> fk_remise_except ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
}
else
{
$this -> error = $this -> db -> error () . ' sql=' . $sql ;
dolibarr_syslog ( " Facture.class::set_valid: Error " . $this -> error );
2006-12-09 15:28:43 +01:00
$error ++ ;
2007-02-20 16:22:41 +01:00
break ;
}
}
else
{
$error ++ ;
$this -> error = $langs -> trans ( " InvoiceDiscountNotAvailable " );
dolibarr_syslog ( " Facture.class::set_valid: Error " . $this -> error );
break ;
}
}
else
{
2006-12-09 15:28:43 +01:00
$this -> error = $this -> db -> error () . ' sql=' . $sql ;
2007-02-20 16:22:41 +01:00
dolibarr_syslog ( " Facture.class::set_valid: Error " . $this -> error );
$error ++ ;
break ;
}
}
}
*/
// On v<> rifie si la facture <20> tait une provisoire
if ( ! $error && $facref == 'PROV' )
{
/*
* Pour chaque produit , on met a jour indicateur nbvente
* On cr<EFBFBD> e ici une d<EFBFBD> normalisation des donn<EFBFBD> es pas forc<EFBFBD> ment utilis<EFBFBD> e .
*/
$sql = 'SELECT fk_product FROM ' . MAIN_DB_PREFIX . 'facturedet' ;
$sql .= ' WHERE fk_facture = ' . $this -> id ;
$sql .= ' AND fk_product > 0' ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
while ( $i < $num )
{
$obj = $this -> db -> fetch_object ( $resql );
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'product SET nbvente=nbvente+1 WHERE rowid = ' . $obj -> fk_product ;
$resql2 = $this -> db -> query ( $sql );
$i ++ ;
}
}
else
{
$error ++ ;
$this -> error = $this -> db -> error () . ' sql=' . $sql ;
}
}
if ( ! $error )
{
// Classe la soci<63> t<EFBFBD> rattach<63> e comme client
$soc = new Societe ( $this -> db );
$soc -> id = $this -> socid ;
$result = $soc -> set_as_client ();
$this -> ref = $numfa ;
$this -> use_webcal = ( $conf -> global -> PHPWEBCALENDAR_BILLSTATUS == 'always' ? 1 : 0 );
// Appel des triggers
include_once ( DOL_DOCUMENT_ROOT . " /interfaces.class.php " );
$interface = new Interfaces ( $this -> db );
$result = $interface -> run_triggers ( 'BILL_VALIDATE' , $this , $user , $langs , $conf );
// Fin appel triggers
$this -> db -> commit ();
return 1 ;
}
else
{
$this -> db -> rollback ();
return - 1 ;
}
}
}
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
/**
*
*
*/
function set_draft ( $userid )
{
dolibarr_syslog ( " Facture::set_draft rowid= " . $this -> id , LOG_DEBUG );
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
$sql = " UPDATE " . MAIN_DB_PREFIX . " facture SET fk_statut = 0 " ;
$sql .= " WHERE rowid = " . $this -> id ;
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
if ( $this -> db -> query ( $sql ))
{
return 1 ;
}
else
{
$this -> error = $this -> db -> error ();
return - 1 ;
}
}
2006-12-09 15:28:43 +01:00
/**
* \brief Positionne modele derniere generation
* \param user Objet use qui modifie
* \param modelpdf Nom du modele
*/
function set_pdf_model ( $user , $modelpdf )
{
if ( $user -> rights -> facture -> creer )
{
$sql = " UPDATE " . MAIN_DB_PREFIX . " facture SET model_pdf = ' $modelpdf ' " ;
$sql .= " WHERE rowid = $this->id AND fk_statut < 2 ; " ;
if ( $this -> db -> query ( $sql ) )
{
$this -> modelpdf = $modelpdf ;
return 1 ;
}
else
{
dolibarr_print_error ( $this -> db );
return 0 ;
}
}
}
2006-12-24 22:24:57 +01:00
/**
\brief Ajoute une ligne dans le tableau products
\param idproduct Id du produit a ajouter
\param qty Quantit
\param remise_percent Remise relative effectu<EFBFBD> e sur le produit
\param date_start
\param date_end
\return void
\remarks $this -> client doit etre charg
\TODO Remplacer les appels a cette fonction par generation objet Ligne
ins<EFBFBD> r<EFBFBD> dans tableau $this -> products
*/
function add_product ( $idproduct , $qty , $remise_percent , $date_start = '' , $date_end = '' )
{
global $conf , $mysoc ;
// Nettoyage parametres
if ( ! $qty ) $qty = 1 ;
dolibarr_syslog ( " Facture.class::add_product $idproduct , $qty , $remise_percent , $date_start , $date_end " );
2006-12-09 15:28:43 +01:00
2006-12-24 22:24:57 +01:00
if ( $idproduct > 0 )
{
$prod = new Product ( $this -> db );
$prod -> fetch ( $idproduct );
$tva_tx = get_default_tva ( $mysoc , $this -> client , $prod -> tva_tx );
// multiprix
if ( $conf -> global -> PRODUIT_MULTIPRICES == 1 )
$price = $prod -> multiprices [ $this -> client -> price_level ];
else
$price = $prod -> price ;
$line = new FactureLigne ( $this -> db );
$line -> rowid = $idproduct ;
$line -> fk_product = $idproduct ;
$line -> desc = $prod -> description ;
$line -> qty = $qty ;
$line -> subprice = $price ;
$line -> remise_percent = $remise_percent ;
$line -> tva_tx = $tva_tx ;
if ( $date_start ) { $line -> date_start = $date_start ; }
if ( $date_end ) { $line -> date_end = $date_end ; }
$this -> products [] = $line ;
}
}
2006-12-09 15:28:43 +01:00
/**
* \brief Ajoute une ligne de facture ( associ<EFBFBD> <EFBFBD> un produit / service pr<EFBFBD> d<EFBFBD> fini ou non )
* \param facid Id de la facture
* \param desc Description de la ligne
* \param pu Prix unitaire
* \param qty Quantit<EFBFBD>
* \param txtva Taux de tva forc<EFBFBD> , sinon - 1
* \param fk_product Id du produit / service pred<EFBFBD> fini
* \param remise_percent Pourcentage de remise de la ligne
* \param date_start Date de debut de validit<EFBFBD> du service
* \param date_end Date de fin de validit<EFBFBD> du service
* \param ventil Code de ventilation comptable
2006-12-15 13:00:18 +01:00
* \param info_bits Bits de type de lignes
2006-12-09 15:28:43 +01:00
* \remarks Les parametres sont deja cens<EFBFBD> etre juste et avec valeurs finales a l ' appel
* de cette methode . Aussi , pour le taux tva , il doit deja avoir ete d<EFBFBD> fini
* par l ' appelant par la methode get_default_tva ( societe_vendeuse , societe_acheteuse , taux_produit )
* et le desc doit deja avoir la bonne valeur ( a l ' appelant de gerer le multilangue )
*/
2007-03-21 00:08:26 +01:00
function addline ( $facid , $desc , $pu , $qty , $txtva , $fk_product = 0 , $remise_percent = 0 , $date_start = '' , $date_end = '' , $ventil = 0 , $info_bits = '' , $fk_remise_except = '' , $price_base_type = 'HT' , $pu_ttc = 0 )
{
dolibarr_syslog ( " Facture::Addline $facid , $desc , $pu , $qty , $txtva , $fk_product , $remise_percent , $date_start , $date_end , $ventil , $info_bits " , LOG_DEBUG );
include_once ( DOL_DOCUMENT_ROOT . '/lib/price.lib.php' );
2006-12-09 15:28:43 +01:00
2007-03-21 00:08:26 +01:00
if ( $this -> brouillon )
{
$this -> db -> begin ();
2006-12-09 15:28:43 +01:00
2007-03-21 00:08:26 +01:00
// Nettoyage param<61> tres
$remise_percent = price2num ( $remise_percent );
$qty = price2num ( $qty );
if ( ! $qty ) $qty = 1 ;
if ( ! $ventil ) $ventil = 0 ;
if ( ! $info_bits ) $info_bits = 0 ;
$pu = price2num ( $pu );
$txtva = price2num ( $txtva );
// Calcul du total TTC et de la TVA pour la ligne a partir de
// qty, pu, remise_percent et txtva
// TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
// la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
$tabprice = calcul_price_total ( $qty , $pu , $remise_percent , $txtva , 0 , $price_base_type , $pu_ttc );
$total_ht = $tabprice [ 0 ];
$total_tva = $tabprice [ 1 ];
$total_ttc = $tabprice [ 2 ];
// Anciens indicateurs: $price, $remise (a ne plus utiliser)
$price = $pu ;
$remise = 0 ;
if ( $remise_percent > 0 )
{
$remise = round (( $pu * $remise_percent / 100 ), 2 );
$price = ( $pu - $remise );
}
2006-12-09 15:28:43 +01:00
2007-03-21 00:08:26 +01:00
// Insertion ligne
$ligne = new FactureLigne ( $this -> db );
$ligne -> fk_facture = $facid ;
$ligne -> desc = $desc ;
$ligne -> qty = $qty ;
$ligne -> txtva = $txtva ;
$ligne -> fk_product = $fk_product ;
$ligne -> remise_percent = $remise_percent ;
$ligne -> subprice = $pu ;
$ligne -> date_start = $date_start ;
$ligne -> date_end = $date_end ;
$ligne -> ventil = $ventil ;
$ligne -> rang =- 1 ;
$ligne -> info_bits = $info_bits ;
$ligne -> fk_remise_except = $fk_remise_except ;
$ligne -> total_ht = $total_ht ;
$ligne -> total_tva = $total_tva ;
$ligne -> total_ttc = $total_ttc ;
// A ne plus utiliser
$ligne -> price = $price ;
$ligne -> remise = $remise ;
$result = $ligne -> insert ();
if ( $result > 0 )
{
// Mise a jour informations denormalisees au niveau de la facture meme
$result = $this -> update_price ( $facid );
if ( $result > 0 )
{
$this -> db -> commit ();
return 1 ;
}
else
{
$this -> error = $this -> db -> error ();
dolibarr_syslog ( " Error sql= $sql , error= " . $this -> error );
$this -> db -> rollback ();
return - 1 ;
}
}
else
{
$this -> error = $ligne -> error ;
$this -> db -> rollback ();
return - 2 ;
}
}
}
2006-12-09 15:28:43 +01:00
/**
* \brief Mets <EFBFBD> jour une ligne de facture
* \param rowid Id de la ligne de facture
* \param desc Description de la ligne
* \param pu Prix unitaire
* \param qty Quantit<EFBFBD>
* \param remise_percent Pourcentage de remise de la ligne
* \param date_start Date de debut de validit<EFBFBD> du service
* \param date_end Date de fin de validit<EFBFBD> du service
* \param tva_tx Taux TVA
* \return int < 0 si erreur , > 0 si ok
*/
function updateline ( $rowid , $desc , $pu , $qty , $remise_percent = 0 , $date_start , $date_end , $txtva )
{
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( " Facture::UpdateLine $rowid , $desc , $pu , $qty , $remise_percent , $date_start , $date_end , $txtva " , LOG_DEBUG );
2006-12-09 15:28:43 +01:00
include_once ( DOL_DOCUMENT_ROOT . '/lib/price.lib.php' );
if ( $this -> brouillon )
{
$this -> db -> begin ();
// Nettoyage param<61> tres
$remise_percent = price2num ( $remise_percent );
$qty = price2num ( $qty );
if ( ! $qty ) $qty = 1 ;
$pu = price2num ( $pu );
$txtva = price2num ( $txtva );
// Calcul du total TTC et de la TVA pour la ligne a partir de
// qty, pu, remise_percent et txtva
// TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
// la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
$tabprice = calcul_price_total ( $qty , $pu , $remise_percent , $txtva );
$total_ht = $tabprice [ 0 ];
$total_tva = $tabprice [ 1 ];
$total_ttc = $tabprice [ 2 ];
// Anciens indicateurs: $price, $remise (a ne plus utiliser)
$price = $pu ;
$remise = 0 ;
if ( $remise_percent > 0 )
{
$remise = round (( $pu * $remise_percent / 100 ), 2 );
$price = ( $pu - $remise );
}
$price = price2num ( $price );
// Mise a jour ligne en base
$ligne = new FactureLigne ( $this -> db );
$ligne -> rowid = $rowid ;
$ligne -> fetch ( $rowid );
$ligne -> desc = $desc ;
$ligne -> qty = $qty ;
$ligne -> tva_tx = $txtva ;
$ligne -> remise_percent = $remise_percent ;
$ligne -> subprice = $pu ;
$ligne -> date_start = $date_start ;
$ligne -> date_end = $date_end ;
$ligne -> total_ht = $total_ht ;
$ligne -> total_tva = $total_tva ;
$ligne -> total_ttc = $total_ttc ;
// A ne plus utiliser
$ligne -> price = $price ;
$ligne -> remise = $remise ;
$result = $ligne -> update ();
if ( $result > 0 )
{
// Mise a jour info denormalisees au niveau facture
$this -> update_price ( $this -> id );
$this -> db -> commit ();
return $result ;
}
else
{
$this -> db -> rollback ();
return - 1 ;
}
}
else
{
$this -> error = " Facture::UpdateLine Invoice statut makes operation forbidden " ;
return - 2 ;
}
}
/**
* \brief Supprime une ligne facture de la base
* \param rowid Id de la ligne de facture a supprimer
*/
2006-12-15 13:00:18 +01:00
function deleteline ( $rowid , $user = '' )
2006-12-09 15:28:43 +01:00
{
2006-12-15 13:00:18 +01:00
global $langs , $conf ;
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( " Facture::Deleteline rowid= " . $rowid , LOG_DEBUG );
2006-12-09 15:28:43 +01:00
if ( $this -> brouillon )
{
$this -> db -> begin ();
// Libere remise liee a ligne de facture
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe_remise_except' ;
$sql .= ' SET fk_facture = NULL where fk_facture = ' . $rowid ;
$result = $this -> db -> query ( $sql );
if ( $result < 0 )
{
$this -> error = $this -> db -> error ();
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( " Facture::Deleteline Error " . $this -> error );
2006-12-09 15:28:43 +01:00
$this -> db -> rollback ();
return - 1 ;
}
// Efface ligne de facture
$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'facturedet WHERE rowid = ' . $rowid ;
$result = $this -> db -> query ( $sql );
if ( $result < 0 )
{
$this -> error = $this -> db -> error ();
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( " Facture::Deleteline Error " . $this -> error );
2006-12-09 15:28:43 +01:00
$this -> db -> rollback ();
return - 1 ;
}
2006-12-15 13:00:18 +01:00
2006-12-16 15:00:08 +01:00
$result = $this -> update_price ( $this -> id );
2006-12-15 13:00:18 +01:00
// Appel des triggers
include_once ( DOL_DOCUMENT_ROOT . " /interfaces.class.php " );
$interface = new Interfaces ( $this -> db );
$result = $interface -> run_triggers ( 'LINEBILL_DELETE' , $this , $user , $langs , $conf );
// Fin appel triggers
2006-12-09 15:28:43 +01:00
$this -> db -> commit ();
return 1 ;
}
}
/**
2007-01-05 10:21:34 +01:00
\brief Mise <EFBFBD> jour des sommes de la facture et calculs denormalises
\param facid id de la facture a modifier
\return int < 0 si ko , > 0 si ok
2006-12-09 15:28:43 +01:00
*/
function update_price ( $facid )
{
$tvas = array ();
$err = 0 ;
// Liste des lignes factures a sommer (Ne plus utiliser price)
$sql = 'SELECT qty, tva_taux, subprice, remise_percent, price,' ;
$sql .= ' total_ht, total_tva, total_ttc' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'facturedet' ;
$sql .= ' WHERE fk_facture = ' . $facid ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$this -> total_ht = 0 ;
$this -> total_tva = 0 ;
$this -> total_ttc = 0 ;
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
while ( $i < $num )
{
$obj = $this -> db -> fetch_object ( $resql );
$this -> total_ht += $obj -> total_ht ;
$this -> total_tva += ( $obj -> total_ttc - $obj -> total_ht );
$this -> total_ttc += $obj -> total_ttc ;
// Ne plus utiliser amount, ni remise
$this -> amount_ht += ( $obj -> price * $obj -> qty );
$this -> total_remise += 0 ; // Plus de remise globale (toute remise est sur une ligne)
$tvas [ $obj -> tva_taux ] += ( $obj -> total_ttc - $obj -> total_ht );
$i ++ ;
}
$this -> db -> free ( $resql );
// Met a jour indicateurs sur facture
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture ' ;
$sql .= " SET amount =' " . price2num ( $this -> amount_ht ) . " ' " ;
$sql .= " , remise=' " . price2num ( $this -> total_remise ) . " ' " ;
$sql .= " , total=' " . price2num ( $this -> total_ht ) . " ' " ;
$sql .= " , tva=' " . price2num ( $this -> total_tva ) . " ' " ;
$sql .= " , total_ttc=' " . price2num ( $this -> total_ttc ) . " ' " ;
$sql .= ' WHERE rowid = ' . $facid ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
// \TODO A supprimer car l'utilisation de facture_tva_sum non utilisable
// dans un context compta propre. On utilisera plutot les lignes.
$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'facture_tva_sum WHERE fk_facture=' . $this -> id ;
if ( $this -> db -> query ( $sql ) )
{
foreach ( $tvas as $key => $value )
{
$sql_del = 'DELETE FROM ' . MAIN_DB_PREFIX . 'facture_tva_sum where fk_facture =' . $this -> id ;
$this -> db -> query ( $sql_del );
$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . " facture_tva_sum (fk_facture,amount,tva_tx) values ( $this->id ,' " . price2num ( $tvas [ $key ]) . " ',' " . price2num ( $key ) . " '); " ;
if ( ! $this -> db -> query ( $sql ) )
{
dolibarr_print_error ( $this -> db );
$err ++ ;
}
}
}
else
{
$err ++ ;
}
if ( $err == 0 )
{
return 1 ;
}
else
{
return - 3 ;
}
}
else
{
dolibarr_print_error ( $this -> db );
}
}
else
{
dolibarr_print_error ( $this -> db );
}
}
/**
* \brief Applique une remise relative
* \param user User qui positionne la remise
* \param remise
* \return int < 0 si ko , > 0 si ok
*/
function set_remise ( $user , $remise )
{
$remise = trim ( $remise ) ? trim ( $remise ) : 0 ;
if ( $user -> rights -> facture -> creer )
{
$remise = price2num ( $remise );
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture' ;
$sql .= ' SET remise_percent = ' . $remise ;
$sql .= ' WHERE rowid = ' . $this -> id . ' AND fk_statut = 0 ;' ;
if ( $this -> db -> query ( $sql ))
{
$this -> remise_percent = $remise ;
$this -> update_price ( $this -> id );
return 1 ;
}
else
{
$this -> error = $this -> db -> error ();
return - 1 ;
}
}
}
/**
* \brief Applique une remise absolue
* \param user User qui positionne la remise
* \param remise
* \return int < 0 si ko , > 0 si ok
*/
function set_remise_absolue ( $user , $remise )
{
$remise = trim ( $remise ) ? trim ( $remise ) : 0 ;
if ( $user -> rights -> facture -> creer )
{
$remise = price2num ( $remise );
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture' ;
$sql .= ' SET remise_absolue = ' . $remise ;
$sql .= ' WHERE rowid = ' . $this -> id . ' AND fk_statut = 0 ;' ;
dolibarr_syslog ( " Facture::set_remise_absolue sql= $sql " );
if ( $this -> db -> query ( $sql ))
{
$this -> remise_absolue = $remise ;
$this -> update_price ( $this -> id );
return 1 ;
}
else
{
$this -> error = $this -> db -> error ();
return - 1 ;
}
}
}
/**
* \brief Renvoie la liste des sommes de tva
*/
function getSumTva ()
{
$tvs = array ();
$sql = 'SELECT amount, tva_tx FROM ' . MAIN_DB_PREFIX . 'facture_tva_sum WHERE fk_facture = ' . $this -> id ;
if ( $this -> db -> query ( $sql ))
{
$num = $this -> db -> num_rows ();
$i = 0 ;
while ( $i < $num )
{
$row = $this -> db -> fetch_row ( $i );
$tvs [ $row [ 1 ]] = $row [ 0 ];
$i ++ ;
}
return $tvs ;
}
else
{
dolibarr_print_error ( $this -> db );
return - 1 ;
}
}
2007-02-20 16:22:41 +01:00
/**
* \brief Renvoie la sommes des paiements deja effectu<EFBFBD> s
* \return Montant deja vers<EFBFBD> , < 0 si ko
*/
function getSommePaiement ()
{
$sql = 'SELECT sum(amount) as amount' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiement_facture' ;
$sql .= ' WHERE fk_facture = ' . $this -> id ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$obj = $this -> db -> fetch_object ( $resql );
return $obj -> amount ;
}
else
{
return - 1 ;
}
}
2006-12-09 15:28:43 +01:00
/**
* \brief Renvoie tableau des ids de facture avoir issus de la facture
* \return array Tableau d ' id de factures avoirs
*/
function getIdAvoirInvoice ()
{
$idarray = array ();
$sql = 'SELECT rowid' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'facture' ;
$sql .= ' WHERE fk_facture_source = ' . $this -> id ;
$sql .= ' AND type = 2' ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
2007-01-04 21:57:11 +01:00
$num = $this -> db -> num_rows ();
$i = 0 ;
while ( $i < $num )
2006-12-09 15:28:43 +01:00
{
2007-01-04 21:57:11 +01:00
$row = $this -> db -> fetch_row ( $i );
$idarray [] = $row [ 0 ];
$i ++ ;
2006-12-09 15:28:43 +01:00
}
}
else
{
dolibarr_print_error ( $this -> db );
}
return $idarray ;
}
/**
* \brief Renvoie l ' id de la facture qui la remplace
* \param option filtre sur statut ( '' , 'validated' , ... )
* \return int < 0 si ko , 0 si aucune facture ne remplace , id facture sinon
*/
function getIdReplacingInvoice ( $option = '' )
{
$sql = 'SELECT rowid' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'facture' ;
$sql .= ' WHERE fk_facture_source = ' . $this -> id ;
$sql .= ' AND type < 2' ;
if ( $option == 'validated' ) $sql .= ' AND fk_statut = 1' ;
// PROTECTION BAD DATA
// Au cas ou base corrompue et qu'il y a une facture de remplacement valid<69> e
// et une autre non, on donne priorit<69> <20> la valid<69> e.
// Ne devrait pas arriver (sauf si acc<63> s concurrentiel et que 2 personnes
// ont cr<63> <72> en meme temps une facture de remplacement pour la meme facture)
$sql .= ' ORDER BY fk_statut DESC' ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$obj = $this -> db -> fetch_object ( $resql );
if ( $obj )
{
// Si il y en a
return $obj -> rowid ;
}
else
{
// Si aucune facture ne remplace
return 0 ;
}
}
else
{
return - 1 ;
}
}
/**
* \brief Retourne le libell<EFBFBD> du type de facture
* \return string Libelle
*/
function getLibType ()
{
global $langs ;
if ( $this -> type == 0 ) return $langs -> trans ( " InvoiceStandard " );
if ( $this -> type == 1 ) return $langs -> trans ( " InvoiceReplacement " );
if ( $this -> type == 2 ) return $langs -> trans ( " InvoiceAvoir " );
return $langs -> trans ( " Unknown " );
}
2007-02-20 16:22:41 +01:00
/**
* \brief Retourne le libell<EFBFBD> du statut d ' une facture ( brouillon , valid<EFBFBD> e , abandonn<EFBFBD> e , pay<EFBFBD> e )
* \param mode 0 = libell<EFBFBD> long , 1 = libell<EFBFBD> court , 2 = Picto + Libell<EFBFBD> court , 3 = Picto , 4 = Picto + Libell<EFBFBD> long
* \return string Libelle
*/
function getLibStatut ( $mode = 0 , $alreadypayed =- 1 )
{
return $this -> LibStatut ( $this -> paye , $this -> statut , $mode , $alreadypayed );
}
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
/**
* \brief Renvoi le libell<EFBFBD> d ' un statut donn<EFBFBD>
* \param paye Etat paye
* \param statut Id statut
* \param mode 0 = libell<EFBFBD> long , 1 = libell<EFBFBD> court , 2 = Picto + Libell<EFBFBD> court , 3 = Picto , 4 = Picto + Libell<EFBFBD> long , 5 = Libell<EFBFBD> court + Picto
* \param alreadypayed Montant deja pay<EFBFBD>
* \return string Libell<EFBFBD> du statut
*/
function LibStatut ( $paye , $statut , $mode = 0 , $alreadypayed =- 1 )
{
global $langs ;
$langs -> load ( 'bills' );
2006-12-09 15:28:43 +01:00
2007-02-20 16:22:41 +01:00
if ( $mode == 0 )
{
$prefix = '' ;
if ( ! $paye )
{
if ( $statut == 0 ) return $langs -> trans ( 'Bill' . $prefix . 'StatusDraft' );
if (( $statut == 3 || $statut == 2 ) && $alreadypayed <= 0 ) return $langs -> trans ( 'Bill' . $prefix . 'StatusClosedUnpayed' );
if (( $statut == 3 || $statut == 2 ) && $alreadypayed > 0 ) return $langs -> trans ( 'Bill' . $prefix . 'StatusClosedPayedPartially' );
if ( $alreadypayed <= 0 ) return $langs -> trans ( 'Bill' . $prefix . 'StatusNotPayed' );
return $langs -> trans ( 'Bill' . $prefix . 'StatusStarted' );
}
else
{
return $langs -> trans ( 'Bill' . $prefix . 'StatusPayed' );
}
}
if ( $mode == 1 )
{
$prefix = 'Short' ;
if ( ! $paye )
{
if ( $statut == 0 ) return $langs -> trans ( 'Bill' . $prefix . 'StatusDraft' );
if (( $statut == 3 || $statut == 2 ) && $alreadypayed <= 0 ) return $langs -> trans ( 'Bill' . $prefix . 'StatusCanceled' );
if (( $statut == 3 || $statut == 2 ) && $alreadypayed > 0 ) return $langs -> trans ( 'Bill' . $prefix . 'StatusClosedPayedPartially' );
if ( $alreadypayed <= 0 ) return $langs -> trans ( 'Bill' . $prefix . 'StatusNotPayed' );
return $langs -> trans ( 'Bill' . $prefix . 'StatusStarted' );
}
else
{
return $langs -> trans ( 'Bill' . $prefix . 'StatusPayed' );
}
}
if ( $mode == 2 )
{
$prefix = 'Short' ;
if ( ! $paye )
{
if ( $statut == 0 ) return img_picto ( $langs -> trans ( 'BillStatusDraft' ), 'statut0' ) . ' ' . $langs -> trans ( 'Bill' . $prefix . 'StatusDraft' );
if (( $statut == 3 || $statut == 2 ) && $alreadypayed <= 0 ) return img_picto ( $langs -> trans ( 'StatusCanceled' ), 'statut5' ) . ' ' . $langs -> trans ( 'Bill' . $prefix . 'StatusCanceled' );
if (( $statut == 3 || $statut == 2 ) && $alreadypayed > 0 ) return img_picto ( $langs -> trans ( 'BillStatusClosedPayedPartially' ), 'statut7' ) . ' ' . $langs -> trans ( 'Bill' . $prefix . 'StatusClosedPayedPartially' );
if ( $alreadypayed <= 0 ) return img_picto ( $langs -> trans ( 'BillStatusNotPayed' ), 'statut1' ) . ' ' . $langs -> trans ( 'Bill' . $prefix . 'StatusNotPayed' );
return img_picto ( $langs -> trans ( 'BillStatusStarted' ), 'statut3' ) . ' ' . $langs -> trans ( 'Bill' . $prefix . 'StatusStarted' );
}
else
{
return img_picto ( $langs -> trans ( 'BillStatusPayed' ), 'statut6' ) . ' ' . $langs -> trans ( 'Bill' . $prefix . 'StatusPayed' );
}
}
if ( $mode == 3 )
{
$prefix = 'Short' ;
if ( ! $paye )
{
if ( $statut == 0 ) return img_picto ( $langs -> trans ( 'BillStatusDraft' ), 'statut0' );
if (( $statut == 3 || $statut == 2 ) && $alreadypayed <= 0 ) return img_picto ( $langs -> trans ( 'BillStatusCanceled' ), 'statut5' );
if (( $statut == 3 || $statut == 2 ) && $alreadypayed > 0 ) return img_picto ( $langs -> trans ( 'BillStatusClosedPayedPartially' ), 'statut7' );
if ( $alreadypayed <= 0 ) return img_picto ( $langs -> trans ( 'BillStatusNotPayed' ), 'statut1' );
return img_picto ( $langs -> trans ( 'BillStatusStarted' ), 'statut3' );
}
else
{
return img_picto ( $langs -> trans ( 'BillStatusPayed' ), 'statut6' );
}
}
if ( $mode == 4 )
{
if ( ! $paye )
{
if ( $statut == 0 ) return img_picto ( $langs -> trans ( 'BillStatusDraft' ), 'statut0' ) . ' ' . $langs -> trans ( 'BillStatusDraft' );
if (( $statut == 3 || $statut == 2 ) && $alreadypayed <= 0 ) return img_picto ( $langs -> trans ( 'BillStatusCanceled' ), 'statut5' ) . ' ' . $langs -> trans ( 'Bill' . $prefix . 'StatusCanceled' );
if (( $statut == 3 || $statut == 2 ) && $alreadypayed > 0 ) return img_picto ( $langs -> trans ( 'BillStatusClosedPayedPartially' ), 'statut7' ) . ' ' . $langs -> trans ( 'Bill' . $prefix . 'StatusClosedPayedPartially' );
if ( $alreadypayed <= 0 ) return img_picto ( $langs -> trans ( 'BillStatusNotPayed' ), 'statut1' ) . ' ' . $langs -> trans ( 'BillStatusNotPayed' );
return img_picto ( $langs -> trans ( 'BillStatusStarted' ), 'statut3' ) . ' ' . $langs -> trans ( 'BillStatusStarted' );
}
else
{
return img_picto ( $langs -> trans ( 'BillStatusPayed' ), 'statut6' ) . ' ' . $langs -> trans ( 'BillStatusPayed' );
}
}
if ( $mode == 5 )
{
$prefix = 'Short' ;
if ( ! $paye )
{
if ( $statut == 0 ) return $langs -> trans ( 'Bill' . $prefix . 'StatusDraft' ) . ' ' . img_picto ( $langs -> trans ( 'BillStatusDraft' ), 'statut0' );
if (( $statut == 3 || $statut == 2 ) && $alreadypayed <= 0 ) return $langs -> trans ( 'Bill' . $prefix . 'StatusCanceled' ) . ' ' . img_picto ( $langs -> trans ( 'BillStatusCanceled' ), 'statut5' );
if (( $statut == 3 || $statut == 2 ) && $alreadypayed > 0 ) return $langs -> trans ( 'Bill' . $prefix . 'StatusClosedPayedPartially' ) . ' ' . img_picto ( $langs -> trans ( 'BillStatusClosedPayedPartially' ), 'statut7' );
if ( $alreadypayed <= 0 ) return $langs -> trans ( 'Bill' . $prefix . 'StatusNotPayed' ) . ' ' . img_picto ( $langs -> trans ( 'BillStatusNotPayed' ), 'statut1' );
return $langs -> trans ( 'Bill' . $prefix . 'StatusStarted' ) . ' ' . img_picto ( $langs -> trans ( 'BillStatusStarted' ), 'statut3' );
}
else
{
return $langs -> trans ( 'Bill' . $prefix . 'StatusPayed' ) . ' ' . img_picto ( $langs -> trans ( 'BillStatusPayed' ), 'statut6' );
}
}
}
2006-12-09 15:28:43 +01:00
/**
* \brief Renvoie la r<EFBFBD> f<EFBFBD> rence de facture suivante non utilis<EFBFBD> e en fonction du module
* de num<EFBFBD> rotation actif d<EFBFBD> fini dans FACTURE_ADDON
* \param soc objet societe
* \return string reference libre pour la facture
*/
function getNextNumRef ( $soc )
{
global $db , $langs ;
$langs -> load ( " bills " );
$dir = DOL_DOCUMENT_ROOT . " /includes/modules/facture/ " ;
if ( defined ( " FACTURE_ADDON " ) && FACTURE_ADDON )
{
$file = FACTURE_ADDON . " / " . FACTURE_ADDON . " .modules.php " ;
// Chargement de la classe de num<75> rotation
$classname = " mod_facture_ " . FACTURE_ADDON ;
require_once ( $dir . $file );
$obj = new $classname ();
$numref = " " ;
$numref = $obj -> getNumRef ( $soc , $this );
if ( $numref != " " )
{
return $numref ;
}
else
{
dolibarr_print_error ( $db , " Facture::getNextNumRef " . $obj -> error );
return " " ;
}
}
else
{
print $langs -> trans ( " Error " ) . " " . $langs -> trans ( " Error_FACTURE_ADDON_NotDefined " );
return " " ;
}
}
/**
* \brief Mets <EFBFBD> jour les commentaires priv<EFBFBD> s
* \param note Commentaire
* \return int < 0 si ko , > 0 si ok
*/
function update_note ( $note )
{
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this -> table ;
$sql .= " SET note = ' " . addslashes ( $note ) . " ' " ;
$sql .= " WHERE rowid = " . $this -> id ;
dolibarr_syslog ( " Facture.class::update_note sql= $sql " );
if ( $this -> db -> query ( $sql ))
{
$this -> note = $note ;
return 1 ;
}
else
{
$this -> error = $this -> db -> error ();
return - 1 ;
}
}
/**
* \brief Mets <EFBFBD> jour les commentaires publiques
* \param note_public Commentaire
* \return int < 0 si ko , > 0 si ok
*/
function update_note_public ( $note_public )
{
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this -> table ;
$sql .= " SET note_public = ' " . addslashes ( $note_public ) . " ' " ;
$sql .= " WHERE rowid = " . $this -> id ;
dolibarr_syslog ( " Facture.class::update_note_public sql= $sql " );
if ( $this -> db -> query ( $sql ))
{
$this -> note_public = $note_public ;
return 1 ;
}
else
{
$this -> error = $this -> db -> error ();
return - 1 ;
}
}
2007-03-21 00:08:26 +01:00
/**
* \brief Charge les informations de l 'onglet info dans l' objet facture
* \param id Id de la facture a charger
*/
function info ( $id )
{
$sql = 'SELECT c.rowid, ' . $this -> db -> pdate ( 'datec' ) . ' as datec,' ;
$sql .= ' ' . $this -> db -> pdate ( 'date_valid' ) . ' as datev,' ;
$sql .= ' fk_user_author, fk_user_valid' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'facture as c' ;
$sql .= ' WHERE c.rowid = ' . $id ;
$result = $this -> db -> query ( $sql );
if ( $result )
{
if ( $this -> db -> num_rows ( $result ))
{
$obj = $this -> db -> fetch_object ( $result );
$this -> id = $obj -> rowid ;
if ( $obj -> fk_user_author )
{
$cuser = new User ( $this -> db , $obj -> fk_user_author );
$cuser -> fetch ();
$this -> user_creation = $cuser ;
}
if ( $obj -> fk_user_valid )
{
$vuser = new User ( $this -> db , $obj -> fk_user_valid );
$vuser -> fetch ();
$this -> user_validation = $vuser ;
}
$this -> date_creation = $obj -> datec ;
$this -> date_validation = $obj -> datev ;
}
$this -> db -> free ( $result );
}
else
{
dolibarr_print_error ( $this -> db );
}
}
2006-12-09 15:28:43 +01:00
/**
* \brief Change les conditions de r<EFBFBD> glement de la facture
* \param cond_reglement_id Id de la nouvelle condition de r<EFBFBD> glement
* \return int > 0 si ok , < 0 si ko
*/
function cond_reglement ( $cond_reglement_id )
{
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( 'Facture::cond_reglement ' . $cond_reglement_id , LOG_DEBUG );
2006-12-09 15:28:43 +01:00
if ( $this -> statut >= 0 && $this -> paye == 0 )
{
$datelim = $this -> calculate_date_lim_reglement ( $cond_reglement_id );
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture' ;
$sql .= ' SET fk_cond_reglement = ' . $cond_reglement_id ;
$sql .= ', date_lim_reglement=' . $this -> db -> idate ( $datelim );
$sql .= ' WHERE rowid=' . $this -> id ;
if ( $this -> db -> query ( $sql ) )
{
$this -> cond_reglement_id = $cond_reglement_id ;
return 1 ;
}
else
{
dolibarr_syslog ( 'Facture::cond_reglement Erreur ' . $sql . ' - ' . $this -> db -> error ());
$this -> error = $this -> db -> error ();
return - 1 ;
}
}
else
{
dolibarr_syslog ( 'Facture::cond_reglement, etat facture incompatible' );
$this -> error = 'Etat facture incompatible ' . $this -> statut . ' ' . $this -> paye ;
return - 2 ;
}
}
/**
* \brief Change le mode de r<EFBFBD> glement
* \param mode Id du nouveau mode
* \return int > 0 si ok , < 0 si ko
*/
function mode_reglement ( $mode_reglement_id )
{
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( 'Facture::mode_reglement(' . $mode_reglement_id . ')' , LOG_DEBUG );
2006-12-09 15:28:43 +01:00
if ( $this -> statut >= 0 && $this -> paye == 0 )
{
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture' ;
$sql .= ' SET fk_mode_reglement = ' . $mode_reglement_id ;
$sql .= ' WHERE rowid=' . $this -> id ;
if ( $this -> db -> query ( $sql ) )
{
$this -> mode_reglement_id = $mode_reglement_id ;
return 1 ;
}
else
{
dolibarr_syslog ( 'Facture::mode_reglement Erreur ' . $sql . ' - ' . $this -> db -> error ());
$this -> error = $this -> db -> error ();
return - 1 ;
}
}
else
{
dolibarr_syslog ( 'Facture::mode_reglement, etat facture incompatible' );
$this -> error = 'Etat facture incompatible ' . $this -> statut . ' ' . $this -> paye ;
return - 2 ;
}
}
/**
* \brief Renvoi si les lignes de facture sont ventil<EFBFBD> es et / ou export<EFBFBD> es en compta
* \param user Utilisateur cr<EFBFBD> ant la demande
* \return int < 0 si ko , 0 = non , 1 = oui
*/
function getVentilExportCompta ()
{
// On v<> rifie si les lignes de factures ont <20> t<EFBFBD> export<72> es en compta et/ou ventil<69> es
$ventilExportCompta = 0 ;
for ( $i = 0 ; $i < sizeof ( $this -> lignes ) ; $i ++ )
{
if ( $this -> lignes [ $i ] -> export_compta <> 0 && $this -> lignes [ $i ] -> code_ventilation <> 0 )
{
$ventilExportCompta ++ ;
}
}
if ( $ventilExportCompta <> 0 )
{
return 1 ;
}
else
{
return 0 ;
}
}
/**
* \brief Renvoi si une facture peut etre supprim<EFBFBD> e compl<EFBFBD> tement .
* La r<EFBFBD> gle est la suivante :
* Si facture derni<EFBFBD> re , non provisoire , sans paiement et non export<EFBFBD> en compta -> oui fin de r<EFBFBD> gle
* Si facture brouillon et provisoire -> oui
* \return int < 0 si ko , 0 = non , 1 = oui
*/
function is_erasable ()
{
global $conf ;
// on v<> rifie si la facture est en num<75> rotation provisoire
$facref = substr ( $this -> ref , 1 , 4 );
// Si facture non brouillon et non provisoire
if ( $facref != 'PROV' && ! $conf -> comptaexpert -> enabled && $conf -> global -> FACTURE_ENABLE_EDITDELETE )
{
// On ne peut supprimer que la derni<6E> re facture valid<69> e
// pour ne pas avoir de trou dans la num<75> rotation
$sql = " SELECT MAX(facnumber) " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " facture " ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$maxfacnumber = $this -> db -> fetch_row ( $resql );
}
2006-07-16 13:51:11 +02:00
2006-12-09 15:28:43 +01:00
$ventilExportCompta = $this -> getVentilExportCompta ();
2006-07-15 20:29:46 +02:00
2006-12-09 15:28:43 +01:00
// Si derniere facture et si non ventil<69> e, on peut supprimer
if ( $maxfacnumber [ 0 ] == $this -> ref && $ventilExportCompta == 0 )
{
return 1 ;
}
}
else if ( $this -> statut == 0 && $facref == 'PROV' ) // Si facture brouillon et provisoire
{
return 1 ;
}
return 0 ;
}
/**
2007-01-05 10:21:34 +01:00
\brief Renvoi liste des factures remplacables
2007-03-06 17:14:14 +01:00
Statut valid<EFBFBD> e ou abandonn<EFBFBD> e pour raison autre + non pay<EFBFBD> e + aucun paiement + pas deja remplac<EFBFBD> e
2007-02-04 02:15:51 +01:00
\param socid Id societe
2007-01-05 10:21:34 +01:00
\return array Tableau des factures ( 'id' => id , 'ref' => ref , 'statut' => status )
2006-12-09 15:28:43 +01:00
*/
function list_replacable_invoices ( $socid = 0 )
{
global $conf ;
$return = array ();
$sql = " SELECT f.rowid as rowid, f.facnumber, f.fk_statut, " ;
$sql .= " ff.rowid as rowidnext " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " facture as f " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " paiement_facture as pf ON f.rowid = pf.fk_facture " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " facture as ff ON f.rowid = ff.fk_facture_source " ;
2007-03-06 17:14:14 +01:00
$sql .= " WHERE (f.fk_statut = 1 OR (f.fk_statut = 3 AND f.close_code = 'abandon')) " ;
2007-02-04 02:15:51 +01:00
$sql .= " AND f.paye = 0 " ; // Pas class<73> e pay<61> e compl<70> tement
$sql .= " AND pf.fk_paiement IS NULL " ; // Aucun paiement deja fait
$sql .= " AND ff.fk_statut IS NULL " ; // Renvoi vrai si pas facture de remplacement
2006-12-09 15:28:43 +01:00
if ( $socid > 0 ) $sql .= " AND f.fk_soc = " . $socid ;
$sql .= " ORDER BY f.facnumber " ;
dolibarr_syslog ( " Facture.class::list_replacable_invoices sql= $sql " );
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
while ( $obj = $this -> db -> fetch_object ( $resql ))
{
$return [ $obj -> rowid ] = array ( 'id' => $obj -> rowid ,
'ref' => $obj -> facnumber ,
'status' => $obj -> fk_status );
}
//print_r($return);
return $return ;
}
else
{
$this -> error = $this -> db -> error ();
dolibarr_syslog ( " Facture.class::list_replacable_invoices " . $this -> error );
return - 1 ;
}
}
/**
* \brief Renvoi liste des factures qualifiables pour avoir
2007-02-04 02:15:51 +01:00
* Statut >= valid<EFBFBD> e + class<EFBFBD> e pay<EFBFBD> e completement ou class<EFBFBD> e pay<EFBFBD> e partiellement + pas deja remplac<EFBFBD> e
2007-01-20 13:15:34 +01:00
* \param socid Id societe
2006-12-09 15:28:43 +01:00
* \return array Tableau des factures ( $id => $ref )
*/
function list_qualified_avoir_invoices ( $socid = 0 )
{
global $conf ;
$return = array ();
$sql = " SELECT f.rowid as rowid, f.facnumber " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " facture as f " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " paiement_facture as pf ON f.rowid = pf.fk_facture " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " facture as ff ON (f.rowid = ff.fk_facture_source AND ff.type=1) " ;
2007-01-20 13:15:34 +01:00
$sql .= " WHERE f.fk_statut >= 1 " ;
2007-02-04 02:15:51 +01:00
$sql .= " AND (f.paye = 1 " ; // Class<73> e pay<61> e compl<70> tement
$sql .= " OR f.close_code IS NOT NULL) " ; // Class<73> e pay<61> e partiellement
$sql .= " AND ff.type IS NULL " ; // Renvoi vrai si pas facture de remplacement
2006-12-09 15:28:43 +01:00
if ( $socid > 0 ) $sql .= " AND f.fk_soc = " . $socid ;
$sql .= " ORDER BY f.facnumber " ;
dolibarr_syslog ( " Facture.class::list_qualified_avoir_invoices sql= $sql " );
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
while ( $obj = $this -> db -> fetch_object ( $resql ))
{
$return [ $obj -> rowid ] = $obj -> facnumber ;
}
return $return ;
}
else
{
$this -> error = $this -> db -> error ();
dolibarr_syslog ( " Facture.class::list_avoir_invoices " . $this -> error );
return - 1 ;
}
}
/**
* \brief Cr<EFBFBD> <EFBFBD> une demande de pr<EFBFBD> l<EFBFBD> vement
* \param user Utilisateur cr<EFBFBD> ant la demande
* \return int < 0 si ko , > 0 si ok
*/
function demande_prelevement ( $user )
{
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( " Facture::demande_prelevement " , LOG_DEBUG );
2006-12-09 15:28:43 +01:00
$soc = new Societe ( $this -> db );
$soc -> id = $this -> socid ;
$soc -> rib ();
if ( $this -> statut > 0 && $this -> paye == 0 && $this -> mode_reglement_id == 3 )
{
$sql = 'SELECT count(*) FROM ' . MAIN_DB_PREFIX . 'prelevement_facture_demande' ;
$sql .= ' WHERE fk_facture=' . $this -> id ;
$sql .= ' AND traite = 0' ;
if ( $this -> db -> query ( $sql ) )
{
$row = $this -> db -> fetch_row ();
if ( $row [ 0 ] == 0 )
{
$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'prelevement_facture_demande' ;
$sql .= ' (fk_facture, amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib)' ;
$sql .= ' VALUES (' . $this -> id ;
$sql .= " ,' " . price2num ( $this -> total_ttc ) . " ' " ;
$sql .= ',now(),' . $user -> id ;
$sql .= " ,' " . $soc -> bank_account -> code_banque . " ' " ;
$sql .= " ,' " . $soc -> bank_account -> code_guichet . " ' " ;
$sql .= " ,' " . $soc -> bank_account -> number . " ' " ;
$sql .= " ,' " . $soc -> bank_account -> cle_rib . " ') " ;
2006-02-09 13:25:34 +01:00
if ( $this -> db -> query ( $sql ) )
2006-12-09 15:28:43 +01:00
{
return 1 ;
}
2006-02-09 13:25:34 +01:00
else
2006-12-09 15:28:43 +01:00
{
$this -> error = $this -> db -> error ();
dolibarr_syslog ( 'Facture::DemandePrelevement Erreur' );
return - 1 ;
}
}
else
{
$this -> error = " Une demande existe d<> j<EFBFBD> " ;
dolibarr_syslog ( 'Facture::DemandePrelevement Impossible de cr<63> er une demande, demande d<> ja en cours' );
}
}
else
{
$this -> error = $this -> db -> error ();
dolibarr_syslog ( 'Facture::DemandePrelevement Erreur -2' );
return - 2 ;
}
}
else
{
$this -> error = " Etat facture incompatible avec l'action " ;
dolibarr_syslog ( " Facture::DemandePrelevement Etat facture incompatible $this->statut , $this->paye , $this->mode_reglement_id " );
return - 3 ;
}
}
/**
* \brief Supprime une demande de pr<EFBFBD> l<EFBFBD> vement
* \param user utilisateur cr<EFBFBD> ant la demande
* \param did id de la demande a supprimer
*/
function demande_prelevement_delete ( $user , $did )
{
$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'prelevement_facture_demande' ;
$sql .= ' WHERE rowid = ' . $did ;
$sql .= ' AND traite = 0' ;
if ( $this -> db -> query ( $sql ) )
{
return 0 ;
}
else
{
dolibarr_syslog ( 'Facture::DemandePrelevement Erreur' );
return - 1 ;
}
}
/**
* \brief Stocke un num<EFBFBD> ro de rang pour toutes les lignes de
* detail d 'une facture qui n' en ont pas .
*/
function line_order ()
{
$sql = 'SELECT count(rowid) FROM ' . MAIN_DB_PREFIX . 'facturedet' ;
$sql .= ' WHERE fk_facture=' . $this -> id ;
$sql .= ' AND rang = 0' ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$row = $this -> db -> fetch_row ( $resql );
$nl = $row [ 0 ];
}
if ( $nl > 0 )
{
$sql = 'SELECT rowid FROM ' . MAIN_DB_PREFIX . 'facturedet' ;
$sql .= ' WHERE fk_facture=' . $this -> id ;
$sql .= ' ORDER BY rang ASC, rowid ASC' ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
while ( $i < $num )
{
$row = $this -> db -> fetch_row ( $resql );
$li [ $i ] = $row [ 0 ];
$i ++ ;
}
}
for ( $i = 0 ; $i < sizeof ( $li ) ; $i ++ )
{
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facturedet SET rang = ' . ( $i + 1 );
$sql .= ' WHERE rowid = ' . $li [ $i ];
if ( ! $this -> db -> query ( $sql ) )
{
dolibarr_syslog ( $this -> db -> error ());
}
}
}
}
function line_up ( $rowid )
{
$this -> line_order ();
/* Lecture du rang de la ligne */
$sql = 'SELECT rang FROM ' . MAIN_DB_PREFIX . 'facturedet' ;
$sql .= ' WHERE rowid =' . $rowid ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$row = $this -> db -> fetch_row ( $resql );
$rang = $row [ 0 ];
}
if ( $rang > 1 )
{
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facturedet SET rang = ' . $rang ;
$sql .= ' WHERE fk_facture = ' . $this -> id ;
$sql .= ' AND rang = ' . ( $rang - 1 );
if ( $this -> db -> query ( $sql ) )
{
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facturedet SET rang = ' . ( $rang - 1 );
$sql .= ' WHERE rowid = ' . $rowid ;
if ( ! $this -> db -> query ( $sql ) )
{
dolibarr_print_error ( $this -> db );
}
}
else
{
dolibarr_print_error ( $this -> db );
}
}
}
function line_down ( $rowid )
{
$this -> line_order ();
/* Lecture du rang de la ligne */
$sql = 'SELECT rang FROM ' . MAIN_DB_PREFIX . 'facturedet' ;
$sql .= ' WHERE rowid =' . $rowid ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$row = $this -> db -> fetch_row ( $resql );
$rang = $row [ 0 ];
}
/* Lecture du rang max de la facture */
$sql = 'SELECT max(rang) FROM ' . MAIN_DB_PREFIX . 'facturedet' ;
$sql .= ' WHERE fk_facture =' . $this -> id ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$row = $this -> db -> fetch_row ( $resql );
$max = $row [ 0 ];
}
if ( $rang < $max )
{
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facturedet SET rang = ' . $rang ;
$sql .= ' WHERE fk_facture = ' . $this -> id ;
$sql .= ' AND rang = ' . ( $rang + 1 );
if ( $this -> db -> query ( $sql ) )
{
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facturedet SET rang = ' . ( $rang + 1 );
$sql .= ' WHERE rowid = ' . $rowid ;
if ( ! $this -> db -> query ( $sql ) )
{
dolibarr_print_error ( $this -> db );
}
}
else
{
dolibarr_print_error ( $this -> db );
}
}
}
/**
* \brief Charge indicateurs this -> nbtodo et this -> nbtodolate de tableau de bord
* \param user Objet user
* \return int < 0 si ko , > 0 si ok
*/
function load_board ( $user )
{
global $conf , $user ;
$this -> nbtodo = $this -> nbtodolate = 0 ;
$sql = 'SELECT f.rowid,' . $this -> db -> pdate ( 'f.date_lim_reglement' ) . ' as datefin' ;
if ( ! $user -> rights -> commercial -> client -> voir && ! $user -> societe_id ) $sql .= " , sc.fk_soc, sc.fk_user " ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'facture as f' ;
if ( ! $user -> rights -> commercial -> client -> voir && ! $user -> societe_id ) $sql .= " , " . MAIN_DB_PREFIX . " societe_commerciaux as sc " ;
$sql .= ' WHERE f.paye=0 AND f.fk_statut = 1' ;
if ( $user -> societe_id ) $sql .= ' AND f.fk_soc = ' . $user -> societe_id ;
if ( ! $user -> rights -> commercial -> client -> voir && ! $user -> societe_id ) $sql .= " AND f.fk_soc = sc.fk_soc AND sc.fk_user = " . $user -> id ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
while ( $obj = $this -> db -> fetch_object ( $resql ))
{
$this -> nbtodo ++ ;
if ( $obj -> datefin < ( time () - $conf -> facture -> client -> warning_delay )) $this -> nbtodolate ++ ;
}
return 1 ;
}
else
{
dolibarr_print_error ( $this -> db );
$this -> error = $this -> db -> error ();
return - 1 ;
}
}
/* gestion des contacts d'une facture */
/**
* \brief Retourne id des contacts clients de facturation
* \return array Liste des id contacts facturation
*/
function getIdBillingContact ()
{
return $this -> getIdContact ( 'external' , 'BILLING' );
}
/**
* \brief Retourne id des contacts clients de livraison
* \return array Liste des id contacts livraison
*/
function getIdShippingContact ()
{
return $this -> getIdContact ( 'external' , 'SHIPPING' );
}
/**
* \brief Initialise la facture avec valeurs fictives al<EFBFBD> atoire
* Sert <EFBFBD> g<EFBFBD> n<EFBFBD> rer une facture pour l ' aperu des mod<EFBFBD> les ou demo
*/
function initAsSpecimen ()
{
global $user , $langs ;
// Charge tableau des id de soci<63> t<EFBFBD> socids
$socids = array ();
$sql = " SELECT idp FROM " . MAIN_DB_PREFIX . " societe WHERE client=1 LIMIT 10 " ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$num_socs = $this -> db -> num_rows ( $resql );
$i = 0 ;
while ( $i < $num_socs )
{
$i ++ ;
$row = $this -> db -> fetch_row ( $resql );
$socids [ $i ] = $row [ 0 ];
}
}
// Charge tableau des produits prodids
$prodids = array ();
$sql = " SELECT rowid FROM " . MAIN_DB_PREFIX . " product WHERE envente=1 " ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$num_prods = $this -> db -> num_rows ( $resql );
$i = 0 ;
while ( $i < $num_prods )
{
$i ++ ;
$row = $this -> db -> fetch_row ( $resql );
$prodids [ $i ] = $row [ 0 ];
}
}
// Initialise param<61> tres
$this -> id = 0 ;
$this -> ref = 'SPECIMEN' ;
$this -> specimen = 1 ;
$socid = rand ( 1 , $num_socs );
$this -> socid = $socids [ $socid ];
$this -> date = time ();
$this -> date_lim_reglement = $this -> date + 3600 * 24 * 30 ;
$this -> cond_reglement_code = 'RECEP' ;
$this -> mode_reglement_code = 'CHQ' ;
$this -> note_public = 'SPECIMEN' ;
$nbp = 5 ;
$xnbp = 0 ;
while ( $xnbp < $nbp )
{
$ligne = new FactureLigne ( $this -> db );
$ligne -> desc = $langs -> trans ( " Description " ) . " " . $xnbp ;
$ligne -> qty = 1 ;
$ligne -> subprice = 100 ;
$ligne -> price = 100 ;
$ligne -> tva_tx = 19.6 ;
$prodid = rand ( 1 , $num_prods );
$ligne -> produit_id = $prodids [ $prodid ];
$this -> lignes [ $xnbp ] = $ligne ;
$xnbp ++ ;
}
$this -> amount_ht = $xnbp * 100 ;
$this -> total_ht = $xnbp * 100 ;
$this -> total_tva = $xnbp * 19.6 ;
$this -> total_ttc = $xnbp * 119.6 ;
}
2006-06-11 02:36:17 +02:00
2006-02-09 13:25:34 +01:00
}
/**
2006-12-09 15:28:43 +01:00
\class FactureLigne
\brief Classe permettant la gestion des lignes de factures
\remarks Gere des lignes de la table llx_facturedet
2006-02-09 13:25:34 +01:00
*/
class FactureLigne
{
2006-12-09 15:28:43 +01:00
var $db ;
var $error ;
2007-01-05 10:21:34 +01:00
//! From llx_facturedet
2006-12-09 15:28:43 +01:00
var $rowid ;
2007-01-05 10:21:34 +01:00
//! Id facture
var $fk_facture ;
//! Description ligne
var $desc ;
2006-12-15 13:00:18 +01:00
var $fk_product ; // Id produit pr<70> d<EFBFBD> fini
2006-12-09 15:28:43 +01:00
2006-12-15 13:00:18 +01:00
var $qty ; // Quantit<69> (exemple 2)
var $tva_tx ; // Taux tva produit/service (exemple 19.6)
2006-12-09 15:28:43 +01:00
var $subprice ; // P.U. HT (exemple 100)
var $remise_percent ; // % de la remise ligne (exemple 20%)
var $rang = 0 ;
var $info_bits = 0 ; // Bit 0: 0 si TVA normal - 1 si TVA NPR
2007-01-05 10:21:34 +01:00
//! Bit 1: 0 si ligne normal - 1 si bit discount
//! Total HT de la ligne toute quantit<69> et incluant la remise ligne
var $total_ht ;
//! Total TVA de la ligne toute quantit<69> et incluant la remise ligne
var $total_tva ;
//! Total TTC de la ligne toute quantit<69> et incluant la remise ligne
var $total_ttc ;
2006-12-09 15:28:43 +01:00
var $fk_code_ventilation = 0 ;
var $fk_export_compta = 0 ;
var $date_start ;
var $date_end ;
// Ne plus utiliser
var $price ; // P.U. HT apres remise % de ligne (exemple 80)
var $remise ; // Montant calcul<75> de la remise % sur PU HT (exemple 20)
// From llx_product
var $ref ; // Reference produit
var $libelle ; // Label produit
var $product_desc ; // Description produit
/**
2007-01-05 10:21:34 +01:00
\brief Constructeur d ' objets ligne de facture
\param DB handler d ' acc<EFBFBD> s base de donn<EFBFBD> e
2006-12-09 15:28:43 +01:00
*/
function FactureLigne ( $DB )
{
$this -> db = $DB ;
}
/**
2007-01-05 10:21:34 +01:00
\brief Recup<EFBFBD> re l ' objet ligne de facture
\param rowid id de la ligne de facture
2006-12-09 15:28:43 +01:00
*/
function fetch ( $rowid )
{
$sql = 'SELECT fd.rowid, fd.fk_facture, fd.fk_product, fd.description, fd.price, fd.qty, fd.tva_taux,' ;
$sql .= ' fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice,' ;
$sql .= ' ' . $this -> db -> pdate ( 'fd.date_start' ) . ' as date_start,' . $this -> db -> pdate ( 'fd.date_end' ) . ' as date_end,' ;
$sql .= ' fd.info_bits, fd.total_ht, fd.total_tva, fd.total_ttc, fd.rang,' ;
$sql .= ' fd.fk_code_ventilation, fd.fk_export_compta,' ;
$sql .= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'facturedet as fd' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'product as p ON fd.fk_product = p.rowid' ;
$sql .= ' WHERE fd.rowid = ' . $rowid ;
$result = $this -> db -> query ( $sql );
if ( $result )
{
$objp = $this -> db -> fetch_object ( $result );
$this -> rowid = $objp -> rowid ;
$this -> fk_facture = $objp -> fk_facture ;
$this -> desc = $objp -> description ;
$this -> qty = $objp -> qty ;
$this -> subprice = $objp -> subprice ;
$this -> tva_tx = $objp -> tva_taux ;
$this -> remise_percent = $objp -> remise_percent ;
$this -> fk_remise_except = $objp -> fk_remise_except ;
$this -> produit_id = $objp -> fk_product ;
$this -> fk_product = $objp -> fk_product ;
$this -> date_start = $objp -> date_start ;
$this -> date_end = $objp -> date_end ;
$this -> info_bits = $objp -> info_bits ;
$this -> total_ht = $objp -> total_ht ;
$this -> total_tva = $objp -> total_tva ;
$this -> total_ttc = $objp -> total_ttc ;
$this -> fk_code_ventilation = $objp -> fk_code_ventilation ;
$this -> fk_export_compta = $objp -> fk_export_compta ;
$this -> rang = $objp -> rang ;
2006-09-09 14:41:13 +02:00
// Ne plus utiliser
2006-12-09 15:28:43 +01:00
$this -> price = $objp -> price ;
$this -> remise = $objp -> remise ;
$this -> ref = $objp -> product_ref ;
$this -> libelle = $objp -> product_libelle ;
$this -> product_desc = $objp -> product_desc ;
$this -> db -> free ( $result );
}
else
{
dolibarr_print_error ( $this -> db );
}
}
/**
2006-12-15 13:00:18 +01:00
* \brief Ins<EFBFBD> re l ' objet ligne de facture en base
* \return int < 0 si ko , > 0 si ok
2006-12-09 15:28:43 +01:00
*/
function insert ()
{
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( " FactureLigne::Insert rang= " . $this -> rang , LOG_DEBUG );
2006-12-09 15:28:43 +01:00
$this -> db -> begin ();
$rangtouse = $this -> rang ;
if ( $rangtouse == - 1 )
{
// R<> cup<75> re rang max de la facture dans $rangmax
$sql = 'SELECT max(rang) as max FROM ' . MAIN_DB_PREFIX . 'facturedet' ;
$sql .= ' WHERE fk_facture =' . $this -> fk_facture ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$obj = $this -> db -> fetch_object ( $resql );
$rangtouse = $obj -> max + 1 ;
}
else
{
dolibarr_print_error ( $this -> db );
$this -> db -> rollback ();
return - 1 ;
}
}
// Insertion dans base de la ligne
$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'facturedet' ;
$sql .= ' (fk_facture, description, qty, tva_taux,' ;
$sql .= ' fk_product, remise_percent, subprice, price, remise, fk_remise_except,' ;
$sql .= ' date_start, date_end, fk_code_ventilation, fk_export_compta, ' ;
$sql .= ' rang,' ;
$sql .= ' info_bits, total_ht, total_tva, total_ttc)' ;
$sql .= " VALUES ( " . $this -> fk_facture . " , " ;
$sql .= " ' " . addslashes ( $this -> desc ) . " ', " ;
$sql .= " ' " . price2num ( $this -> qty ) . " ', " ;
$sql .= " ' " . price2num ( $this -> txtva ) . " ', " ;
if ( $this -> fk_product ) { $sql .= " ' " . $this -> fk_product . " ', " ; }
else { $sql .= 'null,' ; }
$sql .= " ' " . price2num ( $this -> remise_percent ) . " ', " ;
$sql .= " ' " . price2num ( $this -> subprice ) . " ', " ;
$sql .= " ' " . price2num ( $this -> price ) . " ', " ;
$sql .= " ' " . price2num ( $this -> remise ) . " ', " ;
if ( $this -> fk_remise_except ) $sql .= $this -> fk_remise_except . " , " ;
else $sql .= 'null,' ;
if ( $this -> date_start ) { $sql .= " ' " . $this -> date_start . " ', " ; }
else { $sql .= 'null,' ; }
if ( $this -> date_end ) { $sql .= " ' " . $this -> date_end . " ', " ; }
else { $sql .= 'null,' ; }
$sql .= ' ' . $this -> fk_code_ventilation . ',' ;
$sql .= ' ' . $this -> fk_export_compta . ',' ;
$sql .= ' ' . $rangtouse . ',' ;
$sql .= " ' " . $this -> info_bits . " ', " ;
$sql .= " ' " . price2num ( $this -> total_ht ) . " ', " ;
$sql .= " ' " . price2num ( $this -> total_tva ) . " ', " ;
$sql .= " ' " . price2num ( $this -> total_ttc ) . " ' " ;
$sql .= ')' ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$this -> rowid = $this -> db -> last_insert_id ( MAIN_DB_PREFIX . 'facturedet' );
// Appel des triggers
include_once ( DOL_DOCUMENT_ROOT . " /interfaces.class.php " );
$interface = new Interfaces ( $this -> db );
$result = $interface -> run_triggers ( 'LINEBILL_INSERT' , $this , $user , $langs , $conf );
// Fin appel triggers
$this -> db -> commit ();
return $this -> rowid ;
}
else
{
$this -> error = $this -> db -> error ();
dolibarr_syslog ( " FactureLigne::insert Error " . $this -> error );
$this -> db -> rollback ();
return - 2 ;
}
}
/**
2006-12-15 13:00:18 +01:00
* \brief Mise a jour de l ' objet ligne de facture en base
* \return int < 0 si ko , > 0 si ok
2006-12-09 15:28:43 +01:00
*/
function update ()
{
$this -> db -> begin ();
// Mise a jour ligne en base
$sql = " UPDATE " . MAIN_DB_PREFIX . " facturedet SET " ;
$sql .= " description=' " . addslashes ( $this -> desc ) . " ' " ;
$sql .= " ,subprice=' " . price2num ( $this -> subprice ) . " ' " ;
$sql .= " ,price=' " . price2num ( $this -> price ) . " ' " ;
$sql .= " ,remise=' " . price2num ( $this -> remise ) . " ' " ;
$sql .= " ,remise_percent=' " . price2num ( $this -> remise_percent ) . " ' " ;
if ( $this -> fk_remise_except ) $sql .= " ,fk_remise_except= " . $this -> fk_remise_except ;
else $sql .= " ,fk_remise_except=null " ;
$sql .= " ,tva_taux=' " . price2num ( $this -> tva_tx ) . " ' " ;
$sql .= " ,qty=' " . price2num ( $this -> qty ) . " ' " ;
if ( $this -> date_start ) { $sql .= " ,date_start=' " . $this -> date_start . " ' " ; }
else { $sql .= ',date_start=null' ; }
if ( $this -> date_end ) { $sql .= " ,date_end=' " . $this -> date_end . " ' " ; }
else { $sql .= ',date_end=null' ; }
$sql .= " ,rang=' " . $this -> rang . " ' " ;
$sql .= " ,info_bits=' " . $this -> info_bits . " ' " ;
$sql .= " ,total_ht=' " . price2num ( $this -> total_ht ) . " ' " ;
$sql .= " ,total_tva=' " . price2num ( $this -> total_tva ) . " ' " ;
$sql .= " ,total_ttc=' " . price2num ( $this -> total_ttc ) . " ' " ;
$sql .= " WHERE rowid = " . $this -> rowid ;
dolibarr_syslog ( " FactureLigne::update sql= $sql " );
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$this -> db -> commit ();
return 1 ;
}
else
{
$this -> error = $this -> db -> error ();
dolibarr_syslog ( " FactureLigne::update Error " . $this -> error );
$this -> db -> rollback ();
return - 2 ;
}
}
/**
* \brief Mise a jour en base des champs total_xxx de ligne de facture
* \return int < 0 si ko , > 0 si ok
*/
function update_total ()
{
$this -> db -> begin ();
2007-01-05 10:21:34 +01:00
dolibarr_syslog ( " FactureLigne::update_total " , LOG_DEBUG );
2006-12-09 15:28:43 +01:00
// Mise a jour ligne en base
$sql = " UPDATE " . MAIN_DB_PREFIX . " facturedet SET " ;
$sql .= " total_ht=' " . price2num ( $this -> total_ht ) . " ' " ;
$sql .= " ,total_tva=' " . price2num ( $this -> total_tva ) . " ' " ;
$sql .= " ,total_ttc=' " . price2num ( $this -> total_ttc ) . " ' " ;
$sql .= " WHERE rowid = " . $this -> rowid ;
2007-01-05 10:21:34 +01:00
2006-12-09 15:28:43 +01:00
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$this -> db -> commit ();
return 1 ;
}
else
{
$this -> error = $this -> db -> error ();
dolibarr_syslog ( " FactureLigne::update_total Error " . $this -> error );
$this -> db -> rollback ();
return - 2 ;
}
}
2006-02-09 13:25:34 +01:00
}
?>