diff --git a/htdocs/admin/produit.php b/htdocs/admin/produit.php index 5028012cc31..aedcf8c193e 100644 --- a/htdocs/admin/produit.php +++ b/htdocs/admin/produit.php @@ -262,7 +262,7 @@ print ""; print ''; print ''; -// Utilisation de l'�cotaxe +// Utilisation de l'ecotaxe $var=!$var; print "
"; print ""; diff --git a/htdocs/comm/pre.inc.php b/htdocs/comm/pre.inc.php index a74df6ba49a..80240768cfd 100644 --- a/htdocs/comm/pre.inc.php +++ b/htdocs/comm/pre.inc.php @@ -35,7 +35,7 @@ function llxHeader($head = "", $title = "") $langs->load("companies"); $langs->load("commercial"); - top_menu($head, $title); + top_menu($head, $langs->trans($title)); $menu = new Menu(); diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index a7c08218a92..6b28460d7b2 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -615,32 +615,39 @@ if ($_POST['action'] == "addligne" && $user->rights->propale->creer) $info_bits=0; if ($tva_npr) $info_bits |= 0x01; - // Insert line - $result=$propal->addline( - $_POST['propalid'], - $desc, - $pu_ht, - $_POST['qty'], - $tva_tx, - $_POST['idprod'], - $_POST['remise_percent'], - $price_base_type, - $pu_ttc, - $info_bits - ); - - if ($result > 0) + if ($prod->price_min && (price2num($pu_ht)*(1-price2num($_POST['remise_percent'])/100) < price2num($prod->price_min))) { - if ($_REQUEST['lang_id']) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($_REQUEST['lang_id']); - } - propale_pdf_create($db, $propal->id, $propal->modelpdf, $outputlangs); + $mesg = '
'.$langs->trans("CantBeLessThanMinPrice",price2num($prod->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'
' ; } else { - $mesg='
'.$propal->error.'
'; + // Insert line + $result=$propal->addline( + $_POST['propalid'], + $desc, + $pu_ht, + $_POST['qty'], + $tva_tx, + $_POST['idprod'], + $_POST['remise_percent'], + $price_base_type, + $pu_ttc, + $info_bits + ); + + if ($result > 0) + { + if ($_REQUEST['lang_id']) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($_REQUEST['lang_id']); + } + propale_pdf_create($db, $propal->id, $propal->modelpdf, $outputlangs); + } + else + { + $mesg='
'.$propal->error.'
'; + } } } @@ -662,21 +669,32 @@ if ($_POST['action'] == 'updateligne' && $user->rights->propale->creer && $_POST $vat_rate=$_POST['tva_tx']; $vat_rate=eregi_replace('\*','',$vat_rate); - $result = $propal->updateline($_POST['lineid'], - $_POST['subprice'], - $_POST['qty'], - $_POST['remise_percent'], - $vat_rate, - $_POST['desc'], - 'HT', - $info_bits); - - if ($_REQUEST['lang_id']) + // On vérifie que le prix minimum est respecté + $productid = $_POST['productid'] ; + $pruduct = new Product($db) ; + $pruduct->fetch($productid) ; + if ($pruduct->price_min && ($_POST['productid']!='')&&( price2num($_POST['subprice'])*(1-price2num($_POST['remise_percent'])/100) < price2num($pruduct->price_min))) { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($_REQUEST['lang_id']); + $mesg = '
'.$langs->trans("CantBeLessThanMinPrice",price2num($pruduct->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'
' ; + } + else + { + $result = $propal->updateline($_POST['lineid'], + $_POST['subprice'], + $_POST['qty'], + $_POST['remise_percent'], + $vat_rate, + $_POST['desc'], + 'HT', + $info_bits); + + if ($_REQUEST['lang_id']) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($_REQUEST['lang_id']); + } + propale_pdf_create($db, $propal->id, $propal->modelpdf, $outputlangs); } - propale_pdf_create($db, $propal->id, $propal->modelpdf, $outputlangs); } /* @@ -1381,6 +1399,7 @@ if ($_GET['propalid'] > 0) print ''; // ancre pour retourner sur la ligne if ($objp->fk_product > 0) { + print ''; print ''; if ($objp->fk_product_type==1) print img_object($langs->trans('ShowService'),'service'); else print img_object($langs->trans('ShowProduct'),'product'); diff --git a/htdocs/comm/stats.php b/htdocs/comm/stats.php new file mode 100644 index 00000000000..445b6c3f639 --- /dev/null +++ b/htdocs/comm/stats.php @@ -0,0 +1,214 @@ + + * Copyright (C) 2004-2008 Laurent Destailleur + * Copyright (C) 2005-2008 Regis Houssin + * + * 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. + */ + +/** + \file htdocs/comm/index.php + \ingroup commercial + \brief Page acceuil de la zone commercial cliente + \version $Id$ +*/ + +require("./pre.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/dolgraph.class.php"); + +llxHeader('',"Stats"); + +/************** + * Paramètrage + *************/ +// Dossier où générer les fichiers +$dir = $conf->commercial->dir_temp . '/' .$user->id ; +if(!is_dir($dir)) mkdir($dir,0777,true) ; + +// graphes +$graphwidth = 380 ; +$graphheight = 160 ; + + +// Chaine contenant les messages d'erreur +$msq = '' ; + +// Date de début du graphe +$date_debut = time() ; +$annees = "" ; +if ($conf->global->SOCIETE_FISCAL_MONTH_START < dolibarr_date("m",time()) ){ + // Si le mois actuel est plus grand, l'année de départ est là même que l'année actuelle + $date_debut = mktime(0,0,0,$conf->global->SOCIETE_FISCAL_MONTH_START,1,dolibarr_date("Y",time())) ; + $annees = dolibarr_date("Y",time()) ; +} else { + // Sinon le début de l'année comptable était l'année d'avant + $date_debut = mktime(0,0,0,$conf->global->SOCIETE_FISCAL_MONTH_START,1,dolibarr_date("Y",time())-1) ; + $annees = (dolibarr_date("Y",time())-1).' - '.(dolibarr_date("Y",time())) ; +} + +/********************************************** + * Récupération et génération des Infomations + **********************************************/ +$sql = "SELECT sum(d.qty * d.price) as CAMois, sum( d.qty * (d.price - p.price_min) ) as MRMois, date_format(c.date_valid, '%Y%m') as date, date_format(c.date_valid, '%b') as month"; +$sql .= " FROM ".MAIN_DB_PREFIX."commandedet as d, ".MAIN_DB_PREFIX."commande as c, ".MAIN_DB_PREFIX."product as p"; +$sql .= " WHERE c.rowid = d.fk_commande and d.fk_product = p.rowid"; +$sql .= " AND c.fk_user_author = ".$user->id; +$sql .= " AND c.date_valid > ".$db->idate($date_debut)." AND c.date_valid < NOW()"; +$sql .= " GROUP BY date_format(c.date_valid,'%Y%m') ASC ;"; + +$result = $db->query($sql) ; + +// On Récupère tout à la fois +$recapAnneeCA = array() ; +$recapMoisCA = array() ; +$recapAnneeMR = array() ; +$recapMoisMR = array() ; +if($result){ + if($db->num_rows($result)>0){ + while($obj = $db->fetch_object($result)){ + if($obj->date != dolibarr_date("Ym",time())){ + $recapAnneeCA[] = array( $obj->month, $obj->CAMois ) ; + $recapAnneeMR[] = array( $obj->month, $obj->MRMois ) ; + }else{ + $recapMoisCA[] = array( $obj->month, $obj->CAMois ) ; + $recapMoisMR[] = array( $obj->month, $obj->MRMois ) ; + } + } + } else { + $mesg = 'Aucune enregistrmeent retourné pour
' ; + } +} else { + $mesg = 'erreur sql : '.$db->error().'
requète : '.$db->lastquery().'
' ; +} + +$graphfiles=array( + 'recapAnneeCA' =>array( + 'file' => 'recapAnneeCA.png', + 'label' => $langs->trans('CAOrder').' - '.$annees, + 'data' => $recapAnneeCA + ), + 'recapAnneeMR' =>array( + 'file' => 'recapAnneeMR.png', + 'label' => $langs->trans('MargeOrder').' - '.$annees, + 'data' => $recapAnneeMR + ), + 'recapMoisCA' =>array( + 'file' => 'recapMoisCA.png', + 'label' => $langs->trans('CAOrder').' '.$langs->trans('FromTo',dolibarr_date("01/m/Y",time()),dolibarr_date("d/m/Y",time())), + 'data' => $recapMoisCA + ), + 'recapMoisMR'=>array( + 'file' => 'recapMoisMR.png', + 'label' => $langs->trans('MargeOrder').' '.$langs->trans('FromTo',dolibarr_date("01/m/Y",time()),dolibarr_date("d/m/Y",time())), + 'data' => $recapMoisMR + ) +) ; + + +/*********************** + * Affichage de graphes + ***********************/ +$px = new DolGraph(); +$msggraph = $px->isGraphKo(); +if (! $mesg) +{ + + foreach($graphfiles as $key => $graph){ + $graph_data = $graph['data'] ; + + if (is_array($graph_data)) + { + $px->SetData($graph_data); + $px->SetMaxValue($px->GetCeilMaxValue()<0?0:$px->GetCeilMaxValue()); + $px->SetMinValue($px->GetFloorMinValue()>0?0:$px->GetFloorMinValue()); + $px->SetWidth($graphwidth); + $px->SetHeight($graphheight); + $px->SetHorizTickIncrement(1); + $px->SetPrecisionY(0); + $px->SetShading(3); + + $px->draw($dir."/".$graph['file']); + + } + else + { + dolibarr_print_error($db,'Error for calculating graph on key='.$key.' - '.$product->error); + } + } + +} else { + $msg.=$msggraph ; +} + +/************ + * Affichage + ************/ +// en-tête +if($mesg) print '
'.$mesg.'
' ; +dolibarr_fiche_head(array(array('stats.php',$langs->trans("Commercial"))), 0, $langs->trans("Stats")); +/***************************** + * Rappel Infos du Commercial + *****************************/ +print ' + + + + + + + + + +
'.$langs->trans("Name").''.$user->nom.'
'.$langs->trans("Surname").''.$user->prenom.'
'.$langs->trans("Login").''.$user->login.'
' ; + +print "" ; // Fin de dolibarr_fiche_head + +/*************************** + * Affichage des Graphiques + ***************************/ +//tableaux +foreach($graphfiles as $graph){ + // données + $url=DOL_URL_ROOT.'/viewimage.php?modulepart=graph_comm&file='.urlencode($user->id .'/'.$graph['file']); + $generateOn = (file_exists($dir."/".$graph['file']))? $langs->trans("GeneratedOn",dolibarr_print_date(filemtime($dir."/".$graph['file']),"dayhour")) : "" ; + + // html + print ' + + + + + + + + + + +
'.$graph['label'].'
+ '.$langs->trans( + + + + '.array2table($graph['data'],0,'','','align="center"').' +
'.$langs->trans("Month").''.$langs->trans("Currency".$conf->monnaie).'
+
'.$generateOn.''.img_picto($langs->trans("ReCalculate"),'refresh').'
' ; +} + +/************** + * Fin de page + **************/ +$db->close(); +llxFooter(); +?> diff --git a/htdocs/commande/fiche.php b/htdocs/commande/fiche.php index d268b87d7e6..18a892bd53d 100644 --- a/htdocs/commande/fiche.php +++ b/htdocs/commande/fiche.php @@ -360,33 +360,40 @@ if ($_POST['action'] == 'addligne' && $user->rights->commande->creer) $info_bits=0; if ($tva_npr) $info_bits |= 0x01; - // Insert line - $result = $commande->addline( - $_POST['id'], - $desc, - $pu_ht, - $_POST['qty'], - $tva_tx, - $_POST['idprod'], - $_POST['remise_percent'], - $info_bits, - '', - $price_base_type, - $pu_ttc - ); - - if ($result > 0) + if($prod->price_min && (price2num($pu_ht)*(1-price2num($_POST['remise_percent'])/100) < price2num($prod->price_min))) { - if ($_REQUEST['lang_id']) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($_REQUEST['lang_id']); - } - commande_pdf_create($db, $commande->id, $commande->modelpdf, $outputlangs); + $mesg = '
'.$langs->trans("CantBeLessThanMinPrice",price2num($prod->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'
' ; } else { - $mesg='
'.$commande->error.'
'; + // Insert line + $result = $commande->addline( + $_POST['id'], + $desc, + $pu_ht, + $_POST['qty'], + $tva_tx, + $_POST['idprod'], + $_POST['remise_percent'], + $info_bits, + '', + $price_base_type, + $pu_ttc + ); + + if ($result > 0) + { + if ($_REQUEST['lang_id']) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($_REQUEST['lang_id']); + } + commande_pdf_create($db, $commande->id, $commande->modelpdf, $outputlangs); + } + else + { + $mesg='
'.$commande->error.'
'; + } } } } @@ -407,31 +414,37 @@ if ($_POST['action'] == 'updateligne' && $user->rights->commande->creer && $_POS $vat_rate=$_POST['tva_tx']; $vat_rate=eregi_replace('\*','',$vat_rate); - $result = $commande->updateline($_POST['elrowid'], - $_POST['eldesc'], - $_POST['pu'], - $_POST['qty'], - $_POST['elremise_percent'], - $vat_rate, - 'HT', - $info_bits - ); - - if ($result >= 0) + if ($pruduct->price_min && ($_POST['productid']!='') && ( price2num($_POST['pu'])*(1-price2num($_POST['elremise_percent'])/100) < price2num($pruduct->price_min))) { - if ($_REQUEST['lang_id']) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($_REQUEST['lang_id']); - } - commande_pdf_create($db, $commande->id, $commande->modelpdf, $outputlangs); + $mesg = '
'.$langs->trans("CantBeLessThanMinPrice",price2num($pruduct->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'
' ; } else { - dolibarr_print_error($db,$commande->error); - exit; + $result = $commande->updateline($_POST['elrowid'], + $_POST['eldesc'], + $_POST['pu'], + $_POST['qty'], + $_POST['elremise_percent'], + $vat_rate, + 'HT', + $info_bits + ); + + if ($result >= 0) + { + if ($_REQUEST['lang_id']) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($_REQUEST['lang_id']); + } + commande_pdf_create($db, $commande->id, $commande->modelpdf, $outputlangs); + } + else + { + dolibarr_print_error($db,$commande->error); + exit; + } } - $_GET['id']=$_POST['id']; // Pour reaffichage de la fiche en cours d'edition } @@ -1557,6 +1570,7 @@ else print '
'; // ancre pour retourner sur la ligne if ($objp->fk_product > 0) { + print ''; print ''; if ($objp->fk_product_type==1) print img_object($langs->trans('ShowService'),'service'); else print img_object($langs->trans('ShowProduct'),'product'); diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 87c32fead81..42ecf7f7342 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -877,23 +877,32 @@ if (($_POST['action'] == 'addligne' || $_POST['action'] == 'addligne_predef') && $info_bits=0; if ($tva_npr) $info_bits |= 0x01; - // Insert line - $result = $fac->addline( - $_POST['facid'], - $desc, - $pu_ht, - $_POST['qty'], - $tva_tx, - $_POST['idprod'], - $_POST['remise_percent'], - $date_start, - $date_end, - 0, - $info_bits, - '', - $price_base_type, - $pu_ttc - ); + + if($prod->price_min && (price2num($pu_ht)*(1-price2num($_POST['remise_percent'])/100) < price2num($prod->price_min))) + { + $fac->error = $langs->trans("CantBeLessThanMinPrice",price2num($prod->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)) ; + $result = -1 ; + } + else + { + // Insert line + $result = $fac->addline( + $_POST['facid'], + $desc, + $pu_ht, + $_POST['qty'], + $tva_tx, + $_POST['idprod'], + $_POST['remise_percent'], + $date_start, + $date_end, + 0, + $info_bits, + '', + $price_base_type, + $pu_ttc + ); + } } if ($result > 0) @@ -935,25 +944,38 @@ if ($_POST['action'] == 'updateligne' && $user->rights->facture->creer && $_POST $vat_rate=$_POST['tva_tx']; $vat_rate=eregi_replace('\*','',$vat_rate); - $result = $fac->updateline($_POST['rowid'], - $_POST['desc'], - $_POST['price'], - $_POST['qty'], - $_POST['remise_percent'], - $date_start, - $date_end, - $vat_rate, - 'HT', - $info_bits - ); - - if ($_REQUEST['lang_id']) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($_REQUEST['lang_id']); + // On vérifie que le prix minimum est respecté + if($_POST['productid']!=''){ + $productid = $_POST['productid'] ; + $pruduct = new Product($db) ; + $pruduct->fetch($productid) ; } - facture_pdf_create($db, $fac->id, '', $fac->modelpdf, $outputlangs); - + if($pruduct->price_min && ($_POST['productid']!='') && (price2num($_POST['price'])*(1-price2num($_POST['remise_percent'])/100) < price2num($pruduct->price_min))) + { + $mesg = '
'.$langs->trans("CantBeLessThanMinPrice",price2num($pruduct->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'
' ; + } + else + { + $result = $fac->updateline($_POST['rowid'], + $_POST['desc'], + $_POST['price'], + $_POST['qty'], + $_POST['remise_percent'], + $date_start, + $date_end, + $vat_rate, + 'HT', + $info_bits + ); + + if ($_REQUEST['lang_id']) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($_REQUEST['lang_id']); + } + facture_pdf_create($db, $fac->id, '', $fac->modelpdf, $outputlangs); + } + $_GET['facid']=$_POST['facid']; // Pour réaffichage de la fiche en cours d'édition } @@ -2582,6 +2604,7 @@ else print '
'; // ancre pour retourner sur la ligne if ($objp->fk_product > 0) { + print ''; print ''; if ($objp->fk_product_type==1) print img_object($langs->trans('ShowService'),'service'); else print img_object($langs->trans('ShowProduct'),'product'); diff --git a/htdocs/compta/stats/cabyuser.php b/htdocs/compta/stats/cabyuser.php index 3a1a215c26b..7ac8e58ea93 100644 --- a/htdocs/compta/stats/cabyuser.php +++ b/htdocs/compta/stats/cabyuser.php @@ -26,6 +26,8 @@ require("./pre.inc.php"); require_once(DOL_DOCUMENT_ROOT."/lib/report.lib.php"); +if (!$user->rights->compta->resultat->lire) + accessforbidden(); $year=$_GET["year"]; if (! $year) { $year = strftime("%Y", time()); } @@ -75,8 +77,8 @@ $catotal=0; if ($modecompta == 'CREANCES-DETTES') { $sql = "SELECT u.rowid as rowid, u.name as name, u.firstname as firstname, sum(f.total) as amount, sum(f.total_ttc) as amount_ttc"; - $sql .= " FROM ".MAIN_DB_PREFIX."user as u,".MAIN_DB_PREFIX."facture as f"; - $sql .= " WHERE f.fk_statut in (1,2) AND f.fk_user_author = u.rowid"; + $sql .= " FROM ".MAIN_DB_PREFIX."user as u LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.fk_user_author = u.rowid"; + $sql .= " WHERE f.fk_statut in (1,2) "; if ($year) $sql .= " AND f.datef between '".$year."-01-01 00:00:00' and '".$year."-12-31 23:59:59'"; } else @@ -86,9 +88,12 @@ else * vieilles versions, ils n'étaient pas liés via paiement_facture. On les ajoute plus loin) */ $sql = "SELECT u.rowid as rowid, u.name as name, u.firstname as firstname, sum(pf.amount) as amount_ttc"; - $sql .= " FROM ".MAIN_DB_PREFIX."user as u, ".MAIN_DB_PREFIX."facture as f, ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."paiement as p"; - $sql .= " WHERE p.rowid = pf.fk_paiement AND pf.fk_facture = f.rowid AND f.fk_user_author = u.rowid"; - if ($year) $sql .= " AND p.datep between '".$year."-01-01 00:00:00' and '".$year."-12-31 23:59:59'"; + $sql .= " FROM ".MAIN_DB_PREFIX."user as u" ; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.fk_user_author = u.rowid "; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON pf.fk_facture = f.rowid"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement as p ON p.rowid = pf.fk_paiement"; + if ($year) $sql .= " AND p.datep between '".$year."-01-01 00:00:00' and '".$year."-12-31 23:59:59'"; + } if ($socid) $sql .= " AND f.fk_soc = $socid"; $sql .= " GROUP BY rowid"; @@ -149,6 +154,7 @@ print ""; print_liste_field_titre($langs->trans("User"),$_SERVER["PHP_SELF"],"name","",'&year='.($year).'&modecompta='.$modecompta,"",$sortfield,$sortorder); print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER["PHP_SELF"],"amount_ttc","",'&year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Percentage"),$_SERVER["PHP_SELF"],"amount_ttc","",'&year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder); +print_liste_field_titre($langs->trans("OrderStats"),$_SERVER["PHP_SELF"],"","","",'align="center" width="20%"'); print "\n"; $var=true; @@ -189,6 +195,12 @@ if (sizeof($amount)) print "".$linkname."\n"; print ''.price($amount[$key]).''; print ''.($catotal > 0 ? round(100 * $amount[$key] / $catotal,2).'%' : ' ').''; + if($key>0){ + print ''.img_picto($langs->trans("Show"),"vcard").''; + } else { + print '   ' ; + } + print "\n"; $i++; } diff --git a/htdocs/compta/stats/comm.php b/htdocs/compta/stats/comm.php new file mode 100644 index 00000000000..592bc548777 --- /dev/null +++ b/htdocs/compta/stats/comm.php @@ -0,0 +1,222 @@ + + * Copyright (C) 2004-2008 Laurent Destailleur + * Copyright (C) 2005-2008 Regis Houssin + * + * 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. + */ + +/** + \file htdocs/comm/index.php + \ingroup commercial + \brief Page acceuil de la zone commercial cliente + \version $Id$ +*/ + +require("./pre.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/dolgraph.class.php"); + +if (!$user->rights->compta->resultat->lire) + accessforbidden(); + +llxHeader('',"Stats"); + +if($_GET['id']!=""){ + /************** + * Paramètrage + *************/ + // Utilisateur à partir duquel il faut générer les stats + $userstats = new User($db,$_GET['id']) ; + $userstats->fetch() ; + + // Dossier où générer les fichiers + $dir = $conf->commercial->dir_temp . '/' .$userstats->id ; + if(!is_dir($dir)) mkdir($dir,0777,true) ; + + // graphes + $graphwidth = 380 ; + $graphheight = 160 ; + + + // Chaine contenant les messages d'erreur + $msq = '' ; + + // Date de début du graphe + $date_debut = time() ; + $annees = "" ; + if ($conf->global->SOCIETE_FISCAL_MONTH_START < dolibarr_date("m",time()) ){ + // Si le mois actuel est plus grand, l'année de départ est là même que l'année actuelle + $date_debut = mktime(0,0,0,$conf->global->SOCIETE_FISCAL_MONTH_START,1,dolibarr_date("Y",time())) ; + $annees = dolibarr_date("Y",time()) ; + } else { + // Sinon le début de l'année comptable était l'année d'avant + $date_debut = mktime(0,0,0,$conf->global->SOCIETE_FISCAL_MONTH_START,1,dolibarr_date("Y",time())-1) ; + $annees = (dolibarr_date("Y",time())-1).' - '.(dolibarr_date("Y",time())) ; + } + + /********************************************** + * Récupération et génération des Infomations + **********************************************/ + $sql = "SELECT sum(d.qty * d.price) as CAMois, sum( d.qty * (d.price - p.price_min) ) as MRMois, date_format(c.date_valid, '%Y%m') as date, date_format(c.date_valid, '%b') as month"; + $sql .= " FROM ".MAIN_DB_PREFIX."commandedet as d, ".MAIN_DB_PREFIX."commande as c, ".MAIN_DB_PREFIX."product as p"; + $sql .= " WHERE c.rowid = d.fk_commande and d.fk_product = p.rowid"; + $sql .= " AND c.fk_user_author = ".$userstats->id; + $sql .= " AND c.date_valid > ".$db->idate($date_debut)." AND c.date_valid < NOW()"; + $sql .= " GROUP BY date_format(c.date_valid,'%Y%m') ASC ;"; + + $result = $db->query($sql) ; + + // On Récupère tout à la fois + $recapAnneeCA = array() ; + $recapMoisCA = array() ; + $recapAnneeMR = array() ; + $recapMoisMR = array() ; + if($result){ + if($db->num_rows($result)>0){ + while($obj = $db->fetch_object($result)){ + if($obj->date != dolibarr_date("Ym",time())){ + $recapAnneeCA[] = array( $obj->month, $obj->CAMois ) ; + $recapAnneeMR[] = array( $obj->month, $obj->MRMois ) ; + }else{ + $recapMoisCA[] = array( $obj->month, $obj->CAMois ) ; + $recapMoisMR[] = array( $obj->month, $obj->MRMois ) ; + } + } + } else { + $mesg = 'Aucun enregistrement retourné pour '.$user->login.'
' ; + } + } else { + $mesg = 'erreur sql : '.$db->error().'
requète : '.$db->lastquery().'
' ; + } + + $graphfiles=array( + 'recapAnneeCA' =>array( + 'file' => 'recapAnneeCA.png', + 'label' => $langs->trans('CAOrder').' - '.$annees, + 'data' => $recapAnneeCA + ), + 'recapAnneeMR' =>array( + 'file' => 'recapAnneeMR.png', + 'label' => $langs->trans('MargeOrder').' - '.$annees, + 'data' => $recapAnneeMR + ), + 'recapMoisCA' =>array( + 'file' => 'recapMoisCA.png', + 'label' => $langs->trans('CAOrder').' '.$langs->trans('FromTo',dolibarr_date("01/m/Y",time()),dolibarr_date("d/m/Y",time())), + 'data' => $recapMoisCA + ), + 'recapMoisMR'=>array( + 'file' => 'recapMoisMR.png', + 'label' => $langs->trans('MargeOrder').' '.$langs->trans('FromTo',dolibarr_date("01/m/Y",time()),dolibarr_date("d/m/Y",time())), + 'data' => $recapMoisMR + ) + ) ; + + + /*********************** + * Affichage de graphes + ***********************/ + $px = new DolGraph(); + $msggraph = $px->isGraphKo(); + if (! $mesg) + { + + foreach($graphfiles as $key => $graph){ + $graph_data = $graph['data'] ; + + if (is_array($graph_data)) + { + $px->SetData($graph_data); + $px->SetMaxValue($px->GetCeilMaxValue()<0?0:$px->GetCeilMaxValue()); + $px->SetMinValue($px->GetFloorMinValue()>0?0:$px->GetFloorMinValue()); + $px->SetWidth($graphwidth); + $px->SetHeight($graphheight); + $px->SetHorizTickIncrement(1); + $px->SetPrecisionY(0); + $px->SetShading(3); + + $px->draw($dir."/".$graph['file']); + + } + else + { + dolibarr_print_error($db,'Error for calculating graph on key='.$key.' - '.$product->error); + } + } + + } else { + $msg.=$msggraph ; + } + + /************ + * Affichage + ************/ + // en-tête + if($mesg) print '
'.$mesg.'
' ; + dolibarr_fiche_head(array(array('stats.php',$langs->trans("Commercial"))), 0, $langs->trans("Stats")); + /***************************** + * Rappel Infos du Commercial + *****************************/ + print ' + + + + + + + + + +
'.$langs->trans("Name").''.$userstats->nom.'
'.$langs->trans("Surname").''.$userstats->prenom.'
'.$langs->trans("Login").''.$userstats->login.'
' ; + + print "" ; // Fin de dolibarr_fiche_head + + /*************************** + * Affichage des Graphiques + ***************************/ + //tableaux + foreach($graphfiles as $graph){ + // données + $url=DOL_URL_ROOT.'/viewimage.php?modulepart=graph_comm&file='.urlencode($userstats->id .'/'.$graph['file']); + $generateOn = (file_exists($dir."/".$graph['file']))? $langs->trans("GeneratedOn",dolibarr_print_date(filemtime($dir."/".$graph['file']),"dayhour")) : "" ; + + // html + print ' + + + + + + + + + +
'.$graph['label'].'
+ '.$langs->trans( + + + + '.array2table($graph['data'],0,'','','align="center"').' +
'.$langs->trans("Month").''.$langs->trans("Currency".$conf->monnaie).'
+
'.$generateOn.'
' ; + } + +} +/************** + * Fin de page + **************/ +$db->close(); +llxFooter(); +?> diff --git a/htdocs/html.form.class.php b/htdocs/html.form.class.php index fbd49e53189..de5a33019f3 100644 --- a/htdocs/html.form.class.php +++ b/htdocs/html.form.class.php @@ -1086,25 +1086,25 @@ class Form if ($objp2) { if ($objp2->price_base_type == 'HT') - $opt.= price2num($objp2->price,'MU').' '.$langs->trans("Currency".$conf->monnaie).' '.$langs->trans("HT"); + $opt.= price($objp2->price,1).' '.$langs->trans("Currency".$conf->monnaie).' '.$langs->trans("HT"); else - $opt.= price2num($objp2->price_ttc,'MU').' '.$langs->trans("Currency".$conf->monnaie).' '.$langs->trans("TTC"); + $opt.= price($objp2->price_ttc,1).' '.$langs->trans("Currency".$conf->monnaie).' '.$langs->trans("TTC"); } //si il n'y a pas de prix multiple on prend le prix de base du produit/service else { if ($objp->price_base_type == 'HT') - $opt.= price2num($objp->price,'MU').' '.$langs->trans("Currency".$conf->monnaie).' '.$langs->trans("HT"); + $opt.= price($objp->price,1).' '.$langs->trans("Currency".$conf->monnaie).' '.$langs->trans("HT"); else - $opt.= price2num($objp->price_ttc,'MU').' '.$langs->trans("Currency".$conf->monnaie).' '.$langs->trans("TTC"); + $opt.= price($objp->price_ttc,1).' '.$langs->trans("Currency".$conf->monnaie).' '.$langs->trans("TTC"); } } else { if ($objp->price_base_type == 'HT') - $opt.= price2num($objp->price,'MU').' '.$langs->trans("Currency".$conf->monnaie).' '.$langs->trans("HT"); + $opt.= price($objp->price,1).' '.$langs->trans("Currency".$conf->monnaie).' '.$langs->trans("HT"); else - $opt.= price2num($objp->price_ttc,'MU').' '.$langs->trans("Currency".$conf->monnaie).' '.$langs->trans("TTC"); + $opt.= price($objp->price_ttc,1).' '.$langs->trans("Currency".$conf->monnaie).' '.$langs->trans("TTC"); } if ($objp->duration) diff --git a/htdocs/includes/menus/barre_left/eldy_backoffice.php b/htdocs/includes/menus/barre_left/eldy_backoffice.php index bd0fd5271bf..1264b6c25a4 100644 --- a/htdocs/includes/menus/barre_left/eldy_backoffice.php +++ b/htdocs/includes/menus/barre_left/eldy_backoffice.php @@ -356,7 +356,9 @@ class MenuLeft { if ($leftmenu=="ficheinter") $newmenu->add_submenu(DOL_URL_ROOT."/fichinter/fiche.php?action=create&leftmenu=ficheinter", $langs->trans("NewIntervention"), 1, $user->rights->ficheinter->creer); if ($leftmenu=="ficheinter") $newmenu->add_submenu(DOL_URL_ROOT."/fichinter/index.php?leftmenu=ficheinter", $langs->trans("List"), 1 ,$user->rights->ficheinter->lire); } - + + // Statistiques de vente + $newmenu->add(DOL_URL_ROOT."/comm/stats.php", $langs->trans("Stats"), 0 ,1); } diff --git a/htdocs/langs/fr_BE/admin.lang b/htdocs/langs/fr_BE/admin.lang index 871c221b7dc..72f774d6f59 100644 --- a/htdocs/langs/fr_BE/admin.lang +++ b/htdocs/langs/fr_BE/admin.lang @@ -578,23 +578,4 @@ MailingSetup=Configuration du module de publipostage MailingEMailFrom=E-mail d'origine (De:) des e-mails envoyés par le module de publipostage ##### Notification #####= NotificationSetup=Configuration du module de publipostage -NotificationEMailFrom=E-mail d'origine (De:) pour les e-mails envoyés pour les alertes -##### Sendings #####= -SendingsSetup=Configuration du module d'envoi -SendingsReceiptModel=Modèle de reçu d'envoi -SendingsAbility=Supporter les feuilles d'envoi pour les livraisons client -##### Deliveries #####= -DeliveryOrderNumberingModules=Module de numérotation des reçus de livraison de produits -DeliveryOrderModel=Modèle de reçu de livraisons de produits -DeliveriesOrderAbility=Possibilité de reçu des livraisons de produits -##### FCKeditor #####= -ActivateFCKeditor=Activer FCKeditor pour: -FCKeditorForCompany=Édition/création WYSIWYG de descriptions et notes d'entreprises -FCKeditorForProductDescription=Édition/création WYSIWYG de descriptions et notes de produits/services -FCKeditorForDetails=Édition/création WYSIWYG de lignes de détails pour toutes les entités (propositions, commandes, factures, etc...) -FCKeditorForMailing=Édition/création WYSIWYG de publipostages -##### OSCommerce 1 #####= -OSCommerceErrorConnectOkButWrongDatabase=La connexion a réussi mais la base de données n'a pas l'air d'être une base de données OSCommerce -OSCommerceTestOk=Connexion au serveur '%s' à la base de données '%s' avec l'utilisateur '%s' réussie. -OSCommerceTestKo1=Connexion au serveur '%s' réussie mais la base de données '%s' n'a pas pu être contactée. -OSCommerceTestKo2=Connexion au serveur '%s' avec l'utilisateur '%s' échouée. +NotificationEMailFrom=E-mail d'origine (De:) pour les e-mails envoyés pour les alertes \ No newline at end of file diff --git a/htdocs/langs/fr_BE/main.lang b/htdocs/langs/fr_BE/main.lang index 3f2ab329ada..c76aec86665 100644 --- a/htdocs/langs/fr_BE/main.lang +++ b/htdocs/langs/fr_BE/main.lang @@ -1,7 +1,7 @@ # Dolibarr language file - fr_BE - main= charset=iso-8859-15 SeparatorDecimal=, -SeparatorThousand=. +SeparatorThousand= Error=Erreur ErrorFieldRequired=Le champ '%s' est obligatoire ErrorFieldFormat=Le champ '%s' a une valeur erronée diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index 126067eaf64..737a849b913 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -825,6 +825,7 @@ ModifyProductDescAbility=Personnalisation des descriptions produits dans les for ViewProductDescInFormAbility=Visualisation des descriptions produits dans les formulaires (sinon en tant que tooltip) UseSearchToSelectProduct=Utiliser un formulaire de recherche pour choix d'un produit (plutôt que liste déroulante) UseEcoTaxeAbility=Prise en charge des éco-taxes (DEEE) +UseMinPrice=Utilisation d'un prix minimum de vente SetDefaultBarcodeType=Type de code barre utilisé par défaut pour les produits ##### Suppliers ##### SuppliersSetup=Configuration du module Fournisseur diff --git a/htdocs/langs/fr_FR/commercial.lang b/htdocs/langs/fr_FR/commercial.lang index d9dbec5f4eb..d860438794c 100644 --- a/htdocs/langs/fr_FR/commercial.lang +++ b/htdocs/langs/fr_FR/commercial.lang @@ -74,3 +74,9 @@ ActionAC_REL=Relance facture par mail ActionAC_CLO=Clôture ActionAC_EMAILING=Envoi mailing masse ActionAC_COM=Envoi commande par mail +Stats=Statistiques de vente +CAOrder=Chiffre d'affaire (Commandes validées) +FromTo=du %s au %s +MargeOrder=Marge réalisée (Commandes validées) +RecapAnnee=Récaptilatif de l'année +NoData=Aucune donnée \ No newline at end of file diff --git a/htdocs/langs/fr_FR/compta.lang b/htdocs/langs/fr_FR/compta.lang index 2703db0e0f1..23e933fee06 100644 --- a/htdocs/langs/fr_FR/compta.lang +++ b/htdocs/langs/fr_FR/compta.lang @@ -98,4 +98,5 @@ SeeVATReportInDueDebtMode=Voir le rapport %sTVA sur d RulesVATIn=- Pour les services, le rapport inclut les TVA des réglements effectivement reçus ou émis en se basant sur la date du réglement.
- Pour les biens matériels, il inclut les TVA des factures en se basant sur la date de validation de la facture. RulesVATDue=- Pour les services, le rapport inclut les TVA des factures dues, payées ou non en se basant sur la date de validation de ces factures.
- Pour les biens matériels, il inclut les TVA des factures en se basant sur la date de validation de la facture. OptionVatInfoModuleComptabilite=Remarque : Pour les biens matériels, il faudrait utiliser la date de livraison pour être plus juste. -PercentOfInvoice=%%/facture \ No newline at end of file +PercentOfInvoice=%%/facture +OrderStats=Statistiques sur les commandes \ No newline at end of file diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang index 8a8e4a86d40..581593c4d03 100644 --- a/htdocs/langs/fr_FR/products.lang +++ b/htdocs/langs/fr_FR/products.lang @@ -55,6 +55,8 @@ SellingPrice=Prix de vente PublicPrice=Prix public CurrentPrice=Prix actuel NewPrice=Nouveau prix +MinPrice=Prix de vente min. +CantBeLessThanMinPrice=Le prix de vente ne doit pas être inférieur au minimum pour ce produit (%s HT) ContractStatus=État du contrat ContractStatusClosed=Cloturé ContractStatusRunning=En service diff --git a/htdocs/lib/functions.lib.php b/htdocs/lib/functions.lib.php index 887a2984d4b..eda09d7ba4c 100644 --- a/htdocs/lib/functions.lib.php +++ b/htdocs/lib/functions.lib.php @@ -1964,14 +1964,16 @@ function vatrate($rate,$addpercent=false,$info_bits=0) * \param html Type de formatage, html ou pas (par defaut) * \param outlangs Objet langs pour formatage text * \param trunc 1=Tronque affichage si trop de decimales,0=Force le non troncage - * \param nbdecimal Nbre decimals minimum. + * \param rounding Nbre decimals minimum. * \return string Chaine avec montant formate * \seealso price2num Revert function of price */ -function price($amount, $html=0, $outlangs='', $trunc=1, $nbdecimal=2) +function price($amount, $html=0, $outlangs='', $trunc=1, $rounding=2) { global $langs,$conf; + $nbdecimal=$rounding; + // Output separators by default (french) $dec=','; $thousand=' '; @@ -2019,7 +2021,7 @@ function price($amount, $html=0, $outlangs='', $trunc=1, $nbdecimal=2) } /** - * \brief Fonction qui retourne un numerique conforme PHP et SQL, depuis un montant au + * \brief Fonction qui retourne un numerique conforme SQL, depuis un montant au * format utilisateur. * \remarks Fonction a appeler sur montants saisis avant un insert en base * \param amount Montant a formater @@ -2030,28 +2032,33 @@ function price($amount, $html=0, $outlangs='', $trunc=1, $nbdecimal=2) * \return string Montant au format numerique PHP et SQL (Exemple: '99.99999') * \seealso price Fonction inverse de price2num */ -function price2num($amount,$rounding='') +function price2num($amount,$rounding='',$alreadysqlnb=-1) { global $langs,$conf; - // Round PHP function does not allow number like '1,234.5' + // Round PHP function does not allow number like '1,234.5' nor '1.234,5' nor '1 234,5' // Numbers must be '1234.5' // Decimal delimiter for database SQL request must be '.' $dec=','; $thousand=' '; if ($langs->trans("SeparatorDecimal") != "SeparatorDecimal") $dec=$langs->trans("SeparatorDecimal"); if ($langs->trans("SeparatorThousand")!= "SeparatorThousand") $thousand=$langs->trans("SeparatorThousand"); - - if ($thousand != ',' && $thousand != '.') $amount=str_replace(',','.',$amount); // To accept 2 notations for french users - $amount=str_replace(' ','',$amount); // To avoid spaces - $amount=str_replace($thousand,'',$amount); // Replace of thousand before replace of dec to avoid pb if thousand is . - $amount=str_replace($dec,'.',$amount); + + if ($alreadysqlnb != 1) // If not a PHP number or unknown, we change format + { + if ($thousand != ',' && $thousand != '.') $amount=str_replace(',','.',$amount); // To accept 2 notations for french users + $amount=str_replace(' ','',$amount); // To avoid spaces + $amount=str_replace($thousand,'',$amount); // Replace of thousand before replace of dec to avoid pb if thousand is . + $amount=str_replace($dec,'.',$amount); + } if ($rounding) { if ($rounding == 'MU') $amount = round($amount,$conf->global->MAIN_MAX_DECIMALS_UNIT); elseif ($rounding == 'MT') $amount = round($amount,$conf->global->MAIN_MAX_DECIMALS_TOT); elseif ($rounding == 'MS') $amount = round($amount,$conf->global->MAIN_MAX_DECIMALS_SHOWN); else $amount='ErrorBadParameterProvidedToFunction'; + // Always make replace because each math function (like round) replace + // with local values and we want a number that has a SQL string format x.y if ($thousand != ',' && $thousand != '.') $amount=str_replace(',','.',$amount); // To accept 2 notations for french users $amount=str_replace(' ','',$amount); // To avoid spaces $amount=str_replace($thousand,'',$amount); // Replace of thousand before replace of dec to avoid pb if thousand is . @@ -3059,4 +3066,59 @@ function dol_sort_array($array, $index, $order='asc', $natsort, $case_sensitive) return $array; } +/** + * \brief Test if a folder is empty + * \return true is empty or non-existing, false if it contains files + */ +function is_emtpy_folder($folder){ + if(is_dir($folder) ){ + $handle = opendir($folder); + while( (gettype( $name = readdir($handle)) != "boolean")){ + $name_array[] = $name; + } + foreach($name_array as $temp) + $folder_content .= $temp; + + if($folder_content == "...") + return true; + else + return false; + + closedir($handle); + } + else + return true; // Le répertoire n'existe pas +} + +/** + * \brief Return an html table from an array + */ +function array2table($data,$tableMarkup=1,$tableoptions='',$troptions='',$tdoptions=''){ + $text='' ; + if($tableMarkup) $text = '' ; + foreach($data as $key => $item){ + if(is_array($item)){ + $text.=array2tr($item,$troptions,$tdoptions) ; + } else { + $text.= '' ; + $text.= '' ; + $text.= '' ; + $text.= '' ; + } + } + if($tableMarkup) $text.= '
'.$key.''.$item.'
' ; + return $text ; +} + +/** + * \brief Return lines of an html table from an array + */ +function array2tr($data,$troptions='',$tdoptions=''){ + $text = '' ; + foreach($data as $key => $item){ + $text.= ''.$item.'' ; + } + $text.= '' ; + return $text ; +} ?> \ No newline at end of file diff --git a/htdocs/product.class.php b/htdocs/product.class.php index 60effaced27..4886f2cff05 100644 --- a/htdocs/product.class.php +++ b/htdocs/product.class.php @@ -50,6 +50,8 @@ class Product extends CommonObject //! Prix de vente var $price; // Price without tax var $price_ttc; // Price with tax + var $price_min; + var $price_min_ttc; //! Base de prix (ttc ou ht) var $price_base_type; //! Tableau des prix multiples @@ -155,6 +157,7 @@ class Product extends CommonObject */ function create($user) { + global $conf ; $this->errno = 0; // Clean parameters @@ -162,10 +165,13 @@ class Product extends CommonObject $this->libelle = trim($this->libelle); if ($this->tva_tx=='') $this->tva_tx = 0; if ($this->price=='') $this->price = 0; + if ($this->price_min=='') $this->price_min = 0; if ($this->status=='') $this->status = 0; $price_ht=0; $price_ttc=0; + $price_min_ht=0; + $price_min_ttc=0; if ($this->price_base_type == 'TTC' && $this->price_ttc > 0) { $price_ttc = price2num($this->price_ttc,'MU'); @@ -176,6 +182,17 @@ class Product extends CommonObject $price_ht = price2num($this->price,'MU'); $price_ttc = price2num($this->price * (1 + ($this->tva_tx / 100)),'MU'); } + + if (($this->price_min_ttc > 0)&&($this->price_base_type == 'TTC')) + { + $price_min_ttc = price2num($this->price_min_ttc,'MU'); + $price_min_ht = price2num($this->price_min_ttc / (1 + ($this->tva_tx / 100)),'MU'); + } + if (($this->price_min > 0)&&($this->price_base_type != 'TTC')) + { + $price_min_ht = price2num($this->price_min,'MU'); + $price_min_ttc = price2num($this->price_min * (1 + ($this->tva_tx / 100)),'MU'); + } // Check parameters if (empty($this->libelle)) @@ -203,10 +220,13 @@ class Product extends CommonObject $sql = "INSERT INTO ".MAIN_DB_PREFIX."product"; $sql.= " (datec, "; if ($this->ref) $sql.= "ref, "; + $sql.= "price_min, price_min_ttc, "; $sql.= "label, "; $sql.= "fk_user_author, fk_product_type, price, price_ttc, price_base_type, canvas)"; $sql.= " VALUES (".$this->db->idate(mktime()).", "; if ($this->ref) $sql.= "'".$this->ref."',"; + $sql.= price2num($price_min_ht).","; + $sql.= price2num($price_min_ttc).","; $sql.= " ".($this->libelle?"'".addslashes($this->libelle)."'":"null").","; $sql.= $user->id.","; $sql.= " ".$this->type.","; @@ -226,7 +246,9 @@ class Product extends CommonObject $this->id = $id; $this->price = $price_ht; $this->price_ttc = $price_ttc; - + $this->price_min = $price_min_ht; + $this->price_min_ttc = $price_min_ttc; + $result = $this->_log_price($user); if ($result > 0) { @@ -487,6 +509,10 @@ class Product extends CommonObject $sqlb = "DELETE from ".MAIN_DB_PREFIX."product_price"; $sqlb.= " WHERE fk_product = ".$id; $resultb = $this->db->query($sqlb); + + $sqlb = "DELETE from ".MAIN_DB_PREFIX."product_price_min"; + $sqlb.= " WHERE fk_product = ".$id; + $resultb = $this->db->query($sqlb); $sqlc = "DELETE from ".MAIN_DB_PREFIX."product_det"; $sqlc.= " WHERE fk_product = ".$id; @@ -655,9 +681,10 @@ class Product extends CommonObject if (strlen(trim($this->price)) > 0 ) { // On ajoute nouveau tarif - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_price(date_price,fk_product,fk_user_author,price,price_ttc,price_base_type,envente,tva_tx) "; - $sql .= " VALUES(".$this->db->idate(mktime()).",".$this->id.",".$user->id.",".$this->price.",".$this->price_ttc.",'".$this->price_base_type."',".$this->status.",".$this->tva_tx; - $sql .= ")"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_price(date_price,fk_product,fk_user_author,price,price_ttc,price_base_type,envente,tva_tx,price_min,price_min_ttc) "; + $sql.= " VALUES(".$this->db->idate(mktime()).",".$this->id.",".$user->id.",".$this->price.",".$this->price_ttc.",'".$this->price_base_type."',".$this->status.",".$this->tva_tx; + $sql.= ",".$this->price_min.",".$this->price_min_ttc; + $sql.= ")"; if (! $this->db->query($sql) ) $queryError = true; } @@ -671,22 +698,28 @@ class Product extends CommonObject } else { + $queryError = false; + // On ajoute nouveau tarif - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_price(date_price,fk_product,fk_user_author,price,price_ttc,price_base_type,envente,tva_tx) "; - $sql .= " VALUES(".$this->db->idate(mktime()).",".$this->id.",".$user->id.",".$this->price.",".$this->price_ttc.",'".$this->price_base_type."',".$this->status.",".$this->tva_tx; - $sql .= ")"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_price(date_price,fk_product,fk_user_author,price,price_ttc,price_base_type,envente,tva_tx,price_min,price_min_ttc) "; + $sql.= " VALUES(".$this->db->idate(mktime()).",".$this->id.",".$user->id.",".$this->price.",".$this->price_ttc.",'".$this->price_base_type."',".$this->status.",".$this->tva_tx; + $sql.= ",".$this->price_min.",".$this->price_min_ttc; + $sql.= ")"; dolibarr_syslog("Product::_log_price sql=".$sql); $resql=$this->db->query($sql); - if ($resql) - { - return 1; - } - else + if (!$resql) + $queryError = true; + + if($queryError) { dolibarr_print_error($this->db); return -1; } + else + return 1; + + } } @@ -777,7 +810,7 @@ class Product extends CommonObject * \param newvat New VAT Rate * \return int <0 if KO, >0 if OK */ - function update_price($id, $newprice, $newpricebase, $user, $newvat='') + function update_price($id, $newprice, $newpricebase, $user, $newvat='',$newminprice='') { //multiprix global $conf,$langs; @@ -792,12 +825,24 @@ class Product extends CommonObject $price_ttc = price2num($newprice,'MU'); $price = price2num($newprice) / (1 + ($newvat / 100)); $price = price2num($price,'MU'); + + if($newminprice!=''){ + $price_min_ttc = price2num($newminprice,'MU'); + $price_min = price2num($newminprice) / (1 + ($newvat / 100)); + $price_min = price2num($price_min,'MU'); + } } else { $price = price2num($newprice,'MU'); $price_ttc = price2num($newprice) * (1 + ($newvat / 100)); $price_ttc = price2num($price_ttc,'MU'); + + if($newminprice!=''){ + $price_min = price2num($newminprice,'MU'); + $price_min_ttc = price2num($newminprice) * (1 + ($newvat / 100)); + $price_min_ttc = price2num($price_min_ttc,'MU'); + } } // Ne pas mettre de quote sur le num�riques decimaux. @@ -806,6 +851,8 @@ class Product extends CommonObject $sql.= " price_base_type='".$newpricebase."',"; $sql.= " price=".$price.","; $sql.= " price_ttc=".$price_ttc.","; + $sql.= " price_min=".$price_min.","; + $sql.= " price_min_ttc=".$price_min_ttc.","; $sql.= " tva_tx='".price2num($newvat)."'"; $sql.= " WHERE rowid = " . $id; @@ -815,6 +862,8 @@ class Product extends CommonObject { $this->price = $price; $this->price_ttc = $price_ttc; + $this->price_min = $price_min; + $this->price_min_ttc = $price_min_ttc; $this->price_base_type = $newpricebase; $this->tva_tx = $newvat; @@ -861,7 +910,7 @@ class Product extends CommonObject return -1; } - $sql = "SELECT rowid, ref, label, description, note, price, price_ttc, price_base_type, tva_tx, envente,"; + $sql = "SELECT rowid, ref, label, description, note, price, price_ttc, price_min, price_min_ttc, price_base_type, tva_tx, envente,"; $sql.= " nbvente, fk_product_type, duration, seuil_stock_alerte,canvas,"; $sql.= " stock_commande, stock_loc, weight, weight_units, volume, volume_units, barcode, fk_barcode_type"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; @@ -881,6 +930,8 @@ class Product extends CommonObject $this->note = $result["note"]; $this->price = $result["price"]; $this->price_ttc = $result["price_ttc"]; + $this->price_min = $result["price_min"]; + $this->price_min_ttc = $result["price_min_ttc"]; $this->price_base_type = $result["price_base_type"]; $this->tva_tx = $result["tva_tx"]; $this->type = $result["fk_product_type"]; diff --git a/htdocs/product/fiche.php b/htdocs/product/fiche.php index 3e64ac6e98c..636b218cd37 100644 --- a/htdocs/product/fiche.php +++ b/htdocs/product/fiche.php @@ -88,6 +88,8 @@ if ($_POST["action"] == 'add' && $user->rights->produit->creer) $product->price_base_type = $_POST["price_base_type"]; if ($product->price_base_type == 'TTC') $product->price_ttc = $_POST["price"]; else $product->price = $_POST["price"]; + if ($product->price_base_type == 'TTC') $product->price_min_ttc = $_POST["price_min"]; + else $product->price_min = $_POST["price_min"]; $product->tva_tx = $_POST["tva_tx"]; $product->type = $_POST["type"]; $product->status = $_POST["statut"]; @@ -687,6 +689,11 @@ if ($_GET["action"] == 'create' && $user->rights->produit->creer) print ''; } + // MIN PRICE + print ''.$langs->trans("MinPrice").''; + print ''; + print ''; + // VAT print ''.$langs->trans("VATRate").''; print $html->select_tva("tva_tx",$conf->defaulttx,$mysoc,''); @@ -870,6 +877,18 @@ if ($_GET["id"] || $_GET["ref"]) } print ''; } + + // Prix mini + print ''.$langs->trans("MinPrice").''; + if ($product->price_base_type == 'TTC') + { + print price($product->price_min_ttc).' '.$langs->trans($product->price_base_type); + } + else + { + print price($product->price_min).' '.$langs->trans($product->price_base_type); + } + print ''; // TVA print ''.$langs->trans("VATRate").''.vatrate($product->tva_tx,true).''; diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 4648da25d7e..b7b7f754d25 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -91,7 +91,10 @@ if ($_POST["action"] == 'update_price' && $newvat=$_POST["tva_tx"]; } - if ($product->update_price($product->id, $newprice, $newpricebase, $user, $newvat) > 0) + $newprice_min = '' ; + $newprice_min = price2num($_POST["price_min"],'MU'); + + if ($product->update_price($product->id, $newprice, $newpricebase, $user, $newvat,$newprice_min) > 0) { $_GET["action"] = ''; $mesg = $langs->trans("RecordSaved"); @@ -175,6 +178,18 @@ else } } +// Prix minimum +print ''.$langs->trans("MinPrice").''; +if ($product->price_base_type == 'TTC') +{ + print price($product->price_min_ttc).' '.$langs->trans($product->price_base_type); +} +else +{ + print price($product->price_min).' '.$langs->trans($product->price_base_type); +} +print ''; + // TVA print ''.$langs->trans("VATRate").''.vatrate($product->tva_tx,true).''; @@ -237,9 +252,23 @@ if ($_GET["action"] == 'edit_price' && $user->rights->produit->creer) { print ''; } + + print '' ; + $text=$langs->trans('MinPrice') ; + print $html->textwithhelp($text,$langs->trans("PrecisionUnitIsLimitedToXDecimals",$conf->global->MAIN_MAX_DECIMALS_UNIT),$direction=1,$usehelpcursor=1); + if ($product->price_base_type == 'TTC') + { + print ''; + } + else + { + print ''; + } + print ''; + print $html->select_PriceBaseType($product->price_base_type, "price_base_type"); print ''; - + // VAT print ''.$langs->trans("VATRate").''; print $html->select_tva("tva_tx",$product->tva_tx,$mysoc,''); @@ -275,6 +304,19 @@ if ($_GET["action"] == 'edit_price' && $user->rights->produit->creer) print $html->select_PriceBaseType($product->multiprices_base_type["$i"], "multiprices_base_type_".$i); print ''; + print '' ; + $text=$langs->trans('MinPrice') ; + print $html->textwithhelp($text,$langs->trans("PrecisionUnitIsLimitedToXDecimals",$conf->global->MAIN_MAX_DECIMALS_UNIT),$direction=1,$usehelpcursor=1); + if ($product->price_base_type == 'TTC') + { + print ''; + } + else + { + print ''; + } + print ''; + // VAT print ''.$langs->trans("VATRate").''; print $html->select_tva("tva_tx_".$i,$product->multiprices_tva_tx["$i"],$mysoc,''); @@ -286,7 +328,6 @@ if ($_GET["action"] == 'edit_price' && $user->rights->produit->creer) print ''; } } - } @@ -304,9 +345,10 @@ if($conf->global->PRODUIT_MULTIPRICES) else { $sql = "SELECT p.rowid, p.price, p.price_ttc, p.price_base_type, p.tva_tx,"; + $sql.= " p.price_min, p.price_min_ttc,"; $sql.= " ".$db->pdate("p.date_price")." as dp, u.rowid as user_id, u.login"; - $sql.= " FROM ".MAIN_DB_PREFIX."product_price as p, ".MAIN_DB_PREFIX."user as u"; - $sql.= " WHERE fk_product = ".$product->id; + $sql.= " FROM ".MAIN_DB_PREFIX."user as u, ".MAIN_DB_PREFIX."product_price as p "; + $sql.= " WHERE p.fk_product = ".$product->id; $sql.= " AND p.fk_user_author = u.rowid"; $sql.= " ORDER BY p.date_price DESC"; } @@ -323,7 +365,7 @@ if ($result) // Il doit au moins y avoir la ligne de prix initial. // On l'ajoute donc pour remettre à niveau (pb vieilles versions) - $product->update_price($product->id, $product->price, 'HT' ,$user); + $product->update_price($product->id, $product->price, 'HT' ,$user,$newprice_min); $result = $db->query($sql) ; $num = $db->num_rows($result); @@ -347,6 +389,8 @@ if ($result) print ''.$langs->trans("VAT").''; print ''.$langs->trans("HT").''; print ''.$langs->trans("TTC").''; + print ''.$langs->trans("MinPrice").' '.$langs->trans("HT").''; + print ''.$langs->trans("MinPrice").' '.$langs->trans("TTC").''; print ''.$langs->trans("ChangedBy").''; print ''; @@ -370,6 +414,8 @@ if ($result) print ''.vatrate($objp->tva_tx,true).""; print ''.price($objp->price).""; print ''.price($objp->price_ttc).""; + print ''.price($objp->price_min).''; + print ''.price($objp->price_min_ttc).''; // User print ''.img_object($langs->trans("ShowUser"),'user').' '.$objp->login.''; diff --git a/htdocs/propal.class.php b/htdocs/propal.class.php index e507bc6b180..0ba06e78b96 100644 --- a/htdocs/propal.class.php +++ b/htdocs/propal.class.php @@ -23,13 +23,13 @@ */ /** - \file htdocs/propal.class.php - \brief Fichier de la classe des propales - \author Rodolphe Qiedeville - \author Eric Seigne - \author Laurent Destailleur - \version $Id$ -*/ + \file htdocs/propal.class.php + \brief Fichier de la classe des propales + \author Rodolphe Qiedeville + \author Eric Seigne + \author Laurent Destailleur + \version $Id$ + */ require_once(DOL_DOCUMENT_ROOT ."/commonobject.class.php"); require_once(DOL_DOCUMENT_ROOT ."/product.class.php"); @@ -37,9 +37,9 @@ require_once(DOL_DOCUMENT_ROOT ."/contact.class.php"); /** - \class Propal - \brief Classe permettant la gestion des propales -*/ + \class Propal + \brief Classe permettant la gestion des propales + */ class Propal extends CommonObject { @@ -64,7 +64,7 @@ class Propal extends CommonObject var $date; // Date of proposal var $datep; // Duplicate with date var $date_livraison; - + var $fin_validite; var $price; // Total HT var $tva; // Total TVA @@ -93,53 +93,53 @@ class Propal extends CommonObject var $specimen; - /** - * \brief Constructeur - * \param DB Handler d'acc�s base - * \param socid Id de la soci�t� - * \param propalid Id de la propal - */ - function Propal($DB, $socid="", $propalid=0) - { - global $langs; + /** + * \brief Constructeur + * \param DB Handler d'acc�s base + * \param socid Id de la soci�t� + * \param propalid Id de la propal + */ + function Propal($DB, $socid="", $propalid=0) + { + global $langs; - $this->db = $DB ; - $this->socid = $socid; - $this->id = $propalid; - $this->products = array(); - $this->remise = 0; - $this->remise_percent = 0; - $this->remise_absolue = 0; + $this->db = $DB ; + $this->socid = $socid; + $this->id = $propalid; + $this->products = array(); + $this->remise = 0; + $this->remise_percent = 0; + $this->remise_absolue = 0; - $langs->load("propals"); - $this->labelstatut[0]=$langs->trans("PropalStatusDraft"); - $this->labelstatut[1]=$langs->trans("PropalStatusValidated"); - $this->labelstatut[2]=$langs->trans("PropalStatusSigned"); - $this->labelstatut[3]=$langs->trans("PropalStatusNotSigned"); - $this->labelstatut[4]=$langs->trans("PropalStatusBilled"); - $this->labelstatut_short[0]=$langs->trans("PropalStatusDraftShort"); - $this->labelstatut_short[1]=$langs->trans("Opened"); - $this->labelstatut_short[2]=$langs->trans("PropalStatusSignedShort"); - $this->labelstatut_short[3]=$langs->trans("PropalStatusNotSignedShort"); - $this->labelstatut_short[4]=$langs->trans("PropalStatusBilledShort"); - } + $langs->load("propals"); + $this->labelstatut[0]=$langs->trans("PropalStatusDraft"); + $this->labelstatut[1]=$langs->trans("PropalStatusValidated"); + $this->labelstatut[2]=$langs->trans("PropalStatusSigned"); + $this->labelstatut[3]=$langs->trans("PropalStatusNotSigned"); + $this->labelstatut[4]=$langs->trans("PropalStatusBilled"); + $this->labelstatut_short[0]=$langs->trans("PropalStatusDraftShort"); + $this->labelstatut_short[1]=$langs->trans("Opened"); + $this->labelstatut_short[2]=$langs->trans("PropalStatusSignedShort"); + $this->labelstatut_short[3]=$langs->trans("PropalStatusNotSignedShort"); + $this->labelstatut_short[4]=$langs->trans("PropalStatusBilledShort"); + } /** * \brief Ajoute une ligne dans tableau products - * \param idproduct Id du produit � ajouter - * \param qty Quantit� - * \param remise_percent Remise relative effectu�e sur le produit - * \remarks $this->client doit etre charg� - * \TODO Remplacer les appels a cette fonction par generation objet Ligne - * ins�r� dans tableau $this->products + * \param idproduct Id du produit a ajouter + * \param qty Quantity + * \param remise_percent Remise relative effectuee sur le produit + * \remarks $this->client doit etre charge + * \TODO Remplacer les appels a cette fonction par generation objet Ligne + * insere dans tableau $this->products */ - function add_product($idproduct, $qty, $remise_percent=0) + function add_product($idproduct, $qty, $remise_percent=0) { global $conf, $mysoc; - + if (! $qty) $qty = 1; - + dolibarr_syslog("Propal::add_product $idproduct, $qty, $remise_percent"); if ($idproduct > 0) { @@ -158,27 +158,27 @@ class Propal extends CommonObject { $price = $prod->price; } - + $line = new PropaleLigne($this->db); - + $line->fk_product=$idproduct; $line->desc=$productdesc; $line->qty=$qty; $line->subprice=$price; $line->remise_percent=$remise_percent; $line->tva_tx=$tva_tx; - + $this->products[]=$line; } - } + } - /** - * \brief Ajout d'une ligne remise fixe dans la proposition, en base - * \param idremise Id de la remise fixe - * \return int >0 si ok, <0 si ko - */ - function insert_discount($idremise) - { + /** + * \brief Ajout d'une ligne remise fixe dans la proposition, en base + * \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'); @@ -227,26 +227,26 @@ class Propal extends CommonObject } else { - $this->db->rollback(); + $this->db->rollback(); return -1; } } else { $this->error=$propalligne->error; - $this->db->rollback(); + $this->db->rollback(); return -2; } } else { $this->db->rollback(); - return -2; + return -2; } } - /** - * \brief Ajout d'un produit dans la proposition, en base + /** + * \brief Ajout d'un produit dans la proposition, en base * \param propalid Id de la propale * \param desc Description de la ligne * \param pu_ht Prix unitaire @@ -255,68 +255,68 @@ class Propal extends CommonObject * \param fk_product Id du produit/service pred�fini * \param remise_percent Pourcentage de remise de la ligne * \param price_base_type HT or TTC - * \param pu_ttc Prix unitaire TTC - * \param info_bits Bits de type de lignes - * \return int >0 si ok, <0 si ko - * \see add_product + * \param pu_ttc Prix unitaire TTC + * \param info_bits Bits de type de lignes + * \return int >0 si ok, <0 si ko + * \see add_product * \remarks Les parametres sont deja cense etre juste et avec valeurs finales a l'appel * de cette methode. Aussi, pour le taux tva, il doit deja avoir ete d�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) - */ - function addline($propalid, $desc, $pu_ht, $qty, $txtva, $fk_product=0, $remise_percent=0, $price_base_type='HT', $pu_ttc=0, $info_bits=0) - { - global $conf; - - dolibarr_syslog("Propal::Addline propalid=$propalid, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_except=$remise_percent, price_base_type=$price_base_type, pu_ttc=$pu_ttc, info_bits=$info_bits"); - include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php'); - - if ($this->statut == 0) - { - $this->db->begin(); - - // Clean parameters - $remise_percent=price2num($remise_percent); - $qty=price2num($qty); - if ($conf->global->PROPALE_USE_OPTION_LINE && !$qty) - { - $qty=0; - } - else if (! $qty) - { - $qty=1; - } - $pu_ht=price2num($pu_ht); - $pu_ttc=price2num($pu_ttc); - $txtva=price2num($txtva); - - if ($price_base_type=='HT') - { - $pu=$pu_ht; - } - else - { - $pu=$pu_ttc; - } - - // 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, $info_bits); - $total_ht = $tabprice[0]; - $total_tva = $tabprice[1]; - $total_ttc = $tabprice[2]; - - // \TODO A virer - // 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; - } + * et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue) + */ + function addline($propalid, $desc, $pu_ht, $qty, $txtva, $fk_product=0, $remise_percent=0, $price_base_type='HT', $pu_ttc=0, $info_bits=0) + { + global $conf; + + dolibarr_syslog("Propal::Addline propalid=$propalid, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_except=$remise_percent, price_base_type=$price_base_type, pu_ttc=$pu_ttc, info_bits=$info_bits"); + include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php'); + + if ($this->statut == 0) + { + $this->db->begin(); + + // Clean parameters + $remise_percent=price2num($remise_percent); + $qty=price2num($qty); + if ($conf->global->PROPALE_USE_OPTION_LINE && !$qty) + { + $qty=0; + } + else if (! $qty) + { + $qty=1; + } + $pu_ht=price2num($pu_ht); + $pu_ttc=price2num($pu_ttc); + $txtva=price2num($txtva); + + if ($price_base_type=='HT') + { + $pu=$pu_ht; + } + else + { + $pu=$pu_ttc; + } + + // 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, $info_bits); + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + + // \TODO A virer + // 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; + } // Insert line $ligne=new PropaleLigne($this->db); @@ -334,7 +334,7 @@ class Propal extends CommonObject $ligne->total_ht=$total_ht; $ligne->total_tva=$total_tva; $ligne->total_ttc=$total_ttc; - + // Mise en option de la ligne if ($conf->global->PROPALE_USE_OPTION_LINE && !$qty) $ligne->special_code=3; @@ -342,20 +342,20 @@ class Propal extends CommonObject $ligne->price=$price; $ligne->remise=$remise; - $result=$ligne->insert(); + $result=$ligne->insert(); if ($result > 0) { // Mise a jour informations denormalisees au niveau de la propale meme $result=$this->update_price(); - if ($result > 0) - { + if ($result > 0) + { $this->db->commit(); return 1; } else - { - $this->error=$this->db->error(); - dolibarr_syslog("Error sql=$sql, error=".$this->error,LOG_ERR); + { + $this->error=$this->db->error(); + dolibarr_syslog("Error sql=$sql, error=".$this->error,LOG_ERR); $this->db->rollback(); return -1; } @@ -364,589 +364,589 @@ class Propal extends CommonObject { $this->error=$ligne->error; $this->db->rollback(); - return -2; - } - } + return -2; + } + } } - /** - * \brief Mise a jour d'une ligne de produit - * \param rowid Id de la ligne - * \param pu Prix unitaire (HT ou TTC selon price_base_type) - * \param qty Quantity - * \param remise_percent Remise effectuee sur le produit - * \param txtva Taux de TVA - * \param desc Description - * \param price_base_type HT ou TTC - * \param info_bits Miscellanous informations - * \return int 0 en cas de succes - */ - function updateline($rowid, $pu, $qty, $remise_percent=0, $txtva, $desc='', $price_base_type='HT', $info_bits=0) - { - global $conf; - - dolibarr_syslog("Propal::UpdateLine $rowid, $pu, $qty, $remise_percent, $txtva, $desc, $price_base_type, $info_bits"); - include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php'); - - if ($this->statut == 0) - { - $this->db->begin(); - - // Nettoyage param�tres - $remise_percent=price2num($remise_percent); - $qty=price2num($qty); - if ($conf->global->PROPALE_USE_OPTION_LINE && !$qty) - { - $qty=0; - $remise_percent=0; - } - else 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, 0, $price_base_type, $info_bits); - $total_ht = $tabprice[0]; - $total_tva = $tabprice[1]; - $total_ttc = $tabprice[2]; - - // Anciens indicateurs: $price, $remise (a ne plus utiliser) - $price = $pu; - if ($remise_percent > 0) - { - $remise = round(($pu * $remise_percent / 100), 2); - $price = $pu - $remise; - } - - $sql = "UPDATE ".MAIN_DB_PREFIX."propaldet "; - $sql.= " SET qty='".$qty."'"; - $sql.= " , price='". price2num($price)."'"; // \TODO A virer - $sql.= " , remise_percent='".$remise_percent."'"; // \TODO A virer - $sql.= " , subprice=".price2num($pu); - $sql.= " , tva_tx=".price2num($txtva); - $sql.= " , description='".addslashes($desc)."'"; - $sql.= " , total_ht=".price2num($total_ht); - $sql.= " , total_tva=".price2num($total_tva); - $sql.= " , total_ttc=".price2num($total_ttc); - $sql.= " , info_bits=".$info_bits; - if ($conf->global->PROPALE_USE_OPTION_LINE && !$qty) - { - $sql.= " , special_code=3"; - } - else - { - $sql.= " , special_code=0"; - } - $sql.= " WHERE rowid = '".$rowid."';"; + /** + * \brief Mise a jour d'une ligne de produit + * \param rowid Id de la ligne + * \param pu Prix unitaire (HT ou TTC selon price_base_type) + * \param qty Quantity + * \param remise_percent Remise effectuee sur le produit + * \param txtva Taux de TVA + * \param desc Description + * \param price_base_type HT ou TTC + * \param info_bits Miscellanous informations + * \return int 0 en cas de succes + */ + function updateline($rowid, $pu, $qty, $remise_percent=0, $txtva, $desc='', $price_base_type='HT', $info_bits=0) + { + global $conf; + + dolibarr_syslog("Propal::UpdateLine $rowid, $pu, $qty, $remise_percent, $txtva, $desc, $price_base_type, $info_bits"); + include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php'); + + if ($this->statut == 0) + { + $this->db->begin(); + + // Nettoyage param�tres + $remise_percent=price2num($remise_percent); + $qty=price2num($qty); + if ($conf->global->PROPALE_USE_OPTION_LINE && !$qty) + { + $qty=0; + $remise_percent=0; + } + else if (! $qty) + { + $qty=1; + } + $pu = price2num($pu); + $txtva = price2num($txtva); - $result=$this->db->query($sql); - if ($result > 0) - { - $this->update_price(); - $this->db->commit(); - return $result; - } - else - { - $this->error=$this->db->error(); - $this->db->rollback(); - dolibarr_syslog("Propal::UpdateLine Erreur sql=$sql, error=".$this->error); - return -1; - } - } - else - { - dolibarr_syslog("Propal::UpdateLigne Erreur -2 Propal en mode incompatible pour cette action"); - return -2; - } - } + // 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, $info_bits); + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + // Anciens indicateurs: $price, $remise (a ne plus utiliser) + $price = $pu; + if ($remise_percent > 0) + { + $remise = round(($pu * $remise_percent / 100), 2); + $price = $pu - $remise; + } - /** - * \brief Supprime une ligne de detail - * \param idligne Id de la ligne detail � supprimer - * \return int >0 si ok, <0 si ko - */ - function delete_product($idligne) - { - if ($this->statut == 0) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."propaldet WHERE rowid = ".$idligne; + $sql = "UPDATE ".MAIN_DB_PREFIX."propaldet "; + $sql.= " SET qty='".$qty."'"; + $sql.= " , price='". price2num($price)."'"; // \TODO A virer + $sql.= " , remise_percent='".$remise_percent."'"; // \TODO A virer + $sql.= " , subprice=".price2num($pu); + $sql.= " , tva_tx=".price2num($txtva); + $sql.= " , description='".addslashes($desc)."'"; + $sql.= " , total_ht=".price2num($total_ht); + $sql.= " , total_tva=".price2num($total_tva); + $sql.= " , total_ttc=".price2num($total_ttc); + $sql.= " , info_bits=".$info_bits; + if ($conf->global->PROPALE_USE_OPTION_LINE && !$qty) + { + $sql.= " , special_code=3"; + } + else + { + $sql.= " , special_code=0"; + } + $sql.= " WHERE rowid = '".$rowid."';"; - if ($this->db->query($sql) ) - { - $this->update_price(); - - return 1; - } - else - { - return -1; - } - } - else - { - return -2; - } - } - - - /** - * \brief Create commercial proposal - * \param user User that create - * \return int <0 si ko, >=0 si ok - */ - function create($user='') - { - global $langs,$conf,$mysoc; - - // on verifie si la ref n'est pas utilisee - $soc = new Societe($this->db); - $soc->fetch($this->socid); - $this->verifyNumRef($soc); - - // Clean parameters - $this->fin_validite = $this->datep + ($this->duree_validite * 24 * 3600); - - dolibarr_syslog("Propal::create ref=".$this->ref); - - $this->db->begin(); - - $this->fetch_client(); - - // Insertion dans la base - $sql = "INSERT INTO ".MAIN_DB_PREFIX."propal (fk_soc, price,"; - $sql.= " remise, remise_percent, remise_absolue,"; - $sql.= " tva, total, datep, datec, ref, fk_user_author, note, note_public, model_pdf, fin_validite,"; - $sql.= " fk_cond_reglement, fk_mode_reglement, ref_client"; - if ($conf->global->PROPALE_ADD_SHIPPING_DATE) $sql.= ", date_livraison"; - $sql.= ") "; - $sql.= " VALUES (".$this->socid.", 0,"; - $sql.= " ".$this->remise.", ".($this->remise_percent?$this->remise_percent:'null').", ".($this->remise_absolue?$this->remise_absolue:'null').","; - $sql.= " 0,0,".$this->db->idate($this->datep).", ".$this->db->idate(mktime()).", '".$this->ref."', "; - $sql.= ($user->id > 0 ? "'".$user->id."'":"null").","; - $sql.= "'".addslashes($this->note)."',"; - $sql.= "'".addslashes($this->note_public)."',"; - $sql.= "'".$this->modelpdf."',".$this->db->idate($this->fin_validite).","; - $sql.= " ".$this->cond_reglement_id.", ".$this->mode_reglement_id.","; - $sql.= "'".addslashes($this->ref_client)."'"; - if ($conf->global->PROPALE_ADD_SHIPPING_DATE) $sql.= ", ".($this->date_livraison?$this->db->idate($this->date_livraison):'null'); - $sql.= ")"; - - $resql=$this->db->query($sql); - if ($resql) - { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."propal"); - - if ($this->id) - { - /* - * 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, - 'HT' - ); - - if ($resql < 0) - { - $this->error=$this->db->error; - dolibarr_print_error($this->db); - break; - } - } - - // Affectation au projet - if ($resql && $this->projetidp) - { - $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fk_projet=".$this->projetidp." WHERE ref='".$this->ref."'"; - $result=$this->db->query($sql); - } - - // Affectation de l'adresse de livraison - if ($resql && $this->adresse_livraison_id) - { - $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fk_adresse_livraison=$this->adresse_livraison_id WHERE ref='$this->ref'"; - $result=$this->db->query($sql); - } - - if ($resql) - { - // Mise a jour infos denormalisees - $resql=$this->update_price(); - if ($resql) - { - // Appel des triggers - include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('PROPAL_CREATE',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - - $this->db->commit(); - dolibarr_syslog("Propal::ass::Create done id=".$this->id); - return $this->id; - } - else - { - $this->error=$this->db->error(); - dolibarr_syslog("Propal::Create -2 ".$this->error); - $this->db->rollback(); - return -2; - } - } - } - } - else - { - $this->error=$this->db->error(); - dolibarr_syslog("Propal::Create -1 ".$this->error); - $this->db->rollback(); - return -1; - } - - $this->db->commit(); - dolibarr_syslog("Propal::Create done id=".$this->id); - return $this->id; - } + $result=$this->db->query($sql); + if ($result > 0) + { + $this->update_price(); + $this->db->commit(); + return $result; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + dolibarr_syslog("Propal::UpdateLine Erreur sql=$sql, error=".$this->error); + return -1; + } + } + else + { + dolibarr_syslog("Propal::UpdateLigne Erreur -2 Propal en mode incompatible pour cette action"); + return -2; + } + } /** - * \brief Insert en base un objet propal completement definie par ses donnees membres (resultant d'une copie par exemple). - * \return int l'id du nouvel objet propal en base si ok, <0 si ko - * \see create - */ + * \brief Supprime une ligne de detail + * \param idligne Id de la ligne detail � supprimer + * \return int >0 si ok, <0 si ko + */ + function delete_product($idligne) + { + if ($this->statut == 0) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."propaldet WHERE rowid = ".$idligne; + + if ($this->db->query($sql) ) + { + $this->update_price(); + + return 1; + } + else + { + return -1; + } + } + else + { + return -2; + } + } + + + /** + * \brief Create commercial proposal + * \param user User that create + * \return int <0 si ko, >=0 si ok + */ + function create($user='') + { + global $langs,$conf,$mysoc; + + // on verifie si la ref n'est pas utilisee + $soc = new Societe($this->db); + $soc->fetch($this->socid); + $this->verifyNumRef($soc); + + // Clean parameters + $this->fin_validite = $this->datep + ($this->duree_validite * 24 * 3600); + + dolibarr_syslog("Propal::create ref=".$this->ref); + + $this->db->begin(); + + $this->fetch_client(); + + // Insertion dans la base + $sql = "INSERT INTO ".MAIN_DB_PREFIX."propal (fk_soc, price,"; + $sql.= " remise, remise_percent, remise_absolue,"; + $sql.= " tva, total, datep, datec, ref, fk_user_author, note, note_public, model_pdf, fin_validite,"; + $sql.= " fk_cond_reglement, fk_mode_reglement, ref_client"; + if ($conf->global->PROPALE_ADD_SHIPPING_DATE) $sql.= ", date_livraison"; + $sql.= ") "; + $sql.= " VALUES (".$this->socid.", 0,"; + $sql.= " ".$this->remise.", ".($this->remise_percent?$this->remise_percent:'null').", ".($this->remise_absolue?$this->remise_absolue:'null').","; + $sql.= " 0,0,".$this->db->idate($this->datep).", ".$this->db->idate(mktime()).", '".$this->ref."', "; + $sql.= ($user->id > 0 ? "'".$user->id."'":"null").","; + $sql.= "'".addslashes($this->note)."',"; + $sql.= "'".addslashes($this->note_public)."',"; + $sql.= "'".$this->modelpdf."',".$this->db->idate($this->fin_validite).","; + $sql.= " ".$this->cond_reglement_id.", ".$this->mode_reglement_id.","; + $sql.= "'".addslashes($this->ref_client)."'"; + if ($conf->global->PROPALE_ADD_SHIPPING_DATE) $sql.= ", ".($this->date_livraison?$this->db->idate($this->date_livraison):'null'); + $sql.= ")"; + + $resql=$this->db->query($sql); + if ($resql) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."propal"); + + if ($this->id) + { + /* + * 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, + 'HT' + ); + + if ($resql < 0) + { + $this->error=$this->db->error; + dolibarr_print_error($this->db); + break; + } + } + + // Affectation au projet + if ($resql && $this->projetidp) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fk_projet=".$this->projetidp." WHERE ref='".$this->ref."'"; + $result=$this->db->query($sql); + } + + // Affectation de l'adresse de livraison + if ($resql && $this->adresse_livraison_id) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fk_adresse_livraison=$this->adresse_livraison_id WHERE ref='$this->ref'"; + $result=$this->db->query($sql); + } + + if ($resql) + { + // Mise a jour infos denormalisees + $resql=$this->update_price(); + if ($resql) + { + // Appel des triggers + include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('PROPAL_CREATE',$this,$user,$langs,$conf); + if ($result < 0) { $error++; $this->errors=$interface->errors; } + // Fin appel triggers + + $this->db->commit(); + dolibarr_syslog("Propal::ass::Create done id=".$this->id); + return $this->id; + } + else + { + $this->error=$this->db->error(); + dolibarr_syslog("Propal::Create -2 ".$this->error); + $this->db->rollback(); + return -2; + } + } + } + } + else + { + $this->error=$this->db->error(); + dolibarr_syslog("Propal::Create -1 ".$this->error); + $this->db->rollback(); + return -1; + } + + $this->db->commit(); + dolibarr_syslog("Propal::Create done id=".$this->id); + return $this->id; + } + + + /** + * \brief Insert en base un objet propal completement definie par ses donnees membres (resultant d'une copie par exemple). + * \return int l'id du nouvel objet propal en base si ok, <0 si ko + * \see create + */ function create_from($user) { global $conf,$lang; - + $this->products=array(); $i=0; - foreach($this->lignes as $ligne) - { + foreach($this->lignes as $ligne) + { $this->products[$i]->desc=$ligne->desc; $this->products[$i]->subprice=$ligne->subprice; $this->products[$i]->qty=$ligne->qty; $this->products[$i]->tva_tx=$ligne->tva_tx; $this->products[$i]->fk_product=$ligne->fk_product; $this->products[$i]->remise_percent=$ligne->remise_percent; - + $i++; - } + } return $this->create(); } - - /** - * \brief Recupere de la base les caracteristiques d'une propale - * \param rowid id de la propal a recuperer - * \return int <0 si ko, 0 si non trouve, >0 si ok - */ - function fetch($rowid) - { - $sql = "SELECT p.rowid,ref,remise,remise_percent,remise_absolue,fk_soc"; + + /** + * \brief Recupere de la base les caracteristiques d'une propale + * \param rowid id de la propal a recuperer + * \return int <0 si ko, 0 si non trouve, >0 si ok + */ + function fetch($rowid) + { + $sql = "SELECT p.rowid,ref,remise,remise_percent,remise_absolue,fk_soc"; $sql.= ", total, tva, total_ht"; - $sql.= ", ".$this->db->pdate("datep")." as dp"; - $sql.= ", ".$this->db->pdate("fin_validite")." as dfv"; - $sql.= ", ".$this->db->pdate("date_livraison")." as date_livraison"; - $sql.= ", model_pdf, ref_client"; - $sql.= ", note, note_public"; - $sql.= ", fk_projet, fk_statut, fk_user_author"; - $sql.= ", fk_adresse_livraison"; - $sql.= ", p.fk_cond_reglement, cr.code as cond_reglement_code"; - $sql.= ", p.fk_mode_reglement, cp.code as mode_reglement_code"; - $sql.= ", c.label as statut_label"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_propalst as c, ".MAIN_DB_PREFIX."propal as p"; + $sql.= ", ".$this->db->pdate("datep")." as dp"; + $sql.= ", ".$this->db->pdate("fin_validite")." as dfv"; + $sql.= ", ".$this->db->pdate("date_livraison")." as date_livraison"; + $sql.= ", model_pdf, ref_client"; + $sql.= ", note, note_public"; + $sql.= ", fk_projet, fk_statut, fk_user_author"; + $sql.= ", fk_adresse_livraison"; + $sql.= ", p.fk_cond_reglement, cr.code as cond_reglement_code"; + $sql.= ", p.fk_mode_reglement, cp.code as mode_reglement_code"; + $sql.= ", c.label as statut_label"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_propalst as c, ".MAIN_DB_PREFIX."propal as p"; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as cp ON p.fk_mode_reglement = cp.id'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'cond_reglement as cr ON p.fk_cond_reglement = cr.rowid'; - $sql.= " WHERE p.fk_statut = c.id"; - $sql.= " AND p.rowid='".$rowid."'"; + $sql.= " WHERE p.fk_statut = c.id"; + $sql.= " AND p.rowid='".$rowid."'"; dolibarr_syslog("Propal::fecth rowid=".$rowid); - - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - $obj = $this->db->fetch_object($resql); - $this->id = $rowid; + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); - $this->date = $obj->dp; - $this->datep = $obj->dp; - $this->fin_validite = $obj->dfv; - $this->ref = $obj->ref; - $this->ref_client = $obj->ref_client; - $this->remise = $obj->remise; - $this->remise_percent = $obj->remise_percent; - $this->remise_absolue = $obj->remise_absolue; - $this->total = $obj->total; - $this->total_ht = $obj->total_ht; - $this->total_tva = $obj->tva; - $this->total_ttc = $obj->total; - $this->socid = $obj->fk_soc; - $this->projetidp = $obj->fk_projet; - $this->modelpdf = $obj->model_pdf; - $this->note = $obj->note; - $this->note_public = $obj->note_public; - $this->statut = $obj->fk_statut; - $this->statut_libelle = $obj->statut_label; - $this->mode_reglement_id = $obj->fk_mode_reglement; - $this->mode_reglement_code = $obj->mode_reglement_code; - $this->cond_reglement_id = $obj->fk_cond_reglement; - $this->cond_reglement_code = $obj->cond_reglement_code; - $this->date_livraison = $obj->date_livraison; - $this->adresse_livraison_id = $obj->fk_adresse_livraison; + $this->id = $rowid; - $this->user_author_id = $obj->fk_user_author; + $this->date = $obj->dp; + $this->datep = $obj->dp; + $this->fin_validite = $obj->dfv; + $this->ref = $obj->ref; + $this->ref_client = $obj->ref_client; + $this->remise = $obj->remise; + $this->remise_percent = $obj->remise_percent; + $this->remise_absolue = $obj->remise_absolue; + $this->total = $obj->total; + $this->total_ht = $obj->total_ht; + $this->total_tva = $obj->tva; + $this->total_ttc = $obj->total; + $this->socid = $obj->fk_soc; + $this->projetidp = $obj->fk_projet; + $this->modelpdf = $obj->model_pdf; + $this->note = $obj->note; + $this->note_public = $obj->note_public; + $this->statut = $obj->fk_statut; + $this->statut_libelle = $obj->statut_label; + $this->mode_reglement_id = $obj->fk_mode_reglement; + $this->mode_reglement_code = $obj->mode_reglement_code; + $this->cond_reglement_id = $obj->fk_cond_reglement; + $this->cond_reglement_code = $obj->cond_reglement_code; + $this->date_livraison = $obj->date_livraison; + $this->adresse_livraison_id = $obj->fk_adresse_livraison; - if ($this->cond_reglement_id) - { - $sql = "SELECT rowid, libelle, code, libelle_facture"; - $sql.= " FROM ".MAIN_DB_PREFIX."cond_reglement"; - $sql.= " WHERE rowid = ".$this->cond_reglement_id; + $this->user_author_id = $obj->fk_user_author; - $resqlcond = $this->db->query($sql); + if ($this->cond_reglement_id) + { + $sql = "SELECT rowid, libelle, code, libelle_facture"; + $sql.= " FROM ".MAIN_DB_PREFIX."cond_reglement"; + $sql.= " WHERE rowid = ".$this->cond_reglement_id; - if ($resqlcond) - { - $objc = $this->db->fetch_object($resqlcond); - $this->cond_reglement = $objc->libelle; - $this->cond_reglement_document = $objc->libelle_facture; - $this->cond_reglement_code = $objc->code; - } - } + $resqlcond = $this->db->query($sql); - if ($obj->fk_statut == 0) - { - $this->brouillon = 1; - } + if ($resqlcond) + { + $objc = $this->db->fetch_object($resqlcond); + $this->cond_reglement = $objc->libelle; + $this->cond_reglement_document = $objc->libelle_facture; + $this->cond_reglement_code = $objc->code; + } + } - $this->lignes = array(); - $this->db->free($resql); + if ($obj->fk_statut == 0) + { + $this->brouillon = 1; + } - /* - * Lignes propales li�es � un produit ou non - */ - $sql = "SELECT d.description, d.price, d.tva_tx, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,"; - $sql.= " d.info_bits, d.total_ht, d.total_tva, d.total_ttc, d.marge_tx, d.marque_tx, d.special_code, d.rang,"; - $sql.= " p.ref, p.label, p.description as product_desc"; - $sql.= " FROM ".MAIN_DB_PREFIX."propaldet as d"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON d.fk_product = p.rowid"; - $sql.= " WHERE d.fk_propal = ".$this->id; - $sql.= " ORDER by d.rang"; + $this->lignes = array(); + $this->db->free($resql); - $result = $this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - $i = 0; + /* + * Lignes propales li�es � un produit ou non + */ + $sql = "SELECT d.description, d.price, d.tva_tx, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,"; + $sql.= " d.info_bits, d.total_ht, d.total_tva, d.total_ttc, d.marge_tx, d.marque_tx, d.special_code, d.rang,"; + $sql.= " p.ref, p.label, p.description as product_desc"; + $sql.= " FROM ".MAIN_DB_PREFIX."propaldet as d"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON d.fk_product = p.rowid"; + $sql.= " WHERE d.fk_propal = ".$this->id; + $sql.= " ORDER by d.rang"; - while ($i < $num) - { - $objp = $this->db->fetch_object($result); + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; - $ligne = new PropaleLigne($this->db); + while ($i < $num) + { + $objp = $this->db->fetch_object($result); - $ligne->desc = $objp->description; // Description ligne - $ligne->qty = $objp->qty; - $ligne->tva_tx = $objp->tva_tx; - $ligne->subprice = $objp->subprice; - $ligne->fk_remise_except = $objp->fk_remise_except; - $ligne->remise_percent = $objp->remise_percent; - $ligne->price = $objp->price; + $ligne = new PropaleLigne($this->db); - $ligne->info_bits = $objp->info_bits; - $ligne->total_ht = $objp->total_ht; - $ligne->total_tva = $objp->total_tva; - $ligne->total_ttc = $objp->total_ttc; - $ligne->marge_tx = $objp->marge_tx; - $ligne->marque_tx = $objp->marque_tx; - $ligne->special_code = $objp->special_code; - $ligne->rang = $objp->rang; + $ligne->desc = $objp->description; // Description ligne + $ligne->qty = $objp->qty; + $ligne->tva_tx = $objp->tva_tx; + $ligne->subprice = $objp->subprice; + $ligne->fk_remise_except = $objp->fk_remise_except; + $ligne->remise_percent = $objp->remise_percent; + $ligne->price = $objp->price; - $ligne->fk_product = $objp->fk_product; + $ligne->info_bits = $objp->info_bits; + $ligne->total_ht = $objp->total_ht; + $ligne->total_tva = $objp->total_tva; + $ligne->total_ttc = $objp->total_ttc; + $ligne->marge_tx = $objp->marge_tx; + $ligne->marque_tx = $objp->marque_tx; + $ligne->special_code = $objp->special_code; + $ligne->rang = $objp->rang; - $ligne->libelle = $objp->label; // Label produit - $ligne->product_desc = $objp->product_desc; // Description produit - $ligne->ref = $objp->ref; + $ligne->fk_product = $objp->fk_product; - $this->lignes[$i] = $ligne; - //dolibarr_syslog("1 ".$ligne->fk_product); - //print "xx $i ".$this->lignes[$i]->fk_product; - $i++; - } - $this->db->free($result); - } - else - { - $this->error=$this->db->error(); - dolibarr_syslog("Propal::Fetch Error $this->error, sql=$sql"); - return -1; - } + $ligne->libelle = $objp->label; // Label produit + $ligne->product_desc = $objp->product_desc; // Description produit + $ligne->ref = $objp->ref; - return 1; - } - - $this->error="Record Not Found"; - return 0; - } - else - { - $this->error=$this->db->error(); - dolibarr_syslog("Propal::Fetch Error sql=$sql ".$this->error); - return -1; - } - } + $this->lignes[$i] = $ligne; + //dolibarr_syslog("1 ".$ligne->fk_product); + //print "xx $i ".$this->lignes[$i]->fk_product; + $i++; + } + $this->db->free($result); + } + else + { + $this->error=$this->db->error(); + dolibarr_syslog("Propal::Fetch Error $this->error, sql=$sql"); + return -1; + } - /** - * \brief Passe au statut valider une propale - * \param user Objet utilisateur qui valide - * \return int <0 si ko, >=0 si ok - */ - function valid($user) - { - global $conf,$langs; + return 1; + } - if ($user->rights->propale->valider) - { - $this->db->begin(); + $this->error="Record Not Found"; + return 0; + } + else + { + $this->error=$this->db->error(); + dolibarr_syslog("Propal::Fetch Error sql=$sql ".$this->error); + return -1; + } + } - $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; - $sql.= " SET fk_statut = 1, date_valid=".$this->db->idate(mktime()).", fk_user_valid=".$user->id; - $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; + /** + * \brief Passe au statut valider une propale + * \param user Objet utilisateur qui valide + * \return int <0 si ko, >=0 si ok + */ + function valid($user) + { + global $conf,$langs; - if ($this->db->query($sql)) - { - $this->use_webcal=($conf->global->PHPWEBCALENDAR_PROPALSTATUS=='always'?1:0); + if ($user->rights->propale->valider) + { + $this->db->begin(); - // Appel des triggers - include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('PROPAL_VALIDATE',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers + $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; + $sql.= " SET fk_statut = 1, date_valid=".$this->db->idate(mktime()).", fk_user_valid=".$user->id; + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - } + if ($this->db->query($sql)) + { + $this->use_webcal=($conf->global->PHPWEBCALENDAR_PROPALSTATUS=='always'?1:0); + + // Appel des triggers + include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('PROPAL_VALIDATE',$this,$user,$langs,$conf); + if ($result < 0) { $error++; $this->errors=$interface->errors; } + // Fin appel triggers + + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + } - /** - * \brief D�finit la date de fin de validit� - * \param user Objet utilisateur qui modifie - * \param date_fin_validite Date fin - * \return int <0 si ko, >0 si ok - */ - function set_echeance($user, $date_fin_validite) - { - if ($user->rights->propale->creer) - { - $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fin_validite = ".$this->db->idate($date_fin_validite); - $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; - if ($this->db->query($sql) ) - { - $this->fin_validite = $date_fin_validite; - return 1; - } - else - { - $this->error=$this->db->error(); - dolibarr_syslog("Propal::set_echeance Erreur SQL"); - return -1; - } - } - } + /** + * \brief D�finit la date de fin de validit� + * \param user Objet utilisateur qui modifie + * \param date_fin_validite Date fin + * \return int <0 si ko, >0 si ok + */ + function set_echeance($user, $date_fin_validite) + { + if ($user->rights->propale->creer) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fin_validite = ".$this->db->idate($date_fin_validite); + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; + if ($this->db->query($sql) ) + { + $this->fin_validite = $date_fin_validite; + return 1; + } + else + { + $this->error=$this->db->error(); + dolibarr_syslog("Propal::set_echeance Erreur SQL"); + return -1; + } + } + } - /** - * \brief D�finit une date de livraison - * \param user Objet utilisateur qui modifie - * \param date_livraison date de livraison - * \return int <0 si ko, >0 si ok - */ - function set_date_livraison($user, $date_livraison) - { - if ($user->rights->propale->creer) - { - $sql = "UPDATE ".MAIN_DB_PREFIX."propal "; - $sql.= " SET date_livraison = ".$this->db->idate($date_livraison); - $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; + /** + * \brief D�finit une date de livraison + * \param user Objet utilisateur qui modifie + * \param date_livraison date de livraison + * \return int <0 si ko, >0 si ok + */ + function set_date_livraison($user, $date_livraison) + { + if ($user->rights->propale->creer) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."propal "; + $sql.= " SET date_livraison = ".$this->db->idate($date_livraison); + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; - if ($this->db->query($sql)) - { - $this->date_livraison = $date_livraison; - return 1; - } - else - { - $this->error=$this->db->error(); - dolibarr_syslog("Propal::set_date_livraison Erreur SQL"); - return -1; - } - } - } + if ($this->db->query($sql)) + { + $this->date_livraison = $date_livraison; + return 1; + } + else + { + $this->error=$this->db->error(); + dolibarr_syslog("Propal::set_date_livraison Erreur SQL"); + return -1; + } + } + } - /** - * \brief D�finit une adresse de livraison - * \param user Objet utilisateur qui modifie - * \param adresse_livraison Adresse de livraison - * \return int <0 si ko, >0 si ok - */ - function set_adresse_livraison($user, $adresse_livraison) - { - if ($user->rights->propale->creer) - { - $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fk_adresse_livraison = '".$adresse_livraison."'"; - $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; + /** + * \brief D�finit une adresse de livraison + * \param user Objet utilisateur qui modifie + * \param adresse_livraison Adresse de livraison + * \return int <0 si ko, >0 si ok + */ + function set_adresse_livraison($user, $adresse_livraison) + { + if ($user->rights->propale->creer) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fk_adresse_livraison = '".$adresse_livraison."'"; + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; - if ($this->db->query($sql) ) - { - $this->adresse_livraison_id = $adresse_livraison; - return 1; - } - else - { - $this->error=$this->db->error(); - dolibarr_syslog("Propal::set_adresse_livraison Erreur SQL"); - return -1; - } - } - } - - /** - * \brief Positionne numero reference client - * \param user Utilisateur qui modifie - * \param ref_client Reference client - * \return int <0 si ko, >0 si ok - */ + if ($this->db->query($sql) ) + { + $this->adresse_livraison_id = $adresse_livraison; + return 1; + } + else + { + $this->error=$this->db->error(); + dolibarr_syslog("Propal::set_adresse_livraison Erreur SQL"); + return -1; + } + } + } + + /** + * \brief Positionne numero reference client + * \param user Utilisateur qui modifie + * \param ref_client Reference client + * \return int <0 si ko, >0 si ok + */ function set_ref_client($user, $ref_client) { if ($user->rights->propale->creer) { - dolibarr_syslog('Propale::set_ref_client this->id='.$this->id.', ref_client='.$ref_client); + dolibarr_syslog('Propale::set_ref_client this->id='.$this->id.', ref_client='.$ref_client); $sql = 'UPDATE '.MAIN_DB_PREFIX.'propal SET ref_client = '.(empty($ref_client) ? 'NULL' : '\''.addslashes($ref_client).'\''); $sql.= ' WHERE rowid = '.$this->id; @@ -957,161 +957,161 @@ class Propal extends CommonObject } else { - $this->error=$this->db->error(); + $this->error=$this->db->error(); dolibarr_syslog('Propale::set_ref_client Erreur '.$this->error.' - '.$sql); - return -2; + return -2; } } else { - return -1; + return -1; } } - /** - * \brief D�finit une remise globale relative sur la proposition - * \param user Objet utilisateur qui modifie - * \param remise Montant remise - * \return int <0 si ko, >0 si ok - */ - function set_remise_percent($user, $remise) - { + /** + * \brief D�finit une remise globale relative sur la proposition + * \param user Objet utilisateur qui modifie + * \param remise Montant remise + * \return int <0 si ko, >0 si ok + */ + function set_remise_percent($user, $remise) + { $remise=trim($remise)?trim($remise):0; - if ($user->rights->propale->creer) - { - $remise = price2num($remise); + if ($user->rights->propale->creer) + { + $remise = price2num($remise); - $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET remise_percent = ".$remise; - $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; + $sql = "UPDATE ".MAIN_DB_PREFIX."propal 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(); - return 1; - } - else - { - $this->error=$this->db->error(); - dolibarr_syslog("Propal::set_remise_percent Error sql=$sql"); - return -1; - } - } - } + if ($this->db->query($sql) ) + { + $this->remise_percent = $remise; + $this->update_price(); + return 1; + } + else + { + $this->error=$this->db->error(); + dolibarr_syslog("Propal::set_remise_percent Error sql=$sql"); + return -1; + } + } + } - /** - * \brief D�finit une remise globale absolue sur la proposition - * \param user Objet utilisateur qui modifie - * \param remise Montant remise - * \return int <0 si ko, >0 si ok - */ - function set_remise_absolue($user, $remise) - { + /** + * \brief D�finit une remise globale absolue sur la proposition + * \param user Objet utilisateur qui modifie + * \param remise Montant remise + * \return int <0 si ko, >0 si ok + */ + function set_remise_absolue($user, $remise) + { $remise=trim($remise)?trim($remise):0; - if ($user->rights->propale->creer) - { - $remise = price2num($remise); + if ($user->rights->propale->creer) + { + $remise = price2num($remise); - $sql = "UPDATE ".MAIN_DB_PREFIX."propal "; - $sql.= " SET remise_absolue = ".$remise; - $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; + $sql = "UPDATE ".MAIN_DB_PREFIX."propal "; + $sql.= " SET remise_absolue = ".$remise; + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; - if ($this->db->query($sql) ) - { - $this->remise_absolue = $remise; - $this->update_price(); - return 1; - } - else - { - $this->error=$this->db->error(); - dolibarr_syslog("Propal::set_remise_absolue Error sql=$sql"); - return -1; - } - } - } + if ($this->db->query($sql) ) + { + $this->remise_absolue = $remise; + $this->update_price(); + return 1; + } + else + { + $this->error=$this->db->error(); + dolibarr_syslog("Propal::set_remise_absolue Error sql=$sql"); + return -1; + } + } + } - /** - * \brief Cloture de la proposition commerciale - * \param user Utilisateur qui cloture - * \param statut Statut - * \param note Commentaire - * \return int <0 si ko, >0 si ok - */ - function cloture($user, $statut, $note) - { - global $langs,$conf; - + /** + * \brief Cloture de la proposition commerciale + * \param user Utilisateur qui cloture + * \param statut Statut + * \param note Commentaire + * \return int <0 si ko, >0 si ok + */ + function cloture($user, $statut, $note) + { + global $langs,$conf; + $this->statut = $statut; - $this->db->begin(); + $this->db->begin(); - $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; - $sql.= " SET fk_statut = ".$statut.", note = '".addslashes($note)."', date_cloture=".$this->db->idate(mktime()).", fk_user_cloture=".$user->id; - $sql.= " WHERE rowid = ".$this->id; + $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; + $sql.= " SET fk_statut = ".$statut.", note = '".addslashes($note)."', date_cloture=".$this->db->idate(mktime()).", fk_user_cloture=".$user->id; + $sql.= " WHERE rowid = ".$this->id; - $resql=$this->db->query($sql); - if ($resql) - { - if ($statut == 2) - { - // Propale sign�e - include_once(DOL_DOCUMENT_ROOT."/commande/commande.class.php"); + $resql=$this->db->query($sql); + if ($resql) + { + if ($statut == 2) + { + // Propale sign�e + include_once(DOL_DOCUMENT_ROOT."/commande/commande.class.php"); - $result=$this->create_commande($user); + $result=$this->create_commande($user); - if ($result >= 0) - { - // Classe la soci�t� rattach�e comme client - $soc=new Societe($this->db); - $soc->id = $this->socid; - $result=$soc->set_as_client(); - } + if ($result >= 0) + { + // Classe la soci�t� rattach�e comme client + $soc=new Societe($this->db); + $soc->id = $this->socid; + $result=$soc->set_as_client(); + } - if ($result < 0) - { - $this->error=$this->db->error(); - $this->db->rollback(); - return -2; - } + if ($result < 0) + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -2; + } - $this->use_webcal=($conf->global->PHPWEBCALENDAR_PROPALSTATUS=='always'?1:0); + $this->use_webcal=($conf->global->PHPWEBCALENDAR_PROPALSTATUS=='always'?1:0); - // Appel des triggers - include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('PROPAL_CLOSE_SIGNED',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } - else - { - $this->use_webcal=($conf->global->PHPWEBCALENDAR_PROPALSTATUS=='always'?1:0); + // Appel des triggers + include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('PROPAL_CLOSE_SIGNED',$this,$user,$langs,$conf); + if ($result < 0) { $error++; $this->errors=$interface->errors; } + // Fin appel triggers + } + else + { + $this->use_webcal=($conf->global->PHPWEBCALENDAR_PROPALSTATUS=='always'?1:0); - // Appel des triggers - include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('PROPAL_CLOSE_REFUSED',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } + // Appel des triggers + include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('PROPAL_CLOSE_REFUSED',$this,$user,$langs,$conf); + if ($result < 0) { $error++; $this->errors=$interface->errors; } + // Fin appel triggers + } - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error(); - $this->db->rollback(); - return -1; - } - } + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } - /** + /** * \brief Classe la propale comme factur�e * \return int <0 si ko, >0 si ok */ @@ -1130,212 +1130,212 @@ class Propal extends CommonObject } - /** - * \brief Cr�e une commande � partir de la proposition commerciale - * \param user Utilisateur - * \return int <0 si ko, >=0 si ok - */ - function create_commande($user) - { - global $conf; + /** + * \brief Cr�e une commande � partir de la proposition commerciale + * \param user Utilisateur + * \return int <0 si ko, >=0 si ok + */ + function create_commande($user) + { + global $conf; - if ($conf->commande->enabled) - { - if ($this->statut == 2) - { - // Propale sign�e - include_once(DOL_DOCUMENT_ROOT."/commande/commande.class.php"); - $commande = new Commande($this->db); - $result=$commande->create_from_propale($user, $this->id); - - // Ne pas passer par la commande provisoire - if ($conf->global->COMMANDE_VALID_AFTER_CLOSE_PROPAL == 1) - { - $commande->fetch($result); - $commande->valid($user); - } + if ($conf->commande->enabled) + { + if ($this->statut == 2) + { + // Propale sign�e + include_once(DOL_DOCUMENT_ROOT."/commande/commande.class.php"); + $commande = new Commande($this->db); + $result=$commande->create_from_propale($user, $this->id); - return $result; - } - else return 0; - } - else return 0; - } + // Ne pas passer par la commande provisoire + if ($conf->global->COMMANDE_VALID_AFTER_CLOSE_PROPAL == 1) + { + $commande->fetch($result); + $commande->valid($user); + } + + return $result; + } + else return 0; + } + else return 0; + } /** - * \brief Set draft status - * \param user Object user that modify - * \param int <0 if KO, >0 if OK - */ - function set_draft($user) - { + * \brief Set draft status + * \param user Object user that modify + * \param int <0 if KO, >0 if OK + */ + function set_draft($user) + { global $conf,$langs; - $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fk_statut = 0"; - $sql.= " WHERE rowid = ".$this->id; + $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fk_statut = 0"; + $sql.= " WHERE rowid = ".$this->id; - if ($this->db->query($sql)) - { - return 1; - } - else - { - return -1; - } - } + if ($this->db->query($sql)) + { + return 1; + } + else + { + return -1; + } + } - /** - * \brief Renvoi la liste des propal (�ventuellement filtr�e sur un user) dans un tableau - * \param brouillon 0=non brouillon, 1=brouillon - * \param user Objet user de filtre - * \return int -1 si erreur, tableau r�sultat si ok - */ + /** + * \brief Renvoi la liste des propal (�ventuellement filtr�e sur un user) dans un tableau + * \param brouillon 0=non brouillon, 1=brouillon + * \param user Objet user de filtre + * \return int -1 si erreur, tableau r�sultat si ok + */ - function liste_array ($brouillon=0, $user='') - { - $ga = array(); + function liste_array ($brouillon=0, $user='') + { + $ga = array(); - $sql = "SELECT rowid, ref FROM ".MAIN_DB_PREFIX."propal"; + $sql = "SELECT rowid, ref FROM ".MAIN_DB_PREFIX."propal"; - if ($brouillon) - { - $sql .= " WHERE fk_statut = 0"; - if ($user) - { - $sql .= " AND fk_user_author".$user; - } - } - else - { - if ($user) - { - $sql .= " WHERE fk_user_author".$user; - } - } + if ($brouillon) + { + $sql .= " WHERE fk_statut = 0"; + if ($user) + { + $sql .= " AND fk_user_author".$user; + } + } + else + { + if ($user) + { + $sql .= " WHERE fk_user_author".$user; + } + } - $sql .= " ORDER BY datep DESC"; + $sql .= " ORDER BY datep DESC"; - $result=$this->db->query($sql); - if ($result) - { - $nump = $this->db->num_rows($result); + $result=$this->db->query($sql); + if ($result) + { + $nump = $this->db->num_rows($result); - if ($nump) - { - $i = 0; - while ($i < $nump) - { - $obj = $this->db->fetch_object($result); + if ($nump) + { + $i = 0; + while ($i < $nump) + { + $obj = $this->db->fetch_object($result); - $ga[$obj->rowid] = $obj->ref; - $i++; - } - } - return $ga; - } - else - { - return -1; - } - } + $ga[$obj->rowid] = $obj->ref; + $i++; + } + } + return $ga; + } + else + { + return -1; + } + } - /** - * \brief Renvoie un tableau contenant les num�ros de commandes associ�es - * \remarks Fonction plus light que associated_orders - * \sa loadOrders - */ - function getOrderArrayList() - { - $ga = array(); + /** + * \brief Renvoie un tableau contenant les num�ros de commandes associ�es + * \remarks Fonction plus light que associated_orders + * \sa loadOrders + */ + function getOrderArrayList() + { + $ga = array(); - $sql = "SELECT fk_commande FROM ".MAIN_DB_PREFIX."co_pr"; - $sql .= " WHERE fk_propale = " . $this->id; - if ($this->db->query($sql) ) - { - $nump = $this->db->num_rows(); + $sql = "SELECT fk_commande FROM ".MAIN_DB_PREFIX."co_pr"; + $sql .= " WHERE fk_propale = " . $this->id; + if ($this->db->query($sql) ) + { + $nump = $this->db->num_rows(); - if ($nump) - { - $i = 0; - while ($i < $nump) - { - $obj = $this->db->fetch_object(); + if ($nump) + { + $i = 0; + while ($i < $nump) + { + $obj = $this->db->fetch_object(); - $ga[$i] = $obj->fk_commande; - $i++; - } - } - return $ga; - } - else - { - dolibarr_print_error($this->db); - } - } + $ga[$i] = $obj->fk_commande; + $i++; + } + } + return $ga; + } + else + { + dolibarr_print_error($this->db); + } + } - /** - * \brief Charge tableau contenant les commandes associ�es - * \remarks Fonction plus lourde que getOrderArrayList + /** + * \brief Charge tableau contenant les commandes associ�es + * \remarks Fonction plus lourde que getOrderArrayList * \return int <0 si ko, >0 si ok - * \sa getOrdersArrayList - */ - function loadOrders() - { + * \sa getOrdersArrayList + */ + function loadOrders() + { $this->commandes = array(); - $ga = array(); - $sql = "SELECT fk_commande FROM ".MAIN_DB_PREFIX."co_pr"; - $sql.= " WHERE fk_propale = " . $this->id; - $result=$this->db->query($sql); - if ($result) - { - $nump = $this->db->num_rows($result); + $ga = array(); + $sql = "SELECT fk_commande FROM ".MAIN_DB_PREFIX."co_pr"; + $sql.= " WHERE fk_propale = " . $this->id; + $result=$this->db->query($sql); + if ($result) + { + $nump = $this->db->num_rows($result); - if ($nump) - { - $i = 0; - while ($i < $nump) - { - $obj = $this->db->fetch_object($result); - $order=new Commande($this->db); + if ($nump) + { + $i = 0; + while ($i < $nump) + { + $obj = $this->db->fetch_object($result); + $order=new Commande($this->db); - if ($obj->fk_commande) - { - $order->fetch($obj->fk_commande); - $ga[$i] = $order; - } - $i++; - } - } - $this->commandes=$ga; - return 1; - } - else - { - $this->error=$this->db->error(); - return -1; - } - } + if ($obj->fk_commande) + { + $order->fetch($obj->fk_commande); + $ga[$i] = $order; + } + $i++; + } + } + $this->commandes=$ga; + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } - /** - * \brief Renvoie un tableau contenant les num�ros de factures associ�es - * \return array Tableau des id de factures - */ - function getInvoiceArrayList () - { + /** + * \brief Renvoie un tableau contenant les num�ros de factures associ�es + * \return array Tableau des id de factures + */ + function getInvoiceArrayList () + { return $this->InvoiceArrayList($this->id); } - /** - * \brief Renvoie un tableau contenant les id et ref des factures associ�es - * \param id Id propal - * \return array Tableau des id de factures - */ - function InvoiceArrayList($id) - { - $ga = array(); + /** + * \brief Renvoie un tableau contenant les id et ref des factures associ�es + * \param id Id propal + * \return array Tableau des id de factures + */ + function InvoiceArrayList($id) + { + $ga = array(); $sql = "SELECT f.rowid, f.facnumber"; $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; @@ -1348,76 +1348,76 @@ class Propal extends CommonObject $sql2.= ", ".MAIN_DB_PREFIX."co_pr as cp, ".MAIN_DB_PREFIX."co_fa as cf"; $sql2.= " WHERE cp.fk_propale = ".$id." AND cf.fk_commande = cp.fk_commande AND cf.fk_facture = f.rowid"; - //$sql = "SELECT fk_facture FROM ".MAIN_DB_PREFIX."fa_pr as fp"; - //$sql .= " WHERE fk_propal = " . $id; - dolibarr_syslog("Propal::InvoiceArrayList sql=".$sql); + //$sql = "SELECT fk_facture FROM ".MAIN_DB_PREFIX."fa_pr as fp"; + //$sql .= " WHERE fk_propal = " . $id; + dolibarr_syslog("Propal::InvoiceArrayList sql=".$sql); $resql=$this->db->query($sql); $resql2=null; - if ($resql) + if ($resql) { dolibarr_syslog("Propal::InvoiceArrayList sql2=".$sql2); $resql2=$this->db->query($sql2); } if ($resql2) - { + { $tab_sqlobj=array(); $nump = $this->db->num_rows($resql); for ($i = 0;$i < $nump;$i++) - { + { $sqlobj = $this->db->fetch_object($resql); $tab_sqlobj[] = $sqlobj; //$tab_sqlobjOrder[]= $sqlobj->dc; - } - $this->db->free($resql); - $nump = $this->db->num_rows($resql2); - + } + $this->db->free($resql); + $nump = $this->db->num_rows($resql2); + for ($i = 0;$i < $nump;$i++) - { + { $sqlobj = $this->db->fetch_object($resql2); $tab_sqlobj[] = $sqlobj; //$tab_sqlobjOrder[]= $sqlobj->dc; - } + } $this->db->free($resql2); //array_multisort ($tab_sqlobjOrder,$tab_sqlobj); - - //$nump = $this->db->num_rows($resql); + + //$nump = $this->db->num_rows($resql); $nump = sizeOf($tab_sqlobj); - - if ($nump) - { - $i = 0; - while ($i < $nump) - { - //$obj = $this->db->fetch_object($resql); + + if ($nump) + { + $i = 0; + while ($i < $nump) + { + //$obj = $this->db->fetch_object($resql); $obj = array_shift($tab_sqlobj); - - $ga[$obj->rowid] = $obj->facnumber; - $i++; - } - } - return $ga; - } - else - { - return -1; - } - } + + $ga[$obj->rowid] = $obj->facnumber; + $i++; + } + } + return $ga; + } + else + { + return -1; + } + } /** - * \brief Efface propal - * \param user Objet du user qui efface - */ + * \brief Efface propal + * \param user Objet du user qui efface + */ function delete($user) { global $conf; - + $sql = "DELETE FROM ".MAIN_DB_PREFIX."propaldet WHERE fk_propal = ".$this->id; if ( $this->db->query($sql) ) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."propal WHERE rowid = ".$this->id; if ( $this->db->query($sql) ) { - + // On efface le r�pertoire du pdf $propalref = sanitize_string($this->ref); if ($conf->propal->dir_output) @@ -1427,7 +1427,7 @@ class Propal extends CommonObject if (file_exists($file)) { propale_delete_preview($this->db, $this->id, $this->ref); - + if (!dol_delete_file($file)) { $this->error=$langs->trans("ErrorCanNotDeleteFile",$file); @@ -1443,7 +1443,7 @@ class Propal extends CommonObject } } } - + dolibarr_syslog("Suppression de la proposition $this->id par $user->id"); return 1; } @@ -1527,60 +1527,60 @@ class Propal extends CommonObject } - /** - * \brief Information sur l'objet propal - * \param id id de la propale - */ - function info($id) - { - $sql = "SELECT c.rowid, "; - $sql.= $this->db->pdate("datec")." as datec, ".$this->db->pdate("date_valid")." as datev, ".$this->db->pdate("date_cloture")." as dateo"; - $sql.= ", fk_user_author, fk_user_valid, fk_user_cloture"; - $sql.= " FROM ".MAIN_DB_PREFIX."propal as c"; - $sql.= " WHERE c.rowid = $id"; + /** + * \brief Information sur l'objet propal + * \param id id de la propale + */ + function info($id) + { + $sql = "SELECT c.rowid, "; + $sql.= $this->db->pdate("datec")." as datec, ".$this->db->pdate("date_valid")." as datev, ".$this->db->pdate("date_cloture")." as dateo"; + $sql.= ", fk_user_author, fk_user_valid, fk_user_cloture"; + $sql.= " FROM ".MAIN_DB_PREFIX."propal 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); + $result = $this->db->query($sql); - $this->id = $obj->rowid; + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); - $this->date_creation = $obj->datec; - $this->date_validation = $obj->datev; - $this->date_cloture = $obj->dateo; + $this->id = $obj->rowid; - $cuser = new User($this->db, $obj->fk_user_author); - $cuser->fetch(); - $this->user_creation = $cuser; + $this->date_creation = $obj->datec; + $this->date_validation = $obj->datev; + $this->date_cloture = $obj->dateo; - if ($obj->fk_user_valid) - { - $vuser = new User($this->db, $obj->fk_user_valid); - $vuser->fetch(); - $this->user_validation = $vuser; - } + $cuser = new User($this->db, $obj->fk_user_author); + $cuser->fetch(); + $this->user_creation = $cuser; - if ($obj->fk_user_cloture) - { - $cluser = new User($this->db, $obj->fk_user_cloture); - $cluser->fetch(); - $this->user_cloture = $cluser; - } + if ($obj->fk_user_valid) + { + $vuser = new User($this->db, $obj->fk_user_valid); + $vuser->fetch(); + $this->user_validation = $vuser; + } + + if ($obj->fk_user_cloture) + { + $cluser = new User($this->db, $obj->fk_user_cloture); + $cluser->fetch(); + $this->user_cloture = $cluser; + } } - $this->db->free($result); + $this->db->free($result); - } - else - { - dolibarr_print_error($this->db); - } - } + } + else + { + dolibarr_print_error($this->db); + } + } /** @@ -1598,101 +1598,101 @@ class Propal extends CommonObject * \param statut id statut * \param mode 0=libell� long, 1=libell� court, 2=Picto + Libell� court, 3=Picto, 4=Picto + Libell� long, 5=Libell� court + Picto * \return string Libell� - */ - function LibStatut($statut,$mode=1) - { - global $langs; - $langs->load("propal"); + */ + function LibStatut($statut,$mode=1) + { + global $langs; + $langs->load("propal"); - if ($mode == 0) - { - return $this->labelstatut[$statut]; + if ($mode == 0) + { + return $this->labelstatut[$statut]; } - if ($mode == 1) - { - return $this->labelstatut_short[$statut]; - } - if ($mode == 2) - { - if ($statut==0) return img_picto($langs->trans('PropalStatusDraftShort'),'statut0').' '.$this->labelstatut_short[$statut]; - if ($statut==1) return img_picto($langs->trans('PropalStatusOpenedShort'),'statut1').' '.$this->labelstatut_short[$statut]; - if ($statut==2) return img_picto($langs->trans('PropalStatusSignedShort'),'statut3').' '.$this->labelstatut_short[$statut]; - if ($statut==3) return img_picto($langs->trans('PropalStatusNotSignedShort'),'statut5').' '.$this->labelstatut_short[$statut]; - if ($statut==4) return img_picto($langs->trans('PropalStatusBilledShort'),'statut6').' '.$this->labelstatut_short[$statut]; - } - if ($mode == 3) - { - if ($statut==0) return img_picto($langs->trans('PropalStatusDraftShort'),'statut0'); - if ($statut==1) return img_picto($langs->trans('PropalStatusOpenedShort'),'statut1'); - if ($statut==2) return img_picto($langs->trans('PropalStatusSignedShort'),'statut3'); - if ($statut==3) return img_picto($langs->trans('PropalStatusNotSignedShort'),'statut5'); - if ($statut==4) return img_picto($langs->trans('PropalStatusBilledShort'),'statut6'); - } - if ($mode == 4) - { - if ($statut==0) return img_picto($langs->trans('PropalStatusDraft'),'statut0').' '.$this->labelstatut[$statut]; - if ($statut==1) return img_picto($langs->trans('PropalStatusOpened'),'statut1').' '.$this->labelstatut[$statut]; - if ($statut==2) return img_picto($langs->trans('PropalStatusSigned'),'statut3').' '.$this->labelstatut[$statut]; - if ($statut==3) return img_picto($langs->trans('PropalStatusNotSigned'),'statut5').' '.$this->labelstatut[$statut]; - if ($statut==4) return img_picto($langs->trans('PropalStatusBilled'),'statut6').' '.$this->labelstatut[$statut]; - } - if ($mode == 5) - { - if ($statut==0) return $this->labelstatut_short[$statut].' '.img_picto($langs->trans('PropalStatusDraftShort'),'statut0'); - if ($statut==1) return $this->labelstatut_short[$statut].' '.img_picto($langs->trans('PropalStatusOpenedShort'),'statut1'); - if ($statut==2) return $this->labelstatut_short[$statut].' '.img_picto($langs->trans('PropalStatusSignedShort'),'statut3'); - if ($statut==3) return $this->labelstatut_short[$statut].' '.img_picto($langs->trans('PropalStatusNotSignedShort'),'statut5'); - if ($statut==4) return $this->labelstatut_short[$statut].' '.img_picto($langs->trans('PropalStatusBilledShort'),'statut6'); - } - } + if ($mode == 1) + { + return $this->labelstatut_short[$statut]; + } + if ($mode == 2) + { + if ($statut==0) return img_picto($langs->trans('PropalStatusDraftShort'),'statut0').' '.$this->labelstatut_short[$statut]; + if ($statut==1) return img_picto($langs->trans('PropalStatusOpenedShort'),'statut1').' '.$this->labelstatut_short[$statut]; + if ($statut==2) return img_picto($langs->trans('PropalStatusSignedShort'),'statut3').' '.$this->labelstatut_short[$statut]; + if ($statut==3) return img_picto($langs->trans('PropalStatusNotSignedShort'),'statut5').' '.$this->labelstatut_short[$statut]; + if ($statut==4) return img_picto($langs->trans('PropalStatusBilledShort'),'statut6').' '.$this->labelstatut_short[$statut]; + } + if ($mode == 3) + { + if ($statut==0) return img_picto($langs->trans('PropalStatusDraftShort'),'statut0'); + if ($statut==1) return img_picto($langs->trans('PropalStatusOpenedShort'),'statut1'); + if ($statut==2) return img_picto($langs->trans('PropalStatusSignedShort'),'statut3'); + if ($statut==3) return img_picto($langs->trans('PropalStatusNotSignedShort'),'statut5'); + if ($statut==4) return img_picto($langs->trans('PropalStatusBilledShort'),'statut6'); + } + if ($mode == 4) + { + if ($statut==0) return img_picto($langs->trans('PropalStatusDraft'),'statut0').' '.$this->labelstatut[$statut]; + if ($statut==1) return img_picto($langs->trans('PropalStatusOpened'),'statut1').' '.$this->labelstatut[$statut]; + if ($statut==2) return img_picto($langs->trans('PropalStatusSigned'),'statut3').' '.$this->labelstatut[$statut]; + if ($statut==3) return img_picto($langs->trans('PropalStatusNotSigned'),'statut5').' '.$this->labelstatut[$statut]; + if ($statut==4) return img_picto($langs->trans('PropalStatusBilled'),'statut6').' '.$this->labelstatut[$statut]; + } + if ($mode == 5) + { + if ($statut==0) return $this->labelstatut_short[$statut].' '.img_picto($langs->trans('PropalStatusDraftShort'),'statut0'); + if ($statut==1) return $this->labelstatut_short[$statut].' '.img_picto($langs->trans('PropalStatusOpenedShort'),'statut1'); + if ($statut==2) return $this->labelstatut_short[$statut].' '.img_picto($langs->trans('PropalStatusSignedShort'),'statut3'); + if ($statut==3) return $this->labelstatut_short[$statut].' '.img_picto($langs->trans('PropalStatusNotSignedShort'),'statut5'); + if ($statut==4) return $this->labelstatut_short[$statut].' '.img_picto($langs->trans('PropalStatusBilledShort'),'statut6'); + } + } - /** - * \brief Charge indicateurs this->nbtodo et this->nbtodolate de tableau de bord - * \param user Objet user - * \param mode "opened" pour propal � fermer, "signed" pour propale � facturer - * \return int <0 si ko, >0 si ok - */ - function load_board($user,$mode) - { - global $conf, $user; + /** + * \brief Charge indicateurs this->nbtodo et this->nbtodolate de tableau de bord + * \param user Objet user + * \param mode "opened" pour propal � fermer, "signed" pour propale � facturer + * \return int <0 si ko, >0 si ok + */ + function load_board($user,$mode) + { + global $conf, $user; - $this->nbtodo=$this->nbtodolate=0; - $clause = "WHERE"; - - $sql ="SELECT p.rowid, p.ref, ".$this->db->pdate("p.datec")." as datec,".$this->db->pdate("p.fin_validite")." as datefin"; - $sql.=" FROM ".MAIN_DB_PREFIX."propal as p"; - if (!$user->rights->societe->client->voir && !$user->societe_id) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc"; - $sql.= " WHERE sc.fk_user = " .$user->id; - $clause = "AND"; - } - if ($mode == 'opened') $sql.=" ".$clause." p.fk_statut = 1"; - if ($mode == 'signed') $sql.=" ".$clause." p.fk_statut = 2"; - if ($user->societe_id) $sql.=" AND p.fk_soc = ".$user->societe_id; - $resql=$this->db->query($sql); - if ($resql) - { - while ($obj=$this->db->fetch_object($resql)) - { - $this->nbtodo++; - if ($obj->datefin < (time() - $conf->propal->cloture->warning_delay)) - { - if ($mode == 'opened') $this->nbtodolate++; - if ($mode == 'signed') $this->nbtodolate++; - // \todo Definir r�gle des propales � facturer en retard - // if ($mode == 'signed' && ! sizeof($this->FactureListeArray($obj->rowid))) $this->nbtodolate++; - } - } - return 1; - } - else - { - $this->error=$this->db->error(); - return -1; - } - } + $this->nbtodo=$this->nbtodolate=0; + $clause = "WHERE"; + + $sql ="SELECT p.rowid, p.ref, ".$this->db->pdate("p.datec")." as datec,".$this->db->pdate("p.fin_validite")." as datefin"; + $sql.=" FROM ".MAIN_DB_PREFIX."propal as p"; + if (!$user->rights->societe->client->voir && !$user->societe_id) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc"; + $sql.= " WHERE sc.fk_user = " .$user->id; + $clause = "AND"; + } + if ($mode == 'opened') $sql.=" ".$clause." p.fk_statut = 1"; + if ($mode == 'signed') $sql.=" ".$clause." p.fk_statut = 2"; + if ($user->societe_id) $sql.=" AND p.fk_soc = ".$user->societe_id; + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $this->nbtodo++; + if ($obj->datefin < (time() - $conf->propal->cloture->warning_delay)) + { + if ($mode == 'opened') $this->nbtodolate++; + if ($mode == 'signed') $this->nbtodolate++; + // \todo Definir r�gle des propales � facturer en retard + // if ($mode == 'signed' && ! sizeof($this->FactureListeArray($obj->rowid))) $this->nbtodolate++; + } + } + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } /** @@ -1772,9 +1772,9 @@ class Propal extends CommonObject } /** - * \brief Charge indicateurs this->nb de tableau de bord - * \return int <0 si ko, >0 si ok - */ + * \brief Charge indicateurs this->nb de tableau de bord + * \return int <0 si ko, >0 si ok + */ function load_state_board() { global $conf, $user; @@ -1805,17 +1805,17 @@ class Propal extends CommonObject return -1; } } - - /** - * \brief V�rifie si la ref n'est pas d�j� utilis�e - * \param soc objet societe - */ - function verifyNumRef($soc) - { - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."propal"; - $sql.= " WHERE ref = '".$this->ref."'"; - $result = $this->db->query($sql); + /** + * \brief V�rifie si la ref n'est pas d�j� utilis�e + * \param soc objet societe + */ + function verifyNumRef($soc) + { + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."propal"; + $sql.= " WHERE ref = '".$this->ref."'"; + + $result = $this->db->query($sql); if ($result) { $num = $this->db->num_rows($result); @@ -1825,80 +1825,80 @@ class Propal extends CommonObject } } } - - - /** - * \brief Renvoie la r�f�rence de propale suivante non utilis�e en fonction du module - * de num�rotation actif d�fini dans PROPALE_ADDON - * \param soc objet societe - * \return string reference libre pour la propale - */ - function getNextNumRef($soc) - { - global $db, $langs; - $langs->load("propal"); + - $dir = DOL_DOCUMENT_ROOT . "/includes/modules/propale/"; + /** + * \brief Renvoie la r�f�rence de propale suivante non utilis�e en fonction du module + * de num�rotation actif d�fini dans PROPALE_ADDON + * \param soc objet societe + * \return string reference libre pour la propale + */ + function getNextNumRef($soc) + { + global $db, $langs; + $langs->load("propal"); - if (defined("PROPALE_ADDON") && PROPALE_ADDON) - { - $file = PROPALE_ADDON.".php"; + $dir = DOL_DOCUMENT_ROOT . "/includes/modules/propale/"; - // Chargement de la classe de num�rotation - $classname = PROPALE_ADDON; - require_once($dir.$file); + if (defined("PROPALE_ADDON") && PROPALE_ADDON) + { + $file = PROPALE_ADDON.".php"; - $obj = new $classname(); + // Chargement de la classe de num�rotation + $classname = PROPALE_ADDON; + require_once($dir.$file); - $numref = ""; - $numref = $obj->getNextValue($soc,$this); + $obj = new $classname(); - if ( $numref != "") - { - return $numref; - } - else - { - dolibarr_print_error($db,"Propale::getNextNumRef ".$obj->error); - return ""; - } - } - else - { - print $langs->trans("Error")." ".$langs->trans("Error_PROPALE_ADDON_NotDefined"); - return ""; - } - } - - /** + $numref = ""; + $numref = $obj->getNextValue($soc,$this); + + if ( $numref != "") + { + return $numref; + } + else + { + dolibarr_print_error($db,"Propale::getNextNumRef ".$obj->error); + return ""; + } + } + else + { + print $langs->trans("Error")." ".$langs->trans("Error_PROPALE_ADDON_NotDefined"); + return ""; + } + } + + /** \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 - \param get_params Parametres added to url + \param get_params Parametres added to url \return string Chaine avec URL - */ + */ function getNomUrl($withpicto=0,$option='', $get_params='') { global $langs; - + $result=''; if($option == '') - { - $lien = ''; - } - if($option == 'compta') - { - $lien = ''; - } - if($option == 'expedition') - { - $lien = ''; - } - $lienfin=''; - + { + $lien = ''; + } + if($option == 'compta') + { + $lien = ''; + } + if($option == 'expedition') + { + $lien = ''; + } + $lienfin=''; + $picto='order'; $label=$langs->trans("ShowPropal").': '.$this->ref; - + if ($withpicto) $result.=($lien.img_object($label,$picto).$lienfin); if ($withpicto && $withpicto != 2) $result.=' '; $result.=$lien.$this->ref.$lienfin; @@ -1909,9 +1909,9 @@ class Propal extends CommonObject /** - \class PropalLigne - \brief Classe permettant la gestion des lignes de propales -*/ + \class PropalLigne + \brief Classe permettant la gestion des lignes de propales + */ class PropaleLigne { var $db; @@ -1928,20 +1928,20 @@ class PropaleLigne var $subprice; var $remise_percent; var $fk_remise_except; - + var $rang = 0; var $marge_tx; var $marque_tx; - + var $special_code; // Liste d'options non cumulabels: - // 1: frais de port - // 2: ecotaxe - // 3: ?? - + // 1: frais de port + // 2: ecotaxe + // 3: ?? + var $info_bits = 0; // Liste d'options cumulables: - // Bit 0: 0 si TVA normal - 1 si TVA NPR - // Bit 1: 0 ligne normale - 1 si ligne de remise fixe - + // Bit 0: 0 si TVA normal - 1 si TVA NPR + // Bit 1: 0 ligne normale - 1 si ligne de remise fixe + var $total_ht; // Total HT de la ligne toute quantit� et incluant la remise ligne var $total_tva; // Total TVA de la ligne toute quantit� et incluant la remise ligne var $total_ttc; // Total TTC de la ligne toute quantit� et incluant la remise ligne @@ -2013,7 +2013,7 @@ class PropaleLigne dolibarr_print_error($this->db); } } - + /** * \brief Insert object line propal in database * \return int <0 si ko, >0 si ok @@ -2027,7 +2027,7 @@ class PropaleLigne if (! $this->remise) $this->remise=0; if (! $this->remise_percent) $this->remise_percent=0; if (! $this->info_bits) $this->info_bits=0; - + $rangtouse=$this->rang; if ($rangtouse == -1) { @@ -2046,7 +2046,7 @@ class PropaleLigne $this->db->rollback(); return -1; } - } + } // Insertion dans base de la ligne $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'propaldet'; @@ -2077,25 +2077,25 @@ class PropaleLigne $sql.= ' '.$rangtouse; $sql.= ')'; - dolibarr_syslog("PropaleLigne::insert sql=$sql"); + dolibarr_syslog("PropaleLigne::insert sql=$sql"); $resql=$this->db->query($sql); if ($resql) { $this->rang=$rangmax; $this->db->commit(); - return 1; + return 1; } else { - $this->error=$this->db->error()." sql=".$sql; - dolibarr_syslog("PropaleLigne::insert Error ".$this->error); + $this->error=$this->db->error()." sql=".$sql; + dolibarr_syslog("PropaleLigne::insert Error ".$this->error); $this->db->rollback(); - return -1; + return -1; } } - - + + /** * \brief Mise a jour de l'objet ligne de propale en base * \return int <0 si ko, >0 si ok @@ -2124,20 +2124,20 @@ class PropaleLigne $sql.= ",marque_tx='".$this->marque_tx."'"; $sql.= " WHERE rowid = ".$this->rowid; - dolibarr_syslog("PropaleLigne::update sql=$sql"); + dolibarr_syslog("PropaleLigne::update sql=$sql"); $resql=$this->db->query($sql); if ($resql) { $this->db->commit(); - return 1; + return 1; } else { - $this->error=$this->db->error(); - dolibarr_syslog("PropaleLigne::update Error ".$this->error); + $this->error=$this->db->error(); + dolibarr_syslog("PropaleLigne::update Error ".$this->error); $this->db->rollback(); - return -2; + return -2; } } @@ -2157,23 +2157,23 @@ class PropaleLigne $sql.= ",total_ttc=".price2num($this->total_ttc,'MT').""; $sql.= " WHERE rowid = ".$this->rowid; - dolibarr_syslog("PropaleLigne::update_total sql=$sql"); + dolibarr_syslog("PropaleLigne::update_total sql=$sql"); $resql=$this->db->query($sql); if ($resql) { $this->db->commit(); - return 1; + return 1; } else { - $this->error=$this->db->error(); - dolibarr_syslog("PropaleLigne::update_total Error ".$this->error); + $this->error=$this->db->error(); + dolibarr_syslog("PropaleLigne::update_total Error ".$this->error); $this->db->rollback(); - return -2; + return -2; } } - + } ?> diff --git a/htdocs/viewimage.php b/htdocs/viewimage.php index 463e315a894..5f60c3216f7 100644 --- a/htdocs/viewimage.php +++ b/htdocs/viewimage.php @@ -276,7 +276,13 @@ if ($modulepart) $accessallowed=1; $original_file=''; // No files are built on disk } - + + // images des stats du commercial + elseif ($modulepart == 'graph_comm') + { + $accessallowed=1; + $original_file= $conf->commercial->dir_temp . '/' .$original_file ; // No files are built on disk + } // Wrapping generique (allows any module to open a file if file is in directory // called DOL_DATA_ROOT/modulepart. else diff --git a/mysql/migration/2.4.0-2.5.0.sql b/mysql/migration/2.4.0-2.5.0.sql new file mode 100644 index 00000000000..0f6b70d0f23 --- /dev/null +++ b/mysql/migration/2.4.0-2.5.0.sql @@ -0,0 +1,16 @@ +-- +-- $Id$ +-- +-- Attention à l ordre des requetes. +-- Ce fichier doit être chargé sur une version 2.4.0 +-- + +alter table llx_product add column price_min double(24,8) DEFAULT 0; +alter table llx_product add column price_min_ttc double(24,8) DEFAULT 0; + +alter table llx_product_price add column price_min double(24,8) default NULL; +alter table llx_product_price add column price_min_ttc double(24,8) default NULL; + + + + diff --git a/mysql/tables/llx_product.sql b/mysql/tables/llx_product.sql index 503b23ee144..a74e95dcd2a 100644 --- a/mysql/tables/llx_product.sql +++ b/mysql/tables/llx_product.sql @@ -29,6 +29,8 @@ create table llx_product note text, price double(24,8) DEFAULT 0, price_ttc double(24,8) DEFAULT 0, + price_min double(24,8) DEFAULT 0, + price_min_ttc double(24,8) DEFAULT 0, price_base_type varchar(3) DEFAULT 'HT', tva_tx double(6,3), fk_user_author integer, @@ -49,3 +51,4 @@ create table llx_product volume_units tinyint DEFAULT NULL, canvas varchar(15) DEFAULT '' )type=innodb; + diff --git a/mysql/tables/llx_product_price.sql b/mysql/tables/llx_product_price.sql index 65a3146d689..1cf392edf7f 100644 --- a/mysql/tables/llx_product_price.sql +++ b/mysql/tables/llx_product_price.sql @@ -25,8 +25,10 @@ create table llx_product_price fk_product integer NOT NULL, date_price datetime NOT NULL, price_level tinyint(4) NULL DEFAULT 1, - price double(24,8), - price_ttc double(24,8) DEFAULT 0, + price double(24,8) DEFAULT NULL, + price_ttc double(24,8) DEFAULT NULL, + price_min double(24,8) default NULL, + price_min_ttc double(24,8) default NULL, price_base_type varchar(3) DEFAULT 'HT', tva_tx double(6,3) NOT NULL, fk_user_author integer,