Fix: Correction bug divers sur ajout ligne pour un produit avec prix fixé en TTC.

This commit is contained in:
Laurent Destailleur 2007-10-03 23:08:46 +00:00
parent 9acbd9d490
commit 4a9e8c7769
6 changed files with 450 additions and 405 deletions

View File

@ -1066,6 +1066,8 @@ if ($_GET['propalid'] > 0)
if ($_GET['action'] != 'editline' || $_GET['ligne'] != $objp->rowid) if ($_GET['action'] != 'editline' || $_GET['ligne'] != $objp->rowid)
{ {
print '<tr '.$bc[$var].'>'; print '<tr '.$bc[$var].'>';
// Produit
if ($objp->fk_product > 0) if ($objp->fk_product > 0)
{ {
print '<td>'; print '<td>';
@ -1129,65 +1131,72 @@ if ($_GET['propalid'] > 0)
} }
print "</td>\n"; print "</td>\n";
} }
if ($objp->fk_product_type==0 && $conf->global->PRODUIT_USE_MARKUP && $conf->use_ajax)
if ($conf->global->PRODUIT_USE_MARKUP)
{ {
// Champ ???
$formMarkup = '<form id="formMarkup" action="'.$_SERVER["PHP_SELF"].'?propalid='.$propal->id.'" method="post">'."\n"; if ($objp->fk_product_type==0 && $conf->use_ajax)
$formMarkup.= '<table class="border" width="100%">'."\n";
if ($objp->fk_product > 0)
{ {
$formMarkup = '<form id="formMarkup" action="'.$_SERVER["PHP_SELF"].'?propalid='.$propal->id.'" method="post">'."\n";
$formMarkup.= '<table class="border" width="100%">'."\n";
if ($objp->fk_product > 0)
{
$formMarkup.= '<tr><td align="left" colspan="2">&nbsp;</td></tr>'."\n";
$formMarkup.= '<tr><td align="left" width="25%" height="19">&nbsp;'.$langs->trans('SupplierPrice').'</td>'."\n";
$formMarkup.= '<td align="left">'.$html->select_product_fourn_price($objp->fk_product,'productfournpriceid').'</td></tr>'."\n";
}
$formMarkup.= '<tr><td align="left" colspan="2">&nbsp;</td></tr>'."\n"; $formMarkup.= '<tr><td align="left" colspan="2">&nbsp;</td></tr>'."\n";
$formMarkup.= '<tr><td align="left" width="25%" height="19">&nbsp;'.$langs->trans('SupplierPrice').'</td>'."\n"; $formMarkup.= '<tr><td align="left" width="25%" height="19">&nbsp;'.$langs->trans('PurchasePrice').' '.$langs->trans('HT').'</td>'."\n";
$formMarkup.= '<td align="left">'.$html->select_product_fourn_price($objp->fk_product,'productfournpriceid').'</td></tr>'."\n"; $formMarkup.= '<td align="left"><input size="10" type="text" class="flat" name="purchaseprice_ht" value=""></td></tr>'."\n";
} $formMarkup.= '<tr><td align="left" width="25%" height="19">&nbsp;'.$langs->trans('MarkupRate').'</td>'."\n";
$formMarkup.= '<tr><td align="left" colspan="2">&nbsp;</td></tr>'."\n"; $formMarkup.= '<td><input size="10" type="text" class="flat" id="markuprate'.$i.'" name="markuprate'.$i.'" value=""></td></tr>'."\n";
$formMarkup.= '<tr><td align="left" width="25%" height="19">&nbsp;'.$langs->trans('PurchasePrice').' '.$langs->trans('HT').'</td>'."\n"; $formMarkup.= '<tr><td align="left" width="25%" height="19">&nbsp;'.$langs->trans('SellingPrice').' '.$langs->trans('HT').'</td>'."\n";
$formMarkup.= '<td align="left"><input size="10" type="text" class="flat" name="purchaseprice_ht" value=""></td></tr>'."\n"; //$formMarkup.= '<td><div id="sellingprice_ht'.$i.'"><input size="10" type="text" class="flat" id="sellingdata_ht'.$i.'" name="sellingdata_ht'.$i.'" value=""></div></td></tr>'."\n";
$formMarkup.= '<tr><td align="left" width="25%" height="19">&nbsp;'.$langs->trans('MarkupRate').'</td>'."\n"; $formMarkup.= '<td nowrap="nowrap"><div id="sellingprice_ht'.$i.'"><div></td></tr>'."\n";
$formMarkup.= '<td><input size="10" type="text" class="flat" id="markuprate'.$i.'" name="markuprate'.$i.'" value=""></td></tr>'."\n"; $formMarkup.= '<tr><td align="left" width="25%" height="19">&nbsp;'.$langs->trans('CashFlow').' '.$langs->trans('HT').'</td>'."\n";
$formMarkup.= '<tr><td align="left" width="25%" height="19">&nbsp;'.$langs->trans('SellingPrice').' '.$langs->trans('HT').'</td>'."\n"; $formMarkup.= '<td nowrap="nowrap"><div id="cashflow'.$i.'"></div></td></tr>'."\n";
//$formMarkup.= '<td><div id="sellingprice_ht'.$i.'"><input size="10" type="text" class="flat" id="sellingdata_ht'.$i.'" name="sellingdata_ht'.$i.'" value=""></div></td></tr>'."\n"; $formMarkup.= '<tr><td align="center" colspan="2">'."\n";
$formMarkup.= '<td nowrap="nowrap"><div id="sellingprice_ht'.$i.'"><div></td></tr>'."\n"; $formMarkup.= '<input type="submit" class="button" name="validate" value="'.$langs->trans('Validate').'">'."\n";
$formMarkup.= '<tr><td align="left" width="25%" height="19">&nbsp;'.$langs->trans('CashFlow').' '.$langs->trans('HT').'</td>'."\n"; //$formMarkup.= ' &nbsp; <input onClick="Dialog.closeInfo()" type="button" class="button" name="cancel" value="'.$langs->trans('Cancel').'">'."\n";
$formMarkup.= '<td nowrap="nowrap"><div id="cashflow'.$i.'"></div></td></tr>'."\n"; $formMarkup.= '</td></tr></table></form>'."\n";
$formMarkup.= '<tr><td align="center" colspan="2">'."\n"; $formMarkup.= ajax_updaterWithID("rate".$i,"markup","sellingprice_ht".$i,"/product/ajaxproducts.php","&count=".$i,"working")."\n";
$formMarkup.= '<input type="submit" class="button" name="validate" value="'.$langs->trans('Validate').'">'."\n";
//$formMarkup.= ' &nbsp; <input onClick="Dialog.closeInfo()" type="button" class="button" name="cancel" value="'.$langs->trans('Cancel').'">'."\n";
$formMarkup.= '</td></tr></table></form>'."\n";
$formMarkup.= ajax_updaterWithID("rate".$i,"markup","sellingprice_ht".$i,"/product/ajaxproducts.php","&count=".$i,"working")."\n";
print '<td align="right">'."\n"; print '<td align="right">'."\n";
print '<div id="calc_markup'.$i.'" style="display:none">'."\n"; print '<div id="calc_markup'.$i.'" style="display:none">'."\n";
print $formMarkup."\n"; print $formMarkup."\n";
print '</div>'."\n"; print '</div>'."\n";
print '<table class="nobordernopadding" width="100%"><tr class="nocellnopadd">'; print '<table class="nobordernopadding" width="100%"><tr class="nocellnopadd">';
print '<td class="nobordernopadding" nowrap="nowrap" align="left">'; print '<td class="nobordernopadding" nowrap="nowrap" align="left">';
if (($objp->info_bits & 2) == 2) if (($objp->info_bits & 2) == 2)
{ {
// Ligne remise prédéfinie, on ne permet pas modif // Ligne remise prédéfinie, on ne permet pas modif
} }
else else
{ {
$picto = '<a href="#" onClick="dialogWindow($(\'calc_markup'.$i.'\').innerHTML,\''.$langs->trans('ToCalculateMarkup').'\')">'; $picto = '<a href="#" onClick="dialogWindow($(\'calc_markup'.$i.'\').innerHTML,\''.$langs->trans('ToCalculateMarkup').'\')">';
$picto.= img_calc(); $picto.= img_calc();
$picto.= '</a>'; $picto.= '</a>';
print $html->textwithtooltip($picto,$langs->trans("ToCalculateMarkup"),3,'','',$i); print $html->textwithtooltip($picto,$langs->trans("ToCalculateMarkup"),3,'','',$i);
} }
print '</td>'; print '</td>';
print '<td class="nobordernopadding" nowrap="nowrap" align="right">'.vatrate($objp->marge_tx).'% </td>'; print '<td class="nobordernopadding" nowrap="nowrap" align="right">'.vatrate($objp->marge_tx).'% </td>';
print '</tr></table>'; print '</tr></table>';
print '</td>'; print '</td>';
} }
else else
{ {
print '<td>&nbsp;</td>'; print '<td>&nbsp;</td>';
} }
}
// VAT Rate
print '<td align="right">'.vatrate($objp->tva_tx).'%</td>'; print '<td align="right">'.vatrate($objp->tva_tx).'%</td>';
// U.P HT
print '<td align="right">'.price($objp->subprice)."</td>\n"; print '<td align="right">'.price($objp->subprice)."</td>\n";
// Qty // Qty
@ -1198,6 +1207,8 @@ if ($_GET['propalid'] > 0)
} }
else print '&nbsp;'; else print '&nbsp;';
print '</td>'; print '</td>';
// Remise %
if ($objp->remise_percent > 0) if ($objp->remise_percent > 0)
{ {
print '<td align="right">'.$objp->remise_percent."%</td>\n"; print '<td align="right">'.$objp->remise_percent."%</td>\n";

View File

@ -605,102 +605,111 @@ class Commande extends CommonObject
/** /**
* \brief Ajout d'un produit dans la commande, en base * \brief Ajoute une ligne de produit (associé à un produit/service prédéfini ou non)
* \param commandeid id de la commande * \param commandeid Id de la commande
* \param desc description de la ligne * \param desc Description de la ligne
* \param pu prix unitaire * \param pu_ht Prix unitaire HT
* \param qty quantité * \param qty Quantité
* \param txtva taux de tva forcé, sinon -1 * \param txtva Taux de tva forcé, sinon -1
* \param fk_product id du produit/service predéfini * \param fk_product Id du produit/service predéfini
* \param remise_percent pourcentage de remise de la ligne * \param remise_percent Pourcentage de remise de la ligne
* \return int >0 si ok, <0 si ko * \param info_bits Bits de type de lignes
* \param fk_remise_exscept Id remise
* \param price_base_type HT or TTC
* \param pu_ttc Prix unitaire TTC
* \return int >0 si ok, <0 si ko
* \see add_product * \see add_product
* \remarks Les parametres sont deja censé etre juste et avec valeurs finales a l'appel * \remarks Les parametres sont deja censé etre juste et avec valeurs finales a l'appel
* de cette methode. Aussi, pour le taux tva, il doit deja avoir ete défini * 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) * 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) * et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue)
*/ */
function addline($commandeid, $desc, $pu, $qty, $txtva, $fk_product=0, $remise_percent=0, $fk_remise_except=0, $info_bits=0, $price_base_type='HT') function addline($commandeid, $desc, $pu_ht, $qty, $txtva, $fk_product=0, $remise_percent=0, $info_bits=0, $fk_remise_except=0, $price_base_type='HT', $pu_ttc=0)
{ {
dolibarr_syslog("Commande.class.php::addline this->id=$this->id, $commandeid, $desc, $pu, $qty, $txtva, $fk_product, $remise_percent"); dolibarr_syslog("Commande::addline $commandeid, $desc, $pu, $qty, $txtva, $fk_product, $remise_percent, $info_bits, $fk_remise_except, $price_base_type, $pu_ttc");
include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php'); include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php');
if ($this->statut == 0) if ($this->statut == 0)
{ {
$this->db->begin(); $this->db->begin();
// Nettoyage paramètres // Nettoyage paramètres
$remise_percent=price2num($remise_percent); $remise_percent=price2num($remise_percent);
$qty=price2num($qty); $qty=price2num($qty);
if (! $qty) $qty=1; if (! $qty) $qty=1;
$pu = price2num($pu); if (! $info_bits) $info_bits=0;
$txtva = price2num($txtva); $pu_ht=price2num($pu_ht);
$pu_ttc=price2num($pu_ttc);
$txtva = price2num($txtva);
// Calcul du total TTC et de la TVA pour la ligne a partir de if ($price_base_type=='HT') $pu=$pu;
// qty, pu, remise_percent et txtva else $pu=$pu_ttc;
// 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);
$total_ht = $tabprice[0];
$total_tva = $tabprice[1];
$total_ttc = $tabprice[2];
// Anciens indicateurs: $price, $remise (a ne plus utiliser) // Calcul du total TTC et de la TVA pour la ligne a partir de
$price = $pu; // qty, pu, remise_percent et txtva
if ($remise_percent > 0) // 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.
$remise = round(($pu * $remise_percent / 100), 2); $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, 0, $price_base_type);
$price = $pu - $remise; $total_ht = $tabprice[0];
} $total_tva = $tabprice[1];
$total_ttc = $tabprice[2];
// Insertion ligne // Anciens indicateurs: $price, $remise (a ne plus utiliser)
$ligne=new CommandeLigne($this->db); $price = $pu;
$remise = 0;
if ($remise_percent > 0)
{
$remise = round(($pu * $remise_percent / 100), 2);
$price = $pu - $remise;
}
$ligne->fk_commande=$commandeid; // Insertion ligne
$ligne->desc=$desc; $ligne=new CommandeLigne($this->db);
$ligne->qty=$qty;
$ligne->tva_tx=$txtva;
$ligne->fk_product=$fk_product;
$ligne->fk_remise_except=$fk_remise_except;
$ligne->remise_percent=$remise_percent;
$ligne->subprice=$pu;
$ligne->rang=-1;
$ligne->info_bits=$info_bits;
$ligne->total_ht=$total_ht;
$ligne->total_tva=$total_tva;
$ligne->total_ttc=$total_ttc;
// Ne plus utiliser $ligne->fk_commande=$commandeid;
$ligne->price=$price; $ligne->desc=$desc;
$ligne->remise=$remise; $ligne->qty=$qty;
$ligne->tva_tx=$txtva;
$ligne->fk_product=$fk_product;
$ligne->fk_remise_except=$fk_remise_except;
$ligne->remise_percent=$remise_percent;
$ligne->subprice=$pu_ht;
$ligne->rang=-1;
$ligne->info_bits=$info_bits;
$ligne->total_ht=$total_ht;
$ligne->total_tva=$total_tva;
$ligne->total_ttc=$total_ttc;
$result=$ligne->insert(); // Ne plus utiliser
if ($result > 0) $ligne->price=$price;
{ $ligne->remise=$remise;
// Mise a jour informations denormalisees au niveau de la commande meme
$result=$this->update_price($this->id);
if ($result > 0) $result=$ligne->insert();
{ if ($result > 0)
$this->db->commit(); {
return 1; // Mise a jour informations denormalisees au niveau de la commande meme
} $result=$this->update_price($this->id);
else if ($result > 0)
{ {
$this->error=$this->db->error(); $this->db->commit();
dolibarr_syslog("Error sql=$sql, error=".$this->error); return 1;
$this->db->rollback(); }
return -1; else
} {
} $this->error=$this->db->error();
else dolibarr_syslog("Error sql=$sql, error=".$this->error);
{ $this->db->rollback();
$this->error=$ligne->error; return -1;
$this->db->rollback(); }
return -2; }
} else
} {
} $this->error=$ligne->error;
$this->db->rollback();
return -2;
}
}
}
/** /**
@ -1438,75 +1447,72 @@ class Commande extends CommonObject
* \brief Mets à jour le prix total de la commnde * \brief Mets à jour le prix total de la commnde
* \return int <0 si ko, >0 si ok * \return int <0 si ko, >0 si ok
*/ */
function update_price() function update_price()
{ {
include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php'); include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php');
// Liste des lignes factures a sommer $tvas=array();
$sql = "SELECT price, qty, tva_tx, total_ht, total_tva, total_ttc"; $err=0;
$sql.= " FROM ".MAIN_DB_PREFIX."commandedet";
$sql.= " WHERE fk_commande = ".$this->id;
dolibarr_syslog("Commande.class.php::update_price this->id=".$this->id); // Liste des lignes factures a sommer
$sql = "SELECT price, qty, tva_tx, total_ht, total_tva, total_ttc";
$sql.= " FROM ".MAIN_DB_PREFIX."commandedet";
$sql.= " WHERE fk_commande = ".$this->id;
$result = $this->db->query($sql); dolibarr_syslog("Commande::update_price sql=".$sql);
if ($result) $result = $this->db->query($sql);
{ if ($result)
$this->total_ht = 0; {
$this->total_tva = 0; $this->total_ht = 0;
$this->total_ttc = 0; $this->total_tva = 0;
$this->total_ttc = 0;
$num = $this->db->num_rows($result);
$i = 0;
while ($i < $num)
{
$obj = $this->db->fetch_object($result);
$num = $this->db->num_rows($result); $this->total_ht += $obj->total_ht;
$i = 0; $this->total_tva += ($obj->total_ttc - $obj->total_ht);
while ($i < $num) $this->total_ttc += $obj->total_ttc;
{
$obj = $this->db->fetch_object($result);
$this->total_ht += $obj->total_ht; // Anciens indicateurs
$this->total_tva += ($obj->total_ttc - $obj->total_ht); $this->amount_ht += ($obj->price * $obj->qty);
$this->total_ttc += $obj->total_ttc; $this->total_remise += 0; // Plus de remise globale (toute remise est sur une ligne)
$tvas[$obj->tva_taux] += ($obj->total_ttc - $obj->total_ht);
$i++;
}
// Anciens indicateurs $this->db->free($result);
$this->amount_ht += $obj->price * $obj->qty;
$this->total_remise += 0; // Plus de remise globale (toute remise est sur une ligne)
/* \deprecated car simplifie par les 3 indicateurs total_ht, total_tva et total_ttc sur lignes
$products[$i][0] = $obj->price;
$products[$i][1] = $obj->qty;
$products[$i][2] = $obj->tva_tx;
*/
$i++;
}
$this->db->free($result); // Met a jour indicateurs
} $sql = "UPDATE ".MAIN_DB_PREFIX."commande SET";
/* \deprecated car simplifie par les 3 indicateurs total_ht, total_tva et total_ttc sur lignes $sql .= " amount_ht='".price2num($this->amount_ht)."'";
$calculs = calcul_price($products, $this->remise_percent, $this->remise_absolue); $sql .= ", total_ht='". price2num($this->total_ht)."'";
$this->total_remise = $calculs[3]; $sql .= ", tva='". price2num($this->total_tva)."'";
$this->amount_ht = $calculs[4]; $sql .= ", total_ttc='".price2num($this->total_ttc)."'";
$this->total_ht = $calculs[0]; $sql .= ", remise='".price2num($this->total_remise)."'";
$this->total_tva = $calculs[1]; $sql .=" WHERE rowid = ".$this->id;
$this->total_ttc = $calculs[2]; $resql=$this->db->query($sql);
$tvas = $calculs[5];
*/ if ($resql)
// Met a jour en base {
$sql = "UPDATE ".MAIN_DB_PREFIX."commande SET"; return 1;
$sql .= " amount_ht='".price2num($this->total_ht)."'"; }
$sql .= ", total_ht='". price2num($this->total_ht)."'"; else
$sql .= ", tva='". price2num($this->total_tva)."'"; {
$sql .= ", total_ttc='".price2num($this->total_ttc)."'"; $this->error=$this->db->error();
$sql .= ", remise='".price2num($this->total_remise)."'"; dolibarr_syslog("Commande::update_price error=".$this->error,LOG_ERR);
$sql .=" WHERE rowid = ".$this->id; return -1;
if ( $this->db->query($sql) ) }
{ }
return 1; else
} {
else $this->error=$this->db->error();
{ dolibarr_syslog("Commande::update_price error=".$this->error,LOG_ERR);
$this->error=$this->db->error(); return -1;
dolibarr_syslog("Commande::update_price error=".$this->error); }
return -1; }
}
}
/** /**
* \brief Mets à jour les commentaires privés * \brief Mets à jour les commentaires privés
@ -2322,15 +2328,15 @@ class CommandeLigne
var $desc; // Description ligne var $desc; // Description ligne
var $fk_product; // Id produit prédéfini var $fk_product; // Id produit prédéfini
var $qty; var $qty; // Quantité (exemple 2)
var $tva_tx; var $tva_tx; // Taux tva produit/service (exemple 19.6)
var $subprice; var $subprice; // P.U. HT (exemple 100)
var $remise_percent; var $remise_percent; // % de la remise ligne (exemple 20%)
var $rang = 0; var $rang = 0;
var $marge_tx; var $marge_tx;
var $marque_tx; var $marque_tx;
var $info_bits = 0; // Bit 0: 0 si TVA normal - 1 si TVA NPR var $info_bits = 0; // Bit 0: 0 si TVA normal - 1 si TVA NPR
// Bit 1: 0 ligne normale - 1 si ligne de remise fixe // 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_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_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 var $total_ttc; // Total TTC de la ligne toute quantité et incluant la remise ligne
@ -2441,7 +2447,7 @@ class CommandeLigne
{ {
global $langs, $conf, $user; global $langs, $conf, $user;
dolibarr_syslog("CommandeLigne.class::insert rang=".$this->rang); dolibarr_syslog("CommandeLigne::insert rang=".$this->rang);
$this->db->begin(); $this->db->begin();
$rangtouse=$this->rang; $rangtouse=$this->rang;
@ -2466,19 +2472,19 @@ class CommandeLigne
// Insertion dans base de la ligne // Insertion dans base de la ligne
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'commandedet'; $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'commandedet';
$sql.= ' (fk_commande, description, price, qty, tva_tx,'; $sql.= ' (fk_commande, description, qty, tva_tx,';
$sql.= ' fk_product, remise_percent, subprice, remise, fk_remise_except, '; $sql.= ' fk_product, remise_percent, subprice, price, remise, fk_remise_except,';
$sql.= ' rang, marge_tx, marque_tx,'; $sql.= ' rang, marge_tx, marque_tx,';
$sql.= ' info_bits, total_ht, total_tva, total_ttc)'; $sql.= ' info_bits, total_ht, total_tva, total_ttc)';
$sql.= " VALUES (".$this->fk_commande.","; $sql.= " VALUES (".$this->fk_commande.",";
$sql.= " '".addslashes($this->desc)."',"; $sql.= " '".addslashes($this->desc)."',";
$sql.= " '".price2num($this->price)."',";
$sql.= " '".price2num($this->qty)."',"; $sql.= " '".price2num($this->qty)."',";
$sql.= " '".price2num($this->tva_tx)."',"; $sql.= " '".price2num($this->tva_tx)."',";
if ($this->fk_product) { $sql.= "'".$this->fk_product."',"; } if ($this->fk_product) { $sql.= "'".$this->fk_product."',"; }
else { $sql.='null,'; } else { $sql.='null,'; }
$sql.= " '".price2num($this->remise_percent)."',"; $sql.= " '".price2num($this->remise_percent)."',";
$sql.= " '".price2num($this->subprice)."',"; $sql.= " '".price2num($this->subprice)."',";
$sql.= " '".price2num($this->price)."',";
$sql.= " '".price2num($this->remise)."',"; $sql.= " '".price2num($this->remise)."',";
if ($this->fk_remise_except) $sql.= $this->fk_remise_except.","; if ($this->fk_remise_except) $sql.= $this->fk_remise_except.",";
else $sql.= 'null,'; else $sql.= 'null,';
@ -2493,8 +2499,6 @@ class CommandeLigne
$sql.= " '".price2num($this->total_ttc)."'"; $sql.= " '".price2num($this->total_ttc)."'";
$sql.= ')'; $sql.= ')';
dolibarr_syslog("CommandeLigne.class.php::insert sql=$sql");
if ($this->fk_product) if ($this->fk_product)
{ {
$product = new Product($this->db); $product = new Product($this->db);
@ -2502,9 +2506,12 @@ class CommandeLigne
$product->ajust_stock_commande($this->qty, 0); $product->ajust_stock_commande($this->qty, 0);
} }
dolibarr_syslog("CommandeLigne::insert sql=$sql");
$resql=$this->db->query($sql); $resql=$this->db->query($sql);
if ($resql) if ($resql)
{ {
$this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'commandedet');
if (! $notrigger) if (! $notrigger)
{ {
// Appel des triggers // Appel des triggers
@ -2515,7 +2522,7 @@ class CommandeLigne
} }
$this->db->commit(); $this->db->commit();
return 1; return $this->rowid;
} }
else else
{ {

View File

@ -256,76 +256,86 @@ if ($_REQUEST['action'] == 'setremiseabsolue' && $user->rights->facture->creer)
*/ */
if ($_POST['action'] == 'addligne' && $user->rights->commande->creer) if ($_POST['action'] == 'addligne' && $user->rights->commande->creer)
{ {
if ($_POST['qty'] && (($_POST['pu'] && $_POST['np_desc']) || $_POST['idprod'])) if ($_POST['qty'] && (($_POST['pu'] != '' && $_POST['np_desc']) || $_POST['idprod']))
{
$commande = new Commande($db);
$ret=$commande->fetch($_POST['id']);
$soc = new Societe($db, $commande->socid);
$soc->fetch($commande->socid);
if ($ret < 0)
{
dolibarr_print_error($db,$commande->error);
exit;
}
// Ecrase $pu par celui du produit
// Ecrase $desc par celui du produit
// Ecrase $txtva par celui du produit
if ($_POST['idprod'])
{
$prod = new Product($db, $_POST['idprod']);
$prod->fetch($_POST['idprod']);
$libelle = $prod->libelle;
// multiprix
if ($conf->global->PRODUIT_MULTIPRICES == 1)
{
$pu = $prod->multiprices[$soc->price_level];
}
else
{
$pu=$prod->price;
}
// La description de la ligne est celle saisie ou
// celle du produit si PRODUIT_CHANGE_PROD_DESC est défini
if ($conf->global->PRODUIT_CHANGE_PROD_DESC)
{
$desc = $prod->description;
}
else
{
$desc=$_POST['np_desc'];
}
$tva_tx = get_default_tva($mysoc,$soc,$prod->tva_tx);
}
else
{
$pu=$_POST['pu'];
$tva_tx=$_POST['tva_tx'];
$desc=$_POST['np_desc'];
}
$commande->addline(
$_POST['id'],
$desc,
$pu,
$_POST['qty'],
$tva_tx,
$_POST['idprod'],
$_POST['remise_percent']
);
if ($_REQUEST['lang_id'])
{ {
$outputlangs = new Translate(DOL_DOCUMENT_ROOT ."/langs",$conf); $commande = new Commande($db);
$outputlangs->setDefaultLang($_REQUEST['lang_id']); $ret=$commande->fetch($_POST['id']);
$ret=$commande->fetch_client();
if ($ret < 0)
{
dolibarr_print_error($db,$commande->error);
exit;
}
$price_base_type = 'HT';
// Ecrase $pu par celui du produit
// Ecrase $desc par celui du produit
// Ecrase $txtva par celui du produit
// Ecrase $base_price_type par celui du produit
if ($_POST['idprod'])
{
$prod = new Product($db, $_POST['idprod']);
$prod->fetch($_POST['idprod']);
$price_base_type = $prod->price_base_type;
$libelle = $prod->libelle;
// multiprix
if ($conf->global->PRODUIT_MULTIPRICES == 1)
{
$pu = $prod->multiprices[$commande->client->price_level];
$pu_ttc = $prod->multiprices_ttc[$commande->client->price_level];
$price_base_type = $prod->multiprices_base_type[$commande->client->price_level];
}
else
{
$pu = $prod->price;
$pu_ttc = $prod->price_ttc;
}
// La description de la ligne est celle saisie ou
// celle du produit si PRODUIT_CHANGE_PROD_DESC est défini
if ($conf->global->PRODUIT_CHANGE_PROD_DESC)
{
$desc = $prod->description;
}
else
{
$desc=$_POST['np_desc'];
}
$tva_tx = get_default_tva($mysoc,$commande->client,$prod->tva_tx);
}
else
{
$pu=$_POST['pu'];
$tva_tx=$_POST['tva_tx'];
$desc=$_POST['np_desc'];
}
$commande->addline(
$_POST['id'],
$desc,
$pu,
$_POST['qty'],
$tva_tx,
$_POST['idprod'],
$_POST['remise_percent'],
'',
'',
$price_base_type,
$pu_ttc
);
if ($_REQUEST['lang_id'])
{
$outputlangs = new Translate(DOL_DOCUMENT_ROOT ."/langs",$conf);
$outputlangs->setDefaultLang($_REQUEST['lang_id']);
}
commande_pdf_create($db, $commande->id, $commande->modelpdf, $outputlangs);
} }
commande_pdf_create($db, $commande->id, $commande->modelpdf, $outputlangs);
}
} }
/* /*
@ -1268,6 +1278,7 @@ else
*/ */
$sql = 'SELECT l.fk_product, l.description, l.price, l.qty, l.rowid, l.tva_tx, '; $sql = 'SELECT l.fk_product, l.description, l.price, l.qty, l.rowid, l.tva_tx, ';
$sql.= ' l.fk_remise_except, l.remise_percent, l.subprice, l.info_bits,'; $sql.= ' l.fk_remise_except, l.remise_percent, l.subprice, l.info_bits,';
$sql.= ' l.total_ht, l.total_tva, l.total_ttc,';
$sql.= ' p.label as product, p.ref, p.fk_product_type, p.rowid as prodid, '; $sql.= ' p.label as product, p.ref, p.fk_product_type, p.rowid as prodid, ';
$sql.= ' p.description as product_desc'; $sql.= ' p.description as product_desc';
$sql.= ' FROM '.MAIN_DB_PREFIX.'commandedet as l'; $sql.= ' FROM '.MAIN_DB_PREFIX.'commandedet as l';
@ -1386,7 +1397,7 @@ else
{ {
print '<td>&nbsp;</td>'; print '<td>&nbsp;</td>';
} }
print '<td align="right">'.price($objp->subprice*$objp->qty*(100-$objp->remise_percent)/100).'</td>'; print '<td align="right">'.price($objp->total_ht).'</td>';
// Icone d'edition et suppression // Icone d'edition et suppression
if ($commande->statut == 0 && $user->rights->commande->creer) if ($commande->statut == 0 && $user->rights->commande->creer)

View File

@ -757,7 +757,7 @@ if (($_POST['action'] == 'addligne' || $_POST['action'] == 'addligne_predef') &&
$prod = new Product($db, $_POST['idprod']); $prod = new Product($db, $_POST['idprod']);
$prod->fetch($_POST['idprod']); $prod->fetch($_POST['idprod']);
$price_base_type = $prod->price_base_type; $price_base_type = $prod->price_base_type;
// multiprix // multiprix
if ($conf->global->PRODUIT_MULTIPRICES == 1) if ($conf->global->PRODUIT_MULTIPRICES == 1)
@ -792,8 +792,8 @@ if (($_POST['action'] == 'addligne' || $_POST['action'] == 'addligne_predef') &&
$desc=$_POST['np_desc']; $desc=$_POST['np_desc'];
} }
// Insere ligne // Insere ligne
$result = $fac->addline( $result = $fac->addline(
$_POST['facid'], $_POST['facid'],
$desc, $desc,
$pu, $pu,
@ -806,7 +806,8 @@ if (($_POST['action'] == 'addligne' || $_POST['action'] == 'addligne_predef') &&
0, 0,
'', '',
'', '',
$price_base_type, $pu_ttc $price_base_type,
$pu_ttc
); );
} }

View File

@ -1298,25 +1298,29 @@ class Facture extends CommonObject
/** /**
* \brief Ajoute une ligne de facture (associé à un produit/service prédéfini ou non) * \brief Ajoute une ligne de facture (associé à un produit/service prédéfini ou non)
* \param facid Id de la facture * \param facid Id de la facture
* \param desc Description de la ligne * \param desc Description de la ligne
* \param pu Prix unitaire * \param pu_ht Prix unitaire HT
* \param qty Quantité * \param qty Quantité
* \param txtva Taux de tva forcé, sinon -1 * \param txtva Taux de tva forcé, sinon -1
* \param fk_product Id du produit/service predéfini * \param fk_product Id du produit/service predéfini
* \param remise_percent Pourcentage de remise de la ligne * \param remise_percent Pourcentage de remise de la ligne
* \param date_start Date de debut de validité du service * \param date_start Date de debut de validité du service
* \param date_end Date de fin de validité du service * \param date_end Date de fin de validité du service
* \param ventil Code de ventilation comptable * \param ventil Code de ventilation comptable
* \param info_bits Bits de type de lignes * \param info_bits Bits de type de lignes
* \param fk_remise_exscept Id remise
* \param price_base_type HT or TTC
* \param pu_ttc Prix unitaire TTC
* \return int >0 si ok, <0 si ko
* \remarks Les parametres sont deja censé etre juste et avec valeurs finales a l'appel * \remarks Les parametres sont deja censé etre juste et avec valeurs finales a l'appel
* de cette methode. Aussi, pour le taux tva, il doit deja avoir ete défini * 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) * 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) * et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue)
*/ */
function addline($facid, $desc, $pu, $qty, $txtva, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits='', $fk_remise_except='', $price_base_type='HT', $pu_ttc=0) function addline($facid, $desc, $pu_ht, $qty, $txtva, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits='', $fk_remise_except='', $price_base_type='HT', $pu_ttc=0)
{ {
dolibarr_syslog("Facture::Addline $facid,$desc,$pu,$qty,$txtva,$fk_product,$remise_percent,$date_start,$date_end,$ventil,$info_bits,$fk_remise_except", LOG_DEBUG); dolibarr_syslog("Facture::Addline $facid,$desc,$pu_ht,$qty,$txtva,$fk_product,$remise_percent,$date_start,$date_end,$ventil,$info_bits,$fk_remise_except,$price_base_type,$pu_ttc", LOG_DEBUG);
include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php'); include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php');
if ($this->brouillon) if ($this->brouillon)
@ -1329,9 +1333,11 @@ class Facture extends CommonObject
if (! $qty) $qty=1; if (! $qty) $qty=1;
if (! $ventil) $ventil=0; if (! $ventil) $ventil=0;
if (! $info_bits) $info_bits=0; if (! $info_bits) $info_bits=0;
$pu = price2num($pu); $pu_ht=price2num($pu_ht);
$pu_ttc=price2num($pu_ttc);
$txtva=price2num($txtva); $txtva=price2num($txtva);
if ($price_base_type=='HT') $pu=$pu;
if ($price_base_type=='HT') $pu=$pu_ht;
else $pu=$pu_ttc; else $pu=$pu_ttc;
// Calcul du total TTC et de la TVA pour la ligne a partir de // Calcul du total TTC et de la TVA pour la ligne a partir de
@ -1361,7 +1367,7 @@ class Facture extends CommonObject
$ligne->tva_tx=$txtva; $ligne->tva_tx=$txtva;
$ligne->fk_product=$fk_product; $ligne->fk_product=$fk_product;
$ligne->remise_percent=$remise_percent; $ligne->remise_percent=$remise_percent;
$ligne->subprice=$pu; $ligne->subprice=$pu_ht;
$ligne->date_start=$date_start; $ligne->date_start=$date_start;
$ligne->date_end=$date_end; $ligne->date_end=$date_end;
$ligne->ventil=$ventil; $ligne->ventil=$ventil;
@ -1552,94 +1558,99 @@ class Facture extends CommonObject
\return int <0 si ko, >0 si ok \return int <0 si ko, >0 si ok
*/ */
function update_price($facid) function update_price($facid)
{ {
$tvas=array(); $tvas=array();
$err=0; $err=0;
// Liste des lignes factures a sommer (Ne plus utiliser price) // Liste des lignes factures a sommer (Ne plus utiliser price)
$sql = 'SELECT qty, tva_taux, subprice, remise_percent, price,'; $sql = 'SELECT qty, tva_taux, subprice, remise_percent, price,';
$sql.= ' total_ht, total_tva, total_ttc'; $sql.= ' total_ht, total_tva, total_ttc';
$sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet'; $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet';
$sql.= ' WHERE fk_facture = '.$facid; $sql.= ' WHERE fk_facture = '.$facid;
$resql = $this->db->query($sql); dolibarr_syslog("Facture::update_price sql=".$sql);
if ($resql) $resql = $this->db->query($sql);
{ if ($resql)
$this->total_ht = 0; {
$this->total_tva = 0; $this->total_ht = 0;
$this->total_ttc = 0; $this->total_tva = 0;
$num = $this->db->num_rows($resql); $this->total_ttc = 0;
$i = 0; $num = $this->db->num_rows($resql);
while ($i < $num) $i = 0;
{ while ($i < $num)
$obj = $this->db->fetch_object($resql); {
$obj = $this->db->fetch_object($resql);
$this->total_ht += $obj->total_ht; $this->total_ht += $obj->total_ht;
$this->total_tva += ($obj->total_ttc - $obj->total_ht); $this->total_tva += ($obj->total_ttc - $obj->total_ht);
$this->total_ttc += $obj->total_ttc; $this->total_ttc += $obj->total_ttc;
// Ne plus utiliser amount, ni remise // Ne plus utiliser amount, ni remise
$this->amount_ht += ($obj->price * $obj->qty); $this->amount_ht += ($obj->price * $obj->qty);
$this->total_remise += 0; // Plus de remise globale (toute remise est sur une ligne) $this->total_remise += 0; // Plus de remise globale (toute remise est sur une ligne)
$tvas[$obj->tva_taux] += ($obj->total_ttc - $obj->total_ht); $tvas[$obj->tva_taux] += ($obj->total_ttc - $obj->total_ht);
$i++; $i++;
} }
$this->db->free($resql); $this->db->free($resql);
// Met a jour indicateurs sur facture // Met a jour indicateurs
$sql = 'UPDATE '.MAIN_DB_PREFIX.'facture '; $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture ';
$sql .= "SET amount ='".price2num($this->amount_ht)."'"; $sql .= "SET amount ='".price2num($this->amount_ht)."'";
$sql .= ", remise='". price2num($this->total_remise)."'"; $sql .= ", remise='". price2num($this->total_remise)."'";
$sql .= ", total='". price2num($this->total_ht)."'"; $sql .= ", total='". price2num($this->total_ht)."'";
$sql .= ", tva='". price2num($this->total_tva)."'"; $sql .= ", tva='". price2num($this->total_tva)."'";
$sql .= ", total_ttc='".price2num($this->total_ttc)."'"; $sql .= ", total_ttc='".price2num($this->total_ttc)."'";
$sql .= ' WHERE rowid = '.$facid; $sql .= ' WHERE rowid = '.$facid;
$resql=$this->db->query($sql); $resql=$this->db->query($sql);
if ($resql) if ($resql)
{ {
// \TODO A supprimer car l'utilisation de facture_tva_sum non utilisable // \TODO A supprimer car l'utilisation de facture_tva_sum non utilisable
// dans un context compta propre. On utilisera plutot les lignes. // dans un context compta propre. On utilisera plutot les lignes.
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_tva_sum WHERE fk_facture='.$this->id; $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_tva_sum WHERE fk_facture='.$this->id;
if ( $this->db->query($sql) ) if ( $this->db->query($sql) )
{ {
foreach ($tvas as $key => $value) foreach ($tvas as $key => $value)
{ {
$sql_del = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_tva_sum where fk_facture ='.$this->id; $sql_del = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_tva_sum where fk_facture ='.$this->id;
$this->db->query($sql_del); $this->db->query($sql_del);
$sql = 'INSERT INTO '.MAIN_DB_PREFIX."facture_tva_sum (fk_facture,amount,tva_tx) values ($this->id,'".price2num($tvas[$key])."','".price2num($key)."');"; $sql = 'INSERT INTO '.MAIN_DB_PREFIX."facture_tva_sum (fk_facture,amount,tva_tx) values ($this->id,'".price2num($tvas[$key])."','".price2num($key)."');";
if (! $this->db->query($sql) ) if (! $this->db->query($sql) )
{ {
dolibarr_print_error($this->db); dolibarr_print_error($this->db);
$err++; $err++;
} }
} }
} }
else else
{ {
$err++; $err++;
} }
if ($err == 0) if ($err == 0)
{ {
return 1; return 1;
} }
else else
{ {
return -3; return -3;
} }
} }
else else
{ {
dolibarr_print_error($this->db); $this->error=$this->db->error();
} dolibarr_syslog("Facture::update_price error=".$this->error,LOG_ERR);
} return -1;
else }
{ }
dolibarr_print_error($this->db); else
} {
} $this->error=$this->db->error();
dolibarr_syslog("Facture::update_price error=".$this->error,LOG_ERR);
return -1;
}
}
/** /**
* \brief Applique une remise relative * \brief Applique une remise relative
@ -2831,10 +2842,11 @@ class FactureLigne
/** /**
* \brief Insère l'objet ligne de facture en base * \brief Insère l'objet ligne de facture en base
* \return int <0 si ko, >0 si ok * \param notrigger 1 ne declenche pas les triggers, 0 sinon
* \return int <0 si ko, >0 si ok
*/ */
function insert() function insert($notrigger=0)
{ {
global $langs; global $langs;
@ -2945,11 +2957,14 @@ class FactureLigne
} }
} }
// Appel des triggers if (! $notrigger)
include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); {
$interface=new Interfaces($this->db); // Appel des triggers
$result = $interface->run_triggers('LINEBILL_INSERT',$this,$user,$langs,$conf); include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php");
// Fin appel triggers $interface=new Interfaces($this->db);
$result = $interface->run_triggers('LINEBILL_INSERT',$this,$user,$langs,$conf);
// Fin appel triggers
}
$this->db->commit(); $this->db->commit();
return $this->rowid; return $this->rowid;

View File

@ -197,7 +197,7 @@ class User
else else
{ {
$this->error="USERNOTFOUND"; $this->error="USERNOTFOUND";
dolibarr_syslog("User::fetch Error 0, fails to get user - ".$this->error." - sql=".$sql); dolibarr_syslog("User::fetch user not found", LOG_DEBUG);
$this->db->free($result); $this->db->free($result);
return 0; return 0;
@ -206,7 +206,7 @@ class User
else else
{ {
$this->error=$this->db->error(); $this->error=$this->db->error();
dolibarr_syslog("User::fetch Error -1, fails to get user - ".$this->error." - sql=".$sql); dolibarr_syslog("User::fetch Error -1, fails to get user - ".$this->error." - sql=".$sql, LOG_ERR);
return -1; return -1;
} }
@ -232,7 +232,7 @@ class User
else else
{ {
$this->error=$this->db->error(); $this->error=$this->db->error();
dolibarr_syslog("User::fetch Error -2, fails to get setup user - ".$this->error." - sql=".$sql); dolibarr_syslog("User::fetch Error -2, fails to get setup user - ".$this->error." - sql=".$sql, LOG_ERR);
return -2; return -2;
} }