diff --git a/htdocs/product/class/priceexpression.class.php b/htdocs/product/dynamic_price/class/price_expression.class.php similarity index 92% rename from htdocs/product/class/priceexpression.class.php rename to htdocs/product/dynamic_price/class/price_expression.class.php index c5e24d3a228..babf86235c0 100644 --- a/htdocs/product/class/priceexpression.class.php +++ b/htdocs/product/dynamic_price/class/price_expression.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2014 Juanjo Menent -/* Copyright (C) 2014 Ion Agorria +/* Copyright (C) 2015 Ion Agorria * * 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 @@ -18,7 +18,7 @@ */ /** - * \file htdocs/product/class/priceexpression.class.php + * \file htdocs/product/expression/class/price_expression.class.php * \ingroup product * \brief Class for accessing price expression table */ @@ -35,6 +35,7 @@ class PriceExpression var $id; var $title; var $expression; + public $table_element = "c_price_expression"; /** * Constructor @@ -57,14 +58,14 @@ class PriceExpression */ function create($user, $notrigger=0) { - $error=0; + $error=0; // Clean parameters if (isset($this->title)) $this->title=trim($this->title); if (isset($this->expression)) $this->expression=trim($this->expression); // Insert request - $sql = "INSERT INTO ".MAIN_DB_PREFIX."c_price_expression ("; + $sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." ("; $sql.= "title, expression"; $sql.= ") VALUES ("; $sql.= " ".(isset($this->title)?"'".$this->db->escape($this->title)."'":"''").","; @@ -121,7 +122,7 @@ class PriceExpression function fetch($id) { $sql = "SELECT title, expression"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_price_expression"; + $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element; $sql.= " WHERE rowid = ".$id; dol_syslog(get_class($this)."::fetch"); @@ -133,8 +134,8 @@ class PriceExpression { $this->id = $id; $this->title = $obj->title; - $this->expression = $obj->expression; - return 1; + $this->expression = $obj->expression; + return 1; } else { @@ -156,10 +157,10 @@ class PriceExpression function list_price_expression() { $sql = "SELECT rowid, title, expression"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_price_expression"; + $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element; $sql.= " ORDER BY title"; - dol_syslog(get_class($this)."::list_price_expression"); + dol_syslog(get_class($this)."::list_price_expression"); $resql=$this->db->query($sql); if ($resql) { @@ -194,7 +195,7 @@ class PriceExpression function find_title($title) { $sql = "SELECT rowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_price_expression"; + $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element; $sql.= " WHERE title = '".$this->db->escape($title)."'"; dol_syslog(get_class($this)."::find_title"); @@ -235,7 +236,7 @@ class PriceExpression if (isset($this->expression)) $this->expression=trim($this->expression); // Update request - $sql = "UPDATE ".MAIN_DB_PREFIX."c_price_expression SET"; + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; $sql.= " title = ".(isset($this->title)?"'".$this->db->escape($this->title)."'":"''").","; $sql.= " expression = ".(isset($this->expression)?"'".$this->db->escape($this->expression)."'":"''").""; $sql.= " WHERE rowid = ".$this->id; @@ -309,7 +310,7 @@ class PriceExpression if (! $error) { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."c_price_expression"; + $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element; $sql.= " WHERE rowid = ".$rowid; dol_syslog(get_class($this)."::delete"); diff --git a/htdocs/product/class/priceparser.class.php b/htdocs/product/dynamic_price/class/price_parser.class.php similarity index 78% rename from htdocs/product/class/priceparser.class.php rename to htdocs/product/dynamic_price/class/price_parser.class.php index c2b047a7ae1..68367d8ba5f 100644 --- a/htdocs/product/class/priceparser.class.php +++ b/htdocs/product/dynamic_price/class/price_parser.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2015 Ion Agorria * * 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 @@ -16,13 +16,15 @@ */ /** - * \file htdocs/product/class/priceparser.class.php + * \file htdocs/product/expression/class/price_parser.class.php * \ingroup product * \brief File of class to calculate prices using expression */ require_once DOL_DOCUMENT_ROOT.'/includes/evalmath/evalmath.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/class/priceexpression.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_global_variable.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_global_variable_updater.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; /** @@ -30,17 +32,17 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; */ class PriceParser { - protected $db; - // Limit of expressions per price - public $limit = 100; - // The error that ocurred when parsing price - public $error; - // The expression that caused the error - public $error_expr; - //The special char - public $special_chr = "#"; - //The separator char - public $separator_chr = ";"; + protected $db; + // Limit of expressions per price + public $limit = 100; + // The error that occurred when parsing price + public $error; + // The expression that caused the error + public $error_expr; + //The special char + public $special_chr = "#"; + //The separator char + public $separator_chr = ";"; /** * Constructor @@ -104,7 +106,7 @@ class PriceParser { return $langs->trans("ErrorPriceExpression".$code, $info); } - else if (in_array($code, array(6))) //Errors which have 2 args + else if (in_array($code, array(6, 23))) //Errors which have 2 args { return $langs->trans("ErrorPriceExpression".$code, $info[0], $info[1]); } @@ -128,6 +130,7 @@ class PriceParser */ public function parseExpression($product, $expression, $values) { + global $user; //Accessible product values by expressions $values = array_merge($values, array( "tva_tx" => $product->tva_tx, @@ -139,13 +142,31 @@ class PriceParser "price_min" => $product->price_min, )); - //Retreive all extrafield for product and add it to values + //Retrieve all extrafield for product and add it to values $extrafields = new ExtraFields($this->db); $extralabels = $extrafields->fetch_name_optionals_label('product', true); $product->fetch_optionals($product->id, $extralabels); foreach ($extrafields->attribute_label as $key=>$label) { - $values['options_'.$key] = $product->array_options['options_'.$key]; + $values["extrafield_".$key] = $product->array_options['options_'.$key]; + } + + //Process any pending updaters + $price_updaters = new PriceGlobalVariableUpdater($this->db); + foreach ($price_updaters->listPendingUpdaters() as $entry) { + //Schedule the next update by adding current timestamp (secs) + interval (mins) + $entry->update_next_update(dol_now() + ($entry->update_interval * 60), $user); + //Do processing + $res = $entry->process(); + //Store any error or clear status if OK + $entry->update_status($res < 1?$entry->error:'', $user); + } + + //Get all global values + $price_globals = new PriceGlobalVariable($this->db); + foreach ($price_globals->listGlobalVariables() as $entry) + { + $values["global_".$entry->code] = $entry->value; } //Check if empty @@ -153,36 +174,32 @@ class PriceParser if (empty($expression)) { $this->error = array(20, null); - return -1; + return -2; } //Prepare the lib, parameters and values $em = new EvalMath(); $em->suppress_errors = true; //Don't print errors on page $this->error_expr = null; - $search = array(); - $replace = array(); - foreach ($values as $key => $value) { - if ($value !== null) { - $search[] = $this->special_chr.$key.$this->special_chr; - $replace[] = $value; - } - } + $last_result = null; //Iterate over each expression splitted by $separator_chr $expression = str_replace("\n", $this->separator_chr, $expression); + foreach ($values as $key => $value) + { + $expression = str_replace($this->special_chr.$key.$this->special_chr, "$value", $expression); + } $expressions = explode($this->separator_chr, $expression); - $expressions = array_slice($expressions, 0, $limit); + $expressions = array_slice($expressions, 0, $this->limit); foreach ($expressions as $expr) { $expr = trim($expr); if (!empty($expr)) { - $expr = str_ireplace($search, $replace, $expr); $last_result = $em->evaluate($expr); $this->error = $em->last_error_code; if ($this->error !== null) { //$em->last_error is null if no error happened, so just check if error is not null $this->error_expr = $expr; - return -2; + return -3; } } } @@ -190,15 +207,15 @@ class PriceParser if (empty($vars["price"])) { $vars["price"] = $last_result; } - if ($vars["price"] === null) + if (!isset($vars["price"])) { $this->error = array(21, $expression); - return -3; + return -4; } if ($vars["price"] < 0) { $this->error = array(22, $expression); - return -4; + return -5; } return $vars["price"]; } @@ -209,13 +226,13 @@ class PriceParser * @param Product $product The Product object to get information * @param string $expression The expression to parse * @param array $extra_values Any aditional values for expression - * @return int > 0 if OK, < 1 if KO + * @return int > 0 if OK, < 1 if KO */ public function parseProductExpression($product, $expression, $extra_values = array()) { //Get the supplier min - $productFournisseur = new ProductFournisseur($this->db); - $supplier_min_price = $productFournisseur->find_min_price_product_fournisseur($product->id); + $productFournisseur = new ProductFournisseur($this->db); + $supplier_min_price = $productFournisseur->find_min_price_product_fournisseur($product->id); //Accessible values by expressions $extra_values = array_merge($extra_values, array( @@ -237,7 +254,7 @@ class PriceParser * * @param Product $product The Product object to get information * @param array $extra_values Any aditional values for expression - * @return int > 0 if OK, < 1 if KO + * @return int > 0 if OK, < 1 if KO */ public function parseProduct($product, $extra_values = array()) { @@ -261,7 +278,7 @@ class PriceParser * @param int $quantity Supplier Min quantity * @param int $tva_tx Supplier VAT rate * @param array $extra_values Any aditional values for expression - * @return int > 0 if OK, < 1 if KO + * @return int > 0 if OK, < 1 if KO */ public function parseProductSupplierExpression($product_id, $expression, $quantity = null, $tva_tx = null, $extra_values = array()) { @@ -285,7 +302,7 @@ class PriceParser * @param int $quantity Min quantity * @param int $tva_tx VAT rate * @param array $extra_values Any aditional values for expression - * @return int > 0 if OK, < 1 if KO + * @return int > 0 if OK, < 1 if KO */ public function parseProductSupplier($product_id, $expression_id, $quantity = null, $tva_tx = null, $extra_values = array()) { diff --git a/htdocs/product/expression.php b/htdocs/product/dynamic_price/editor.php similarity index 85% rename from htdocs/product/expression.php rename to htdocs/product/dynamic_price/editor.php index be3e5401789..1fc7df3b731 100644 --- a/htdocs/product/expression.php +++ b/htdocs/product/dynamic_price/editor.php @@ -16,16 +16,17 @@ */ /** - * \file htdocs/product/expression.php + * \file htdocs/product/expression/editor.php * \ingroup product * \brief Page for editing expression */ -require '../main.inc.php'; +require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/class/priceexpression.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/class/priceparser.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_global_variable.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; $langs->load("products"); $langs->load("accountancy"); //"Back" translation is on this file @@ -47,6 +48,7 @@ $product = new Product($db); $product->fetch($id, ''); $price_expression = new PriceExpression($db); +$price_globals = new PriceGlobalVariable($db); //Fetch expression data if (empty($eid)) //This also disables fetch when eid == 0 @@ -184,8 +186,17 @@ print ''.$langs->trans("Name").''; print ''; print ''; +//Help text +$help_text = $langs->trans("PriceExpressionEditorHelp1"); +$help_text.= '

'.$langs->trans("PriceExpressionEditorHelp2"); +$help_text.= '

'.$langs->trans("PriceExpressionEditorHelp3"); +$help_text.= '

'.$langs->trans("PriceExpressionEditorHelp4"); +$help_text.= '

'.$langs->trans("PriceExpressionEditorHelp5"); +foreach ($price_globals->listGlobalVariables() as $entry) { + $help_text.= '
#globals_'.$entry->code.'# '.$entry->description.' = '.$entry->value; +} + //Price expression editor -$help_text = $langs->trans("PriceExpressionEditorHelp1").'

'.$langs->trans("PriceExpressionEditorHelp2").'

'.$langs->trans("PriceExpressionEditorHelp3").'

'.$langs->trans("PriceExpressionEditorHelp4"); print ''.$form->textwithpicto($langs->trans("PriceExpressionEditor"),$help_text,1).''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $doleditor=new DolEditor('expression',isset($price_expression->expression)?$price_expression->expression:'','',300,'','',false,false,false,4,80); @@ -194,7 +205,7 @@ print ''; print ''; //Buttons -print '
'; +print '
'; print ''; print ''.$langs->trans("Back").''; if ($eid == 0) @@ -205,9 +216,9 @@ else { print ''; } -print '
'; +print ''; -print ''; +print ''; // This code reloads the page depending of selected option, goes to page selected by tab when back is pressed print '