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 ''; + +print ''."\n"; +print ''."\n"; +print ''; + +$var=true; +$form = new Form($db); + +// GLOBAL DISCOUNT MANAGEMENT +$var=!$var; +print ""; +print ''; +print ""; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +// DISPLAY MARGIN RATES +$var=!$var; +print ''; +print ''; + + +print ''; +print ''; +print ''; + +// DISPLAY MARK RATES +$var=!$var; +print ''; +print ''; + + +print ''; +print ''; +print ''; +print ''; +print ''; + +print ''; +print ''; +print ''; + +// GLOBAL DISCOUNT MANAGEMENT +$var=!$var; +print ""; +print ''; +print ""; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +print '
'.$langs->trans("Description").''.$langs->trans("Value").''.$langs->trans("Details").'
'.$langs->trans("MARGIN_TYPE").''.$langs->trans('MargeBrute'); +print ' global->MARGIN_TYPE == '1') + print 'checked '; +print '/>
'.$langs->trans('MargeNette'); +print ' global->MARGIN_TYPE == '2') + print 'checked '; +print '/>'; +print '
'; +print ''; +print ''.$langs->trans('MARGIN_TYPE_DETAILS').'
'.$langs->trans("DisplayMarginRates").''; +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 ''.$langs->trans('MarginRate').' = '.$langs->trans('Margin').' / '.$langs->trans('BuyingPrice').'
'.$langs->trans("DisplayMarkRates").''; +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 ''.$langs->trans('MarkRate').' = '.$langs->trans('Margin').' / '.$langs->trans('SellingPrice').'
'.$langs->trans("ForceBuyingPriceIfNull").''; +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 ''.$langs->trans('ForceBuyingPriceIfNullDetails').'
'.$langs->trans("MARGIN_METHODE_FOR_DISCOUNT").''; +print ''; +print ''; +print ''; +print ''.$langs->trans('MARGIN_METHODE_FOR_DISCOUNT_DETAILS').'
'; +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 ''; + print ''; + print ''; + print ''; + if($conf->global->DISPLAY_MARGIN_RATES) + print ''; + if($conf->global->DISPLAY_MARK_RATES) + print ''; + print ''; + if ($marginInfo['margin_on_products'] != 0 && $marginInfo['margin_on_services'] != 0) { + print ''; + print ''; + print ''; + print ''; + print ''; + if($conf->global->DISPLAY_MARGIN_RATES) + print ''; + if($conf->global->DISPLAY_MARK_RATES) + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if($conf->global->DISPLAY_MARGIN_RATES) + print ''; + if($conf->global->DISPLAY_MARK_RATES) + print ''; + print ''; + } + print ''; + print ''; + print ''; + print ''; + print ''; + if($conf->global->DISPLAY_MARGIN_RATES) + print ''; + if($conf->global->DISPLAY_MARK_RATES) + print ''; + print ''; + print '
'.$langs->trans('Margins').''.$langs->trans('SellingPrice').''.$langs->trans('BuyingPrice').''.$langs->trans('Margin').''.$langs->trans('MarginRate').''.$langs->trans('MarkRate').'
'.$langs->trans('MarginOnProducts').''.price($marginInfo['pv_products']).''.price($marginInfo['pa_products']).''.price($marginInfo['margin_on_products']).''.(($marginInfo['margin_rate_products'] == '')?'n/a':price($marginInfo['margin_rate_products']).'%').''.(($marginInfo['mark_rate_products'] == '')?'n/a':price($marginInfo['mark_rate_products']).'%').'
'.$langs->trans('MarginOnServices').''.price($marginInfo['pv_services']).''.price($marginInfo['pa_services']).''.price($marginInfo['margin_on_services']).''.(($marginInfo['margin_rate_services'] == '')?'n/a':price($marginInfo['margin_rate_services']).'%').''.(($marginInfo['mark_rate_services'] == '')?'n/a':price($marginInfo['mark_rate_services']).'%').'
'.$langs->trans('TotalMargin').''.price($marginInfo['pv_total']).''.price($marginInfo['pa_total']).''.price($marginInfo['total_margin']).''.(($marginInfo['total_margin_rate'] == '')?'n/a':price($marginInfo['total_margin_rate']).'%').''.(($marginInfo['total_mark_rate'] == '')?'n/a':price($marginInfo['total_mark_rate']).'%').'
'; + } } ?> 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 ''; print ''; print ''; print '
'; - print $this->select_company($selected, $htmlname); + print $this->select_company($selected , $htmlname, $filter,$showempty, $showtype, $forcecombo, $event); 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++; +} +?> +  
    "> "> % - +marges->enabled) { +?> + "> +global->DISPLAY_MARGIN_RATES) + $colspan++; + if($conf->global->DISPLAY_MARK_RATES) + $colspan++; +} +?> + -service->enabled && $dateSelector) { ?> + +service->enabled && $dateSelector) { +if(! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) + $colspan = 10; +else + $colspan = 9; +if ($conf->marges->enabled) { + if($conf->global->DISPLAY_MARGIN_RATES) + $colspan++; + if($conf->global->DISPLAY_MARK_RATES) + $colspan++; +} +?> > - global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="10"' : ' colspan="9"'); ?>> + trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; echo $form->select_date('','date_start',$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,1,"addproduct"); diff --git a/htdocs/core/tpl/freeproductline_edit.tpl.php b/htdocs/core/tpl/freeproductline_edit.tpl.php index ab4cc989c70..6b067951401 100644 --- a/htdocs/core/tpl/freeproductline_edit.tpl.php +++ b/htdocs/core/tpl/freeproductline_edit.tpl.php @@ -1,6 +1,7 @@ * Copyright (C) 2010-2012 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 @@ -73,6 +74,13 @@ +marges->enabled) { +?> + + ">
    "> diff --git a/htdocs/core/tpl/freeproductline_view.tpl.php b/htdocs/core/tpl/freeproductline_view.tpl.php index f3824738054..3e090c5c92e 100644 --- a/htdocs/core/tpl/freeproductline_view.tpl.php +++ b/htdocs/core/tpl/freeproductline_view.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 @@ -82,7 +83,18 @@ remise_percent,$langs); ?>   - + marges->enabled) { + ?> + pa_ht); ?> + global->DISPLAY_MARGIN_RATES) {?> + pa_ht == 0)?'n/a':price($line->marge_tx).'%'); ?> + global->DISPLAY_MARK_RATES) {?> + marque_tx).'%'; ?> + special_code == 3) { ?> trans('Option'); ?> diff --git a/htdocs/core/tpl/predefinedproductline_create.tpl.php b/htdocs/core/tpl/predefinedproductline_create.tpl.php index c9791d4a060..c4a0bebd614 100644 --- a/htdocs/core/tpl/predefinedproductline_create.tpl.php +++ b/htdocs/core/tpl/predefinedproductline_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 @@ -39,7 +40,19 @@ trans('Qty'); ?> trans('ReductionShort'); ?> -   +marges->enabled) { +?> + trans('BuyingPrice'); ?> +global->DISPLAY_MARGIN_RATES) + $colspan++; + if($conf->global->DISPLAY_MARK_RATES) + $colspan++; +} +?> +   "> + +global->DISPLAY_MARGIN_RATES) + $colspan++; + if($conf->global->DISPLAY_MARK_RATES) + $colspan++; +} +?> + " name="addline"> -service->enabled && $dateSelector) {?> +service->enabled && $dateSelector) { +if(! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) + $colspan = 10; +else + $colspan = 9; +if ($conf->marges->enabled) { + if($conf->global->DISPLAY_MARGIN_RATES) + $colspan++; + if($conf->global->DISPLAY_MARK_RATES) + $colspan++; +} +?> > - global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="10"' : ' colspan="9"'); ?>> + trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; echo $form->select_date('','date_start_predef',$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,1,"addpredefinedproduct"); @@ -95,4 +133,41 @@ jQuery(document).ready(function() { +marges->enabled) { +?> + + diff --git a/htdocs/core/tpl/predefinedproductline_edit.tpl.php b/htdocs/core/tpl/predefinedproductline_edit.tpl.php index eddfc704341..fc824b3005e 100644 --- a/htdocs/core/tpl/predefinedproductline_edit.tpl.php +++ b/htdocs/core/tpl/predefinedproductline_edit.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 @@ -82,6 +83,16 @@   +marges->enabled) { +?> + + + + + ">
    @@ -100,4 +111,55 @@ - \ No newline at end of file +marges->enabled) { +?> + + + + diff --git a/htdocs/core/tpl/predefinedproductline_view.tpl.php b/htdocs/core/tpl/predefinedproductline_view.tpl.php index f9098c25711..a74c7405d7a 100644 --- a/htdocs/core/tpl/predefinedproductline_view.tpl.php +++ b/htdocs/core/tpl/predefinedproductline_view.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 @@ -51,7 +52,18 @@ remise_percent,$langs); ?>   - + marges->enabled) { + ?> + pa_ht); ?> + global->DISPLAY_MARGIN_RATES) {?> + pa_ht == 0)?'n/a':price($line->marge_tx).'%'); ?> + global->DISPLAY_MARK_RATES) {?> + marque_tx).'%'; ?> + special_code == 3) { ?> trans('Option'); ?> diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 4fbb595c6f8..c7fa32d7835 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -3,6 +3,7 @@ * Copyright (C) 2006-2011 Laurent Destailleur * Copyright (C) 2009-2012 Regis Houssin * Copyright (C) 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 @@ -136,105 +137,135 @@ class ProductFournisseur extends Product * @param float $buyprice Purchase price for the quantity min * @param User $user Object user user made changes * @param string $price_base_type HT or TTC + * @param string $charges costs affering to product * @param Societe $fourn Supplier * @param int $availability Product availability * @param string $ref_fourn Supplier ref * @param float $tva_tx VAT rate * @return int >0 if KO, >0 if OK */ - function update_buyprice($qty, $buyprice, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx) + function update_buyprice($qty, $buyprice, $charges, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx) { global $conf,$mysoc; // Clean parameter $buyprice=price2num($buyprice); + $charges=price2num($charges); $qty=price2num($qty); if (empty($availability)) $availability=0; - $error=0; + $error=0; + + if ($price_base_type == 'TTC') + { + $ttx = get_default_tva($fourn,$mysoc,$this->id); + $buyprice = $buyprice/(1+($ttx/100)); + } + $unitBuyPrice = price2num($buyprice/$qty,'MU'); + $unitCharges = price2num($charges/$qty,'MU'); + + $now=dol_now(); + $this->db->begin(); if ($this->product_fourn_price_id) { - // Supprime prix courant du fournisseur pour cette quantite - $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_fournisseur_price"; - $sql.= " WHERE rowid = ".$this->product_fourn_price_id; - $resql=$this->db->query($sql); - if ($resql < 0) $error++; + $sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price"; + $sql.= " SET fk_user = " . $user->id." ,"; + $sql.= " price = ".price2num($buyprice).","; + $sql.= " quantity = ".$qty.","; + $sql.= " charges = ".price2num($charges).","; + $sql.= " unitprice = ".$unitBuyPrice.","; + $sql.= " unitcharges = ".$unitCharges.","; + $sql.= " tva_tx = ".$tva_tx.","; + $sql.= " fk_availability = ".$availability.","; + $sql.= " entity = ".$conf->entity; + $sql .= " WHERE rowid = ".$this->product_fourn_price_id; + + $resql = $this->db->query($sql) ; + if ($resql) + { + $this->db->commit(); + return 0; + } + else + { + $this->error=$this->db->error()." sql=".$sql; + $this->db->rollback(); + return -2; + } } - if (! $error) - { - if ($price_base_type == 'TTC') - { - //$ttx = get_default_tva($fourn,$mysoc,$this->id); - //$buyprice = $buyprice/(1+($ttx/100)); - $buyprice = $buyprice/(1+($tva_tx/100)); - } - $unitBuyPrice = price2num($buyprice/$qty,'MU'); - - $now=dol_now(); - - // Ajoute prix courant du fournisseur pour cette quantite - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price("; - $sql.= "datec, fk_product, fk_soc, ref_fourn, fk_user, price, quantity, unitprice, tva_tx, fk_availability, entity)"; - $sql.= " values('".$this->db->idate($now)."',"; - $sql.= " ".$this->id.","; - $sql.= " ".$fourn->id.","; - $sql.= " '".$this->db->escape($ref_fourn)."',"; - $sql.= " ".$user->id.","; - $sql.= " ".price2num($buyprice).","; - $sql.= " ".$qty.","; - $sql.= " ".$unitBuyPrice.","; - $sql.= " ".$tva_tx.","; - $sql.= " ".$availability.","; - $sql.= $conf->entity; - $sql.=")"; - - dol_syslog(get_class($this)."::update_buyprice sql=".$sql); - if (! $this->db->query($sql)) - { - $error++; - } - - /*if (! $error) - { - // Ajoute modif dans table log - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price_log("; - $sql.= "datec, fk_product_fournisseur,fk_user,price,quantity)"; - $sql.= "values('".$this->db->idate($now)."',"; - $sql.= " ".$this->product_fourn_id.","; - $sql.= " ".$user->id.","; - $sql.= " ".price2num($buyprice).","; - $sql.= " ".$qty; - $sql.=")"; - - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - } - } - */ - - if (! $error) - { - $this->db->commit(); - return 0; - } - else - { - $this->error=$this->db->error()." sql=".$sql; - $this->db->rollback(); - return -2; - } - } else { - $this->error=$this->db->error()." sql=".$sql; - $this->db->rollback(); - return -1; - } + // Supprime prix courant du fournisseur pour cette quantite + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_fournisseur_price"; + $sql.= " WHERE rowid = ".$this->product_fourn_price_id; + $resql=$this->db->query($sql); + if ($resql) + { + + // Ajoute prix courant du fournisseur pour cette quantite + $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price("; + $sql.= "datec, fk_product, fk_soc, ref_fourn, fk_user, price, quantity, unitprice, tva_tx, fk_availability, entity)"; + $sql.= " values('".$this->db->idate($now)."',"; + $sql.= " ".$this->id.","; + $sql.= " ".$fourn->id.","; + $sql.= " '".$this->db->escape($ref_fourn)."',"; + $sql.= " ".$user->id.","; + $sql.= " ".price2num($buyprice).","; + $sql.= " ".$qty.","; + $sql.= " ".$unitBuyPrice.","; + $sql.= " ".$tva_tx.","; + $sql.= " ".$availability.","; + $sql.= $conf->entity; + $sql.=")"; + + dol_syslog(get_class($this)."::update_buyprice sql=".$sql); + if (! $this->db->query($sql)) + { + $error++; + } + + /*if (! $error) + { + // Ajoute modif dans table log + $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price_log("; + $sql.= "datec, fk_product_fournisseur,fk_user,price,quantity)"; + $sql.= "values('".$this->db->idate($now)."',"; + $sql.= " ".$this->product_fourn_id.","; + $sql.= " ".$user->id.","; + $sql.= " ".price2num($buyprice).","; + $sql.= " ".$qty; + $sql.=")"; + + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + } + } + */ + + if (! $error) + { + $this->db->commit(); + return 0; + } + else + { + $this->error=$this->db->error()." sql=".$sql; + $this->db->rollback(); + return -2; + } + } + else + { + $this->error=$this->db->error()." sql=".$sql; + $this->db->rollback(); + return -1; + } + } } /** @@ -246,7 +277,7 @@ class ProductFournisseur extends Product function fetch_product_fournisseur_price($rowid) { $sql = "SELECT pfp.rowid, pfp.price, pfp.quantity, pfp.unitprice, pfp.tva_tx, pfp.fk_availability,"; - $sql.= " pfp.fk_soc, pfp.ref_fourn, pfp.fk_product"; + $sql.= " pfp.fk_soc, pfp.ref_fourn, pfp.fk_product, pfp.charges, pfp.unitcharges"; $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; $sql.= " WHERE pfp.rowid = ".$rowid; @@ -260,8 +291,10 @@ class ProductFournisseur extends Product $this->product_fourn_price_id = $rowid; $this->fourn_ref = $obj->ref_fourn; $this->fourn_price = $obj->price; - $this->fourn_qty = $obj->quantity; - $this->fourn_unitprice = $obj->unitprice; + $this->fourn_charges = $obj->charges; + $this->fourn_qty = $obj->quantity; + $this->fourn_unitprice = $obj->unitprice; + $this->fourn_unitcharges = $obj->unitcharges; $this->tva_tx = $obj->tva_tx; $this->product_id = $obj->fk_product; // deprecated $this->fk_product = $obj->fk_product; @@ -294,7 +327,7 @@ class ProductFournisseur extends Product $sql = "SELECT s.nom as supplier_name, s.rowid as fourn_id,"; $sql.= " pfp.rowid as product_fourn_pri_id, pfp.ref_fourn, pfp.fk_product as product_fourn_id,"; - $sql.= " pfp.price, pfp.quantity, pfp.unitprice, pfp.tva_tx, pfp.fk_availability"; + $sql.= " pfp.price, pfp.quantity, pfp.unitprice, pfp.tva_tx, pfp.fk_availability, pfp.charges, pfp.unitcharges"; $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; $sql.= ", ".MAIN_DB_PREFIX."societe as s"; $sql.= " WHERE pfp.entity IN (".getEntity('product', 1).")"; @@ -320,6 +353,8 @@ class ProductFournisseur extends Product $prodfourn->fourn_price = $record["price"]; $prodfourn->fourn_qty = $record["quantity"]; $prodfourn->fourn_unitprice = $record["unitprice"]; + $prodfourn->fourn_charges = $record["charges"]; + $prodfourn->fourn_unitcharges = $record["unitcharges"]; $prodfourn->fourn_tva_tx = $record["tva_tx"]; $prodfourn->fourn_id = $record["fourn_id"]; $prodfourn->fourn_name = $record["supplier_name"]; @@ -374,7 +409,7 @@ class ProductFournisseur extends Product $sql = "SELECT s.nom as supplier_name, s.rowid as fourn_id,"; $sql.= " pfp.rowid as product_fourn_price_id, pfp.ref_fourn,"; - $sql.= " pfp.price, pfp.quantity, pfp.unitprice, pfp.tva_tx"; + $sql.= " pfp.price, pfp.quantity, pfp.unitprice, pfp.tva_tx, pfp.charges, pfp.unitcharges"; $sql.= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; $sql.= " WHERE s.entity IN (".getEntity('societe', 1).")"; $sql.= " AND pfp.fk_product = ".$prodid; @@ -393,6 +428,8 @@ class ProductFournisseur extends Product $this->fourn_price = $record["price"]; $this->fourn_qty = $record["quantity"]; $this->fourn_unitprice = $record["unitprice"]; + $this->fourn_charges = $record["charges"]; + $this->fourn_unitcharges = $record["unitcharges"]; $this->fourn_tva_tx = $record["tva_tx"]; $this->fourn_id = $record["fourn_id"]; $this->fourn_name = $record["supplier_name"]; diff --git a/htdocs/fourn/product/getSupplierPrices.php b/htdocs/fourn/product/getSupplierPrices.php new file mode 100644 index 00000000000..a521140f7bc --- /dev/null +++ b/htdocs/fourn/product/getSupplierPrices.php @@ -0,0 +1,92 @@ + + * + * 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, see . + * + */ +require("../../main.inc.php"); + +$prices = array(); + +$langs->load('stocks'); + +$sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration,"; +$sql.= " pfp.ref_fourn,"; +$sql.= " pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.unitprice, pfp.charges, pfp.unitcharges,"; +$sql.= " s.nom"; +$sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = pfp.fk_product"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = pfp.fk_soc"; +$sql.= " WHERE pfp.fk_product = ".$_REQUEST['idprod']; +$sql.= " AND p.tobuy = 1"; +$sql.= " AND s.fournisseur = 1"; +$sql.= " ORDER BY s.nom, pfp.ref_fourn DESC"; + +dol_syslog("Form::select_product_fourn_price sql=".$sql,LOG_DEBUG); +$result=$db->query($sql); + +if ($result) +{ + $num = $db->num_rows($result); + + if ($num) + { + $i = 0; + while ($i < $num) + { + $objp = $db->fetch_object($result); + + $label = $objp->nom.' - '.$objp->ref_fourn.' - '; + + if ($objp->quantity == 1) + { + $label.= price($objp->fprice); + $label.= $langs->trans("Currency".$conf->monnaie)."/"; + $price = $objp->fprice; + } + + $label.= $objp->quantity.' '; + + if ($objp->quantity == 1) + { + $label.= strtolower($langs->trans("Unit")); + } + else + { + $label.= strtolower($langs->trans("Units")); + } + if ($objp->quantity > 1) + { + $label.=" - "; + $label.= price($objp->unitprice).$langs->trans("Currency".$conf->monnaie)."/".strtolower($langs->trans("Unit")); + $price = $objp->unitprice; + } + if ($objp->unitcharges > 0 && ($conf->global->MARGIN_TYPE == "2")) { + $label.=" + "; + $label.= price($objp->unitcharges).$langs->trans("Currency".$conf->monnaie); + $price += $objp->unitcharges; + } + if ($objp->duration) $label .= " - ".$objp->duration; + + $prices[] = array("id" => $objp->idprodfournprice, "price" => price($price,0,'',0), "label" => $label); + $i++; + } + + $db->free($result); + } +} + +echo json_encode($prices); + +?> diff --git a/htdocs/install/mysql/migration/3.2.0-3.3.0.sql b/htdocs/install/mysql/migration/3.2.0-3.3.0.sql index 24a92e8854e..00d8979316d 100755 --- a/htdocs/install/mysql/migration/3.2.0-3.3.0.sql +++ b/htdocs/install/mysql/migration/3.2.0-3.3.0.sql @@ -41,3 +41,20 @@ ALTER TABLE llx_mailing ADD COLUMN extraparams varchar(255); ALTER TABLE llx_product MODIFY ref varchar(128) NOT NULL; ALTER TABLE llx_product MODIFY ref_ext varchar(128); +ALTER TABLE llx_product_fournisseur_price ADD charges DOUBLE( 24, 8 ) DEFAULT 0 AFTER unitprice; +ALTER TABLE llx_product_fournisseur_price ADD unitcharges DOUBLE( 24, 8 ) DEFAULT 0 AFTER charges; + +alter table llx_commandedet add column fk_product_fournisseur_price int(11) after info_bits; +alter table llx_commandedet add column buy_price_ht double(24,8) DEFAULT 0 after fk_product_fournisseur_price; +alter table llx_commandedet drop column marge_tx; +alter table llx_commandedet drop column marque_tx; + +alter table llx_facturedet add column fk_product_fournisseur_price int(11) after info_bits; +alter table llx_facturedet add column buy_price_ht double(24,8) DEFAULT 0 after fk_product_fournisseur_price; + +alter table llx_propaldet add column fk_product_fournisseur_price int(11) after info_bits; +alter table llx_propaldet add column buy_price_ht double(24,8) DEFAULT 0 after fk_product_fournisseur_price; +alter table llx_propaldet drop column pa_ht; +alter table llx_propaldet drop column marge_tx; +alter table llx_propaldet drop column marque_tx; + diff --git a/htdocs/install/mysql/tables/llx_commandedet.sql b/htdocs/install/mysql/tables/llx_commandedet.sql index 6c629b38c61..36318a566e7 100644 --- a/htdocs/install/mysql/tables/llx_commandedet.sql +++ b/htdocs/install/mysql/tables/llx_commandedet.sql @@ -43,8 +43,8 @@ create table llx_commandedet date_start datetime DEFAULT NULL, -- date debut si service date_end datetime DEFAULT NULL, -- date fin si service info_bits integer DEFAULT 0, -- TVA NPR ou non - marge_tx double(6,3) DEFAULT 0, -- taux de marge (marge sur prix d'achat) - marque_tx double(6,3) DEFAULT 0, -- taux de marque (marge sur prix de vente) + buy_price_ht double(24,8) DEFAULT 0, -- prix d'achat HT + fk_product_fournisseur_price int(11) DEFAULT NULL, -- référence prix fournisseur special_code integer UNSIGNED DEFAULT 0, -- code pour les lignes speciales rang integer DEFAULT 0, import_key varchar(14) diff --git a/htdocs/install/mysql/tables/llx_facturedet.sql b/htdocs/install/mysql/tables/llx_facturedet.sql index fd5ee387d93..f2dba3e600e 100644 --- a/htdocs/install/mysql/tables/llx_facturedet.sql +++ b/htdocs/install/mysql/tables/llx_facturedet.sql @@ -45,6 +45,8 @@ create table llx_facturedet date_start datetime DEFAULT NULL, -- date debut si service date_end datetime DEFAULT NULL, -- date fin si service info_bits integer DEFAULT 0, -- TVA NPR ou non + buy_price_ht double(24,8) DEFAULT 0, -- prix d'achat HT + fk_product_fournisseur_price int(11) DEFAULT NULL, -- référence prix fournisseur fk_code_ventilation integer DEFAULT 0 NOT NULL, fk_export_compta integer DEFAULT 0 NOT NULL, special_code integer UNSIGNED DEFAULT 0, -- code pour les lignes speciales diff --git a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql index 9d6c25fe1e8..5f497232312 100644 --- a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql +++ b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql @@ -23,14 +23,16 @@ create table llx_product_fournisseur_price rowid integer AUTO_INCREMENT PRIMARY KEY, entity integer DEFAULT 1 NOT NULL, -- multi company id datec datetime, - tms timestamp, - fk_product integer, + tms timestamp, + fk_product integer, fk_soc integer, - ref_fourn varchar(30), - fk_availability integer, + ref_fourn varchar(30), + fk_availability integer, price double(24,8) DEFAULT 0, - quantity double, - unitprice double(24,8) DEFAULT 0, + quantity double, + unitprice double(24,8) DEFAULT 0, + charges double(24,8) DEFAULT 0, + unitcharges double(24,8) DEFAULT 0, tva_tx double(6,3) NOT NULL, fk_user integer )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_propaldet.sql b/htdocs/install/mysql/tables/llx_propaldet.sql index 597dcc2a9bc..2986432046f 100644 --- a/htdocs/install/mysql/tables/llx_propaldet.sql +++ b/htdocs/install/mysql/tables/llx_propaldet.sql @@ -44,10 +44,9 @@ create table llx_propaldet date_end datetime DEFAULT NULL, -- date fin si service info_bits integer DEFAULT 0, -- TVA NPR ou non - pa_ht double(24,8) DEFAULT 0, -- prix d'achat HT - marge_tx double(6,3) DEFAULT 0, -- taux de marge (marge sur prix d'achat) - marque_tx double(6,3) DEFAULT 0, -- taux de marque (marge sur prix de vente) - + buy_price_ht double(24,8) DEFAULT 0, -- prix d'achat HT + fk_product_fournisseur_price int(11) DEFAULT NULL, -- référence prix fournisseur + special_code integer DEFAULT 0, -- code pour les lignes speciales rang integer DEFAULT 0 -- ordre affichage sur la propal )ENGINE=innodb; diff --git a/htdocs/langs/fr_FR/marges.lang b/htdocs/langs/fr_FR/marges.lang new file mode 100644 index 00000000000..d19348d605d --- /dev/null +++ b/htdocs/langs/fr_FR/marges.lang @@ -0,0 +1,45 @@ +# Dolibarr language file - fr_FR - marges +CHARSET=UTF-8 + +Margin=Marge +Margins=Marges +TotalMargin=Marge totale +MarginOnProducts=Marge / Produits +MarginOnServices=Marge / Services +MarginRate=Taux de marge +MarkRate=Taux de marque +DisplayMarginRates=Afficher les taux de marge +DisplayMarkRates=Afficher les taux de marque +InputPrice=Saisir un prix + +marges=Gestion des marges +margesSetup=Paramétrage de la gestion des marges + +MarginDetails=Détails des marges réalisées + +ProductMargins=Marges par produit +CustomerMargins=Marges par client +AgentMargins=Marges par commercial + +ProductService=Produit ou Service +AllProducts=Tous les produits et services +ChooseProduct/Service=Choisissez le produit ou le service +CommercialAgent=Agent commercial + +StartDate=Date de début +EndDate=Date de fin +Launch=Démarrer + +ForceBuyingPriceIfNull=Forcer le prix d'achat si non renseigné +ForceBuyingPriceIfNullDetails=Si "ON", la ligne sera prise en compte avec une marge nulle (on forcera le prix d'achat avec le prix de vente) , sinon ("OFF") la marge sera égale au prix de vente pour cette ligne (prix d'achat à zéro). +MARGIN_METHODE_FOR_DISCOUNT=Méthode de gestion des remises globales +UseDiscountAsProduct=Comme un produit +UseDiscountAsService=Comme un service +UseDiscountOnTotal=Sur le total +MARGIN_METHODE_FOR_DISCOUNT_DETAILS=Définit si une remise globale est prise en compte comme un produit, comme un service ou uniquement sur le total lors du calcul des marges. + +MARGIN_TYPE=Type de marge gérée +MARGIN_TYPE_DETAILS=Marge brute : Prix de vente HT - Prix d'achat HT
    Marge nette : Prix de vente HT - Coût de revient + +BuyingCost=Coût de revient +UnitCharges=Charge unitaire \ No newline at end of file diff --git a/htdocs/marges/agentMargins.php b/htdocs/marges/agentMargins.php new file mode 100644 index 00000000000..8501f50b5cd --- /dev/null +++ b/htdocs/marges/agentMargins.php @@ -0,0 +1,274 @@ + + * + * 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, see . + */ + +/** + * \file htdocs/custom/marges/agentMargins.php + * \ingroup marges + * \brief Page des marges par agent commercial + * \version $Id: facture.php,v 1.84 2011/08/08 16:07:47 eldy Exp $ + */ + +require("../main.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/company.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php"); +require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php"); +require_once(DOL_DOCUMENT_ROOT."/marges/lib/marges.lib.php"); + +$langs->load("companies"); +$langs->load("bills"); +$langs->load("products"); +$langs->load("marges"); + +// Security check +$agentid = isset($_REQUEST["agentid"])?$_REQUEST["agentid"]:''; + +$mesg = ''; + +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if ($page == -1) { $page = 0; } +$offset = $conf->liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +if (!empty($_POST['startdatemonth'])) + $startdate = date('Y-m-d', dol_mktime(12, 0, 0, $_POST['startdatemonth'], $_POST['startdateday'], $_POST['startdateyear'])); +if (!empty($_POST['enddatemonth'])) + $enddate = date('Y-m-d', dol_mktime(12, 0, 0, $_POST['enddatemonth'], $_POST['enddateday'], $_POST['enddateyear'])); + +/* + * View + */ + +$userstatic = new User($db); +$companystatic = new Societe($db); +$invoicestatic=new Facture($db); + +$form = new Form($db); + +llxHeader('',$langs->trans("Margins").' - '.$langs->trans("Agents")); + +$text=$langs->trans("Margins"); +print_fiche_titre($text); + +// Show tabs +$head=marges_prepare_head($user); +$titre=$langs->trans("Margins"); +$picto='marges@marges'; +dol_fiche_head($head, 'agentMargins', $titre, 0, $picto); + +print '
    '; +print ''; + +if ($agentid > 0) { + + print ''; + print ''; + + if (! $sortorder) $sortorder="ASC"; + if (! $sortfield) $sortfield="s.nom"; +} +else { + print ''; + print ''; + if (! $sortorder) $sortorder="ASC"; + if (! $sortfield) $sortfield="u.login"; +} + +// Date début +print ''; +print ''; +print ''; +print ''; +print ''; + +// Total Margin +print ''; + +// Margin Rate +if ($conf->global->DISPLAY_MARGIN_RATES) { + print ''; +} + +// Mark Rate +if ($conf->global->DISPLAY_MARK_RATES) { + print ''; +} + +print "
    '.$langs->trans('CommercialAgent').''; + print $form->select_dolusers($selected=$agentid,$htmlname='agentid',$show_empty=1,$exclude='',$disabled=0,$include='',$enableonly=''); + print '
    '.$langs->trans('CommercialAgent').''; + print $form->select_dolusers($selected='',$htmlname='agentid',$show_empty=1,$exclude='',$disabled=0,$include='',$enableonly=''); + print '
    '.$langs->trans('StartDate').''; +$form->select_date($startdate,'startdate','','',1,"sel",1,1); +print ''.$langs->trans('EndDate').''; +$form->select_date($enddate,'enddate','','',1,"sel",1,1); +print ''; +print ''; +print '
    '.$langs->trans("TotalMargin").''; +print ''; // set by jquery (see below) +print '
    '.$langs->trans("MarginRate").''; + print ''; // set by jquery (see below) + print '
    '.$langs->trans("MarkRate").''; + print ''; // set by jquery (see below) + print '
    "; +print '
    '; + +$sql = "SELECT distinct s.nom, s.rowid as socid, s.code_client, s.client, sc.fk_user as agent,"; +$sql.= " u.login,"; +$sql.= " f.facnumber, f.total as total_ht,"; +$sql.= " sum(d.subprice * d.qty * (1 - d.remise_percent / 100)) as selling_price,"; +$sql.= " sum(d.buy_price_ht * d.qty) as buying_price, sum(((d.subprice * (1 - d.remise_percent / 100)) - d.buy_price_ht) * d.qty) as marge," ; +$sql.= " f.datef, f.paye, f.fk_statut as statut, f.rowid as facid"; +$sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; +$sql.= ", ".MAIN_DB_PREFIX."facture as f"; +$sql.= ", ".MAIN_DB_PREFIX."facturedet as d"; +$sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; +$sql.= ", ".MAIN_DB_PREFIX."user as u"; +$sql.= " WHERE f.fk_soc = s.rowid"; +$sql.= " AND sc.fk_soc = f.fk_soc"; +$sql.= " AND sc.fk_user = u.rowid"; +$sql.= " AND f.fk_statut > 0"; +$sql.= " AND s.entity = ".$conf->entity; +$sql.= " AND d.fk_facture = f.rowid"; +if ($agentid > 0) + $sql.= " AND sc.fk_user = $agentid"; +if (!empty($startdate)) + $sql.= " AND f.datef >= '".$startdate."'"; +if (!empty($enddate)) + $sql.= " AND f.datef <= '".$enddate."'"; +if ($agentid > 0) + $sql.= " GROUP BY s.rowid"; +else + $sql.= " GROUP BY sc.fk_user"; +$sql.= " ORDER BY $sortfield $sortorder "; +$sql.= $db->plimit($conf->liste_limit +1, $offset); + +$result = $db->query($sql); +if ($result) +{ + $num = $db->num_rows($result); + + print '
    '; + print_barre_liste($langs->trans("MarginDetails"),$page,$_SERVER["PHP_SELF"],"&socid=$societe->id",$sortfield,$sortorder,'',$num,0,''); + + $i = 0; + print ""; + + print ''; + if ($agentid > 0) + print_liste_field_titre($langs->trans("Customer"),$_SERVER["PHP_SELF"],"s.nom","","&agentid=".$_REQUEST["agentid"],'align="center"',$sortfield,$sortorder); + else + print_liste_field_titre($langs->trans("CommercialAgent"),$_SERVER["PHP_SELF"],"u.login","","&agentid=".$_REQUEST["agentid"],'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("SellingPrice"),$_SERVER["PHP_SELF"],"selling_price","","&agentid=".$_REQUEST["agentid"],'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("BuyingPrice"),$_SERVER["PHP_SELF"],"buyng_price","","&agentid=".$_REQUEST["agentid"],'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Margin"),$_SERVER["PHP_SELF"],"marge","","&agentid=".$_REQUEST["agentid"],'align="right"',$sortfield,$sortorder); + if ($conf->global->DISPLAY_MARGIN_RATES) + print_liste_field_titre($langs->trans("MarginRate"),$_SERVER["PHP_SELF"],"d.marge_tx","","&agentid=".$_REQUEST["agentid"],'align="right"',$sortfield,$sortorder); + if ($conf->global->DISPLAY_MARK_RATES) + print_liste_field_titre($langs->trans("MarkRate"),$_SERVER["PHP_SELF"],"d.marque_tx","","&agentid=".$_REQUEST["agentid"],'align="right"',$sortfield,$sortorder); + print "\n"; + + $cumul_achat = 0; + $cumul_vente = 0; + $cumul_qty = 0; + if ($num > 0) + { + $var=True; + while ($i < $num && $i < $conf->liste_limit) + { + $objp = $db->fetch_object($result); + + $marginRate = ($objp->buying_price != 0)?(100 * round($objp->marge / $objp->buying_price ,5)):'' ; + $markRate = ($objp->selling_price != 0)?(100 * round($objp->marge / $objp->selling_price ,5)):'' ; + + $var=!$var; + + print ""; + if ($agentid > 0) { + $companystatic->id=$objp->socid; + $companystatic->nom=$objp->nom; + $companystatic->client=$objp->client; + print "\n"; + } + else { + $userstatic->id=$objp->agent; + $userstatic->login=$objp->login; + print "\n"; + } + print "\n"; + print "\n"; + print "\n"; + if ($conf->global->DISPLAY_MARGIN_RATES) + print "\n"; + if ($conf->global->DISPLAY_MARK_RATES) + print "\n"; + print "\n"; + $i++; + $cumul_achat += $objp->buying_price; + $cumul_vente += $objp->selling_price; + } + } + + // affichage totaux marges + $var=!$var; + $totalMargin = $cumul_vente - $cumul_achat; + $marginRate = ($cumul_achat != 0)?(100 * round($totalMargin / $cumul_achat, 5)):'' ; + $markRate = ($cumul_vente != 0)?(100 * round($totalMargin / $cumul_vente, 5)):'' ; + print ''; + if ($client) + print '"; + print "\n"; + print "\n"; + print "\n"; + if ($conf->global->DISPLAY_MARGIN_RATES) + print "\n"; + if ($conf->global->DISPLAY_MARK_RATES) + print "\n"; + print "\n"; + + print "
    ".$companystatic->getNomUrl(1,'customer')."".$userstatic->getLoginUrl(1)."".price($objp->selling_price)."".price($objp->buying_price)."".price($objp->marge)."".(($marginRate === '')?'n/a':price($marginRate)."%")."".(($markRate === '')?'n/a':price($markRate)."%")."
    '; + else + print ''; + print $langs->trans('TotalMargin')."".price($cumul_vente)."".price($cumul_achat)."".price($totalMargin)."".(($marginRate === '')?'n/a':price($marginRate)."%")."".(($markRate === '')?'n/a':price($markRate)."%")."
    "; +} +else +{ + dol_print_error($db); +} +$db->free($result); + +$db->close(); + +llxFooter('$Date: 2011/08/08 16:07:47 $ - $Revision: 1.84 $'); +?> + \ No newline at end of file diff --git a/htdocs/marges/css/marges.css b/htdocs/marges/css/marges.css new file mode 100644 index 00000000000..c804c801a24 --- /dev/null +++ b/htdocs/marges/css/marges.css @@ -0,0 +1,3 @@ +div.mainmenu.margins { + background : url('../img/marges.png') no-repeat 20px 0; +} \ No newline at end of file diff --git a/htdocs/marges/customerMargins.php b/htdocs/marges/customerMargins.php new file mode 100644 index 00000000000..13594f0aff1 --- /dev/null +++ b/htdocs/marges/customerMargins.php @@ -0,0 +1,287 @@ + + * + * 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, see . + */ + +/** + * \file htdocs/custom/marges/customerMargins.php + * \ingroup marges + * \brief Page des marges par client + * \version $Id: facture.php,v 1.84 2011/08/08 16:07:47 eldy Exp $ + */ + +require("../main.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/company.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php"); +require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php"); +require_once(DOL_DOCUMENT_ROOT."/marges/lib/marges.lib.php"); + +$langs->load("companies"); +$langs->load("bills"); +$langs->load("products"); +$langs->load("marges"); + +// Security check +$socid = isset($_REQUEST["socid"])?$_REQUEST["socid"]:''; +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'societe','',''); + + +$mesg = ''; + +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if ($page == -1) { $page = 0; } +$offset = $conf->liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +if (!empty($_POST['startdatemonth'])) + $startdate = date('Y-m-d', dol_mktime(12, 0, 0, $_POST['startdatemonth'], $_POST['startdateday'], $_POST['startdateyear'])); +if (!empty($_POST['enddatemonth'])) + $enddate = date('Y-m-d', dol_mktime(12, 0, 0, $_POST['enddatemonth'], $_POST['enddateday'], $_POST['enddateyear'])); + +/* + * View + */ + +$companystatic = new Societe($db); +$invoicestatic=new Facture($db); + +$form = new Form($db); + +llxHeader('',$langs->trans("Margins").' - '.$langs->trans("Clients")); + +$text=$langs->trans("Margins"); +print_fiche_titre($text); + +// Show tabs +$head=marges_prepare_head($user); +$titre=$langs->trans("Margins"); +$picto='marges@marges'; +dol_fiche_head($head, 'customerMargins', $titre, 0, $picto); + +print '
    '; +print ''; + +$client = null; +if ($socid > 0) { + + $societe = new Societe($db, $socid); + $societe->fetch($socid); + + if ($societe->client) + { + print ''; + print ''; + + $client = true; + if (! $sortorder) $sortorder="DESC"; + if (! $sortfield) $sortfield="f.datef"; + } +} +if (!$client) { + print ''; + print ''; + if (! $sortorder) $sortorder="ASC"; + if (! $sortfield) $sortfield="s.nom"; +} + +// Date début +print ''; +print ''; +print ''; +print ''; +print ''; + +// Total Margin +print ''; + +// Margin Rate +if ($conf->global->DISPLAY_MARGIN_RATES) { + print ''; +} + +// Mark Rate +if ($conf->global->DISPLAY_MARK_RATES) { + print ''; +} + +print "
    '.$langs->trans('ThirdPartyName').''; + $form->form_thirdparty($_SERVER['PHP_SELF'].'?socid='.$socid,$socid,'socid', $filter='client=1',$showempty=1, $showtype=0, $forcecombo=1); + print '
    '.$langs->trans('ThirdPartyName').''; + $form->form_thirdparty($_SERVER['PHP_SELF'].'?socid='.$socid,null,'socid', $filter='client=1',$showempty=1, $showtype=0, $forcecombo=1); + print '
    '.$langs->trans('StartDate').''; +$form->select_date($startdate,'startdate','','',1,"sel",1,1); +print ''.$langs->trans('EndDate').''; +$form->select_date($enddate,'enddate','','',1,"sel",1,1); +print ''; +print ''; +print '
    '.$langs->trans("TotalMargin").''; +print ''; // set by jquery (see below) +print '
    '.$langs->trans("MarginRate").''; + print ''; // set by jquery (see below) + print '
    '.$langs->trans("MarkRate").''; + print ''; // set by jquery (see below) + print '
    "; +print '
    '; + +$sql = "SELECT distinct s.nom, s.rowid as socid, s.code_client, s.client,"; +$sql.= " f.facnumber, f.total as total_ht,"; +$sql.= " sum(d.subprice * d.qty * (1 - d.remise_percent / 100)) as selling_price,"; +$sql.= " sum(d.buy_price_ht * d.qty) as buying_price, sum(((d.subprice * (1 - d.remise_percent / 100)) - d.buy_price_ht) * d.qty) as marge," ; +$sql.= " f.datef, f.paye, f.fk_statut as statut, f.rowid as facid"; +$sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; +$sql.= ", ".MAIN_DB_PREFIX."facture as f"; +$sql.= ", ".MAIN_DB_PREFIX."facturedet as d"; +$sql.= " WHERE f.fk_soc = s.rowid"; +$sql.= " AND f.fk_statut > 0"; +$sql.= " AND s.entity = ".$conf->entity; +$sql.= " AND d.fk_facture = f.rowid"; +if ($client) + $sql.= " AND f.fk_soc = $socid"; +if (!empty($startdate)) + $sql.= " AND f.datef >= '".$startdate."'"; +if (!empty($enddate)) + $sql.= " AND f.datef <= '".$enddate."'"; +if ($client) + $sql.= " GROUP BY f.rowid"; +else + $sql.= " GROUP BY s.rowid"; +$sql.= " ORDER BY $sortfield $sortorder "; +$sql.= $db->plimit($conf->liste_limit +1, $offset); + +$result = $db->query($sql); +if ($result) +{ + $num = $db->num_rows($result); + + print '
    '; + print_barre_liste($langs->trans("MarginDetails"),$page,$_SERVER["PHP_SELF"],"&socid=$societe->id",$sortfield,$sortorder,'',$num,0,''); + + $i = 0; + print ""; + + print ''; + if ($client) { + print_liste_field_titre($langs->trans("Invoice"),$_SERVER["PHP_SELF"],"f.facnumber","","&socid=".$_REQUEST["socid"],'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateInvoice"),$_SERVER["PHP_SELF"],"f.datef","","&socid=".$_REQUEST["socid"],'align="center"',$sortfield,$sortorder); + } + else + print_liste_field_titre($langs->trans("Customer"),$_SERVER["PHP_SELF"],"s.nom","","&socid=".$_REQUEST["socid"],'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("SellingPrice"),$_SERVER["PHP_SELF"],"selling_price","","&socid=".$_REQUEST["socid"],'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("BuyingPrice"),$_SERVER["PHP_SELF"],"buyng_price","","&socid=".$_REQUEST["socid"],'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Margin"),$_SERVER["PHP_SELF"],"marge","","&socid=".$_REQUEST["socid"],'align="right"',$sortfield,$sortorder); + if ($conf->global->DISPLAY_MARGIN_RATES) + print_liste_field_titre($langs->trans("MarginRate"),$_SERVER["PHP_SELF"],"d.marge_tx","","&socid=".$_REQUEST["socid"],'align="right"',$sortfield,$sortorder); + if ($conf->global->DISPLAY_MARK_RATES) + print_liste_field_titre($langs->trans("MarkRate"),$_SERVER["PHP_SELF"],"d.marque_tx","","&socid=".$_REQUEST["socid"],'align="right"',$sortfield,$sortorder); + print "\n"; + + $cumul_achat = 0; + $cumul_vente = 0; + $cumul_qty = 0; + if ($num > 0) + { + $var=True; + while ($i < $num && $i < $conf->liste_limit) + { + $objp = $db->fetch_object($result); + + $marginRate = ($objp->buying_price != 0)?(100 * round($objp->marge / $objp->buying_price ,5)):'' ; + $markRate = ($objp->selling_price != 0)?(100 * round($objp->marge / $objp->selling_price ,5)):'' ; + + $var=!$var; + + print ""; + if ($client) { + print '\n"; + print ""; + } + else { + $companystatic->id=$objp->socid; + $companystatic->nom=$objp->nom; + $companystatic->client=$objp->client; + print "\n"; + } + print "\n"; + print "\n"; + print "\n"; + if ($conf->global->DISPLAY_MARGIN_RATES) + print "\n"; + if ($conf->global->DISPLAY_MARK_RATES) + print "\n"; + print "\n"; + $i++; + $cumul_achat += $objp->buying_price; + $cumul_vente += $objp->selling_price; + } + } + + // affichage totaux marges + $var=!$var; + $totalMargin = $cumul_vente - $cumul_achat; + $marginRate = ($cumul_achat != 0)?(100 * round($totalMargin / $cumul_achat, 5)):'' ; + $markRate = ($cumul_vente != 0)?(100 * round($totalMargin / $cumul_vente, 5)):'' ; + print ''; + if ($client) + print '"; + print "\n"; + print "\n"; + print "\n"; + if ($conf->global->DISPLAY_MARGIN_RATES) + print "\n"; + if ($conf->global->DISPLAY_MARK_RATES) + print "\n"; + print "\n"; + + print "
    '; + $invoicestatic->id=$objp->facid; + $invoicestatic->ref=$objp->facnumber; + print $invoicestatic->getNomUrl(1); + print ""; + print dol_print_date($db->jdate($objp->datef),'day')."".$companystatic->getNomUrl(1,'customer')."".price($objp->selling_price)."".price($objp->buying_price)."".price($objp->marge)."".(($marginRate === '')?'n/a':price($marginRate)."%")."".(($markRate === '')?'n/a':price($markRate)."%")."
    '; + else + print ''; + print $langs->trans('TotalMargin')."".price($cumul_vente)."".price($cumul_achat)."".price($totalMargin)."".(($marginRate === '')?'n/a':price($marginRate)."%")."".(($markRate === '')?'n/a':price($markRate)."%")."
    "; +} +else +{ + dol_print_error($db); +} +$db->free($result); + +$db->close(); + +llxFooter('$Date: 2011/08/08 16:07:47 $ - $Revision: 1.84 $'); +?> + \ No newline at end of file diff --git a/htdocs/marges/img/marges.png b/htdocs/marges/img/marges.png new file mode 100644 index 00000000000..4746f0fc779 Binary files /dev/null and b/htdocs/marges/img/marges.png differ diff --git a/htdocs/marges/img/object_marges.png b/htdocs/marges/img/object_marges.png new file mode 100644 index 00000000000..13e4b92c9ce Binary files /dev/null and b/htdocs/marges/img/object_marges.png differ diff --git a/htdocs/marges/index.php b/htdocs/marges/index.php new file mode 100644 index 00000000000..ff28c32f8a0 --- /dev/null +++ b/htdocs/marges/index.php @@ -0,0 +1,26 @@ + + * + * 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, see . + */ + +/** + * \file htdocs/custom/marges/index.php + * \ingroup product marges + * \brief Page d'index du module marges + */ + +require("./productMargins.php"); + +?> diff --git a/htdocs/marges/lib/marges.lib.php b/htdocs/marges/lib/marges.lib.php new file mode 100644 index 00000000000..f2837a62915 --- /dev/null +++ b/htdocs/marges/lib/marges.lib.php @@ -0,0 +1,108 @@ + + * + * 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/lib/marges.lib.php + * \ingroup marges + * \brief Library for common marges functions + * \version $Id:$ + */ + +/** + * Define head array for tabs of marges tools setup pages + * @return Array of head + */ +function marges_admin_prepare_head() +{ + global $langs, $conf; + + $h = 0; + $head = array(); + + $head[$h][0] = dol_buildpath("/marges/admin/marges.php",1); + $head[$h][1] = $langs->trans("Parameters"); + $head[$h][2] = 'parameters'; + $h++; + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab + // $this->tabs = array('entity:-tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to remove a tab + complete_head_from_modules($conf,$langs,$object,$head,$h,'margesadmin'); + + return $head; +} + +function marges_prepare_head($user) +{ + global $langs, $conf; + $langs->load("marges@marges"); + + $h = 0; + $head = array(); + + $head[$h][0] = DOL_URL_ROOT."/marges/productMargins.php"; + $head[$h][1] = $langs->trans("ProductMargins"); + $head[$h][2] = 'productMargins'; + $h++; + + $head[$h][0] = DOL_URL_ROOT."/marges/customerMargins.php"; + $head[$h][1] = $langs->trans("CustomerMargins"); + $head[$h][2] = 'customerMargins'; + $h++; + + $head[$h][0] = DOL_URL_ROOT."/marges/agentMargins.php"; + $head[$h][1] = $langs->trans("AgentMargins"); + $head[$h][2] = 'agentMargins'; + $h++; + + return $head; +} + +function getMarginInfos($pvht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $paht) { + global $db, $conf; + + if($fk_pa > 0) { + require_once DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.product.class.php"; + $product = new ProductFournisseur($db); + if ($product->fetch_product_fournisseur_price($fk_pa)) { + $paht_ret = $product->fourn_unitprice; + if ($conf->global->MARGIN_TYPE == "2" && $product->fourn_unitcharges > 0) + $paht_ret += $product->fourn_unitcharges; + } + else + $paht_ret = $paht; + } + else + $paht_ret = $paht; + + require_once(DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'); + // calcul pu_ht remisés + $tabprice=calcul_price_total(1, $pvht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, 0, 'HT', $objp->info_bits); + $pu_ht_remise = $tabprice[0]; + // calcul taux marge + if ($paht_ret != 0) + $marge_tx_ret = round((100 * ($pu_ht_remise - $paht_ret)) / $paht_ret, 3); + // calcul taux marque + if ($pu_ht_remise != 0) + $marque_tx_ret = round((100 * ($pu_ht_remise - $paht_ret)) / $pu_ht_remise, 3); + + return array($paht_ret, $marge_tx_ret, $marque_tx_ret); +} +?> \ No newline at end of file diff --git a/htdocs/marges/productMargins.php b/htdocs/marges/productMargins.php new file mode 100644 index 00000000000..d9e5a6af2df --- /dev/null +++ b/htdocs/marges/productMargins.php @@ -0,0 +1,296 @@ + + * + * 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, see . + */ + +/** + * \file htdocs/custom/marges/productMargins.php + * \ingroup marges + * \brief Page des marges par produit + * \version $Id: facture.php,v 1.84 2011/08/08 16:07:47 eldy Exp $ + */ + +require("../main.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/company.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php"); +require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php"); +require_once(DOL_DOCUMENT_ROOT."/marges/lib/marges.lib.php"); + +$langs->load("companies"); +$langs->load("bills"); +$langs->load("products"); +$langs->load("marges"); + +// Security check +if (isset($_REQUEST["id"]) || isset($_REQUEST["ref"])) +{ + $id = isset($_REQUEST["id"])?$_REQUEST["id"]:(isset($_REQUEST["ref"])?$_REQUEST["ref"]:''); +} +$fieldid = isset($_REQUEST["ref"])?'ref':'rowid'; +if ($user->societe_id) $socid=$user->societe_id; +$result=restrictedArea($user,'produit|service',$id,'product','','',$fieldid); + +$mesg = ''; + +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if ($page == -1) { $page = 0; } +$offset = $conf->liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +if (!empty($_POST['startdatemonth'])) + $startdate = date('Y-m-d', dol_mktime(12, 0, 0, $_POST['startdatemonth'], $_POST['startdateday'], $_POST['startdateyear'])); +if (!empty($_POST['enddatemonth'])) + $enddate = date('Y-m-d', dol_mktime(12, 0, 0, $_POST['enddatemonth'], $_POST['enddateday'], $_POST['enddateyear'])); + +/* + * View + */ + +$product_static = new Product($db); +$invoicestatic=new Facture($db); + +$form = new Form($db); + +llxHeader('',$langs->trans("Margins").' - '.$langs->trans("Products")); + +$text=$langs->trans("Margins"); + +print_fiche_titre($text); + +// Show tabs +$head=marges_prepare_head($user); +$titre=$langs->trans("Margins"); +$picto='marges@marges'; +dol_fiche_head($head, 'productMargins', $titre, 0, $picto); + +print '
    '; +print ''; + +if ($id > 0) { + + $societe = new Societe($db, $socid); + $societe->fetch($socid); + + print ''; + print ''; + + print ''; + print ''; + + if (! $sortorder) $sortorder="DESC"; + if (! $sortfield) $sortfield="f.datef"; +} +else { + print ''; + print ''; + if (! $sortorder) $sortorder="ASC"; + if (! $sortfield) $sortfield="p.ref"; +} + +// Date début +print ''; +print ''; +print ''; +print ''; +print ''; + +// Total Margin +print ''; + +// Margin Rate +if ($conf->global->DISPLAY_MARGIN_RATES) { + print ''; +} + +// Mark Rate +if ($conf->global->DISPLAY_MARK_RATES) { + print ''; +} + +print "
    '.$langs->trans('ChooseProduct/Service').''; + print $form->select_produits($selected=$id,$htmlname='id',$filtertype='',$limit=20,$price_level=0,$status=1,$finished=2,$selected_input_value='',$hidelabel=1); + print '
    '.$langs->trans('AllProducts').'
    '.$langs->trans('ChooseProduct/Service').''; + print $form->select_produits($selected='',$htmlname='id',$filtertype='',$limit=20,$price_level=0,$status=1,$finished=2,$selected_input_value='',$hidelabel=1); + print '
    '.$langs->trans('StartDate').''; +$form->select_date($startdate,'startdate','','',1,"sel",1,1); +print ''.$langs->trans('EndDate').''; +$form->select_date($enddate,'enddate','','',1,"sel",1,1); +print ''; +print ''; +print '
    '.$langs->trans("TotalMargin").''; +print ''; // set by jquery (see below) +print '
    '.$langs->trans("MarginRate").''; + print ''; // set by jquery (see below) + print '
    '.$langs->trans("MarkRate").''; + print ''; // set by jquery (see below) + print '
    "; +print '
    '; + +$sql = "SELECT distinct d.fk_product, p.label, p.rowid, p.fk_product_type, p.ref,"; +$sql.= " f.facnumber, f.total as total_ht,"; +$sql.= " sum(d.subprice * d.qty * (1 - d.remise_percent / 100)) as selling_price,"; +$sql.= " sum(d.buy_price_ht * d.qty) as buying_price, sum(((d.subprice * (1 - d.remise_percent / 100)) - d.buy_price_ht) * d.qty) as marge," ; +$sql.= " f.datef, f.paye, f.fk_statut as statut, f.rowid as facid"; +$sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; +$sql.= ", ".MAIN_DB_PREFIX."product as p"; +$sql.= ", ".MAIN_DB_PREFIX."facture as f"; +$sql.= ", ".MAIN_DB_PREFIX."facturedet as d"; +$sql.= " WHERE f.fk_soc = s.rowid"; +$sql.= " AND d.fk_product = p.rowid"; +$sql.= " AND f.fk_statut > 0"; +$sql.= " AND s.entity = ".$conf->entity; +$sql.= " AND d.fk_facture = f.rowid"; +if ($id > 0) + $sql.= " AND d.fk_product =".$id; +if (!empty($startdate)) + $sql.= " AND f.datef >= '".$startdate."'"; +if (!empty($enddate)) + $sql.= " AND f.datef <= '".$enddate."'"; +if ($id > 0) + $sql.= " GROUP BY f.rowid"; +else + $sql.= " GROUP BY d.fk_product"; +$sql.= " ORDER BY $sortfield $sortorder "; +$sql.= $db->plimit($conf->liste_limit +1, $offset); + +$result = $db->query($sql); +if ($result) +{ + $num = $db->num_rows($result); + + print '
    '; + print_barre_liste($langs->trans("MarginDetails"),$page,$_SERVER["PHP_SELF"],"&id=$product->id",$sortfield,$sortorder,'',$num,0,''); + + $i = 0; + print ""; + + print ''; + if ($id > 0) { + print_liste_field_titre($langs->trans("Invoice"),$_SERVER["PHP_SELF"],"f.facnumber","","&id=".$_REQUEST["id"],'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateInvoice"),$_SERVER["PHP_SELF"],"f.datef","","&id=".$_REQUEST["id"],'align="center"',$sortfield,$sortorder); + } + else + print_liste_field_titre($langs->trans("ProductService"),$_SERVER["PHP_SELF"],"p.ref","","&id=".$_REQUEST["id"],'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("SellingPrice"),$_SERVER["PHP_SELF"],"selling_price","","&id=".$_REQUEST["id"],'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("BuyingPrice"),$_SERVER["PHP_SELF"],"buyng_price","","&id=".$_REQUEST["id"],'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Margin"),$_SERVER["PHP_SELF"],"marge","","&id=".$_REQUEST["id"],'align="right"',$sortfield,$sortorder); + if ($conf->global->DISPLAY_MARGIN_RATES) + print_liste_field_titre($langs->trans("MarginRate"),$_SERVER["PHP_SELF"],"d.marge_tx","","&id=".$_REQUEST["id"],'align="right"',$sortfield,$sortorder); + if ($conf->global->DISPLAY_MARK_RATES) + print_liste_field_titre($langs->trans("MarkRate"),$_SERVER["PHP_SELF"],"d.marque_tx","","&id=".$_REQUEST["id"],'align="right"',$sortfield,$sortorder); + print "\n"; + + $cumul_achat = 0; + $cumul_vente = 0; + $cumul_qty = 0; + if ($num > 0) + { + $var=True; + while ($i < $num && $i < $conf->liste_limit) + { + $objp = $db->fetch_object($result); + + $marginRate = ($objp->buying_price != 0)?(100 * round($objp->marge / $objp->buying_price ,5)):'' ; + $markRate = ($objp->selling_price != 0)?(100 * round($objp->marge / $objp->selling_price ,5)):'' ; + + $var=!$var; + + print ""; + if ($id > 0) { + print '\n"; + print ""; + } + else { + $product_static->type=$objp->fk_product_type; + $product_static->id=$objp->fk_product; + $product_static->ref=$objp->ref; + $product_static->libelle=$objp->label; + $text=$product_static->getNomUrl(1); + $text.= ' - '.$objp->label; + print "\n"; + } + print "\n"; + print "\n"; + print "\n"; + if ($conf->global->DISPLAY_MARGIN_RATES) + print "\n"; + if ($conf->global->DISPLAY_MARK_RATES) + print "\n"; + print "\n"; + $i++; + $cumul_achat += $objp->buying_price; + $cumul_vente += $objp->selling_price; + } + } + + // affichage totaux marges + $var=!$var; + $totalMargin = $cumul_vente - $cumul_achat; + $marginRate = ($cumul_achat != 0)?(100 * round($totalMargin / $cumul_achat, 5)):'' ; + $markRate = ($cumul_vente != 0)?(100 * round($totalMargin / $cumul_vente, 5)):'' ; + print ''; + if ($id > 0) + print '"; + print "\n"; + print "\n"; + print "\n"; + if ($conf->global->DISPLAY_MARGIN_RATES) + print "\n"; + if ($conf->global->DISPLAY_MARK_RATES) + print "\n"; + print "\n"; + + print "
    '; + $invoicestatic->id=$objp->facid; + $invoicestatic->ref=$objp->facnumber; + print $invoicestatic->getNomUrl(1); + print ""; + print dol_print_date($db->jdate($objp->datef),'day')."".$product_static->getNomUrl(1)."".price($objp->selling_price)."".price($objp->buying_price)."".price($objp->marge)."".(($marginRate === '')?'n/a':price($marginRate)."%")."".(($markRate === '')?'n/a':price($markRate)."%")."
    '; + else + print ''; + print $langs->trans('TotalMargin')."".price($cumul_vente)."".price($cumul_achat)."".price($totalMargin)."".(($marginRate === '')?'n/a':price($marginRate)."%")."".(($markRate === '')?'n/a':price($markRate)."%")."
    "; +} +else +{ + dol_print_error($db); +} +$db->free($result); + +$db->close(); + +llxFooter('$Date: 2011/08/08 16:07:47 $ - $Revision: 1.84 $'); +?> + \ No newline at end of file diff --git a/htdocs/marges/tabs/productMargins.php b/htdocs/marges/tabs/productMargins.php new file mode 100644 index 00000000000..3b109b9b77c --- /dev/null +++ b/htdocs/marges/tabs/productMargins.php @@ -0,0 +1,261 @@ + + * + * 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, see . + */ + +/** + * \file htdocs/custom/marges/tabs/productMargins.php + * \ingroup product marges + * \brief Page des marges des factures clients pour un produit + * \version $Id: facture.php,v 1.84 2011/08/08 16:07:47 eldy Exp $ + */ + +require("../../main.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/product.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php"); +require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php"); + +$langs->load("companies"); +$langs->load("bills"); +$langs->load("products"); +$langs->load("marges"); + +// Security check +if (isset($_GET["id"]) || isset($_GET["ref"])) +{ + $id = isset($_GET["id"])?$_GET["id"]:(isset($_GET["ref"])?$_GET["ref"]:''); +} +$fieldid = isset($_GET["ref"])?'ref':'rowid'; +if ($user->societe_id) $socid=$user->societe_id; +$result=restrictedArea($user,'produit|service',$id,'product','','',$fieldid); + +$mesg = ''; + +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if ($page == -1) { $page = 0; } +$offset = $conf->liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortorder) $sortorder="DESC"; +if (! $sortfield) $sortfield="f.datef"; + + +/* + * View + */ + +$invoicestatic=new Facture($db); + +$html = new Form($db); + + +if ($_GET["id"] || $_GET["ref"]) +{ + $product = new Product($db); + if ($_GET["ref"]) + { + $result = $product->fetch('',$_GET["ref"]); + $_GET["id"]=$product->id; + } + if ($_GET["id"]) $result = $product->fetch($_GET["id"]); + + llxHeader("","",$langs->trans("CardProduct".$product->type)); + + /* + * En mode visu + */ + if ($result > 0) + { + $head=product_prepare_head($product, $user); + $titre=$langs->trans("CardProduct".$product->type); + $picto=($product->type==1?'service':'product'); + dol_fiche_head($head, 'marges', $titre, 0, $picto); + + print ''; + + // Reference + print ''; + print ''; + print ''; + + // Libelle + print ''; + print ''; + + // Status (to sell) + print ''; + + // Status (to buy) + print ''; + + // Total Margin + print ''; + + // Margin Rate + if ($conf->global->DISPLAY_MARGIN_RATES) { + print ''; + } + + // Mark Rate + if ($conf->global->DISPLAY_MARK_RATES) { + print ''; + } + + print "
    '.$langs->trans("Ref").''; + print $html->showrefnav($product,'ref','',1,'ref'); + print '
    '.$langs->trans("Label").''.$product->libelle.'
    '.$langs->trans("Status").' ('.$langs->trans("Sell").')'.''; + print $product->getLibStatut(2,0); + print '
    '.$langs->trans("Status").' ('.$langs->trans("Buy").')'.''; + print $product->getLibStatut(2,1); + print '
    '.$langs->trans("TotalMargin").''; + print ''; // set by jquery (see below) + print '
    '.$langs->trans("MarginRate").''; + print ''; // set by jquery (see below) + print '
    '.$langs->trans("MarkRate").''; + print ''; // set by jquery (see below) + print '
    "; + print ''; + + + $sql = "SELECT distinct s.nom, s.rowid as socid, s.code_client,"; + $sql.= " f.facnumber, f.total as total_ht,"; + $sql.= " (d.subprice * d.qty * (1 - d.remise_percent / 100)) as selling_price, (d.buy_price_ht * d.qty) as buying_price, d.qty, ((d.subprice - d.buy_price_ht) * d.qty) as marge," ; + $sql.= " f.datef, f.paye, f.fk_statut as statut, f.rowid as facid"; + if (!$user->rights->societe->client->voir && !$socid) $sql.= ", sc.fk_soc, sc.fk_user "; + $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; + $sql.= ", ".MAIN_DB_PREFIX."facture as f"; + $sql.= ", ".MAIN_DB_PREFIX."facturedet as d"; + if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE f.fk_soc = s.rowid"; + $sql.= " AND f.fk_statut > 0"; + $sql.= " AND s.entity = ".$conf->entity; + $sql.= " AND d.fk_facture = f.rowid"; + $sql.= " AND d.fk_product =".$product->id; + if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + if ($socid) $sql.= " AND f.fk_soc = $socid"; + $sql.= " ORDER BY $sortfield $sortorder "; + $sql.= $db->plimit($conf->liste_limit +1, $offset); + + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); + + print_barre_liste($langs->trans("MarginDetails"),$page,$_SERVER["PHP_SELF"],"&id=$product->id",$sortfield,$sortorder,'',$num,0,''); + + $i = 0; + print ""; + + print ''; + print_liste_field_titre($langs->trans("Invoice"),$_SERVER["PHP_SELF"],"f.facnumber","","&id=".$_GET["id"],'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"s.nom","","&id=".$_GET["id"],'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("CustomerCode"),$_SERVER["PHP_SELF"],"s.code_client","","&id=".$_GET["id"],'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateInvoice"),$_SERVER["PHP_SELF"],"f.datef","","&id=".$_GET["id"],'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("SellingPrice"),$_SERVER["PHP_SELF"],"selling_price","","&id=".$_GET["id"],'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("BuyingPrice"),$_SERVER["PHP_SELF"],"buyng_price","","&id=".$_GET["id"],'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Qty"),$_SERVER["PHP_SELF"],"d.qty","","&id=".$_GET["id"],'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Margin"),$_SERVER["PHP_SELF"],"marge","","&id=".$_GET["id"],'align="right"',$sortfield,$sortorder); + if ($conf->global->DISPLAY_MARGIN_RATES) + print_liste_field_titre($langs->trans("MarginRate"),$_SERVER["PHP_SELF"],"d.marge_tx","","&id=".$_GET["id"],'align="right"',$sortfield,$sortorder); + if ($conf->global->DISPLAY_MARK_RATES) + print_liste_field_titre($langs->trans("MarkRate"),$_SERVER["PHP_SELF"],"d.marque_tx","","&id=".$_GET["id"],'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"f.paye,f.fk_statut","","&id=".$_GET["id"],'align="right"',$sortfield,$sortorder); + print "\n"; + + $cumul_achat = 0; + $cumul_vente = 0; + $cumul_qty = 0; + if ($num > 0) + { + $var=True; + while ($i < $num && $i < $conf->liste_limit) + { + $objp = $db->fetch_object($result); + $var=!$var; + + $marginRate = ($objp->buying_price != 0)?(100 * round($objp->marge / $objp->buying_price ,5)):'' ; + $markRate = ($objp->selling_price != 0)?(100 * round($objp->marge / $objp->selling_price ,5)):'' ; + print ""; + print '\n"; + print ''; + print "\n"; + print ""; + print "\n"; + print "\n"; + print "\n"; + print "\n"; + if ($conf->global->DISPLAY_MARGIN_RATES) + print "\n"; + if ($conf->global->DISPLAY_MARK_RATES) + print "\n"; + print ''; + print "\n"; + $i++; + $cumul_achat += $objp->buying_price; + $cumul_vente += $objp->selling_price; + $cumul_qty += $objp->qty; + } + } + + // affichage totaux marges + $var=!$var; + $totalMargin = $cumul_vente - $cumul_achat; + $marginRate = ($cumul_achat != 0)?(100 * round($totalMargin / $cumul_achat, 5)):''; + $markRate = ($cumul_vente != 0)?(100 * round($totalMargin / $cumul_vente ,5)):''; + print ''; + print '"; + print "\n"; + print "\n"; + print "\n"; + print "\n"; + if ($conf->global->DISPLAY_MARGIN_RATES) + print "\n"; + if ($conf->global->DISPLAY_MARK_RATES) + print "\n"; + print ''; + print "\n"; + } + else + { + dol_print_error($db); + } + print "
    '; + $invoicestatic->id=$objp->facid; + $invoicestatic->ref=$objp->facnumber; + print $invoicestatic->getNomUrl(1); + print "'.img_object($langs->trans("ShowCompany"),"company").' '.dol_trunc($objp->nom,44).'".$objp->code_client.""; + print dol_print_date($db->jdate($objp->datef),'day')."".price($objp->selling_price)."".price($objp->buying_price)."".price($objp->qty)."".price($objp->marge)."".(($marginRate === '')?'n/a':price($marginRate)."%")."".(($markRate === '')?'n/a':price($markRate)."%")."'.$invoicestatic->LibStatut($objp->paye,$objp->statut,5).'
    '.$langs->trans('TotalMargin')."".price($cumul_vente)."".price($cumul_achat)."".price($cumul_qty)."".price($totalMargin)."".(($marginRate === '')?'n/a':price($marginRate)."%")."".(($markRate === '')?'n/a':price($markRate)."%")." 
    "; + print '
    '; + $db->free($result); + } +} +else +{ + dol_print_error(); +} + +$db->close(); + +llxFooter('$Date: 2011/08/08 16:07:47 $ - $Revision: 1.84 $'); +?> + \ No newline at end of file diff --git a/htdocs/marges/tabs/thirdpartyMargins.php b/htdocs/marges/tabs/thirdpartyMargins.php new file mode 100644 index 00000000000..a4cc52c89df --- /dev/null +++ b/htdocs/marges/tabs/thirdpartyMargins.php @@ -0,0 +1,247 @@ + + * + * 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, see . + */ + +/** + * \file htdocs/custom/marges/tabs/thirdpartyMargins.php + * \ingroup product marges + * \brief Page des marges des factures clients pour un tiers + * \version $Id: facture.php,v 1.84 2011/08/08 16:07:47 eldy Exp $ + */ + +require("../../main.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/company.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php"); +require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php"); + +$langs->load("companies"); +$langs->load("bills"); +$langs->load("products"); +$langs->load("marges"); + +// Security check +$socid = isset($_GET["socid"])?$_GET["socid"]:''; +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'societe','',''); + + +$mesg = ''; + +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if ($page == -1) { $page = 0; } +$offset = $conf->liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortorder) $sortorder="DESC"; +if (! $sortfield) $sortfield="f.datef"; + + +/* + * View + */ + +$invoicestatic=new Facture($db); +$form = new Form($db); + +$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; +llxHeader('',$langs->trans("ThirdParty").' - '.$langs->trans("Margins"),$help_url); + +if ($socid > 0) +{ + $societe = new Societe($db, $socid); + $societe->fetch($socid); + + /* + * Affichage onglets + */ + + $head = societe_prepare_head($societe); + + dol_fiche_head($head, 'marges', $langs->trans("ThirdParty"),0,'company'); + + print ''; + + print ''; + print ''; + + if (! empty($conf->global->SOCIETE_USEPREFIX)) // Old not used prefix field + { + print ''; + } + + if ($societe->client) + { + print ''; + } + + if ($societe->fournisseur) + { + print ''; + } + + // Total Margin + print ''; + + // Margin Rate + if ($conf->global->DISPLAY_MARGIN_RATES) { + print ''; + } + + // Mark Rate + if ($conf->global->DISPLAY_MARK_RATES) { + print ''; + } + + print "
    '.$langs->trans('ThirdPartyName').''; + print $form->showrefnav($societe,'socid','',($user->societe_id?0:1),'rowid','nom'); + print '
    '.$langs->trans('Prefix').''.$societe->prefix_comm.'
    '; + print $langs->trans('CustomerCode').''; + print $societe->code_client; + if ($societe->check_codeclient() <> 0) print ' ('.$langs->trans("WrongCustomerCode").')'; + print '
    '; + print $langs->trans('SupplierCode').''; + print $societe->code_fournisseur; + if ($societe->check_codefournisseur() <> 0) print ' ('.$langs->trans("WrongSupplierCode").')'; + print '
    '.$langs->trans("TotalMargin").''; + print ''; // set by jquery (see below) + print '
    '.$langs->trans("MarginRate").''; + print ''; // set by jquery (see below) + print '
    '.$langs->trans("MarkRate").''; + print ''; // set by jquery (see below) + print '
    "; + print ''; + + + $sql = "SELECT distinct s.nom, s.rowid as socid, s.code_client,"; + $sql.= " f.facnumber, f.total as total_ht,"; + $sql.= " sum(d.subprice * d.qty * (1 - d.remise_percent / 100)) as selling_price, sum(d.buy_price_ht * d.qty) as buying_price, sum(((d.subprice * (1 - d.remise_percent / 100)) - d.buy_price_ht) * d.qty) as marge," ; + $sql.= " f.datef, f.paye, f.fk_statut as statut, f.rowid as facid"; + $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; + $sql.= ", ".MAIN_DB_PREFIX."facture as f"; + $sql.= ", ".MAIN_DB_PREFIX."facturedet as d"; + $sql.= " WHERE f.fk_soc = s.rowid"; + $sql.= " AND f.fk_statut > 0"; + $sql.= " AND s.entity = ".$conf->entity; + $sql.= " AND d.fk_facture = f.rowid"; + $sql.= " AND f.fk_soc = $socid"; + $sql.= " GROUP BY f.rowid"; + $sql.= " ORDER BY $sortfield $sortorder "; + $sql.= $db->plimit($conf->liste_limit +1, $offset); + + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); + + print_barre_liste($langs->trans("MarginDetails"),$page,$_SERVER["PHP_SELF"],"&socid=$societe->id",$sortfield,$sortorder,'',$num,0,''); + + $i = 0; + print ""; + + print ''; + print_liste_field_titre($langs->trans("Invoice"),$_SERVER["PHP_SELF"],"f.facnumber","","&socid=".$_REQUEST["socid"],'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateInvoice"),$_SERVER["PHP_SELF"],"f.datef","","&socid=".$_REQUEST["socid"],'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("SellingPrice"),$_SERVER["PHP_SELF"],"selling_price","","&socid=".$_REQUEST["socid"],'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("BuyingPrice"),$_SERVER["PHP_SELF"],"buyng_price","","&socid=".$_REQUEST["socid"],'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Margin"),$_SERVER["PHP_SELF"],"marge","","&socid=".$_REQUEST["socid"],'align="right"',$sortfield,$sortorder); + if ($conf->global->DISPLAY_MARGIN_RATES) + print_liste_field_titre($langs->trans("MarginRate"),$_SERVER["PHP_SELF"],"d.marge_tx","","&socid=".$_REQUEST["socid"],'align="right"',$sortfield,$sortorder); + if ($conf->global->DISPLAY_MARK_RATES) + print_liste_field_titre($langs->trans("MarkRate"),$_SERVER["PHP_SELF"],"d.marque_tx","","&socid=".$_REQUEST["socid"],'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"f.paye,f.fk_statut","","&socid=".$_REQUEST["socid"],'align="right"',$sortfield,$sortorder); + print "\n"; + + $cumul_achat = 0; + $cumul_vente = 0; + $cumul_qty = 0; + if ($num > 0) + { + $var=True; + while ($i < $num && $i < $conf->liste_limit) + { + $objp = $db->fetch_object($result); + + $marginRate = ($objp->buying_price != 0)?(100 * round($objp->marge / $objp->buying_price ,5)):'' ; + $markRate = ($objp->selling_price != 0)?(100 * round($objp->marge / $objp->selling_price ,5)):'' ; + + $var=!$var; + + print ""; + print '\n"; + print ""; + print "\n"; + print "\n"; + print "\n"; + if ($conf->global->DISPLAY_MARGIN_RATES) + print "\n"; + if ($conf->global->DISPLAY_MARK_RATES) + print "\n"; + print ''; + print "\n"; + $i++; + $cumul_achat += $objp->buying_price; + $cumul_vente += $objp->selling_price; + } + } + + // affichage totaux marges + $var=!$var; + $totalMargin = $cumul_vente - $cumul_achat; + $marginRate = ($cumul_achat != 0)?(100 * round($totalMargin / $cumul_achat, 5)):'' ; + $markRate = ($cumul_vente != 0)?(100 * round($totalMargin / $cumul_vente, 5)):'' ; + print ''; + print '"; + print "\n"; + print "\n"; + print "\n"; + if ($conf->global->DISPLAY_MARGIN_RATES) + print "\n"; + if ($conf->global->DISPLAY_MARK_RATES) + print "\n"; + print ''; + print "\n"; + } + else + { + dol_print_error($db); + } + print "
    '; + $invoicestatic->id=$objp->facid; + $invoicestatic->ref=$objp->facnumber; + print $invoicestatic->getNomUrl(1); + print ""; + print dol_print_date($db->jdate($objp->datef),'day')."".price($objp->selling_price)."".price($objp->buying_price)."".price($objp->marge)."".(($marginRate === '')?'n/a':price($marginRate)."%")."".(($markRate === '')?'n/a':price($markRate)."%")."'.$invoicestatic->LibStatut($objp->paye,$objp->statut,5).'
    '.$langs->trans('TotalMargin')."".price($cumul_vente)."".price($cumul_achat)."".price($totalMargin)."".(($marginRate === '')?'n/a':price($marginRate)."%")."".(($markRate === '')?'n/a':price($markRate)."%")." 
    "; + print '
    '; + $db->free($result); +} +else +{ + dol_print_error(); +} + +$db->close(); + +llxFooter('$Date: 2011/08/08 16:07:47 $ - $Revision: 1.84 $'); +?> + \ No newline at end of file diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 27a27cb98c1..83178537734 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -4,6 +4,7 @@ * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005-2012 Regis Houssin * 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 @@ -151,7 +152,10 @@ if ($action == 'updateprice' && $_POST["cancel"] <> $langs->trans("Cancel")) $supplier=new Fournisseur($db); $result=$supplier->fetch($id_fourn); - $ret=$product->update_buyprice($quantity, $_POST["price"], $user, $_POST["price_base_type"], $supplier, $_POST["oselDispo"], $ref_fourn, $tva_tx); + if (isset($_POST['ref_fourn_price_id'])) + $product->fetch_product_fournisseur_price($_POST['ref_fourn_price_id']); + + $ret=$product->update_buyprice($quantity, $_POST["price"], $_POST["charges"], $user, $_POST["price_base_type"], $supplier, $_POST["oselDispo"], $ref_fourn, $tva_tx); if ($ret < 0) { $error++; @@ -267,7 +271,7 @@ if ($id || $ref) print ''; - print ''; // Ref supplier - print ''; print ''; + print ''; + print ''; + print '
    '.$langs->trans("Supplier").''; + print '
    '.$langs->trans("Supplier").''; if ($_GET["rowid"]) { $supplier=new Fournisseur($db); @@ -292,7 +296,7 @@ if ($id || $ref) print '
    '.$langs->trans("SupplierRef").''; + print '
    '.$langs->trans("SupplierRef").''; if ($_GET["rowid"]) { print $product->fourn_ref; @@ -344,6 +348,10 @@ if ($id || $ref) print '
    '.$langs->trans("Charges").'fourn_charges)).'">'; + print '
    '; print '
    '; @@ -389,7 +397,9 @@ if ($id || $ref) print_liste_field_titre($langs->trans("QtyMin"),$_SERVER["PHP_SELF"],"pfp.quantity","",$param,'align="right"',$sortfield,$sortorder); print ''.$langs->trans("VATRate").''; print ''.$langs->trans("PriceQtyMinHT").''; + print ''.$langs->trans("Charges").''; print_liste_field_titre($langs->trans("UnitPriceHT"),$_SERVER["PHP_SELF"],"pfp.unitprice","",$param,'align="right"',$sortfield,$sortorder); + print ''.$langs->trans("UnitCharges").''; print ''; print "\n"; @@ -434,12 +444,22 @@ if ($id || $ref) print $productfourn->fourn_price?price($productfourn->fourn_price):""; print ''; + // Charges + print ''; + print $productfourn->fourn_charges?price($productfourn->fourn_charges):""; + print ''; + // Unit price print ''; print price($productfourn->fourn_unitprice); //print $objp->unitprice? price($objp->unitprice) : ($objp->quantity?price($objp->price/$objp->quantity):" "); print ''; + // Unit Charges + print ''; + print $productfourn->fourn_unitcharges?price($productfourn->fourn_unitcharges) : ($productfourn->fourn_qty?price($productfourn->fourn_charges/$productfourn->fourn_qty):" "); + print ''; + // Modify-Remove print ''; if ($user->rights->produit->creer || $user->rights->service->creer) diff --git a/htdocs/theme/eldy/img/menus/marges.png b/htdocs/theme/eldy/img/menus/marges.png new file mode 100644 index 00000000000..4746f0fc779 Binary files /dev/null and b/htdocs/theme/eldy/img/menus/marges.png differ