From fc5899174be30836c958bda923f43851ec4d919b Mon Sep 17 00:00:00 2001 From: Ion Agorria Date: Sat, 14 Mar 2015 16:48:56 +0100 Subject: [PATCH 1/6] Relocation of expression files --- .../class/price_expression.class.php} | 25 ++--- .../class/price_parser.class.php} | 93 +++++++++++-------- .../editor.php} | 29 ++++-- 3 files changed, 88 insertions(+), 59 deletions(-) rename htdocs/product/{class/priceexpression.class.php => dynamic_price/class/price_expression.class.php} (92%) rename htdocs/product/{class/priceparser.class.php => dynamic_price/class/price_parser.class.php} (78%) rename htdocs/product/{expression.php => dynamic_price/editor.php} (85%) 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 ''; + print ''; + //Parameters + print ''; + $help = $langs->trans("GlobalVariableUpdaterHelp".$type).'
'.$langs->trans("GlobalVariableUpdaterHelpFormat".$type).''; + print ''.$form->textwithpicto($langs->trans("Parameters"),$help,1).''; + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor=new DolEditor('parameters',empty($price_updaters->parameters)?'':$price_updaters->parameters,'',300,'','',false,false,false,10,80); + $doleditor->Create(); + print ''; + print ''; + //Interval + print ''; + print ''.$langs->trans("UpdateInterval").''; + print ''; + print ''; + print ''; + + //Form Buttons + print '
'; + print '  '; + print ''; + print '
'; + print ''; +} else { + //Action Buttons + print '
'; + print ''.$langs->trans("Add").''; + print '
'; +} + +llxFooter(); +$db->close(); From 2d09d8196f85e56b970de315e9f5fa686782cc28 Mon Sep 17 00:00:00 2001 From: Ion Agorria Date: Sat, 14 Mar 2015 16:51:50 +0100 Subject: [PATCH 5/6] Language additions --- htdocs/langs/en_US/errors.lang | 6 ++++++ htdocs/langs/en_US/products.lang | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 3d83901194b..37670b7f003 100755 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -161,6 +161,12 @@ ErrorPriceExpressionUnknown=Unknown error '%s' ErrorSrcAndTargetWarehouseMustDiffers=Source and target warehouses must differs ErrorTryToMakeMoveOnProductRequiringBatchData=Error, trying to make a stock movement without batch/serial information, on a product requiring batch/serial information ErrorCantSetReceptionToTotalDoneWithReceptionToApprove=All recorded receptions must first be verified before being allowed to do this action +ErrorGlobalVariableUpdater0=HTTP request failed with error '%s' +ErrorGlobalVariableUpdater1=Invalid JSON format '%s' +ErrorGlobalVariableUpdater2=Missing parameter '%s' +ErrorGlobalVariableUpdater3=The requested data was not found in result +ErrorGlobalVariableUpdater4=SOAP client failed with error '%s' +ErrorGlobalVariableUpdater5=No global variable selected # Warnings WarningMandatorySetupNotComplete=Mandatory setup parameters are not yet defined diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index eb7261ab613..1b9a49b559d 100755 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -245,12 +245,25 @@ MinimumRecommendedPrice=Minimum recommended price is : %s PriceExpressionEditor=Price expression editor PriceExpressionSelected=Selected price expression PriceExpressionEditorHelp1="price = 2 + 2" or "2 + 2" for setting the price. Use ; to separate expressions -PriceExpressionEditorHelp2=You can access ExtraFields with variables like #options_myextrafieldkey# +PriceExpressionEditorHelp2=You can access ExtraFields with variables like #extrafield_myextrafieldkey# and global variables with #global_mycode# PriceExpressionEditorHelp3=In both product/service and supplier prices there are these variables available:
#tva_tx# #localtax1_tx# #localtax2_tx# #weight# #length# #surface# #price_min# PriceExpressionEditorHelp4=In product/service price only: #supplier_min_price#
In supplier prices only: #supplier_quantity# and #supplier_tva_tx# +PriceExpressionEditorHelp5=Available global values: PriceMode=Price mode PriceNumeric=Number DefaultPrice=Default price ComposedProductIncDecStock=Increase/Decrease stock on parent change ComposedProduct=Sub-product -MinSupplierPrice=Minimun supplier price +MinSupplierPrice=Minimum supplier price +DynamicPriceConfiguration=Dynamic price configuration +GlobalVariables=Global variables +GlobalVariableUpdaters=Global variable updaters +GlobalVariableUpdaterType0=JSON data +GlobalVariableUpdaterHelp0=Parses JSON data from specified URL, VALUE specifies the location of relevant value, +GlobalVariableUpdaterHelpFormat0=format is {"URL": "http://example.com/urlofjson", "VALUE": "array1,array2,targetvalue"} +GlobalVariableUpdaterType1=WebService data +GlobalVariableUpdaterHelp1=Parses WebService data from specified URL, NS specifies the namespace, VALUE specifies the location of relevant value, DATA should contain the data to send and METHOD is the calling WS method +GlobalVariableUpdaterHelpFormat1=format is {"URL": "http://example.com/urlofws", "VALUE": "array,targetvalue", "NS": "http://example.com/urlofns", "METHOD": "myWSMethod", "DATA": {"your": "data, "to": "send"}} +UpdateInterval=Update interval (minutes) +LastUpdated=Last updated +CorrectlyUpdated=Correctly updated \ No newline at end of file From e76b6e740f442e865939303134488f821f709c46 Mon Sep 17 00:00:00 2001 From: Ion Agorria Date: Sat, 14 Mar 2015 16:52:01 +0100 Subject: [PATCH 6/6] SQL additions --- .../install/mysql/migration/3.7.0-3.8.0.sql | 20 +++++++++++++ .../tables/llx_c_price_global_variable.sql | 25 ++++++++++++++++ .../llx_c_price_global_variable_updater.sql | 29 +++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 htdocs/install/mysql/tables/llx_c_price_global_variable.sql create mode 100644 htdocs/install/mysql/tables/llx_c_price_global_variable_updater.sql diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index b7475d88f91..12d6cce2022 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -370,3 +370,23 @@ INSERT INTO llx_c_incoterms (code, libelle, active) VALUES ('DDP', 'Delivered Du -- Extrafields fk_object must be unique (1-1 relation) ALTER TABLE llx_societe_extrafields DROP INDEX idx_societe_extrafields; ALTER TABLE llx_societe_extrafields ADD UNIQUE INDEX uk_societe_extrafields (fk_object); + +create table llx_c_price_global_variable +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + code varchar(20) NOT NULL, + description text DEFAULT NULL, + value double(24,8) DEFAULT 0 +)ENGINE=innodb; + +create table llx_c_price_global_variable_updater +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + type integer NOT NULL, + description text DEFAULT NULL, + parameters text DEFAULT NULL, + fk_variable integer NOT NULL, + update_interval integer DEFAULT 0, + next_update integer DEFAULT 0, + last_status text DEFAULT NULL +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_c_price_global_variable.sql b/htdocs/install/mysql/tables/llx_c_price_global_variable.sql new file mode 100644 index 00000000000..0f5630ed193 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_c_price_global_variable.sql @@ -0,0 +1,25 @@ +-- ============================================================================ +-- 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 +-- 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 . +-- +-- ============================================================================ + +create table llx_c_price_global_variable +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + code varchar(20) NOT NULL, + description text DEFAULT NULL, + value double(24,8) DEFAULT 0 +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_c_price_global_variable_updater.sql b/htdocs/install/mysql/tables/llx_c_price_global_variable_updater.sql new file mode 100644 index 00000000000..0c1dcfba701 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_c_price_global_variable_updater.sql @@ -0,0 +1,29 @@ +-- ============================================================================ +-- 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 +-- 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 . +-- +-- ============================================================================ + +create table llx_c_price_global_variable_updater +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + type integer NOT NULL, + description text DEFAULT NULL, + parameters text DEFAULT NULL, + fk_variable integer NOT NULL, + update_interval integer DEFAULT 0, + next_update integer DEFAULT 0, + last_status text DEFAULT NULL +)ENGINE=innodb;