* Copyright (C) 2004-2014 Laurent Destailleur * Copyright (C) 2005 Eric Seigne * Copyright (C) 2005-2017 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2014 Florian Henry * Copyright (C) 2014-2018 Juanjo Menent * Copyright (C) 2014-2018 Philippe Grand * Copyright (C) 2014 Ion agorria * Copyright (C) 2015 Alexandre Spangaro * Copyright (C) 2015 Marcos García * Copyright (C) 2016 Ferran Marcet * Copyright (C) 2018 Frédéric France * Copyright (C) 2018 Nicolas ZABOURI * * 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 . */ /** * \file htdocs/product/price.php * \ingroup product * \brief Page to show product prices */ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php'; require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT . '/product/dynamic_price/class/price_expression.class.php'; require_once DOL_DOCUMENT_ROOT . '/product/dynamic_price/class/price_parser.class.php'; if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; $prodcustprice = new Productcustomerprice($db); } // Load translation files required by the page $langs->loadLangs(array('products', 'bills', 'companies', 'other')); $mesg=''; $error=0; $errors=array(); $id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'alpha'); $cancel = GETPOST('cancel', 'alpha'); $eid = GETPOST('eid', 'int'); $search_soc = GETPOST('search_soc'); // Security check $fieldvalue = (! empty($id) ? $id : (! empty($ref) ? $ref : '')); $fieldtype = (! empty($ref) ? 'ref' : 'rowid'); if ($user->societe_id) $socid = $user->societe_id; $result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); if ($id > 0 || ! empty($ref)) { $object = new Product($db); $object->fetch($id, $ref); } // Clean param if ((! empty($conf->global->PRODUIT_MULTIPRICES) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) && empty($conf->global->PRODUIT_MULTIPRICES_LIMIT)) $conf->global->PRODUIT_MULTIPRICES_LIMIT = 5; // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('productpricecard','globalcard')); /* * Actions */ if ($cancel) $action=''; $parameters=array('id'=>$id, 'ref'=>$ref); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); if (empty($reshook)) { if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers { $search_soc = ''; } if ($action == 'setlabelsellingprice' && $user->admin) { require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php'; $keyforlabel = 'PRODUIT_MULTIPRICES_LABEL'.GETPOST('pricelevel'); dolibarr_set_const($db, $keyforlabel, GETPOST('labelsellingprice','alpha'), 'chaine', 0, '', $conf->entity); $action = ''; } if (($action == 'update_vat') && !$cancel && ($user->rights->produit->creer || $user->rights->service->creer)) { $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' // We must define tva_tx, npr and local taxes $tva_tx = $tva_tx_txt; $vatratecode = ''; if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { $vat_src_code = $reg[1]; $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. } $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { // We look into database using code (we can't use get_localtax() because it depends on buyer that is not known). Same in create product. $vatratecode=$reg[1]; // Get record from code $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; $sql.= " AND t.taux = ".((float) $tva_tx)." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); $npr = $obj->recuperableonly; $localtax1 = $obj->localtax1; $localtax2 = $obj->localtax2; $localtax1_type = $obj->localtax1_type; $localtax2_type = $obj->localtax2_type; } } $object->default_vat_code = $vatratecode; $object->tva_tx = $tva_tx; $object->tva_npr = $npr; $object->localtax1_tx = $localtax1; $object->localtax2_tx = $localtax2; $object->localtax1_type = $localtax1_type; $object->localtax2_type = $localtax2_type; $db->begin(); $resql = $object->update($object->id, $user); if (! $resql || $resql < 0) { $error++; setEventMessages($object->error, $object->errors, 'errors'); } if ($error) { //$localtaxarray=array('0'=>$localtax1_type,'1'=>$localtax1,'2'=>$localtax2_type,'3'=>$localtax2); $localtaxarray=array(); // We do not store localtaxes into product, we will use instead the "vat code" to retreive them. $object->updatePrice(0, $object->price_base_type, $user, $tva_tx, '', 0, $npr, 0, 0, $localtaxarray, $vatratecode); } if (! $error) { $db->commit(); } else { $db->rollback(); } $action=''; } if (($action == 'update_price') && !$cancel && $object->getRights()->creer) { $error = 0; $pricestoupdate = array(); $psq = GETPOST('psqflag'); $psq = empty($newpsq) ? 0 : $newpsq; $maxpricesupplier = $object->min_recommended_price(); if (!empty($conf->dynamicprices->enabled)) { $object->fk_price_expression = empty($eid) ? 0 : $eid; //0 discards expression if ($object->fk_price_expression != 0) { //Check the expression validity by parsing it $priceparser = new PriceParser($db); if ($priceparser->parseProduct($object) < 0) { $error ++; setEventMessages($priceparser->translatedError(), null, 'errors'); } } } // Multiprices if (! $error && (! empty($conf->global->PRODUIT_MULTIPRICES) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))) { $newprice = GETPOST('price', 'array'); $newprice_min = GETPOST('price_min', 'array'); $newpricebase = GETPOST('multiprices_base_type', 'array'); $newvattx = GETPOST('tva_tx', 'array'); $newvatnpr = GETPOST('tva_npr', 'array'); $newlocaltax1_tx = GETPOST('localtax1_tx', 'array'); $newlocaltax1_type = GETPOST('localtax1_type', 'array'); $newlocaltax2_tx = GETPOST('localtax2_tx', 'array'); $newlocaltax2_type = GETPOST('localtax2_type', 'array'); //Shall we generate prices using price rules? $object->price_autogen = GETPOST('usePriceRules') == 'on'; for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i ++) { if (!isset($newprice[$i])) { continue; } $tva_tx_txt = $newvattx[$i]; $tva_tx = $tva_tx_txt; $vatratecode = ''; if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { $vat_src_code = $reg[1]; $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. } $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = $newlocaltax1_tx[$i]; $localtax1_type = $newlocaltax1_type[$i]; $localtax2 = $newlocaltax2_tx[$i]; $localtax2_type = $newlocaltax2_type[$i]; if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { // We look into database using code $vatratecode=$reg[1]; // Get record from code $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; $sql.= " AND t.taux = ".((float) $tva_tx)." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); $npr = $obj->recuperableonly; $localtax1 = $obj->localtax1; $localtax2 = $obj->localtax2; $localtax1_type = $obj->localtax1_type; $localtax2_type = $obj->localtax2_type; } } $pricestoupdate[$i] = array( 'price' => $newprice[$i], 'price_min' => $newprice_min[$i], 'price_base_type' => $newpricebase[$i], 'default_vat_code' => $vatratecode, 'vat_tx' => $tva_tx, // default_vat_code should be used in priority in a future 'npr' => $npr, // default_vat_code should be used in priority in a future 'localtaxes_array' => array('0'=>$localtax1_type, '1'=>$localtax1, '2'=>$localtax2_type, '3'=>$localtax2) // default_vat_code should be used in priority in a future ); //If autogeneration is enabled, then we only set the first level if ($object->price_autogen) { break; } } } elseif (! $error) { $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' $tva_tx = $tva_tx_txt; $vatratecode = ''; if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { $vat_src_code = $reg[1]; $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. } $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { // We look into database using code $vatratecode=$reg[1]; // Get record from code $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; $sql.= " AND t.taux = ".$tva_tx." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); $npr = $obj->recuperableonly; $localtax1 = $obj->localtax1; $localtax2 = $obj->localtax2; $localtax1_type = $obj->localtax1_type; $localtax2_type = $obj->localtax2_type; // If spain, we don't use the localtax found into tax record in database with same code, but using the get_localtax rule if (in_array($mysoc->country_code, array('ES'))) { $localtax1 = get_localtax($tva_tx,1); $localtax2 = get_localtax($tva_tx,2); } } } $pricestoupdate[0] = array( 'price' => $_POST["price"], 'price_min' => $_POST["price_min"], 'price_base_type' => $_POST["price_base_type"], 'default_vat_code' => $vatratecode, 'vat_tx' => $tva_tx, // default_vat_code should be used in priority in a future 'npr' => $npr, // default_vat_code should be used in priority in a future 'localtaxes_array' => array('0'=>$localtax1_type, '1'=>$localtax1, '2'=>$localtax2_type, '3'=>$localtax2) // default_vat_code should be used in priority in a future ); } if (!$error) { $db->begin(); foreach ($pricestoupdate as $key => $val) { $newprice = $val['price']; if ($val['price'] < $val['price_min'] && !empty($object->fk_price_expression)) { $newprice = $val['price_min']; //Set price same as min, the user will not see the } $newprice = price2num($newprice, 'MU'); $newprice_min = price2num($val['price_min'], 'MU'); if (!empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE) && $newprice_min < $maxpricesupplier) { setEventMessages($langs->trans("MinimumPriceLimit", price($maxpricesupplier, 0, '', 1, - 1, - 1, 'auto')), null, 'errors'); $error ++; break; } if($object->multiprices[$key]!=$newprice || $object->multiprices_min[$key]!=$newprice_min || $object->multiprices_base_type[$key]!=$val['price_base_type']) $res = $object->updatePrice($newprice, $val['price_base_type'], $user, $val['vat_tx'], $newprice_min, $key, $val['npr'], $psq, 0, $val['localtaxes_array'], $val['default_vat_code']); else $res=0; if ($res < 0) { $error ++; setEventMessages($object->error, $object->errors, 'errors'); break; } } } if (!$error && $object->update($object->id, $user) < 0) { $error++; setEventMessages($object->error, $object->errors, 'errors'); } if (empty($error)) { $action = ''; setEventMessages($langs->trans("RecordSaved"), null, 'mesgs'); $db->commit(); } else { $action = 'edit_price'; $db->rollback(); } } if ($action == 'delete' && $user->rights->produit->supprimer) { $result = $object->log_price_delete($user, GETPOST('lineid','int')); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); } } // Set Price by quantity if ($action == 'activate_price_by_qty') { // Activating product price by quantity add a new price line with price_by_qty set to 1 $level = GETPOST('level','int'); $object->updatePrice(0, $object->price_base_type, $user, $object->tva_tx, 0, $level, $object->tva_npr, 1); } // Unset Price by quantity if ($action == 'disable_price_by_qty') { // Disabling product price by quantity add a new price line with price_by_qty set to 0 $level = GETPOST('level','int'); $object->updatePrice(0, $object->price_base_type, $user, $object->tva_tx, 0, $level, $object->tva_npr, 0); } if ($action == 'edit_price_by_qty') { // Edition d'un prix par quantité $rowid = GETPOST('rowid','int'); } // Add or update price by quantity if ($action == 'update_price_by_qty') { // Récupération des variables $rowid = GETPOST('rowid','int'); $priceid = GETPOST('priceid','int'); $newprice = price2num(GETPOST("price",'alpha'), 'MU'); // $newminprice=price2num(GETPOST("price_min"),'MU'); // TODO : Add min price management $quantity = GETPOST('quantity','int'); $remise_percent = price2num(GETPOST('remise_percent','alpha')); $remise = 0; // TODO : allow discount by amount when available on documents if (empty($quantity)) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Qty")), null, 'errors'); } if (empty($newprice)) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Price")), null, 'errors'); } if (! $error) { // Calcul du prix HT et du prix unitaire if ($object->price_base_type == 'TTC') { $price = price2num($newprice) / (1 + ($object->tva_tx / 100)); } $price = price2num($newprice, 'MU'); $unitPrice = price2num($price / $quantity, 'MU'); // Ajout / mise à jour if ($rowid > 0) { $sql = "UPDATE " . MAIN_DB_PREFIX . "product_price_by_qty SET"; $sql .= " price='" . $price . "',"; $sql .= " unitprice=" . $unitPrice . ","; $sql .= " quantity=" . $quantity . ","; $sql .= " remise_percent=" . $remise_percent . ","; $sql .= " remise=" . $remise; $sql .= " WHERE rowid = " . $rowid; $result = $db->query($sql); if (! $result) dol_print_error($db); } else { $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_price_by_qty (fk_product_price,price,unitprice,quantity,remise_percent,remise) values ("; $sql .= $priceid . ',' . $price . ',' . $unitPrice . ',' . $quantity . ',' . $remise_percent . ',' . $remise . ')'; $result = $db->query($sql); if (! $result) dol_print_error($db); } } } if ($action == 'delete_price_by_qty') { $rowid = GETPOST('rowid','int'); if (!empty($rowid)) { $sql = "DELETE FROM " . MAIN_DB_PREFIX . "product_price_by_qty"; $sql .= " WHERE rowid = " . $rowid; $result = $db->query($sql); } else { setEventMessages(('delete_price_by_qty'.$langs->transnoentities(MissingIds)), null,'errors'); } } if ($action == 'delete_all_price_by_qty') { $priceid = GETPOST('priceid','int'); if (!empty($rowid)) { $sql = "DELETE FROM " . MAIN_DB_PREFIX . "product_price_by_qty"; $sql .= " WHERE fk_product_price = " . $priceid; $result = $db->query($sql); } else { setEventMessages(('delete_price_by_qty'.$langs->transnoentities(MissingIds)), null,'errors'); } } /** * *************************************************** * Price by customer * **************************************************** */ if ($action == 'add_customer_price_confirm' && !$cancel && ($user->rights->produit->creer || $user->rights->service->creer)) { $maxpricesupplier = $object->min_recommended_price(); $update_child_soc = GETPOST('updatechildprice','int'); // add price by customer $prodcustprice->fk_soc = GETPOST('socid', 'int'); $prodcustprice->fk_product = $object->id; $prodcustprice->price = price2num(GETPOST("price"), 'MU'); $prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU'); $prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha'); $tva_tx_txt = GETPOST("tva_tx",'alpha'); $tva_tx = $tva_tx_txt; $vatratecode = ''; if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { $vat_src_code = $reg[1]; $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. } $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { // We look into database using code $vatratecode=$reg[1]; // Get record from code $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; $sql.= " AND t.taux = ".$tva_tx." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); $npr = $obj->recuperableonly; $localtax1 = $obj->localtax1; $localtax2 = $obj->localtax2; $localtax1_type = $obj->localtax1_type; $localtax2_type = $obj->localtax2_type; } } $prodcustprice->default_vat_code = $vatratecode; $prodcustprice->tva_tx = $tva_tx; $prodcustprice->recuperableonly = $npr; $prodcustprice->localtax1_tx = $localtax1; $prodcustprice->localtax2_tx = $localtax2; $prodcustprice->localtax1_type = $localtax1_type; $prodcustprice->localtax2_type = $localtax2_type; if (! ($prodcustprice->fk_soc > 0)) { $langs->load("errors"); setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("ThirdParty")), null, 'errors'); $error++; $action='add_customer_price'; } if (! empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE) && $prodcustprice->price_min < $maxpricesupplier) { $langs->load("errors"); setEventMessages($langs->trans("MinimumPriceLimit",price($maxpricesupplier,0,'',1,-1,-1,'auto')), null, 'errors'); $error++; $action='add_customer_price'; } if (! $error) { $result = $prodcustprice->create($user, 0, $update_child_soc); if ($result < 0) { setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors'); } else { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); } $action = ''; } } if ($action == 'delete_customer_price' && ($user->rights->produit->supprimer || $user->rights->service->supprimer)) { // Delete price by customer $prodcustprice->id = GETPOST('lineid'); $result = $prodcustprice->delete($user); if ($result < 0) { setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors'); } else { setEventMessages($langs->trans('RecordDeleted'), null, 'mesgs'); } $action = ''; } if ($action == 'update_customer_price_confirm' && !$cancel && ($user->rights->produit->creer || $user->rights->service->creer)) { $maxpricesupplier = $object->min_recommended_price(); $update_child_soc = GETPOST('updatechildprice','int'); $prodcustprice->fetch(GETPOST('lineid', 'int')); // 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'); $tva_tx_txt = GETPOST("tva_tx"); $tva_tx = $tva_tx_txt; $vatratecode = ''; if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { $vat_src_code = $reg[1]; $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. } $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { // We look into database using code $vatratecode=$reg[1]; // Get record from code $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; $sql.= " AND t.taux = ".$tva_tx." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); $npr = $obj->recuperableonly; $localtax1 = $obj->localtax1; $localtax2 = $obj->localtax2; $localtax1_type = $obj->localtax1_type; $localtax2_type = $obj->localtax2_type; } } $prodcustprice->default_vat_code = $vatratecode; $prodcustprice->tva_tx = $tva_tx; $prodcustprice->recuperableonly = $npr; $prodcustprice->localtax1_tx = $localtax1; $prodcustprice->localtax2_tx = $localtax2; $prodcustprice->localtax1_type = $localtax1_type; $prodcustprice->localtax2_type = $localtax2_type; if ($prodcustprice->price_min < $maxpricesupplier && !empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE)) { setEventMessages($langs->trans("MinimumPriceLimit",price($maxpricesupplier,0,'',1,-1,-1,'auto')), null, 'errors'); $error++; $action='update_customer_price'; } if ( ! $error) { $result = $prodcustprice->update($user, 0, $update_child_soc); if ($result < 0) { setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors'); } else { setEventMessages($langs->trans('Save'), null, 'mesgs'); } $action = ''; } } } /* * View */ $form = new Form($db); if (! empty($id) || ! empty($ref)) { // fetch updated prices $object->fetch($id, $ref); } $title = $langs->trans('ProductServiceCard'); $helpurl = ''; $shortlabel = dol_trunc($object->label,16); if (GETPOST("type") == '0' || ($object->type == Product::TYPE_PRODUCT)) { $title = $langs->trans('Product')." ". $shortlabel ." - ".$langs->trans('SellingPrices'); $helpurl='EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos'; } if (GETPOST("type") == '1' || ($object->type == Product::TYPE_SERVICE)) { $title = $langs->trans('Service')." ". $shortlabel ." - ".$langs->trans('SellingPrices'); $helpurl='EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios'; } llxHeader('', $title, $helpurl); $head = product_prepare_head($object); $titre = $langs->trans("CardProduct" . $object->type); $picto = ($object->type == Product::TYPE_SERVICE ? 'service' : 'product'); dol_fiche_head($head, 'price', $titre, -1, $picto); $linkback = ''.$langs->trans("BackToList").''; $object->next_prev_filter=" fk_product_type = ".$object->type; $shownav = 1; if ($user->societe_id && ! in_array('product', explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL))) $shownav=0; dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref'); print '
'; print '
'; print ''; // Price per customer segment/level if (! empty($conf->global->PRODUIT_MULTIPRICES) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { // Price and min price are variable (depends on level of company). if (! empty($socid)) { $soc = new Societe($db); $soc->id = $socid; $soc->fetch($socid); // Selling price print ''; print ''; // Price min print ''; if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) // using this option is a bug. kept for backward compatibility { // TVA print ''; } else { // TVA print ''; } } else { if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) // using this option is a bug. kept for backward compatibility { // We show only vat for level 1 print ''; print ''; print ''; } else { // TVA print ''; } print '
'; print $langs->trans("SellingPrice"); print ''; if ($object->multiprices_base_type[$soc->price_level] == 'TTC') { print price($object->multiprices_ttc[$soc->price_level]); } else { print price($object->multiprices[$soc->price_level]); } if ($object->multiprices_base_type[$soc->price_level]) { print ' ' . $langs->trans($object->multiprices_base_type[$soc->price_level]); } else { print ' ' . $langs->trans($object->price_base_type); } print '
' . $langs->trans("MinPrice") . ''; if ($object->multiprices_base_type[$soc->price_level] == 'TTC') { print price($object->multiprices_min_ttc[$soc->price_level]) . ' ' . $langs->trans($object->multiprices_base_type[$soc->price_level]); } else { print price($object->multiprices_min[$soc->price_level]) . ' ' . $langs->trans(empty($object->multiprices_base_type[$soc->price_level])?'HT':$object->multiprices_base_type[$soc->price_level]); } print '
' . $langs->trans("DefaultTaxRate") . ''; $positiverates=''; if (price2num($object->multiprices_tva_tx[$soc->price_level])) $positiverates.=($positiverates?'/':'').price2num($object->multiprices_tva_tx[$soc->price_level]); if (price2num($object->multiprices_localtax1_type[$soc->price_level])) $positiverates.=($positiverates?'/':'').price2num($object->multiprices_localtax1_tx[$soc->price_level]); if (price2num($object->multiprices_localtax2_type[$soc->price_level])) $positiverates.=($positiverates?'/':'').price2num($object->multiprices_localtax2_tx[$soc->price_level]); if (empty($positiverates)) $positiverates='0'; echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); //print vatrate($object->multiprices_tva_tx[$soc->price_level], true); print '
' . $langs->trans("DefaultTaxRate") . ''; $positiverates=''; if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); if (empty($positiverates)) $positiverates='0'; echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); /* if ($object->default_vat_code) { print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')'; } else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true);*/ print '
' . $langs->trans("DefaultTaxRate") . '' . vatrate($object->multiprices_tva_tx[1], true) . '
' . $langs->trans("DefaultTaxRate") . ''; $positiverates=''; if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); if (empty($positiverates)) $positiverates='0'; echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); /* if ($object->default_vat_code) { print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')'; } else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true);*/ print '
'; print '
'; print ''; print ''; print ''; print ''; print ''; for($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { print ''; // Label of price print ''; if ($object->multiprices_base_type [$i] == 'TTC') { print ''; } else { print ' '.$langs->trans($object->price_base_type).''; } // Prix min print ''; // Price by quantity if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) // TODO Fix the form included into a tr instead of a td { print ''; } } } } else { // TVA print ''; // Price print ''; // Price minimum print ''; // Price by quantity if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) // TODO Fix the form inside tr instead of td { print ''; } } print "
'; print $langs->trans("PriceLevel"); if ($user->admin) print ' id.'">'.img_edit($langs->trans('EditSellingPriceLabel'),0).''; print ''.$langs->trans("SellingPrice").''.$langs->trans("MinPrice").'
'; $keyforlabel='PRODUIT_MULTIPRICES_LABEL'.$i; if (preg_match('/editlabelsellingprice/', $action)) { print '
'; print ''; print ''; print ''; print $langs->trans("SellingPrice") . ' ' . $i.' - '; print ''; print ' '; print '
'; } else { print $langs->trans("SellingPrice") . ' ' . $i; if (! empty($conf->global->$keyforlabel)) print ' - '.$langs->trans($conf->global->$keyforlabel); } print '
' . price($object->multiprices_ttc[$i]); } else { print '' . price($object->multiprices[$i]); } if ($object->multiprices_base_type[$i]) { print ' '.$langs->trans($object->multiprices_base_type [$i]).''; if (empty($object->multiprices_base_type[$i])) $object->multiprices_base_type[$i]="HT"; if ($object->multiprices_base_type[$i] == 'TTC') { print price($object->multiprices_min_ttc[$i]) . ' ' . $langs->trans($object->multiprices_base_type[$i]); } else { print price($object->multiprices_min[$i]) . ' ' . $langs->trans($object->multiprices_base_type[$i]); } print '
' . $langs->trans("PriceByQuantity") . ' ' . $i; if (! empty($conf->global->$keyforlabel)) print ' - '.$langs->trans($conf->global->$keyforlabel); print ''; if ($object->prices_by_qty[$i] == 1) { print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; foreach ($object->prices_by_qty_list[$i] as $ii => $prices) { if ($action == 'edit_price_by_qty' && $rowid == $prices['rowid'] && ($user->rights->produit->creer || $user->rights->service->creer)) { print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; } else { print ''; print ''; print ''; print ''; print ''; print ''; print ''; } } if ($action != 'edit_price_by_qty' && ($user->rights->produit->creer || $user->rights->service->creer)) { print ''; print ''; print ''; // id in product_price print ''; // id in product_price print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; } print '
' . $langs->trans("PriceByQuantityRange") . ' ' . $i . '' . $langs->trans("HT") . '' . $langs->trans("UnitPrice") . '' . $langs->trans("Discount") . ' 
 ' . $object->price_base_type . ' %
' . $prices['quantity'] . '' . price($prices['price']) . '' . price($prices['unitprice']) . '' . price($prices['remise_percent']) . ' %'; if (($user->rights->produit->creer || $user->rights->service->creer)) { print ''; print img_edit() . ''; print ''; print img_delete() . ''; } else { print ' '; } print '
 ' . $object->price_base_type . '  %
'; print '(' . $langs->trans("DisablePriceByQty").')'; } else { print $langs->trans("No"); print '  (' . $langs->trans("Activate") . ')'; } print '
' . $langs->trans("DefaultTaxRate") . ''; $positiverates=''; if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); if (empty($positiverates)) $positiverates='0'; echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); /* if ($object->default_vat_code) { print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')'; } else print vatrate($object->tva_tx, true, $object->tva_npr, true);*/ print '
' . $langs->trans("SellingPrice") . ''; if ($object->price_base_type == 'TTC') { print price($object->price_ttc) . ' ' . $langs->trans($object->price_base_type); } else { print price($object->price) . ' ' . $langs->trans($object->price_base_type); } print '
' . $langs->trans("MinPrice") . ''; if ($object->price_base_type == 'TTC') { print price($object->price_min_ttc) . ' ' . $langs->trans($object->price_base_type); } else { print price($object->price_min) . ' ' . $langs->trans($object->price_base_type); } print '
' . $langs->trans("PriceByQuantity"); if ($object->prices_by_qty[0] == 0) { print '  (' . $langs->trans("Activate").')'; } else { print '  (' . $langs->trans("DisablePriceByQty").')'; } print ''; if ($object->prices_by_qty[0] == 1) { print ''; print ''; //print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; if ($action != 'edit_price_by_qty') { print ''; // FIXME a form into a table is not allowed print ''; print ''; // id in product_price print ''; // id in product_price_by_qty print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; } foreach ($object->prices_by_qty_list[0] as $ii => $prices) { if ($action == 'edit_price_by_qty' && $rowid == $prices['rowid'] && ($user->rights->produit->creer || $user->rights->service->creer)) { print ''; print ''; print ''; // id in product_price print ''; // id in product_price_by_qty print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; } else { print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; } } print '
' . $langs->trans("PriceByQuantityRange") . '' . $langs->trans("Quantity") . '' . $langs->trans("Price") . '' . $langs->trans("UnitPrice") . '' . $langs->trans("Discount") . ' 
'; //print $object->price_base_type; print '  %
'; //print $object->price_base_type; print $prices['price_base_type']; print '  %
' . $prices['quantity'] . '' . price($prices['price']) . ''; //print $object->price_base_type; print $prices['price_base_type']; print '' . price($prices['unitprice']) . '' . price($prices['remise_percent']) . ' %'; if (($user->rights->produit->creer || $user->rights->service->creer)) { print ''; print img_edit() . ''; print ''; print img_delete() . ''; } else { print ' '; } print '
'; } else { print $langs->trans("No"); } print '
\n"; print '
'; print '
'; dol_fiche_end(); /* ************************************************************************** */ /* */ /* Barre d'action */ /* */ /* ************************************************************************** */ if (! $action || $action == 'delete' || $action == 'showlog_customer_price' || $action == 'showlog_default_price' || $action == 'add_customer_price' || $action == 'activate_price_by_qty' || $action == 'disable_price_by_qty') { print "\n" . '
' . "\n"; if ($object->isVariant()) { if ($user->rights->produit->creer || $user->rights->service->creer) { print ''; } } else { if (empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { if ($user->rights->produit->creer || $user->rights->service->creer) { print ''; } } if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { if ($user->rights->produit->creer || $user->rights->service->creer) { print ''; } } if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { if ($user->rights->produit->creer || $user->rights->service->creer) { print ''; } if ($user->rights->produit->creer || $user->rights->service->creer) { print ''; } } } print "\n
\n"; } /* * Edit price area */ if ($action == 'edit_vat' && ($user->rights->produit->creer || $user->rights->service->creer)) { print load_fiche_titre($langs->trans("UpdateVAT"), ''); print '
'; print ''; print ''; print ''; dol_fiche_head(''); print ''; // VAT print ''; print '
' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); print '
'; dol_fiche_end(); print '
'; print ''; print '     '; print ''; print '
'; print '

'; } if ($action == 'edit_price' && $object->getRights()->creer) { print load_fiche_titre($langs->trans("NewPrice"), ''); if (empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { print ''."\n"; print '
'; print ''; print ''; print ''; dol_fiche_head(''); print ''; // VAT print ''; // Price base print ''; print ''; print ''; // Only show price mode and expression selector if module is enabled if (! empty($conf->dynamicprices->enabled)) { // Price mode selector print ''; // This code hides the numeric price input if is not selected, loads the editor page if editor button is pressed ?> fetch($id, $ref, '', 1); //Ignore the math expression when getting the price print ''; // Price minimum print ''; } print ''; print ''; $parameters=array('colspan' => 2); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook $parameters=array('colspan' => 2); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook print '
' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); print '
'; print $langs->trans('PriceBase'); print ''; print $form->selectPriceBaseType($object->price_base_type, "price_base_type"); print '
'.$langs->trans("PriceMode").''; $price_expression = new PriceExpression($db); $price_expression_list = array(0 => $langs->trans("PriceNumeric")); //Put the numeric mode as first option foreach ($price_expression->list_price_expression() as $entry) { $price_expression_list[$entry->id] = $entry->title; } $price_expression_preselection = GETPOST('eid') ? GETPOST('eid') : ($object->fk_price_expression ? $object->fk_price_expression : '0'); print $form->selectarray('eid', $price_expression_list, $price_expression_preselection); print ' 
'.$langs->trans("PriceExpressionEditor").'
'; print '
'; $text = $langs->trans('SellingPrice'); print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1); print ''; if ($object->price_base_type == 'TTC') { print ''; } else { print ''; } print '
'; $text = $langs->trans('MinPrice'); print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1); print ''; if ($object->price_base_type == 'TTC') { print ''; } else { print ''; } if (! empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE)) { print '   '.$langs->trans("MinimumRecommendedPrice", price($maxpricesupplier,0,'',1,-1,-1,'auto')).' '.img_warning().'
'; dol_fiche_end(); print '
'; print ''; print '     '; print ''; print '
'; print '
'; } else { print ''."\n"; ?> id . '" method="POST">'; print ''; print ''; print ''; //dol_fiche_head('', '', '', -1); if ((! empty($conf->global->PRODUIT_MULTIPRICES) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) && ! empty($conf->global->PRODUIT_MULTIPRICES_ALLOW_AUTOCALC_PRICELEVEL)) { print $langs->trans('UseMultipriceRules'). ' price_autogen ? 'checked' : '').'>

'; } print ''; print ''; print ''; if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) print ''; else print ''; print ''; print ''; if (!empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE)) { print ''; } print ''; print ''; for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i ++) { print ''; print ''; // VAT if (empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) { print ''; } else { // This option is kept for backward compatibility but has no sense print ''; } // Selling price print ''; // Min price print ''; } print ''; print ''; } print ''; print '
'.$langs->trans("PriceLevel").''.$langs->trans("DefaultTaxRate").''.$langs->trans("SellingPrice").''.$langs->trans("MinPrice").'
'; print $form->textwithpicto($langs->trans('SellingPrice') . ' ' . $i, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1); print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print $form->load_tva("tva_tx[" . $i.']', $object->multiprices_tva_tx[$i], $mysoc, '', $object->id, false, $object->type, false, 1); print ''; if ($object->multiprices_base_type [$i] == 'TTC') { print ''; } else { print ''; } print ' '.$form->selectPriceBaseType($object->multiprices_base_type [$i], "multiprices_base_type[" . $i."]"); print ''; if ($object->multiprices_base_type [$i] == 'TTC') { print ''; } else { print ''; } if ( !empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE)) { print ''.$langs->trans("MinimumRecommendedPrice", price($maxpricesupplier,0,'',1,-1,-1,'auto')).' '.img_warning().'
'; //dol_fiche_end(); print '
'; print ''; print '   '; print '
'; print ''; } } // List of price changes - log historic (ordered by descending date) if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action=='showlog_default_price') && ! in_array($action, array('edit_price','edit_vat'))) { $sql = "SELECT p.rowid, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.default_vat_code, p.recuperableonly, p.localtax1_tx, p.localtax1_type, p.localtax2_tx, p.localtax2_type,"; $sql .= " p.price_level, p.price_min, p.price_min_ttc,p.price_by_qty,"; $sql .= " p.date_price as dp, p.fk_price_expression, u.rowid as user_id, u.login"; $sql .= " FROM " . MAIN_DB_PREFIX . "product_price as p,"; $sql .= " " . MAIN_DB_PREFIX . "user as u"; $sql .= " WHERE fk_product = " . $object->id; $sql .= " AND p.entity IN (" . getEntity('productprice') . ")"; $sql .= " AND p.fk_user_author = u.rowid"; if (! empty($socid) && ! empty($conf->global->PRODUIT_MULTIPRICES)) $sql .= " AND p.price_level = " . $soc->price_level; $sql .= " ORDER BY p.date_price DESC, p.rowid DESC, p.price_level ASC"; // $sql .= $db->plimit(); $result = $db->query($sql); if ($result) { print '
'; $num = $db->num_rows($result); if (! $num) { $db->free($result); // Il doit au moins y avoir la ligne de prix initial. // On l'ajoute donc pour remettre a niveau (pb vieilles versions) //$object->updatePrice($object->price, $object->price_base_type, $user, $newprice_min); if (! empty($conf->global->PRODUIT_MULTIPRICES)) { $object->updatePrice($object->multiprices[1], $object->multiprices_base_type[1], $user, (empty($object->multiprices_tva_tx[1])?0:$object->multiprices_tva_tx[1]), $object->multiprices_min[1], 1); } else { $object->updatePrice($object->price, $object->price_base_type, $user, $object->tva_tx, $object->price_min); } $result = $db->query($sql); $num = $db->num_rows($result); } if ($num > 0) { // Default prices or // Log of previous customer prices $backbutton='' . $langs->trans("Back") . ''; if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print_barre_liste($langs->trans("DefaultPrice"), 0, $_SERVER["PHP_SELF"], '', '', '', $backbutton, 0, $num, 'title_accountancy.png'); else print_barre_liste($langs->trans("PriceByCustomerLog"), 0, $_SERVER["PHP_SELF"], '', '', '', '', 0, $num, 'title_accountancy.png'); //if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print_barre_liste($langs->trans("DefaultPrice"),'','','','','',$backbutton, 0, 0, 'title_accountancy.png'); //else print_barre_liste($langs->trans("PriceByCustomerLog"),'','','','','','', 0, 0, 'title_accountancy.png'); print '
'; print ''; print ''; print ''; if (! empty($conf->global->PRODUIT_MULTIPRICES) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { print ''; } if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { print ''; } print ''; print $conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL; if (empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) print ''; print ''; print ''; if (! empty($conf->dynamicprices->enabled)) { print ''; } print ''; print ''; print ''; if ($user->rights->produit->supprimer) print ''; print ''; $notfirstlineforlevel=array(); $i = 0; while ($i < $num) { $objp = $db->fetch_object($result); print ''; // Date print ""; // Price level if (! empty($conf->global->PRODUIT_MULTIPRICES) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { print '"; } // Price by quantity if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { $type = ($objp->price_by_qty == 1) ? 'PriceByQuantity' : 'Standard'; print '"; } print '"; if (empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { print '"; } // Price if (! empty($objp->fk_price_expression) && ! empty($conf->dynamicprices->enabled)) { $price_expression = new PriceExpression($db); $res = $price_expression->fetch($objp->fk_price_expression); $title = $price_expression->title; print ''; print ''; print '"; } else { print '"; print '"; if (! empty($conf->dynamicprices->enabled)) { //Only if module is enabled print ''; } } print ''; print ''; // User print ''; // Action if ($user->rights->produit->supprimer) { $candelete=0; if (! empty($conf->global->PRODUIT_MULTIPRICES) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { if (empty($notfirstlineforlevel[$objp->price_level])) $notfirstlineforlevel[$objp->price_level]=1; else $candelete=1; } elseif ($i > 0) $candelete=1; print ''; } print "\n"; $i++; } $db->free($result); print "
' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("PriceLevel") . '' . $langs->trans("Type") . '' . $langs->trans("PriceBase") . '' . $langs->trans("DefaultTaxRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . '' . $langs->trans("PriceExpressionSelected") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("HT") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("TTC") . '' . $langs->trans("ChangedBy") . ' 
" . dol_print_date($db->jdate($objp->dp), "dayhour") . "' . $objp->price_level . "' . $langs->trans($type) . "'; if (empty($objp->price_by_qty)) { print $langs->trans($objp->price_base_type); } print "'; if (empty($objp->price_by_qty)) { $positiverates=''; if (price2num($objp->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($objp->tva_tx); if (price2num($objp->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax1_tx); if (price2num($objp->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax2_tx); if (empty($positiverates)) $positiverates='0'; echo vatrate($positiverates.($objp->default_vat_code?' ('.$objp->default_vat_code.')':''), '%', $objp->tva_npr); /* if ($objp->default_vat_code) { print vatrate($objp->tva_tx, true) . ' ('.$objp->default_vat_code.')'; } else print vatrate($objp->tva_tx, true, $objp->recuperableonly);*/ } print "' . $title . "'; if (empty($objp->price_by_qty)) { print ($objp->price_base_type != 'TTC' ? price($objp->price) : ''); } print "'; if (empty($objp->price_by_qty)) { print ($objp->price_base_type == 'TTC' ? price($objp->price_ttc) : ''); } print "'; if (empty($objp->price_by_qty)) { print ($objp->price_base_type != 'TTC' ? price($objp->price_min) : ''); } print ''; if (empty($objp->price_by_qty)) { print ($objp->price_base_type == 'TTC' ? price($objp->price_min_ttc) : ''); } print '' . img_object($langs->trans("ShowUser"), 'user') . ' ' . $objp->login . ''; if ($candelete) { print 'id . '&lineid=' . $objp->rowid . '">'; print img_delete(); print ''; } else print ' '; // Can not delete last price (it's current price) print '
"; print '
'; print "
"; } print '
'; } else { dol_print_error($db); } } // Add area to show/add/edit a price for a dedicated customer if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { $prodcustprice = new Productcustomerprice($db); $sortfield = GETPOST("sortfield", 'alpha'); $sortorder = GETPOST("sortorder", 'alpha'); $page = (GETPOST("page",'int')?GETPOST("page", 'int'):0); if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 $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_product' => $object->id); if (! empty($search_soc)) { $filter['soc.nom'] = $search_soc; } if ($action == 'add_customer_price') { // Form to add a new customer price $maxpricesupplier = $object->min_recommended_price(); print load_fiche_titre($langs->trans('PriceByCustomer')); print '
'; print ''; print ''; print ''; dol_fiche_head(); print ''; print ''; print ''; print ''; print ''; // VAT print ''; // Price base print ''; print ''; print ''; // Price print ''; // Price minimum print ''; } print ''; // Update all child soc print ''; print ''; print ''; print '
' . $langs->trans('ThirdParty') . ''; print $form->select_company('', 'socid', 's.client in (1,2,3)', 'SelectThirdParty', 0, 0, array(), 0, 'minwidth300'); print '
' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); print '
'; print $langs->trans('PriceBase'); print ''; print $form->selectPriceBaseType($object->price_base_type, "price_base_type"); print '
'; $text = $langs->trans('SellingPrice'); print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1); print ''; if ($object->price_base_type == 'TTC') { print ''; } else { print ''; } print '
'; $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 ''; } else { print ''; } if ( !empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE)) { print ''.$langs->trans("MinimumRecommendedPrice", price($maxpricesupplier,0,'',1,-1,-1,'auto')).' '.img_warning().'
'; print $langs->trans('ForceUpdateChildPriceSoc'); print ''; print ''; print '
'; dol_fiche_end(); print '
'; print ''; print '     '; print ''; print '
'; print '
'; } elseif ($action == 'edit_customer_price') { // Edit mode $maxpricesupplier = $object->min_recommended_price(); print load_fiche_titre($langs->trans('PriceByCustomer')); $result = $prodcustprice->fetch(GETPOST('lineid', 'int')); if ($result < 0) { setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors'); } print '
'; print ''; print ''; print ''; dol_fiche_head(); print ''; print ''; print ''; $staticsoc = new Societe($db); $staticsoc->fetch($prodcustprice->fk_soc); print ""; print ''; // VAT print ''; // Price base print ''; print ''; print ''; // Price print ''; // Price minimum print ''; if ( !empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE)) { print ''; } print ''; // Update all child soc print ''; print ''; print ''; print '
' . $langs->trans('ThirdParty') . '" . $staticsoc->getNomUrl(1) . "
' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $prodcustprice->default_vat_code ? $prodcustprice->tva_tx.' ('.$prodcustprice->default_vat_code.')' : $prodcustprice->tva_tx, $mysoc, '', $object->id, $prodcustprice->recuperableonly, $object->type, false, 1); print '
'; print $langs->trans('PriceBase'); print ''; print $form->selectPriceBaseType($prodcustprice->price_base_type, "price_base_type"); print '
'; $text = $langs->trans('SellingPrice'); print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1); print ''; if ($prodcustprice->price_base_type == 'TTC') { print ''; } else { print ''; } print '
'; $text = $langs->trans('MinPrice'); print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1); print ''; if ($prodcustprice->price_base_type == 'TTC') { print ''; } else { print ''; } print ''.$langs->trans("MinimumRecommendedPrice", price($maxpricesupplier,0,'',1,-1,-1,'auto')).' '.img_warning().'
'; print $langs->trans('ForceUpdateChildPriceSoc'); print ''; print ''; print '
'; dol_fiche_end(); print '
'; print ''; print '     '; print ''; print '
'; print '
'; } elseif ($action == 'showlog_customer_price') { // List of all log of prices by customers print ''."\n"; $filter = array('t.fk_product' => $object->id,'t.fk_soc' => GETPOST('socid', 'int')); // Count total nb of records $nbtotalofrecords = ''; 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) { setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors'); } $option = '&socid=' . GETPOST('socid', 'int') . '&id=' . $object->id; $staticsoc = new Societe($db); $staticsoc->fetch(GETPOST('socid', 'int')); $title=$langs->trans('PriceByCustomerLog'); $title.=' - '.$staticsoc->getNomUrl(1); $backbutton='' . $langs->trans("Back") . ''; print_barre_liste($title, $page, $_SERVEUR['PHP_SELF'], $option, $sortfield, $sortorder, $backbutton, count($prodcustprice->lines), $nbtotalofrecords, 'title_accountancy.png'); if (count($prodcustprice->lines) > 0) { print '
'; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { //print ''; print ''; } else { print ''; } print ''; print ''; print ''; print ''; print ''; foreach ($prodcustprice->lines as $line) { // Date $staticsoc = new Societe($db); $staticsoc->fetch($line->fk_soc); $tva_tx = $line->default_vat_code ? $line->tva_tx.' ('.$line->default_vat_code.')' : $line->tva_tx; // Line for default price if ($line->price_base_type=='HT') { $pu=$line->price; } else { $pu=$line->price_ttc; } // Local tax is not saved into table of product. We use value linked to VAT code. $localtaxarray=getLocalTaxesFromRate($line->tva_tx.($line->default_vat_code?' ('.$line->default_vat_code.')':''), 0, $staticsoc, $mysoc); // Define part of HT, VAT, TTC $resultarray=calcul_price_total(1, $pu, 0, $line->tva_tx, 1, 1, 0, $line->price_base_type, $line->recuperableonly, $object->type, $mysoc, $localtaxarray); // Calcul du total ht sans remise $total_ht = $resultarray[0]; $total_vat = $resultarray[1]; $total_localtax1 = $resultarray[9]; $total_localtax2 = $resultarray[10]; $total_ttc = $resultarray[2]; print ''; print ""; print ""; print '"; print '"; print '"; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { //print '"; print ''; } else { print '"; } print ''; print ''; // User $userstatic = new User($db); $userstatic->fetch($line->fk_user); print ''; print ''; } print "
' . $langs->trans("ThirdParty") . '' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("PriceBase") . '' . $langs->trans("DefaultTaxRate") . '' . $langs->trans("HT") . '' . $langs->trans("INCVATONLY") . '' . $langs->trans("INCT") . '' . $langs->trans("TTC") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("HT") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("TTC") . '' . $langs->trans("ChangedBy") . ' 
" . $staticsoc->getNomUrl(1) . "" . dol_print_date($line->datec, "dayhour") . "' . $langs->trans($line->price_base_type) . "'; $positiverates=''; if (price2num($line->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($line->tva_tx); if (price2num($line->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax1_tx); if (price2num($line->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax2_tx); if (empty($positiverates)) $positiverates='0'; echo vatrate($positiverates.($line->default_vat_code?' ('.$line->default_vat_code.')':''), '%', ($line->tva_npr?$line->tva_npr:$line->recuperableonly)); //. vatrate($tva_tx, true, $line->recuperableonly) . print "' . price($line->price) . "' . price($line->price_ttc) . "' . price($resultarray[2]) . '' . price($line->price_ttc) . "' . price($line->price_min) . '' . price($line->price_min_ttc) . ''; print $userstatic->getLoginUrl(1); print '
"; } else { print $langs->trans('None'); } } else if ($action != 'showlog_default_price' && $action != 'edit_price') { // List of all prices by customers print ''."\n"; // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $nbtotalofrecords = $prodcustprice->fetch_all($sortorder, $sortfield, 0, 0, $filter); } $result = $prodcustprice->fetch_all($sortorder, $sortfield, $conf->liste_limit, $offset, $filter); if ($result < 0) { setEventMessages($prodcustprice->error, $prodcustprice->errors, '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, 'title_accountancy.png'); print ''; print ''; print ''; if (count($prodcustprice->lines) > 0 || $search_soc) { $colspan=8; //if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") $colspan++; print ''; print ''; print ''; // Print the search button print ''; print ''; } print ''; print ''; print ''; print ''; print ''; print ''; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { //print ''; print ''; } else { print ''; } print ''; print ''; print ''; print ''; print ''; // Line for default price if ($object->price_base_type=='HT') { $pu=$object->price; } else { $pu=$object->price_ttc; } // Local tax is not saved into table of product. We use value linked to VAT code. $localtaxarray=getLocalTaxesFromRate($object->tva_tx.($object->default_vat_code?' ('.$object->default_vat_code.')':''), 0, $mysoc, $mysoc); // Define part of HT, VAT, TTC $resultarray=calcul_price_total(1, $pu, 0, $object->tva_tx, 1, 1, 0, $object->price_base_type, $object->recuperableonly, $object->type, $mysoc, $localtaxarray); // Calcul du total ht sans remise $total_ht = $resultarray[0]; $total_vat = $resultarray[1]; $total_localtax1 = $resultarray[9]; $total_localtax2 = $resultarray[10]; $total_ttc = $resultarray[2]; print ''; print ""; print ""; print '"; print '"; print '"; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { //print '"; print ''; } else { print '"; } print ''; print ''; print ''; if ($user->rights->produit->supprimer || $user->rights->service->supprimer) { print ''; } print "\n"; if (count($prodcustprice->lines) > 0) { foreach ($prodcustprice->lines as $line) { // Date $staticsoc = new Societe($db); $staticsoc->fetch($line->fk_soc); $tva_tx = $line->default_vat_code ? $line->tva_tx.' ('.$line->default_vat_code.')' : $line->tva_tx; // Line for default price if ($line->price_base_type=='HT') { $pu=$line->price; } else { $pu=$line->price_ttc; } // Local tax is not saved into table of product. We use value linked to VAT code. $localtaxarray=getLocalTaxesFromRate($line->tva_tx.($line->default_vat_code?' ('.$line->default_vat_code.')':''), 0, $staticsoc, $mysoc); // Define part of HT, VAT, TTC $resultarray=calcul_price_total(1, $pu, 0, $line->tva_tx, 1, 1, 0, $line->price_base_type, $line->recuperableonly, $object->type, $mysoc, $localtaxarray); // Calcul du total ht sans remise $total_ht = $resultarray[0]; $total_vat = $resultarray[1]; $total_localtax1 = $resultarray[9]; $total_localtax2 = $resultarray[10]; $total_ttc = $resultarray[2]; print ''; print ""; print ""; print '"; print '"; print '"; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") { //print '"; print ''; } else { print '"; } print ''; print ''; // User $userstatic = new User($db); $userstatic->fetch($line->fk_user); print ''; // Todo Edit or delete button // Action if ($user->rights->produit->supprimer || $user->rights->service->supprimer) { print ''; } print "\n"; } } /*else { $colspan=9; if ($user->rights->produit->supprimer || $user->rights->service->supprimer) $colspan+=1; print ""; print ''; print ""; }*/ print "
 '; $searchpicto=$form->showFilterAndCheckAddButtons(0); print $searchpicto; print '
' . $langs->trans("ThirdParty") . '' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("PriceBase") . '' . $langs->trans("DefaultTaxRate") . '' . $langs->trans("HT") . '' . $langs->trans("INCVATONLY") . '' . $langs->trans("INCT") . '' . $langs->trans("TTC") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("HT") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("TTC") . '' . $langs->trans("ChangedBy") . ' 
" . $langs->trans("Default") . "" . "' . $langs->trans($object->price_base_type) . "'; $positiverates=''; if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); if (empty($positiverates)) $positiverates='0'; echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); //print vatrate($object->tva_tx, true, $object->tva_npr); //print $object->default_vat_code?' ('.$object->default_vat_code.')':''; print "' . price($object->price) . "' . price($object->price_ttc) . "' . price($resultarray[2]) . '' . price($object->price_ttc) . "' . price($object->price_min) . '' . price($object->price_min_ttc) . ''; print ''; print 'id . '">'; print img_info($langs->trans('PriceByCustomerLog')); print ''; print ' '; print 'id . '">'; print img_edit('default', 0, 'style="vertical-align: middle;"'); print ''; print '   '; print '
" . $staticsoc->getNomUrl(1) . "" . dol_print_date($line->datec, "dayhour") . "' . $langs->trans($line->price_base_type) . "'; $positiverates=''; if (price2num($line->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($line->tva_tx); if (price2num($line->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax1_tx); if (price2num($line->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax2_tx); if (empty($positiverates)) $positiverates='0'; echo vatrate($positiverates.($line->default_vat_code?' ('.$line->default_vat_code.')':''), '%', ($line->tva_npr?$line->tva_npr:$line->recuperableonly)); print "' . price($line->price) . "' . price($line->price_ttc) . "' . price($resultarray[2]) . '' . price($line->price_ttc) . "' . price($line->price_min) . '' . price($line->price_min_ttc) . ''; print $userstatic->getLoginUrl(1); print ''; print 'id . '&socid=' . $line->fk_soc . '">'; print img_info($langs->trans('PriceByCustomerLog')); print ''; print ' '; print 'id . '&lineid=' . $line->id . '">'; print img_edit('default', 0, 'style="vertical-align: middle;"'); print ''; print ' '; print 'id . '&lineid=' . $line->id . '">'; print img_delete('default', 'style="vertical-align: middle;"'); print ''; print '
'.$langs->trans('None').'
"; print "
"; } } // End of page llxFooter(); $db->close();