Merge pull request #1430 from FHenry/develop
Price management enhancement (multiprice level, price by … customer, if MAIN_FEATURES_LEVEL=2 Price by qty)
This commit is contained in:
commit
28739414f2
@ -23,6 +23,8 @@ For users:
|
||||
- New: Increase length of url into bookmark module.
|
||||
- New: Add an admin page to make a mass init of barcode values for all products.
|
||||
- New: Automatic events for sending mails showing info about mail linked objects.
|
||||
- New: Price management enhancement (multiprice level, price by customer, if MAIN_FEATURES_LEVEL=2 Price by qty)
|
||||
- Fix: Project Task numbering rule customs rule works
|
||||
|
||||
TODO
|
||||
- New: Predefined product and free product use same form.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -105,8 +105,7 @@ if ($action == 'presend' && GETPOST('sendmail'))
|
||||
$message = $conf->global->RELANCES_MASSE_TEXTE_EMAIL;
|
||||
$subject = $conf->global->RELANCES_MASSE_OBJET_EMAIL;
|
||||
|
||||
$substitutionarray=
|
||||
make_substitutions($message, $substitutionarray);
|
||||
$substitutionarray=make_substitutions($message, $substitutionarray);
|
||||
|
||||
$actiontypecode='AC_FAC';
|
||||
$actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n";
|
||||
|
||||
@ -1264,9 +1264,10 @@ class Form
|
||||
* @param string $selected_input_value Value of preselected input text (with ajax)
|
||||
* @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
|
||||
* @param array $ajaxoptions Options for ajax_autocompleter
|
||||
* @param int $socid Thridparty Id
|
||||
* @return void
|
||||
*/
|
||||
function select_produits($selected='', $htmlname='productid', $filtertype='', $limit=20, $price_level=0, $status=1, $finished=2, $selected_input_value='', $hidelabel=0, $ajaxoptions=array())
|
||||
function select_produits($selected='', $htmlname='productid', $filtertype='', $limit=20, $price_level=0, $status=1, $finished=2, $selected_input_value='', $hidelabel=0, $ajaxoptions=array(),$socid=0)
|
||||
{
|
||||
global $langs,$conf;
|
||||
|
||||
@ -1285,6 +1286,10 @@ class Form
|
||||
}
|
||||
// mode=1 means customers products
|
||||
$urloption='htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=1&status='.$status.'&finished='.$finished;
|
||||
//Price by customer
|
||||
if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
|
||||
$urloption.='&socid='.$socid;
|
||||
}
|
||||
print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions);
|
||||
if (empty($hidelabel)) print $langs->trans("RefOrLabel").' : ';
|
||||
else if ($hidelabel > 1) {
|
||||
@ -1301,7 +1306,7 @@ class Form
|
||||
}
|
||||
else
|
||||
{
|
||||
print $this->select_produits_list($selected,$htmlname,$filtertype,$limit,$price_level,'',$status,$finished,0);
|
||||
print $this->select_produits_list($selected,$htmlname,$filtertype,$limit,$price_level,'',$status,$finished,0,$socid);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1317,9 +1322,10 @@ class Form
|
||||
* @param int $status -1=Return all products, 0=Products not on sell, 1=Products on sell
|
||||
* @param int $finished Filter on finished field: 2=No filter
|
||||
* @param int $outputmode 0=HTML select string, 1=Array
|
||||
* @param int $socid Thridparty Id
|
||||
* @return array Array of keys for json
|
||||
*/
|
||||
function select_produits_list($selected='',$htmlname='productid',$filtertype='',$limit=20,$price_level=0,$filterkey='',$status=1,$finished=2,$outputmode=0)
|
||||
function select_produits_list($selected='',$htmlname='productid',$filtertype='',$limit=20,$price_level=0,$filterkey='',$status=1,$finished=2,$outputmode=0,$socid=0)
|
||||
{
|
||||
global $langs,$conf,$user,$db;
|
||||
|
||||
@ -1328,6 +1334,13 @@ class Form
|
||||
|
||||
$sql = "SELECT ";
|
||||
$sql.= " p.rowid, p.label, p.ref, p.description, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.duration, p.stock";
|
||||
|
||||
//Price by customer
|
||||
if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
|
||||
$sql.=' ,pcp.rowid as idprodcustprice, pcp.price as custprice, pcp.price_ttc as custprice_ttc,';
|
||||
$sql.=' pcp.price_base_type as custprice_base_type, pcp.tva_tx as custtva_tx';
|
||||
}
|
||||
|
||||
// Multilang : we add translation
|
||||
if (! empty($conf->global->MAIN_MULTILANGS))
|
||||
{
|
||||
@ -1337,15 +1350,19 @@ class Form
|
||||
if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY))
|
||||
{
|
||||
$sql.= ", (SELECT pp.rowid FROM ".MAIN_DB_PREFIX."product_price as pp WHERE pp.fk_product = p.rowid";
|
||||
if ($price_level >= 1) $sql.= " AND price_level=".$price_level;
|
||||
if ($price_level >= 1 && !empty($conf->global->PRODUIT_MULTIPRICES)) $sql.= " AND price_level=".$price_level;
|
||||
$sql.= " ORDER BY date_price";
|
||||
$sql.= " DESC LIMIT 1) as price_rowid";
|
||||
$sql.= ", (SELECT pp.price_by_qty FROM ".MAIN_DB_PREFIX."product_price as pp WHERE pp.fk_product = p.rowid";
|
||||
if ($price_level >= 1) $sql.= " AND price_level=".$price_level;
|
||||
if ($price_level >= 1 && !empty($conf->global->PRODUIT_MULTIPRICES)) $sql.= " AND price_level=".$price_level;
|
||||
$sql.= " ORDER BY date_price";
|
||||
$sql.= " DESC LIMIT 1) as price_by_qty";
|
||||
}
|
||||
$sql.= " FROM ".MAIN_DB_PREFIX."product as p";
|
||||
//Price by customer
|
||||
if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
|
||||
$sql.=" LEFT JOIN ".MAIN_DB_PREFIX."product_customer_price as pcp ON pcp.fk_soc=".$socid." AND pcp.fk_product=p.rowid";
|
||||
}
|
||||
// Multilang : we add translation
|
||||
if (! empty($conf->global->MAIN_MULTILANGS))
|
||||
{
|
||||
@ -1407,7 +1424,7 @@ class Form
|
||||
$optJson = array();
|
||||
$objp = $this->db->fetch_object($result);
|
||||
|
||||
if (!empty($objp->price_by_qty) && $objp->price_by_qty == 1)
|
||||
if (!empty($objp->price_by_qty) && $objp->price_by_qty == 1 && !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY))
|
||||
{ // Price by quantity will return many prices for the same product
|
||||
$sql = "SELECT rowid, quantity, price, unitprice, remise_percent, remise";
|
||||
$sql.= " FROM ".MAIN_DB_PREFIX."product_price_by_qty";
|
||||
@ -1523,7 +1540,7 @@ class Form
|
||||
$found=0;
|
||||
|
||||
// Multiprice
|
||||
if ($price_level >= 1) // If we need a particular price level (from 1 to 6)
|
||||
if ($price_level >= 1 && $conf->global->PRODUIT_MULTIPRICES) // If we need a particular price level (from 1 to 6)
|
||||
{
|
||||
$sql = "SELECT price, price_ttc, price_base_type, tva_tx";
|
||||
$sql.= " FROM ".MAIN_DB_PREFIX."product_price";
|
||||
@ -1533,7 +1550,7 @@ class Form
|
||||
$sql.= " ORDER BY date_price";
|
||||
$sql.= " DESC LIMIT 1";
|
||||
|
||||
dol_syslog(get_class($this)."::constructProductListOption search price for level '.$price_level.' sql=".$sql);
|
||||
dol_syslog(get_class($this).'::constructProductListOption search price for level '.$price_level.' sql='.$sql);
|
||||
$result2 = $this->db->query($sql);
|
||||
if ($result2)
|
||||
{
|
||||
@ -1564,7 +1581,7 @@ class Form
|
||||
}
|
||||
|
||||
// Price by quantity
|
||||
if (!empty($objp->quantity) && $objp->quantity >= 1)
|
||||
if (!empty($objp->quantity) && $objp->quantity >= 1 && $conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)
|
||||
{
|
||||
$found = 1;
|
||||
$outqty=$objp->quantity;
|
||||
@ -1599,6 +1616,29 @@ class Form
|
||||
$opt.=" - ".$langs->trans("Discount")." : ".vatrate($objp->remise_percent).' %';
|
||||
$outval.=" - ".$langs->transnoentities("Discount")." : ".vatrate($objp->remise_percent).' %';
|
||||
}
|
||||
|
||||
//Price by customer
|
||||
if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
|
||||
if (!empty($objp->idprodcustprice)) {
|
||||
$found = 1;
|
||||
|
||||
if ($objp->custprice_base_type == 'HT')
|
||||
{
|
||||
$opt.= price($objp->custprice,1).' '.$currencytext.' '.$langs->trans("HT");
|
||||
$outval.= price($objp->custprice,1).' '.$currencytextnoent.' '.$langs->transnoentities("HT");
|
||||
}
|
||||
else
|
||||
{
|
||||
$opt.= price($objp->custprice_ttc,1).' '.$currencytext.' '.$langs->trans("TTC");
|
||||
$outval.= price($objp->custprice_ttc,1).' '.$currencytextnoent.' '.$langs->transnoentities("TTC");
|
||||
}
|
||||
|
||||
$outprice_ht=price($objp->custprice);
|
||||
$outprice_ttc=price($objp->custprice_ttc);
|
||||
$outpricebasetype=$objp->custprice_base_type;
|
||||
$outtva_tx=$objp->custtva_tx;
|
||||
}
|
||||
}
|
||||
|
||||
// If level no defined or multiprice not found, we used the default price
|
||||
if (! $found)
|
||||
@ -3735,7 +3775,7 @@ class Form
|
||||
*
|
||||
* @param string $htmlname Name of html select area
|
||||
* @param array $array Array with key+value
|
||||
* @param int $id Preselected key
|
||||
* @param string $id Preselected key
|
||||
* @param int $show_empty 1 si il faut ajouter une valeur vide dans la liste, 0 sinon
|
||||
* @param int $key_in_label 1 pour afficher la key dans la valeur "[key] value"
|
||||
* @param int $value_as_key 1 to use value as key
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* Copyright (C) 2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
|
||||
* Copyright (C) 2007 Patrick Raguin <patrick.raguin@gmail.com>
|
||||
* Copyright (C) 2010-2012 Regis Houssin <regis.houssin@capnetworks.com>
|
||||
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2013 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2013 Christophe Battarel <contact@altairis.fr>
|
||||
* Copyright (C) 2013 Alexandre Spangaro <alexandre.spangaro@gmail.com>
|
||||
@ -136,6 +136,16 @@ function societe_prepare_head($object)
|
||||
$h++;
|
||||
}
|
||||
|
||||
if (($object->client==1 || $object->client==2 || $object->client==3) && (! empty ( $conf->global->PRODUIT_CUSTOMER_PRICES )))
|
||||
{
|
||||
$langs->load("products");
|
||||
// price
|
||||
$head[$h][0] = DOL_URL_ROOT.'/societe/price.php?socid='.$object->id;
|
||||
$head[$h][1] = $langs->trans("CustomerPrices");
|
||||
$head[$h][2] = 'price';
|
||||
$h++;
|
||||
}
|
||||
|
||||
// Log
|
||||
$head[$h][0] = DOL_URL_ROOT.'/societe/info.php?socid='.$object->id;
|
||||
$head[$h][1] = $langs->trans("Info");
|
||||
|
||||
@ -2868,7 +2868,7 @@ function get_localtax($tva, $local, $thirdparty_buyer="", $thirdparty_seller="")
|
||||
global $db, $conf, $mysoc;
|
||||
|
||||
if (empty($thirdparty_seller) || ! is_object($thirdparty_seller)) $thirdparty_seller=$mysoc;
|
||||
|
||||
|
||||
dol_syslog("get_localtax tva=".$tva." local=".$local." thirdparty_buyer id=".(is_object($thirdparty_buyer)?$thirdparty_buyer->id:'')."/country_code=".(is_object($thirdparty_buyer)?$thirdparty_buyer->country_code:'')." thirdparty_seller id=".$thirdparty_seller->id."/country_code=".$thirdparty_seller->country_code." thirdparty_seller localtax1_assuj=".$thirdparty_seller->localtax1_assuj." thirdparty_seller localtax2_assuj=".$thirdparty_seller->localtax2_assuj);
|
||||
|
||||
// Some test to guess with no need to make database access
|
||||
|
||||
@ -270,7 +270,7 @@ class modSociete extends DolibarrModules
|
||||
$this->export_TypeFields_array[$r]=array('s.nom'=>"Text",'s.status'=>"Number",'s.client'=>"Boolean",'s.fournisseur'=>"Boolean",'s.datec'=>"Date",'s.tms'=>"Date",'s.code_client'=>"Text",'s.code_fournisseur'=>"Text",'s.code_compta'=>"Text",'s.code_compta_fournisseur'=>"Text",'s.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'p.libelle'=>"List:c_pays:libelle:libelle",'p.code'=>"Text",'s.phone'=>"Text",'s.fax'=>"Text",'s.url'=>"Text",'s.email'=>"Text",'s.default_lang'=>"Text",'s.siret'=>"Text",'s.siren'=>"Text",'s.ape'=>"Text",'s.idprof4'=>"Text",'s.idprof5'=>"Text",'s.idprof6'=>"Text",'s.tva_intra'=>"Text",'s.capital'=>"Number",'s.note_private'=>"Text",'s.note_public'=>"Text",'t.libelle'=>"Text",'ce.code'=>"List:c_effectif:libelle:code","cfj.libelle"=>"Text",'s.fk_prospectlevel'=>'List:c_prospectlevel:label:code','st.code'=>'List:c_stcomm:libelle:code','d.nom'=>'Text');
|
||||
$this->export_entities_array[$r]=array(); // We define here only fields that use another picto
|
||||
// Add extra fields
|
||||
$sql="SELECT name, label, type FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'societe'";
|
||||
$sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'societe'";
|
||||
$resql=$this->db->query($sql);
|
||||
if ($resql) // This can fail when class is used on old database (during migration for example)
|
||||
{
|
||||
|
||||
@ -107,7 +107,7 @@ if (! empty($conf->margin->enabled)) {
|
||||
'select_type'
|
||||
)
|
||||
);
|
||||
$form->select_produits('', 'idprod', '', $conf->product->limit_size, $buyer->price_level, 1, 2, '', 3, $ajaxoptions);
|
||||
$form->select_produits('', 'idprod', '', $conf->product->limit_size, $buyer->price_level, 1, 2, '', 3, $ajaxoptions,$buyer->id);
|
||||
}
|
||||
?>
|
||||
<span id="add_product_area" class="hideobject"> | <input type="checkbox" id="add_product_checkbox" name="add_product" value="1" />
|
||||
@ -270,6 +270,9 @@ $(document).ready(function() {
|
||||
'id': $(this).val(),
|
||||
'price_level': <?php echo empty($buyer->price_level)?1:$buyer->price_level; ?>,
|
||||
'pbq': $("option:selected", this).attr('pbq')
|
||||
<?php if (! empty ( $conf->global->PRODUIT_CUSTOMER_PRICES )) {?>
|
||||
,'socid': <?php echo $buyer->id; ?>
|
||||
<?php }?>
|
||||
},
|
||||
function(data) {
|
||||
if (typeof data != 'undefined') {
|
||||
|
||||
@ -101,7 +101,7 @@ else {
|
||||
echo '<span>';
|
||||
$filtertype='';
|
||||
if (! empty($object->element) && $object->element == 'contrat') $filtertype='1';
|
||||
$form->select_produits('','idprod',$filtertype,$conf->product->limit_size,$buyer->price_level);
|
||||
$form->select_produits('','idprod',$filtertype,$conf->product->limit_size,$buyer->price_level, 1, 2, '', 3, array(),$buyer->id);
|
||||
echo '</span>';
|
||||
|
||||
if (is_object($hookmanager))
|
||||
|
||||
@ -957,3 +957,56 @@ INSERT INTO llx_accountingaccount (fk_pcg_version, pcg_type, pcg_subtype, accoun
|
||||
INSERT INTO llx_accountingaccount (fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUE ('PCMN-BASE', 'PROD', 'XXXXXX', '793', '79', 'Perte à reporter', '1');
|
||||
INSERT INTO llx_accountingaccount (fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUE ('PCMN-BASE', 'PROD', 'XXXXXX', '794', '79', 'Intervention d''associés (ou du propriétaire) dans la perte', '1');
|
||||
|
||||
|
||||
ALTER TABLE llx_projet_task ADD COLUMN entity integer DEFAULT 1 NOT NULL AFTER ref;
|
||||
|
||||
create table llx_product_customer_price
|
||||
(
|
||||
rowid integer AUTO_INCREMENT PRIMARY KEY,
|
||||
entity integer DEFAULT 1 NOT NULL, -- multi company id
|
||||
datec datetime,
|
||||
tms timestamp,
|
||||
fk_product integer NOT NULL,
|
||||
fk_soc integer NOT NULL,
|
||||
price double(24,8) DEFAULT 0,
|
||||
price_ttc double(24,8) DEFAULT 0,
|
||||
price_min double(24,8) DEFAULT 0,
|
||||
price_min_ttc double(24,8) DEFAULT 0,
|
||||
price_base_type varchar(3) DEFAULT 'HT',
|
||||
tva_tx double(6,3),
|
||||
recuperableonly integer NOT NULL DEFAULT '0', -- Other NPR VAT
|
||||
localtax1_tx double(6,3) DEFAULT 0, -- Other local VAT 1
|
||||
localtax2_tx double(6,3) DEFAULT 0, -- Other local VAT 2
|
||||
fk_user integer,
|
||||
import_key varchar(14) -- Import key
|
||||
)ENGINE=innodb;
|
||||
|
||||
ALTER TABLE llx_product_customer_price ADD INDEX idx_product_customer_price_fk_user (fk_user);
|
||||
|
||||
ALTER TABLE llx_product_customer_price ADD CONSTRAINT fk_product_customer_price_fk_user FOREIGN KEY (fk_user) REFERENCES llx_user (rowid);
|
||||
|
||||
ALTER TABLE llx_product_customer_price ADD UNIQUE INDEX uk_customer_price_fk_product_fk_soc (fk_product, fk_soc);
|
||||
|
||||
ALTER TABLE llx_product_customer_price ADD CONSTRAINT fk_customer_price_fk_product FOREIGN KEY (fk_product) REFERENCES llx_product(rowid) ON DELETE CASCADE;
|
||||
ALTER TABLE llx_product_customer_price ADD CONSTRAINT fk_customer_price_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe(rowid) ON DELETE CASCADE;
|
||||
|
||||
|
||||
create table llx_product_customer_price_log
|
||||
(
|
||||
rowid integer AUTO_INCREMENT PRIMARY KEY,
|
||||
entity integer DEFAULT 1 NOT NULL, -- multi company id
|
||||
datec datetime,
|
||||
fk_product integer NOT NULL,
|
||||
fk_soc integer NOT NULL,
|
||||
price double(24,8) DEFAULT 0,
|
||||
price_ttc double(24,8) DEFAULT 0,
|
||||
price_min double(24,8) DEFAULT 0,
|
||||
price_min_ttc double(24,8) DEFAULT 0,
|
||||
price_base_type varchar(3) DEFAULT 'HT',
|
||||
tva_tx double(6,3),
|
||||
recuperableonly integer NOT NULL DEFAULT '0', -- Other NPR VAT
|
||||
localtax1_tx double(6,3) DEFAULT 0, -- Other local VAT 1
|
||||
localtax2_tx double(6,3) DEFAULT 0, -- Other local VAT 2
|
||||
fk_user integer,
|
||||
import_key varchar(14) -- Import key
|
||||
)ENGINE=innodb;
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
-- ============================================================================
|
||||
-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
|
||||
-- Copyright (C) 2005-2012 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
-- Copyright (C) 2009-2012 Regis Houssin <regis.houssin@capnetworks.com>
|
||||
-- Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
|
||||
--
|
||||
-- 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
ALTER TABLE llx_product_customer_price ADD INDEX idx_product_customer_price_fk_user (fk_user);
|
||||
|
||||
ALTER TABLE llx_product_customer_price ADD CONSTRAINT fk_product_customer_price_fk_user FOREIGN KEY (fk_user) REFERENCES llx_user (rowid);
|
||||
|
||||
ALTER TABLE llx_product_customer_price ADD UNIQUE INDEX uk_customer_price_fk_product_fk_soc (fk_product, fk_soc);
|
||||
|
||||
ALTER TABLE llx_product_customer_price ADD CONSTRAINT fk_customer_price_fk_product FOREIGN KEY (fk_product) REFERENCES llx_product(rowid) ON DELETE CASCADE;
|
||||
ALTER TABLE llx_product_customer_price ADD CONSTRAINT fk_customer_price_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe(rowid) ON DELETE CASCADE;
|
||||
42
htdocs/install/mysql/tables/llx_product_customer_price.sql
Normal file
42
htdocs/install/mysql/tables/llx_product_customer_price.sql
Normal file
@ -0,0 +1,42 @@
|
||||
-- ============================================================================
|
||||
-- Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
|
||||
-- Copyright (C) 2009-2011 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
-- Copyright (C) 2009-2013 Regis Houssin <regis.houssin@capnetworks.com>
|
||||
-- Copyright (C) 2012 Juanjo Menent <jmenent@2byte.es>
|
||||
-- Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
|
||||
--
|
||||
-- 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
create table llx_product_customer_price
|
||||
(
|
||||
rowid integer AUTO_INCREMENT PRIMARY KEY,
|
||||
entity integer DEFAULT 1 NOT NULL, -- multi company id
|
||||
datec datetime,
|
||||
tms timestamp,
|
||||
fk_product integer NOT NULL,
|
||||
fk_soc integer NOT NULL,
|
||||
price double(24,8) DEFAULT 0,
|
||||
price_ttc double(24,8) DEFAULT 0,
|
||||
price_min double(24,8) DEFAULT 0,
|
||||
price_min_ttc double(24,8) DEFAULT 0,
|
||||
price_base_type varchar(3) DEFAULT 'HT',
|
||||
tva_tx double(6,3),
|
||||
recuperableonly integer NOT NULL DEFAULT '0', -- Other NPR VAT
|
||||
localtax1_tx double(6,3) DEFAULT 0, -- Other local VAT 1
|
||||
localtax2_tx double(6,3) DEFAULT 0, -- Other local VAT 2
|
||||
fk_user integer,
|
||||
import_key varchar(14) -- Import key
|
||||
)ENGINE=innodb;
|
||||
@ -0,0 +1,39 @@
|
||||
-- ============================================================================
|
||||
-- Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
|
||||
-- Copyright (C) 2009 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
-- Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
|
||||
--
|
||||
-- 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
create table llx_product_customer_price_log
|
||||
(
|
||||
rowid integer AUTO_INCREMENT PRIMARY KEY,
|
||||
entity integer DEFAULT 1 NOT NULL, -- multi company id
|
||||
datec datetime,
|
||||
fk_product integer NOT NULL,
|
||||
fk_soc integer NOT NULL,
|
||||
price double(24,8) DEFAULT 0,
|
||||
price_ttc double(24,8) DEFAULT 0,
|
||||
price_min double(24,8) DEFAULT 0,
|
||||
price_min_ttc double(24,8) DEFAULT 0,
|
||||
price_base_type varchar(3) DEFAULT 'HT',
|
||||
tva_tx double(6,3),
|
||||
recuperableonly integer NOT NULL DEFAULT '0', -- Other NPR VAT
|
||||
localtax1_tx double(6,3) DEFAULT 0, -- Other local VAT 1
|
||||
localtax2_tx double(6,3) DEFAULT 0, -- Other local VAT 2
|
||||
fk_user integer,
|
||||
import_key varchar(14) -- Import key
|
||||
)ENGINE=innodb;
|
||||
@ -21,6 +21,7 @@ create table llx_projet_task
|
||||
(
|
||||
rowid integer AUTO_INCREMENT PRIMARY KEY,
|
||||
ref varchar(50),
|
||||
entity integer DEFAULT 1 NOT NULL, -- multi company id
|
||||
fk_projet integer NOT NULL,
|
||||
fk_task_parent integer DEFAULT 0 NOT NULL,
|
||||
datec datetime, -- date creation
|
||||
|
||||
@ -221,3 +221,9 @@ DefinitionOfBarCodeForThirdpartyNotComplete=Definition of type or value of bar c
|
||||
BarCodeDataForProduct=Barcode information of product %s :
|
||||
BarCodeDataForThirdparty=Barcode information of thirdparty %s :
|
||||
ResetBarcodeForAllRecords=Define barcode value for all records (this will also reset barcode value already defined with new values)
|
||||
PriceByCustomer=Price by customer
|
||||
PriceCatalogue=Catalogue Price
|
||||
PricingRule=Pricing Rules
|
||||
AddCustomerPrice=Add price by customers
|
||||
ForceUpdateChildPriceSoc=Set same price on customer subsidiaries
|
||||
PriceByCustomerLog=Price by customer log
|
||||
@ -217,4 +217,9 @@ DefinitionOfBarCodeForThirdpartyNotComplete=Définition du type ou valeure du co
|
||||
BarCodeDataForProduct=Information de code barre du produit %s :
|
||||
BarCodeDataForThirdparty=Information de code barre du tiers %s :
|
||||
BarcodeStickersMask=xxx
|
||||
|
||||
PriceByCustomer=Prix par clients
|
||||
PriceCatalogue=Prix unique
|
||||
PricingRule=Régles de prix
|
||||
AddCustomerPrice=Ajouter un prix par client
|
||||
ForceUpdateChildPriceSoc=Mettre le même prix pour les filliales
|
||||
PriceByCustomerLog=Historique prix par client
|
||||
@ -42,6 +42,17 @@ if (! $user->admin || (empty($conf->product->enabled) && empty($conf->service->e
|
||||
$action = GETPOST('action','alpha');
|
||||
$value = GETPOST('value','alpha');
|
||||
|
||||
// Pricing Rules
|
||||
$select_pricing_rules=array(
|
||||
'PRODUCT_PRICE_UNIQ'=>$langs->trans('PriceCatalogue'),
|
||||
'PRODUIT_MULTIPRICES'=>$langs->trans('MultiPricesAbility'),
|
||||
'PRODUIT_CUSTOMER_PRICES'=>$langs->trans('PriceByCustomer')
|
||||
);
|
||||
if ($conf->global->MAIN_FEATURES_LEVEL==2) {
|
||||
$select_pricing_rules['PRODUIT_CUSTOMER_PRICES_BY_QTY'] = $langs->trans('PriceByQuantity');
|
||||
$select_pricing_rules['PRODUIT_CUSTOMER_PRICES_BY_QTY&PRODUIT_MULTIPRICES'] = $langs->trans('MultiPricesAbility') . '+' . $langs->trans('PriceByQuantity');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Actions
|
||||
@ -96,12 +107,33 @@ else if ($action == 'multiprix_num')
|
||||
{
|
||||
$res = dolibarr_set_const($db, "PRODUIT_MULTIPRICES_LIMIT", $value,'chaine',0,'',$conf->entity);
|
||||
}
|
||||
if ($action == 'multiprix')
|
||||
if ($action == 'pricingrule')
|
||||
{
|
||||
$multiprix = GETPOST('activate_multiprix','alpha');
|
||||
$princingrules = GETPOST('princingrule','alpha');
|
||||
foreach ($select_pricing_rules as $rule=>$label) {
|
||||
|
||||
$res = dolibarr_set_const($db, "PRODUIT_MULTIPRICES", $multiprix,'chaine',0,'',$conf->entity);
|
||||
$res =dolibarr_set_const($db, "PRODUIT_MULTIPRICES_LIMIT", "5",'chaine',0,'',$conf->entity);
|
||||
if ($rule==$princingrules) {
|
||||
if ( $princingrules =='PRODUCT_PRICE_UNIQ') {
|
||||
$res = dolibarr_set_const($db, 'PRODUIT_MULTIPRICES', 0,'chaine',0,'',$conf->entity);
|
||||
$res = dolibarr_set_const($db, 'PRODUIT_CUSTOMER_PRICES_BY_QTY', 0,'chaine',0,'',$conf->entity);
|
||||
$res = dolibarr_set_const($db, 'PRODUIT_CUSTOMER_PRICES', 0,'chaine',0,'',$conf->entity);
|
||||
} else {
|
||||
$multirule=explode('&',$princingrules);
|
||||
if (is_array($multirule) && count($multirule)>0) {
|
||||
foreach($multirule as $rulesselected) {
|
||||
$res = dolibarr_set_const($db, $rulesselected, 1,'chaine',0,'',$conf->entity);
|
||||
}
|
||||
} else {
|
||||
$res = dolibarr_set_const($db, $rule, 1,'chaine',0,'',$conf->entity);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (strpos($rule,'&')===false) {
|
||||
$res = dolibarr_set_const($db, $rule, 0,'chaine',0,'',$conf->entity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if ($action == 'sousproduits')
|
||||
{
|
||||
@ -278,15 +310,20 @@ print '<td width="80"> </td></tr>'."\n";
|
||||
* Formulaire parametres divers
|
||||
*/
|
||||
|
||||
// multiprix activation/desactivation
|
||||
|
||||
$var=!$var;
|
||||
print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
|
||||
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||
print '<input type="hidden" name="action" value="multiprix">';
|
||||
print '<input type="hidden" name="action" value="pricingrule">';
|
||||
print '<tr '.$bc[$var].'>';
|
||||
print '<td>'.$langs->trans("MultiPricesAbility").'</td>';
|
||||
print '<td>'.$langs->trans("PricingRule").'</td>';
|
||||
print '<td width="60" align="right">';
|
||||
print $form->selectyesno("activate_multiprix",$conf->global->PRODUIT_MULTIPRICES,1);
|
||||
$current_rule = 'PRODUCT_PRICE_UNIQ';
|
||||
if (!empty($conf->global->PRODUIT_MULTIPRICES)) $current_rule='PRODUIT_MULTIPRICES';
|
||||
if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) $current_rule='PRODUIT_CUSTOMER_PRICES_BY_QTY';
|
||||
if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) $current_rule='PRODUIT_CUSTOMER_PRICES';
|
||||
if ((!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) && (!empty($conf->global->PRODUIT_MULTIPRICES)))$current_rule='PRODUIT_CUSTOMER_PRICES_BY_QTY&PRODUIT_MULTIPRICES';
|
||||
print $form->selectarray("princingrule",$select_pricing_rules,$current_rule);
|
||||
print '</td><td align="right">';
|
||||
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
|
||||
print '</td>';
|
||||
|
||||
@ -18,156 +18,176 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file htdocs/product/ajax/products.php
|
||||
* \brief File to return Ajax response on product list request
|
||||
* \file htdocs/product/ajax/products.php
|
||||
* \brief File to return Ajax response on product list request
|
||||
*/
|
||||
|
||||
if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal
|
||||
if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1');
|
||||
if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1');
|
||||
if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1');
|
||||
if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1');
|
||||
if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1');
|
||||
if (empty($_GET['keysearch']) && ! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1');
|
||||
if (! defined('NOTOKENRENEWAL'))
|
||||
define('NOTOKENRENEWAL', 1); // Disables token renewal
|
||||
if (! defined('NOREQUIREMENU'))
|
||||
define('NOREQUIREMENU', '1');
|
||||
if (! defined('NOREQUIREHTML'))
|
||||
define('NOREQUIREHTML', '1');
|
||||
if (! defined('NOREQUIREAJAX'))
|
||||
define('NOREQUIREAJAX', '1');
|
||||
if (! defined('NOREQUIRESOC'))
|
||||
define('NOREQUIRESOC', '1');
|
||||
if (! defined('NOCSRFCHECK'))
|
||||
define('NOCSRFCHECK', '1');
|
||||
if (empty($_GET ['keysearch']) && ! defined('NOREQUIREHTML'))
|
||||
define('NOREQUIREHTML', '1');
|
||||
|
||||
require '../../main.inc.php';
|
||||
|
||||
$htmlname=GETPOST('htmlname','alpha');
|
||||
$socid=GETPOST('socid','int');
|
||||
$type=GETPOST('type','int');
|
||||
$mode=GETPOST('mode','int');
|
||||
$status=((GETPOST('status','int') >= 0) ? GETPOST('status','int') : -1);
|
||||
$outjson=(GETPOST('outjson','int') ? GETPOST('outjson','int') : 0);
|
||||
$price_level=GETPOST('price_level','int');
|
||||
$action=GETPOST('action', 'alpha');
|
||||
$id=GETPOST('id', 'int');
|
||||
$price_by_qty_rowid=GETPOST('pbq', 'int');
|
||||
$htmlname = GETPOST('htmlname', 'alpha');
|
||||
$socid = GETPOST('socid', 'int');
|
||||
$type = GETPOST('type', 'int');
|
||||
$mode = GETPOST('mode', 'int');
|
||||
$status = ((GETPOST('status', 'int') >= 0) ? GETPOST('status', 'int') : - 1);
|
||||
$outjson = (GETPOST('outjson', 'int') ? GETPOST('outjson', 'int') : 0);
|
||||
$price_level = GETPOST('price_level', 'int');
|
||||
$action = GETPOST('action', 'alpha');
|
||||
$id = GETPOST('id', 'int');
|
||||
$price_by_qty_rowid = GETPOST('pbq', 'int');
|
||||
|
||||
/*
|
||||
* View
|
||||
*/
|
||||
|
||||
//print '<!-- Ajax page called with url '.$_SERVER["PHP_SELF"].'?'.$_SERVER["QUERY_STRING"].' -->'."\n";
|
||||
// print '<!-- Ajax page called with url '.$_SERVER["PHP_SELF"].'?'.$_SERVER["QUERY_STRING"].' -->'."\n";
|
||||
|
||||
dol_syslog(join(',',$_GET));
|
||||
//print_r($_GET);
|
||||
dol_syslog(join(',', $_GET));
|
||||
// print_r($_GET);
|
||||
|
||||
if (! empty($action) && $action == 'fetch' && ! empty($id))
|
||||
{
|
||||
if (! empty($action) && $action == 'fetch' && ! empty($id)) {
|
||||
require DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
|
||||
|
||||
$outjson=array();
|
||||
|
||||
|
||||
$outjson = array();
|
||||
|
||||
$object = new Product($db);
|
||||
$ret=$object->fetch($id);
|
||||
if ($ret > 0)
|
||||
{
|
||||
$outref=$object->ref;
|
||||
$outlabel=$object->label;
|
||||
$outdesc=$object->description;
|
||||
$outtype=$object->type;
|
||||
$outqty=1;
|
||||
$outdiscount=0;
|
||||
|
||||
$found=false;
|
||||
|
||||
$ret = $object->fetch($id);
|
||||
if ($ret > 0) {
|
||||
$outref = $object->ref;
|
||||
$outlabel = $object->label;
|
||||
$outdesc = $object->description;
|
||||
$outtype = $object->type;
|
||||
$outqty = 1;
|
||||
$outdiscount = 0;
|
||||
|
||||
$found = false;
|
||||
|
||||
// Price by qty
|
||||
if (!empty($price_by_qty_rowid) && $price_by_qty_rowid >= 1) // If we need a particular price related to qty
|
||||
if (! empty($price_by_qty_rowid) && $price_by_qty_rowid >= 1 && (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY))) // If we need a
|
||||
// particular price related
|
||||
// to qty
|
||||
{
|
||||
$sql = "SELECT price, unitprice, quantity, remise_percent";
|
||||
$sql.= " FROM ".MAIN_DB_PREFIX."product_price_by_qty ";
|
||||
$sql.= " WHERE rowid=".$price_by_qty_rowid."";
|
||||
|
||||
$sql .= " FROM " . MAIN_DB_PREFIX . "product_price_by_qty ";
|
||||
$sql .= " WHERE rowid=" . $price_by_qty_rowid . "";
|
||||
|
||||
$result = $db->query($sql);
|
||||
if ($result)
|
||||
{
|
||||
if ($result) {
|
||||
$objp = $db->fetch_object($result);
|
||||
if ($objp)
|
||||
{
|
||||
$found=true;
|
||||
$outprice_ht=price($objp->unitprice);
|
||||
$outprice_ttc=price($objp->unitprice * (1 + ($object->tva_tx / 100)));
|
||||
$outpricebasetype=$object->price_base_type;
|
||||
$outtva_tx=$object->tva_tx;
|
||||
$outqty=$objp->quantity;
|
||||
$outdiscount=$objp->remise_percent;
|
||||
if ($objp) {
|
||||
$found = true;
|
||||
$outprice_ht = price($objp->unitprice);
|
||||
$outprice_ttc = price($objp->unitprice * (1 + ($object->tva_tx / 100)));
|
||||
$outpricebasetype = $object->price_base_type;
|
||||
$outtva_tx = $object->tva_tx;
|
||||
$outqty = $objp->quantity;
|
||||
$outdiscount = $objp->remise_percent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Multiprice
|
||||
if (! $found && isset($price_level) && $price_level >= 1) // If we need a particular price level (from 1 to 6)
|
||||
if (! $found && isset($price_level) && $price_level >= 1 && (! empty($conf->global->PRODUIT_MULTIPRICES))) // If we need a particular price
|
||||
// level (from 1 to 6)
|
||||
{
|
||||
$sql = "SELECT price, price_ttc, price_base_type, tva_tx";
|
||||
$sql.= " FROM ".MAIN_DB_PREFIX."product_price ";
|
||||
$sql.= " WHERE fk_product='".$id."'";
|
||||
$sql.= " AND entity IN (".getEntity('productprice', 1).")";
|
||||
$sql.= " AND price_level=".$price_level;
|
||||
$sql.= " ORDER BY date_price";
|
||||
$sql.= " DESC LIMIT 1";
|
||||
|
||||
$sql .= " FROM " . MAIN_DB_PREFIX . "product_price ";
|
||||
$sql .= " WHERE fk_product='" . $id . "'";
|
||||
$sql .= " AND entity IN (" . getEntity('productprice', 1) . ")";
|
||||
$sql .= " AND price_level=" . $price_level;
|
||||
$sql .= " ORDER BY date_price";
|
||||
$sql .= " DESC LIMIT 1";
|
||||
|
||||
$result = $db->query($sql);
|
||||
if ($result)
|
||||
{
|
||||
if ($result) {
|
||||
$objp = $db->fetch_object($result);
|
||||
if ($objp)
|
||||
{
|
||||
$found=true;
|
||||
$outprice_ht=price($objp->price);
|
||||
$outprice_ttc=price($objp->price_ttc);
|
||||
$outpricebasetype=$objp->price_base_type;
|
||||
$outtva_tx=$objp->tva_tx;
|
||||
if ($objp) {
|
||||
$found = true;
|
||||
$outprice_ht = price($objp->price);
|
||||
$outprice_ttc = price($objp->price_ttc);
|
||||
$outpricebasetype = $objp->price_base_type;
|
||||
$outtva_tx = $objp->tva_tx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! $found)
|
||||
{
|
||||
$outprice_ht=price($object->price);
|
||||
$outprice_ttc=price($object->price_ttc);
|
||||
$outpricebasetype=$object->price_base_type;
|
||||
$outtva_tx=$object->tva_tx;
|
||||
|
||||
// Price by customer
|
||||
if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && ! empty($socid)) {
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
|
||||
|
||||
$prodcustprice = new Productcustomerprice($db);
|
||||
|
||||
$filter = array('t.fk_product' => $object->id,'t.fk_soc' => $socid);
|
||||
|
||||
$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
|
||||
if ($result) {
|
||||
if (count($prodcustprice->lines) > 0) {
|
||||
$found = true;
|
||||
$outprice_ht = price($prodcustprice->lines [0]->price);
|
||||
$outprice_ttc = price($prodcustprice->lines [0]->price_ttc);
|
||||
$outpricebasetype = $prodcustprice->lines [0]->price_base_type;
|
||||
$outtva_tx = $prodcustprice->lines [0]->tva_tx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$outjson = array('ref'=>$outref, 'label'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>$outprice_ht, 'price_ttc'=>$outprice_ttc, 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, 'discount'=>$outdiscount);
|
||||
|
||||
if (! $found) {
|
||||
$outprice_ht = price($object->price);
|
||||
$outprice_ttc = price($object->price_ttc);
|
||||
$outpricebasetype = $object->price_base_type;
|
||||
$outtva_tx = $object->tva_tx;
|
||||
}
|
||||
|
||||
$outjson = array('ref' => $outref,'label' => $outlabel,'desc' => $outdesc,'type' => $outtype,'price_ht' => $outprice_ht,'price_ttc' => $outprice_ttc,'pricebasetype' => $outpricebasetype,'tva_tx' => $outtva_tx,'qty' => $outqty,'discount' => $outdiscount);
|
||||
}
|
||||
|
||||
|
||||
echo json_encode($outjson);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
|
||||
|
||||
} else {
|
||||
require_once DOL_DOCUMENT_ROOT . '/core/class/html.form.class.php';
|
||||
|
||||
$langs->load("products");
|
||||
$langs->load("main");
|
||||
|
||||
|
||||
top_httphead();
|
||||
|
||||
if (empty($htmlname)) return;
|
||||
|
||||
$match = preg_grep('/('.$htmlname.'[0-9]+)/',array_keys($_GET));
|
||||
|
||||
if (empty($htmlname))
|
||||
return;
|
||||
|
||||
$match = preg_grep('/(' . $htmlname . '[0-9]+)/', array_keys($_GET));
|
||||
sort($match);
|
||||
$idprod = (! empty($match[0]) ? $match[0] : '');
|
||||
|
||||
if (! GETPOST($htmlname) && ! GETPOST($idprod)) return;
|
||||
|
||||
// When used from jQuery, the search term is added as GET param "term".
|
||||
$searchkey=(GETPOST($idprod)?GETPOST($idprod):(GETPOST($htmlname)?GETPOST($htmlname):''));
|
||||
|
||||
$idprod = (! empty($match [0]) ? $match [0] : '');
|
||||
|
||||
if (! GETPOST($htmlname) && ! GETPOST($idprod))
|
||||
return;
|
||||
|
||||
// When used from jQuery, the search term is added as GET param "term".
|
||||
$searchkey = (GETPOST($idprod) ? GETPOST($idprod) : (GETPOST($htmlname) ? GETPOST($htmlname) : ''));
|
||||
|
||||
$form = new Form($db);
|
||||
if (empty($mode) || $mode == 1)
|
||||
{
|
||||
$arrayresult=$form->select_produits_list("",$htmlname,$type,"",$price_level,$searchkey,$status,2,$outjson);
|
||||
if (empty($mode) || $mode == 1) {
|
||||
$arrayresult = $form->select_produits_list("", $htmlname, $type, "", $price_level, $searchkey, $status, 2, $outjson, $socid);
|
||||
} elseif ($mode == 2) {
|
||||
$arrayresult = $form->select_produits_fournisseurs_list($socid, "", $htmlname, $type, "", $searchkey, $status, $outjson, $socid);
|
||||
}
|
||||
elseif ($mode == 2)
|
||||
{
|
||||
$arrayresult=$form->select_produits_fournisseurs_list($socid,"",$htmlname,$type,"",$searchkey,$status,$outjson);
|
||||
}
|
||||
|
||||
|
||||
$db->close();
|
||||
|
||||
if ($outjson) print json_encode($arrayresult);
|
||||
|
||||
if ($outjson)
|
||||
print json_encode($arrayresult);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@ -1183,6 +1183,7 @@ class Product extends CommonObject
|
||||
}
|
||||
//print 'x'.$id.'-'.$newprice.'-'.$newpricebase.'-'.$price.'-'.$price_ttc.'-'.$price_min.'-'.$price_min_ttc;
|
||||
|
||||
|
||||
//Local taxes
|
||||
$localtax1=get_localtax($newvat,1);
|
||||
$localtax2=get_localtax($newvat,2);
|
||||
|
||||
946
htdocs/product/class/productcustomerprice.class.php
Normal file
946
htdocs/product/class/productcustomerprice.class.php
Normal file
@ -0,0 +1,946 @@
|
||||
<?php
|
||||
/* Copyright (C) 2007-2012 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
|
||||
*
|
||||
* 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 3 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file htdocs/product/class/productcustomerprice.class.php
|
||||
* \ingroup produit
|
||||
* \brief File of class to manage predefined price products or services by customer
|
||||
*/
|
||||
require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
|
||||
|
||||
/**
|
||||
* File of class to manage predefined price products or services by customer
|
||||
*/
|
||||
class Productcustomerprice extends CommonObject
|
||||
{
|
||||
var $db; // !< To store db handler
|
||||
var $error; // !< To return error code (or message)
|
||||
var $errors = array (); // !< To return several error codes (or messages)
|
||||
var $element = 'product_customer_price'; // !< Id that identify managed objects
|
||||
var $table_element = 'product_customer_price'; // !< Name of table without prefix where object is stored
|
||||
var $id;
|
||||
var $entity;
|
||||
var $datec = '';
|
||||
var $tms = '';
|
||||
var $fk_product;
|
||||
var $fk_soc;
|
||||
var $price;
|
||||
var $price_ttc;
|
||||
var $price_min;
|
||||
var $price_min_ttc;
|
||||
var $price_base_type;
|
||||
var $tva_tx;
|
||||
var $recuperableonly;
|
||||
var $localtax1_tx;
|
||||
var $localtax2_tx;
|
||||
var $fk_user;
|
||||
var $import_key;
|
||||
var $lines = array ();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param DoliDb $db handler
|
||||
*/
|
||||
function __construct($db) {
|
||||
|
||||
$this->db = $db;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create object into database
|
||||
*
|
||||
* @param User $user that creates
|
||||
* @param int $notrigger triggers after, 1=disable triggers
|
||||
* @param int $forceupdateaffiliate update price on each soc child
|
||||
* @return int <0 if KO, Id of created object if OK
|
||||
*/
|
||||
function create($user, $notrigger = 0, $forceupdateaffiliate = 0) {
|
||||
|
||||
global $conf, $langs;
|
||||
$error = 0;
|
||||
|
||||
// Clean parameters
|
||||
|
||||
if (isset($this->entity))
|
||||
$this->entity = trim($this->entity);
|
||||
if (isset($this->fk_product))
|
||||
$this->fk_product = trim($this->fk_product);
|
||||
if (isset($this->fk_soc))
|
||||
$this->fk_soc = trim($this->fk_soc);
|
||||
if (isset($this->price))
|
||||
$this->price = trim($this->price);
|
||||
if (isset($this->price_ttc))
|
||||
$this->price_ttc = trim($this->price_ttc);
|
||||
if (isset($this->price_min))
|
||||
$this->price_min = trim($this->price_min);
|
||||
if (isset($this->price_min_ttc))
|
||||
$this->price_min_ttc = trim($this->price_min_ttc);
|
||||
if (isset($this->price_base_type))
|
||||
$this->price_base_type = trim($this->price_base_type);
|
||||
if (isset($this->tva_tx))
|
||||
$this->tva_tx = trim($this->tva_tx);
|
||||
if (isset($this->recuperableonly))
|
||||
$this->recuperableonly = trim($this->recuperableonly);
|
||||
if (isset($this->localtax1_tx))
|
||||
$this->localtax1_tx = trim($this->localtax1_tx);
|
||||
if (isset($this->localtax2_tx))
|
||||
$this->localtax2_tx = trim($this->localtax2_tx);
|
||||
if (isset($this->fk_user))
|
||||
$this->fk_user = trim($this->fk_user);
|
||||
if (isset($this->import_key))
|
||||
$this->import_key = trim($this->import_key);
|
||||
|
||||
// Check parameters
|
||||
// Put here code to add control on parameters values
|
||||
|
||||
if ($this->price != '' || $this->price == 0) {
|
||||
if ($this->price_base_type == 'TTC') {
|
||||
$this->price_ttc = price2num($this->price, 'MU');
|
||||
$this->price = price2num($this->price) / (1 + ($this->tva_tx / 100));
|
||||
$this->price = price2num($this->price, 'MU');
|
||||
|
||||
if ($this->price_min != '' || $this->price_min == 0) {
|
||||
$this->price_min_ttc = price2num($this->price_min, 'MU');
|
||||
$this->price_min = price2num($this->price_min) / (1 + ($this->tva_tx / 100));
|
||||
$this->price_min = price2num($this->price_min, 'MU');
|
||||
} else {
|
||||
$this->price_min = 0;
|
||||
$this->price_min_ttc = 0;
|
||||
}
|
||||
} else {
|
||||
$this->price = price2num($this->price, 'MU');
|
||||
$this->price_ttc = ($this->recuperableonly != 1) ? price2num($this->price) * (1 + ($this->tva_tx / 100)) : $this->price;
|
||||
$this->price_ttc = price2num($this->price_ttc, 'MU');
|
||||
|
||||
if ($this->price_min != '' || $this->price_min == 0) {
|
||||
$this->price_min = price2num($this->price_min, 'MU');
|
||||
$this->price_min_ttc = price2num($this->price_min) * (1 + ($this->tva_tx / 100));
|
||||
$this->price_min_ttc = price2num($this->price_min_ttc, 'MU');
|
||||
// print 'X'.$newminprice.'-'.$price_min;
|
||||
} else {
|
||||
$this->price_min = 0;
|
||||
$this->price_min_ttc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert request
|
||||
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_customer_price(";
|
||||
|
||||
$sql .= "entity,";
|
||||
$sql .= "datec,";
|
||||
$sql .= "fk_product,";
|
||||
$sql .= "fk_soc,";
|
||||
$sql .= "price,";
|
||||
$sql .= "price_ttc,";
|
||||
$sql .= "price_min,";
|
||||
$sql .= "price_min_ttc,";
|
||||
$sql .= "price_base_type,";
|
||||
$sql .= "tva_tx,";
|
||||
$sql .= "recuperableonly,";
|
||||
$sql .= "localtax1_tx,";
|
||||
$sql .= "localtax2_tx,";
|
||||
$sql .= "fk_user,";
|
||||
$sql .= "import_key";
|
||||
|
||||
$sql .= ") VALUES (";
|
||||
|
||||
$sql .= " " . $conf->entity . ",";
|
||||
$sql .= " '" . $this->db->idate(dol_now()) . "',";
|
||||
$sql .= " " . (! isset($this->fk_product) ? 'NULL' : "'" . $this->fk_product . "'") . ",";
|
||||
$sql .= " " . (! isset($this->fk_soc) ? 'NULL' : "'" . $this->fk_soc . "'") . ",";
|
||||
$sql .= " " . (empty($this->price) ? '0' : "'" . $this->price . "'") . ",";
|
||||
$sql .= " " . (empty($this->price_ttc) ? '0' : "'" . $this->price_ttc . "'") . ",";
|
||||
$sql .= " " . (empty($this->price_min) ? '0' : "'" . $this->price_min . "'") . ",";
|
||||
$sql .= " " . (empty($this->price_min_ttc) ? '0' : "'" . $this->price_min_ttc . "'") . ",";
|
||||
$sql .= " " . (! isset($this->price_base_type) ? 'NULL' : "'" . $this->db->escape($this->price_base_type) . "'") . ",";
|
||||
$sql .= " " . (! isset($this->tva_tx) ? 'NULL' : "'" . $this->tva_tx . "'") . ",";
|
||||
$sql .= " " . (! isset($this->recuperableonly) ? 'NULL' : "'" . $this->recuperableonly . "'") . ",";
|
||||
$sql .= " " . (! isset($this->localtax1_tx) ? 'NULL' : "'" . $this->localtax1_tx . "'") . ",";
|
||||
$sql .= " " . (! isset($this->localtax2_tx) ? 'NULL' : "'" . $this->localtax2_tx . "'") . ",";
|
||||
$sql .= " " . $user->id . ",";
|
||||
$sql .= " " . (! isset($this->import_key) ? 'NULL' : "'" . $this->db->escape($this->import_key) . "'") . "";
|
||||
|
||||
$sql .= ")";
|
||||
|
||||
$this->db->begin();
|
||||
|
||||
dol_syslog(get_class($this) . "::create sql=" . $sql, LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if (! $resql) {
|
||||
$error ++;
|
||||
$this->errors [] = "Error " . $this->db->lasterror();
|
||||
}
|
||||
|
||||
if (! $error) {
|
||||
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "product_customer_price");
|
||||
|
||||
if (! $notrigger) {
|
||||
// Uncomment this and change MYOBJECT to your own tag if you
|
||||
// want this action calls a trigger.
|
||||
|
||||
// // Call triggers
|
||||
// include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
|
||||
// $interface=new Interfaces($this->db);
|
||||
// $result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf);
|
||||
// if ($result < 0) { $error++; $this->errors=$interface->errors; }
|
||||
// // End call triggers
|
||||
}
|
||||
}
|
||||
|
||||
if (! $error) {
|
||||
$result = $this->setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate);
|
||||
if ($result < 0) {
|
||||
$error ++;
|
||||
}
|
||||
}
|
||||
|
||||
// Commit or rollback
|
||||
if ($error) {
|
||||
foreach ( $this->errors as $errmsg ) {
|
||||
dol_syslog(get_class($this) . "::create " . $errmsg, LOG_ERR);
|
||||
$this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
|
||||
}
|
||||
$this->db->rollback();
|
||||
return - 1 * $error;
|
||||
} else {
|
||||
$this->db->commit();
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load object in memory from the database
|
||||
*
|
||||
* @param int $id object
|
||||
* @return int <0 if KO, >0 if OK
|
||||
*/
|
||||
function fetch($id) {
|
||||
|
||||
global $langs;
|
||||
$sql = "SELECT";
|
||||
$sql .= " t.rowid,";
|
||||
|
||||
$sql .= " t.entity,";
|
||||
$sql .= " t.datec,";
|
||||
$sql .= " t.tms,";
|
||||
$sql .= " t.fk_product,";
|
||||
$sql .= " t.fk_soc,";
|
||||
$sql .= " t.price,";
|
||||
$sql .= " t.price_ttc,";
|
||||
$sql .= " t.price_min,";
|
||||
$sql .= " t.price_min_ttc,";
|
||||
$sql .= " t.price_base_type,";
|
||||
$sql .= " t.tva_tx,";
|
||||
$sql .= " t.recuperableonly,";
|
||||
$sql .= " t.localtax1_tx,";
|
||||
$sql .= " t.localtax2_tx,";
|
||||
$sql .= " t.fk_user,";
|
||||
$sql .= " t.import_key";
|
||||
|
||||
$sql .= " FROM " . MAIN_DB_PREFIX . "product_customer_price as t";
|
||||
$sql .= " WHERE t.rowid = " . $id;
|
||||
|
||||
dol_syslog(get_class($this) . "::fetch sql=" . $sql, LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
if ($this->db->num_rows($resql)) {
|
||||
$obj = $this->db->fetch_object($resql);
|
||||
|
||||
$this->id = $obj->rowid;
|
||||
|
||||
$this->entity = $obj->entity;
|
||||
$this->datec = $this->db->jdate($obj->datec);
|
||||
$this->tms = $this->db->jdate($obj->tms);
|
||||
$this->fk_product = $obj->fk_product;
|
||||
$this->fk_soc = $obj->fk_soc;
|
||||
$this->price = $obj->price;
|
||||
$this->price_ttc = $obj->price_ttc;
|
||||
$this->price_min = $obj->price_min;
|
||||
$this->price_min_ttc = $obj->price_min_ttc;
|
||||
$this->price_base_type = $obj->price_base_type;
|
||||
$this->tva_tx = $obj->tva_tx;
|
||||
$this->recuperableonly = $obj->recuperableonly;
|
||||
$this->localtax1_tx = $obj->localtax1_tx;
|
||||
$this->localtax2_tx = $obj->localtax2_tx;
|
||||
$this->fk_user = $obj->fk_user;
|
||||
$this->import_key = $obj->import_key;
|
||||
}
|
||||
$this->db->free($resql);
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
$this->error = "Error " . $this->db->lasterror();
|
||||
dol_syslog(get_class($this) . "::fetch " . $this->error, LOG_ERR);
|
||||
return - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all objects in memory from database
|
||||
*
|
||||
* @param string $sortorder order
|
||||
* @param string $sortfield field
|
||||
* @param int $limit page
|
||||
* @param int $offset offset
|
||||
* @param array $filter output
|
||||
* @return int <0 if KO, >0 if OK
|
||||
*/
|
||||
function fetch_all($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = array()) {
|
||||
|
||||
global $langs;
|
||||
$sql = "SELECT";
|
||||
$sql .= " t.rowid,";
|
||||
|
||||
$sql .= " t.entity,";
|
||||
$sql .= " t.datec,";
|
||||
$sql .= " t.tms,";
|
||||
$sql .= " t.fk_product,";
|
||||
$sql .= " t.fk_soc,";
|
||||
$sql .= " t.price,";
|
||||
$sql .= " t.price_ttc,";
|
||||
$sql .= " t.price_min,";
|
||||
$sql .= " t.price_min_ttc,";
|
||||
$sql .= " t.price_base_type,";
|
||||
$sql .= " t.tva_tx,";
|
||||
$sql .= " t.recuperableonly,";
|
||||
$sql .= " t.localtax1_tx,";
|
||||
$sql .= " t.localtax2_tx,";
|
||||
$sql .= " t.fk_user,";
|
||||
$sql .= " t.import_key,";
|
||||
$sql .= " soc.nom as socname,";
|
||||
$sql .= " prod.ref as prodref";
|
||||
$sql .= " FROM " . MAIN_DB_PREFIX . "product_customer_price as t ";
|
||||
$sql .= " ," . MAIN_DB_PREFIX . "product as prod ";
|
||||
$sql .= " ," . MAIN_DB_PREFIX . "societe as soc ";
|
||||
$sql .= " WHERE soc.rowid=t.fk_soc ";
|
||||
$sql .= " AND prod.rowid=t.fk_product ";
|
||||
$sql .= " AND prod.entity IN (" . getEntity('product', 1) . ")";
|
||||
|
||||
// Manage filter
|
||||
if (count($filter) > 0) {
|
||||
foreach ( $filter as $key => $value ) {
|
||||
if (strpos($key, 'date')) // To allow $filter['YEAR(s.dated)']=>$year
|
||||
{
|
||||
$sql .= ' AND ' . $key . ' = \'' . $value . '\'';
|
||||
} elseif ($key == 'soc.nom') {
|
||||
$sql .= ' AND ' . $key . ' LIKE \'%' . $value . '%\'';
|
||||
} else {
|
||||
$sql .= ' AND ' . $key . ' = ' . $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! empty($sortfield)) {
|
||||
$sql .= " ORDER BY " . $sortfield . ' ' . $sortorder;
|
||||
}
|
||||
if (! empty($limit)) {
|
||||
$sql .= ' ' . $this->db->plimit($limit + 1, $offset);
|
||||
}
|
||||
|
||||
dol_syslog(get_class($this) . "::fetch_all sql=" . $sql, LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
|
||||
$this->lines = array ();
|
||||
$num = $this->db->num_rows($resql);
|
||||
|
||||
while ( $obj = $this->db->fetch_object($resql) ) {
|
||||
|
||||
$line = new PriceByCustomerLine();
|
||||
|
||||
$line->id = $obj->rowid;
|
||||
|
||||
$line->entity = $obj->entity;
|
||||
$line->datec = $this->db->jdate($obj->datec);
|
||||
$line->tms = $this->db->jdate($obj->tms);
|
||||
$line->fk_product = $obj->fk_product;
|
||||
$line->fk_soc = $obj->fk_soc;
|
||||
$line->price = $obj->price;
|
||||
$line->price_ttc = $obj->price_ttc;
|
||||
$line->price_min = $obj->price_min;
|
||||
$line->price_min_ttc = $obj->price_min_ttc;
|
||||
$line->price_base_type = $obj->price_base_type;
|
||||
$line->tva_tx = $obj->tva_tx;
|
||||
$line->recuperableonly = $obj->recuperableonly;
|
||||
$line->localtax1_tx = $obj->localtax1_tx;
|
||||
$line->localtax2_tx = $obj->localtax2_tx;
|
||||
$line->fk_user = $obj->fk_user;
|
||||
$line->import_key = $obj->import_key;
|
||||
$line->socname = $obj->socname;
|
||||
$line->prodref = $obj->prodref;
|
||||
|
||||
$this->lines [] = $line;
|
||||
}
|
||||
$this->db->free($resql);
|
||||
|
||||
return $num;
|
||||
} else {
|
||||
$this->error = "Error " . $this->db->lasterror();
|
||||
dol_syslog(get_class($this) . "::fetch_all " . $this->error, LOG_ERR);
|
||||
return - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all objects in memory from database
|
||||
*
|
||||
* @param string $sortorder order
|
||||
* @param string $sortfield field
|
||||
* @param int $limit page
|
||||
* @param int $offset offset
|
||||
* @param array $filter output
|
||||
* @return int <0 if KO, >0 if OK
|
||||
*/
|
||||
function fetch_all_log($sortorder, $sortfield, $limit, $offset, $filter = array()) {
|
||||
|
||||
global $langs;
|
||||
$sql = "SELECT";
|
||||
$sql .= " t.rowid,";
|
||||
|
||||
$sql .= " t.entity,";
|
||||
$sql .= " t.datec,";
|
||||
$sql .= " t.fk_product,";
|
||||
$sql .= " t.fk_soc,";
|
||||
$sql .= " t.price,";
|
||||
$sql .= " t.price_ttc,";
|
||||
$sql .= " t.price_min,";
|
||||
$sql .= " t.price_min_ttc,";
|
||||
$sql .= " t.price_base_type,";
|
||||
$sql .= " t.tva_tx,";
|
||||
$sql .= " t.recuperableonly,";
|
||||
$sql .= " t.localtax1_tx,";
|
||||
$sql .= " t.localtax2_tx,";
|
||||
$sql .= " t.fk_user,";
|
||||
$sql .= " t.import_key,";
|
||||
$sql .= " soc.nom as socname,";
|
||||
$sql .= " prod.ref as prodref";
|
||||
$sql .= " FROM " . MAIN_DB_PREFIX . "product_customer_price_log as t ";
|
||||
$sql .= " ," . MAIN_DB_PREFIX . "product as prod ";
|
||||
$sql .= " ," . MAIN_DB_PREFIX . "societe as soc ";
|
||||
$sql .= " WHERE soc.rowid=t.fk_soc ";
|
||||
$sql .= " AND prod.rowid=t.fk_product ";
|
||||
$sql .= " AND prod.entity IN (" . getEntity('product', 1) . ")";
|
||||
|
||||
// Manage filter
|
||||
if (count($filter) > 0) {
|
||||
foreach ( $filter as $key => $value ) {
|
||||
if (strpos($key, 'date')) // To allow $filter['YEAR(s.dated)']=>$year
|
||||
{
|
||||
$sql .= ' AND ' . $key . ' = \'' . $value . '\'';
|
||||
} elseif ($key == 'soc.nom') {
|
||||
$sql .= ' AND ' . $key . ' LIKE \'%' . $value . '%\'';
|
||||
} else {
|
||||
$sql .= ' AND ' . $key . ' = ' . $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! empty($sortfield)) {
|
||||
$sql .= " ORDER BY " . $sortfield . ' ' . $sortorder;
|
||||
}
|
||||
if (! empty($limit)) {
|
||||
$sql .= ' ' . $this->db->plimit($limit + 1, $offset);
|
||||
}
|
||||
|
||||
dol_syslog(get_class($this) . "::fetch_all_log sql=" . $sql, LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
|
||||
$this->lines = array ();
|
||||
$num = $this->db->num_rows($resql);
|
||||
|
||||
while ( $obj = $this->db->fetch_object($resql) ) {
|
||||
|
||||
$line = new PriceByCustomerLine();
|
||||
|
||||
$line->id = $obj->rowid;
|
||||
|
||||
$line->entity = $obj->entity;
|
||||
$line->datec = $this->db->jdate($obj->datec);
|
||||
$line->tms = $this->db->jdate($obj->tms);
|
||||
$line->fk_product = $obj->fk_product;
|
||||
$line->fk_soc = $obj->fk_soc;
|
||||
$line->price = $obj->price;
|
||||
$line->price_ttc = $obj->price_ttc;
|
||||
$line->price_min = $obj->price_min;
|
||||
$line->price_min_ttc = $obj->price_min_ttc;
|
||||
$line->price_base_type = $obj->price_base_type;
|
||||
$line->tva_tx = $obj->tva_tx;
|
||||
$line->recuperableonly = $obj->recuperableonly;
|
||||
$line->localtax1_tx = $obj->localtax1_tx;
|
||||
$line->localtax2_tx = $obj->localtax2_tx;
|
||||
$line->fk_user = $obj->fk_user;
|
||||
$line->import_key = $obj->import_key;
|
||||
$line->socname = $obj->socname;
|
||||
$line->prodref = $obj->prodref;
|
||||
|
||||
$this->lines [] = $line;
|
||||
}
|
||||
$this->db->free($resql);
|
||||
|
||||
return $num;
|
||||
} else {
|
||||
$this->error = "Error " . $this->db->lasterror();
|
||||
dol_syslog(get_class($this) . "::fetch_all_log " . $this->error, LOG_ERR);
|
||||
return - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update object into database
|
||||
*
|
||||
* @param User $user that modifies
|
||||
* @param int $notrigger triggers after, 1=disable triggers
|
||||
* @param int $forceupdateaffiliate update price on each soc child
|
||||
* @return int <0 if KO, >0 if OK
|
||||
*/
|
||||
function update($user = 0, $notrigger = 0, $forceupdateaffiliate = 0) {
|
||||
|
||||
global $conf, $langs;
|
||||
$error = 0;
|
||||
|
||||
// Clean parameters
|
||||
|
||||
if (isset($this->entity))
|
||||
$this->entity = trim($this->entity);
|
||||
if (isset($this->fk_product))
|
||||
$this->fk_product = trim($this->fk_product);
|
||||
if (isset($this->fk_soc))
|
||||
$this->fk_soc = trim($this->fk_soc);
|
||||
if (isset($this->price))
|
||||
$this->price = trim($this->price);
|
||||
if (isset($this->price_ttc))
|
||||
$this->price_ttc = trim($this->price_ttc);
|
||||
if (isset($this->price_min))
|
||||
$this->price_min = trim($this->price_min);
|
||||
if (isset($this->price_min_ttc))
|
||||
$this->price_min_ttc = trim($this->price_min_ttc);
|
||||
if (isset($this->price_base_type))
|
||||
$this->price_base_type = trim($this->price_base_type);
|
||||
if (isset($this->tva_tx))
|
||||
$this->tva_tx = trim($this->tva_tx);
|
||||
if (isset($this->recuperableonly))
|
||||
$this->recuperableonly = trim($this->recuperableonly);
|
||||
if (isset($this->localtax1_tx))
|
||||
$this->localtax1_tx = trim($this->localtax1_tx);
|
||||
if (isset($this->localtax2_tx))
|
||||
$this->localtax2_tx = trim($this->localtax2_tx);
|
||||
if (isset($this->fk_user))
|
||||
$this->fk_user = trim($this->fk_user);
|
||||
if (isset($this->import_key))
|
||||
$this->import_key = trim($this->import_key);
|
||||
|
||||
// Check parameters
|
||||
// Put here code to add a control on parameters values
|
||||
|
||||
if ($this->price != '' || $this->price == 0) {
|
||||
if ($this->price_base_type == 'TTC') {
|
||||
$this->price_ttc = price2num($this->price, 'MU');
|
||||
$this->price = price2num($this->price) / (1 + ($this->tva_tx / 100));
|
||||
$this->price = price2num($this->price, 'MU');
|
||||
|
||||
if ($this->price_min != '' || $this->price_min == 0) {
|
||||
$this->price_min_ttc = price2num($this->price_min, 'MU');
|
||||
$this->price_min = price2num($this->price_min) / (1 + ($this->tva_tx / 100));
|
||||
$this->price_min = price2num($this->price_min, 'MU');
|
||||
} else {
|
||||
$this->price_min = 0;
|
||||
$this->price_min_ttc = 0;
|
||||
}
|
||||
} else {
|
||||
$this->price = price2num($this->price, 'MU');
|
||||
$this->price_ttc = ($this->recuperableonly != 1) ? price2num($this->price) * (1 + ($this->tva_tx / 100)) : $this->price;
|
||||
$this->price_ttc = price2num($this->price_ttc, 'MU');
|
||||
|
||||
if ($this->price_min != '' || $this->price_min == 0) {
|
||||
$this->price_min = price2num($this->price_min, 'MU');
|
||||
$this->price_min_ttc = price2num($this->price_min) * (1 + ($this->tva_tx / 100));
|
||||
$this->price_min_ttc = price2num($this->price_min_ttc, 'MU');
|
||||
// print 'X'.$newminprice.'-'.$price_min;
|
||||
} else {
|
||||
$this->price_min = 0;
|
||||
$this->price_min_ttc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do a copy of current record into log table
|
||||
// Insert request
|
||||
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_customer_price_log(";
|
||||
|
||||
$sql .= "entity,";
|
||||
$sql .= "datec,";
|
||||
$sql .= "fk_product,";
|
||||
$sql .= "fk_soc,";
|
||||
$sql .= "price,";
|
||||
$sql .= "price_ttc,";
|
||||
$sql .= "price_min,";
|
||||
$sql .= "price_min_ttc,";
|
||||
$sql .= "price_base_type,";
|
||||
$sql .= "tva_tx,";
|
||||
$sql .= "recuperableonly,";
|
||||
$sql .= "localtax1_tx,";
|
||||
$sql .= "localtax2_tx,";
|
||||
$sql .= "fk_user,";
|
||||
$sql .= "import_key";
|
||||
|
||||
$sql .= ") ";
|
||||
$sql .= "SELECT";
|
||||
|
||||
$sql .= " t.entity,";
|
||||
$sql .= " t.datec,";
|
||||
$sql .= " t.fk_product,";
|
||||
$sql .= " t.fk_soc,";
|
||||
$sql .= " t.price,";
|
||||
$sql .= " t.price_ttc,";
|
||||
$sql .= " t.price_min,";
|
||||
$sql .= " t.price_min_ttc,";
|
||||
$sql .= " t.price_base_type,";
|
||||
$sql .= " t.tva_tx,";
|
||||
$sql .= " t.recuperableonly,";
|
||||
$sql .= " t.localtax1_tx,";
|
||||
$sql .= " t.localtax2_tx,";
|
||||
$sql .= " t.fk_user,";
|
||||
$sql .= " t.import_key";
|
||||
|
||||
$sql .= " FROM " . MAIN_DB_PREFIX . "product_customer_price as t";
|
||||
$sql .= " WHERE t.rowid = " . $this->id;
|
||||
|
||||
$this->db->begin();
|
||||
dol_syslog(get_class($this) . "::update sql=" . $sql, LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if (! $resql) {
|
||||
$error ++;
|
||||
$this->errors [] = "Error " . $this->db->lasterror();
|
||||
}
|
||||
|
||||
// Update request
|
||||
$sql = "UPDATE " . MAIN_DB_PREFIX . "product_customer_price SET";
|
||||
|
||||
$sql .= " entity=" . $conf->entity . ",";
|
||||
$sql .= " datec='" . $this->db->idate(dol_now()) . "',";
|
||||
$sql .= " tms=" . (dol_strlen($this->tms) != 0 ? "'" . $this->db->idate($this->tms) . "'" : 'null') . ",";
|
||||
$sql .= " fk_product=" . (isset($this->fk_product) ? $this->fk_product : "null") . ",";
|
||||
$sql .= " fk_soc=" . (isset($this->fk_soc) ? $this->fk_soc : "null") . ",";
|
||||
$sql .= " price=" . (isset($this->price) ? $this->price : "null") . ",";
|
||||
$sql .= " price_ttc=" . (isset($this->price_ttc) ? $this->price_ttc : "null") . ",";
|
||||
$sql .= " price_min=" . (isset($this->price_min) ? $this->price_min : "null") . ",";
|
||||
$sql .= " price_min_ttc=" . (isset($this->price_min_ttc) ? $this->price_min_ttc : "null") . ",";
|
||||
$sql .= " price_base_type=" . (isset($this->price_base_type) ? "'" . $this->db->escape($this->price_base_type) . "'" : "null") . ",";
|
||||
$sql .= " tva_tx=" . (isset($this->tva_tx) ? $this->tva_tx : "null") . ",";
|
||||
$sql .= " recuperableonly=" . (isset($this->recuperableonly) ? $this->recuperableonly : "null") . ",";
|
||||
$sql .= " localtax1_tx=" . (isset($this->localtax1_tx) ? $this->localtax1_tx : "null") . ",";
|
||||
$sql .= " localtax2_tx=" . (isset($this->localtax2_tx) ? $this->localtax2_tx : "null") . ",";
|
||||
$sql .= " fk_user=" . $user->id . ",";
|
||||
$sql .= " import_key=" . (isset($this->import_key) ? "'" . $this->db->escape($this->import_key) . "'" : "null") . "";
|
||||
|
||||
$sql .= " WHERE rowid=" . $this->id;
|
||||
|
||||
dol_syslog(get_class($this) . "::update sql=" . $sql, LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if (! $resql) {
|
||||
$error ++;
|
||||
$this->errors [] = "Error " . $this->db->lasterror();
|
||||
}
|
||||
|
||||
if (! $error) {
|
||||
if (! $notrigger) {
|
||||
// Uncomment this and change MYOBJECT to your own tag if you
|
||||
// want this action calls a trigger.
|
||||
|
||||
// // Call triggers
|
||||
// include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
|
||||
// $interface=new Interfaces($this->db);
|
||||
// $result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf);
|
||||
// if ($result < 0) { $error++; $this->errors=$interface->errors; }
|
||||
// // End call triggers
|
||||
}
|
||||
}
|
||||
|
||||
if (! $error) {
|
||||
$result = $this->setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate);
|
||||
if ($result < 0) {
|
||||
$error ++;
|
||||
}
|
||||
}
|
||||
|
||||
// Commit or rollback
|
||||
if ($error) {
|
||||
foreach ( $this->errors as $errmsg ) {
|
||||
dol_syslog(get_class($this) . "::update " . $errmsg, LOG_ERR);
|
||||
$this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
|
||||
}
|
||||
$this->db->rollback();
|
||||
return - 1 * $error;
|
||||
} else {
|
||||
$this->db->commit();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force update price on child price
|
||||
*
|
||||
* @param User $user that modifies
|
||||
* @param int $forceupdateaffiliate update price on each soc child
|
||||
* @return int <0 if KO, >0 if OK
|
||||
*/
|
||||
function setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate) {
|
||||
|
||||
$error = 0;
|
||||
|
||||
// Find all susidiaries
|
||||
$sql = "SELECT s.rowid";
|
||||
$sql .= " FROM " . MAIN_DB_PREFIX . "societe as s";
|
||||
$sql .= " WHERE s.parent = " . $this->fk_soc;
|
||||
$sql .= " AND s.entity IN (" . getEntity('societe', 1) . ")";
|
||||
|
||||
dol_syslog(get_class($this) . "::setPriceOnAffiliateThirdparty sql=" . $sql, LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
|
||||
if ($resql) {
|
||||
|
||||
$this->lines = array ();
|
||||
$num = $this->db->num_rows($resql);
|
||||
|
||||
while ( ($obj = $this->db->fetch_object($resql)) && (empty($error)) ) {
|
||||
|
||||
// find if there is an existing line for the product and the subsidiaries
|
||||
$prodsocprice = new Productcustomerprice($this->db);
|
||||
|
||||
$filter = array (
|
||||
't.fk_product' => $this->fk_product,'t.fk_soc' => $obj->rowid
|
||||
);
|
||||
|
||||
$result = $prodsocprice->fetch_all('', '', 0, 0, $filter);
|
||||
if ($result < 0) {
|
||||
$error ++;
|
||||
$this->error = $prodsocprice->error;
|
||||
} else {
|
||||
|
||||
// There is one line
|
||||
if (count($prodsocprice->lines) > 0) {
|
||||
// If force update => Update
|
||||
if (! empty($forceupdateaffiliate)) {
|
||||
|
||||
$prodsocpriceupd = new Productcustomerprice($this->db);
|
||||
$prodsocpriceupd->fetch($prodsocprice->lines [0]->id);
|
||||
|
||||
$prodsocpriceupd->price = $this->price;
|
||||
$prodsocpriceupd->price_min = $this->price_min;
|
||||
$prodsocpriceupd->price_base_type = $this->price_base_type;
|
||||
$prodsocpriceupd->tva_tx = $this->tva_tx;
|
||||
$prodsocpriceupd->recuperableonly = $this->recuperableonly;
|
||||
|
||||
$resultupd = $prodsocpriceupd->update($user, 0, $forceupdateaffiliate);
|
||||
if ($result < 0) {
|
||||
$error ++;
|
||||
$this->error = $prodsocpriceupd->error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If line do not exits then create it
|
||||
$prodsocpricenew = new Productcustomerprice($this->db);
|
||||
$prodsocpricenew->fk_soc = $obj->rowid;
|
||||
$prodsocpricenew->fk_product = $this->fk_product;
|
||||
$prodsocpricenew->price = $this->price;
|
||||
$prodsocpricenew->price_min = $this->price_min;
|
||||
$prodsocpricenew->price_base_type = $this->price_base_type;
|
||||
$prodsocpricenew->tva_tx = $this->tva_tx;
|
||||
$prodsocpricenew->recuperableonly = $this->recuperableonly;
|
||||
|
||||
$resultupd = $prodsocpricenew->create($user, 0, $forceupdateaffiliate);
|
||||
if ($result < 0) {
|
||||
$error ++;
|
||||
$this->error = $prodsocpriceupd->error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->db->free($resql);
|
||||
|
||||
if (empty($error)) {
|
||||
return 1;
|
||||
} else {
|
||||
return - 1;
|
||||
}
|
||||
} else {
|
||||
$this->error = "Error " . $this->db->lasterror();
|
||||
dol_syslog(get_class($this) . "::setPriceOnAffiliateThirdparty " . $this->error, LOG_ERR);
|
||||
return - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete object in database
|
||||
*
|
||||
* @param User $user that deletes
|
||||
* @param int $notrigger triggers after, 1=disable triggers
|
||||
* @return int <0 if KO, >0 if OK
|
||||
*/
|
||||
function delete($user, $notrigger = 0) {
|
||||
|
||||
global $conf, $langs;
|
||||
$error = 0;
|
||||
|
||||
$this->db->begin();
|
||||
|
||||
if (! $error) {
|
||||
if (! $notrigger) {
|
||||
// Uncomment this and change MYOBJECT to your own tag if you
|
||||
// want this action calls a trigger.
|
||||
|
||||
// // Call triggers
|
||||
// include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
|
||||
// $interface=new Interfaces($this->db);
|
||||
// $result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf);
|
||||
// if ($result < 0) { $error++; $this->errors=$interface->errors; }
|
||||
// // End call triggers
|
||||
}
|
||||
}
|
||||
|
||||
if (! $error) {
|
||||
$sql = "DELETE FROM " . MAIN_DB_PREFIX . "product_customer_price";
|
||||
$sql .= " WHERE rowid=" . $this->id;
|
||||
|
||||
dol_syslog(get_class($this) . "::delete sql=" . $sql);
|
||||
$resql = $this->db->query($sql);
|
||||
if (! $resql) {
|
||||
$error ++;
|
||||
$this->errors [] = "Error " . $this->db->lasterror();
|
||||
}
|
||||
}
|
||||
|
||||
// Commit or rollback
|
||||
if ($error) {
|
||||
foreach ( $this->errors as $errmsg ) {
|
||||
dol_syslog(get_class($this) . "::delete " . $errmsg, LOG_ERR);
|
||||
$this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
|
||||
}
|
||||
$this->db->rollback();
|
||||
return - 1 * $error;
|
||||
} else {
|
||||
$this->db->commit();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an object from its id and create a new one in database
|
||||
*
|
||||
* @param int $fromid of object to clone
|
||||
* @return int id of clone
|
||||
*/
|
||||
function createFromClone($fromid) {
|
||||
|
||||
global $user, $langs;
|
||||
|
||||
$error = 0;
|
||||
|
||||
$object = new Productcustomerprice($this->db);
|
||||
|
||||
$this->db->begin();
|
||||
|
||||
// Load source object
|
||||
$object->fetch($fromid);
|
||||
$object->id = 0;
|
||||
$object->statut = 0;
|
||||
|
||||
// Clear fields
|
||||
// ...
|
||||
|
||||
// Create clone
|
||||
$result = $object->create($user);
|
||||
|
||||
// Other options
|
||||
if ($result < 0) {
|
||||
$this->error = $object->error;
|
||||
$error ++;
|
||||
}
|
||||
|
||||
if (! $error) {
|
||||
}
|
||||
|
||||
// End
|
||||
if (! $error) {
|
||||
$this->db->commit();
|
||||
return $object->id;
|
||||
} else {
|
||||
$this->db->rollback();
|
||||
return - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise object with example values
|
||||
* Id must be 0 if object instance is a specimen
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function initAsSpecimen() {
|
||||
|
||||
$this->id = 0;
|
||||
|
||||
$this->entity = '';
|
||||
$this->datec = '';
|
||||
$this->tms = '';
|
||||
$this->fk_product = '';
|
||||
$this->fk_soc = '';
|
||||
$this->price = '';
|
||||
$this->price_ttc = '';
|
||||
$this->price_min = '';
|
||||
$this->price_min_ttc = '';
|
||||
$this->price_base_type = '';
|
||||
$this->tva_tx = '';
|
||||
$this->recuperableonly = '';
|
||||
$this->localtax1_tx = '';
|
||||
$this->localtax2_tx = '';
|
||||
$this->fk_user = '';
|
||||
$this->import_key = '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* File of class to manage predefined price products or services by customer lines
|
||||
*/
|
||||
class PriceByCustomerLine
|
||||
{
|
||||
var $id;
|
||||
var $entity;
|
||||
var $datec = '';
|
||||
var $tms = '';
|
||||
var $fk_product;
|
||||
var $fk_soc;
|
||||
var $price;
|
||||
var $price_ttc;
|
||||
var $price_min;
|
||||
var $price_min_ttc;
|
||||
var $price_base_type;
|
||||
var $tva_tx;
|
||||
var $recuperableonly;
|
||||
var $localtax1_tx;
|
||||
var $localtax2_tx;
|
||||
var $fk_user;
|
||||
var $import_key;
|
||||
var $socname;
|
||||
var $prodref;
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
565
htdocs/societe/price.php
Normal file
565
htdocs/societe/price.php
Normal file
@ -0,0 +1,565 @@
|
||||
<?php
|
||||
/* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
|
||||
* Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2005 Eric Seigne <eric.seigne@ryxeo.com>
|
||||
* Copyright (C) 2005-2013 Regis Houssin <regis.houssin@capnetworks.com>
|
||||
* Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file htdocs/societe/price.php
|
||||
* \ingroup product
|
||||
* \brief Page to show product prices by customer
|
||||
*/
|
||||
require '../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
|
||||
|
||||
if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
|
||||
require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
|
||||
|
||||
$prodcustprice = new Productcustomerprice($db);
|
||||
}
|
||||
|
||||
$langs->load("products");
|
||||
$langs->load("companies");
|
||||
$langs->load("bills");
|
||||
|
||||
$action = GETPOST('action', 'alpha');
|
||||
|
||||
// Security check
|
||||
$socid = GETPOST('socid', 'int');
|
||||
if ($user->societe_id)
|
||||
$socid = $user->societe_id;
|
||||
$result = restrictedArea($user, 'societe', $socid, '&societe');
|
||||
|
||||
/**
|
||||
* ***************************************************
|
||||
* Price by customer
|
||||
* ****************************************************
|
||||
*/
|
||||
if ($action == 'add_customer_price_confirm' && ! $_POST ["cancel"] && ($user->rights->produit->creer || $user->rights->service->creer)) {
|
||||
|
||||
$update_child_soc = GETPOST('updatechildprice');
|
||||
|
||||
// add price by customer
|
||||
$prodcustprice->fk_soc = $socid;
|
||||
$prodcustprice->fk_product = GETPOST('prodid', 'int');
|
||||
$prodcustprice->price = price2num(GETPOST("price"), 'MU');
|
||||
$prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU');
|
||||
$prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha');
|
||||
$prodcustprice->tva_tx = str_replace('*', '', GETPOST("tva_tx"));
|
||||
$prodcustprice->recuperableonly = (preg_match('/\*/', GETPOST("tva_tx")) ? 1 : 0);
|
||||
|
||||
$result = $prodcustprice->create($user, 0, $update_child_soc);
|
||||
|
||||
if ($result < 0) {
|
||||
setEventMessage($prodcustprice->error, 'errors');
|
||||
} else {
|
||||
setEventMessage($langs->trans('Save'), 'mesgs');
|
||||
}
|
||||
|
||||
$action = '';
|
||||
}
|
||||
|
||||
if ($action == 'delete_customer_price' && ($user->rights->produit->creer || $user->rights->service->creer)) {
|
||||
// Delete price by customer
|
||||
$prodcustprice->id = GETPOST('lineid');
|
||||
$result = $prodcustprice->delete($user);
|
||||
|
||||
if ($result < 0) {
|
||||
setEventMessage($prodcustprice->error, 'mesgs');
|
||||
} else {
|
||||
setEventMessage($langs->trans('Delete'), 'errors');
|
||||
}
|
||||
$action = '';
|
||||
}
|
||||
|
||||
if ($action == 'update_customer_price_confirm' && ! $_POST ["cancel"] && ($user->rights->produit->creer || $user->rights->service->creer)) {
|
||||
|
||||
$prodcustprice->fetch(GETPOST('lineid', 'int'));
|
||||
|
||||
$update_child_soc = GETPOST('updatechildprice');
|
||||
|
||||
// update price by customer
|
||||
$prodcustprice->price = price2num(GETPOST("price"), 'MU');
|
||||
$prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU');
|
||||
$prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha');
|
||||
$prodcustprice->tva_tx = str_replace('*', '', GETPOST("tva_tx"));
|
||||
$prodcustprice->recuperableonly = (preg_match('/\*/', GETPOST("tva_tx")) ? 1 : 0);
|
||||
|
||||
$result = $prodcustprice->update($user, 0, $update_child_soc);
|
||||
if ($result < 0) {
|
||||
setEventMessage($prodcustprice->error, 'errors');
|
||||
} else {
|
||||
setEventMessage($langs->trans('Save'), 'mesgs');
|
||||
}
|
||||
|
||||
$action = '';
|
||||
}
|
||||
|
||||
/*
|
||||
* View
|
||||
*/
|
||||
|
||||
$form = new Form($db);
|
||||
|
||||
$soc = new Societe($db);
|
||||
|
||||
$result = $soc->fetch($socid);
|
||||
llxHeader("", $langs->trans("ThirdParty") . '-' . $langs->trans('PriceByCustomer'));
|
||||
|
||||
if (! empty($conf->notification->enabled))
|
||||
$langs->load("mails");
|
||||
$head = societe_prepare_head($soc);
|
||||
|
||||
dol_fiche_head($head, 'price', $langs->trans("ThirdParty"), 0, 'company');
|
||||
|
||||
print '<table class="border" width="100%">';
|
||||
|
||||
print '<tr><td width="25%">' . $langs->trans("ThirdPartyName") . '</td><td colspan="3">';
|
||||
print $form->showrefnav($soc, 'socid', '', ($user->societe_id ? 0 : 1), 'rowid', 'nom');
|
||||
print '</td></tr>';
|
||||
|
||||
if (! empty($conf->global->SOCIETE_USEPREFIX)) // Old not used prefix field
|
||||
{
|
||||
print '<tr><td>' . $langs->trans('Prefix') . '</td><td colspan="3">' . $soc->prefix_comm . '</td></tr>';
|
||||
}
|
||||
|
||||
if ($soc->client) {
|
||||
print '<tr><td>';
|
||||
print $langs->trans('CustomerCode') . '</td><td colspan="3">';
|
||||
print $soc->code_client;
|
||||
if ($soc->check_codeclient() != 0)
|
||||
print ' <font class="error">(' . $langs->trans("WrongCustomerCode") . ')</font>';
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
if ($soc->fournisseur) {
|
||||
print '<tr><td>';
|
||||
print $langs->trans('SupplierCode') . '</td><td colspan="3">';
|
||||
print $soc->code_fournisseur;
|
||||
if ($soc->check_codefournisseur() != 0)
|
||||
print ' <font class="error">(' . $langs->trans("WrongSupplierCode") . ')</font>';
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
if (! empty($conf->barcode->enabled)) {
|
||||
print '<tr><td>' . $langs->trans('Gencod') . '</td><td colspan="3">' . $soc->barcode . '</td></tr>';
|
||||
}
|
||||
|
||||
print "<tr><td valign=\"top\">" . $langs->trans('Address') . "</td><td colspan=\"3\">";
|
||||
dol_print_address($soc->address, 'gmap', 'thirdparty', $soc->id);
|
||||
print "</td></tr>";
|
||||
|
||||
// Zip / Town
|
||||
print '<tr><td width="25%">' . $langs->trans('Zip') . '</td><td width="25%">' . $soc->zip . "</td>";
|
||||
print '<td width="25%">' . $langs->trans('Town') . '</td><td width="25%">' . $soc->town . "</td></tr>";
|
||||
|
||||
// Country
|
||||
if ($soc->country) {
|
||||
print '<tr><td>' . $langs->trans('Country') . '</td><td colspan="3">';
|
||||
$img = picto_from_langcode($soc->country_code);
|
||||
print($img ? $img . ' ' : '');
|
||||
print $soc->country;
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
// EMail
|
||||
print '<tr><td>' . $langs->trans('EMail') . '</td><td colspan="3">';
|
||||
print dol_print_email($soc->email, 0, $soc->id, 'AC_EMAIL');
|
||||
print '</td></tr>';
|
||||
|
||||
// Web
|
||||
print '<tr><td>' . $langs->trans('Web') . '</td><td colspan="3">';
|
||||
print dol_print_url($soc->url);
|
||||
print '</td></tr>';
|
||||
|
||||
// Phone / Fax
|
||||
print '<tr><td>' . $langs->trans('Phone') . '</td><td>' . dol_print_phone($soc->tel, $soc->country_code, 0, $soc->id, 'AC_TEL') . '</td>';
|
||||
print '<td>' . $langs->trans('Fax') . '</td><td>' . dol_print_phone($soc->fax, $soc->country_code, 0, $soc->id, 'AC_FAX') . '</td></tr>';
|
||||
|
||||
print '</table>';
|
||||
|
||||
print '</div>';
|
||||
|
||||
if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
|
||||
|
||||
$prodcustprice = new Productcustomerprice($db);
|
||||
|
||||
$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 = "ASC";
|
||||
if (! $sortfield)
|
||||
$sortfield = "soc.nom";
|
||||
|
||||
// Build filter to diplay only concerned lines
|
||||
$filter = array (
|
||||
't.fk_soc' => $soc->id
|
||||
);
|
||||
|
||||
$search_soc = GETPOST('search_soc');
|
||||
if (! empty($search_soc)) {
|
||||
$filter ['soc.nom'] = $search_soc;
|
||||
}
|
||||
|
||||
if ($action == 'add_customer_price') {
|
||||
|
||||
// Create mode
|
||||
|
||||
print_fiche_titre($langs->trans('PriceByCustomer'));
|
||||
|
||||
print '<form action="' . $_SERVER ["PHP_SELF"] . '?socid=' . $soc->id . '" method="POST">';
|
||||
print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
|
||||
print '<input type="hidden" name="action" value="add_customer_price_confirm">';
|
||||
print '<input type="hidden" name="socid" value="' . $soc->id . '">';
|
||||
print '<table class="border" width="100%">';
|
||||
print '<tr>';
|
||||
print '<td>' . $langs->trans('Product') . '</td>';
|
||||
print '<td>';
|
||||
print $form->select_produits('', 'prodid', '', 0);
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
// VAT
|
||||
print '<tr><td>' . $langs->trans("VATRate") . '</td><td>';
|
||||
print $form->load_tva("tva_tx", $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr);
|
||||
print '</td></tr>';
|
||||
|
||||
// Price base
|
||||
print '<tr><td width="15%">';
|
||||
print $langs->trans('PriceBase');
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print $form->select_PriceBaseType($object->price_base_type, "price_base_type");
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
// Price
|
||||
print '<tr><td width="20%">';
|
||||
$text = $langs->trans('SellingPrice');
|
||||
print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1);
|
||||
print '</td><td>';
|
||||
if ($object->price_base_type == 'TTC') {
|
||||
print '<input name="price" size="10" value="' . price($object->price_ttc) . '">';
|
||||
} else {
|
||||
print '<input name="price" size="10" value="' . price($object->price) . '">';
|
||||
}
|
||||
print '</td></tr>';
|
||||
|
||||
// Price minimum
|
||||
print '<tr><td>';
|
||||
$text = $langs->trans('MinPrice');
|
||||
print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1);
|
||||
if ($object->price_base_type == 'TTC') {
|
||||
print '<td><input name="price_min" size="10" value="' . price($object->price_min_ttc) . '">';
|
||||
} else {
|
||||
print '<td><input name="price_min" size="10" value="' . price($object->price_min) . '">';
|
||||
}
|
||||
print '</td></tr>';
|
||||
|
||||
// Update all child soc
|
||||
print '<tr><td width="15%">';
|
||||
print $langs->trans('ForceUpdateChildPriceSoc');
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print '<input type="checkbox" name="updatechildprice" value="1"/>';
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
print '</table>';
|
||||
|
||||
print '<center><br><input type="submit" class="button" value="' . $langs->trans("Save") . '"> ';
|
||||
print '<input type="submit" class="button" name="cancel" value="' . $langs->trans("Cancel") . '"></center>';
|
||||
|
||||
print '<br></form>';
|
||||
} elseif ($action == 'edit_customer_price') {
|
||||
|
||||
// Edit mode
|
||||
|
||||
print_fiche_titre($langs->trans('PriceByCustomer'));
|
||||
|
||||
$result = $prodcustprice->fetch(GETPOST('lineid', 'int'));
|
||||
if ($result < 0) {
|
||||
setEventMessage($prodcustprice->error, 'errors');
|
||||
}
|
||||
|
||||
print '<form action="' . $_SERVER ["PHP_SELF"] . '?socid=' . $soc->id . '" method="POST">';
|
||||
print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
|
||||
print '<input type="hidden" name="action" value="update_customer_price_confirm">';
|
||||
print '<input type="hidden" name="lineid" value="' . $prodcustprice->id . '">';
|
||||
print '<table class="border" width="100%">';
|
||||
print '<tr>';
|
||||
print '<td>' . $langs->trans('Product') . '</td>';
|
||||
$staticprod = new Product($db);
|
||||
$staticprod->fetch($prodcustprice->fk_product);
|
||||
print "<td>" . $staticprod->getNomUrl(1) . "</td>";
|
||||
print '</tr>';
|
||||
|
||||
// VAT
|
||||
print '<tr><td>' . $langs->trans("VATRate") . '</td><td>';
|
||||
print $form->load_tva("tva_tx", $prodcustprice->tva_tx, $mysoc, '', $staticprod->id, $prodcustprice->recuperableonly);
|
||||
print '</td></tr>';
|
||||
|
||||
// Price base
|
||||
print '<tr><td width="15%">';
|
||||
print $langs->trans('PriceBase');
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print $form->select_PriceBaseType($prodcustprice->price_base_type, "price_base_type");
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
// Price
|
||||
print '<tr><td width="20%">';
|
||||
$text = $langs->trans('SellingPrice');
|
||||
print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1);
|
||||
print '</td><td>';
|
||||
if ($prodcustprice->price_base_type == 'TTC') {
|
||||
print '<input name="price" size="10" value="' . price($prodcustprice->price_ttc) . '">';
|
||||
} else {
|
||||
print '<input name="price" size="10" value="' . price($prodcustprice->price) . '">';
|
||||
}
|
||||
print '</td></tr>';
|
||||
|
||||
// Price minimum
|
||||
print '<tr><td>';
|
||||
$text = $langs->trans('MinPrice');
|
||||
print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1);
|
||||
if ($prodcustprice->price_base_type == 'TTC') {
|
||||
print '<td><input name="price_min" size="10" value="' . price($prodcustprice->price_min_ttc) . '">';
|
||||
} else {
|
||||
print '<td><input name="price_min" size="10" value="' . price($prodcustprice->price_min) . '">';
|
||||
}
|
||||
print '</td></tr>';
|
||||
|
||||
// Update all child soc
|
||||
print '<tr><td width="15%">';
|
||||
print $langs->trans('ForceUpdateChildPriceSoc');
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print '<input type="checkbox" name="updatechildprice" value="1">';
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
print '</table>';
|
||||
|
||||
print '<center><br><input type="submit" class="button" value="' . $langs->trans("Save") . '"> ';
|
||||
print '<input type="submit" class="button" name="cancel" value="' . $langs->trans("Cancel") . '"></center>';
|
||||
|
||||
print '<br></form>';
|
||||
} elseif ($action == 'showlog_customer_price') {
|
||||
|
||||
$filter = array (
|
||||
't.fk_product' => GETPOST('prodid', 'int'),'t.fk_soc' => $socid
|
||||
);
|
||||
|
||||
// Count total nb of records
|
||||
$nbtotalofrecords = 0;
|
||||
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
|
||||
$nbtotalofrecords = $prodcustprice->fetch_all_log($sortorder, $sortfield, $conf->liste_limit, $offset, $filter);
|
||||
}
|
||||
|
||||
$result = $prodcustprice->fetch_all_log($sortorder, $sortfield, $conf->liste_limit, $offset, $filter);
|
||||
if ($result < 0) {
|
||||
setEventMessage($prodcustprice->error, 'errors');
|
||||
}
|
||||
|
||||
$option = '&socid=' . GETPOST('socid', 'int') . '&prodid=' . GETPOST('prodid', 'int');
|
||||
|
||||
print_barre_liste($langs->trans('PriceByCustomerLog'), $page, $_SERVEUR ['PHP_SELF'], $option, $sortfield, $sortorder, '', count($prodcustprice->lines), $nbtotalofrecords);
|
||||
|
||||
if (count($prodcustprice->lines) > 0) {
|
||||
|
||||
print '<form action="' . $_SERVER ["PHP_SELF"] . '?id=' . $object->id . '" method="POST">';
|
||||
print '<input type="hidden" name="id" value="' . $object->id . '">';
|
||||
|
||||
print '<table class="noborder" width="100%">';
|
||||
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>' . $langs->trans("Product") . '</td>';
|
||||
print '<td>' . $langs->trans("AppliedPricesFrom") . '</td>';
|
||||
print '<td align="center">' . $langs->trans("PriceBase") . '</td>';
|
||||
print '<td align="right">' . $langs->trans("VAT") . '</td>';
|
||||
print '<td align="right">' . $langs->trans("HT") . '</td>';
|
||||
print '<td align="right">' . $langs->trans("TTC") . '</td>';
|
||||
print '<td align="right">' . $langs->trans("MinPrice") . ' ' . $langs->trans("HT") . '</td>';
|
||||
print '<td align="right">' . $langs->trans("MinPrice") . ' ' . $langs->trans("TTC") . '</td>';
|
||||
print '<td align="right">' . $langs->trans("ChangedBy") . '</td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
|
||||
$var = True;
|
||||
|
||||
foreach ( $prodcustprice->lines as $line ) {
|
||||
|
||||
print "<tr $bc[$var]>";
|
||||
$staticprod = new Product($db);
|
||||
$staticprod->fetch($line->fk_product);
|
||||
|
||||
print "<td>" . $staticprod->getNomUrl(1) . "</td>";
|
||||
print "<td>" . dol_print_date($line->datec, "dayhour") . "</td>";
|
||||
|
||||
print '<td align="center">' . $langs->trans($line->price_base_type) . "</td>";
|
||||
print '<td align="right">' . vatrate($line->tva_tx, true, $line->recuperableonly) . "</td>";
|
||||
print '<td align="right">' . price($line->price) . "</td>";
|
||||
print '<td align="right">' . price($line->price_ttc) . "</td>";
|
||||
print '<td align="right">' . price($line->price_min) . '</td>';
|
||||
print '<td align="right">' . price($line->price_min_ttc) . '</td>';
|
||||
|
||||
// User
|
||||
$userstatic = new User($db);
|
||||
$userstatic->fetch($line->fk_user);
|
||||
print '<td align="right">';
|
||||
print $userstatic->getLoginUrl(1);
|
||||
print '</td>';
|
||||
}
|
||||
print "</table>";
|
||||
} else {
|
||||
print $langs->trans('None');
|
||||
}
|
||||
|
||||
print "\n" . '<div class="tabsAction">' . "\n";
|
||||
print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER ["PHP_SELF"] . '?socid=' . $soc->id . '">' . $langs->trans("Ok") . '</a></div>';
|
||||
print "\n</div><br>\n";
|
||||
} else {
|
||||
|
||||
// View mode
|
||||
|
||||
// Count total nb of records
|
||||
$nbtotalofrecords = 0;
|
||||
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
|
||||
$nbtotalofrecords = $prodcustprice->fetch_all('', '', 0, 0, $filter);
|
||||
}
|
||||
|
||||
$result = $prodcustprice->fetch_all($sortorder, $sortfield, $conf->liste_limit, $offset, $filter);
|
||||
if ($result < 0) {
|
||||
setEventMessage($prodcustprice->error, 'errors');
|
||||
}
|
||||
|
||||
$option = '&search_soc=' . $search_soc . '&id=' . $object->id;
|
||||
|
||||
print_barre_liste($langs->trans('PriceByCustomer'), $page, $_SERVEUR ['PHP_SELF'], $option, $sortfield, $sortorder, '', count($prodcustprice->lines), $nbtotalofrecords);
|
||||
|
||||
if (count($prodcustprice->lines) > 0) {
|
||||
|
||||
print '<form action="' . $_SERVER ["PHP_SELF"] . '?id=' . $object->id . '" method="POST">';
|
||||
print '<input type="hidden" name="id" value="' . $object->id . '">';
|
||||
|
||||
print '<table class="noborder" width="100%">';
|
||||
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td>' . $langs->trans("Product") . '</td>';
|
||||
print '<td>' . $langs->trans("AppliedPricesFrom") . '</td>';
|
||||
print '<td align="center">' . $langs->trans("PriceBase") . '</td>';
|
||||
print '<td align="right">' . $langs->trans("VAT") . '</td>';
|
||||
print '<td align="right">' . $langs->trans("HT") . '</td>';
|
||||
print '<td align="right">' . $langs->trans("TTC") . '</td>';
|
||||
print '<td align="right">' . $langs->trans("MinPrice") . ' ' . $langs->trans("HT") . '</td>';
|
||||
print '<td align="right">' . $langs->trans("MinPrice") . ' ' . $langs->trans("TTC") . '</td>';
|
||||
print '<td align="right">' . $langs->trans("ChangedBy") . '</td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
|
||||
print '<tr class="liste_titre">';
|
||||
print '<td><input type="text" class="flat" name="search_soc" value="' . $search_soc . '" size="20"></td>';
|
||||
print '<td colspan="8"> </td>';
|
||||
// Print the search button
|
||||
print '<td class="liste_titre" align="right">';
|
||||
print '<input class="liste_titre" name="button_search" type="image" src="' . DOL_URL_ROOT . '/theme/' . $conf->theme . '/img/search.png" value="' . dol_escape_htmltag($langs->trans("Search")) . '" title="' . dol_escape_htmltag($langs->trans("Search")) . '">';
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
$var = True;
|
||||
|
||||
foreach ( $prodcustprice->lines as $line ) {
|
||||
|
||||
print "<tr $bc[$var]>";
|
||||
|
||||
$staticprod = new Product($db);
|
||||
$staticprod->fetch($line->fk_product);
|
||||
|
||||
print "<td>" . $staticprod->getNomUrl(1) . "</td>";
|
||||
print "<td>" . dol_print_date($line->datec, "dayhour") . "</td>";
|
||||
|
||||
print '<td align="center">' . $langs->trans($line->price_base_type) . "</td>";
|
||||
print '<td align="right">' . vatrate($line->tva_tx, true, $line->recuperableonly) . "</td>";
|
||||
print '<td align="right">' . price($line->price) . "</td>";
|
||||
print '<td align="right">' . price($line->price_ttc) . "</td>";
|
||||
print '<td align="right">' . price($line->price_min) . '</td>';
|
||||
print '<td align="right">' . price($line->price_min_ttc) . '</td>';
|
||||
|
||||
// User
|
||||
$userstatic = new User($db);
|
||||
$userstatic->fetch($line->fk_user);
|
||||
print '<td align="right">';
|
||||
print $userstatic->getLoginUrl(1);
|
||||
print '</td>';
|
||||
|
||||
// Todo Edit or delete button
|
||||
// Action
|
||||
if ($user->rights->produit->creer || $user->rights->service->creer) {
|
||||
print '<td align="right">';
|
||||
print '<a href="' . $_SERVER ["PHP_SELF"] . '?action=delete_customer_price&socid=' . $soc->id . '&lineid=' . $line->id . '">';
|
||||
print img_delete();
|
||||
print '</a>';
|
||||
print '<a href="' . $_SERVER ["PHP_SELF"] . '?action=edit_customer_price&socid=' . $soc->id . '&lineid=' . $line->id . '">';
|
||||
print img_edit();
|
||||
print '</a>';
|
||||
print '<a href="' . $_SERVER ["PHP_SELF"] . '?action=showlog_customer_price&socid=' . $soc->id . '&prodid=' . $line->fk_product . '">';
|
||||
print img_info();
|
||||
print '</a>';
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
print "</tr>\n";
|
||||
}
|
||||
print "</table>";
|
||||
|
||||
print "</form>";
|
||||
} else {
|
||||
print $langs->trans('None');
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* Barre d'action */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
print "\n" . '<div class="tabsAction">' . "\n";
|
||||
|
||||
if ($user->rights->produit->creer || $user->rights->service->creer) {
|
||||
print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER ["PHP_SELF"] . '?action=add_customer_price&socid=' . $soc->id . '">' . $langs->trans("AddCustomerPrice") . '</a></div>';
|
||||
}
|
||||
print "\n</div><br>\n";
|
||||
}
|
||||
}
|
||||
|
||||
llxFooter();
|
||||
|
||||
$db->close();
|
||||
?>
|
||||
Loading…
Reference in New Issue
Block a user