Add: Permettre de dterminer une ligne produit ayant une quantit nulle comme option

This commit is contained in:
Regis Houssin 2007-12-12 16:35:19 +00:00
parent 890c74ca7a
commit a8ac4cf565
7 changed files with 230 additions and 147 deletions

View File

@ -100,6 +100,13 @@ if ($_POST["action"] == 'setadddeliveryaddress')
exit;
}
if ($_POST["action"] == 'setuseoptionline')
{
dolibarr_set_const($db, "PROPALE_USE_OPTION_LINE",$_POST["value"]);
Header("Location: propale.php");
exit;
}
if ($_POST["action"] == 'setclassifiedinvoiced')
{
dolibarr_set_const($db, "PROPALE_CLASSIFIED_INVOICED_WITH_ORDER",$_POST["value"]);
@ -107,9 +114,9 @@ if ($_POST["action"] == 'setclassifiedinvoiced')
exit;
}
if ($_POST["action"] == 'set_use_customer_contact_as_recipient')
if ($_POST["action"] == 'setusecustomercontactasrecipient')
{
dolibarr_set_const($db, "PROPALE_USE_CUSTOMER_CONTACT_AS_RECIPIENT",$_POST["use_customer_contact_as_recipient"]);
dolibarr_set_const($db, "PROPALE_USE_CUSTOMER_CONTACT_AS_RECIPIENT",$_POST["value"]);
Header("Location: propale.php");
exit;
}
@ -429,11 +436,23 @@ print '</form>';
$var=! $var;
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
print '<input type="hidden" name="action" value="set_use_customer_contact_as_recipient">';
print '<input type="hidden" name="action" value="setusecustomercontactasrecipient">';
print '<tr '.$bc[$var].'><td>';
print $langs->trans("UseCustomerContactAsPropalRecipientIfExist");
print '</td><td width="60" align="center">';
print $html->selectyesno("use_customer_contact_as_recipient",$conf->global->PROPALE_USE_CUSTOMER_CONTACT_AS_RECIPIENT,1);
print $html->selectyesno("value",$conf->global->PROPALE_USE_CUSTOMER_CONTACT_AS_RECIPIENT,1);
print '</td><td align="right">';
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
print "</td></tr>\n";
print '</form>';
$var=! $var;
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
print '<input type="hidden" name="action" value="setuseoptionline">';
print '<tr '.$bc[$var].'><td>';
print $langs->trans("UseOptionLineIfNoQuantity");
print '</td><td width="60" align="center">';
print $html->selectyesno("value",$conf->global->PROPALE_USE_OPTION_LINE,1);
print '</td><td align="right">';
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
print "</td></tr>\n";

View File

@ -506,7 +506,7 @@ if ($_POST['action'] == "setabsolutediscount" && $user->rights->propale->creer)
*/
if ($_POST['action'] == "addligne" && $user->rights->propale->creer)
{
if ($_POST['qty'] && (($_POST['np_price']!='' && ($_POST['np_desc'] || $_POST['dp_desc'])) || $_POST['idprod']))
if (isset($_POST['qty']) && (($_POST['np_price']!='' && ($_POST['np_desc'] || $_POST['dp_desc'])) || $_POST['idprod']))
{
$propal = new Propal($db);
$ret=$propal->fetch($_POST['propalid']);
@ -1068,7 +1068,7 @@ if ($_GET['propalid'] > 0)
$sql = 'SELECT pt.rowid, pt.description, pt.fk_product, pt.fk_remise_except,';
$sql.= ' pt.qty, pt.tva_tx, pt.remise_percent, pt.subprice, pt.info_bits,';
$sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.marge_tx, pt.marque_tx,pt.pa_ht,';
$sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.marge_tx, pt.marque_tx, pt.pa_ht, pt.special_code,';
$sql.= ' p.label as product, p.ref, p.fk_product_type, p.rowid as prodid,';
$sql.= ' p.description as product_desc';
$sql.= ' FROM '.MAIN_DB_PREFIX.'propaldet as pt';
@ -1112,8 +1112,7 @@ if ($_GET['propalid'] > 0)
if ($objp->fk_product > 0)
{
print '<td>';
print '<a name="'.$objp->rowid.'"></a>'; // ancre pour retourner sur la ligne
$text = '<a href="'.DOL_URL_ROOT.'/product/fiche.php?id='.$objp->fk_product.'">';
print '<a name="'.$objp->rowid.'"></a>'; // ancre pour retourner sur la ligne;
// Affiche ligne produit
$text = '<a href="'.DOL_URL_ROOT.'/product/fiche.php?id='.$objp->fk_product.'">';
@ -1223,7 +1222,7 @@ if ($_GET['propalid'] > 0)
// Qty
print '<td align="right">';
if (($objp->info_bits & 2) != 2)
if ((($objp->info_bits & 2) != 2) && $objp->special_code != 3)
{
print $objp->qty;
}
@ -1231,7 +1230,7 @@ if ($_GET['propalid'] > 0)
print '</td>';
// Remise %
if ($objp->remise_percent > 0)
if ($objp->remise_percent > 0 && $objp->special_code != 3)
{
print '<td align="right">'.dolibarr_print_reduction($objp->remise_percent)."</td>\n";
}
@ -1239,7 +1238,17 @@ if ($_GET['propalid'] > 0)
{
print '<td>&nbsp;</td>';
}
print '<td align="right">'.price($objp->total_ht)."</td>\n";
// Montant total HT
if ($objp->special_code == 3)
{
// Si ligne en option
print '<td align="right">'.$langs->trans('Option').'</td>';
}
else
{
print '<td align="right">'.price($objp->total_ht)."</td>\n";
}
// Icone d'edition et suppression
if ($propal->statut == 0 && $user->rights->propale->creer)

View File

@ -288,21 +288,29 @@ class pdf_propale_azur extends ModelePDFPropales
// Quantité
$pdf->SetXY ($this->posxqty, $curY);
$pdf->MultiCell(10, 4, $propale->lignes[$i]->qty, 0, 'R');
if ($propale->lignes[$i]->special_code != 3) $pdf->MultiCell(10, 4, $propale->lignes[$i]->qty, 0, 'R');
// Remise sur ligne
$pdf->SetXY ($this->posxdiscount, $curY);
if ($propale->lignes[$i]->remise_percent)
if ($propale->lignes[$i]->remise_percent && $propale->lignes[$i]->special_code != 3)
{
$pdf->MultiCell(14, 4, dolibarr_print_reduction($propale->lignes[$i]->remise_percent), 0, 'R');
}
// Total HT ligne
$pdf->SetXY ($this->postotalht, $curY);
$total = price($propale->lignes[$i]->total_ht);
$pdf->MultiCell(23, 4, $total, 0, 'R', 0);
if ($propale->lignes[$i]->special_code == 3)
{
// Ligne produit en option
$pdf->MultiCell(23, 4, $outputlangs->transnoentities("Option"), 0, 'R', 0);
}
else
{
$total = price($propale->lignes[$i]->total_ht);
$pdf->MultiCell(23, 4, $total, 0, 'R', 0);
}
// Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
// Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
$tvaligne=$propale->lignes[$i]->total_tva;
if ($propale->remise_percent) $tvaligne-=($tvaligne*$propale->remise_percent)/100;
$this->tva[(string) $propale->lignes[$i]->tva_tx] += $tvaligne;

View File

@ -547,6 +547,7 @@ ClassifiedInvoicedWithOrder=Classify invoiced proposal at the same time as the o
HideTreadedPropal=Hide the treated commercial proposals in the list
AddShippingDateAbility=Add shipping date ability
AddDeliveryAddressAbility=Add delivery date ability
UseOptionLineIfNoQuantity=A line of product/service with a zero amount is considered as an option
##### Orders #####
OrdersSetup=Orders' management setup
OrdersNumberingModules=Orders numbering modules

View File

@ -546,6 +546,7 @@ ClassifiedInvoicedWithOrder=Class
HideTreadedPropal=Cacher les propositions commerciales traitées de la liste
AddShippingDateAbility=Possibilité de déterminer une date de livraison
AddDeliveryAddressAbility=Possibilité de sélectionner une adresse de livraison
UseOptionLineIfNoQuantity=Une ligne de produit/service ayant une quantité nulle est considérée comme une option
##### Orders #####
OrdersSetup=Configuration du module Commandes
OrdersNumberingModules=Modules de numérotation des commandes

View File

@ -270,6 +270,8 @@ class Propal extends CommonObject
*/
function addline($propalid, $desc, $pu_ht, $qty, $txtva, $fk_product=0, $remise_percent=0, $price_base_type='HT', $pu_ttc=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");
include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php');
@ -280,7 +282,14 @@ class Propal extends CommonObject
// Nettoyage paramètres
$remise_percent=price2num($remise_percent);
$qty=price2num($qty);
if (! $qty) $qty=1;
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);
@ -329,6 +338,9 @@ 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;
// \TODO Ne plus utiliser
$ligne->price=$price;
@ -336,30 +348,31 @@ class Propal extends CommonObject
$result=$ligne->insert();
if ($result > 0)
{
// Mise a jour informations denormalisees au niveau de la facture meme
{
// Mise a jour informations denormalisees au niveau de la propale meme
$result=$this->update_price($propalid);
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);
}
else
{
$this->error=$this->db->error();
dolibarr_syslog("Error sql=$sql, error=".$this->error);
$this->db->rollback();
return -1;
}
}
else
{
$this->error=$ligne->error;
}
}
else
{
$this->error=$ligne->error;
$this->db->rollback();
return -2;
}
}
return -2;
}
}
}
/**
@ -375,71 +388,90 @@ class Propal extends CommonObject
*/
function updateline($rowid, $pu, $qty, $remise_percent=0, $txtva, $desc='', $price_base_type='HT')
{
global $conf;
dolibarr_syslog("Propal::UpdateLine $rowid, $pu, $qty, $remise_percent, $txtva, $desc, $price_base_type");
include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php');
if ($this->statut == 0)
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);
$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)
{
$this->db->begin();
// Nettoyage paramètres
$remise_percent=price2num($remise_percent);
$qty=price2num($qty);
if (! $qty) $qty=1;
$pu = price2num($pu);
$txtva = price2num($txtva);
// Calcul du total TTC et de la TVA pour la ligne a partir de
// qty, pu, remise_percent et txtva
// TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
// la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
$tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, 0, $price_base_type);
$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.= " WHERE rowid = '".$rowid."';";
$result=$this->db->query($sql);
if ($result > 0)
{
$this->update_price();
$this->db->commit();
return 0;
}
else
{
$this->error=$this->db->error();
$this->db->rollback();
dolibarr_syslog("Propal.class::UpdateLine Erreur sql=$sql, error=".$this->error);
return -1;
}
$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);
if ($conf->global->PROPALE_USE_OPTION_LINE && !$qty)
{
$sql.= " , special_code=3";
}
else
{
dolibarr_syslog("Propal.class::UpdateLigne Erreur -2 Propal en mode incompatible pour cette action");
return -2;
$sql.= " , special_code=0";
}
$sql.= " WHERE rowid = '".$rowid."';";
$result=$this->db->query($sql);
if ($result > 0)
{
$this->update_price();
$this->db->commit();
return 0;
}
else
{
$this->error=$this->db->error();
$this->db->rollback();
dolibarr_syslog("Propal.class::UpdateLine Erreur sql=$sql, error=".$this->error);
return -1;
}
}
else
{
dolibarr_syslog("Propal.class::UpdateLigne Erreur -2 Propal en mode incompatible pour cette action");
return -2;
}
}
/**
* \brief Supprime une ligne de detail
* \param idligne Id de la ligne detail à supprimer
@ -604,7 +636,7 @@ class Propal extends CommonObject
// Liste des lignes a sommer
$sql = "SELECT qty, tva_tx, subprice, remise_percent,";
$sql.= " total_ht, total_tva, total_ttc";
$sql.= " total_ht, total_tva, total_ttc, special_code";
$sql.= " FROM ".MAIN_DB_PREFIX."propaldet";
$sql.= " WHERE fk_propal = ".$this->id;
@ -612,46 +644,50 @@ class Propal extends CommonObject
$result = $this->db->query($sql);
if ($result)
{
$this->total_ht = 0;
$this->total_tva = 0;
$this->total_ttc = 0;
$this->total_ht = 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);
$this->total_ht += $obj->total_ht;
$this->total_tva += ($obj->total_ttc - $obj->total_ht);
$this->total_ttc += $obj->total_ttc;
$tvas[$obj->tva_taux] += ($obj->total_ttc - $obj->total_ht);
$i++;
}
$this->db->free($result);
$num = $this->db->num_rows($result);
$i = 0;
while ($i < $num)
{
$obj = $this->db->fetch_object($result);
if ($this->special_code != 3)
{
$this->total_ht += $obj->total_ht;
$this->total_tva += ($obj->total_ttc - $obj->total_ht);
$this->total_ttc += $obj->total_ttc;
$tvas[$obj->tva_taux] += ($obj->total_ttc - $obj->total_ht);
}
$i++;
}
$this->db->free($result);
// Met a jour indicateurs
$sql = "UPDATE ".MAIN_DB_PREFIX."propal SET";
$sql.= " total_ht=".price2num($this->total_ht).",";
$sql.= " tva=". price2num($this->total_tva).",";
$sql.= " total=". price2num($this->total_ttc);
$sql.= " WHERE rowid = ".$this->id;
$sql = "UPDATE ".MAIN_DB_PREFIX."propal SET";
$sql.= " total_ht=".price2num($this->total_ht).",";
$sql.= " tva=". price2num($this->total_tva).",";
$sql.= " total=". price2num($this->total_ttc);
$sql.= " WHERE rowid = ".$this->id;
dolibarr_syslog("Propal::update_price sql=".$sql);
if ( $this->db->query($sql) )
{
return 1;
}
else
{
$this->error=$this->db->error();
dolibarr_syslog("Propal::update_price error=".$this->error);
return -1;
}
}
else
if ( $this->db->query($sql) )
{
return 1;
}
else
{
$this->error=$this->db->error();
dolibarr_syslog("Propal::update_price error=".$this->error);
return -1;
}
}
else
{
$this->error=$this->db->error();
dolibarr_syslog("Propal::update_price error=".$this->error,LOG_ERR);
@ -876,7 +912,7 @@ class Propal extends CommonObject
* 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.rang,";
$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";
@ -909,6 +945,7 @@ class Propal extends CommonObject
$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->fk_product = $objp->fk_product;
@ -2222,35 +2259,39 @@ class PropaleLigne
var $db;
var $error;
// From llx_propaldet
// From llx_propaldet
var $rowid;
var $fk_propal;
var $desc; // Description ligne
var $fk_product; // Id produit prédéfini
var $desc; // Description ligne
var $fk_product; // Id produit prédéfini
var $qty;
var $tva_tx;
var $subprice;
var $remise_percent;
var $qty;
var $tva_tx;
var $subprice;
var $remise_percent;
var $fk_remise_except;
var $rang = 0;
var $marge_tx;
var $marque_tx;
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
var $special_code; // Bit 3: ligne en option
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
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
// Ne plus utiliser
var $remise;
var $price;
var $remise;
var $price;
// From llx_product
var $ref; // Reference produit
var $libelle; // Label produit
var $product_desc; // Description produit
// From llx_product
var $ref; // Reference produit
var $libelle; // Label produit
var $product_desc; // Description produit
/**
@ -2270,7 +2311,7 @@ class PropaleLigne
{
$sql = 'SELECT pd.rowid, pd.fk_propal, pd.fk_product, pd.description, pd.price, pd.qty, pd.tva_tx,';
$sql.= ' pd.remise, pd.remise_percent, pd.fk_remise_except, pd.subprice,';
$sql.= ' pd.info_bits, pd.total_ht, pd.total_tva, pd.total_ttc, pd.marge_tx, pd.marque_tx, pd.rang,';
$sql.= ' pd.info_bits, pd.total_ht, pd.total_tva, pd.total_ttc, pd.marge_tx, pd.marque_tx, pd.special_code, pd.rang,';
$sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc';
$sql.= ' FROM '.MAIN_DB_PREFIX.'propaldet as pd';
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pd.fk_product = p.rowid';
@ -2296,10 +2337,11 @@ class PropaleLigne
$this->total_ttc = $objp->total_ttc;
$this->marge_tx = $objp->marge_tx;
$this->marque_tx = $objp->marque_tx;
$this->special_code = $objp->special_code;
$this->rang = $objp->rang;
$this->ref = $objp->product_ref;
$this->libelle = $objp->product_libelle;
$this->ref = $objp->product_ref;
$this->libelle = $objp->product_libelle;
$this->product_desc = $objp->product_desc;
$this->db->free($result);
@ -2348,7 +2390,7 @@ class PropaleLigne
$sql.= ' (fk_propal, description, fk_product, fk_remise_except, qty, tva_tx,';
$sql.= ' subprice, remise_percent, ';
$sql.= ' info_bits, ';
$sql.= ' total_ht, total_tva, total_ttc, marge_tx, marque_tx, rang)';
$sql.= ' total_ht, total_tva, total_ttc, marge_tx, marque_tx, special_code, rang)';
$sql.= " VALUES (".$this->fk_propal.",";
$sql.= " '".addslashes($this->desc)."',";
if ($this->fk_product) { $sql.= "'".$this->fk_product."',"; }
@ -2367,6 +2409,8 @@ class PropaleLigne
else $sql.= ' null,';
if (isset($this->marque_tx)) $sql.= ' '.$this->marque_tx.',';
else $sql.= ' null,';
if (isset($this->special_code)) $sql.= ' '.$this->special_code.',';
else $sql.= ' 0,';
$sql.= ' '.$rangtouse;
$sql.= ')';

View File

@ -47,4 +47,5 @@ create table llx_propaldet
--
-- 1 : frais de port
-- 2 : ecotaxe
-- 3 : option
--