diff --git a/ChangeLog b/ChangeLog index 99c3e31221f..aaad1ca826b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -74,6 +74,10 @@ Fix: Page load not ending when large number of thirdparies. We combo feature that is root cause of problem. Fix: [ bug #1231 ] PDF always generated in interventions Fix: Be sure there is no duplicate default rib. +Fix: Enable extrafields for customer order, proposal and invoice lines. This feature + was developed for 3.5 but was disabled (hidden) because of a bug not possible to + fix enough quickly for 3.5.0 release. +Fix: user right on Holiday for month report nor working. ***** ChangeLog for 3.5 compared to 3.4.* ***** For users: diff --git a/htdocs/cashdesk/index_verif.php b/htdocs/cashdesk/index_verif.php index 94ec87edea0..9f7e0332046 100644 --- a/htdocs/cashdesk/index_verif.php +++ b/htdocs/cashdesk/index_verif.php @@ -65,6 +65,21 @@ if (! empty($conf->stock->enabled) && $conf->global->STOCK_CALCULATE_ON_BILL && exit; } +// If stock decrease on bill validation, check user has stock edit permissions +if (! empty($conf->stock->enabled) && $conf->global->STOCK_CALCULATE_ON_BILL && ! empty($username)) +{ + $testuser=new User($db); + $testuser->fetch(0,$username); + $testuser->getrights('stock'); + if (empty($testuser->rights->stock->creer)) + { + $retour=$langs->trans("UserNeedPermissionToEditStockToUsePos"); + header('Location: '.DOL_URL_ROOT.'/cashdesk/index.php?err='.urlencode($retour).'&user='.$username.'&socid='.$thirdpartyid.'&warehouseid='.$warehouseid.'&bankid_cash='.$bankid_cash.'&bankid_cheque='.$bankid_cheque.'&bankid_cb='.$bankid_cb); + exit; + } +} + + /* if (! empty($_POST['txtUsername']) && ! empty($conf->banque->enabled) && (empty($conf_fkaccount_cash) && empty($conf_fkaccount_cheque) && empty($conf_fkaccount_cb))) { diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index e61750f7bfd..a8dd4ab2a9e 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -657,7 +657,7 @@ else if (($action == 'addline' || $action == 'addline_predef') && $user->rights- //Extrafields $extrafieldsline = new ExtraFields($db); $extralabelsline =$extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline,$predef); //Unset extrafield if (is_array($extralabelsline)) { diff --git a/htdocs/commande/fiche.php b/htdocs/commande/fiche.php index 9b1093873ed..760324d23e8 100644 --- a/htdocs/commande/fiche.php +++ b/htdocs/commande/fiche.php @@ -591,7 +591,7 @@ else if ($action == 'addline' && $user->rights->commande->creer) //Extrafields $extrafieldsline = new ExtraFields($db); $extralabelsline =$extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline,$predef); //Unset extrafield if (is_array($extralabelsline)) { @@ -605,12 +605,12 @@ else if ($action == 'addline' && $user->rights->commande->creer) if ((empty($idprod) || GETPOST('usenewaddlineform')) && ($price_ht < 0) && ($qty < 0)) { setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error = true; + $error++; } if (empty($idprod) && GETPOST('type') < 0) { setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); - $error = true; + $error++; } if ((empty($idprod) || GETPOST('usenewaddlineform')) && (!($price_ht >= 0) || $price_ht == '')) // Unit price can be 0 but not '' { @@ -620,12 +620,12 @@ else if ($action == 'addline' && $user->rights->commande->creer) if ($qty == '') { setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error = true; + $error++; } if (empty($idprod) && empty($product_desc)) { setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); - $error = true; + $error++; } if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index fcf48c5f2ab..c900b0d7ebb 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -1147,13 +1147,13 @@ else if (($action == 'addline' || $action == 'addline_predef') && $user->rights- //Extrafields $extrafieldsline = new ExtraFields($db); $extralabelsline =$extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline,$predef); //Unset extrafield if (is_array($extralabelsline)) { // Get extra fields foreach ($extralabelsline as $key => $value) { - unset($_POST["options_".$key]); + unset($_POST["options_".$key.$predef]); } } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 35f09944ef7..20299041dfe 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2268,13 +2268,14 @@ abstract class CommonObject /** * Function to show lines of extrafields with output datas * - * @param object $extrafields extrafield Object + * @param object $extrafields Extrafield Object * @param string $mode Show output (view) or input (edit) for extrafield - * @param array $params optionnal parameters + * @param array $params Optionnal parameters + * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) * * @return string */ - function showOptionals($extrafields,$mode='view',$params=0) + function showOptionals($extrafields, $mode='view', $params=0, $keyprefix='') { global $_POST; @@ -2342,7 +2343,7 @@ abstract class CommonObject $out .= $extrafields->showOutputField($key,$value); break; case "edit": - $out .= $extrafields->showInputField($key,$value); + $out .= $extrafields->showInputField($key,$value,'',$keyprefix); break; } diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index ae705ee7ab8..128dec24d8c 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -571,14 +571,15 @@ class ExtraFields /** - * Return HTML string to put an input field into a page + * Return HTML string to put an input field into a page * - * @param string $key Key of attribute - * @param string $value Value to show (for date type it must be in timestamp format) - * @param string $moreparam To add more parametes on html input tag - * @return void + * @param string $key Key of attribute + * @param string $value Value to show (for date type it must be in timestamp format) + * @param string $moreparam To add more parametes on html input tag + * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @return void */ - function showInputField($key,$value,$moreparam='') + function showInputField($key,$value,$moreparam='',$keyprefix='') { global $conf,$langs; @@ -620,23 +621,23 @@ class ExtraFields if(!$required && $value == '') $value = '-1'; - $out = $formstat->select_date($value, 'options_'.$key, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1); - //$out=''; + $out = $formstat->select_date($value, 'options_'.$key.$keyprefix, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1); + // TODO Missing to add $moreparam } elseif (in_array($type,array('int'))) { $tmp=explode(',',$size); $newsize=$tmp[0]; - $out=''; + $out=''; } elseif ($type == 'varchar') { - $out=''; + $out=''; } elseif ($type == 'text') { require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('options_'.$key,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100); + $doleditor=new DolEditor('options_'.$key.$keyprefix,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100); $out=$doleditor->Create(1); } elseif ($type == 'boolean') @@ -647,36 +648,36 @@ class ExtraFields } else { $checked=' value="1" '; } - $out=''; + $out=''; } elseif ($type == 'mail') { - $out=''; + $out=''; } elseif ($type == 'phone') { - $out=''; + $out=''; } elseif ($type == 'price') { - $out=' '.$langs->getCurrencySymbol($conf->currency); + $out=' '.$langs->getCurrencySymbol($conf->currency); } elseif ($type == 'double') { if (!empty($value)) { $value=price($value); } - $out=' '; + $out=' '; } elseif ($type == 'select') { $out = ''; if ($conf->use_javascript_ajax && $conf->global->COMPANY_USE_SEARCH_TO_SELECT && ! $forcecombo) { - $out.= ajax_combobox('options_'.$key, $event, $conf->global->COMPANY_USE_SEARCH_TO_SELECT); + $out.= ajax_combobox('options_'.$key.$keyprefix, $event, $conf->global->COMPANY_USE_SEARCH_TO_SELECT); } - $out.=''; foreach ($param['options'] as $key=>$val ) { list($val, $parent) = explode('|', $val); @@ -692,10 +693,10 @@ class ExtraFields $out = ''; if ($conf->use_javascript_ajax && $conf->global->COMPANY_USE_SEARCH_TO_SELECT && ! $forcecombo) { - $out.= ajax_combobox('options_'.$key, $event, $conf->global->COMPANY_USE_SEARCH_TO_SELECT); + $out.= ajax_combobox('options_'.$key.$keyprefix, $event, $conf->global->COMPANY_USE_SEARCH_TO_SELECT); } - $out.=''; if (is_array($param['options'])) { $param_list=array_keys($param['options']); @@ -836,7 +837,7 @@ class ExtraFields foreach ($param['options'] as $keyopt=>$val ) { - $out.='$val ) { - $out.=''; @@ -1101,9 +1102,10 @@ class ExtraFields * return array_options array for object by extrafields value (using for data send by forms) * * @param array $extralabels $array of extrafields + * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) * @return int 1 if array_options set / 0 if no value */ - function getOptionalsFromPost($extralabels) + function getOptionalsFromPost($extralabels,$keyprefix='') { global $_POST; @@ -1118,23 +1120,24 @@ class ExtraFields if (in_array($key_type,array('date','datetime'))) { // Clean parameters - $value_key=dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]); + $value_key=dol_mktime($_POST["options_".$key.$keyprefix."hour"], $_POST["options_".$key.$keyprefix."min"], 0, $_POST["options_".$key.$keyprefix."month"], $_POST["options_".$key.$keyprefix."day"], $_POST["options_".$key.$keyprefix."year"]); } else if (in_array($key_type,array('checkbox'))) { - $value_arr=GETPOST("options_".$key); + $value_arr=GETPOST("options_".$key.$keyprefix); $value_key=implode($value_arr,','); } else if (in_array($key_type,array('price','double'))) { - $value_arr=GETPOST("options_".$key); + $value_arr=GETPOST("options_".$key.$keyprefix); $value_key=price2num($value_arr); } else { - $value_key=GETPOST("options_".$key); + $value_key=GETPOST("options_".$key.$keyprefix); } - $array_options["options_".$key]=$value_key; + + $array_options["options_".$key]=$value_key; // No keyprefix here. keyprefix is used only for read. } return $array_options; diff --git a/htdocs/core/class/html.formadmin.class.php b/htdocs/core/class/html.formadmin.class.php index ccd3e038f74..6d570b70880 100644 --- a/htdocs/core/class/html.formadmin.class.php +++ b/htdocs/core/class/html.formadmin.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2004-2014 Laurent Destailleur * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2007 Patrick Raguin * @@ -146,7 +146,7 @@ class FormAdmin if (preg_match('/eldy_(backoffice|frontoffice)\.php$/i',$file)) continue; // We exclude all menu manager files if (preg_match('/auguria_(backoffice|frontoffice)\.php$/i',$file)) continue; // We exclude all menu manager files if (preg_match('/smartphone_(backoffice|frontoffice)\.php$/i',$file)) continue; // We exclude all menu manager files - + $filelib=preg_replace('/\.php$/i','',$file); $prefix=''; // 0=Recommanded, 1=Experimental, 2=Developpement, 3=Other @@ -324,7 +324,7 @@ class FormAdmin * * @param string $selected Paper format pre-selected * @param string $htmlname Name of HTML select field - * @param string $filter Key to filter + * @param string $filter Value to filter on code * @param int $showempty Add empty value * @return string Return HTML output */ @@ -332,8 +332,12 @@ class FormAdmin { global $langs; - $sql="SELECT code, label, width, height, unit FROM ".MAIN_DB_PREFIX."c_paper_format where active=1"; - if ($filter) $sql.=" WHERE code LIKE '%".$filter."%'"; + $langs->load("dict"); + + $sql = "SELECT code, label, width, height, unit"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_paper_format"; + $sql.= " WHERE active=1"; + if ($filter) $sql.=" AND code LIKE '%".$this->db->escape($filter)."%'"; $resql=$this->db->query($sql); if ($resql) @@ -350,7 +354,11 @@ class FormAdmin $i++; } } - else dol_print_error($this->db); + else + { + dol_print_error($this->db); + return ''; + } $out=''; $out.= '"> rights->margins->creer) { if (! empty($conf->global->DISPLAY_MARGIN_RATES)) { echo '%'; + $colspan++; + $coldisplay++; } if (! empty($conf->global->DISPLAY_MARK_RATES)) { echo '%'; + $colspan++; + $coldisplay++; } } else @@ -164,7 +171,7 @@ else { $newline = new FactureLigne($this->db); } if (is_object($newline)) { - print $newline->showOptionals($extrafieldsline,'edit',array('style'=>$bcnd[$var],'colspan'=>$coldisplay+8)); + print $newline->showOptionals($extrafieldsline, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay+8)); } } ?> diff --git a/htdocs/core/tpl/objectline_add.tpl.php b/htdocs/core/tpl/objectline_add.tpl.php index 6a354358497..0c03206ae67 100644 --- a/htdocs/core/tpl/objectline_add.tpl.php +++ b/htdocs/core/tpl/objectline_add.tpl.php @@ -190,10 +190,10 @@ if (! empty($conf->margin->enabled)) { if ($user->rights->margins->creer) { if (! empty($conf->global->DISPLAY_MARGIN_RATES)) { - echo '%'; + echo '%'; } elseif (! empty($conf->global->DISPLAY_MARK_RATES)) { - echo '%'; + echo '%'; } } else diff --git a/htdocs/core/tpl/predefinedproductline_create.tpl.php b/htdocs/core/tpl/predefinedproductline_create.tpl.php index ec430015135..acd06c807d3 100644 --- a/htdocs/core/tpl/predefinedproductline_create.tpl.php +++ b/htdocs/core/tpl/predefinedproductline_create.tpl.php @@ -134,13 +134,20 @@ else { "> rights->margins->creer) { if (! empty($conf->global->DISPLAY_MARGIN_RATES)) { echo '%'; + $colspan++; + $coldisplay++; } if (! empty($conf->global->DISPLAY_MARK_RATES)) { echo '%'; + $colspan++; + $coldisplay++; } } else @@ -172,7 +179,7 @@ else { $newline = new FactureLigne($this->db); } if (is_object($newline)) { - print $newline->showOptionals($extrafieldsline,'edit',array('style'=>$bcnd[$var],'colspan'=>$coldisplay+5)); + print $newline->showOptionals($extrafieldsline, 'edit', array('style'=>$bcnd[$var],'colspan'=>$coldisplay+5), '_predef'); } } ?> diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang index ea617c19583..22cc717df1a 100644 --- a/htdocs/langs/en_US/cashdesk.lang +++ b/htdocs/langs/en_US/cashdesk.lang @@ -36,4 +36,5 @@ BankToPay=Charge Account ShowCompany=Show company ShowStock=Show warehouse DeleteArticle=Click to remove this article -FilterRefOrLabelOrBC=Search (Ref/Label) \ No newline at end of file +FilterRefOrLabelOrBC=Search (Ref/Label) +UserNeedPermissionToEditStockToUsePos=You ask to decrease stock on invoice creation, so user that use POS need to have permission to edit stock. \ No newline at end of file diff --git a/htdocs/langs/fr_FR/cashdesk.lang b/htdocs/langs/fr_FR/cashdesk.lang index ceab9ef95d1..5dd2fe6ec57 100644 --- a/htdocs/langs/fr_FR/cashdesk.lang +++ b/htdocs/langs/fr_FR/cashdesk.lang @@ -37,3 +37,4 @@ ShowCompany=Voir société ShowStock=Voir entrepôt DeleteArticle=Cliquez pour enlever cet article FilterRefOrLabelOrBC=Recherche (Ref/Lib.) +UserNeedPermissionToEditStockToUsePos=La configuration du module stock demande une réduction du stock sur facturation, aussi l'utilisateur du Point De Vente doit avoir les droits de modifier les stocks \ No newline at end of file diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 479f211eaef..25fc77311ac 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -8,7 +8,7 @@ * Copyright (C) 2005 Lionel Cousteix * Copyright (C) 2011 Herve Prot * Copyright (C) 2013 Philippe Grand - * Copyright (C) 2013 Alexandre Spangaro + * Copyright (C) 2013 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 @@ -488,6 +488,7 @@ class User extends CommonObject * Clear all permissions array of user * * @return void + * @see getrights */ function clearrights() { @@ -503,6 +504,7 @@ class User extends CommonObject * * @param string $moduletag Limit permission for a particular module ('' by default means load all permissions) * @return void + * @see clearrights */ function getrights($moduletag='') { @@ -1013,7 +1015,7 @@ class User extends CommonObject { $newpass=$this->setPassword($user,$this->pass); if (is_numeric($newpass) && $newpass < 0) $result=-2; - + if ($result > 0 && $member->fk_soc) // If member is linked to a thirdparty { $sql = "UPDATE ".MAIN_DB_PREFIX."user"; diff --git a/test/phpunit/FormAdminTest.php b/test/phpunit/FormAdminTest.php new file mode 100644 index 00000000000..363fd4acf2e --- /dev/null +++ b/test/phpunit/FormAdminTest.php @@ -0,0 +1,139 @@ + + * + * 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 . + * or see http://www.gnu.org/ + */ + +/** + * \file test/phpunit/FormAdminTest.php + * \ingroup test + * \brief PHPUnit test + * \remarks To run this script as CLI: phpunit filename.php + */ + +global $conf,$user,$langs,$db; +//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver +require_once 'PHPUnit/Autoload.php'; +require_once dirname(__FILE__).'/../../htdocs/master.inc.php'; +require_once dirname(__FILE__).'/../../htdocs/core/class/html.formadmin.class.php'; + +if (empty($user->id)) +{ + print "Load permissions for admin user nb 1\n"; + $user->fetch(1); + $user->getrights(); +} +$conf->global->MAIN_DISABLE_ALL_MAILS=1; + + +/** + * Class for PHPUnit tests + * + * @backupGlobals disabled + * @backupStaticAttributes enabled + * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. + */ +class FormAdminTest extends PHPUnit_Framework_TestCase +{ + protected $savconf; + protected $savuser; + protected $savlangs; + protected $savdb; + + /** + * Constructor + * We save global variables into local variables + * + * @return FactureTest + */ + function __construct() + { + //$this->sharedFixture + global $conf,$user,$langs,$db; + $this->savconf=$conf; + $this->savuser=$user; + $this->savlangs=$langs; + $this->savdb=$db; + + print __METHOD__." db->type=".$db->type." user->id=".$user->id; + //print " - db ".$db->db; + print "\n"; + } + + // Static methods + public static function setUpBeforeClass() + { + global $conf,$user,$langs,$db; + $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. + + print __METHOD__."\n"; + } + public static function tearDownAfterClass() + { + global $conf,$user,$langs,$db; + $db->rollback(); + + print __METHOD__."\n"; + } + + /** + * Init phpunit tests + * + * @return void + */ + protected function setUp() + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + print __METHOD__."\n"; + } + + /** + * End phpunit tests + * + * @return void + */ + protected function tearDown() + { + print __METHOD__."\n"; + } + + /** + * testFactureCreate + * + * @return int + */ + public function testSelectPaperFormat() + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $localobject=new FormAdmin($this->savdb); + $result=$localobject->select_paper_format('','paperformat_id','A4'); + + $this->assertEquals($result, ''); + print __METHOD__." result=".$result."\n"; + return $result; + } + +} +?> \ No newline at end of file