diff --git a/htdocs/admin/marges.php b/htdocs/admin/marges.php
new file mode 100644
index 00000000000..2bc9da0d48e
--- /dev/null
+++ b/htdocs/admin/marges.php
@@ -0,0 +1,260 @@
+
+ *
+ * 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.
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file /marges/admin/marges.php
+ * \ingroup marges
+ * \brief Page to setup advanced extra fields module
+ * \version $Id:$
+ */
+
+$res=@include("../main.inc.php"); // For root directory
+
+require_once(DOL_DOCUMENT_ROOT."/marges/lib/marges.lib.php");
+require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php");
+
+$langs->load("admin");
+$langs->load("marges");
+
+if (!$user->admin)
+accessforbidden();
+
+
+/*
+ * Action
+ */
+if (preg_match('/set_(.*)/',$action,$reg))
+{
+ $code=$reg[1];
+ if (dolibarr_set_const($db, $code, 1, 'yesno', 0, '', $conf->entity) > 0)
+ {
+ Header("Location: ".$_SERVER["PHP_SELF"]);
+ exit;
+ }
+ else
+ {
+ dol_print_error($db);
+ }
+}
+
+if (preg_match('/del_(.*)/',$action,$reg))
+{
+ $code=$reg[1];
+ if (dolibarr_del_const($db, $code, $conf->entity) > 0)
+ {
+ Header("Location: ".$_SERVER["PHP_SELF"]);
+ exit;
+ }
+ else
+ {
+ dol_print_error($db);
+ }
+}
+
+if ($_POST["action"] == 'remises')
+{
+ if (dolibarr_set_const($db, 'MARGIN_METHODE_FOR_DISCOUNT', $_POST['MARGIN_METHODE_FOR_DISCOUNT'], 'chaine', 0, '', $conf->entity) > 0)
+ {
+ $conf->global->MARGIN_METHODE_FOR_DISCOUNT = $_POST['MARGIN_METHODE_FOR_DISCOUNT'];
+ }
+ else
+ {
+ dol_print_error($db);
+ }
+}
+
+if ($_POST["action"] == 'typemarges')
+{
+ if (dolibarr_set_const($db, 'MARGIN_TYPE', $_POST['MARGIN_TYPE'], 'chaine', 0, '', $conf->entity) > 0)
+ {
+ $conf->global->MARGIN_METHODE_FOR_DISCOUNT = $_POST['MARGIN_TYPE'];
+ }
+ else
+ {
+ dol_print_error($db);
+ }
+}
+
+/*
+ * View
+ */
+
+llxHeader('',$langs->trans("margesSetup"));
+
+
+$linkback=''.$langs->trans("BackToModuleList").' ';
+print_fiche_titre($langs->trans("margesSetup"),$linkback,'setup');
+
+
+$head = marges_admin_prepare_head($adh);
+
+dol_fiche_head($head, 'parameters', $langs->trans("marges"), 0, 'company');
+
+print " ";
+
+
+print_fiche_titre($langs->trans("MemberMainOptions"),'','');
+print '
';
+print '';
+print ''.$langs->trans("Description").' ';
+
+print ''.$langs->trans("Value").' '."\n";
+print ''.$langs->trans("Details").' '."\n";
+print ' ';
+
+$var=true;
+$form = new Form($db);
+
+// GLOBAL DISCOUNT MANAGEMENT
+$var=!$var;
+print "';
+
+// DISPLAY MARGIN RATES
+$var=!$var;
+print '';
+print ''.$langs->trans("DisplayMarginRates").' ';
+
+
+print '';
+if ($conf->use_javascript_ajax)
+{
+ print ajax_constantonoff('DISPLAY_MARGIN_RATES');
+}
+else
+{
+ if($conf->global->DISPLAY_MARGIN_RATES == 0)
+ {
+ print ''.img_picto($langs->trans("Disabled"),'off').' ';
+ }
+ else if($conf->global->DISPLAY_MARGIN_RATES == 1)
+ {
+ print ''.img_picto($langs->trans("Enabled"),'on').' ';
+ }
+}
+print ' ';
+print ''.$langs->trans('MarginRate').' = '.$langs->trans('Margin').' / '.$langs->trans('BuyingPrice').' ';
+print ' ';
+
+// DISPLAY MARK RATES
+$var=!$var;
+print '';
+print ''.$langs->trans("DisplayMarkRates").' ';
+
+
+print '';
+if ($conf->use_javascript_ajax)
+{
+ print ajax_constantonoff('DISPLAY_MARK_RATES');
+}
+else
+{
+ if($conf->global->DISPLAY_MARK_RATES == 0)
+ {
+ print ''.img_picto($langs->trans("Disabled"),'off').' ';
+ }
+ else if($conf->global->DISPLAY_MARK_RATES == 1)
+ {
+ print ''.img_picto($langs->trans("Enabled"),'on').' ';
+ }
+}
+print ' ';
+print ''.$langs->trans('MarkRate').' = '.$langs->trans('Margin').' / '.$langs->trans('SellingPrice').' ';
+print ' ';
+print '';
+print ''.$langs->trans("ForceBuyingPriceIfNull").' ';
+
+print '';
+if ($conf->use_javascript_ajax)
+{
+ print ajax_constantonoff('ForceBuyingPriceIfNull');
+}
+else
+{
+ if($conf->global->ForceBuyingPriceIfNull == 0)
+ {
+ print ''.img_picto($langs->trans("Disabled"),'off').' ';
+ }
+ else if($conf->global->ForceBuyingPriceIfNull == 1)
+ {
+ print ''.img_picto($langs->trans("Enabled"),'on').' ';
+ }
+}
+print ' ';
+print ''.$langs->trans('ForceBuyingPriceIfNullDetails').' ';
+print ' ';
+
+// GLOBAL DISCOUNT MANAGEMENT
+$var=!$var;
+print "';
+
+print '
';
+print ' ';
+
+
+
+$db->close();
+
+llxFooter('$Date: 2011/07/31 22:23:21 $ - $Revision: 1.6 $');
+?>
diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php
index 403fedddd15..c127e4cada5 100644
--- a/htdocs/comm/propal.php
+++ b/htdocs/comm/propal.php
@@ -46,6 +46,8 @@ $langs->load('compta');
$langs->load('bills');
$langs->load('orders');
$langs->load('products');
+if ($conf->marges->enabled)
+ $langs->load('marges');
$id=GETPOST('id','int');
$ref=GETPOST('ref','alpha');
@@ -788,6 +790,13 @@ else if ($action == "addline" && $user->rights->propale->creer)
$localtax2_tx=get_localtax($tva_tx,2,$object->client);
}
+ // ajout prix achat
+ $fk_fournprice = $_POST['np_fournprice'];
+ if ( ! empty($_POST['np_buying_price']) )
+ $pa_ht = $_POST['np_buying_price'];
+ else
+ $pa_ht = null;
+
$info_bits=0;
if ($tva_npr) $info_bits |= 0x01;
@@ -814,7 +823,9 @@ else if ($action == "addline" && $user->rights->propale->creer)
$type,
-1,
0,
- $_POST['fk_parent_line']
+ $_POST['fk_parent_line'],
+ $fk_fournprice,
+ $pa_ht
);
if ($result > 0)
@@ -841,6 +852,7 @@ else if ($action == "addline" && $user->rights->propale->creer)
unset($_POST['dp_desc']);
unset($_POST['np_tva_tx']);
unset($_POST['np_desc']);
+ unset($_POST['np_buying_price']);
}
else
{
@@ -869,11 +881,18 @@ else if ($action == 'updateligne' && $user->rights->propale->creer && $_POST["sa
$vat_rate=str_replace('*','',$vat_rate);
$localtax1_rate=get_localtax($vat_rate,1,$object->client);
$localtax2_rate=get_localtax($vat_rate,2,$object->client);
- $up_ht=GETPOST('pu')?GETPOST('pu'):GETPOST('subprice');
+ $pu_ht=GETPOST('pu')?GETPOST('pu'):GETPOST('subprice');
- // Define special_code for special lines
- $special_code=0;
- if (empty($_POST['qty'])) $special_code=3;
+ // ajout prix d'achat
+ $fk_fournprice = $_POST['fournprice'];
+ if ( ! empty($_POST['buying_price']) )
+ $pa_ht = $_POST['buying_price'];
+ else
+ $pa_ht = null;
+
+ // Define special_code for special lines
+ $special_code=0;
+ if (empty($_POST['qty'])) $special_code=3;
// On verifie que le prix minimum est respecte
$productid = $_POST['productid'] ;
@@ -884,7 +903,7 @@ else if ($action == 'updateligne' && $user->rights->propale->creer && $_POST["sa
$price_min = $product->price_min;
if ($conf->global->PRODUIT_MULTIPRICES && $object->client->price_level) $price_min = $product->multiprices_min[$object->client->price_level];
}
- if ($productid && $price_min && (price2num($up_ht)*(1-price2num($_POST['remise_percent'])/100) < price2num($price_min)))
+ if ($productid && $price_min && (price2num($pu_ht)*(1-price2num($_POST['remise_percent'])/100) < price2num($price_min)))
{
$mesg = ''.$langs->trans("CantBeLessThanMinPrice",price2num($price_min,'MU').' '.$langs->trans("Currency".$conf->currency)).'
' ;
}
@@ -892,7 +911,7 @@ else if ($action == 'updateligne' && $user->rights->propale->creer && $_POST["sa
{
$result = $object->updateline(
$_POST['lineid'],
- $up_ht,
+ $pu_ht,
$_POST['qty'],
$_POST['remise_percent'],
$vat_rate,
@@ -902,7 +921,10 @@ else if ($action == 'updateligne' && $user->rights->propale->creer && $_POST["sa
'HT',
$info_bits,
$special_code,
- $_POST['fk_parent_line']
+ $_POST['fk_parent_line'],
+ 0,
+ $fk_fournprice,
+ $pa_ht
);
// Define output language
@@ -917,8 +939,15 @@ else if ($action == 'updateligne' && $user->rights->propale->creer && $_POST["sa
}
if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
{
- $ret=$object->fetch($id); // Reload to get new records
+ $ret=$object->fetch($id); // Reload to get new records
propale_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
+
+ unset($_POST['qty']);
+ unset($_POST['type']);
+ unset($_POST['np_price']);
+ unset($_POST['dp_desc']);
+ unset($_POST['np_tva_tx']);
+ unset($_POST['np_buying_price']);
}
}
}
@@ -1527,10 +1556,18 @@ if (empty($reshook) && ! empty($extrafields->attribute_label))
}
}
-// Amount HT
+// Amount HT
print ''.$langs->trans('AmountHT').' ';
print ''.price($object->total_ht).' ';
-print ''.$langs->trans("Currency".$conf->currency).' ';
+print ''.$langs->trans("Currency".$conf->currency).' ';
+
+// Margin Infos
+if ($conf->marges->enabled) {
+ print '';
+ $object->displayMarginInfos();
+ print ' ';
+}
+print '';
// Amount VAT
print ''.$langs->trans('AmountVAT').' ';
@@ -1560,7 +1597,7 @@ print ''.price($object->total_ttc).' ';
print ''.$langs->trans("Currency".$conf->currency).' ';
// Statut
-print ''.$langs->trans('Status').' '.$object->getLibStatut(4).' ';
+print ''.$langs->trans('Status').' '.$object->getLibStatut(4).' ';
print ' ';
@@ -1607,7 +1644,7 @@ if ($object->statut == 0 && $user->rights->propale->creer)
// Add free products/services
$object->formAddFreeProduct(0,$mysoc,$soc,$hookmanager);
-
+
// Add predefined products/services
if ($conf->product->enabled || $conf->service->enabled)
{
diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php
index d378fafb523..29cc04a477a 100644
--- a/htdocs/comm/propal/class/propal.class.php
+++ b/htdocs/comm/propal/class/propal.class.php
@@ -8,6 +8,7 @@
* Copyright (C) 2008 Raphael Bertrand
* Copyright (C) 2010-2011 Juanjo Menent
* Copyright (C) 2010-2011 Philippe Grand
+ * Copyright (C) 2012 Christophe Battarel
*
* 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
@@ -32,6 +33,7 @@ require_once(DOL_DOCUMENT_ROOT ."/core/class/commonobject.class.php");
require_once(DOL_DOCUMENT_ROOT ."/product/class/product.class.php");
require_once(DOL_DOCUMENT_ROOT ."/contact/class/contact.class.php");
+require_once(DOL_DOCUMENT_ROOT ."/marges/lib/marges.lib.php");
/**
* \class Propal
@@ -306,7 +308,7 @@ class Propal extends CommonObject
*
* @see add_product
*/
- function addline($propalid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $price_base_type='HT', $pu_ttc=0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0)
+ function addline($propalid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $price_base_type='HT', $pu_ttc=0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht = 0)
{
global $conf;
@@ -327,6 +329,7 @@ class Propal extends CommonObject
$txtva=price2num($txtva);
$txlocaltax1=price2num($txlocaltax1);
$txlocaltax2=price2num($txlocaltax2);
+ $pa_ht=price2num($pa_ht);
if ($price_base_type=='HT')
{
$pu=$pu_ht;
@@ -395,6 +398,10 @@ class Propal extends CommonObject
$this->line->special_code=$special_code;
$this->line->fk_parent_line=$fk_parent_line;
+ // infos marge
+ $this->line->fk_fournprice = $fk_fournprice;
+ $this->line->pa_ht = $pa_ht;
+
// Mise en option de la ligne
//if ($conf->global->PROPALE_USE_OPTION_LINE && !$qty) $ligne->special_code=3;
if (empty($qty) && empty($special_code)) $this->line->special_code=3;
@@ -452,7 +459,7 @@ class Propal extends CommonObject
* @param int $skip_update_total Skip update total
* @return int 0 if OK, <0 if KO
*/
- function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0, $txlocaltax2=0, $desc='', $price_base_type='HT', $info_bits=0, $special_code=0, $fk_parent_line=0, $skip_update_total=0)
+ function updateline($rowid, $pu, $qty, $remise_percent=0, $txtva, $txlocaltax1=0, $txlocaltax2=0, $desc='', $price_base_type='HT', $info_bits=0, $special_code=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht = 0)
{
global $conf,$user,$langs;
@@ -466,6 +473,7 @@ class Propal extends CommonObject
$txtva = price2num($txtva);
$txlocaltax1=price2num($txlocaltax1);
$txlocaltax2=price2num($txlocaltax2);
+ $pa_ht=price2num($pa_ht);
if (empty($qty) && empty($special_code)) $special_code=3; // Set option tag
if (! empty($qty) && $special_code == 3) $special_code=0; // Remove option tag
@@ -525,6 +533,10 @@ class Propal extends CommonObject
$this->line->fk_parent_line = $fk_parent_line;
$this->line->skip_update_total = $skip_update_total;
+ // infos marge
+ $this->line->fk_fournprice = $fk_fournprice;
+ $this->line->pa_ht = $pa_ht;
+
// TODO deprecated
$this->line->price=$price;
$this->line->remise=$remise;
@@ -738,7 +750,9 @@ class Propal extends CommonObject
$this->lines[$i]->product_type,
$this->lines[$i]->rang,
$this->lines[$i]->special_code,
- $fk_parent_line
+ $fk_parent_line,
+ $this->lines[$i]->fk_fournprice,
+ $this->lines[$i]->pa_ht
);
if ($result < 0)
@@ -1057,7 +1071,7 @@ class Propal extends CommonObject
* Lignes propales liees a un produit ou non
*/
$sql = "SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.description, d.price, d.tva_tx, d.localtax1_tx, d.localtax2_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_localtax1, d.total_localtax2, d.total_ttc, d.marge_tx, d.marque_tx, d.special_code, d.rang, d.product_type,";
+ $sql.= " d.info_bits, d.total_ht, d.total_tva, d.total_localtax1, d.total_localtax2, d.total_ttc, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht, d.special_code, d.rang, d.product_type,";
$sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label';
$sql.= " FROM ".MAIN_DB_PREFIX."propaldet as d";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON d.fk_product = p.rowid";
@@ -1096,8 +1110,11 @@ class Propal extends CommonObject
$line->total_localtax1 = $objp->total_localtax1;
$line->total_localtax2 = $objp->total_localtax2;
$line->total_ttc = $objp->total_ttc;
- $line->marge_tx = $objp->marge_tx;
- $line->marque_tx = $objp->marque_tx;
+ $line->fk_fournprice = $objp->fk_fournprice;
+ $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
+ $line->pa_ht = $marginInfos[0];
+ $line->marge_tx = $marginInfos[1];
+ $line->marque_tx = $marginInfos[2];
$line->special_code = $objp->special_code;
$line->rang = $objp->rang;
@@ -2358,7 +2375,7 @@ class Propal extends CommonObject
{
$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, pt.special_code,';
+ $sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code, pt.localtax1_tx, pt.localtax2_tx,';
$sql.= ' pt.date_start, pt.date_end, pt.product_type, pt.rang,';
$sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid,';
$sql.= ' p.description as product_desc';
@@ -2387,7 +2404,6 @@ class Propal extends CommonObject
$this->lines[$i]->product_type = $obj->product_type;
$this->lines[$i]->qty = $obj->qty;
$this->lines[$i]->subprice = $obj->subprice;
- $this->lines[$i]->pa_ht = $obj->pa_ht;
$this->lines[$i]->fk_remise_except = $obj->fk_remise_except;
$this->lines[$i]->remise_percent = $obj->remise_percent;
$this->lines[$i]->tva_tx = $obj->tva_tx;
@@ -2395,8 +2411,11 @@ class Propal extends CommonObject
$this->lines[$i]->total_ht = $obj->total_ht;
$this->lines[$i]->total_tva = $obj->total_tva;
$this->lines[$i]->total_ttc = $obj->total_ttc;
- $this->lines[$i]->marge_tx = $obj->marge_tx;
- $this->lines[$i]->marque_tx = $obj->marque_tx;
+ $this->lines[$i]->fk_fournprice = $obj->fk_fournprice;
+ $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->lines[$i]->fk_fournprice, $obj->pa_ht);
+ $this->lines[$i]->pa_ht = $marginInfos[0];
+ $this->lines[$i]->marge_tx = $marginInfos[1];
+ $this->lines[$i]->marque_tx = $marginInfos[2];
$this->lines[$i]->special_code = $obj->special_code;
$this->lines[$i]->rang = $obj->rang;
$this->lines[$i]->date_start = $this->db->jdate($obj->date_start);
@@ -2445,8 +2464,11 @@ class PropaleLigne
var $fk_remise_except;
var $rang = 0;
- var $marge_tx;
- var $marque_tx;
+
+ var $fk_fournprice;
+ var $pa_ht;
+ var $marge_tx;
+ var $marque_tx;
var $special_code; // Liste d'options non cumulabels:
// 1: frais de port
@@ -2497,7 +2519,7 @@ class PropaleLigne
{
$sql = 'SELECT pd.rowid, pd.fk_propal, pd.fk_parent_line, 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.special_code, pd.rang,';
+ $sql.= ' pd.info_bits, pd.total_ht, pd.total_tva, pd.total_ttc, pd.fk_product_fournisseur_price as fk_fournprice, pd.buy_price_ht as pa_ht, 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';
@@ -2525,8 +2547,11 @@ class PropaleLigne
$this->total_tva = $objp->total_tva;
$this->total_ttc = $objp->total_ttc;
- $this->marge_tx = $objp->marge_tx;
- $this->marque_tx = $objp->marque_tx;
+ $this->fk_fournprice = $objp->fk_fournprice;
+ $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
+ $this->pa_ht = $marginInfos[0];
+ $this->marge_tx = $marginInfos[1];
+ $this->marque_tx = $marginInfos[2];
$this->special_code = $objp->special_code;
$this->rang = $objp->rang;
@@ -2571,6 +2596,14 @@ class PropaleLigne
if (empty($this->special_code)) $this->special_code=0;
if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
+ if (empty($this->pa_ht)) $this->pa_ht=0;
+
+ // si prix d'achat non renseigné et utilisé pour calcul des marges alors prix achat = prix vente (idem pour remises)
+ if ($this->pa_ht == 0) {
+ if ($this->subprice < 0 || ($conf->global->CalculateMarginsOnLinesWithoutBuyingPrice == 1))
+ $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100);
+ }
+
// Check parameters
if ($this->product_type < 0) return -1;
@@ -2581,7 +2614,7 @@ class PropaleLigne
$sql.= ' (fk_propal, fk_parent_line, description, fk_product, product_type, fk_remise_except, qty, tva_tx, localtax1_tx, localtax2_tx,';
$sql.= ' subprice, remise_percent, ';
$sql.= ' info_bits, ';
- $sql.= ' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, special_code, rang, marge_tx, marque_tx)';
+ $sql.= ' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, special_code, rang, fk_product_fournisseur_price, buy_price_ht)';
$sql.= " VALUES (".$this->fk_propal.",";
$sql.= " ".($this->fk_parent_line>0?"'".$this->fk_parent_line."'":"null").",";
$sql.= " '".$this->db->escape($this->desc)."',";
@@ -2602,10 +2635,10 @@ class PropaleLigne
$sql.= " ".price2num($this->total_ttc).",";
$sql.= ' '.$this->special_code.',';
$sql.= ' '.$this->rang.',';
- if (isset($this->marge_tx)) $sql.= ' '.$this->marge_tx.',';
- else $sql.= ' null,';
- if (isset($this->marque_tx)) $sql.= ' '.$this->marque_tx;
- else $sql.= ' null';
+ if (isset($this->fk_fournprice)) $sql.= ' '.$this->fk_fournprice.',';
+ else $sql.= ' null,';
+ if (isset($this->pa_ht)) $sql.= ' '.price2num($this->pa_ht);
+ else $sql.= ' null';
$sql.= ')';
dol_syslog("PropaleLigne::insert sql=$sql");
@@ -2701,6 +2734,14 @@ class PropaleLigne
if (empty($this->special_code)) $this->special_code=0;
if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
+ if (empty($this->pa_ht)) $this->pa_ht=0;
+
+ // si prix d'achat non renseigné et utilisé pour calcul des marges alors prix achat = prix vente (idem pour remises)
+ if ($this->pa_ht == 0) {
+ if ($this->subprice < 0 || ($conf->global->CalculateMarginsOnLinesWithoutBuyingPrice == 1))
+ $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100);
+ }
+
$this->db->begin();
// Mise a jour ligne en base
@@ -2721,8 +2762,8 @@ class PropaleLigne
$sql.= " , total_tva=".price2num($this->total_tva)."";
$sql.= " , total_ttc=".price2num($this->total_ttc)."";
}
- $sql.= " , marge_tx='".$this->marge_tx."'";
- $sql.= " , marque_tx='".$this->marque_tx."'";
+ $sql.= " , fk_product_fournisseur_price='".$this->fk_fournprice."'";
+ $sql.= " , buy_price_ht='".price2num($this->pa_ht)."'";
$sql.= " , info_bits=".$this->info_bits;
if (strlen($this->special_code)) $sql.= " , special_code=".$this->special_code;
$sql.= " , fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null");
diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php
index 6a561ecffb3..f43e78a1d76 100644
--- a/htdocs/commande/class/commande.class.php
+++ b/htdocs/commande/class/commande.class.php
@@ -5,6 +5,7 @@
* Copyright (C) 2006 Andre Cianfarani
* Copyright (C) 2010-2011 Juanjo Menent
* Copyright (C) 2011 Jean Heimburger
+ * Copyright (C) 2012 Christophe Battarel
*
* 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
@@ -28,6 +29,7 @@
include_once(DOL_DOCUMENT_ROOT."/core/class/commonorder.class.php");
require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php");
+require_once(DOL_DOCUMENT_ROOT ."/marges/lib/marges.lib.php");
/**
* \class Commande
@@ -695,7 +697,9 @@ class Commande extends CommonOrder
$this->lines[$i]->product_type,
$this->lines[$i]->rang,
$this->lines[$i]->special_code,
- $fk_parent_line
+ $fk_parent_line,
+ $this->lines[$i]->fk_fournprice,
+ $this->lines[$i]->pa_ht
);
if ($result < 0)
{
@@ -1002,7 +1006,7 @@ class Commande extends CommonOrder
* par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,produit)
* et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue)
*/
- function addline($commandeid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $info_bits=0, $fk_remise_except=0, $price_base_type='HT', $pu_ttc=0, $date_start='', $date_end='', $type=0, $rang=-1, $special_code=0, $fk_parent_line=0)
+ function addline($commandeid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $info_bits=0, $fk_remise_except=0, $price_base_type='HT', $pu_ttc=0, $date_start='', $date_end='', $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht = 0)
{
dol_syslog("Commande::addline commandeid=$commandeid, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_percent=$remise_percent, info_bits=$info_bits, fk_remise_except=$fk_remise_except, price_base_type=$price_base_type, pu_ttc=$pu_ttc, date_start=$date_start, date_end=$date_end, type=$type", LOG_DEBUG);
@@ -1022,6 +1026,7 @@ class Commande extends CommonOrder
$qty=price2num($qty);
$pu_ht=price2num($pu_ht);
$pu_ttc=price2num($pu_ttc);
+ $pa_ht=price2num($pa_ht);
$txtva = price2num($txtva);
$txlocaltax1 = price2num($txlocaltax1);
$txlocaltax2 = price2num($txlocaltax2);
@@ -1098,6 +1103,10 @@ class Commande extends CommonOrder
$this->line->date_start=$date_start;
$this->line->date_end=$date_end;
+ // infos marge
+ $this->line->fk_fournprice = $fk_fournprice;
+ $this->line->pa_ht = $pa_ht;
+
// TODO Ne plus utiliser
$this->line->price=$price;
$this->line->remise=$remise;
@@ -1417,7 +1426,7 @@ class Commande extends CommonOrder
$this->lines=array();
$sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.product_type, l.fk_commande, l.description, l.price, l.qty, l.tva_tx,';
- $sql.= ' l.localtax1_tx, l.localtax2_tx, l.fk_remise_except, l.remise_percent, l.subprice, l.marge_tx, l.marque_tx, l.rang, l.info_bits, l.special_code,';
+ $sql.= ' l.localtax1_tx, l.localtax2_tx, l.fk_remise_except, l.remise_percent, l.subprice, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht, l.rang, l.info_bits, l.special_code,';
$sql.= ' l.total_ht, l.total_ttc, l.total_tva, l.total_localtax1, l.total_localtax2, l.date_start, l.date_end,';
$sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label';
$sql.= ' FROM '.MAIN_DB_PREFIX.'commandedet as l';
@@ -1459,8 +1468,11 @@ class Commande extends CommonOrder
$line->remise_percent = $objp->remise_percent;
$line->price = $objp->price;
$line->fk_product = $objp->fk_product;
- $line->marge_tx = $objp->marge_tx;
- $line->marque_tx = $objp->marque_tx;
+ $line->fk_fournprice = $objp->fk_fournprice;
+ $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
+ $line->pa_ht = $marginInfos[0];
+ $line->marge_tx = $marginInfos[1];
+ $line->marque_tx = $marginInfos[2];
$line->rang = $objp->rang;
$line->info_bits = $objp->info_bits;
$line->special_code = $objp->special_code;
@@ -2142,7 +2154,7 @@ class Commande extends CommonOrder
* @param int $skip_update_total Skip update of total
* @return int < 0 if KO, > 0 if OK
*/
- function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0,$txlocaltax2=0, $price_base_type='HT', $info_bits=0, $date_start='', $date_end='', $type=0, $fk_parent_line=0, $skip_update_total=0)
+ function updateline($rowid, $desc, $pu, $qty, $remise_percent=0, $txtva, $txlocaltax1=0,$txlocaltax2=0, $price_base_type='HT', $info_bits=0, $date_start='', $date_end='', $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht = 0)
{
global $conf;
@@ -2164,6 +2176,7 @@ class Commande extends CommonOrder
$remise_percent=price2num($remise_percent);
$qty=price2num($qty);
$pu = price2num($pu);
+ $pa_ht=price2num($pa_ht);
$txtva=price2num($txtva);
$txlocaltax1=price2num($txlocaltax1);
$txlocaltax2=price2num($txlocaltax2);
@@ -2224,6 +2237,10 @@ class Commande extends CommonOrder
$this->line->fk_parent_line=$fk_parent_line;
$this->line->skip_update_total=$skip_update_total;
+ // infos marge
+ $this->line->fk_fournprice = $fk_fournprice;
+ $this->line->pa_ht = $pa_ht;
+
// TODO deprecated
$this->line->price=$price;
$this->line->remise=$remise;
@@ -2723,7 +2740,7 @@ class Commande extends CommonOrder
$sql = 'SELECT l.rowid, l.fk_product, l.product_type, l.description, l.price, l.qty, l.tva_tx, ';
$sql.= ' l.fk_remise_except, l.remise_percent, l.subprice, l.info_bits,l.rang,l.special_code,';
- $sql.= ' l.total_ht, l.total_tva, l.total_ttc,';
+ $sql.= ' l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht, l.localtax1_tx, l.localtax2_tx,';
$sql.= ' l.date_start,';
$sql.= ' l.date_end,';
$sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, ';
@@ -2764,6 +2781,11 @@ class Commande extends CommonOrder
$this->lines[$i]->rang = $obj->rang;
$this->lines[$i]->date_start = $this->db->jdate($obj->date_start);
$this->lines[$i]->date_end = $this->db->jdate($obj->date_end);
+ $this->lines[$i]->fk_fournprice = $obj->fk_fournprice;
+ $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->lines[$i]->fk_fournprice, $obj->pa_ht);
+ $this->lines[$i]->pa_ht = $marginInfos[0];
+ $this->lines[$i]->marge_tx = $marginInfos[1];
+ $this->lines[$i]->marque_tx = $marginInfos[2];
$i++;
}
@@ -2809,6 +2831,8 @@ class OrderLine
var $subprice; // U.P. HT (example 100)
var $remise_percent; // % for line discount (example 20%)
var $rang = 0;
+ var $fk_fournprice;
+ var $pa_ht;
var $marge_tx;
var $marque_tx;
var $info_bits = 0; // Bit 0: 0 si TVA normal - 1 si TVA NPR
@@ -2856,7 +2880,7 @@ class OrderLine
{
$sql = 'SELECT cd.rowid, cd.fk_commande, cd.fk_parent_line, cd.fk_product, cd.product_type, cd.description, cd.price, cd.qty, cd.tva_tx, cd.localtax1_tx, cd.localtax2_tx,';
$sql.= ' cd.remise, cd.remise_percent, cd.fk_remise_except, cd.subprice,';
- $sql.= ' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.marge_tx, cd.marque_tx, cd.rang, cd.special_code,';
+ $sql.= ' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.fk_product_fournisseur_price as fk_fournprice, cd.buy_price_ht as pa_ht, cd.rang, cd.special_code,';
$sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc,';
$sql.= ' cd.date_start, cd.date_end';
$sql.= ' FROM '.MAIN_DB_PREFIX.'commandedet as cd';
@@ -2887,8 +2911,11 @@ class OrderLine
$this->total_localtax1 = $objp->total_localtax1;
$this->total_localtax2 = $objp->total_localtax2;
$this->total_ttc = $objp->total_ttc;
- $this->marge_tx = $objp->marge_tx;
- $this->marque_tx = $objp->marque_tx;
+ $this->fk_fournprice = $objp->fk_fournprice;
+ $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
+ $this->pa_ht = $marginInfos[0];
+ $this->marge_tx = $marginInfos[1];
+ $this->marque_tx = $marginInfos[2];
$this->special_code = $objp->special_code;
$this->rang = $objp->rang;
@@ -2970,6 +2997,14 @@ class OrderLine
if (empty($this->special_code)) $this->special_code=0;
if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
+ if (empty($this->pa_ht)) $this->pa_ht=0;
+
+ // si prix d'achat non renseigné et utilisé pour calcul des marges alors prix achat = prix vente (idem pour remises)
+ if ($this->pa_ht == 0) {
+ if ($this->subprice < 0 || ($conf->global->CalculateMarginsOnLinesWithoutBuyingPrice == 1))
+ $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100);
+ }
+
// Check parameters
if ($this->product_type < 0) return -1;
@@ -2979,7 +3014,7 @@ class OrderLine
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'commandedet';
$sql.= ' (fk_commande, fk_parent_line, description, qty, tva_tx, localtax1_tx, localtax2_tx,';
$sql.= ' fk_product, product_type, remise_percent, subprice, price, remise, fk_remise_except,';
- $sql.= ' special_code, rang, marge_tx, marque_tx,';
+ $sql.= ' special_code, rang, fk_product_fournisseur_price, buy_price_ht,';
$sql.= ' info_bits, total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, date_start, date_end)';
$sql.= " VALUES (".$this->fk_commande.",";
$sql.= " ".($this->fk_parent_line>0?"'".$this->fk_parent_line."'":"null").",";
@@ -2999,10 +3034,10 @@ class OrderLine
else $sql.= 'null,';
$sql.= ' '.$this->special_code.',';
$sql.= ' '.$this->rang.',';
- if (isset($this->marge_tx)) $sql.= ' '.$this->marge_tx.',';
- else $sql.= ' null,';
- if (isset($this->marque_tx)) $sql.= ' '.$this->marque_tx.',';
- else $sql.= ' null,';
+ if (isset($this->fk_fournprice)) $sql.= ' '.$this->fk_fournprice.',';
+ else $sql.= ' null,';
+ if (isset($this->pa_ht)) $sql.= ' '.price2num($this->pa_ht).',';
+ else $sql.= ' null,';
$sql.= " '".$this->info_bits."',";
$sql.= " '".price2num($this->total_ht)."',";
$sql.= " '".price2num($this->total_tva)."',";
@@ -3070,6 +3105,14 @@ class OrderLine
if (empty($this->product_type)) $this->product_type=0;
if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
+ if (empty($this->pa_ht)) $this->pa_ht=0;
+
+ // si prix d'achat non renseigné et utilisé pour calcul des marges alors prix achat = prix vente (idem pour remises)
+ if ($this->pa_ht == 0) {
+ if ($this->subprice < 0 || ($conf->global->CalculateMarginsOnLinesWithoutBuyingPrice == 1))
+ $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100);
+ }
+
$this->db->begin();
// Mise a jour ligne en base
@@ -3089,6 +3132,8 @@ class OrderLine
$sql.= " , total_tva=".price2num($this->total_tva)."";
$sql.= " , total_ttc=".price2num($this->total_ttc)."";
}
+ $sql.= " , fk_product_fournisseur_price='".$this->fk_fournprice."'";
+ $sql.= " , buy_price_ht='".price2num($this->pa_ht)."'";
$sql.= " , total_localtax1=".price2num($this->total_localtax1);
$sql.= " , total_localtax2=".price2num($this->total_localtax2);
$sql.= " , info_bits=".$this->info_bits;
diff --git a/htdocs/commande/fiche.php b/htdocs/commande/fiche.php
index 459b2f1540f..4c5b0d57fa8 100644
--- a/htdocs/commande/fiche.php
+++ b/htdocs/commande/fiche.php
@@ -49,6 +49,8 @@ $langs->load('bills');
$langs->load('propal');
$langs->load('deliveries');
$langs->load('products');
+if ($conf->marges->enabled)
+ $langs->load('marges');
$id = (GETPOST('id','int')?GETPOST('id','int'):GETPOST("orderid"));
$ref = GETPOST('ref');
@@ -294,7 +296,9 @@ else if ($action == 'add' && $user->rights->commande->creer)
$product_type,
$lines[$i]->rang,
$lines[$i]->special_code,
- $fk_parent_line
+ $fk_parent_line,
+ $lines[$i]->fk_fournprice,
+ $lines[$i]->pa_ht
);
if ($result < 0)
@@ -607,6 +611,13 @@ else if ($action == 'addline' && $user->rights->commande->creer)
$desc=dol_htmlcleanlastbr($desc);
+ // ajout prix achat
+ $fk_fournprice = $_POST['np_fournprice'];
+ if ( ! empty($_POST['np_buying_price']) )
+ $pa_ht = $_POST['np_buying_price'];
+ else
+ $pa_ht = null;
+
$info_bits=0;
if ($tva_npr) $info_bits |= 0x01;
@@ -639,7 +650,9 @@ else if ($action == 'addline' && $user->rights->commande->creer)
$type,
-1,
'',
- $_POST['fk_parent_line']
+ $_POST['fk_parent_line'],
+ $fk_fournprice,
+ $pa_ht
);
if ($result > 0)
@@ -668,6 +681,7 @@ else if ($action == 'addline' && $user->rights->commande->creer)
unset($_POST['np_desc']);
unset($_POST['np_price']);
unset($_POST['np_tva_tx']);
+ unset($_POST['np_buying_price']);
}
else
{
@@ -701,6 +715,14 @@ else if ($action == 'updateligne' && $user->rights->commande->creer && $_POST['s
$localtax1_rate=get_localtax($vat_rate,1,$object->client);
$localtax2_rate=get_localtax($vat_rate,2,$object->client);
+
+ // ajout prix d'achat
+ $fk_fournprice = $_POST['fournprice'];
+ if ( ! empty($_POST['buying_price']) )
+ $pa_ht = $_POST['buying_price'];
+ else
+ $pa_ht = null;
+
// Check parameters
if (empty($_POST['productid']) && $_POST["type"] < 0)
{
@@ -749,7 +771,10 @@ else if ($action == 'updateligne' && $user->rights->commande->creer && $_POST['s
$date_start,
$date_end,
$type,
- $_POST['fk_parent_line']
+ $_POST['fk_parent_line'],
+ 0,
+ $fk_fournprice,
+ $pa_ht
);
if ($result >= 0)
@@ -768,6 +793,12 @@ else if ($action == 'updateligne' && $user->rights->commande->creer && $_POST['s
{
$ret=$object->fetch($object->id); // Reload to get new records
commande_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
+ unset($_POST['qty']);
+ unset($_POST['type']);
+ unset($_POST['np_price']);
+ unset($_POST['dp_desc']);
+ unset($_POST['np_tva_tx']);
+ unset($_POST['np_buying_price']);
}
}
else
@@ -1955,7 +1986,15 @@ else
// Total HT
print ''.$langs->trans('AmountHT').' ';
print ''.price($object->total_ht).' ';
- print ''.$langs->trans('Currency'.$conf->currency).' ';
+ print ''.$langs->trans('Currency'.$conf->currency).' ';
+
+ // Margin Infos
+ if ($conf->marges->enabled) {
+ print '';
+ $object->displayMarginInfos();
+ print ' ';
+ }
+ print '';
// Total TVA
print ''.$langs->trans('AmountVAT').' '.price($object->total_tva).' ';
diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php
index 5ff20189268..5d306dd6977 100644
--- a/htdocs/compta/facture.php
+++ b/htdocs/compta/facture.php
@@ -51,6 +51,8 @@ $langs->load('bills');
$langs->load('companies');
$langs->load('products');
$langs->load('main');
+if ($conf->marges->enabled)
+ $langs->load('marges');
$mesg='';
$errors=array();
@@ -863,7 +865,9 @@ else if ($action == 'add' && $user->rights->facture->creer)
$lines[$i]->special_code,
$object->origin,
$lines[$i]->rowid,
- $fk_parent_line
+ $fk_parent_line,
+ $lines[$i]->fk_fournprice,
+ $lines[$i]->pa_ht
);
if ($result > 0)
@@ -1072,6 +1076,13 @@ else if (($action == 'addline' || $action == 'addline_predef') && $user->rights-
$localtax1_tx=get_localtax($tva_tx,1,$object->client);
$localtax2_tx=get_localtax($tva_tx,2,$object->client);
+ // ajout prix achat
+ $fk_fournprice = $_POST['np_fournprice'];
+ if ( ! empty($_POST['np_buying_price']) )
+ $pa_ht = $_POST['np_buying_price'];
+ else
+ $pa_ht = null;
+
$info_bits=0;
if ($tva_npr) $info_bits |= 0x01;
@@ -1107,7 +1118,9 @@ else if (($action == 'addline' || $action == 'addline_predef') && $user->rights-
0,
'',
0,
- GETPOST('fk_parent_line')
+ GETPOST('fk_parent_line'),
+ $fk_fournprice,
+ $pa_ht
);
}
}
@@ -1138,6 +1151,7 @@ else if (($action == 'addline' || $action == 'addline_predef') && $user->rights-
unset($_POST['np_desc']);
unset($_POST['np_price']);
unset($_POST['np_tva_tx']);
+ unset($_POST['np_buying_price']);
}
else
{
@@ -1170,6 +1184,13 @@ else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['sa
$localtax1_rate=get_localtax($vat_rate,1,$object->client);
$localtax2_rate=get_localtax($vat_rate,2,$object->client);
+ // ajout prix d'achat
+ $fk_fournprice = $_POST['fournprice'];
+ if ( ! empty($_POST['buying_price']) )
+ $pa_ht = $_POST['buying_price'];
+ else
+ $pa_ht = null;
+
// Check parameters
if (! GETPOST('productid') && GETPOST("type") < 0)
{
@@ -1214,7 +1235,10 @@ else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['sa
'HT',
$info_bits,
$type,
- GETPOST('fk_parent_line')
+ GETPOST('fk_parent_line'),
+ 0,
+ $fk_fournprice,
+ $pa_ht
);
// Define output language
@@ -1231,6 +1255,13 @@ else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['sa
{
$ret=$object->fetch($id); // Reload to get new records
facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref, $hookmanager);
+
+ unset($_POST['qty']);
+ unset($_POST['type']);
+ unset($_POST['np_price']);
+ unset($_POST['dp_desc']);
+ unset($_POST['np_tva_tx']);
+ unset($_POST['np_buying_price']);
}
}
}
@@ -2734,6 +2765,12 @@ else if ($id > 0 || ! empty($ref))
print '';
+ // Margin Infos
+ if ($conf->marges->enabled) {
+ print ' ';
+ $object->displayMarginInfos($object->statut > 0);
+ }
+
print ' ';
// Date payment term
@@ -2810,7 +2847,9 @@ else if ($id > 0 || ! empty($ref))
print ''.price($object->total_ht).' ';
print ''.$langs->trans('Currency'.$conf->currency).' ';
print ''.$langs->trans('AmountVAT').' '.price($object->total_tva).' ';
- print ''.$langs->trans('Currency'.$conf->currency).' ';
+ print ''.$langs->trans('Currency'.$conf->currency).' ';
+
+ print '';
// Amount Local Taxes
if ($mysoc->pays_code=='ES')
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index f4cba88828b..7f2ebbafd8a 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -8,6 +8,7 @@
* Copyright (C) 2006 Andre Cianfarani
* Copyright (C) 2007 Franky Van Liedekerke
* Copyright (C) 2010-2011 Juanjo Menent
+ * Copyright (C) 2012 Christophe Battarel
*
* 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
@@ -33,6 +34,8 @@ include_once(DOL_DOCUMENT_ROOT."/core/class/commoninvoice.class.php");
require_once(DOL_DOCUMENT_ROOT ."/product/class/product.class.php");
require_once(DOL_DOCUMENT_ROOT ."/societe/class/client.class.php");
+require_once(DOL_DOCUMENT_ROOT ."/marges/lib/marges.lib.php");
+
/**
* Class to manage invoices
@@ -358,7 +361,9 @@ class Facture extends CommonInvoice
$this->lines[$i]->special_code,
'',
0,
- $fk_parent_line
+ $fk_parent_line,
+ $this->lines[$i]->fk_fournprice,
+ $this->lines[$i]->pa_ht
);
if ($result < 0)
{
@@ -880,7 +885,7 @@ class Facture extends CommonInvoice
$sql.= ' l.localtax1_tx, l.localtax2_tx, l.remise, l.remise_percent, l.fk_remise_except, l.subprice,';
$sql.= ' l.rang, l.special_code,';
$sql.= ' l.date_start as date_start, l.date_end as date_end,';
- $sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_export_compta,';
+ $sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_export_compta, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,';
$sql.= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
$sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l';
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
@@ -926,6 +931,11 @@ class Facture extends CommonInvoice
$line->total_ttc = $objp->total_ttc;
$line->export_compta = $objp->fk_export_compta;
$line->code_ventilation = $objp->fk_code_ventilation;
+ $line->fk_fournprice = $objp->fk_fournprice;
+ $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
+ $line->pa_ht = $marginInfos[0];
+ $line->marge_tx = $marginInfos[1];
+ $line->marque_tx = $marginInfos[2];
$line->rang = $objp->rang;
$line->special_code = $objp->special_code;
$line->fk_parent_line = $objp->fk_parent_line;
@@ -1858,7 +1868,7 @@ class Facture extends CommonInvoice
* @param int $fk_parent_line Id of parent line
* @return int <0 if KO, Id of line if OK
*/
- function addline($facid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0)
+ function addline($facid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht = 0)
{
dol_syslog(get_class($this)."::Addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product,remise_percent=$remise_percent,date_start=$date_start,date_end=$date_end,ventil=$ventil,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type", LOG_DEBUG);
include_once(DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php');
@@ -1878,6 +1888,7 @@ class Facture extends CommonInvoice
$qty=price2num($qty);
$pu_ht=price2num($pu_ht);
$pu_ttc=price2num($pu_ttc);
+ $pa_ht=price2num($pa_ht);
$txtva=price2num($txtva);
$txlocaltax1=price2num($txlocaltax1);
$txlocaltax2=price2num($txlocaltax2);
@@ -1964,6 +1975,10 @@ class Facture extends CommonInvoice
$this->line->origin=$origin;
$this->line->origin_id=$origin_id;
+ // infos marge
+ $this->line->fk_fournprice = $fk_fournprice;
+ $this->line->pa_ht = $pa_ht;
+
// TODO Ne plus utiliser
//$this->line->price=($this->type==2?-1:1)*abs($price);
//$this->line->remise=($this->type==2?-1:1)*abs($remise);
@@ -2019,7 +2034,7 @@ class Facture extends CommonInvoice
* @param int $skip_update_total ???
* @return int < 0 if KO, > 0 if OK
*/
- function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type=0, $fk_parent_line=0, $skip_update_total=0)
+ function updateline($rowid, $desc, $pu, $qty, $remise_percent=0, $date_start, $date_end, $txtva, $txlocaltax1=0, $txlocaltax2=0,$price_base_type='HT', $info_bits=0, $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht = 0)
{
include_once(DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php');
@@ -2036,6 +2051,7 @@ class Facture extends CommonInvoice
$remise_percent = price2num($remise_percent);
$qty = price2num($qty);
$pu = price2num($pu);
+ $pa_ht = price2num($pa_ht);
$txtva = price2num($txtva);
$txlocaltax1 = price2num($txlocaltax1);
$txlocaltax2 = price2num($txlocaltax2);
@@ -2101,6 +2117,10 @@ class Facture extends CommonInvoice
$this->line->fk_parent_line = $fk_parent_line;
$this->line->skip_update_total = $skip_update_total;
+ // infos marge
+ $this->line->fk_fournprice = $fk_fournprice;
+ $this->line->pa_ht = $pa_ht;
+
// A ne plus utiliser
//$this->line->price=$price;
//$this->line->remise=$remise;
@@ -2988,7 +3008,7 @@ class Facture extends CommonInvoice
$sql = 'SELECT l.rowid, l.description, l.fk_product, l.product_type, l.qty, l.tva_tx,';
$sql.= ' l.fk_remise_except,';
$sql.= ' l.remise_percent, l.subprice, l.info_bits, l.rang, l.special_code,';
- $sql.= ' l.total_ht, l.total_tva, l.total_ttc,';
+ $sql.= ' l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,';
$sql.= ' l.date_start,';
$sql.= ' l.date_end,';
$sql.= ' l.product_type,';
@@ -3030,6 +3050,11 @@ class Facture extends CommonInvoice
$this->lines[$i]->rang = $obj->rang;
$this->lines[$i]->date_start = $this->db->jdate($obj->date_start);
$this->lines[$i]->date_end = $this->db->jdate($obj->date_end);
+ $this->lines[$i]->fk_fournprice = $obj->fk_fournprice;
+ $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->lines[$i]->fk_fournprice, $obj->pa_ht);
+ $this->lines[$i]->pa_ht = $marginInfos[0];
+ $this->lines[$i]->marge_tx = $marginInfos[1];
+ $this->lines[$i]->marque_tx = $marginInfos[2];
$i++;
}
@@ -3080,6 +3105,11 @@ class FactureLigne
var $remise_percent; // % de la remise ligne (example 20%)
var $fk_remise_except; // Link to line into llx_remise_except
var $rang = 0;
+
+ var $fk_fournprice;
+ var $pa_ht;
+ var $marge_tx;
+ var $marque_tx;
var $info_bits = 0; // Liste d'options cumulables:
// Bit 0: 0 si TVA normal - 1 si TVA NPR
@@ -3142,7 +3172,7 @@ class FactureLigne
{
$sql = 'SELECT fd.rowid, fd.fk_facture, fd.fk_parent_line, fd.fk_product, fd.product_type, fd.description, fd.price, fd.qty, fd.tva_tx,';
$sql.= ' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice,';
- $sql.= ' fd.date_start as date_start, fd.date_end as date_end,';
+ $sql.= ' fd.date_start as date_start, fd.date_end as date_end, fd.fk_product_fournisseur_price as fk_fournprice, fd.buy_price_ht as pa_ht,';
$sql.= ' fd.info_bits, fd.total_ht, fd.total_tva, fd.total_ttc, fd.total_localtax1, fd.total_localtax2, fd.rang,';
$sql.= ' fd.fk_code_ventilation, fd.fk_export_compta,';
$sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc';
@@ -3179,6 +3209,11 @@ class FactureLigne
$this->fk_code_ventilation = $objp->fk_code_ventilation;
$this->fk_export_compta = $objp->fk_export_compta;
$this->rang = $objp->rang;
+ $this->fk_fournprice = $objp->fk_fournprice;
+ $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
+ $this->pa_ht = $marginInfos[0];
+ $this->marge_tx = $marginInfos[1];
+ $this->marque_tx = $marginInfos[2];
// Ne plus utiliser
//$this->price = $objp->price;
@@ -3228,6 +3263,15 @@ class FactureLigne
if (empty($this->special_code)) $this->special_code=0;
if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
+
+ if (empty($this->pa_ht)) $this->pa_ht=0;
+
+ // si prix d'achat non renseigné et utilisé pour calcul des marges alors prix achat = prix vente (idem pour remises)
+ if ($this->pa_ht == 0) {
+ if ($this->subprice < 0 || ($conf->global->CalculateMarginsOnLinesWithoutBuyingPrice == 1))
+ $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100);
+ }
+
// Check parameters
if ($this->product_type < 0) return -1;
@@ -3238,7 +3282,7 @@ class FactureLigne
$sql.= ' (fk_facture, fk_parent_line, description, qty, tva_tx, localtax1_tx, localtax2_tx,';
$sql.= ' fk_product, product_type, remise_percent, subprice, fk_remise_except,';
$sql.= ' date_start, date_end, fk_code_ventilation, fk_export_compta, ';
- $sql.= ' rang, special_code,';
+ $sql.= ' rang, special_code, fk_product_fournisseur_price, buy_price_ht,';
$sql.= ' info_bits, total_ht, total_tva, total_ttc, total_localtax1, total_localtax2)';
$sql.= " VALUES (".$this->fk_facture.",";
$sql.= " ".($this->fk_parent_line>0?"'".$this->fk_parent_line."'":"null").",";
@@ -3264,6 +3308,10 @@ class FactureLigne
$sql.= ' '.$this->fk_export_compta.',';
$sql.= ' '.$this->rang.',';
$sql.= ' '.$this->special_code.',';
+ if (isset($this->fk_fournprice)) $sql.= ' '.$this->fk_fournprice.',';
+ else $sql.= ' null,';
+ if (isset($this->pa_ht)) $sql.= ' '.price2num($this->pa_ht).',';
+ else $sql.= ' null,';
$sql.= " '".$this->info_bits."',";
$sql.= " ".price2num($this->total_ht).",";
$sql.= " ".price2num($this->total_tva).",";
@@ -3378,6 +3426,14 @@ class FactureLigne
// Check parameters
if ($this->product_type < 0) return -1;
+ if (empty($this->pa_ht)) $this->pa_ht=0;
+
+ // si prix d'achat non renseigné et utilisé pour calcul des marges alors prix achat = prix vente (idem pour remises)
+ if ($this->pa_ht == 0) {
+ if ($this->subprice < 0 || ($conf->global->CalculateMarginsOnLinesWithoutBuyingPrice == 1))
+ $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100);
+ }
+
$this->db->begin();
// Mise a jour ligne en base
@@ -3405,6 +3461,8 @@ class FactureLigne
$sql.= ",total_tva=".price2num($this->total_tva)."";
$sql.= ",total_ttc=".price2num($this->total_ttc)."";
}
+ $sql.= " , fk_product_fournisseur_price='".$this->fk_fournprice."'";
+ $sql.= " , buy_price_ht='".price2num($this->pa_ht)."'";
$sql.= ",total_localtax1=".price2num($this->total_localtax1)."";
$sql.= ",total_localtax2=".price2num($this->total_localtax2)."";
$sql.= ",fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null");
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 31125a8eadc..0685fde414b 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -2533,6 +2533,16 @@ abstract class CommonObject
print ''.$langs->trans('PriceUHT').' ';
print ''.$langs->trans('Qty').' ';
print ''.$langs->trans('ReductionShort').' ';
+ if ($conf->marges->enabled) {
+ if ($conf->global->MARGIN_TYPE == "1")
+ print ''.$langs->trans('BuyingPrice').' ';
+ else
+ print ''.$langs->trans('BuyingCost').' ';
+ if($conf->global->DISPLAY_MARGIN_RATES)
+ print ''.$langs->trans('MarginRate').' ';
+ if($conf->global->DISPLAY_MARK_RATES)
+ print ''.$langs->trans('MarkRate').' ';
+ }
print ''.$langs->trans('TotalHTShort').' ';
print ' ';
print ' ';
@@ -2829,6 +2839,148 @@ abstract class CommonObject
if ($res) break;
}
}
+
+
+
+ function getMarginInfos($force_price=false) {
+ global $conf;
+ require_once(DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php');
+ $marginInfos = array(
+ 'pa_products' => 0,
+ 'pv_products' => 0,
+ 'margin_on_products' => 0,
+ 'margin_rate_products' => '',
+ 'mark_rate_products' => '',
+ 'pa_services' => 0,
+ 'pv_services' => 0,
+ 'margin_on_services' => 0,
+ 'margin_rate_services' => '',
+ 'mark_rate_services' => '',
+ 'pa_total' => 0,
+ 'pv_total' => 0,
+ 'total_margin' => 0,
+ 'total_margin_rate' => '',
+ 'total_mark_rate' => ''
+ );
+ foreach($this->lines as $line) {
+ if (isset($line->fk_fournprice) && !$force_price) {
+ $product = new ProductFournisseur($this->db);
+ if ( $product->fetch_product_fournisseur_price($line->fk_fournprice))
+ $line->pa_ht = $product->fourn_unitprice;
+ if ($conf->global->MARGIN_TYPE == "2" && $product->fourn_unitcharges > 0)
+ $line->pa_ht += $product->fourn_unitcharges;
+ }
+ // si prix d'achat non renseigné et devrait l'être, alors prix achat = prix vente
+ if ((!isset($line->pa_ht) || $line->pa_ht == 0) && ($conf->global->ForceBuyingPriceIfNull == 1)) {
+ $line->pa_ht = $line->subprice * (1 - ($line->remise_percent / 100));
+ }
+
+ // calcul des marges
+ if(isset($line->fk_remise_except)) { // remise
+ if ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '1') { // remise globale considérée comme produit
+ $marginInfos['pa_products'] += ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
+ $marginInfos['pv_products'] += $line->subprice * (1 - $line->remise_percent / 100);
+ $marginInfos['pa_total'] += ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
+ $marginInfos['pv_total'] += $line->subprice * (1 - $line->remise_percent / 100);
+ }
+ elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '2') { // remise globale considérée comme service
+ $marginInfos['pa_services'] += ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
+ $marginInfos['pv_services'] += $line->subprice * (1 - ($line->remise_percent / 100));
+ $marginInfos['pa_total'] += ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
+ $marginInfos['pv_total'] += $line->subprice * (1 - $line->remise_percent / 100);
+ }
+ elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '3') { // remise globale prise en compte uniqt sur total
+ $marginInfos['pa_total'] += ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100);
+ $marginInfos['pv_total'] += $line->subprice * (1 - ($line->remise_percent / 100));
+ }
+ }
+ else {
+ $type=$line->product_type?$line->product_type:$line->fk_product_type;
+ if ($type == 0) { // product
+ $marginInfos['pa_products'] += $line->qty * $line->pa_ht;
+ $marginInfos['pv_products'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100);
+ $marginInfos['pa_total'] += $line->qty * $line->pa_ht;
+ $marginInfos['pv_total'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100);
+ }
+ elseif ($type == 1) { // service
+ $marginInfos['pa_services'] += $line->qty * $line->pa_ht;
+ $marginInfos['pv_services'] += $line->qty * $line->subprice * (1 - ($line->remise_percent / 100));
+ $marginInfos['pa_total'] += $line->qty * $line->pa_ht;
+ $marginInfos['pv_total'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100);
+ }
+ }
+ }
+
+ $marginInfos['margin_on_products'] = $marginInfos['pv_products'] - $marginInfos['pa_products'];
+ if ($marginInfos['pa_products'] > 0)
+ $marginInfos['margin_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pa_products'],5);
+ if ($marginInfos['pv_products'] > 0)
+ $marginInfos['mark_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pv_products'],5);
+
+ $marginInfos['margin_on_services'] = $marginInfos['pv_services'] - $marginInfos['pa_services'];
+ if ($marginInfos['pa_services'] > 0)
+ $marginInfos['margin_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pa_services'],5);
+ if ($marginInfos['pv_services'] > 0)
+ $marginInfos['mark_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pv_services'],5);
+
+
+ $marginInfos['total_margin'] = $marginInfos['pv_total'] - $marginInfos['pa_total'];
+ if ($marginInfos['pa_total'] > 0)
+ $marginInfos['total_margin_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pa_total'],5);
+ if ($marginInfos['pv_total'] > 0)
+ $marginInfos['total_mark_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pv_total'],5);
+
+ return $marginInfos;
+ }
+
+ function displayMarginInfos($force_price=false) {
+ global $langs, $conf;
+ $marginInfo = $this->getMarginInfos($force_price);
+ print '';
+ print '';
+ print ''.$langs->trans('Margins').' ';
+ print ''.$langs->trans('SellingPrice').' ';
+ print ''.$langs->trans('BuyingPrice').' ';
+ print ''.$langs->trans('Margin').' ';
+ if($conf->global->DISPLAY_MARGIN_RATES)
+ print ''.$langs->trans('MarginRate').' ';
+ if($conf->global->DISPLAY_MARK_RATES)
+ print ''.$langs->trans('MarkRate').' ';
+ print ' ';
+ if ($marginInfo['margin_on_products'] != 0 && $marginInfo['margin_on_services'] != 0) {
+ print '';
+ print ''.$langs->trans('MarginOnProducts').' ';
+ print ''.price($marginInfo['pv_products']).' ';
+ print ''.price($marginInfo['pa_products']).' ';
+ print ''.price($marginInfo['margin_on_products']).' ';
+ if($conf->global->DISPLAY_MARGIN_RATES)
+ print ''.(($marginInfo['margin_rate_products'] == '')?'n/a':price($marginInfo['margin_rate_products']).'%').' ';
+ if($conf->global->DISPLAY_MARK_RATES)
+ print ''.(($marginInfo['mark_rate_products'] == '')?'n/a':price($marginInfo['mark_rate_products']).'%').' ';
+ print ' ';
+ print '';
+ print ''.$langs->trans('MarginOnServices').' ';
+ print ''.price($marginInfo['pv_services']).' ';
+ print ''.price($marginInfo['pa_services']).' ';
+ print ''.price($marginInfo['margin_on_services']).' ';
+ if($conf->global->DISPLAY_MARGIN_RATES)
+ print ''.(($marginInfo['margin_rate_services'] == '')?'n/a':price($marginInfo['margin_rate_services']).'%').' ';
+ if($conf->global->DISPLAY_MARK_RATES)
+ print ''.(($marginInfo['mark_rate_services'] == '')?'n/a':price($marginInfo['mark_rate_services']).'%').' ';
+ print ' ';
+ }
+ print '';
+ print ''.$langs->trans('TotalMargin').' ';
+ print ''.price($marginInfo['pv_total']).' ';
+ print ''.price($marginInfo['pa_total']).' ';
+ print ''.price($marginInfo['total_margin']).' ';
+ if($conf->global->DISPLAY_MARGIN_RATES)
+ print ''.(($marginInfo['total_margin_rate'] == '')?'n/a':price($marginInfo['total_margin_rate']).'%').' ';
+ if($conf->global->DISPLAY_MARK_RATES)
+ print ''.(($marginInfo['total_mark_rate'] == '')?'n/a':price($marginInfo['total_mark_rate']).'%').' ';
+ print ' ';
+ print '
';
+ }
}
?>
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index 2ef140e2ced..f94797cb679 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -2683,9 +2683,14 @@ class Form
* @param string $page Page
* @param string $selected Id preselected
* @param string $htmlname Name of HTML select
+ * @param string $filter Optionnal filters criteras
+ * @param int $showempty Add an empty field
+ * @param int $showtype Show third party type in combolist (customer, prospect or supplier)
+ * @param int $forcecombo Force to use combo box
+ * @param array $event Event options
* @return void
*/
- function form_thirdparty($page, $selected='', $htmlname='socid')
+ function form_thirdparty($page, $selected='', $htmlname='socid', $filter='',$showempty=0, $showtype=0, $forcecombo=0, $event=array())
{
global $langs;
@@ -2696,7 +2701,7 @@ class Form
print ' ';
print '';
diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php
index 1eec9ff53be..21f6c427471 100644
--- a/htdocs/core/lib/ajax.lib.php
+++ b/htdocs/core/lib/ajax.lib.php
@@ -1,6 +1,7 @@
* Copyright (C) 2007-2012 Regis Houssin
+ * Copyright (C) 2012 Christophe Battarel
*
* 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
@@ -48,7 +49,7 @@ function ajax_autocompleter($selected,$htmlname,$url,$option='',$minLength=2,$au
if (this.value.length == 0)
{
jQuery("#search_'.$htmlname.'").val("");
- jQuery("#'.$htmlname.'").val("");
+ jQuery("#'.$htmlname.'").val("").trigger("change");
}
});
jQuery("input#search_'.$htmlname.'").autocomplete({
@@ -57,7 +58,7 @@ function ajax_autocompleter($selected,$htmlname,$url,$option='',$minLength=2,$au
response( jQuery.map( data, function( item ) {
if (autoselect == 1 && data.length == 1) {
jQuery("#search_'.$htmlname.'").val(item.value);
- jQuery("#'.$htmlname.'").val(item.key);
+ jQuery("#'.$htmlname.'").val(item.key).trigger("change");
}
var label = item.label.toString();
return { label: label, value: item.value, id: item.key}
@@ -67,7 +68,7 @@ function ajax_autocompleter($selected,$htmlname,$url,$option='',$minLength=2,$au
dataType: "json",
minLength: '.$minLength.',
select: function( event, ui ) {
- jQuery("#'.$htmlname.'").val(ui.item.id);
+ jQuery("#'.$htmlname.'").val(ui.item.id).trigger("change");
}
}).data( "autocomplete" )._renderItem = function( ul, item ) {
return jQuery( " " )
diff --git a/htdocs/core/modules/modMarges.class.php b/htdocs/core/modules/modMarges.class.php
new file mode 100644
index 00000000000..413578597ce
--- /dev/null
+++ b/htdocs/core/modules/modMarges.class.php
@@ -0,0 +1,227 @@
+
+ *
+ * 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.
+ */
+
+/** \defgroup mymodule Module MyModule
+ * \brief Example of a module descriptor.
+ * Such a file must be copied into htdocs/includes/module directory.
+ */
+
+/**
+ * \file htdocs/includes/modules/modMyModule.class.php
+ * \ingroup mymodule
+ * \brief Description and activation file for module MyModule
+ * \version $Id: modMyModule.class.php,v 1.26 2008/12/15 18:27:00 eldy Exp $
+ */
+include_once(DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php");
+
+
+/** \class modMyModule
+ * \brief Description and activation class for module MyModule
+ */
+class modMarges extends DolibarrModules
+{
+ /**
+ * \brief Constructor. Define names, constants, directories, boxes, permissions
+ * \param DB Database handler
+ */
+ function modMarges($DB)
+ {
+ $this->db = $DB;
+
+ // Id for module (must be unique).
+ // Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
+ $this->numero = 59000;
+ // Key text used to identify module (for permissions, menus, etc...)
+ $this->rights_class = 'Marges';
+
+ // Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
+ // It is used to group modules in module setup page
+ $this->family = "financial";
+ // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
+ $this->name = mb_ereg_replace('^mod','',get_class($this), "i");
+ // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
+ $this->description = "Gestion des marges";
+ // Possible values for version are: 'development', 'experimental', 'dolibarr' or version
+ $this->version = '2.0';
+ // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase)
+ $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
+ // Where to store the module in setup page (0=common,1=interface,2=other)
+ $this->special = 0;
+ // Name of png file (without png) used for this module.
+ // Png file must be in theme/yourtheme/img directory under name object_pictovalue.png.
+ $this->picto='marges@marges';
+
+ // Data directories to create when module is enabled.
+ $this->dirs = array();
+ //$this->dirs[0] = DOL_DATA_ROOT.'/Marges';
+ //$this->dirs[1] = DOL_DATA_ROOT.'/mymodule/temp;
+
+ // Relative path to module style sheet if exists. Example: '/mymodule/mycss.css'.
+ $this->style_sheet = '/custom/marges/css/marges.css';
+
+ // Config pages. Put here list of php page names stored in admmin directory used to setup module.
+ $this->config_page_url = array("marges.php");
+
+ // Dependencies
+ $this->depends = array("modPropale", "modProduct"); // List of modules id that must be enabled if this module is enabled
+ $this->requiredby = array(); // List of modules id to disable if this one is disabled
+ $this->phpmin = array(4,1); // Minimum version of PHP required by module
+ $this->need_dolibarr_version = array(3,1); // Minimum version of Dolibarr required by module
+ $this->langfiles = array("marges");
+
+ // Constants
+ $this->const = array(); // List of particular constants to add when module is enabled
+ //$this->const = array( 0=>array('MAIN_MODULE_MARGES_HOOKS', 'chaine', 'propalcard', 'Hooks list for displaying Marges data on entity lists', 0, 'current', 1) );
+
+ // New pages on tabs
+ $this->tabs = array(
+ 'product:+marges:Marges:marges:/marges/tabs/productMargins.php?id=__ID__',
+ 'thirdparty:+marges:Marges:marges:/marges/tabs/thirdpartyMargins.php?socid=__ID__',
+ );
+
+
+ // Boxes
+ $this->boxes = array(); // List of boxes
+ $r=0;
+
+ // Add here list of php file(s) stored in includes/boxes that contains class to show a box.
+ // Example:
+ //$this->boxes[$r][1] = "myboxa.php";
+ //$r++;
+ //$this->boxes[$r][1] = "myboxb.php";
+ //$r++;
+
+
+ // Permissions
+ $this->rights = array(); // Permission array used by this module
+ $r=0;
+
+ // Add here list of permission defined by an id, a label, a boolean and two constant strings.
+ // Example:
+ // $this->rights[$r][0] = 2000; // Permission id (must not be already used)
+ // $this->rights[$r][1] = 'Permision label'; // Permission label
+ // $this->rights[$r][3] = 1; // Permission by default for new user (0/1)
+ // $this->rights[$r][4] = 'level1'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
+ // $this->rights[$r][5] = 'level2'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
+ // $r++;
+
+
+ // Main menu entries
+ $this->menu = array(); // List of menus to add
+ $r = 0;
+
+ // left menu entry
+ $this->menu[$r]=array( 'fk_menu'=>0, // Put 0 if this is a top menu
+ 'type'=>'top', // This is a Top menu entry
+ 'titre'=>'Margins',
+ 'mainmenu'=>'margins',
+ 'leftmenu'=>'1', // Use 1 if you also want to add left menu entries using this descriptor. Use 0 if left menu entries are defined in a file pre.inc.php (old school).
+ 'url'=>'/marges/index.php',
+ 'langs'=>'marges', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position'=>100,
+ 'enabled'=>'1', // Define condition to show or hide menu entry. Use '$conf->monmodule->enabled' if entry must be visible if module is enabled.
+ 'perms'=>'1', // Use 'perms'=>'$user->rights->monmodule->level1->level2' if you want your menu with a permission rules
+ 'target'=>'',
+ 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both
+ $r++;
+
+ // top menu entry
+ $this->menu[$r]=array( 'fk_menu'=>'r=0', // Use r=value where r is index key used for the parent menu entry (higher parent must be a top menu entry)
+ 'type'=>'left', // This is a Left menu entry
+ 'titre'=>'ProductMargins',
+ 'mainmenu'=>'margins',
+ 'url'=>'/marges/productMargins.php',
+ 'langs'=>'marges', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position'=>100,
+ 'enabled'=>'1', // Define condition to show or hide menu entry. Use '$conf->monmodule->enabled' if entry must be visible if module is enabled.
+ 'perms'=>'1', // Use 'perms'=>'$user->rights->monmodule->level1->level2' if you want your menu with a permission rules
+ 'target'=>'',
+ 'user'=>2); // 0=Menu for internal users,1=external users, 2=both
+ $r++;
+
+ $this->menu[$r]=array( 'fk_menu'=>'r=0', // Use r=value where r is index key used for the parent menu entry (higher parent must be a top menu entry)
+ 'type'=>'left', // This is a Left menu entry
+ 'titre'=>'CustomerMargins',
+ 'mainmenu'=>'margins',
+ 'url'=>'/marges/customerMargins.php',
+ 'langs'=>'marges', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position'=>200,
+ 'enabled'=>'1', // Define condition to show or hide menu entry. Use '$conf->monmodule->enabled' if entry must be visible if module is enabled.
+ 'perms'=>'1', // Use 'perms'=>'$user->rights->monmodule->level1->level2' if you want your menu with a permission rules
+ 'target'=>'',
+ 'user'=>2); // 0=Menu for internal users,1=external users, 2=both
+ $r++;
+
+ $this->menu[$r]=array( 'fk_menu'=>'r=0', // Use r=value where r is index key used for the parent menu entry (higher parent must be a top menu entry)
+ 'type'=>'left', // This is a Left menu entry
+ 'titre'=>'AgentMargins',
+ 'mainmenu'=>'margins',
+ 'url'=>'/marges/agentMargins.php',
+ 'langs'=>'marges', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position'=>300,
+ 'enabled'=>'1', // Define condition to show or hide menu entry. Use '$conf->monmodule->enabled' if entry must be visible if module is enabled.
+ 'perms'=>'1', // Use 'perms'=>'$user->rights->monmodule->level1->level2' if you want your menu with a permission rules
+ 'target'=>'',
+ 'user'=>2); // 0=Menu for internal users,1=external users, 2=both
+ $r++;
+
+ }
+
+ /**
+ * \brief Function called when module is enabled.
+ * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
+ * It also creates data directories.
+ * \return int 1 if OK, 0 if KO
+ */
+ function init()
+ {
+ $sql = array();
+
+ $result=$this->load_tables();
+
+ return $this->_init($sql);
+ }
+
+ /**
+ * \brief Function called when module is disabled.
+ * Remove from database constants, boxes and permissions from Dolibarr database.
+ * Data directories are not deleted.
+ * \return int 1 if OK, 0 if KO
+ */
+ function remove()
+ {
+ $sql = array();
+
+ return $this->_remove($sql);
+ }
+
+
+ /**
+ * \brief Create tables and keys required by module
+ * Files mymodule.sql and mymodule.key.sql with create table and create keys
+ * commands must be stored in directory /mymodule/sql/
+ * This function is called by this->init.
+ * \return int <=0 if KO, >0 if OK
+ */
+ function load_tables()
+ {
+ //return $this->_load_tables('/marges/sql/');
+ }
+}
+
+?>
diff --git a/htdocs/core/tpl/freeproductline_create.tpl.php b/htdocs/core/tpl/freeproductline_create.tpl.php
index 18f76aa105d..aaca8feab4e 100644
--- a/htdocs/core/tpl/freeproductline_create.tpl.php
+++ b/htdocs/core/tpl/freeproductline_create.tpl.php
@@ -1,6 +1,7 @@
* Copyright (C) 2010-2011 Laurent Destailleur
+ * Copyright (C) 2012 Christophe Battarel
*
* 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
@@ -22,7 +23,7 @@
* $dateSelector
* $this (invoice, order, ...)
* $line defined
- */
+ */
?>
@@ -32,7 +33,19 @@
trans('PriceUHT'); ?>
trans('Qty'); ?>
trans('ReductionShort'); ?>
-
+marges->enabled) {
+?>
+ trans('BuyingPrice'); ?>
+global->DISPLAY_MARGIN_RATES)
+ $colspan++;
+ if($conf->global->DISPLAY_MARK_RATES)
+ $colspan++;
+}
+?>
+