Add patch from patrick raguin to support minimum for a price

This commit is contained in:
Laurent Destailleur 2008-08-27 23:00:37 +00:00
parent 4d0a68d48c
commit 8411203632
25 changed files with 2108 additions and 1406 deletions

View File

@ -262,7 +262,7 @@ print "</td>";
print '</tr>';
print '</form>';
// Utilisation de l'<EFBFBD>cotaxe
// Utilisation de l'ecotaxe
$var=!$var;
print "<form method=\"post\" action=\"produit.php\">";
print "<input type=\"hidden\" name=\"action\" value=\"useecotaxe\">";

View File

@ -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();

View File

@ -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 = '<div class="error">'.$langs->trans("CantBeLessThanMinPrice",price2num($prod->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'</div>' ;
}
else
{
$mesg='<div class="error">'.$propal->error.'</div>';
// 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='<div class="error">'.$propal->error.'</div>';
}
}
}
@ -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 = '<div class="error">'.$langs->trans("CantBeLessThanMinPrice",price2num($pruduct->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'</div>' ;
}
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 '<a name="'.$objp->rowid.'"></a>'; // ancre pour retourner sur la ligne
if ($objp->fk_product > 0)
{
print '<input type="hidden" name="productid" value="'.$objp->fk_product.'">';
print '<a href="'.DOL_URL_ROOT.'/product/fiche.php?id='.$objp->fk_product.'">';
if ($objp->fk_product_type==1) print img_object($langs->trans('ShowService'),'service');
else print img_object($langs->trans('ShowProduct'),'product');

214
htdocs/comm/stats.php Normal file
View File

@ -0,0 +1,214 @@
<?php
/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2008 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2008 Regis Houssin <regis@dolibarr.fr>
*
* 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 <br>' ;
}
} else {
$mesg = 'erreur sql : '.$db->error().'<br> requète : '.$db->lastquery().'<br>' ;
}
$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 '<div class="error">'.$mesg.'</div>' ;
dolibarr_fiche_head(array(array('stats.php',$langs->trans("Commercial"))), 0, $langs->trans("Stats"));
/*****************************
* Rappel Infos du Commercial
*****************************/
print '<table class="border" width="100%">
<tr>
<td width="15%">'.$langs->trans("Name").'</td><td colspan="3">'.$user->nom.'</td>
</tr>
<tr>
<td width="15%">'.$langs->trans("Surname").'</td><td colspan="3">'.$user->prenom.'</td>
</tr>
<tr>
<td width="15%">'.$langs->trans("Login").'</td><td colspan="3">'.$user->login.'</td>
</tr>
</table>' ;
print "</div>" ; // 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 '<table class="border" style="float:left;margin:5px;width:48%;min-width:470px;">
<tr class="liste_titre">
<td colspan="2">'.$graph['label'].'</td>
</tr>
<tr>
<td colspan="2" align="center" style="padding:5px;">
<img src="'.$url.'" alt="'.$langs->trans("NoData").'" style="float:left" width="'.$graphwidth.'">
<table class="border" style="float:right">
<tr class="liste_titre">
<td align="center">'.$langs->trans("Month").'</td><td align="center">'.$langs->trans("Currency".$conf->monnaie).'</td>
</tr>'.array2table($graph['data'],0,'','','align="center"').'
</table>
</td>
</tr>
<tr>
<td>'.$generateOn.'</td>
<td align="center"><a href="stats.php?action=recalcul">'.img_picto($langs->trans("ReCalculate"),'refresh').'</a></td>
</tr>
</table>' ;
}
/**************
* Fin de page
**************/
$db->close();
llxFooter();
?>

View File

@ -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 = '<div class="error">'.$langs->trans("CantBeLessThanMinPrice",price2num($prod->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'</div>' ;
}
else
{
$mesg='<div class="error">'.$commande->error.'</div>';
// 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='<div class="error">'.$commande->error.'</div>';
}
}
}
}
@ -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 = '<div class="error">'.$langs->trans("CantBeLessThanMinPrice",price2num($pruduct->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'</div>' ;
}
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 '<a name="'.$objp->rowid.'"></a>'; // ancre pour retourner sur la ligne
if ($objp->fk_product > 0)
{
print '<input type="hidden" name="productid" value="'.$objp->fk_product.'">';
print '<a href="'.DOL_URL_ROOT.'/product/fiche.php?id='.$objp->fk_product.'">';
if ($objp->fk_product_type==1) print img_object($langs->trans('ShowService'),'service');
else print img_object($langs->trans('ShowProduct'),'product');

View File

@ -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 = '<div class="error">'.$langs->trans("CantBeLessThanMinPrice",price2num($pruduct->price_min,'MU').' '.$langs->trans("Currency".$conf->monnaie)).'</div>' ;
}
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 '<a name="'.$objp->rowid.'"></a>'; // ancre pour retourner sur la ligne
if ($objp->fk_product > 0)
{
print '<input type="hidden" name="productid" value="'.$objp->fk_product.'">';
print '<a href="'.DOL_URL_ROOT.'/product/fiche.php?id='.$objp->fk_product.'">';
if ($objp->fk_product_type==1) print img_object($langs->trans('ShowService'),'service');
else print img_object($langs->trans('ShowProduct'),'product');

View File

@ -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 "<tr class=\"liste_titre\">";
print_liste_field_titre($langs->trans("User"),$_SERVER["PHP_SELF"],"name","",'&amp;year='.($year).'&modecompta='.$modecompta,"",$sortfield,$sortorder);
print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER["PHP_SELF"],"amount_ttc","",'&amp;year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder);
print_liste_field_titre($langs->trans("Percentage"),$_SERVER["PHP_SELF"],"amount_ttc","",'&amp;year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder);
print_liste_field_titre($langs->trans("OrderStats"),$_SERVER["PHP_SELF"],"","","",'align="center" width="20%"');
print "</tr>\n";
$var=true;
@ -189,6 +195,12 @@ if (sizeof($amount))
print "<td>".$linkname."</td>\n";
print '<td align="right">'.price($amount[$key]).'</td>';
print '<td align="right">'.($catotal > 0 ? round(100 * $amount[$key] / $catotal,2).'%' : '&nbsp;').'</td>';
if($key>0){
print '<td align="center"><a href="comm.php?id='.$key.'">'.img_picto($langs->trans("Show"),"vcard").'</a></td>';
} else {
print '<td> &nbsp; </td>' ;
}
print "</tr>\n";
$i++;
}

View File

@ -0,0 +1,222 @@
<?php
/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2008 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2008 Regis Houssin <regis@dolibarr.fr>
*
* 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.'<br>' ;
}
} else {
$mesg = 'erreur sql : '.$db->error().'<br> requète : '.$db->lastquery().'<br>' ;
}
$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 '<div class="error">'.$mesg.'</div>' ;
dolibarr_fiche_head(array(array('stats.php',$langs->trans("Commercial"))), 0, $langs->trans("Stats"));
/*****************************
* Rappel Infos du Commercial
*****************************/
print '<table class="border" width="100%">
<tr>
<td width="15%">'.$langs->trans("Name").'</td><td colspan="3">'.$userstats->nom.'</td>
</tr>
<tr>
<td width="15%">'.$langs->trans("Surname").'</td><td colspan="3">'.$userstats->prenom.'</td>
</tr>
<tr>
<td width="15%">'.$langs->trans("Login").'</td><td colspan="3">'.$userstats->login.'</td>
</tr>
</table>' ;
print "</div>" ; // 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 '<table class="border" style="float:left;margin:5px;width:48%;min-width:470px;">
<tr class="liste_titre">
<td>'.$graph['label'].'</td>
</tr>
<tr>
<td align="center" style="padding:5px;">
<img src="'.$url.'" alt="'.$langs->trans("NoData").'" style="float:left" width="'.$graphwidth.'">
<table class="border" style="float:right">
<tr class="liste_titre">
<td align="center">'.$langs->trans("Month").'</td><td align="center">'.$langs->trans("Currency".$conf->monnaie).'</td>
</tr>'.array2table($graph['data'],0,'','','align="center"').'
</table>
</td>
</tr>
<tr>
<td>'.$generateOn.'</td>
</tr>
</table>' ;
}
}
/**************
* Fin de page
**************/
$db->close();
llxFooter();
?>

View File

@ -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)

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -98,4 +98,5 @@ SeeVATReportInDueDebtMode=Voir le rapport <b>%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.<br>- 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.<br>- 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
PercentOfInvoice=%%/facture
OrderStats=Statistiques sur les commandes

View File

@ -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

View File

@ -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 = '<table '.$tableoptions.'>' ;
foreach($data as $key => $item){
if(is_array($item)){
$text.=array2tr($item,$troptions,$tdoptions) ;
} else {
$text.= '<tr '.$troptions.'>' ;
$text.= '<td '.$tdoptions.'>'.$key.'</td>' ;
$text.= '<td '.$tdoptions.'>'.$item.'</td>' ;
$text.= '</tr>' ;
}
}
if($tableMarkup) $text.= '</table>' ;
return $text ;
}
/**
* \brief Return lines of an html table from an array
*/
function array2tr($data,$troptions='',$tdoptions=''){
$text = '<tr '.$troptions.'>' ;
foreach($data as $key => $item){
$text.= '<td '.$tdoptions.'>'.$item.'</td>' ;
}
$text.= '</tr>' ;
return $text ;
}
?>

View File

@ -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<75>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"];

View File

@ -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 '</td></tr>';
}
// MIN PRICE
print '<tr><td>'.$langs->trans("MinPrice").'</td>';
print '<td><input name="price_min" size="10" value="'.$product->price_min.'">';
print '</td></tr>';
// VAT
print '<tr><td width="20%">'.$langs->trans("VATRate").'</td><td>';
print $html->select_tva("tva_tx",$conf->defaulttx,$mysoc,'');
@ -870,6 +877,18 @@ if ($_GET["id"] || $_GET["ref"])
}
print '</td></tr>';
}
// Prix mini
print '<tr><td>'.$langs->trans("MinPrice").'</td><td>';
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 '</td></tr>';
// TVA
print '<tr><td>'.$langs->trans("VATRate").'</td><td>'.vatrate($product->tva_tx,true).'</td></tr>';

View File

@ -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 '<tr><td>'.$langs->trans("MinPrice").'</td><td>';
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 '</td></tr>';
// TVA
print '<tr><td>'.$langs->trans("VATRate").'</td><td colspan="2">'.vatrate($product->tva_tx,true).'</td></tr>';
@ -237,9 +252,23 @@ if ($_GET["action"] == 'edit_price' && $user->rights->produit->creer)
{
print '<td><input name="price" size="10" value="'.price($product->price).'">';
}
print '<tr><td>' ;
$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 '<td><input name="price_min" size="10" value="'.price($product->price_min_ttc).'">';
}
else
{
print '<td><input name="price_min" size="10" value="'.price($product->price_min).'">';
}
print '</td>';
print $html->select_PriceBaseType($product->price_base_type, "price_base_type");
print '</td></tr>';
// VAT
print '<tr><td width="20%">'.$langs->trans("VATRate").'</td><td>';
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 '</td>';
print '<tr><td>' ;
$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 '<td><input name="price_min" size="10" value="'.price($product->price_min_ttc).'">';
}
else
{
print '<td><input name="price_min" size="10" value="'.price($product->price_min).'">';
}
print '</td>';
// VAT
print '<td width="20%">'.$langs->trans("VATRate").'</td><td>';
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 '</form>';
}
}
}
@ -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 '<td align="right">'.$langs->trans("VAT").'</td>';
print '<td align="right">'.$langs->trans("HT").'</td>';
print '<td align="right">'.$langs->trans("TTC").'</td>';
print '<td align="right">'.$langs->trans("MinPrice").' '.$langs->trans("HT").'</td>';
print '<td align="right">'.$langs->trans("MinPrice").' '.$langs->trans("TTC").'</td>';
print '<td align="right">'.$langs->trans("ChangedBy").'</td>';
print '</tr>';
@ -370,6 +414,8 @@ if ($result)
print '<td align="right">'.vatrate($objp->tva_tx,true)."</td>";
print '<td align="right">'.price($objp->price)."</td>";
print '<td align="right">'.price($objp->price_ttc)."</td>";
print '<td align="right">'.price($objp->price_min).'</td>';
print '<td align="right">'.price($objp->price_min_ttc).'</td>';
// User
print '<td align="right"><a href="'.DOL_URL_ROOT.'/user/fiche.php?id='.$objp->user_id.'">'.img_object($langs->trans("ShowUser"),'user').' '.$objp->login.'</a></td>';

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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,