* Copyright (C) 2004-2014 Laurent Destailleur * Copyright (C) 2005 Eric Seigne * Copyright (C) 2005-2015 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2014 Florian Henry * Copyright (C) 2014 Juanjo Menent * Copyright (C) 2014 Philippe Grand * Copyright (C) 2014 Ion agorria * Copyright (C) 2015 Alexandre Spangaro * * 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 . '/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); } $langs->load("products"); $langs->load("bills"); $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'); // 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_MULTIPRICES_LIMIT)) $conf->global->PRODUIT_MULTIPRICES_LIMIT = 5; // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array $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 ($action == 'update_price' && !$cancel && ($user->rights->produit->creer || $user->rights->service->creer)) { $maxpricesupplier = $object->min_recommended_price(); $object->fk_price_expression = empty($eid) ? 0 : $eid; //0 discards expression // MultiPrix if (! empty($conf->global->PRODUIT_MULTIPRICES)) { $newprice = ''; $newprice_min = ''; $newpricebase = ''; $newvat = ''; for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i ++) { if (isset($_POST ["price_" . $i])) { $level = $i; $newprice = price2num($_POST ["price_" . $i], 'MU'); $newprice_min = price2num($_POST ["price_min_" . $i], 'MU'); $newpricebase = $_POST ["multiprices_base_type_" . $i]; $newnpr = (preg_match('/\*/', $_POST ["tva_tx_" . $i]) ? 1 : 0); $newvat = str_replace('*', '', $_POST ["tva_tx_" . $i]); $newpsq = GETPOST('psqflag'); $newpsq = empty($newpsq) ? 0 : $newpsq; break; // We found submited price } } } else { $level = 0; $newprice = price2num($_POST ["price"], 'MU'); $newprice_min = price2num($_POST ["price_min"], 'MU'); $newpricebase = $_POST ["price_base_type"]; $newnpr = (preg_match('/\*/', $_POST ["tva_tx"]) ? 1 : 0); $newvat = str_replace('*', '', $_POST ["tva_tx"]); $newpsq = GETPOST('psqflag'); $newpsq = empty($newpsq) ? 0 : $newpsq; } if (! empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE) && $newprice_min < $maxpricesupplier) { setEventMessage($langs->trans("MinimumPriceLimit",price($maxpricesupplier,0,'',1,-1,-1,'auto')),'errors'); $error++; $action='edit_price'; } if ($newprice < $newprice_min && ! empty($object->fk_price_expression)) { $newprice = $newprice_min; //Set price same as min, the user will not see the } if ($object->updatePrice($newprice, $newpricebase, $user, $newvat, $newprice_min, $level, $newnpr, $newpsq) > 0) { if ($object->fk_price_expression != 0) { //Check the expression validity by parsing it $priceparser = new PriceParser($db); $price_result = $priceparser->parseProduct($object); if ($price_result < 0) { //Expression is not valid $error++; $action='edit_price'; setEventMessage($priceparser->translatedError(), 'errors'); } } if (empty($error) && ! empty($conf->dynamicprices->enabled)) { $ret=$object->setPriceExpression($object->fk_price_expression); if ($ret < 0) { $error++; $action='edit_price'; setEventMessage($object->error, 'errors'); } } if (empty($error)) { $action = ''; setEventMessage($langs->trans("RecordSaved")); } } else { $action = 'edit_price'; setEventMessage($object->error, 'errors'); } } if ($action == 'delete' && $user->rights->produit->supprimer) { $result = $object->log_price_delete($user, $_GET ["lineid"]); if ($result < 0) { setEventMessage($object->error, 'errors'); } } /** * *************************************************** * Price by quantity * *************************************************** */ if ($action == 'activate_price_by_qty') { // Activating product price by quantity add a new price, specified as by quantity $level = GETPOST('level'); $object->updatePrice(0, $object->price_base_type, $user, $object->tva_tx, 0, $level, $object->tva_npr, 1); } if ($action == 'edit_price_by_qty') { // Edition d'un prix par quantité $rowid = GETPOST('rowid'); } if ($action == 'update_price_by_qty') { // Ajout / Mise à jour d'un prix par quantité // Récupération des variables $rowid = GETPOST('rowid'); $priceid = GETPOST('priceid'); $newprice = price2num(GETPOST("price"), 'MU'); // $newminprice=price2num(GETPOST("price_min"),'MU'); // TODO : Add min price management $quantity = GETPOST('quantity'); $remise_percent = price2num(GETPOST('remise_percent')); $remise = 0; // TODO : allow discount by amount when available on documents if (empty($quantity)) { $error ++; setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentities("Qty")), 'errors'); } if (empty($newprice)) { $error ++; setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentities("Price")), '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 = " . GETPOST('rowid'); $result = $db->query($sql); } 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 ($action == 'delete_price_by_qty') { $rowid = GETPOST('rowid'); $sql = "DELETE FROM " . MAIN_DB_PREFIX . "product_price_by_qty"; $sql .= " WHERE rowid = " . GETPOST('rowid'); $result = $db->query($sql); } if ($action == 'delete_all_price_by_qty') { $priceid = GETPOST('priceid'); $sql = "DELETE FROM " . MAIN_DB_PREFIX . "product_price_by_qty"; $sql .= " WHERE fk_product_price = " . $priceid; $result = $db->query($sql); } /** * *************************************************** * 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'); // 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'); $prodcustprice->tva_tx = str_replace('*', '', GETPOST("tva_tx")); $prodcustprice->recuperableonly = (preg_match('/\*/', GETPOST("tva_tx")) ? 1 : 0); if (! empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE) && $prodcustprice->price_min<$maxpricesupplier) { setEventMessage($langs->trans("MinimumPriceLimit",price($maxpricesupplier,0,'',1,-1,-1,'auto')),'errors'); $error++; $action='add_customer_price'; } if (! $error) { $result = $prodcustprice->create($user, 0, $update_child_soc); if ($result < 0) { setEventMessage($prodcustprice->error, 'errors'); } else { setEventMessage($langs->trans('RecordSaved'), '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) { setEventMessage($prodcustprice->error, 'mesgs'); } else { setEventMessage($langs->trans('RecordDeleted'), 'errors'); } $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'); $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'); $prodcustprice->tva_tx = str_replace('*', '', GETPOST("tva_tx")); $prodcustprice->recuperableonly = (preg_match('/\*/', GETPOST("tva_tx")) ? 1 : 0); if ($prodcustprice->price_min<$maxpricesupplier && !empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE)) { setEventMessage($langs->trans("MinimumPriceLimit",price($maxpricesupplier,0,'',1,-1,-1,'auto')),'errors'); $error++; $action='update_customer_price'; } if ( ! $error) { $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); if (! empty($id) || ! empty($ref)) { // fetch updated prices $object->fetch($id, $ref); } llxHeader("", "", $langs->trans("CardProduct" . $object->type)); $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, 0, $picto); print ''; // Ref print ''; print ''; print ''; // Label print ''; $isphoto = $object->is_photo_available($conf->product->multidir_output [$object->entity]); $nblignes = 5; if ($isphoto) { // Photo print ''; } print ''; // MultiPrix if (! empty($conf->global->PRODUIT_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 ''; // TVA print ''; } else { for($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i ++) { // TVA if ($i == 1) // We show only vat for level 1 { print ''; } print ''; // Label of price print ''; if ($object->multiprices_base_type ["$i"] == 'TTC') { print ''; // Prix mini print ''; // Price by quantity if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) { print ''; } } } } else { // TVA print ''; // Price print ''; // Price minimum print ''; // Price by quantity if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) { print ''; } } // Status (to sell) print ''; print "
' . $langs->trans("Ref") . ''; print $form->showrefnav($object, 'ref', '', 1, 'ref'); print '
' . $langs->trans("Label") . '' . $object->label . ''; print $object->show_photos($conf->product->multidir_output [$object->entity], 1, 1, 0, 0, 0, 80); print '
' . $langs->trans("SellingPrice") . ''; 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("VATRate") . '' . vatrate($object->multiprices_tva_tx["$soc->price_level"], true) . '
' . $langs->trans("VATRate") . '' . vatrate($object->multiprices_tva_tx [1], true) . '
' . $langs->trans("SellingPrice") . ' ' . $i; $keyforlabel='PRODUIT_MULTIPRICES_LABEL'.$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"]); } else { print ' ' . $langs->trans($object->price_base_type); } print '
' . $langs->trans("MinPrice") . ' ' . $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; 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 ''; 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 ''; print ''; 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 . '  %
'; } else { print $langs->trans("No"); print ' (' . $langs->trans("Activate") . ')'; } print '
' . $langs->trans("VATRate") . '' . vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true) . '
' . $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"); } print ''; if ($object->prices_by_qty [0] == 1) { 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 ''; print ''; print ''; print ''; print ''; // print ''; print ''; print ''; print ''; print ''; } else { print ''; print ''; print ''; print ''; print ''; print ''; print ''; } } if ($action != 'edit_price_by_qty') { print ''; print ''; print ''; print ''; print ''; print ''; print ''; // print ''; print ''; print ''; print ''; print ''; } print '
' . $langs->trans("PriceByQuantityRange") . '' . $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 . '  %
'; } else { print $langs->trans("No"); } print '
' . $langs->trans("Status") . ' (' . $langs->trans("Sell") . ')'; print $object->getLibStatut(2, 0); print '
\n"; dol_fiche_end(); /* ************************************************************************** */ /* */ /* Barre d'action */ /* */ /* ************************************************************************** */ if (! $action || $action == 'delete' || $action == 'showlog_customer_price' || $action == 'add_customer_price') { print "\n" . '
' . "\n"; if ($user->rights->produit->creer || $user->rights->service->creer) { print ''; } print "\n
\n"; } /* * Edition du prix */ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights->service->creer)) { print_fiche_titre($langs->trans("NewPrice"), ''); if (empty($conf->global->PRODUIT_MULTIPRICES)) { 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 print ''; } // Price $product = new Product($db); $product->fetch($id, $ref, '', 1); //Ignore the math expression when getting the price print ''; // Price minimum print ''; } print ''; print '
' . $langs->trans("VATRate") . ''; print $form->load_tva("tva_tx", $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr); 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); 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 { for($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i ++) { print '
'; print ''; print ''; print ''; dol_fiche_head(''); print ''; // VAT if ($i == 1) { print ''; } else { // We always use the vat rate of price level 1 (A vat rate does not depends on customer) print ''; } // Selling price print ''; // Min price print ''; } print ''; print ''; print '
' . $langs->trans("VATRate") . ''; print $form->load_tva("tva_tx_" . $i, $object->multiprices_tva_tx ["$i"], $mysoc, '', $object->id); print '
'; $text = $langs->trans('SellingPrice') . ' ' . $i; print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 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 '
'; $text = $langs->trans('MinPrice') . ' ' . $i; print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1); 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().'
'; print '   '; print '
'; dol_fiche_end(); print '
'; } } } // List of price changes (ordered by descending date) $sql = "SELECT p.rowid, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.recuperableonly,"; $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', 1) . ")"; $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.price_level ASC, p.rowid DESC"; // $sql .= $db->plimit(); $result = $db->query($sql); if ($result) { $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); $result = $db->query($sql); $num = $db->num_rows($result); } if ($num > 0) { if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print_fiche_titre($langs->trans("DefaultPrice"),'',''); print ''; print ''; print ''; if (! empty($conf->global->PRODUIT_MULTIPRICES)) { print ''; } if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) { print ''; } print ''; print ''; print ''; print ''; if (! empty($conf->dynamicprices->enabled)) { print ''; } print ''; print ''; print ''; if ($user->rights->produit->supprimer) print ''; print ''; $var = True; $i = 0; while ($i < $num) { $objp = $db->fetch_object($result); $var = ! $var; print ""; // Date print ""; // Price level if (! empty($conf->global->PRODUIT_MULTIPRICES)) { print '"; } // Price by quantity if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) { $type = ($objp->price_by_qty == 1) ? 'PriceByQuantity' : 'Standard'; print '"; } print '"; 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) { print ''; } print "\n"; $i ++; } $db->free($result); print "
' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("MultiPriceLevelsName") . '' . $langs->trans("Type") . '' . $langs->trans("PriceBase") . '' . $langs->trans("VAT") . '' . $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) . "' . $langs->trans($objp->price_base_type) . "' . vatrate($objp->tva_tx, true, $objp->recuperableonly) . "' . $title . "' . price($objp->price) . "' . price($objp->price_ttc) . "' . price($objp->price_min) . '' . price($objp->price_min_ttc) . '' . img_object($langs->trans("ShowUser"), 'user') . ' ' . $objp->login . ''; if ($i > 0) { print 'id . '&lineid=' . $objp->rowid . '">'; print img_delete(); print ''; } else print ' '; // Can not delete last price (it's current price) 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'); 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_product' => $object->id); $search_soc = GETPOST('search_soc'); if (! empty($search_soc)) { $filter['soc.nom'] = $search_soc; } if ($action == 'add_customer_price') { // Create mode $maxpricesupplier = $object->min_recommended_price(); print_fiche_titre($langs->trans('PriceByCustomer')); print '
'; print ''; print ''; print ''; 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) AND s.rowid NOT IN (SELECT fk_soc FROM ' . MAIN_DB_PREFIX . 'product_customer_price WHERE fk_product='.$object->id.')', 1, 0, 0, array(), 0, 'minwidth300'); print '
' . $langs->trans("VATRate") . ''; print $form->load_tva("tva_tx", $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr); 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 '
'; print '
'; print ''; print '     '; print ''; print '
'; print '
'; } elseif ($action == 'edit_customer_price') { // Edit mode $maxpricesupplier = $object->min_recommended_price(); print_fiche_titre($langs->trans('PriceByCustomer')); $result = $prodcustprice->fetch(GETPOST('lineid', 'int')); if ($result < 0) { setEventMessage($prodcustprice->error, 'errors'); } print '
'; print ''; print ''; print ''; 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("VATRate") . ''; print $form->load_tva("tva_tx", $prodcustprice->tva_tx, $mysoc, '', $object->id, $prodcustprice->recuperableonly); 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 '
'; print '
'; print ''; print '     '; print ''; print '
'; print '
'; } elseif ($action == 'showlog_customer_price') { $filter = array('t.fk_product' => $object->id,'t.fk_soc' => GETPOST('socid', 'int')); // 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') . '&id=' . $object->id; print_barre_liste($langs->trans('PriceByCustomerLog'), $page, $_SERVEUR['PHP_SELF'], $option, $sortfield, $sortorder, '', count($prodcustprice->lines), $nbtotalofrecords, ''); if (count($prodcustprice->lines) > 0) { print '
'; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; $var = True; foreach ($prodcustprice->lines as $line) { $var = ! $var; print ""; // Date $staticsoc = new Societe($db); $staticsoc->fetch($line->fk_soc); print ""; print ""; print '"; print '"; print '"; print '"; print ''; print ''; // User $userstatic = new User($db); $userstatic->fetch($line->fk_user); print ''; } print "
' . $langs->trans("ThirdParty") . '' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("PriceBase") . '' . $langs->trans("VAT") . '' . $langs->trans("HT") . '' . $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) . "' . vatrate($line->tva_tx, true, $line->recuperableonly) . "' . price($line->price) . "' . price($line->price_ttc) . "' . price($line->price_min) . '' . price($line->price_min_ttc) . ''; print $userstatic->getLoginUrl(1); print '
"; } else { print $langs->trans('None'); } print "\n" . '
' . "\n"; print ''; print "\n

\n"; } else { // View mode // Count total nb of records $nbtotalofrecords = 0; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $nbtotalofrecords = $prodcustprice->fetch_all($sortfield, $sortorder, 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, ''); print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; print ''; // Print the search button print ''; print ''; if (count($prodcustprice->lines) > 0) { $var = False; foreach ($prodcustprice->lines as $line) { print ""; // Date $staticsoc = new Societe($db); $staticsoc->fetch($line->fk_soc); print ""; print ""; print '"; print '"; print '"; 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 "
' . $langs->trans("ThirdParty") . '' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("PriceBase") . '' . $langs->trans("VAT") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("HT") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("TTC") . '' . $langs->trans("ChangedBy") . ' 
 '; print ''; print '
" . $staticsoc->getNomUrl(1) . "" . dol_print_date($line->datec, "dayhour") . "' . $langs->trans($line->price_base_type) . "' . vatrate($line->tva_tx, true, $line->recuperableonly) . "' . price($line->price) . "' . 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(); 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 "
"; /* ************************************************************************** */ /* */ /* Barre d'action */ /* */ /* ************************************************************************** */ print "\n" . '
' . "\n"; if ($user->rights->produit->creer || $user->rights->service->creer) { print ''; } print "\n

\n"; } } llxFooter(); $db->close();