From 1beec519282fb75eb7eede8682bc273fb4642440 Mon Sep 17 00:00:00 2001 From: phf Date: Thu, 15 Jun 2017 11:08:53 +0200 Subject: [PATCH 001/112] New expense report rules and ik (index kilometers) - MAIN_USE_EXPENSE_IK - MAIN_USE_EXPENSE_RULE --- htdocs/admin/dict.php | 68 ++- htdocs/admin/expensereport_ik.php | 188 ++++++++ htdocs/admin/expensereport_rules.php | 366 ++++++++++++++++ htdocs/core/class/html.form.class.php | 170 ++++++++ htdocs/core/lib/expensereport.lib.php | 16 + htdocs/core/lib/functions.lib.php | 40 ++ htdocs/expensereport/ajax/ajaxik.php | 76 ++++ htdocs/expensereport/card.php | 380 ++++++++-------- .../class/expensereport.class.php | 408 ++++++++++++++++-- .../class/expensereport_ik.class.php | 248 +++++++++++ .../class/expensereport_rule.class.php | 236 ++++++++++ .../install/mysql/data/llx_c_exp_tax_cat.sql | 56 +++ .../mysql/data/llx_c_exp_tax_range.sql | 47 ++ htdocs/install/mysql/data/llx_c_type_fees.sql | 26 ++ .../mysql/data/llx_expensereport_ik.sql | 47 ++ .../install/mysql/migration/5.0.0-6.0.0.sql | 135 ++++++ .../mysql/tables/llx_c_exp_tax_cat.sql | 26 ++ .../mysql/tables/llx_c_exp_tax_range.sql | 27 ++ .../mysql/tables/llx_expensereport_det.sql | 4 +- .../mysql/tables/llx_expensereport_ik.sql | 29 ++ .../mysql/tables/llx_expensereport_rules.sql | 34 ++ htdocs/install/mysql/tables/llx_user.sql | 4 +- htdocs/langs/en_US/admin.lang | 6 + htdocs/langs/en_US/dict.lang | 29 ++ htdocs/langs/en_US/trips.lang | 63 ++- htdocs/user/card.php | 48 ++- htdocs/user/class/user.class.php | 12 +- 27 files changed, 2551 insertions(+), 238 deletions(-) create mode 100644 htdocs/admin/expensereport_ik.php create mode 100644 htdocs/admin/expensereport_rules.php create mode 100644 htdocs/expensereport/ajax/ajaxik.php create mode 100644 htdocs/expensereport/class/expensereport_ik.class.php create mode 100644 htdocs/expensereport/class/expensereport_rule.class.php create mode 100644 htdocs/install/mysql/data/llx_c_exp_tax_cat.sql create mode 100644 htdocs/install/mysql/data/llx_c_exp_tax_range.sql create mode 100644 htdocs/install/mysql/data/llx_expensereport_ik.sql create mode 100644 htdocs/install/mysql/tables/llx_c_exp_tax_cat.sql create mode 100644 htdocs/install/mysql/tables/llx_c_exp_tax_range.sql create mode 100644 htdocs/install/mysql/tables/llx_expensereport_ik.sql create mode 100644 htdocs/install/mysql/tables/llx_expensereport_rules.sql diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index c83a3aa39be..2975c7095fc 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -87,7 +87,7 @@ $hookmanager->initHooks(array('admin')); // Put here declaration of dictionaries properties // Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this. -$taborder=array(9,0,4,3,2,0,1,8,19,16,27,0,5,11,0,33,34,0,6,0,29,0,7,17,24,28,0,10,23,12,13,0,14,0,22,20,18,21,0,15,30,0,26,0); +$taborder=array(9,0,4,3,2,0,1,8,19,16,27,0,5,11,0,33,34,0,6,0,29,0,7,17,35,36,24,28,0,10,23,12,13,0,14,0,22,20,18,21,0,15,30,0,26,0,); // Name of SQL tables of dictionaries $tabname=array(); @@ -125,6 +125,8 @@ $tabname[30]= MAIN_DB_PREFIX."c_format_cards"; //$tabname[32]= MAIN_DB_PREFIX."c_accounting_category"; $tabname[33]= MAIN_DB_PREFIX."c_hrm_department"; $tabname[34]= MAIN_DB_PREFIX."c_hrm_function"; +$tabname[35]= MAIN_DB_PREFIX."c_exp_tax_cat"; +$tabname[36]= MAIN_DB_PREFIX."c_exp_tax_range"; // Dictionary labels $tablib=array(); @@ -162,6 +164,8 @@ $tablib[30]= "DictionaryFormatCards"; //$tablib[32]= "DictionaryAccountancyCategory"; $tablib[33]= "DictionaryDepartment"; $tablib[34]= "DictionaryFunction"; +$tablib[35]= "DictionaryExpenseTaxCat"; +$tablib[36]= "DictionaryExpenseTaxRange"; // Requests to extract data $tabsql=array(); @@ -199,6 +203,8 @@ $tabsql[30]= "SELECT rowid, code, name, paper_size, orientation, metric, leftmar //$tabsql[32]= "SELECT a.rowid as rowid, a.code as code, a.label, a.range_account, a.sens, a.category_type, a.formula, a.position as position, a.fk_country as country_id, c.code as country_code, c.label as country, a.active FROM ".MAIN_DB_PREFIX."c_accounting_category as a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_country=c.rowid and c.active=1"; $tabsql[33]= "SELECT rowid, pos, code, label, active FROM ".MAIN_DB_PREFIX."c_hrm_department"; $tabsql[34]= "SELECT rowid, pos, code, label, c_level, active FROM ".MAIN_DB_PREFIX."c_hrm_function"; +$tabsql[35]= "SELECT c.rowid, c.label, c.active, c.entity FROM ".MAIN_DB_PREFIX."c_exp_tax_cat c"; +$tabsql[36]= "SELECT r.rowid, r.fk_cat, r.range, r.active, r.entity FROM ".MAIN_DB_PREFIX."c_exp_tax_range r"; // Criteria to sort dictionaries $tabsqlsort=array(); @@ -236,6 +242,8 @@ $tabsqlsort[30]="code ASC"; //$tabsqlsort[32]="position ASC"; $tabsqlsort[33]="code ASC"; $tabsqlsort[34]="code ASC"; +$tabsqlsort[35]="c.label ASC"; +$tabsqlsort[36]="r.fk_cat ASC, r.range ASC"; // Nom des champs en resultat de select pour affichage du dictionnaire $tabfield=array(); @@ -271,8 +279,8 @@ $tabfield[29]= "code,label,percent,position"; $tabfield[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; //$tabfield[31]= "pcg_version,label"; //$tabfield[32]= "code,label,range_account,sens,category_type,formula,position,country_id,country"; -$tabfield[33]= "code,label"; -$tabfield[34]= "code,label"; +$tabfield[35]= "label"; +$tabfield[36]= "range,fk_cat"; // Nom des champs d'edition pour modification d'un enregistrement $tabfieldvalue=array(); @@ -310,6 +318,8 @@ $tabfieldvalue[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargi //$tabfieldvalue[32]= "code,label,range_account,sens,category_type,formula,position,country"; $tabfieldvalue[33]= "code,label"; $tabfieldvalue[34]= "code,label"; +$tabfieldvalue[35]= "label"; +$tabfieldvalue[36]= "range,fk_cat"; // Nom des champs dans la table pour insertion d'un enregistrement $tabfieldinsert=array(); @@ -347,6 +357,8 @@ $tabfieldinsert[30]= "code,name,paper_size,orientation,metric,leftmargin,topmarg //$tabfieldinsert[32]= "code,label,range_account,sens,category_type,formula,position,fk_country"; $tabfieldinsert[33]= "code,label"; $tabfieldinsert[34]= "code,label"; +$tabfieldinsert[35]= "label"; +$tabfieldinsert[36]= "`range`,fk_cat"; // Nom du rowid si le champ n'est pas de type autoincrement // Example: "" if id field is "rowid" and has autoincrement on @@ -386,6 +398,8 @@ $tabrowid[30]= ""; //$tabrowid[32]= ""; $tabrowid[33]= "rowid"; $tabrowid[34]= "rowid"; +$tabrowid[35]= ""; +$tabrowid[36]= ""; // Condition to show dictionary in setup page $tabcond=array(); @@ -423,6 +437,8 @@ $tabcond[30]= ! empty($conf->label->enabled); //$tabcond[32]= ! empty($conf->accounting->enabled); $tabcond[33]= ! empty($conf->hrm->enabled); $tabcond[34]= ! empty($conf->hrm->enabled); +$tabcond[35]= ! empty($conf->expensereport->enabled); +$tabcond[36]= ! empty($conf->expensereport->enabled); // List of help for fields $tabhelp=array(); @@ -460,6 +476,8 @@ $tabhelp[30] = array('code'=>$langs->trans("EnterAnyCode"), 'name'=>$langs->tran //$tabhelp[32] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[33] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[34] = array('code'=>$langs->trans("EnterAnyCode")); +$tabhelp[35]= array(); +$tabhelp[36]= array('range'=>$langs->trans('PrevRangeToThisRange')); // List of check for fields (NOT USED YET) $tabfieldcheck=array(); @@ -497,6 +515,8 @@ $tabfieldcheck[30] = array(); //$tabfieldcheck[32] = array(); $tabfieldcheck[33] = array(); $tabfieldcheck[34] = array(); +$tabfieldcheck[35]= array(); +$tabfieldcheck[36]= array(); // Complete all arrays with entries found into modules complete_dictionary_with_modules($taborder,$tabname,$tablib,$tabsql,$tabsqlsort,$tabfield,$tabfieldvalue,$tabfieldinsert,$tabrowid,$tabcond,$tabhelp,$tabfieldcheck); @@ -1064,6 +1084,7 @@ if ($id) if ($fieldlist[$field]=='affect') { $valuetoshow=$langs->trans("WithCounter"); } if ($fieldlist[$field]=='delay') { $valuetoshow=$langs->trans("NoticePeriod"); } if ($fieldlist[$field]=='newbymonth') { $valuetoshow=$langs->trans("NewByMonth"); } + if ($fieldlist[$field]=='fk_tva') { $valuetoshow=$langs->trans("VAT"); } if ($id == 2) // Special cas for state page { @@ -1283,6 +1304,7 @@ if ($id) if ($fieldlist[$field]=='affect') { $valuetoshow=$langs->trans("WithCounter"); } if ($fieldlist[$field]=='delay') { $valuetoshow=$langs->trans("NoticePeriod"); } if ($fieldlist[$field]=='newbymonth') { $valuetoshow=$langs->trans("NewByMonth"); } + if ($fieldlist[$field]=='fk_tva') { $valuetoshow=$langs->trans("VAT"); } // Affiche nom du champ if ($showfield) @@ -1500,6 +1522,26 @@ if ($id) else if ($fieldlist[$field]=='accountancy_code' || $fieldlist[$field]=='accountancy_code_sell' || $fieldlist[$field]=='accountancy_code_buy') { $valuetoshow = length_accountg($valuetoshow); } + elseif ($fieldlist[$field] == 'fk_tva') + { + foreach ($form->cache_vatrates as $key => $Tab) + { + if ($form->cache_vatrates[$key]['rowid'] == $valuetoshow) + { + $valuetoshow = $form->cache_vatrates[$key]['libtva']; + break; + } + } + } + elseif (in_array($fieldlist[$field], array('fk_cat', 'fk_exp_tax_cat'))) + { + $valuetoshow = getDictvalue(MAIN_DB_PREFIX.'c_exp_tax_cat', 'label', $valuetoshow); + $valuetoshow = $langs->trans($valuetoshow); + } + elseif ($tabname[$id] == MAIN_DB_PREFIX.'c_exp_tax_cat') + { + $valuetoshow = $langs->trans($valuetoshow); + } $class='tddict'; if ($fieldlist[$field] == 'tracking') $class.=' tdoverflowauto'; @@ -1663,7 +1705,7 @@ $db->close(); */ function fieldList($fieldlist, $obj='', $tabname='', $context='') { - global $conf,$langs,$db; + global $conf,$langs,$db,$mysoc; global $form; global $region_id; global $elementList,$sourceList,$localtax_typeList; @@ -1829,6 +1871,24 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') } print ''; } + elseif ($fieldlist[$field] == 'fk_tva') + { + print ''; + print $form->load_tva('fk_tva', $obj->taux, $mysoc, new Societe($db), 0, 0, '', false, -1); + print ''; + } + elseif ($fieldlist[$field] == 'fk_cat') + { + print ''; + print $form->selectExpenseCategories($obj->fk_cat); + print ''; + } + elseif ($fieldlist[$field] == 'fk_range') + { + print ''; + print $form->selectExpenseRanges($obj->fk_range); + print ''; + } else { $classtd=''; $class=''; diff --git a/htdocs/admin/expensereport_ik.php b/htdocs/admin/expensereport_ik.php new file mode 100644 index 00000000000..bb50bfc58f0 --- /dev/null +++ b/htdocs/admin/expensereport_ik.php @@ -0,0 +1,188 @@ + + * Copyright (C) 2017 ATM Consulting + * Copyright (C) 2017 Pierre-Henry Favre + * + * 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 2 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/admin/expensereport_ik.php + * \ingroup expensereport + * \brief Page to display expense tax ik + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/expensereport.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; +require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_ik.class.php'; + +$langs->load('admin'); +$langs->load('other'); +$langs->load('trips'); +$langs->load('errors'); +$langs->load('dict'); + +if (!$user->admin) accessforbidden(); + +//Init error +$error = false; +$message = false; + +$action = GETPOST('action','alpha'); +$id = GETPOST('id','int'); +$offset = GETPOST('offset','int'); +$coef = GETPOST('coef','int'); + +$fk_cat = GETPOST('fk_cat'); +$fk_range = GETPOST('fk_range'); + +if ($action == 'updateik') +{ + $expIk = new ExpenseReportIk($db); + if ($id > 0) + { + $result = $expIk->fetch($id); + if ($result < 0) dol_print_error('', $expIk->error, $expIk->errors); + } + + $expIk->setValues($_POST); + $result = $expIk->create($user); + + if ($result > 0) setEventMessages('SetupSaved', null, 'mesgs'); + + header('Location: '.$_SERVER['PHP_SELF']); + exit; +} +elseif ($action == 'delete') // TODO add confirm +{ + $expIk = new ExpenseReportIk($db); + if ($id > 0) + { + $result = $expIk->fetch($id); + if ($result < 0) dol_print_error('', $expIk->error, $expIk->errors); + + $expIk->delete($user); + } + + + header('Location: '.$_SERVER['PHP_SELF']); + exit; +} + +$rangesbycateg = ExpenseReportIk::getAllRanges(); + +/* + * View + */ + +llxHeader(); + +$form=new Form($db); + +$linkback=''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("ExpenseReportsIkSetup"),$linkback,'title_setup'); + +$head=expensereport_admin_prepare_head(); +dol_fiche_head($head, 'expenseik', $langs->trans("ExpenseReportsIk"), -1, 'trip'); + +echo $langs->trans('ExpenseReportIkDesc'); + +echo '
'; + +if ($action == 'edit') +{ + echo ''; + echo ''; + echo ''; + echo ''; +} + +echo ''; + +echo ''; + +foreach ($rangesbycateg as $fk_cat => $Tab) +{ + $title = ($Tab['active'] == 1) ? $langs->trans($Tab['label']) : $form->textwithpicto($langs->trans($Tab['label']), $langs->trans('expenseReportCatDisabled'), 1, 'help', '', 0, 3); + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + + if ($Tab['active'] == 0) continue; + + $tranche=1; + $var = true; + foreach ($Tab['ranges'] as $k => $range) + { + if (isset($Tab['ranges'][$k+1])) $label = $langs->trans('expenseReportRangeFromTo', $range->range, ($Tab['ranges'][$k+1]->range-1)); + else $label = $langs->trans('expenseReportRangeMoreThan', $range->range); + + if ($range->range_active == 0) $label = $form->textwithpicto($label, $langs->trans('expenseReportRangeDisabled'), 1, 'help', '', 0, 3); + + echo ''; + + // Label + echo ''; + + // Offset + echo ''; + // Coef + echo ''; + + // Total for one + echo ''; + + // Action + echo ''; + + echo ''; + $var=!$var; + } +} + +echo '
'.$title.''.$langs->trans('expenseReportOffset').''.$langs->trans('expenseReportCoef').''.$langs->trans('expenseReportTotalForFive').' 
['.$langs->trans('RangeNum', $tranche++).'] - '.$label.''; + if ($action == 'edit' && $range->ik->id == $id && $range->rowid == $fk_range && $range->fk_cat == $fk_cat) echo ''; + else echo $range->ik->offset; + echo ''; + if ($action == 'edit' && $range->ik->id == $id && $range->rowid == $fk_range && $range->fk_cat == $fk_cat) echo ''; + else echo ($range->ik->id > 0 ? $range->ik->coef : $langs->trans('expenseReportCoefUndefined')); + echo ''.$langs->trans('expenseReportPrintExample', price($range->ik->offset + 5 * $range->ik->coef)).''; + if ($range->range_active == 1) + { + if ($action == 'edit' && $range->ik->id == $id && $range->rowid == $fk_range && $range->fk_cat == $fk_cat) + { + echo ''; + echo ''; + } + else + { + echo ''.img_edit().''; + if (!empty($range->ik->id)) echo ''.img_delete().''; + // TODO add delete link + } + } + echo '
'; +echo '
'; + +dol_fiche_end(); +llxFooter(); + +$db->close(); \ No newline at end of file diff --git a/htdocs/admin/expensereport_rules.php b/htdocs/admin/expensereport_rules.php new file mode 100644 index 00000000000..695bdf09a12 --- /dev/null +++ b/htdocs/admin/expensereport_rules.php @@ -0,0 +1,366 @@ + + * Copyright (C) 2017 ATM Consulting + * Copyright (C) 2017 Pierre-Henry Favre + * + * 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 2 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/admin/expensereport_ik.php + * \ingroup expensereport + * \brief Page to display expense tax ik + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/expensereport.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; +require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_rule.class.php'; + +$langs->load('admin'); +$langs->load('other'); +$langs->load('trips'); +$langs->load('errors'); +$langs->load('dict'); + +if (!$user->admin) accessforbidden(); + +//Init error +$error = false; +$message = false; + +$action = GETPOST('action','alpha'); +$id = GETPOST('id','int'); + +$apply_to = GETPOST('apply_to'); +$fk_user = GETPOST('fk_user'); +$fk_usergroup = GETPOST('fk_usergroup'); + +$fk_c_type_fees = GETPOST('fk_c_type_fees'); +$code_expense_rules_type = GETPOST('code_expense_rules_type'); +$dates = dol_mktime(12, 0, 0, GETPOST('startmonth'), GETPOST('startday'), GETPOST('startyear')); +$datee = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear')); +$amount = GETPOST('amount'); +$restrictive = GETPOST('restrictive'); + +$object = new ExpenseReportRule($db); +if (!empty($id)) +{ + $result = $object->fetch($id); + if ($result < 0) dol_print_error('', $object->error, $object->errors); +} + +// TODO do action +if ($action == 'save') +{ + $error = 0; + + // check parameters + if (empty($apply_to)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportApplyTo")), null, 'errors'); + } + if (empty($fk_c_type_fees)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDomain")), null, 'errors'); + } + if (empty($code_expense_rules_type)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportLimitOn")), null, 'errors'); + } + if (empty($dates)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDateStart")), null, 'errors'); + } + if (empty($datee)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDateEnd")), null, 'errors'); + } + if (empty($amount)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportLimitAmount")), null, 'errors'); + } + + if (empty($error)) + { + $object->setValues($_POST); + + if($apply_to=='U'){ + $object->fk_user=$fk_user; + $object->fk_usergroup=0; + $object->is_for_all=0; + }elseif($apply_to=='G'){ + $object->fk_usergroup=$fk_usergroup; + $object->fk_user=0; + $object->is_for_all=0; + }elseif($apply_to=='A'){ + $object->is_for_all=1; + $object->fk_user=0; + $object->fk_usergroup=0; + } + + $object->dates = $dates; + $object->datee = $datee; + + $object->entity = $conf->entity; + + $res = $object->create($user); + if ($res > 0) setEventMessages($langs->trans('ExpenseReportRuleSave'), null); + else dol_print_error($object->db); + + header('Location: '.$_SERVER['PHP_SELF']); + exit; + } +} +elseif ($action == 'delete') +{ + // TODO add confirm + $res = $object->delete($user); + + if ($res < 0) dol_print_error($object->db); + + header('Location: '.$_SERVER['PHP_SELF']); + exit; +} + +$rules = ExpenseReportRule::getAllRule(); + +$tab_apply = array('A' => $langs->trans('All'), 'G' => $langs->trans('Group'), 'U' => $langs->trans('User')); +$tab_rules_type = array('EX_DAY' => $langs->trans('Day'), 'EX_MON' => $langs->trans('Month'), 'EX_YEA' => $langs->trans('Year'), 'EX_EXP' => $langs->trans('OnExpense')); + +/* + * View + */ + +llxHeader(); + +$form=new Form($db); + +$linkback=''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("ExpenseReportsRulesSetup"),$linkback,'title_setup'); + +$head=expensereport_admin_prepare_head(); +dol_fiche_head($head, 'expenserules', $langs->trans("ExpenseReportsRules"), -1, 'trip'); + +echo $langs->trans('ExpenseReportRulesDesc'); + +if ($action != 'edit') +{ + echo '
'; + echo ''; + echo ''; + + echo ''; + + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + + $var=true; + echo ''; + echo ''; + + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + + echo '
'.$langs->trans('ExpenseReportApplyTo').''.$langs->trans('ExpenseReportDomain').''.$langs->trans('ExpenseReportLimitOn').''.$langs->trans('ExpenseReportDateStart').''.$langs->trans('ExpenseReportDateEnd').''.$langs->trans('ExpenseReportLimitAmount').''.$langs->trans('ExpenseReportRestrictive').' 
'; + echo '
'.$form->selectarray('apply_to', $tab_apply, '', 0).'
'; + echo '
'.$form->select_dolusers('', 'fk_user').'
'; + echo '
'.$form->select_dolgroups('', 'fk_usergroup').'
'; + echo '
'.$form->selectExpense('', 'fk_c_type_fees', 0, 1, 1).''.$form->selectarray('code_expense_rules_type', $tab_rules_type, '', 0).''.$form->select_date(strtotime(date('Y-m-01', dol_now())), 'start', '', '', 0, '', 1, 0, 1).''.$form->select_date(strtotime(date('Y-m-t', dol_now())), 'end', '', '', 0, '', 1, 0, 1).''.$conf->currency.''.$form->selectyesno('restrictive', 0, 1).'
'; + echo '
'; +} + + +echo '
'; +echo ''; + +if ($action == 'edit') +{ + echo ''; + echo ''; +} + +echo ''; + +echo ''; +echo ''; +echo ''; +echo ''; +echo ''; +echo ''; +echo ''; +echo ''; +echo ''; +echo ''; + +$var=true; +foreach ($rules as $rule) +{ + echo ''; + + echo ''; + + + echo ''; + + + + echo ''; + + + echo ''; + + + echo ''; + + + echo ''; + + + echo ''; + + + echo ''; + + echo ''; + $var=!$var; +} + + +echo '
'.$langs->trans('ExpenseReportApplyTo').''.$langs->trans('ExpenseReportDomain').''.$langs->trans('ExpenseReportLimitOn').''.$langs->trans('ExpenseReportDateStart').''.$langs->trans('ExpenseReportDateEnd').''.$langs->trans('ExpenseReportLimitAmount').''.$langs->trans('ExpenseReportRestrictive').' 
'; + if ($action == 'edit' && $object->id == $rule->id) + { + $selected = ($object->is_for_all > 0) ? 'A' : ($object->fk_usergroup > 0 ? 'G' : 'U'); + echo '
'.$form->selectarray('apply_to', $tab_apply, $selected, 0).'
'; + echo '
'.$form->select_dolusers($object->fk_user, 'fk_user').'
'; + echo '
'.$form->select_dolgroups($object->fk_usergroup, 'fk_usergroup').'
'; + } + else + { + if ($rule->is_for_all > 0) echo $tab_apply['A']; + elseif ($rule->fk_usergroup > 0) echo $tab_apply['G'].' ('.$rule->getGroupLabel().')'; + elseif ($rule->fk_user > 0) echo $tab_apply['U'].' ('.$rule->getUserName().')'; + } + echo '
'; + if ($action == 'edit' && $object->id == $rule->id) + { + echo $form->selectExpense($object->fk_c_type_fees, 'fk_c_type_fees', 0, 1, 1); + } + else + { + if ($rule->fk_c_type_fees == -1) echo $langs->trans('AllExpenseReport'); + else + { + $key = getDictvalue(MAIN_DB_PREFIX.'c_type_fees', 'code', $rule->fk_c_type_fees, false, 'id'); + if ($key != $langs->trans($key)) echo $langs->trans($key); + else echo $langs->trans(getDictvalue(MAIN_DB_PREFIX.'c_type_fees', 'label', $rule->fk_c_type_fees, false, 'id')); // TODO check to return trans of 'code' + } + } + echo ''; + if ($action == 'edit' && $object->id == $rule->id) + { + echo $form->selectarray('code_expense_rules_type', $tab_rules_type, $object->code_expense_rules_type, 0); + } + else + { + echo $tab_rules_type[$rule->code_expense_rules_type]; + } + echo ''; + if ($action == 'edit' && $object->id == $rule->id) + { + echo $form->select_date(strtotime(date('Y-m-d', $object->dates)), 'start', '', '', 0, '', 1, 0, 1); + } + else + { + echo dol_print_date($rule->dates, 'day'); + } + echo ''; + if ($action == 'edit' && $object->id == $rule->id) + { + echo $form->select_date(strtotime(date('Y-m-d', $object->datee)), 'end', '', '', 0, '', 1, 0, 1); + } + else + { + echo dol_print_date($rule->datee, 'day'); + } + echo ''; + if ($action == 'edit' && $object->id == $rule->id) + { + echo ''.$conf->currency; + } + else + { + echo price($rule->amount, 0, $langs, 1, -1, -1, $conf->currency); + } + echo ''; + if ($action == 'edit' && $object->id == $rule->id) + { + echo $form->selectyesno('restrictive', $object->restrictive, 1); + } + else + { + echo yn($rule->restrictive, 1, 1); + } + echo ''; + if ($object->id != $rule->id) + { + echo ''.img_edit().' '; + echo ''.img_delete().''; + } + else + { + echo ' '; + echo ''.$langs->trans('Cancel').''; + } + echo '
'; +echo '
'; + +echo ''; + +dol_fiche_end(); +llxFooter(); + +$db->close(); \ No newline at end of file diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 7c8efcc8328..b96e50e8e79 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -6294,5 +6294,175 @@ class Form } return $out; } + + /** + * Return HTML to show the select categories of expense category + * + * @param string $selected preselected category + * @param string $htmlname name of HTML select list + * @param integer $useempty 1=Add empty line + * @param array $excludeid id to exclude + * @param string $target htmlname of target select to bind event + * @param int $default_selected default category to select if fk_c_type_fees change = EX_KME + * @param array $params param to give + * @return string + */ + function selectExpenseCategories($selected='', $htmlname='fk_cat', $useempty=0, $excludeid=array(), $target='', $default_selected=0, $params=array()) + { + global $db,$conf,$langs; + + $sql = 'SELECT rowid, label FROM '.MAIN_DB_PREFIX.'c_exp_tax_cat WHERE active = 1'; + $sql.= ' AND entity IN (0,'.getEntity('').')'; + if (!empty($excludeid)) $sql.= ' AND rowid NOT IN ('.implode(',', $excludeid).')'; + $sql.= ' ORDER BY label'; + + $resql = $db->query($sql); + if ($resql) + { + $out = ''; + + if (!empty($target)) + { + $sql = "SELECT c.id FROM ".MAIN_DB_PREFIX."c_type_fees as c WHERE c.code = 'EX_KME' AND c.active = 1"; + $resql = $db->query($sql); + if ($resql) + { + if ($db->num_rows($resql) > 0) + { dol_buildpath($path); + $obj = $db->fetch_object($resql); + $out.= ''; + } + } + } + } + else + { + dol_print_error($db); + } + + return $out; + } + + /** + * Return HTML to show the select ranges of expense range + * + * @param string $selected preselected category + * @param string $htmlname name of HTML select list + * @param integer $useempty 1=Add empty line + * @return string + */ + function selectExpenseRanges($selected='', $htmlname='fk_range', $useempty=0) + { + global $db,$conf,$langs; + + $sql = 'SELECT rowid, `range` FROM '.MAIN_DB_PREFIX.'c_exp_tax_range'; + $sql.= ' WHERE entity = '.$conf->entity.' AND active = 1'; + + $resql = $db->query($sql); + if ($resql) + { + $out = ''; + } + else + { + dol_print_error($db); + } + + return $out; + } + + /** + * Return HTML to show a select of expense + * + * @param string $selected preselected category + * @param string $htmlname name of HTML select list + * @param integer $useempty 1=Add empty choice + * @param integer $allchoice 1=Add all choice + * @param integer $useid 0=use 'code' as key, 1=use 'id' as key + * @return string + */ + function selectExpense($selected='', $htmlname='fk_c_type_fees', $useempty=0, $allchoice=1, $useid=0) + { + global $db,$langs; + + $sql = 'SELECT id, code, label FROM '.MAIN_DB_PREFIX.'c_type_fees'; + $sql.= ' WHERE active = 1'; + + $resql = $db->query($sql); + if ($resql) + { + $out = ''; + } + else + { + dol_print_error($db); + } + + return $out; + } + } diff --git a/htdocs/core/lib/expensereport.lib.php b/htdocs/core/lib/expensereport.lib.php index a5f19174a84..1efdc73f247 100644 --- a/htdocs/core/lib/expensereport.lib.php +++ b/htdocs/core/lib/expensereport.lib.php @@ -132,6 +132,22 @@ function expensereport_admin_prepare_head() $head[$h][2] = 'expensereport'; $h++; + if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) + { + $head[$h][0] = DOL_URL_ROOT."/admin/expensereport_ik.php"; + $head[$h][1] = $langs->trans("ExpenseReportsIk"); + $head[$h][2] = 'expenseik'; + $h++; + } + + if (!empty($conf->global->MAIN_USE_EXPENSE_RULE)) + { + $head[$h][0] = DOL_URL_ROOT."/admin/expensereport_rules.php"; + $head[$h][1] = $langs->trans("ExpenseReportsRules"); + $head[$h][2] = 'expenserules'; + $h++; + } + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 49bcc265050..b1d30f38949 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6383,3 +6383,43 @@ function dol_mimetype($file,$default='application/octet-stream',$mode=0) return $mime; } +/** + * Return value from dictionary + * + * @param string $tablename name of dictionary + * @param string $field the value to return + * @param int $id id of line + * @param bool $checkentity add filter on entity + * @param string $rowidfield name of the column rowid + */ +function getDictvalue($tablename, $field, $id, $checkentity=false, $rowidfield='rowid') +{ + global $dictvalues,$db,$langs; + + if (!isset($dictvalues[$tablename])) + { + $dictvalues[$tablename] = array(); + $sql = 'SELECT * FROM '.$tablename.' WHERE 1'; + if ($checkentity) $sql.= ' entity IN (0,'.getEntity('').')'; + + $resql = $db->query($sql); + if ($resql) + { + while ($obj = $db->fetch_object($resql)) + { + $dictvalues[$tablename][$obj->{$rowidfield}] = $obj; + } + } + else + { + dol_print_error($db); + } + } + + if (!empty($dictvalues[$tablename][$id])) return $dictvalues[$tablename][$id]->{$field}; // Found + else // Not found + { + if ($id > 0) return $id; + return ''; + } +} \ No newline at end of file diff --git a/htdocs/expensereport/ajax/ajaxik.php b/htdocs/expensereport/ajax/ajaxik.php new file mode 100644 index 00000000000..e1856f438b0 --- /dev/null +++ b/htdocs/expensereport/ajax/ajaxik.php @@ -0,0 +1,76 @@ + + * Copyright (C) 2017 Pierre-Henry Favre + * + * 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/expensereport/ajax/ajaxprojet.php + * \ingroup expensereport + * \brief File to return Ajax response on third parties request + */ + +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); + +$res=0; +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; +require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_ik.class.php'; + +$langs->load('errors'); +$langs->load('trips'); + +/* + * View + */ + +top_httphead(); + + +dol_syslog(join(',',$_POST)); + +$fk_expense = GETPOST('fk_expense'); +$fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat'); + + +if (empty($fk_expense) || $fk_expense < 0) echo json_encode(array('error' => $langs->transnoentitiesnoconv('ErrorBadValueForParameter', $fk_expense, 'fk_expense'))); +elseif (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) echo json_encode(array('error' => $langs->transnoentitiesnoconv('ErrorBadValueForParameter', $fk_c_exp_tax_cat, 'fk_c_exp_tax_cat'))); +else +{ + // @see ndfp.class.php:3576 (method: compute_total_km) + $expense = new ExpenseReport($db); + if ($expense->fetch($fk_expense) <= 0) echo json_encode(array('error' => $langs->transnoentitiesnoconv('ErrorRecordNotFound'), 'fk_expense' => $fk_expense)); + else + { + $userauthor = new User($db); + if ($userauthor->fetch($expense->fk_user_author) <= 0) echo json_encode(array('error' => $langs->transnoentitiesnoconv('ErrorRecordNotFound'), 'fk_user_author' => $expense->fk_user_author)); + else + { + $range = ExpenseReportIk::getRangeByUser($userauthor, $fk_c_exp_tax_cat); + + if (empty($range)) echo json_encode(array('error' => $langs->transnoentitiesnoconv('ErrorRecordNotFound'), 'range' => $range)); + else + { + $offset = price($range->offset, 0, $langs, 1, -1, -1, $conf->currency); + echo json_encode(array('up' => $range->coef, 'offset' => $range->offset, 'title' => $langs->transnoentitiesnoconv('ExpenseRangeOffset', $offset), 'comment' => 'offset should be apply on addline or updateline')); + } + } + } +} diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index c4aa6caccd8..4201c6ef865 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1058,31 +1058,18 @@ if (empty($reshook)) if ($action == "addline" && $user->rights->expensereport->creer) { $error = 0; - - $db->begin(); - - $object_ligne = new ExpenseReportLine($db); - - $vatrate = GETPOST('vatrate'); - $object_ligne->comments = GETPOST('comments'); + + // if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary. + if (empty($vatrate)) $vatrate = "0.000"; + $vatrate = price2num($vatrate); + + $value_unit=price2num(GETPOST('value_unit'),'MU'); + $fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat'); + $qty = GETPOST('qty','int'); if (empty($qty)) $qty=1; - $object_ligne->qty = $qty; - - $up=price2num(GETPOST('value_unit'),'MU'); - $object_ligne->value_unit = $up; - - $object_ligne->date = $date; - - $object_ligne->fk_c_type_fees = GETPOST('fk_c_type_fees'); - - // if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary. - if (empty($vatrate)) $vatrate = "0.000"; - $object_ligne->vatrate = price2num($vatrate); - - $object_ligne->fk_projet = $fk_projet; - - if (! GETPOST('fk_c_type_fees') > 0) + + if (! $fk_c_type_fees > 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors'); @@ -1107,44 +1094,54 @@ if (empty($reshook)) }*/ // Si aucune date n'est rentrée - if (empty($object_ligne->date) || $object_ligne->date=="--") + if (empty($date) || $date=="--") { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors'); } // Si aucun prix n'est rentré - if($object_ligne->value_unit==0) + if($value_unit==0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PriceUTTC")), null, 'errors'); } - + // S'il y'a eu au moins une erreur if (! $error) { - $object_ligne->fk_expensereport = $_POST['fk_expensereport']; - $type = 0; // TODO What if service ? - $seller = ''; // seller is unknown - $tmp = calcul_price_total($qty, $up, 0, $vatrate, 0, 0, 0, 'TTC', 0, $type, $seller); - $object_ligne->vatrate = price2num($vatrate); - $object_ligne->total_ttc = $tmp[2]; - $object_ligne->total_ht = $tmp[0]; - $object_ligne->total_tva = $tmp[1]; + // Insert line + $result = $object->addline($qty,$value_unit,$fk_c_type_fees,$vatrate,$date,$comments,$fk_projet,$fk_c_exp_tax_cat,$type); + if ($result > 0) { + $ret = $object->fetch($object->id); // Reload to get new records - $result = $object_ligne->insert(); - if ($result > 0) - { - $db->commit(); - header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id); - exit; - } - else - { - dol_print_error($db,$object->error); - $db->rollback(); - } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + $newlang = GETPOST('lang_id', 'alpha'); + if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + unset($qty); + unset($value_unit); + unset($vatrate); + unset($comments); + unset($fk_c_type_fees); + unset($fk_projet); + + unset($date); + + } else { + setEventMessages($object->error, $object->errors, 'errors'); + } } $action=''; @@ -1200,6 +1197,7 @@ if (empty($reshook)) $rowid = $_POST['rowid']; $type_fees_id = GETPOST('fk_c_type_fees'); + $fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat'); $projet_id = $fk_projet; $comments = GETPOST('comments'); $qty = GETPOST('qty'); @@ -1226,7 +1224,7 @@ if (empty($reshook)) if (! $error) { // TODO Use update method of ExpenseReportLine - $result = $object->updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $id); + $result = $object->updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $id, $fk_c_exp_tax_cat); if ($result >= 0) { if ($result > 0) @@ -1922,17 +1920,6 @@ else print '

'; - // Fetch Lines of current expense report - $sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_projet, fde.date,'; - $sql.= ' fde.tva_tx as vatrate, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc,'; - $sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,'; - $sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det as fde'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as pjt ON fde.fk_projet=pjt.rowid'; - $sql.= ' WHERE fde.fk_expensereport = '.$object->id; - $sql.= ' ORDER BY fde.date ASC'; - print '
'; $actiontouse='updateligne'; @@ -1947,158 +1934,160 @@ else print '
'; print ''; - $resql = $db->query($sql); - if ($resql) + if (!empty($object->lines)) { - $num_lignes = $db->num_rows($resql); $i = 0;$total = 0; - if ($num_lignes) + print ''; + print ''; + print ''; + if (! empty($conf->projet->enabled)) print ''; + if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if ($action != 'editline') { - print ''; - print ''; - print ''; - if (! empty($conf->projet->enabled)) print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - if ($action != 'editline') - { - print ''; - print ''; - } - // Ajout des boutons de modification/suppression - if (($object->fk_statut < 2 || $object->fk_statut == 99) && $user->rights->expensereport->creer) - { - print ''; - } - print ''; + print ''; + print ''; + } + // Ajout des boutons de modification/suppression + if (($object->fk_statut < 2 || $object->fk_statut == 99) && $user->rights->expensereport->creer) + { + print ''; + } + print ''; - while ($i < $num_lignes) - { - $piece_comptable = $i + 1; - $objp = $db->fetch_object($resql); + foreach ($object->lines as &$line) + { + $piece_comptable = $i + 1; - if ($action != 'editline' || $objp->rowid != GETPOST('rowid')) + if ($action != 'editline' || $line->rowid != GETPOST('rowid')) + { + print ''; + + print ''; + print ''; + if (! empty($conf->projet->enabled)) { + print ''; + } + if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) + { + print ''; + } + // print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + if ($action != 'editline') + { + print ''; + print ''; + } + + // Ajout des boutons de modification/suppression + if (($object->fk_statut < 2 || $object->fk_statut == 99) && $user->rights->expensereport->creer) + { + print ''; + } + + print ''; + } + + if ($action == 'editline' && $line->rowid == GETPOST('rowid')) + { print ''; - print ''; - print ''; + print ''; + + // Select date + print ''; + + // Select project if (! empty($conf->projet->enabled)) { - print ''; + print ''; } - // print ''; - print ''; - print ''; - print ''; - print ''; - print ''; + + if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) + { + print ''; + } + + // Select type + print ''; + + // Add comments + print ''; + + // VAT + print ''; + + // Unit price + print ''; + + // Quantity + print ''; if ($action != 'editline') { - print ''; - print ''; + print ''; + print ''; } - // Ajout des boutons de modification/suppression - if (($object->fk_statut < 2 || $object->fk_statut == 99) && $user->rights->expensereport->creer) - { - print ''; - } - - print ''; - } - - if ($action == 'editline' && $objp->rowid == GETPOST('rowid')) - { - print ''; - - print ''; - - // Select date - print ''; - - // Select project - if (! empty($conf->projet->enabled)) - { - print ''; - } - - // Select type - print ''; - - // Add comments - print ''; - - // VAT - print ''; - - // Unit price - print ''; - - // Quantity - print ''; - - if ($action != 'editline') - { - print ''; - print ''; - } - - print ''; - } - - $i++; + print ''; } - $db->free($resql); - } - else - { - /* print '
'.$langs->trans('Piece').''.$langs->trans('Date').''.$langs->trans('Project').''.$langs->trans('CarCategory').''.$langs->trans('Type').''.$langs->trans('Description').''.$langs->trans('VAT').''.$langs->trans('PriceUTTC').''.$langs->trans('Qty').'
'.$langs->trans('Piece').''.$langs->trans('Date').''.$langs->trans('Project').''.$langs->trans('Type').''.$langs->trans('Description').''.$langs->trans('VAT').''.$langs->trans('PriceUTTC').''.$langs->trans('Qty').''.$langs->trans('AmountHT').''.$langs->trans('AmountTTC').'
'.$langs->trans('AmountHT').''.$langs->trans('AmountTTC').'
'; + print img_picto($langs->trans("Document"), "object_generic"); + print ' '.$piece_comptable.''.dol_print_date($db->jdate($line->date), 'day').''; + if ($line->fk_projet > 0) + { + $projecttmp->id=$line->fk_projet; + $projecttmp->ref=$line->projet_ref; + print $projecttmp->getNomUrl(1); + } + print ''; + print dol_getIdFromCode($db, $line->fk_c_exp_tax_cat, 'c_exp_tax_cat', 'rowid', 'label'); + print ''.$langs->trans("TF_".strtoupper(empty($objp->type_fees_libelle)?'OTHER':$objp->type_fees_libelle)).''.($langs->trans(($line->type_fees_code)) == $line->type_fees_code ? $line->type_fees_libelle : $langs->trans(($line->type_fees_code))).''.$line->comments.''.vatrate($line->vatrate,true).''.price($line->value_unit).''.$line->qty.''.price($line->total_ht).''.price($line->total_ttc).''; + + print 'rowid.'#'.$line->rowid.'">'; + print img_edit(); + print '   '; + print 'rowid.'">'; + print img_delete(); + print ''; + + print '
'; - print img_picto($langs->trans("Document"), "object_generic"); - print ' '.$piece_comptable.''.dol_print_date($db->jdate($objp->date), 'day').''; + $form->select_date($line->date,'date'); + print ''; - if ($objp->projet_id > 0) - { - $projecttmp->id=$objp->projet_id; - $projecttmp->ref=$objp->projet_ref; - print $projecttmp->getNomUrl(1); - } - print ''; + $formproject->select_projects(-1, $line->fk_projet,'fk_projet', 0, 0, 1, 1); + print ''.$langs->trans("TF_".strtoupper(empty($objp->type_fees_libelle)?'OTHER':$objp->type_fees_libelle)).''.($langs->trans(($objp->type_fees_code)) == $objp->type_fees_code ? $objp->type_fees_libelle : $langs->trans(($objp->type_fees_code))).''.$objp->comments.''.vatrate($objp->vatrate,true).''.price($objp->value_unit).''.$objp->qty.''; + $params = array('fk_expense' => $object->id, 'fk_expense_det' => $line->rowid, 'date' => $line->dates); + print $form->selectExpenseCategories($line->fk_c_exp_tax_cat, 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', $userauthor->default_c_exp_tax_cat, $params); + print ''; + select_type_fees_id($line->fk_c_type_fees,'fk_c_type_fees'); + print ''; + print ''; + print ''; + print $form->load_tva('vatrate', (isset($_POST["vatrate"])?$_POST["vatrate"]:$line->vatrate), $mysoc, ''); + print ''; + print ''; + print ''; + print ''; + print ''.price($objp->total_ht).''.price($objp->total_ttc).''.$langs->trans('AmountHT').''.$langs->trans('AmountTTC').''; - - print 'rowid.'#'.$objp->rowid.'">'; - print img_edit(); - print '   '; - print 'rowid.'">'; - print img_delete(); - print ''; - - print '
'; - $form->select_date($objp->date,'date'); - print ''; - $formproject->select_projects(-1, $objp->fk_projet,'fk_projet', 0, 0, 1, 1); - print ''; - select_type_fees_id($objp->type_fees_code,'fk_c_type_fees'); - print ''; - print ''; - print ''; - print $form->load_tva('vatrate', (isset($_POST["vatrate"])?$_POST["vatrate"]:$objp->vatrate), $mysoc, ''); - print ''; - print ''; - print ''; - print ''; - print ''.$langs->trans('AmountHT').''.$langs->trans('AmountTTC').''; - print ''; - print ''; - print '
'; - print '
'; + print ''; + print ''; + print '
'; + print '
'; - print ''; - print '
'.$langs->trans("AucuneLigne").'
';*/ + $i++; } + //print '
'; // Add a line @@ -2108,6 +2097,7 @@ else print ''; print ''.$langs->trans('Date').''; if (! empty($conf->projet->enabled)) print ''.$langs->trans('Project').''; + if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) print ''.$langs->trans('CarCategory').''; print ''.$langs->trans('Type').''; print ''.$langs->trans('Description').''; print ''.$langs->trans('VAT').''; @@ -2133,6 +2123,14 @@ else $formproject->select_projects(-1, $fk_projet, 'fk_projet', 0, 0, 1, 1); print ''; } + + if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) + { + print ''; + $params = array('fk_expense' => $object->id); + print $form->selectExpenseCategories('', 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', $userauthor->default_c_exp_tax_cat, $params); + print ''; + } // Select type print ''; @@ -2350,6 +2348,8 @@ if ($action != 'create' && $action != 'edit') print ''; } + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been } print ''; diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index ffef31cad8b..c948c1ebcce 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -24,6 +24,8 @@ * \brief File to manage Expense Reports */ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT .'/expensereport/class/expensereport_ik.class.php'; +require_once DOL_DOCUMENT_ROOT .'/expensereport/class/expensereport_rule.class.php'; /** * Class to manage Trips and Expenses @@ -91,9 +93,35 @@ class ExpenseReport extends CommonObject /* END ACTIONS */ + + /** + * Draft + */ + const STATUS_DRAFT = 0; + /** + * Validated (need to be paid) + */ + const STATUS_VALIDATED = 2; - /** + /** + * Classified approved + */ + const STATUS_APPROVED = 5; + + /** + * Classified refused + */ + const STATUS_REFUSED = 99; + + /** + * Classified paid. + */ + const STATUS_CLOSED = 6; + + + + /** * Constructor * * @param DoliDB $db Handler acces base de donnees @@ -911,7 +939,7 @@ class ExpenseReport extends CommonObject $this->lines=array(); $sql = ' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date,'; - $sql.= ' de.'.$this->fk_element.', de.fk_c_type_fees, de.fk_projet, de.tva_tx,'; + $sql.= ' de.'.$this->fk_element.', de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet, de.tva_tx,'; $sql.= ' de.total_ht, de.total_tva, de.total_ttc,'; $sql.= ' ctf.code as code_type_fees, ctf.label as libelle_type_fees,'; $sql.= ' p.ref as ref_projet, p.title as title_projet'; @@ -933,13 +961,16 @@ class ExpenseReport extends CommonObject $deplig = new ExpenseReportLine($this->db); $deplig->rowid = $objp->rowid; + $deplig->id = $objp->id; $deplig->comments = $objp->comments; $deplig->qty = $objp->qty; $deplig->value_unit = $objp->value_unit; $deplig->date = $objp->date; + $deplig->dates = $this->db->jdate($objp->date); $deplig->fk_expensereport = $objp->fk_expensereport; $deplig->fk_c_type_fees = $objp->fk_c_type_fees; + $deplig->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat; $deplig->fk_projet = $objp->fk_projet; $deplig->total_ht = $objp->total_ht; @@ -1570,7 +1601,244 @@ class ExpenseReport extends CommonObject endif; } + /** + * addline + * + * @param real $qty Qty + * @param double $up Value init + * @param int $fk_c_type_fees Type payment + * @param double $vatrate Vat rate + * @param string $date Date + * @param string $comments Description + * @param int $fk_project Project id + * @param int $fk_c_exp_tax_cat Car category id + * @param int $type Type line + * @return int <0 if KO, >0 if OK + */ + function addline($qty=0, $up=0, $fk_c_type_fees=0, $vatrate=0, $date='', $comments='', $fk_project=0, $fk_c_exp_tax_cat=0, $type=0) + { + global $conf,$langs; + dol_syslog(get_class($this)."::addline qty=$qty, up=$up, fk_c_type_fees=$fk_c_type_fees, vatrate=$vatrate, date=$date, fk_project=$fk_project, type=$type, comments=$comments", LOG_DEBUG); + + if (empty($qty)) $qty = 0; + if (empty($fk_c_type_fees) || $fk_c_type_fees < 0) $fk_c_type_fees = 0; + if (empty($fk_c_exp_tax_cat) || $fk_c_exp_tax_cat < 0) $fk_c_exp_tax_cat = 0; + if (empty($vatrate) || $vatrate < 0) $vatrate = 0; + if (empty($date)) $date = ''; + if (empty($fk_project)) $fk_project = 0; + + $qty = price2num($qty); + $vatrate = price2num($vatrate); + $up = price2num($up); + + if ($this->fk_statut == self::STATUS_DRAFT) + { + $this->db->begin(); + + $this->line = new ExpenseReportLine($this->db); + + $seller = ''; // seller is unknown + $tmp = calcul_price_total($qty, $up, 0, $vatrate, 0, 0, 0, 'TTC', 0, $type, $seller); + + $this->line->value_unit = $up; + $this->line->vatrate = price2num($vatrate); + $this->line->total_ttc = $tmp[2]; + $this->line->total_ht = $tmp[0]; + $this->line->total_tva = $tmp[1]; + + $this->line->fk_expensereport = $this->id; + $this->line->qty = $qty; + $this->line->date = $date; + $this->line->fk_c_type_fees = $fk_c_type_fees; + $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat; + $this->line->comments = $comments; + $this->line->fk_projet = $fk_project; + + $this->applyOffset(); + $this->checkRules($type, $seller); + + $result=$this->line->insert(0, true); + if ($result > 0) + { + $result=$this->update_price(); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + if ($result > 0) + { + $this->db->commit(); + return $this->line->rowid; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->line->error; + dol_syslog(get_class($this)."::addline error=".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } + else + { + dol_syslog(get_class($this)."::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR); + $this->error = 'ErrorExpenseNotDraft'; + return -3; + } + + + } + + /** + * Check constraint of rules and update price if needed + * + * @param int $type type of line + * @param string $seller seller, but actually he is unknown + * @return true or false + */ + function checkRules($type=0, $seller='') + { + global $user,$conf,$db,$langs; + + $langs->load('trips'); + + if (empty($conf->global->MAIN_USE_EXPENSE_RULE)) return true; // if don't use rules + + $rulestocheck = ExpenseReportRule::getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author); + + $violation = 0; + $rule_warning_message_tab = array(); + + $current_total_ttc = $this->line->total_ttc; + $new_current_total_ttc = $this->line->total_ttc; + + // check if one is violated + foreach ($rulestocheck as $rule) + { + if (in_array($rule->code_expense_rules_type, array('EX_DAY', 'EX_MON', 'EX_YEA'))) $amount_to_test = $this->line->getExpAmount($rule, $this->fk_user_author, $rule->code_expense_rules_type); + else $amount_to_test = $current_total_ttc; // EX_EXP + + $amount_to_test = $amount_to_test - $current_total_ttc + $new_current_total_ttc; // if amount as been modified by a previous rule + + if ($amount_to_test > $rule->amount) + { + $violation++; + + if ($rule->restrictive) + { + $this->error = 'ExpenseReportConstraintViolationError'; + $this->errors[] = $this->error; + + $new_current_total_ttc -= $amount_to_test - $rule->amount; // ex, entered 16€, limit 12€, subtracts 4€; + $rule_warning_message_tab[] = $langs->trans('ExpenseReportConstraintViolationError', $rule->id, price($amount_to_test,0,$langs,1,-1,-1,$conf->currency), price($rule->amount,0,$langs,1,-1,-1,$conf->currency), $langs->trans('by'.$rule->code_expense_rules_type, price($new_current_total_ttc,0,$langs,1,-1,-1,$conf->currency))); + } + else + { + $this->error = 'ExpenseReportConstraintViolationWarning'; + $this->errors[] = $this->error; + + $rule_warning_message_tab[] = $langs->trans('ExpenseReportConstraintViolationWarning', $rule->id, price($amount_to_test,0,$langs,1,-1,-1,$conf->currency), price($rule->amount,0,$langs,1,-1,-1,$conf->currency), $langs->trans('nolimitby'.$rule->code_expense_rules_type)); + } + + // No break, we sould test if another rule is violated + } + } + + $this->line->rule_warning_message = implode('\n', $rule_warning_message_tab); + + if ($violation > 0) + { + $tmp = calcul_price_total($this->line->qty, $new_current_total_ttc/$this->line->qty, 0, $this->line->vatrate, 0, 0, 0, 'TTC', 0, $type, $seller); + + $this->line->value_unit = $tmp[5]; + $this->line->total_ttc = $tmp[2]; + $this->line->total_ht = $tmp[0]; + $this->line->total_tva = $tmp[1]; + + return false; + } + else return true; + } + + /** + * Method to apply the offset if needed + * + * @return boolean true=applied, false=not applied + */ + function applyOffset() + { + global $conf; + + if (empty($conf->global->MAIN_USE_EXPENSE_IK)) return false; + + $userauthor = new User($this->db); + if ($userauthor->fetch($this->fk_user_author) <= 0) + { + $this->error = 'ErrorCantFetchUser'; + $this->errors[] = 'ErrorCantFetchUser'; + return false; + } + + $range = ExpenseReportIk::getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat); + + if (empty($range)) + { + $this->error = 'ErrorNoRangeAvailable'; + $this->errors[] = 'ErrorNoRangeAvailable'; + return false; + } + + if (!empty($conf->global->MAIN_EXPENSE_APPLY_ENTIRE_OFFSET)) $offset = $range->offset; + else $offset = $range->offset / 12; // The amount of offset is a global value for the year + + // Test if offset has been applied for the current month + if (!$this->offsetAlreadyGiven()) + { + $new_up = $range->coef + ($offset / $this->line->qty); + $tmp = calcul_price_total($this->line->qty, $new_up, 0, $this->line->vatrate, 0, 0, 0, 'TTC', 0, $type, $seller); + + $this->line->value_unit = $tmp[5]; + $this->line->total_ttc = $tmp[2]; + $this->line->total_ht = $tmp[0]; + $this->line->total_tva = $tmp[1]; + + return true; + } + + return false; + } + + /** + * If the sql find any rows then the offset is already given (offset is applied at the first expense report line) + * + * @return bool + */ + function offsetAlreadyGiven() + { + $sql = 'SELECT e.rowid FROM '.MAIN_DB_PREFIX.'expensereport e'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'expensereport_det d ON (e.rowid = d.fk_expensereport)'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees f ON (d.fk_c_type_fees = f.id AND f.code = "EX_KME")'; + $sql.= ' WHERE e.fk_user_author = '.(int) $this->fk_user_author; + $sql.= ' AND YEAR(d.date) = "'.dol_print_date($this->line->date, '%Y').'" AND MONTH(d.date) = "'.dol_print_date($this->line->date, '%m').'"'; + if (!empty($this->line->id)) $sql.= ' AND d.rowid <> '.$this->line->id; + + dol_syslog(get_class($this)."::offsetAlreadyGiven sql=".$sql); + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + if ($num > 0) return true; + } + else + { + dol_print_error($this->db); + } + + return false; + } + /** * updateline * @@ -1583,9 +1851,10 @@ class ExpenseReport extends CommonObject * @param double $value_unit Value init * @param int $date Date * @param int $expensereport_id Expense report id + * @param int $fk_c_exp_tax_cat id of category of car * @return int <0 if KO, >0 if OK */ - function updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $expensereport_id) + function updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $expensereport_id, $fk_c_exp_tax_cat=0) { global $user; @@ -1603,21 +1872,23 @@ class ExpenseReport extends CommonObject $total_tva = price2num($total_ttc - $total_ht, 'MT'); // fin calculs - $ligne = new ExpenseReportLine($this->db); - $ligne->comments = $comments; - $ligne->qty = $qty; - $ligne->value_unit = $value_unit; - $ligne->date = $date; + $this->line = new ExpenseReportLine($this->db); + $this->line->comments = $comments; + $this->line->qty = $qty; + $this->line->value_unit = $value_unit; + $this->line->date = $date; - $ligne->fk_expensereport= $expensereport_id; - $ligne->fk_c_type_fees = $type_fees_id; - $ligne->fk_projet = $projet_id; + $this->line->fk_expensereport= $expensereport_id; + $this->line->fk_c_type_fees = $type_fees_id; + $this->line->fk_c_exp_tax_cat = $fk_c_exp_tax_cat; + $this->line->fk_projet = $projet_id; - $ligne->total_ht = $total_ht; - $ligne->total_tva = $total_tva; - $ligne->total_ttc = $total_ttc; - $ligne->vatrate = price2num($vatrate); - $ligne->rowid = $rowid; + $this->line->total_ht = $total_ht; + $this->line->total_tva = $total_tva; + $this->line->total_ttc = $total_ttc; + $this->line->vatrate = price2num($vatrate); + $this->line->rowid = $rowid; + $this->line->id = $rowid; // Select des infos sur le type fees $sql = "SELECT c.code as code_type_fees, c.label as libelle_type_fees"; @@ -1625,8 +1896,8 @@ class ExpenseReport extends CommonObject $sql.= " WHERE c.id = ".$type_fees_id; $result = $this->db->query($sql); $objp_fees = $this->db->fetch_object($result); - $ligne->type_fees_code = $objp_fees->code_type_fees; - $ligne->type_fees_libelle = $objp_fees->libelle_type_fees; + $this->line->type_fees_code = $objp_fees->code_type_fees; + $this->line->type_fees_libelle = $objp_fees->libelle_type_fees; // Select des informations du projet $sql = "SELECT p.ref as ref_projet, p.title as title_projet"; @@ -1636,10 +1907,13 @@ class ExpenseReport extends CommonObject if ($result) { $objp_projet = $this->db->fetch_object($result); } - $ligne->projet_ref = $objp_projet->ref_projet; - $ligne->projet_title = $objp_projet->title_projet; + $this->line->projet_ref = $objp_projet->ref_projet; + $this->line->projet_title = $objp_projet->title_projet; - $result = $ligne->update($user); + $this->applyOffset(); + $this->checkRules(); + + $result = $this->line->update($user); if ($result > 0) { $this->db->commit(); @@ -1647,8 +1921,8 @@ class ExpenseReport extends CommonObject } else { - $this->error=$ligne->error; - $this->errors=$ligne->errors; + $this->error=$this->line->error; + $this->errors=$this->line->errors; $this->db->rollback(); return -2; } @@ -1992,6 +2266,7 @@ class ExpenseReportLine var $date; var $fk_c_type_fees; + var $fk_c_exp_tax_cat; var $fk_projet; var $fk_expensereport; @@ -2024,7 +2299,7 @@ class ExpenseReportLine */ function fetch($rowid) { - $sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_projet, fde.date,'; + $sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_c_exp_tax_cat, fde.fk_projet, fde.date,'; $sql.= ' fde.tva_tx as vatrate, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc,'; $sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,'; $sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref'; @@ -2046,8 +2321,10 @@ class ExpenseReportLine $this->comments = $objp->comments; $this->qty = $objp->qty; $this->date = $objp->date; + $this->dates = $this->db->jdate($objp->date); $this->value_unit = $objp->value_unit; $this->fk_c_type_fees = $objp->fk_c_type_fees; + $this->fk_c_exp_tax_cat = $objp->fk_c_exp_tax_cat; $this->fk_projet = $objp->fk_projet; $this->type_fees_code = $objp->type_fees_code; $this->type_fees_libelle = $objp->type_fees_libelle; @@ -2068,9 +2345,10 @@ class ExpenseReportLine * insert * * @param int $notrigger 1=No trigger + * @param bool $fromaddline false=keep default behavior, true=exclude the update_price() of parent object * @return int <0 if KO, >0 if OK */ - function insert($notrigger=0) + function insert($notrigger=0,$fromaddline=false) { global $langs,$user,$conf; @@ -2083,12 +2361,13 @@ class ExpenseReportLine if (!$this->value_unit_HT) $this->value_unit_HT=0; $this->qty = price2num($this->qty); $this->vatrate = price2num($this->vatrate); - + if (empty($this->fk_c_exp_tax_cat)) $this->fk_c_exp_tax_cat = 0; + $this->db->begin(); $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'expensereport_det'; $sql.= ' (fk_expensereport, fk_c_type_fees, fk_projet,'; - $sql.= ' tva_tx, comments, qty, value_unit, total_ht, total_tva, total_ttc, date)'; + $sql.= ' tva_tx, comments, qty, value_unit, total_ht, total_tva, total_ttc, date, rule_warning_message, fk_c_exp_tax_cat)'; $sql.= " VALUES (".$this->fk_expensereport.","; $sql.= " ".$this->fk_c_type_fees.","; $sql.= " ".($this->fk_projet>0?$this->fk_projet:'null').","; @@ -2099,7 +2378,9 @@ class ExpenseReportLine $sql.= " ".$this->total_ht.","; $sql.= " ".$this->total_tva.","; $sql.= " ".$this->total_ttc.","; - $sql.= "'".$this->db->idate($this->date)."'"; + $sql.= "'".$this->db->idate($this->date)."',"; + $sql.= " '".$this->db->escape($this->rule_warning_message)."',"; + $sql.= " ".$this->fk_c_exp_tax_cat; $sql.= ")"; dol_syslog("ExpenseReportLine::insert sql=".$sql); @@ -2109,16 +2390,23 @@ class ExpenseReportLine { $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'expensereport_det'); - $tmpparent=new ExpenseReport($this->db); - $tmpparent->fetch($this->fk_expensereport); - $result = $tmpparent->update_price(); - if ($result < 0) - { - $error++; - $this->error = $tmpparent->error; - $this->errors = $tmpparent->errors; - } + if (! $fromaddline) + { + $tmpparent=new ExpenseReport($this->db); + $tmpparent->fetch($this->fk_expensereport); + $result = $tmpparent->update_price(); + if ($result < 0) + { + $error++; + $this->error = $tmpparent->error; + $this->errors = $tmpparent->errors; + } + } } + else + { + $error++; + } if (! $error) { @@ -2133,7 +2421,50 @@ class ExpenseReportLine return -2; } } + + /** + * Function to get total amount in expense reports for a same rule + * + * @param ExpenseReportRule $rule object rule to check + * @param int $fk_user user author id + * @param string $mode day|EX_DAY / month|EX_MON / year|EX_YEA to get amount + * @return amount + */ + public function getExpAmount(ExpenseReportRule $rule, $fk_user, $mode='day') + { + $amount = 0; + + $sql = 'SELECT SUM(d.total_ttc) as total_amount'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'expensereport_det d'; + $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'expensereport e ON (d.fk_expensereport = e.rowid)'; + $sql .= ' WHERE e.fk_user_author = '.$fk_user; + if (!empty($this->id)) $sql.= ' AND d.rowid <> '.$this->id; + $sql .= ' AND d.fk_c_type_fees = '.$rule->fk_c_type_fees; + if ($mode == 'day' || $mode == 'EX_DAY') $sql .= ' AND d.date = \''.dol_print_date($this->date, '%Y-%m-%d').'\''; + elseif ($mode == 'mon' || $mode == 'EX_MON') $sql .= ' AND DATE_FORMAT(d.date, \'%Y-%m\') = \''.dol_print_date($this->date, '%Y-%m').'\''; + elseif ($mode == 'year' || $mode == 'EX_YEA') $sql .= ' AND DATE_FORMAT(d.date, \'%Y\') = \''.dol_print_date($this->date, '%Y').'\''; + + dol_syslog('ExpenseReportLine::getExpAmountByDay sql='.$sql); + + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + if ($num > 0) + { + $obj = $this->db->fetch_object($resql); + $amount = (double) $obj->total_amount; + } + } + else + { + dol_print_error($this->db); + } + + return $amount + $this->total_ttc; + } + /** * update * @@ -2150,6 +2481,7 @@ class ExpenseReportLine $this->comments=trim($this->comments); $this->vatrate = price2num($this->vatrate); $this->value_unit = price2num($this->value_unit); + if (empty($this->fk_c_exp_tax_cat)) $this->fk_c_exp_tax_cat = 0; $this->db->begin(); @@ -2163,6 +2495,8 @@ class ExpenseReportLine $sql.= ",total_tva=".$this->total_tva.""; $sql.= ",total_ttc=".$this->total_ttc.""; $sql.= ",tva_tx=".$this->vatrate; + $sql.= ",rule_warning_message='".$this->db->escape($this->rule_warning_message)."'"; + $sql.= ",fk_c_exp_tax_cat=".$this->fk_c_exp_tax_cat; if ($this->fk_c_type_fees) $sql.= ",fk_c_type_fees=".$this->fk_c_type_fees; else $sql.= ",fk_c_type_fees=null"; if ($this->fk_projet) $sql.= ",fk_projet=".$this->fk_projet; diff --git a/htdocs/expensereport/class/expensereport_ik.class.php b/htdocs/expensereport/class/expensereport_ik.class.php new file mode 100644 index 00000000000..775837692eb --- /dev/null +++ b/htdocs/expensereport/class/expensereport_ik.class.php @@ -0,0 +1,248 @@ + + * Copyright (C) 2017 Pierre-Henry Favre + * + * 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/expensereport/class/expensereport_ik.class.php + * \ingroup expenseik + * \brief File of class to manage expense ik + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/coreobject.class.php'; + +/** + * Class to manage inventories + */ +class ExpenseReportIk extends CoreObject +{ + public $element='expenseik'; + public $table_element='expensereport_ik'; + public $fk_element='fk_expense_ik'; + + /** + * c_exp_tax_cat Id + * @var int + */ + public $fk_cat; + + /** + * c_exp_tax_range id + * @var int + */ + public $fk_range; + + /** + * Coef + * @var double + */ + public $coef; + + /** + * Offset + * @var double + */ + public $offset; + + /** + * Attribute object linked with database + * @var array + */ + protected $fields=array( + 'fk_cat'=>array('type'=>'integer','index'=>true) + ,'fk_range'=>array('type'=>'integer','index'=>true) + ,'coef'=>array('type'=>'double') + ,'offset'=>array('type'=>'double') + ); + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct(DoliDB &$db) + { + global $conf; + + parent::__construct($db); + parent::init(); + + $this->errors = array(); + } + + + /** + * Return expense categories in array + * + * @param int $mode 1=only active; 2=only inactive; other value return all + * @return array of category + */ + public static function getTaxCategories($mode=1) + { + global $db; + + $categories = array(); + + $sql = 'SELECT rowid, label, entity, active'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_cat'; + $sql.= ' WHERE entity IN (0,'. getEntity('').')'; + if ($mode == 1) $sql.= ' AND active = 1'; + elseif ($mode == 2) $sql.= 'AND active = 0'; + + dol_syslog(get_called_class().'::getTaxCategories sql='.$sql, LOG_DEBUG); + $resql = $db->query($sql); + if ($resql) + { + while ($obj = $db->fetch_object($resql)) + { + $categories[$obj->rowid] = $obj; + } + } + else + { + dol_print_error($db); + } + + return $categories; + } + + public static function getRangeByUser(User $userauthor, $fk_c_exp_tax_cat) + { + $default_range = (int) $userauthor->default_range; // if not defined, then 0 + $ranges = self::getRangesByCategory($fk_c_exp_tax_cat); + + // substract 1 because array start from 0 + if (empty($ranges) || !isset($ranges[$default_range-1])) return false; + else return $ranges[$default_range-1]; + } + + /** + * Return an array of ranges for a category + * + * @param int $fk_c_exp_tax_cat category id + * @param int $active active + * @return array + */ + public static function getRangesByCategory($fk_c_exp_tax_cat, $active=1) + { + global $db; + + $ranges = array(); + + $sql = 'SELECT r.rowid FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r'; + if ($active) $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_cat = c.rowid)'; + $sql.= ' WHERE r.fk_cat = '.$fk_c_exp_tax_cat; + if ($active) $sql.= ' AND r.active = 1 AND c.active = 1'; + $sql.= ' ORDER BY r.range'; + + dol_syslog(get_called_class().'::getRangesByCategory sql='.$sql, LOG_DEBUG); + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + if ($num > 0) + { + while ($obj = $db->fetch_object($resql)) + { + $object = new ExpenseReportIk($db); + $object->fetch($obj->rowid); + + $ranges[] = $object; + } + } + } + else + { + dol_print_error($db); + } + + return $ranges; + } + + /** + * Return an array of ranges grouped by category + * + * @return array + */ + public static function getAllRanges() + { + global $db; + + $ranges = array(); + + $sql = ' SELECT r.rowid, r.fk_cat, r.range, c.label, i.rowid as fk_expense_ik, r.active as range_active, c.active as cat_active'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r'; + $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_cat = c.rowid)'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'expensereport_ik i ON (r.rowid = i.fk_range)'; + $sql.= ' WHERE r.entity IN (0, '. getEntity('').')'; + $sql.= ' ORDER BY r.fk_cat, r.range'; + + dol_syslog(get_called_class().'::getAllRanges sql='.$sql, LOG_DEBUG); + $resql = $db->query($sql); + if ($resql) + { + while ($obj = $db->fetch_object($resql)) + { + $ik = new ExpenseReportIk($db); + if ($obj->fk_expense_ik > 0) $ik->fetch($obj->fk_expense_ik); + + $obj->ik = $ik; + + if (!isset($ranges[$obj->fk_cat])) $ranges[$obj->fk_cat] = array('label' => $obj->label, 'active' => $obj->cat_active, 'ranges' => array()); + $ranges[$obj->fk_cat]['ranges'][] = $obj; + } + } + else + { + dol_print_error($db); + } + + return $ranges; + } + + /** + * Return the max number of range by a category + * + * @param int $default_c_exp_tax_cat id + * @return int + */ + public static function getMaxRangeNumber($default_c_exp_tax_cat=0) + { + global $db,$conf; + + $sql = 'SELECT MAX(counted) as nbRange FROM ('; + $sql.= ' SELECT COUNT(*) as counted'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r'; + $sql.= ' WHERE r.entity IN (0, '.$conf->entity.')'; + if ($default_c_exp_tax_cat > 0) $sql .= ' AND r.fk_cat = '.$default_c_exp_tax_cat; + $sql.= ' GROUP BY r.fk_cat'; + $sql .= ') as counts'; + + dol_syslog(get_called_class().'::getMaxRangeNumber sql='.$sql, LOG_DEBUG); + $resql = $db->query($sql); + if ($resql) + { + $obj = $db->fetch_object($resql); + return $obj->nbRange; + } + else + { + dol_print_error($db); + } + + return 0; + } +} \ No newline at end of file diff --git a/htdocs/expensereport/class/expensereport_rule.class.php b/htdocs/expensereport/class/expensereport_rule.class.php new file mode 100644 index 00000000000..a8b43bb4479 --- /dev/null +++ b/htdocs/expensereport/class/expensereport_rule.class.php @@ -0,0 +1,236 @@ + + * Copyright (C) 2017 Pierre-Henry Favre + * + * 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/expensereport/class/expensereport_ik.class.php + * \ingroup expenseik + * \brief File of class to manage expense ik + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/coreobject.class.php'; + +/** + * Class to manage inventories + */ +class ExpenseReportRule extends CoreObject +{ + public $element='expenserule'; + public $table_element='expensereport_rules'; + public $fk_element='fk_expense_rule'; + + /** + * date start + * @var date + */ + public $dates; + + /** + * date end + * @var date + */ + public $datee; + + /** + * amount + * @var double + */ + public $amount; + + /** + * restrective + * @var int + */ + public $restrictive; + + /** + * rule for user + * @var int + */ + public $fk_user; + + /** + * rule for group + * @var int + */ + public $fk_usergroup; + + /** + * c_type_fees id + * @var int + */ + public $fk_c_type_fees; + + /** + * code type of expense report + * @var string + */ + public $code_expense_rules_type; + + + /** + * rule for all + * @var int + */ + public $is_for_all; + + /** + * entity + * @var int + */ + public $entity; + + + + /** + * Attribute object linked with database + * @var array + */ + protected $fields=array( + 'dates'=>array('type'=>'date') + ,'datee'=>array('type'=>'date') + ,'amount'=>array('type'=>'double') + ,'restrictive'=>array('type'=>'integer') + ,'fk_user'=>array('type'=>'integer') + ,'fk_usergroup'=>array('type'=>'integer') + ,'fk_c_type_fees'=>array('type'=>'integer') + ,'code_expense_rules_type'=>array('type'=>'string') + ,'is_for_all'=>array('type'=>'integer') + ,'entity'=>array('type'=>'integer') + ); + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct(DoliDB &$db) + { + global $conf; + + parent::__construct($db); + parent::init(); + + $this->errors = array(); + } + + /** + * Return all rules or filtered by something + * + * @param int $fk_c_type_fees type of expense + * @param date $date date of expense + * @param type $fk_user user of expense + * @return array \ExpenseReportRule + */ + public static function getAllRule($fk_c_type_fees='', $date='', $fk_user='') + { + global $db; + + $rules = array(); + $sql = 'SELECT er.rowid'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_rules er'; + $sql.= ' WHERE er.entity IN (0,'. getEntity('').')'; + if (!empty($fk_c_type_fees)) + { + $sql.= ' AND er.fk_c_type_fees IN (-1, '.$fk_c_type_fees.')'; + } + if (!empty($date)) + { + $date = dol_print_date($date, '%Y-%m-%d'); + $sql.= ' AND er.dates <= \''.$date.'\''; + $sql.= ' AND er.datee >= \''.$date.'\''; + } + if ($fk_user > 0) + { + $sql.= ' AND (er.is_for_all = 1'; + $sql.= ' OR er.fk_user = '.$fk_user; + $sql.= ' OR er.fk_usergroup IN (SELECT ugu.fk_usergroup FROM '.MAIN_DB_PREFIX.'usergroup_user ugu WHERE ugu.fk_user = '.$fk_user.') )'; + } + $sql.= ' ORDER BY er.is_for_all, er.fk_usergroup, er.fk_user'; + + dol_syslog("ExpenseReportRule::getAllRule sql=".$sql); + + $resql = $db->query($sql); + if ($resql) + { + while ($obj = $db->fetch_object($resql)) + { + $rule = new ExpenseReportRule($db); + if ($rule->fetch($obj->rowid) > 0) $rules[$rule->id] = $rule; + else dol_print_error($db); + } + } + else + { + dol_print_error($db); + } + + return $rules; + } + + /** + * Return the label of group for the current object + * + * @return string + */ + public function getGroupLabel() + { + include_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; + + if ($this->fk_usergroup > 0) + { + $group = new UserGroup($this->db); + if ($group->fetch($this->fk_usergroup) > 0) + { + return $group->nom; + } + else + { + $this->error = $group->error; + $this->errors[] = $this->error; + } + } + + return ''; + } + + /** + * Return the name of user for the current object + * + * @return string + */ + public function getUserName() + { + include_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; + + if ($this->fk_user > 0) + { + $u = new User($this->db); + if ($u->fetch($this->fk_user) > 0) + { + return dolGetFirstLastname($u->firstname, $u->lastname); + } + else + { + $this->error = $u->error; + $this->errors[] = $this->error; + } + } + + return ''; + } +} \ No newline at end of file diff --git a/htdocs/install/mysql/data/llx_c_exp_tax_cat.sql b/htdocs/install/mysql/data/llx_c_exp_tax_cat.sql new file mode 100644 index 00000000000..576d90236b5 --- /dev/null +++ b/htdocs/install/mysql/data/llx_c_exp_tax_cat.sql @@ -0,0 +1,56 @@ +-- Copyright (C) 2017 ATM Consulting +-- Copyright (C) 2017 Pierre-Henry Favre +-- +-- 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 . +-- +-- + +-- +-- Ne pas placer de commentaire en fin de ligne, ce fichier est parsé lors +-- de l'install et tous les sigles '--' sont supprimés. +-- + + +-- +-- Categories expense +-- + +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (1,'ExpAutoCat', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (2,'ExpCycloCat', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (3,'ExpMotoCat', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (4,'ExpAuto3CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (5,'ExpAuto4CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (6,'ExpAuto5CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (7,'ExpAuto6CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (8,'ExpAuto7CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (9,'ExpAuto8CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (10,'ExpAuto9CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (11,'ExpAuto10CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (12,'ExpAuto11CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (13,'ExpAuto12CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (14,'ExpAuto3PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (15,'ExpAuto4PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (16,'ExpAuto5PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (17,'ExpAuto6PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (18,'ExpAuto7PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (19,'ExpAuto8PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (20,'ExpAuto9PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (21,'ExpAuto10PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (22,'ExpAuto11PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (23,'ExpAuto12PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (24,'ExpAuto13PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (25,'ExpCyclo', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (26,'ExpMoto12CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (27,'ExpMoto345CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (28,'ExpMoto5PCV', 1, 1); diff --git a/htdocs/install/mysql/data/llx_c_exp_tax_range.sql b/htdocs/install/mysql/data/llx_c_exp_tax_range.sql new file mode 100644 index 00000000000..cb568fdc0c1 --- /dev/null +++ b/htdocs/install/mysql/data/llx_c_exp_tax_range.sql @@ -0,0 +1,47 @@ +-- Copyright (C) 2017 ATM Consulting +-- Copyright (C) 2017 Pierre-Henry Favre +-- +-- 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 . +-- +-- + +-- +-- Ne pas placer de commentaire en fin de ligne, ce fichier est parsé lors +-- de l'install et tous les sigles '--' sont supprimés. +-- + + +-- +-- Range expense +-- + +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (1,4, 0, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (2,4, 5000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (3,4, 20000, 1, 1); + +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (4,5, 0, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (5,5, 5000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (6,5, 20000, 1, 1); + +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (7,6, 0, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (8,6, 5000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (9,6, 20000, 1, 1); + +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (10,7, 0, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (11,7, 5000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (12,7, 20000, 1, 1); + +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (13,8, 0, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (14,8, 5000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (15,8, 20000, 1, 1); \ No newline at end of file diff --git a/htdocs/install/mysql/data/llx_c_type_fees.sql b/htdocs/install/mysql/data/llx_c_type_fees.sql index 19ee7865e9f..3065133fbeb 100644 --- a/htdocs/install/mysql/data/llx_c_type_fees.sql +++ b/htdocs/install/mysql/data/llx_c_type_fees.sql @@ -5,6 +5,8 @@ -- Copyright (C) 2004 Guillaume Delecourt -- Copyright (C) 2005-2009 Regis Houssin -- Copyright (C) 2007 Patrick Raguin +-- Copyright (C) 2017 ATM Consulting +-- Copyright (C) 2017 Pierre-Henry Favre -- -- 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 @@ -33,3 +35,27 @@ insert into llx_c_type_fees (code,label,active) values ('TF_OTHER', 'Other', 1); insert into llx_c_type_fees (code,label,active) values ('TF_TRIP', 'Transportation', 1); insert into llx_c_type_fees (code,label,active) values ('TF_LUNCH', 'Lunch', 1); + +INSERT INTO llx_c_type_fees (code, label, active, accountancy_code) VALUES +('EX_KME', 'ExpLabelKm', 0, '625100'), +('EX_FUE', 'ExpLabelFuelCV', 0, '606150'), +('EX_HOT', 'ExpLabelHotel', 0, '625160'), +('EX_PAR', 'ExpLabelParkingCV', 0, '625160'), +('EX_TOL', 'ExpLabelTollCV', 0, '625160'), +('EX_TAX', 'ExpLabelVariousTaxes', 0, '637800'), +('EX_IND', 'ExpLabelIndemnityTransportationSubscription', 0, '648100'), +('EX_SUM', 'ExpLabelMaintenanceSupply', 0, '606300'), +('EX_SUO', 'ExpLabelOfficeSupplies', 0, '606400'), +('EX_CAR', 'ExpLabelCarRental', 0, '613000'), +('EX_DOC', 'ExpLabelDocumentation', 0, '618100'), +('EX_CUR', 'ExpLabelCustomersReceiving', 0, '625710'), +('EX_OTR', 'ExpLabelOtherReceiving', 0, '625700'), +('EX_POS', 'ExpLabelPostage', 0, '626100'), +('EX_CAM', 'ExpLabelMaintenanceRepairCV', 0, '615300'), +('EX_EMM', 'ExpLabelEmployeesMeal', 0, '625160'), +('EX_GUM', 'ExpLabelGuestsMeal', 0, '625160'), +('EX_BRE', 'ExpLabelBreakfast', 0, '625160'), +('EX_FUE_VP', 'ExpLabelFuelPV', 0, '606150'), +('EX_TOL_VP', 'ExpLabelTollPV', 0, '625160'), +('EX_PAR_VP', 'ExpLabelParkingPV', 0, '625160'), +('EX_CAM_VP', 'ExpLabelMaintenanceRepairPV', 0, '615300'); \ No newline at end of file diff --git a/htdocs/install/mysql/data/llx_expensereport_ik.sql b/htdocs/install/mysql/data/llx_expensereport_ik.sql new file mode 100644 index 00000000000..957e824bdca --- /dev/null +++ b/htdocs/install/mysql/data/llx_expensereport_ik.sql @@ -0,0 +1,47 @@ +-- Copyright (C) 2017 ATM Consulting +-- Copyright (C) 2017 Pierre-Henry Favre +-- +-- 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 . +-- +-- + +-- +-- Ne pas placer de commentaire en fin de ligne, ce fichier est parsé lors +-- de l'install et tous les sigles '--' sont supprimés. +-- + + +-- +-- Coef expense +-- + +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (1,4, 1, 0.41, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (2,4, 2, 0.244, 824); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (3,4, 3, 0.286, 0); + +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (4,5, 4, 0.493, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (5,5, 5, 0.277, 1082); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (6,5, 6, 0.332, 0); + +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (7,6, 7, 0.543, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (8,6, 8, 0.305, 1180); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (9,6, 9, 0.364, 0); + +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (10,7, 10, 0.568, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (11,7, 11, 0.32, 1244); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (12,7, 12, 0.382, 0); + +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (13,8, 13, 0.595, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (14,8, 14, 0.337, 1288); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (15,8, 15, 0.401, 0); \ No newline at end of file diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index bc09bf25ca3..8a332d66f8f 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -431,3 +431,138 @@ CREATE TABLE llx_blockedlog_authority ) ENGINE=innodb; ALTER TABLE llx_blockedlog_authority ADD INDEX signature (signature); + + +CREATE TABLE IF NOT EXISTS llx_expensereport_ik ( + rowid integer AUTO_INCREMENT PRIMARY KEY, + datec datetime DEFAULT NULL, + tms timestamp, + fk_cat integer DEFAULT 0 NOT NULL, + fk_range integer DEFAULT 0 NOT NULL, + coef double DEFAULT 0 NOT NULL, + offset double DEFAULT 0 NOT NULL +)ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS llx_c_exp_tax_cat ( + rowid integer AUTO_INCREMENT PRIMARY KEY, + label varchar(48) NOT NULL, + entity integer DEFAULT 1 NOT NULL, + active integer DEFAULT 1 NOT NULL +)ENGINE=innodb DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS llx_c_exp_tax_range ( + rowid integer AUTO_INCREMENT PRIMARY KEY, + fk_cat integer DEFAULT 1 NOT NULL, + `range` double DEFAULT 0 NOT NULL, + entity integer DEFAULT 1 NOT NULL, + active integer DEFAULT 1 NOT NULL +)ENGINE=innodb DEFAULT CHARSET=utf8; + +INSERT INTO llx_c_type_fees (code, label, active, accountancy_code) VALUES +('EX_KME', 'ExpLabelKm', 0, '625100'), +('EX_FUE', 'ExpLabelFuelCV', 0, '606150'), +('EX_HOT', 'ExpLabelHotel', 0, '625160'), +('EX_PAR', 'ExpLabelParkingCV', 0, '625160'), +('EX_TOL', 'ExpLabelTollCV', 0, '625160'), +('EX_TAX', 'ExpLabelVariousTaxes', 0, '637800'), +('EX_IND', 'ExpLabelIndemnityTransportationSubscription', 0, '648100'), +('EX_SUM', 'ExpLabelMaintenanceSupply', 0, '606300'), +('EX_SUO', 'ExpLabelOfficeSupplies', 0, '606400'), +('EX_CAR', 'ExpLabelCarRental', 0, '613000'), +('EX_DOC', 'ExpLabelDocumentation', 0, '618100'), +('EX_CUR', 'ExpLabelCustomersReceiving', 0, '625710'), +('EX_OTR', 'ExpLabelOtherReceiving', 0, '625700'), +('EX_POS', 'ExpLabelPostage', 0, '626100'), +('EX_CAM', 'ExpLabelMaintenanceRepairCV', 0, '615300'), +('EX_EMM', 'ExpLabelEmployeesMeal', 0, '625160'), +('EX_GUM', 'ExpLabelGuestsMeal', 0, '625160'), +('EX_BRE', 'ExpLabelBreakfast', 0, '625160'), +('EX_FUE_VP', 'ExpLabelFuelPV', 0, '606150'), +('EX_TOL_VP', 'ExpLabelTollPV', 0, '625160'), +('EX_PAR_VP', 'ExpLabelParkingPV', 0, '625160'), +('EX_CAM_VP', 'ExpLabelMaintenanceRepairPV', 0, '615300'); + +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (1,4, 1, 0.41, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (2,4, 2, 0.244, 824); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (3,4, 3, 0.286, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (4,5, 4, 0.493, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (5,5, 5, 0.277, 1082); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (6,5, 6, 0.332, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (7,6, 7, 0.543, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (8,6, 8, 0.305, 1180); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (9,6, 9, 0.364, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (10,7, 10, 0.568, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (11,7, 11, 0.32, 1244); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (12,7, 12, 0.382, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (13,8, 13, 0.595, 0); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (14,8, 14, 0.337, 1288); +INSERT INTO llx_expensereport_ik (rowid,fk_cat, fk_range, coef, offset) values (15,8, 15, 0.401, 0); + + +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (1,'ExpAutoCat', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (2,'ExpCycloCat', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (3,'ExpMotoCat', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (4,'ExpAuto3CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (5,'ExpAuto4CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (6,'ExpAuto5CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (7,'ExpAuto6CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (8,'ExpAuto7CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (9,'ExpAuto8CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (10,'ExpAuto9CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (11,'ExpAuto10CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (12,'ExpAuto11CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (13,'ExpAuto12CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (14,'ExpAuto3PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (15,'ExpAuto4PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (16,'ExpAuto5PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (17,'ExpAuto6PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (18,'ExpAuto7PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (19,'ExpAuto8PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (20,'ExpAuto9PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (21,'ExpAuto10PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (22,'ExpAuto11PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (23,'ExpAuto12PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (24,'ExpAuto13PCV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (25,'ExpCyclo', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (26,'ExpMoto12CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (27,'ExpMoto345CV', 1, 1); +INSERT INTO llx_c_exp_tax_cat (rowid, label, entity, active) values (28,'ExpMoto5PCV', 1, 1); + + +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (1,4, 0, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (2,4, 5000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (3,4, 20000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (4,5, 0, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (5,5, 5000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (6,5, 20000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (7,6, 0, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (8,6, 5000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (9,6, 20000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (10,7, 0, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (11,7, 5000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (12,7, 20000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (13,8, 0, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (14,8, 5000, 1, 1); +INSERT INTO llx_c_exp_tax_range (rowid,fk_cat,`range`, entity, active) values (15,8, 20000, 1, 1); + +CREATE TABLE `llx_expensereport_rules` ( + `rowid` integer AUTO_INCREMENT PRIMARY KEY, + `datec` datetime DEFAULT NULL, + `tms` timestamp, + `dates` datetime NOT NULL, + `datee` datetime NOT NULL, + `amount` numeric(24,8) NOT NULL, + `restrictive` tinyint(1) NOT NULL, + `fk_user` integer DEFAULT NULL, + `fk_usergroup` integer DEFAULT NULL, + `fk_c_type_fees` integer NOT NULL, + `code_expense_rules_type` varchar(50) NOT NULL, + `is_for_all` tinyint(1) DEFAULT '0', + `entity` integer DEFAULT 1 +); + +ALTER TABLE llx_expensereport_det ADD COLUMN rule_warning_message text; +ALTER TABLE llx_expensereport_det ADD COLUMN fk_c_exp_tax_cat integer; + +ALTER TABLE llx_user ADD COLUMN default_range integer; +ALTER TABLE llx_user ADD COLUMN default_c_exp_tax_cat integer; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_c_exp_tax_cat.sql b/htdocs/install/mysql/tables/llx_c_exp_tax_cat.sql new file mode 100644 index 00000000000..9caea48ca21 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_c_exp_tax_cat.sql @@ -0,0 +1,26 @@ +-- ============================================================================ +-- Copyright (C) 2012 Mikael Carlavan +-- Copyright (C) 2017 ATM Consulting +-- Copyright (C) 2017 Pierre-Henry Favre +-- +-- 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 2 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 IF NOT EXISTS llx_c_exp_tax_cat ( + rowid integer AUTO_INCREMENT PRIMARY KEY, + label varchar(48) NOT NULL, + entity integer DEFAULT 1 NOT NULL, + active integer DEFAULT 1 NOT NULL +)ENGINE=innodb DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_c_exp_tax_range.sql b/htdocs/install/mysql/tables/llx_c_exp_tax_range.sql new file mode 100644 index 00000000000..15c9d4ce35b --- /dev/null +++ b/htdocs/install/mysql/tables/llx_c_exp_tax_range.sql @@ -0,0 +1,27 @@ +-- ============================================================================ +-- Copyright (C) 2012 Mikael Carlavan +-- Copyright (C) 2017 ATM Consulting +-- Copyright (C) 2017 Pierre-Henry Favre +-- +-- 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 2 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 IF NOT EXISTS llx_c_exp_tax_range ( + rowid integer AUTO_INCREMENT PRIMARY KEY, + fk_cat integer DEFAULT 1 NOT NULL, + `range` double DEFAULT 0 NOT NULL, + entity integer DEFAULT 1 NOT NULL, + active integer DEFAULT 1 NOT NULL +)ENGINE=innodb DEFAULT CHARSET=utf8; diff --git a/htdocs/install/mysql/tables/llx_expensereport_det.sql b/htdocs/install/mysql/tables/llx_expensereport_det.sql index 069cd534e4f..9b30932ee7a 100644 --- a/htdocs/install/mysql/tables/llx_expensereport_det.sql +++ b/htdocs/install/mysql/tables/llx_expensereport_det.sql @@ -21,6 +21,7 @@ CREATE TABLE llx_expensereport_det rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY, fk_expensereport integer NOT NULL, fk_c_type_fees integer NOT NULL, + fk_c_exp_tax_cat integer, fk_projet integer, comments text NOT NULL, product_type integer DEFAULT -1, @@ -49,5 +50,6 @@ CREATE TABLE llx_expensereport_det fk_facture integer DEFAULT 0, -- ID of customer invoice line if expense is rebilled to a customer fk_code_ventilation integer DEFAULT 0, rang integer DEFAULT 0, -- position of line - import_key varchar(14) + import_key varchar(14), + rule_warning_message text ) ENGINE=innodb; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_expensereport_ik.sql b/htdocs/install/mysql/tables/llx_expensereport_ik.sql new file mode 100644 index 00000000000..c2d0999c6d6 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_expensereport_ik.sql @@ -0,0 +1,29 @@ +-- ============================================================================ +-- Copyright (C) 2012 Mikael Carlavan +-- Copyright (C) 2017 ATM Consulting +-- Copyright (C) 2017 Pierre-Henry Favre +-- +-- 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 2 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 IF NOT EXISTS llx_expensereport_ik ( + rowid integer AUTO_INCREMENT PRIMARY KEY, + datec datetime DEFAULT NULL, + tms timestamp, + fk_cat integer DEFAULT 0 NOT NULL, + fk_range integer DEFAULT 0 NOT NULL, + coef double DEFAULT 0 NOT NULL, + offset double DEFAULT 0 NOT NULL +)ENGINE=innodb DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_expensereport_rules.sql b/htdocs/install/mysql/tables/llx_expensereport_rules.sql new file mode 100644 index 00000000000..1045a29b70a --- /dev/null +++ b/htdocs/install/mysql/tables/llx_expensereport_rules.sql @@ -0,0 +1,34 @@ +-- ============================================================================ +-- Copyright (C) 2017 ATM Consulting +-- Copyright (C) 2017 Pierre-Henry Favre +-- +-- 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 2 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_expensereport_rules` ( + `rowid` integer AUTO_INCREMENT PRIMARY KEY, + `datec` datetime DEFAULT NULL, + `tms` timestamp, + `dates` datetime NOT NULL, + `datee` datetime NOT NULL, + `amount` numeric(24,8) NOT NULL, + `restrictive` tinyint(1) NOT NULL, + `fk_user` integer DEFAULT NULL, + `fk_usergroup` integer DEFAULT NULL, + `fk_c_type_fees` integer NOT NULL, + `code_expense_rules_type` varchar(50) NOT NULL, + `is_for_all` tinyint(1) DEFAULT '0', + `entity` integer DEFAULT 1 +) ENGINE=InnoDB \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_user.sql b/htdocs/install/mysql/tables/llx_user.sql index d033ba5eca4..93d39f83b0d 100644 --- a/htdocs/install/mysql/tables/llx_user.sql +++ b/htdocs/install/mysql/tables/llx_user.sql @@ -85,5 +85,7 @@ create table llx_user dateemployment date, -- denormalized value coming from llx_user_employment weeklyhours double(16,8), -- denormalized value coming from llx_user_employment - import_key varchar(14) -- import key + import_key varchar(14), -- import key + default_range integer, + default_c_exp_tax_cat integer )ENGINE=innodb; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 695373e22b5..641466b9337 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -873,6 +873,8 @@ DictionaryUnits=Units DictionaryProspectStatus=Prospection status DictionaryHolidayTypes=Types of leaves DictionaryOpportunityStatus=Opportunity status for project/lead +DictionaryExpenseTaxCat=Expense report categories +DictionaryExpenseTaxRange=Expense report range by category SetupSaved=Setup saved SetupNotSaved=Setup not saved BackToModuleList=Back to modules list @@ -1139,6 +1141,8 @@ RuleForGeneratedPasswords=Rule to generate suggested passwords or validate passw DisableForgetPasswordLinkOnLogonPage=Do not show the link "Forget password" on login page UsersSetup=Users module setup UserMailRequired=EMail required to create a new user +DefaultCategoryCar=Default car category +DefaultRangeNumber=Default range number ##### HRM setup ##### HRMSetup=HRM module setup ##### Company setup ##### @@ -1607,6 +1611,8 @@ TypePaymentDesc=0:Customer payment type, 1:Supplier payment type, 2:Both custome IncludePath=Include path (defined into variable %s) ExpenseReportsSetup=Setup of module Expense Reports TemplatePDFExpenseReports=Document templates to generate expense report document +ExpenseReportsIkSetup=Setup of module Expense Reports - Milles index +ExpenseReportsRulesSetup=Setup of module Expense Reports - Rules NoModueToManageStockIncrease=No module able to manage automatic stock increase has been activated. Stock increase will be done on manual input only. YouMayFindNotificationsFeaturesIntoModuleNotification=You may find options for EMail notifications by enabling and configuring the module "Notification". ListOfNotificationsPerUser=List of notifications per user* diff --git a/htdocs/langs/en_US/dict.lang b/htdocs/langs/en_US/dict.lang index 8971d8e82d4..f0fa27bcbf8 100644 --- a/htdocs/langs/en_US/dict.lang +++ b/htdocs/langs/en_US/dict.lang @@ -325,3 +325,32 @@ PaperFormatCAP3=Format P3 Canada PaperFormatCAP4=Format P4 Canada PaperFormatCAP5=Format P5 Canada PaperFormatCAP6=Format P6 Canada +#### Expense report categories #### +ExpAutoCat=Car +ExpCycloCat=Moped +ExpMotoCat=Motorbike +ExpAuto3CV=3 CV +ExpAuto4CV=4 CV +ExpAuto5CV=5 CV +ExpAuto6CV=6 CV +ExpAuto7CV=7 CV +ExpAuto8CV=8 CV +ExpAuto9CV=9 CV +ExpAuto10CV=10 CV +ExpAuto11CV=11 CV +ExpAuto12CV=12 CV +ExpAuto3PCV=3 CV and more +ExpAuto4PCV=4 CV and more +ExpAuto5PCV=5 CV and more +ExpAuto6PCV=6 CV and more +ExpAuto7PCV=7 CV and more +ExpAuto8PCV=8 CV and more +ExpAuto9PCV=9 CV and more +ExpAuto10PCV=10 CV and more +ExpAuto11PCV=11 CV and more +ExpAuto12PCV=12 CV and more +ExpAuto13PCV=13 CV and more +ExpCyclo=Capacity lower to 50cm3 +ExpMoto12CV=Motorbike 1 or 2 CV +ExpMoto345CV=Motorbike 3, 4 or 5 CV +ExpMoto5PCV=Motorbike 5 CV and more \ No newline at end of file diff --git a/htdocs/langs/en_US/trips.lang b/htdocs/langs/en_US/trips.lang index a51a392499b..75b0d18e56f 100644 --- a/htdocs/langs/en_US/trips.lang +++ b/htdocs/langs/en_US/trips.lang @@ -49,6 +49,28 @@ TF_PEAGE=Toll TF_ESSENCE=Fuel TF_HOTEL=Hotel TF_TAXI=Taxi +EX_KME=Mileage costs +EX_FUE=Fuel CV +EX_HOT=Hotel +EX_PAR=Parking CV +EX_TOL=Toll CV +EX_TAX=Various Taxes +EX_IND=Indemnity transportation subscription +EX_SUM=Maintenance supply +EX_SUO=Office supplies +EX_CAR=Car rental +EX_DOC=Documentation +EX_CUR=Customers receiving +EX_OTR=Other receiving +EX_POS=Postage +EX_CAM=CV maintenance and repair +EX_EMM=Employees meal +EX_GUM=Guests meal +EX_BRE=Breakfast +EX_FUE_VP=Fuel PV +EX_TOL_VP=Toll PV +EX_PAR_VP=Parking PV +EX_CAM_VP=PV maintenance and repair ErrorDoubleDeclaration=You have declared another expense report into a similar date range. AucuneLigne=There is no expense report declared yet @@ -89,4 +111,43 @@ ExpenseReportPayment=Expense report payment ExpenseReportsToApprove=Expense reports to approve ExpenseReportsToPay=Expense reports to pay CloneExpenseReport=Clone expense report -ConfirmCloneExpenseReport=Are you sure you want to clone this expense report ? \ No newline at end of file +ConfirmCloneExpenseReport=Are you sure you want to clone this expense report ? +ExpenseReportsIk=Expense report milles index +ExpenseReportsRules=Expense report rules +ExpenseReportIkDesc=You can modify the calculation of kilometers expense by category and range who they are previously defined. d is the distance in kilometers +ExpenseReportRulesDesc=You can create or update any rules of calculation. This part will be used when user will create a new expense report +expenseReportOffset=Offset +expenseReportCoef=Coefficient +expenseReportTotalForFive=Example with d = 5 +expenseReportRangeFromTo=from %d to %d +expenseReportRangeMoreThan=more than %d +expenseReportCoefUndefined=(value not defined) +expenseReportCatDisabled=Category disabled - see the c_exp_tax_cat dictionary +expenseReportRangeDisabled=Range disabled - see the c_exp_tax_range dictionay +expenseReportPrintExample=offset + (d x coef) = %s +ExpenseReportApplyTo=Apply to +ExpenseReportDomain=Domain to apply +ExpenseReportLimitOn=Limit on +ExpenseReportDateStart=Date start +ExpenseReportDateEnd=Date end +ExpenseReportLimitAmount=Limite amount +ExpenseReportRestrictive=Restrictive +AllExpenseReport=All type of expense report +OnExpense=Expense line +ExpenseReportRuleSave=Expense report rule saved +ExpenseReportRuleErrorOnSave=Error: %s +RangeNum=Range %d + +ExpenseReportConstraintViolationError=Contraint violation id [%s]: %s is superior to %s %s +byEX_DAY=by day (limitation to %s) +byEX_MON=by month (limitation to %s) +byEX_YEA=by year (limitation to %s) +byEX_EXP=by line (limitation to %s) +ExpenseReportConstraintViolationWarning=Contraint violation id [%s]: %s is superior to %s %s +nolimitbyEX_DAY=by day (no limitation) +nolimitbyEX_MON=by month (no limitation) +nolimitbyEX_YEA=by year (no limitation) +nolimitbyEX_EXP=by line (no limitation) + +CarCategory=Category of car +ExpenseRangeOffset=Offset amount: %s \ No newline at end of file diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 089820da442..2ebd93d05da 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -47,7 +47,7 @@ if (! empty($conf->ldap->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class/l if (! empty($conf->adherent->enabled)) require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; if (! empty($conf->multicompany->enabled)) dol_include_once('/multicompany/class/actions_multicompany.class.php'); if (! empty($conf->categorie->enabled)) require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; - +if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_ik.class.php'; $id = GETPOST('id','int'); $action = GETPOST('action','alpha'); @@ -367,6 +367,9 @@ if (empty($reshook)) { $dateemployment = dol_mktime(0, 0, 0, GETPOST('dateemploymentmonth'), GETPOST('dateemploymentday'), GETPOST('dateemploymentyear')); $object->dateemployment = $dateemployment; + $object->default_range = GETPOST('default_range'); + $object->default_c_exp_tax_cat = GETPOST('default_c_exp_tax_cat'); + if (! empty($conf->multicompany->enabled)) { if (! empty($_POST["superadmin"])) @@ -1108,7 +1111,21 @@ if ($action == 'create' || $action == 'adduserldap') null, '90%' ); print ""; } + + if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) + { + print ''.$langs->trans("DefaultCategoryCar").''; + print ''; + print $form->selectExpenseCategories($object->default_c_exp_tax_cat, 'default_c_exp_tax_cat', 1); + print ''; + print ''.$langs->trans("DefaultRangeNumber").''; + print ''; + $maxRangeNum = ExpenseReportIk::getMaxRangeNumber($object->default_c_exp_tax_cat); + print $form->selectarray('default_range', range(0, $maxRangeNum), $object->default_range); + print ''; + } + // Other attributes $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"'); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook @@ -1126,7 +1143,7 @@ if ($action == 'create' || $action == 'adduserldap') $doleditor=new DolEditor('note','','',120,'dolibarr_notes','',false,true,$conf->global->FCKEDITOR_ENABLE_SOCIETE,ROWS_3,'90%'); $doleditor->Create(); print "\n"; - + // Signature print ''.$langs->trans("Signature").''; print ''; @@ -1498,6 +1515,19 @@ else print ''.dol_print_date($object->datepreviouslogin,"dayhour").''; print "\n"; + if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) + { + print ''.$langs->trans("DefaultCategoryCar").''; + print ''; + print dol_getIdFromCode($db, $object->default_c_exp_tax_cat, 'c_exp_tax_cat', 'rowid', 'label'); + print ''; + + print ''.$langs->trans("DefaultRangeNumber").''; + print ''; + print $object->default_range; + print ''; + } + // Other attributes include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; @@ -2423,6 +2453,20 @@ else print "\n"; } + if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) + { + print ''.$langs->trans("DefaultCategoryCar").''; + print ''; + print $form->selectExpenseCategories($object->default_c_exp_tax_cat, 'default_c_exp_tax_cat', 1); + print ''; + + print ''.$langs->trans("DefaultRangeNumber").''; + print ''; + $maxRangeNum = ExpenseReportIk::getMaxRangeNumber($object->default_c_exp_tax_cat); + print $form->selectarray('default_range', range(0, $maxRangeNum), $object->default_range); + print ''; + } + // Other attributes $parameters=array('colspan' => ' colspan="2"'); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 6b39158a87b..2a04cf27ec1 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -130,7 +130,8 @@ class User extends CommonObject public $dateemployment; // Define date of employment by company - + public $default_c_exp_tax_cat; + public $default_range; /** * Constructor de la classe @@ -199,6 +200,7 @@ class User extends CommonObject $sql.= " u.color,"; $sql.= " u.dateemployment,"; $sql.= " u.ref_int, u.ref_ext,"; + $sql.= " u.default_range, u.default_c_exp_tax_cat,"; $sql.= " c.code as country_code, c.label as country,"; $sql.= " d.code_departement as state_code, d.nom as state"; $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; @@ -309,6 +311,9 @@ class User extends CommonObject $this->contactid = $obj->fk_socpeople; $this->fk_member = $obj->fk_member; $this->fk_user = $obj->fk_user; + + $this->default_range = $obj->default_range; + $this->default_c_exp_tax_cat = $obj->default_c_exp_tax_cat; // Protection when module multicompany was set, admin was set to first entity and the module disabled, // then this admin user must be admin for all entities. @@ -1319,7 +1324,7 @@ class User extends CommonObject $this->accountancy_code = trim($this->accountancy_code); $this->color = empty($this->color)?'':$this->color; $this->dateemployment = empty($this->dateemployment)?'':$this->dateemployment; - + // Check parameters if (! empty($conf->global->USER_MAIL_REQUIRED) && ! isValidEMail($this->email)) { @@ -1370,6 +1375,9 @@ class User extends CommonObject if (isset($this->salaryextra) || $this->salaryextra != '') $sql.= ", salaryextra= ".($this->salaryextra != ''?"'".$this->db->escape($this->salaryextra)."'":"null"); $sql.= ", weeklyhours= ".($this->weeklyhours != ''?"'".$this->db->escape($this->weeklyhours)."'":"null"); $sql.= ", entity = '".$this->db->escape($this->entity)."'"; + $sql.= ", default_range = ".($this->default_range > 0 ? $this->default_range : 'null'); + $sql.= ", default_c_exp_tax_cat = ".($this->default_c_exp_tax_cat > 0 ? $this->default_c_exp_tax_cat : 'null'); + $sql.= " WHERE rowid = ".$this->id; dol_syslog(get_class($this)."::update", LOG_DEBUG); From 6ab0ec4b1ba6b1b8ce27afdf0de0b59d1b55e1f8 Mon Sep 17 00:00:00 2001 From: phf Date: Fri, 7 Jul 2017 10:22:37 +0200 Subject: [PATCH 002/112] Fix travis and rename 2 fields --- htdocs/admin/dict.php | 22 +++-- htdocs/admin/expensereport_ik.php | 18 ++-- htdocs/core/class/html.form.class.php | 8 +- .../class/expensereport_ik.class.php | 24 ++--- .../install/mysql/data/llx_c_exp_tax_cat.sql | 44 ++++----- .../mysql/data/llx_c_exp_tax_range.sql | 30 +++--- htdocs/install/mysql/data/llx_c_type_fees.sql | 2 +- .../mysql/data/llx_expensereport_ik.sql | 30 +++--- .../install/mysql/migration/5.0.0-6.0.0.sql | 96 +++++++++---------- .../mysql/tables/llx_c_exp_tax_range.sql | 4 +- .../mysql/tables/llx_expensereport_ik.sql | 2 +- .../mysql/tables/llx_expensereport_rules.sql | 28 +++--- htdocs/langs/en_US/trips.lang | 7 +- 13 files changed, 160 insertions(+), 155 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index a52c27b74c1..99b23cbd8d8 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -205,7 +205,7 @@ $tabsql[30]= "SELECT rowid, code, name, paper_size, orientation, metric, leftmar $tabsql[33]= "SELECT rowid, pos, code, label, active FROM ".MAIN_DB_PREFIX."c_hrm_department"; $tabsql[34]= "SELECT rowid, pos, code, label, c_level, active FROM ".MAIN_DB_PREFIX."c_hrm_function"; $tabsql[35]= "SELECT c.rowid, c.label, c.active, c.entity FROM ".MAIN_DB_PREFIX."c_exp_tax_cat c"; -$tabsql[36]= "SELECT r.rowid, r.fk_cat, r.range, r.active, r.entity FROM ".MAIN_DB_PREFIX."c_exp_tax_range r"; +$tabsql[36]= "SELECT r.rowid, r.fk_c_exp_tax_cat, r.range_ik, r.active, r.entity FROM ".MAIN_DB_PREFIX."c_exp_tax_range r"; // Criteria to sort dictionaries $tabsqlsort=array(); @@ -244,7 +244,7 @@ $tabsqlsort[30]="code ASC"; $tabsqlsort[33]="code ASC"; $tabsqlsort[34]="code ASC"; $tabsqlsort[35]="c.label ASC"; -$tabsqlsort[36]="r.fk_cat ASC, r.range ASC"; +$tabsqlsort[36]="r.fk_c_exp_tax_cat ASC, r.range_ik ASC"; // Nom des champs en resultat de select pour affichage du dictionnaire $tabfield=array(); @@ -281,7 +281,7 @@ $tabfield[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx, //$tabfield[31]= "pcg_version,label"; //$tabfield[32]= "code,label,range_account,sens,category_type,formula,position,country_id,country"; $tabfield[35]= "label"; -$tabfield[36]= "range,fk_cat"; +$tabfield[36]= "range_ik,fk_c_exp_tax_cat"; // Nom des champs d'edition pour modification d'un enregistrement $tabfieldvalue=array(); @@ -320,7 +320,7 @@ $tabfieldvalue[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargi $tabfieldvalue[33]= "code,label"; $tabfieldvalue[34]= "code,label"; $tabfieldvalue[35]= "label"; -$tabfieldvalue[36]= "range,fk_cat"; +$tabfieldvalue[36]= "range_ik,fk_c_exp_tax_cat"; // Nom des champs dans la table pour insertion d'un enregistrement $tabfieldinsert=array(); @@ -359,7 +359,7 @@ $tabfieldinsert[30]= "code,name,paper_size,orientation,metric,leftmargin,topmarg $tabfieldinsert[33]= "code,label"; $tabfieldinsert[34]= "code,label"; $tabfieldinsert[35]= "label"; -$tabfieldinsert[36]= "`range`,fk_cat"; +$tabfieldinsert[36]= "range_ik,fk_c_exp_tax_cat"; // Nom du rowid si le champ n'est pas de type autoincrement // Example: "" if id field is "rowid" and has autoincrement on @@ -478,7 +478,7 @@ $tabhelp[30] = array('code'=>$langs->trans("EnterAnyCode"), 'name'=>$langs->tran $tabhelp[33] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[34] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[35]= array(); -$tabhelp[36]= array('range'=>$langs->trans('PrevRangeToThisRange')); +$tabhelp[36]= array('range_ik'=>$langs->trans('PrevRangeToThisRange')); // List of check for fields (NOT USED YET) $tabfieldcheck=array(); @@ -1086,6 +1086,8 @@ if ($id) if ($fieldlist[$field]=='delay') { $valuetoshow=$langs->trans("NoticePeriod"); } if ($fieldlist[$field]=='newbymonth') { $valuetoshow=$langs->trans("NewByMonth"); } if ($fieldlist[$field]=='fk_tva') { $valuetoshow=$langs->trans("VAT"); } + if ($fieldlist[$field]=='range_ik') { $valuetoshow=$langs->trans("RangeIk"); } + if ($fieldlist[$field]=='fk_c_exp_tax_cat'){ $valuetoshow=$langs->trans("CarCategory"); } if ($id == 2) // Special cas for state page { @@ -1306,6 +1308,8 @@ if ($id) if ($fieldlist[$field]=='delay') { $valuetoshow=$langs->trans("NoticePeriod"); } if ($fieldlist[$field]=='newbymonth') { $valuetoshow=$langs->trans("NewByMonth"); } if ($fieldlist[$field]=='fk_tva') { $valuetoshow=$langs->trans("VAT"); } + if ($fieldlist[$field]=='range_ik') { $valuetoshow=$langs->trans("RangeIk"); } + if ($fieldlist[$field]=='fk_c_exp_tax_cat'){ $valuetoshow=$langs->trans("CarCategory"); } // Affiche nom du champ if ($showfield) @@ -1534,7 +1538,7 @@ if ($id) } } } - elseif (in_array($fieldlist[$field], array('fk_cat', 'fk_exp_tax_cat'))) + elseif ($fieldlist[$field] == 'fk_c_exp_tax_cat') { $valuetoshow = getDictvalue(MAIN_DB_PREFIX.'c_exp_tax_cat', 'label', $valuetoshow); $valuetoshow = $langs->trans($valuetoshow); @@ -1881,10 +1885,10 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') print $form->load_tva('fk_tva', $obj->taux, $mysoc, new Societe($db), 0, 0, '', false, -1); print ''; } - elseif ($fieldlist[$field] == 'fk_cat') + elseif ($fieldlist[$field] == 'fk_c_exp_tax_cat') { print ''; - print $form->selectExpenseCategories($obj->fk_cat); + print $form->selectExpenseCategories($obj->fk_c_exp_tax_cat); print ''; } elseif ($fieldlist[$field] == 'fk_range') diff --git a/htdocs/admin/expensereport_ik.php b/htdocs/admin/expensereport_ik.php index bb50bfc58f0..9e653dce906 100644 --- a/htdocs/admin/expensereport_ik.php +++ b/htdocs/admin/expensereport_ik.php @@ -47,7 +47,7 @@ $id = GETPOST('id','int'); $offset = GETPOST('offset','int'); $coef = GETPOST('coef','int'); -$fk_cat = GETPOST('fk_cat'); +$fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat'); $fk_range = GETPOST('fk_range'); if ($action == 'updateik') @@ -106,7 +106,7 @@ echo '
'; if ($action == 'edit') { echo ''; - echo ''; + echo ''; echo ''; echo ''; } @@ -115,7 +115,7 @@ echo ''; echo ''; -foreach ($rangesbycateg as $fk_cat => $Tab) +foreach ($rangesbycateg as $fk_c_exp_tax_cat => $Tab) { $title = ($Tab['active'] == 1) ? $langs->trans($Tab['label']) : $form->textwithpicto($langs->trans($Tab['label']), $langs->trans('expenseReportCatDisabled'), 1, 'help', '', 0, 3); echo ''; @@ -132,8 +132,8 @@ foreach ($rangesbycateg as $fk_cat => $Tab) $var = true; foreach ($Tab['ranges'] as $k => $range) { - if (isset($Tab['ranges'][$k+1])) $label = $langs->trans('expenseReportRangeFromTo', $range->range, ($Tab['ranges'][$k+1]->range-1)); - else $label = $langs->trans('expenseReportRangeMoreThan', $range->range); + if (isset($Tab['ranges'][$k+1])) $label = $langs->trans('expenseReportRangeFromTo', $range->range_ik, ($Tab['ranges'][$k+1]->range_ik-1)); + else $label = $langs->trans('expenseReportRangeMoreThan', $range->range_ik); if ($range->range_active == 0) $label = $form->textwithpicto($label, $langs->trans('expenseReportRangeDisabled'), 1, 'help', '', 0, 3); @@ -144,12 +144,12 @@ foreach ($rangesbycateg as $fk_cat => $Tab) // Offset echo ''; // Coef echo ''; @@ -160,14 +160,14 @@ foreach ($rangesbycateg as $fk_cat => $Tab) echo ''; $entity=(! empty($objexport->array_export_entities[0][$code])?$objexport->array_export_entities[0][$code]:$objexport->array_export_icon[0]); - $entityicon=(! empty($entitytoicon[$entity])?$entitytoicon[$entity]:$entity); + $entityicon=strtolower(! empty($entitytoicon[$entity])?$entitytoicon[$entity]:$entity); $entitylang=(! empty($entitytolang[$entity])?$entitytolang[$entity]:$entity); print ''."\n"; // User + /* print ''; + */ // Ref print ''."\n"; // User + /* print ''; + */ // Ref print ''; } @@ -443,21 +445,21 @@ if ($id > 0) { $langs->load("projects"); $morehtmlref.='
'.$langs->trans('Project') . ' '; - if ($user->rights->commande->creer) + if ($user->rights->loan->write) { - if ($action != 'classify') - $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.=''; - } else { - $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); - } + if ($action != 'classify') + $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + if ($action == 'classify') { + //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref.=''; + $morehtmlref.=''; + $morehtmlref.=''; + $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref.=''; + $morehtmlref.=''; + } else { + $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } } else { if (! empty($object->fk_project)) { $proj = new Project($db); diff --git a/htdocs/loan/document.php b/htdocs/loan/document.php index f4f490a146a..b43261d2b9d 100644 --- a/htdocs/loan/document.php +++ b/htdocs/loan/document.php @@ -89,8 +89,38 @@ if ($object->id) $morehtmlref='
'; // Ref loan - $morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', 0, 1); - $morehtmlref.=$form->editfieldval("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', null, null, '', 1); + $morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, 0, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("Label", 'label', $object->label, $object, 0, 'string', '', null, null, '', 1); + // Project + if (! empty($conf->projet->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
' . $langs->trans('Project') . ' : '; + if ($user->rights->loan->write) { + //if ($action != 'classify') + // $morehtmlref .= '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + if ($action == 'classify') { + // $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref .= '
'; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= ''; + } else { + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ''; + $morehtmlref .= $proj->ref; + $morehtmlref .= ''; + } else { + $morehtmlref .= ''; + } + } + } $morehtmlref.='
'; $linkback = '' . $langs->trans("BackToList") . ''; diff --git a/htdocs/loan/info.php b/htdocs/loan/info.php index 73bb1c1f984..96da6182da6 100644 --- a/htdocs/loan/info.php +++ b/htdocs/loan/info.php @@ -57,8 +57,38 @@ dol_fiche_head($head, 'info', $langs->trans("Loan"), -1, 'bill'); $morehtmlref='
'; // Ref loan -$morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', 0, 1); -$morehtmlref.=$form->editfieldval("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', null, null, '', 1); +$morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, 0, 'string', '', 0, 1); +$morehtmlref.=$form->editfieldval("Label", 'label', $object->label, $object, 0, 'string', '', null, null, '', 1); +// Project +if (! empty($conf->projet->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
' . $langs->trans('Project') . ' : '; + if ($user->rights->loan->write) { + //if ($action != 'classify') + // $morehtmlref .= '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + if ($action == 'classify') { + // $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref .= '
'; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= ''; + } else { + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ''; + $morehtmlref .= $proj->ref; + $morehtmlref .= ''; + } else { + $morehtmlref .= ''; + } + } +} $morehtmlref.='
'; $linkback = '' . $langs->trans("BackToList") . ''; diff --git a/htdocs/loan/note.php b/htdocs/loan/note.php index 4b76cad1d6d..5f435444f32 100644 --- a/htdocs/loan/note.php +++ b/htdocs/loan/note.php @@ -74,8 +74,38 @@ if ($id > 0) $morehtmlref='
'; // Ref loan - $morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', 0, 1); - $morehtmlref.=$form->editfieldval("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', null, null, '', 1); + $morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, 0, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("Label", 'label', $object->label, $object, 0, 'string', '', null, null, '', 1); + // Project + if (! empty($conf->projet->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
' . $langs->trans('Project') . ' : '; + if ($user->rights->loan->write) { + //if ($action != 'classify') + // $morehtmlref .= '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + if ($action == 'classify') { + // $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref .= '
'; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= ''; + } else { + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ''; + $morehtmlref .= $proj->ref; + $morehtmlref .= ''; + } else { + $morehtmlref .= ''; + } + } + } $morehtmlref.='
'; $linkback = '' . $langs->trans("BackToList") . ''; diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 93e15f2fe77..bda8d793840 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -336,7 +336,7 @@ $listofreferent=array( 'table'=>'fichinter', 'datefieldname'=>'date_valid', 'disableamount'=>0, - 'margin'=>'minus', + 'margin'=>'minus', 'urlnew'=>DOL_URL_ROOT.'/fichinter/card.php?action=create&origin=project&originid='.$id.'&socid='.$socid, 'lang'=>'interventions', 'buttonnew'=>'AddIntervention', @@ -417,9 +417,9 @@ $listofreferent=array( 'lang'=>'compta', 'buttonnew'=>'AddSocialContribution', 'testnew'=>$user->rights->tax->charges->lire, - 'test'=>$conf->tax->enabled && $user->rights->tax->charges->lire), + 'test'=>$conf->tax->enabled && $user->rights->tax->charges->lire), 'project_task'=>array( - 'name'=>"TaskTimeValorised", + 'name'=>"TaskTimeSpent", 'title'=>"ListTaskTimeUserProject", 'class'=>'Task', 'margin'=>'minus', @@ -573,7 +573,7 @@ foreach ($listofreferent as $key => $value) if ($tablename != 'expensereport_det' && method_exists($element, 'fetch_thirdparty')) $element->fetch_thirdparty(); if ($tablename == 'don' || $tablename == 'chargesociales') $total_ht_by_line=$element->amount; elseif ($tablename == 'stock_mouvement') $total_ht_by_line=$element->price*abs($element->qty); - else if($tablename == 'fichinter') $total_ht_by_line=$element->getAmount(); + else if($tablename == 'fichinter') $total_ht_by_line=$element->getAmount(); elseif ($tablename == 'projet_task') { if ($idofelementuser) @@ -598,7 +598,7 @@ foreach ($listofreferent as $key => $value) if ($qualifiedfortotal) $total_ht = $total_ht + $total_ht_by_line; if ($tablename == 'don' || $tablename == 'chargesociales') $total_ttc_by_line=$element->amount; - else if($tablename == 'fichinter') $total_ttc_by_line=$element->getAmount(); + else if($tablename == 'fichinter') $total_ttc_by_line=$element->getAmount(); elseif ($tablename == 'stock_mouvement') $total_ttc_by_line=$element->price*abs($element->qty); elseif ($tablename == 'projet_task') { @@ -629,7 +629,7 @@ foreach ($listofreferent as $key => $value) $total_ttc = -$total_ttc; } - switch ($classname) { + /*switch ($classname) { case 'FactureFournisseur': $newclassname = 'SupplierInvoice'; break; @@ -653,12 +653,12 @@ foreach ($listofreferent as $key => $value) break; default: $newclassname = $classname; - } + }*/ $var = ! $var; print ''; // Module - print ''; + print ''; // Nb print ''; // Amount HT @@ -711,7 +711,7 @@ foreach ($listofreferent as $key => $value) $idtofilterthirdparty=0; $array_of_element_linkable_with_different_thirdparty = array('facture_fourn', 'commande_fournisseur'); - if (! in_array($tablename, $array_of_element_linkable_with_different_thirdparty)) + if (! in_array($tablename, $array_of_element_linkable_with_different_thirdparty)) { $idtofilterthirdparty=$object->thirdparty->id; if (! empty($conf->global->PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS)) $idtofilterthirdparty.=','.$conf->global->PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS; @@ -854,7 +854,7 @@ foreach ($listofreferent as $key => $value) print '' . img_picto($langs->trans('Unlink'), 'editdelete') . ''; } print "\n"; - + // Ref print ''; //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print ''; print ''; //elseif (empty($value['disableamount']) && in_array($tablename, array('projet_task'))) print ''; print '
'; - if ($action == 'edit' && $range->ik->id == $id && $range->rowid == $fk_range && $range->fk_cat == $fk_cat) echo ''; + if ($action == 'edit' && $range->ik->id == $id && $range->rowid == $fk_range && $range->fk_c_exp_tax_cat == $fk_c_exp_tax_cat) echo ''; else echo $range->ik->offset; echo ''; - if ($action == 'edit' && $range->ik->id == $id && $range->rowid == $fk_range && $range->fk_cat == $fk_cat) echo ''; + if ($action == 'edit' && $range->ik->id == $id && $range->rowid == $fk_range && $range->fk_c_exp_tax_cat == $fk_c_exp_tax_cat) echo ''; else echo ($range->ik->id > 0 ? $range->ik->coef : $langs->trans('expenseReportCoefUndefined')); echo ''; if ($range->range_active == 1) { - if ($action == 'edit' && $range->ik->id == $id && $range->rowid == $fk_range && $range->fk_cat == $fk_cat) + if ($action == 'edit' && $range->ik->id == $id && $range->rowid == $fk_range && $range->fk_c_exp_tax_cat == $fk_c_exp_tax_cat) { echo ''; echo ''; } else { - echo ''.img_edit().''; + echo ''.img_edit().''; if (!empty($range->ik->id)) echo ''.img_delete().''; // TODO add delete link } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 9285bbd3035..9e93332e7a8 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -6307,7 +6307,7 @@ class Form * @param array $params param to give * @return string */ - function selectExpenseCategories($selected='', $htmlname='fk_cat', $useempty=0, $excludeid=array(), $target='', $default_selected=0, $params=array()) + function selectExpenseCategories($selected='', $htmlname='fk_c_exp_tax_cat', $useempty=0, $excludeid=array(), $target='', $default_selected=0, $params=array()) { global $db,$conf,$langs; @@ -6335,7 +6335,7 @@ class Form if ($resql) { if ($db->num_rows($resql) > 0) - { dol_buildpath($path); + { $obj = $db->fetch_object($resql); $out.= ' - - '."\n"; print ''."\n"; print ''."\n"; - + print dol_fiche_head(); - + ?> - + @@ -445,7 +445,7 @@ if (! empty($id) || ! empty($ref))

- @@ -495,12 +495,12 @@ if (! empty($id) || ! empty($ref))   - + '; } - else + else { if ($action === 'delete') { @@ -538,7 +538,7 @@ if (! empty($id) || ! empty($ref)) $comb2val = new ProductCombination2ValuePair($db); - if ($productCombinations) + if ($productCombinations) { ?> @@ -563,36 +563,36 @@ if (! empty($id) || ! empty($ref)) }); - '; - + print '
'; if ($productCombinations) { print ''.$langs->trans('PropagateVariant').''; } - + print ''.$langs->trans('NewProductCombination').''; // NewVariant - + // Too much bugged page. /* print ''.$langs->trans('ProductCombinationGenerator').''; */ - + print '
'; - + print ''; - - - + + + $arrayofselected=is_array($toselect)?$toselect:array(); - - + + // List of variants print ''; - - + + // List of mass actions available /* $arrayofmassactions = array( @@ -603,7 +603,7 @@ if (! empty($id) || ! empty($ref)) if ($massaction == 'presend' || $massaction == 'createbills') $arrayofmassactions=array(); $massactionbutton=$form->selectMassAction('', $arrayofmassactions); */ - + $aaa=''; if (count($productCombinations)) { @@ -620,11 +620,11 @@ if (! empty($id) || ! empty($ref)) $aaa .= ''; } $massactionbutton = $aaa; - + $title = $langs->trans("ProductCombinations"); - + print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $aaa, 0); - + print '
'; ?>
@@ -636,7 +636,7 @@ if (! empty($id) || ! empty($ref)) - '; $searchpicto=$form->showCheckAddButtons('checkforselect', 1); print $searchpicto; @@ -644,23 +644,23 @@ if (! empty($id) || ! empty($ref)) ?> fetch($currcomb->fk_product_child); + $prodstatic->fetch($currcomb->fk_product_child); ?> - '; if ($productCombinations || $massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined { @@ -690,7 +690,7 @@ if (! empty($id) || ! empty($ref)) } else { - print ''; + print ''; } ?>
trans('OnSell') ?> trans('OnBuy') ?>
getNomUrl(1) ?> fetchByFkCombination($currcomb->id); $iMax = count($productCombination2ValuePairs); - + for ($i = 0; $i < $iMax; $i++) { echo dol_htmlentities($productCombination2ValuePairs[$i]); - + if ($i !== ($iMax - 1)) { echo ', '; } @@ -674,7 +674,7 @@ if (! empty($id) || ! empty($ref))
'.$langs->trans("None").'
'.$langs->trans("None").'
From 60493d0a4774735616feefe769cfe40a74db7921 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 10:16:17 +0200 Subject: [PATCH 025/112] Several fixes (permission, missing method or class) in REST APIs --- htdocs/api/index.php | 1 + .../comm/propal/class/api_proposals.class.php | 128 +++--- htdocs/commande/class/api_orders.class.php | 20 +- .../facture/class/api_invoices.class.php | 127 ++++-- htdocs/core/lib/functions2.lib.php | 2 +- .../class/api_supplier_invoices.class.php | 126 ++++-- .../fourn/class/api_supplier_orders.class.php | 365 ++++++++++++++++++ 7 files changed, 623 insertions(+), 146 deletions(-) create mode 100644 htdocs/fourn/class/api_supplier_orders.class.php diff --git a/htdocs/api/index.php b/htdocs/api/index.php index 905d560f9c2..9f734c9e24d 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -238,6 +238,7 @@ if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/resources.json' { $classfile = str_replace('_', '', $module); if ($module == 'supplierinvoices') $classfile = 'supplier_invoices'; + if ($module == 'supplierorders') $classfile = 'supplier_orders'; $dir_part_file = dol_buildpath('/'.$moduledirforclass.'/class/api_'.$classfile.'.class.php'); $classname=ucwords($module); diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 2f067f46b18..42dbdbf9d2c 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -24,14 +24,14 @@ require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; /** * API class for orders * - * @access protected + * @access protected * @class DolibarrApiAccess {@requires user,external} */ class Proposals extends DolibarrApi { /** - * @var array $FIELDS Mandatory fields, checked when create and update object + * @var array $FIELDS Mandatory fields, checked when create and update object */ static $FIELDS = array( 'socid' @@ -56,36 +56,36 @@ class Proposals extends DolibarrApi * Get properties of a commercial proposal object * * Return an array with commercial proposal informations - * + * * @param int $id ID of commercial proposal * @return array|mixed data without useless information * * @throws RestException */ function get($id) - { + { if(! DolibarrApiAccess::$user->rights->propal->lire) { throw new RestException(401); } - + $result = $this->propal->fetch($id); if( ! $result ) { throw new RestException(404, 'Commercial Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $this->propal->fetchObjectLinked(); return $this->_cleanObjectDatas($this->propal); } /** * List commercial proposals - * + * * Get a list of commercial proposals - * + * * @param string $sortfield Sort field * @param string $sortorder Sort order * @param int $limit Limit for list @@ -96,12 +96,12 @@ class Proposals extends DolibarrApi */ function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids = '', $sqlfilters = '') { global $db, $conf; - + $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; - + // If the internal user must only see his customers, force searching by him $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; @@ -109,7 +109,7 @@ class Proposals extends DolibarrApi $sql = "SELECT t.rowid"; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) $sql.= " FROM ".MAIN_DB_PREFIX."propal as t"; - + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale $sql.= ' WHERE t.entity IN ('.getEntity('propal').')'; @@ -122,7 +122,7 @@ class Proposals extends DolibarrApi $sql .= " AND sc.fk_user = ".$search_sale; } // Add sql filters - if ($sqlfilters) + if ($sqlfilters) { if (! DolibarrApi::_checkFilters($sqlfilters)) { @@ -131,7 +131,7 @@ class Proposals extends DolibarrApi $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } - + $sql.= $db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) @@ -144,7 +144,7 @@ class Proposals extends DolibarrApi } $result = $db->query($sql); - + if ($result) { $num = $db->num_rows($result); @@ -195,7 +195,7 @@ class Proposals extends DolibarrApi if ($this->propal->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, "Error creating order", array_merge(array($this->propal->error), $this->propal->errors)); } - + return $this->propal->id; } @@ -203,21 +203,21 @@ class Proposals extends DolibarrApi * Get lines of a commercial proposal * * @param int $id Id of commercial proposal - * + * * @url GET {id}/lines - * - * @return int + * + * @return int */ function getLines($id) { if(! DolibarrApiAccess::$user->rights->propal->lire) { throw new RestException(401); } - + $result = $this->propal->fetch($id); if( ! $result ) { throw new RestException(404, 'Commercial Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -233,22 +233,22 @@ class Proposals extends DolibarrApi * Add a line to given commercial proposal * * @param int $id Id of commercial proposal to update - * @param array $request_data Commercial proposal line data - * + * @param array $request_data Commercial proposal line data + * * @url POST {id}/lines - * - * @return int + * + * @return int */ function postLine($id, $request_data = NULL) { if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401); } - + $result = $this->propal->fetch($id); if( ! $result ) { throw new RestException(404, 'Commercial Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -294,22 +294,22 @@ class Proposals extends DolibarrApi * * @param int $id Id of commercial proposal to update * @param int $lineid Id of line to update - * @param array $request_data Commercial proposal line data - * + * @param array $request_data Commercial proposal line data + * * @url PUT {id}/lines/{lineid} - * - * @return object + * + * @return object */ function putLine($id, $lineid, $request_data = NULL) { if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401); } - + $result = $this->propal->fetch($id); if( ! $result ) { throw new RestException(404, 'Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -352,21 +352,21 @@ class Proposals extends DolibarrApi * * @param int $id Id of commercial proposal to update * @param int $lineid Id of line to delete - * + * * @url DELETE {id}/lines/{lineid} - * - * @return int + * + * @return int */ function delLine($id, $lineid) { if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401); } - + $result = $this->propal->fetch($id); if( ! $result ) { throw new RestException(404, 'Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -382,20 +382,20 @@ class Proposals extends DolibarrApi * Update commercial proposal general fields (won't touch lines of commercial proposal) * * @param int $id Id of commercial proposal to update - * @param array $request_data Datas - * - * @return int + * @param array $request_data Datas + * + * @return int */ function put($id, $request_data = NULL) { if(! DolibarrApiAccess::$user->rights->propal->creer) { throw new RestException(401); } - + $result = $this->propal->fetch($id); if( ! $result ) { throw new RestException(404, 'Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -403,18 +403,18 @@ class Proposals extends DolibarrApi if ($field == 'id') continue; $this->propal->$field = $value; } - + if($this->propal->update($id, DolibarrApiAccess::$user,1,'','','update')) return $this->get($id); - + return false; } - + /** * Delete commercial proposal * * @param int $id Commercial proposal ID - * + * * @return array */ function delete($id) @@ -426,32 +426,32 @@ class Proposals extends DolibarrApi if( ! $result ) { throw new RestException(404, 'Commercial Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + if( ! $this->propal->delete(DolibarrApiAccess::$user)) { throw new RestException(500, 'Error when delete Commercial Proposal : '.$this->propal->error); } - + return array( 'success' => array( 'code' => 200, 'message' => 'Commercial Proposal deleted' ) ); - + } - + /** * Validate a commercial proposal - * + * * @param int $id Commercial proposal ID * @param int $notrigger Use {} - * + * * @url POST {id}/validate - * + * * @return array * FIXME An error 403 is returned if the request has an empty body. * Error message: "Forbidden: Content type `text/plain` is not supported." @@ -469,11 +469,11 @@ class Proposals extends DolibarrApi if( ! $result ) { throw new RestException(404, 'Commercial Proposal not found'); } - + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $result = $this->propal->valid(DolibarrApiAccess::$user, $notrigger); if ($result == 0) { throw new RestException(500, 'Error nothing done. May be object is already validated'); @@ -481,30 +481,30 @@ class Proposals extends DolibarrApi if ($result < 0) { throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error); } - + return array( 'success' => array( 'code' => 200, - 'message' => 'Commercial Proposal validated' + 'message' => 'Commercial Proposal validated (Ref='.$this->propal->ref.')' ) ); } - + /** * Validate fields before create or update object - * + * * @param array $data Array with data to verify - * @return array + * @return array * @throws RestException */ function _validate($data) { $propal = array(); - foreach (Orders::$FIELDS as $field) { + foreach (Proposals::$FIELDS as $field) { if (!isset($data[$field])) throw new RestException(400, "$field field missing"); $propal[$field] = $data[$field]; - + } return $propal; } diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index a1330a7be04..d4b4502d4ed 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -80,8 +80,8 @@ class Orders extends DolibarrApi return $this->_cleanObjectDatas($this->commande); } - - + + /** * List orders * @@ -101,7 +101,7 @@ class Orders extends DolibarrApi global $db, $conf; $obj_ret = array(); - + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; @@ -125,7 +125,7 @@ class Orders extends DolibarrApi $sql .= " AND sc.fk_user = ".$search_sale; } // Add sql filters - if ($sqlfilters) + if ($sqlfilters) { if (! DolibarrApi::_checkFilters($sqlfilters)) { @@ -134,7 +134,7 @@ class Orders extends DolibarrApi $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } - + $sql.= $db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) @@ -490,7 +490,7 @@ class Orders extends DolibarrApi return array( 'success' => array( 'code' => 200, - 'message' => 'Order validated' + 'message' => 'Order validated (Ref='.$this->commande->ref.')' ) ); } @@ -502,14 +502,14 @@ class Orders extends DolibarrApi * @return array Array of cleaned object properties */ function _cleanObjectDatas($object) { - + $object = parent::_cleanObjectDatas($object); - + unset($object->address); - + return $object; } - + /** * Validate fields before create or update object * diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index 55304136ed6..f841fc80050 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -22,14 +22,14 @@ /** * API class for invoices * - * @access protected + * @access protected * @class DolibarrApiAccess {@requires user,external} */ class Invoices extends DolibarrApi { /** * - * @var array $FIELDS Mandatory fields, checked when create and update object + * @var array $FIELDS Mandatory fields, checked when create and update object */ static $FIELDS = array( 'socid' @@ -54,23 +54,23 @@ class Invoices extends DolibarrApi * Get properties of a invoice object * * Return an array with invoice informations - * + * * @param int $id ID of invoice * @return array|mixed data without useless information * * @throws RestException */ function get($id) - { + { if(! DolibarrApiAccess::$user->rights->facture->lire) { throw new RestException(401); } - + $result = $this->invoice->fetch($id); if( ! $result ) { throw new RestException(404, 'Invoice not found'); } - + if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -80,9 +80,9 @@ class Invoices extends DolibarrApi /** * List invoices - * + * * Get a list of invoices - * + * * @param string $sortfield Sort field * @param string $sortorder Sort order * @param int $limit Limit for list @@ -96,12 +96,12 @@ class Invoices extends DolibarrApi */ function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids='', $status='', $sqlfilters = '') { global $db, $conf; - + $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; - + // If the internal user must only see his customers, force searching by him $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; @@ -109,7 +109,7 @@ class Invoices extends DolibarrApi $sql = "SELECT t.rowid"; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) $sql.= " FROM ".MAIN_DB_PREFIX."facture as t"; - + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale $sql.= ' WHERE t.entity IN ('.getEntity('facture').')'; @@ -117,7 +117,7 @@ class Invoices extends DolibarrApi if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")"; if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale - + // Filter by status if ($status == 'draft') $sql.= " AND t.fk_statut IN (0)"; if ($status == 'unpaid') $sql.= " AND t.fk_statut IN (1)"; @@ -129,7 +129,7 @@ class Invoices extends DolibarrApi $sql .= " AND sc.fk_user = ".$search_sale; } // Add sql filters - if ($sqlfilters) + if ($sqlfilters) { if (! DolibarrApi::_checkFilters($sqlfilters)) { @@ -138,7 +138,7 @@ class Invoices extends DolibarrApi $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } - + $sql.= $db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) @@ -174,10 +174,10 @@ class Invoices extends DolibarrApi } return $obj_ret; } - + /** * Create invoice object - * + * * @param array $request_data Request datas * @return int ID of invoice */ @@ -188,7 +188,7 @@ class Invoices extends DolibarrApi } // Check mandatory fields $result = $this->_validate($request_data); - + foreach($request_data as $field => $value) { $this->invoice->$field = $value; } @@ -203,7 +203,7 @@ class Invoices extends DolibarrApi } $this->invoice->lines = $lines; }*/ - + if ($this->invoice->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, "Error creating invoice", array_merge(array($this->invoice->error), $this->invoice->errors)); } @@ -214,20 +214,20 @@ class Invoices extends DolibarrApi * Update invoice * * @param int $id Id of invoice to update - * @param array $request_data Datas - * @return int + * @param array $request_data Datas + * @return int */ function put($id, $request_data = NULL) { if(! DolibarrApiAccess::$user->rights->facture->creer) { throw new RestException(401); } - + $result = $this->invoice->fetch($id); if( ! $result ) { throw new RestException(404, 'Invoice not found'); } - + if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -236,13 +236,13 @@ class Invoices extends DolibarrApi if ($field == 'id') continue; $this->invoice->$field = $value; } - + if($this->invoice->update($id, DolibarrApiAccess::$user)) return $this->get ($id); - + return false; } - + /** * Delete invoice * @@ -258,16 +258,16 @@ class Invoices extends DolibarrApi if( ! $result ) { throw new RestException(404, 'Invoice not found'); } - + if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + if( $this->invoice->delete($id) < 0) { throw new RestException(500); } - + return array( 'success' => array( 'code' => 200, @@ -275,13 +275,76 @@ class Invoices extends DolibarrApi ) ); } - + + /** + * Validate an order + * + * @param int $id Order ID + * @param int $idwarehouse Warehouse ID + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * + * @url POST {id}/validate + * + * @return array + * FIXME An error 403 is returned if the request has an empty body. + * Error message: "Forbidden: Content type `text/plain` is not supported." + * Workaround: send this in the body + * { + * "idwarehouse": 0, + * "notrigger": 0 + * } + */ + function validate($id, $idwarehouse=0, $notrigger=0) + { + if(! DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + $result = $this->invoice->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Invoice not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger); + if ($result == 0) { + throw new RestException(500, 'Error nothing done. May be object is already validated'); + } + if ($result < 0) { + throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Invoice validated (Ref='.$this->invoice->ref.')' + ) + ); + } + + /** + * Clean sensible object datas + * + * @param object $object Object to clean + * @return array Array of cleaned object properties + */ + function _cleanObjectDatas($object) { + + $object = parent::_cleanObjectDatas($object); + + unset($object->address); + + return $object; + } + /** * Validate fields before create or update object - * + * * @param array|null $data Datas to validate * @return array - * + * * @throws RestException */ function _validate($data) @@ -294,5 +357,5 @@ class Invoices extends DolibarrApi } return $invoice; } - + } diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 72f27a16602..181e8a7fe11 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -2200,7 +2200,7 @@ function getModuleDirForApiClass($module) elseif ($module == 'stock' || $module == 'stockmovements' || $module == 'warehouses') { $moduledirforclass = 'product/stock'; } - elseif ($module == 'fournisseur' || $module == 'supplierinvoices') { + elseif ($module == 'fournisseur' || $module == 'supplierinvoices' || $module == 'supplierorders') { $moduledirforclass = 'fourn'; } elseif ($module == 'expensereports') { diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 6f3291518ca..26ae936d5a0 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -23,14 +23,14 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; /** * API class for supplier invoices * - * @access protected + * @access protected * @class DolibarrApiAccess {@requires user,external} */ class SupplierInvoices extends DolibarrApi { /** * - * @var array $FIELDS Mandatory fields, checked when create and update object + * @var array $FIELDS Mandatory fields, checked when create and update object */ static $FIELDS = array( 'socid' @@ -55,24 +55,24 @@ class SupplierInvoices extends DolibarrApi * Get properties of a supplier invoice object * * Return an array with supplier invoice information - * + * * @param int $id ID of supplier invoice * @return array|mixed data without useless information * * @throws RestException */ function get($id) - { + { if(! DolibarrApiAccess::$user->rights->fournisseur->facture->lire) { throw new RestException(401); } - + $result = $this->invoice->fetch($id); if( ! $result ) { throw new RestException(404, 'Supplier invoice not found'); } - - if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->invoice->id,'facture_fourn','facture')) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -81,9 +81,9 @@ class SupplierInvoices extends DolibarrApi /** * List invoices - * + * * Get a list of supplier invoices - * + * * @param string $sortfield Sort field * @param string $sortorder Sort order * @param int $limit Limit for list @@ -97,12 +97,12 @@ class SupplierInvoices extends DolibarrApi */ function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids='', $status='', $sqlfilters = '') { global $db, $conf; - + $obj_ret = array(); // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; - + // If the internal user must only see his customers, force searching by him $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; @@ -110,14 +110,14 @@ class SupplierInvoices extends DolibarrApi $sql = "SELECT t.rowid"; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as t"; - + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale $sql.= ' WHERE t.entity IN ('.getEntity('supplier_invoice').')'; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")"; if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale - + // Filter by status if ($status == 'draft') $sql.= " AND t.fk_statut IN (0)"; if ($status == 'unpaid') $sql.= " AND t.fk_statut IN (1)"; @@ -129,7 +129,7 @@ class SupplierInvoices extends DolibarrApi $sql .= " AND sc.fk_user = ".$search_sale; } // Add sql filters - if ($sqlfilters) + if ($sqlfilters) { if (! DolibarrApi::_checkFilters($sqlfilters)) { @@ -138,7 +138,7 @@ class SupplierInvoices extends DolibarrApi $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } - + $sql.= $db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) @@ -174,10 +174,10 @@ class SupplierInvoices extends DolibarrApi } return $obj_ret; } - + /** * Create supplier invoice object - * + * * @param array $request_data Request datas * @return int ID of supplier invoice */ @@ -188,7 +188,7 @@ class SupplierInvoices extends DolibarrApi } // Check mandatory fields $result = $this->_validate($request_data); - + foreach($request_data as $field => $value) { $this->invoice->$field = $value; } @@ -203,7 +203,7 @@ class SupplierInvoices extends DolibarrApi } $this->invoice->lines = $lines; }*/ - + if ($this->invoice->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, "Error creating order", array_merge(array($this->invoice->error), $this->invoice->errors)); } @@ -214,21 +214,21 @@ class SupplierInvoices extends DolibarrApi * Update supplier invoice * * @param int $id Id of supplier invoice to update - * @param array $request_data Datas - * @return int + * @param array $request_data Datas + * @return int */ function put($id, $request_data = NULL) { if(! DolibarrApiAccess::$user->rights->fournisseur->facture->creer) { throw new RestException(401); } - + $result = $this->invoice->fetch($id); if( ! $result ) { throw new RestException(404, 'Supplier invoice not found'); } - - if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->invoice->id,'facture_fourn','facture')) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -236,13 +236,13 @@ class SupplierInvoices extends DolibarrApi if ($field == 'id') continue; $this->invoice->$field = $value; } - + if($this->invoice->update($id, DolibarrApiAccess::$user)) return $this->get ($id); - + return false; } - + /** * Delete supplier invoice * @@ -258,16 +258,16 @@ class SupplierInvoices extends DolibarrApi if( ! $result ) { throw new RestException(404, 'Supplier invoice not found'); } - - if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->invoice->id,'facture_fourn','facture')) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + if( $this->invoice->delete(DolibarrApiAccess::$user) < 0) { throw new RestException(500); } - + return array( 'success' => array( 'code' => 200, @@ -275,8 +275,56 @@ class SupplierInvoices extends DolibarrApi ) ); } - - + + + /** + * Validate an order + * + * @param int $id Order ID + * @param int $idwarehouse Warehouse ID + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * + * @url POST {id}/validate + * + * @return array + * FIXME An error 403 is returned if the request has an empty body. + * Error message: "Forbidden: Content type `text/plain` is not supported." + * Workaround: send this in the body + * { + * "idwarehouse": 0, + * "notrigger": 0 + * } + */ + function validate($id, $idwarehouse=0, $notrigger=0) + { + if(! DolibarrApiAccess::$user->rights->fournisseur->facture->creer) { + throw new RestException(401); + } + $result = $this->invoice->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Invoice not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->invoice->id,'facture_fourn','facture')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger); + if ($result == 0) { + throw new RestException(500, 'Error nothing done. May be object is already validated'); + } + if ($result < 0) { + throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Invoice validated (Ref='.$this->invoice->ref.')' + ) + ); + } + /** * Clean sensible object datas * @@ -284,20 +332,20 @@ class SupplierInvoices extends DolibarrApi * @return array Array of cleaned object properties */ function _cleanObjectDatas($object) { - + $object = parent::_cleanObjectDatas($object); - + unset($object->rowid); - + return $object; } - + /** * Validate fields before create or update object - * + * * @param array $data Datas to validate * @return array - * + * * @throws RestException */ function _validate($data) diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php new file mode 100644 index 00000000000..2695727c3ee --- /dev/null +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -0,0 +1,365 @@ + + * Copyright (C) 2016 Laurent Destailleur + * + * 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 . + */ + +use Luracast\Restler\RestException; + +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; + +/** + * API class for supplier orders + * + * @access protected + * @class DolibarrApiAccess {@requires user,external} + */ +class SupplierOrders extends DolibarrApi +{ + /** + * + * @var array $FIELDS Mandatory fields, checked when create and update object + */ + static $FIELDS = array( + 'socid' + ); + + /** + * @var CommandeFournisseur $order {@type CommandeFournisseur} + */ + public $order; + + /** + * Constructor + */ + function __construct() + { + global $db, $conf; + $this->db = $db; + $this->order = new CommandeFournisseur($this->db); + } + + /** + * Get properties of a supplier order object + * + * Return an array with supplier order information + * + * @param int $id ID of supplier order + * @return array|mixed data without useless information + * + * @throws RestException + */ + function get($id) + { + if(! DolibarrApiAccess::$user->rights->fournisseur->commande->lire) { + throw new RestException(401); + } + + $result = $this->order->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Supplier order not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->order->id,'','commande')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + return $this->_cleanObjectDatas($this->order); + } + + /** + * List orders + * + * Get a list of supplier orders + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $thirdparty_ids Thirdparty ids to filter orders of. {@example '1' or '1,2,3'} {@pattern /^[0-9,]*$/i} + * @param string $status Filter by order status : draft | validated | approved | running | received_start | received_end | cancelled | refused + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.datec:<:'20160101')" + * @return array Array of order objects + * + * @throws RestException + */ + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids='', $status='', $sqlfilters = '') { + global $db, $conf; + + $obj_ret = array(); + + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid + $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; + + // If the internal user must only see his customers, force searching by him + $search_sale = 0; + if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; + + $sql = "SELECT t.rowid"; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) + $sql.= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as t"; + + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale + + $sql.= ' WHERE t.entity IN ('.getEntity('supplier_order').')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; + if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")"; + if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale + + // Filter by status + if ($status == 'draft') $sql.= " AND t.fk_statut IN (0)"; + if ($status == 'validated') $sql.= " AND t.fk_statut IN (1)"; + if ($status == 'approved') $sql.= " AND t.fk_statut IN (2)"; + if ($status == 'running') $sql.= " AND t.fk_statut IN (3)"; + if ($status == 'received_start') $sql.= " AND t.fk_statut IN (4)"; + if ($status == 'received_end') $sql.= " AND t.fk_statut IN (5)"; + if ($status == 'cancelled') $sql.= " AND t.fk_statut IN (6,7)"; + if ($status == 'refused') $sql.= " AND t.fk_statut IN (9)"; + // Insert sale filter + if ($search_sale > 0) + { + $sql .= " AND sc.fk_user = ".$search_sale; + } + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $sql.= $db->order($sortfield, $sortorder); + if ($limit) { + if ($page < 0) + { + $page = 0; + } + $offset = $limit * $page; + + $sql.= $db->plimit($limit + 1, $offset); + } + + $result = $db->query($sql); + if ($result) + { + $i = 0; + $num = $db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + while ($i < $min) + { + $obj = $db->fetch_object($result); + $order_static = new CommandeFournisseur($db); + if($order_static->fetch($obj->rowid)) { + $obj_ret[] = $this->_cleanObjectDatas($order_static); + } + $i++; + } + } + else { + throw new RestException(503, 'Error when retrieve supplier order list : '.$db->lasterror()); + } + if( ! count($obj_ret)) { + throw new RestException(404, 'No supplier order found'); + } + return $obj_ret; + } + + /** + * Create supplier order object + * + * @param array $request_data Request datas + * @return int ID of supplier order + */ + function post($request_data = NULL) + { + if(! DolibarrApiAccess::$user->rights->fournisseur->commande->creer) { + throw new RestException(401, "Insuffisant rights"); + } + // Check mandatory fields + $result = $this->_validate($request_data); + + foreach($request_data as $field => $value) { + $this->order->$field = $value; + } + if(! array_keys($request_data,'date')) { + $this->order->date = dol_now(); + } + /* We keep lines as an array + if (isset($request_data["lines"])) { + $lines = array(); + foreach ($request_data["lines"] as $line) { + array_push($lines, (object) $line); + } + $this->order->lines = $lines; + }*/ + + if ($this->order->create(DolibarrApiAccess::$user) < 0) { + throw new RestException(500, "Error creating order", array_merge(array($this->order->error), $this->order->errors)); + } + return $this->order->id; + } + + /** + * Update supplier order + * + * @param int $id Id of supplier order to update + * @param array $request_data Datas + * @return int + */ + function put($id, $request_data = NULL) + { + if(! DolibarrApiAccess::$user->rights->fournisseur->commande->creer) { + throw new RestException(401); + } + + $result = $this->order->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Supplier order not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->order->id,'','commande')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + foreach($request_data as $field => $value) { + if ($field == 'id') continue; + $this->order->$field = $value; + } + + if($this->order->update($id, DolibarrApiAccess::$user)) + return $this->get ($id); + + return false; + } + + /** + * Delete supplier order + * + * @param int $id Supplier order ID + * @return type + */ + function delete($id) + { + if(! DolibarrApiAccess::$user->rights->fournisseur->commande->supprimer) { + throw new RestException(401); + } + $result = $this->order->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Supplier order not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->order->id,'','commande')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if( $this->order->delete(DolibarrApiAccess::$user) < 0) + { + throw new RestException(500); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Supplier order deleted' + ) + ); + } + + + /** + * Validate an order + * + * @param int $id Order ID + * @param int $idwarehouse Warehouse ID + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * + * @url POST {id}/validate + * + * @return array + * FIXME An error 403 is returned if the request has an empty body. + * Error message: "Forbidden: Content type `text/plain` is not supported." + * Workaround: send this in the body + * { + * "idwarehouse": 0, + * "notrigger": 0 + * } + */ + function validate($id, $idwarehouse=0, $notrigger=0) + { + if(! DolibarrApiAccess::$user->rights->fournisseur->commande->creer) { + throw new RestException(401); + } + $result = $this->order->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Order not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->order->id,'','commande')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->order->valid(DolibarrApiAccess::$user, $idwarehouse, $notrigger); + if ($result == 0) { + throw new RestException(500, 'Error nothing done. May be object is already validated'); + } + if ($result < 0) { + throw new RestException(500, 'Error when validating Order: '.$this->order->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Order validated (Ref='.$this->order->ref.')' + ) + ); + } + + /** + * Clean sensible object datas + * + * @param Object $object Object to clean + * @return array Array of cleaned object properties + */ + function _cleanObjectDatas($object) { + + $object = parent::_cleanObjectDatas($object); + + unset($object->rowid); + + return $object; + } + + /** + * Validate fields before create or update object + * + * @param array $data Datas to validate + * @return array + * + * @throws RestException + */ + function _validate($data) + { + $order = array(); + foreach (SupplierOrders::$FIELDS as $field) { + if (!isset($data[$field])) + throw new RestException(400, "$field field missing"); + $order[$field] = $data[$field]; + } + return $order; + } +} From f9442c10924d5c9c5a63abbfc8333bd748ff8c88 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 11:10:00 +0200 Subject: [PATCH 026/112] Fix box activity --- htdocs/core/boxes/box_activity.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index 8d8b2962688..ae3e270101e 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -83,17 +83,17 @@ class box_activity extends ModeleBoxes $cachetime = 3600; $fileid = '-e'.$conf->entity.'-u'.$user->id.'-s'.$user->societe_id.'-r'.($user->rights->societe->client->voir?'1':'0').'.cache'; $now = dol_now(); - $nbofyears=2; + $nbofperiod=3; - if (! empty($conf->global->MAIN_BOX_ACTIVITY_DURATION)) $nbofyears=$conf->global->MAIN_BOX_ACTIVITY_DURATION; - $textHead = $langs->trans("Activity").' - '.$langs->trans("LastXMonthRolling", $nbofyears*12); + if (! empty($conf->global->MAIN_BOX_ACTIVITY_DURATION)) $nbofperiod=$conf->global->MAIN_BOX_ACTIVITY_DURATION; + $textHead = $langs->trans("Activity").' - '.$langs->trans("LastXMonthRolling", $nbofperiod); $this->info_box_head = array( 'text' => $textHead, 'limit'=> dol_strlen($textHead), ); // compute the year limit to show - $tmpdate= dol_time_plus_duree(dol_now(), -1*$nbofyears, "y"); + $tmpdate= dol_time_plus_duree(dol_now(), -1*$nbofperiod, "m"); $cumuldata = array(); @@ -103,6 +103,7 @@ class box_activity extends ModeleBoxes include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $facturestatic=new Facture($db); + // part 1 $cachedir = DOL_DATA_ROOT.'/facture/temp'; $filename = '/boxactivity-invoice'.$fileid; @@ -189,6 +190,7 @@ class box_activity extends ModeleBoxes ); } + // part 2 $cachedir = DOL_DATA_ROOT.'/facture/temp'; $filename = '/boxactivity-invoice2'.$fileid; From cb5b0f33526dba01b93895c68edef38c1cc66cee Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 11:20:01 +0200 Subject: [PATCH 027/112] NEW Module "Product variants" is moved as stable. --- htdocs/core/modules/modVariants.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modVariants.class.php b/htdocs/core/modules/modVariants.class.php index 892d0903826..358a35b4435 100644 --- a/htdocs/core/modules/modVariants.class.php +++ b/htdocs/core/modules/modVariants.class.php @@ -59,7 +59,7 @@ class modVariants extends DolibarrModules // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module) $this->description = 'Allows creating products variant based on new attributes'; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = 'experimental'; + $this->version = 'dolibarr'; // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) From bfb904557f8a96b424c1046de8157dcc100bf854 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 12:06:12 +0200 Subject: [PATCH 028/112] Fix include fails --- ChangeLog | 8 +++++--- htdocs/websites/index.php | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2417a7db682..bdc39167310 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,9 +4,11 @@ English Dolibarr ChangeLog ***** ChangeLog for 6.0.0 compared to 5.0.* ***** -NEW: Add experimental BlockeLog module (to log business events in a non reversible log file). NEW: Add a payment module for Stripe. -NEW: Add module "Product variant" (like red, blue for the product shoes) +NEW: Add "Non Reversible Logs" module as experimental (to log business events in a non reversible log file). +NEW: Add module "Product variant" as experimental (like red, blue for the product shoes) +NEW: Add module "Website" as experimental +NEW: Add module "Module Builder" as experimental NEW: Accountancy - Activate multi-journal & Add journal_label to database (FEC) NEW: Add a tracking id into mass emailing. NEW: Tax system more compatible with the new tax roollout in India (IGST / CGST / SGST). @@ -115,7 +117,7 @@ NEW: Add hook "formatNotificationMessage" NEW: Add index and constraints keys on supplier proposal detail table NEW: Add phpunit to check the engine is defined into sql create files. NEW: Add project and Hook to Loan -NEW: Add REST API to push a file. +NEW: Add more REST API (API to push a file, to manage supplier orders, to validate invoices) NEW: Allow extrafields list select to be dependands on other standard list and not only other extrafields list NEW: Architecture to manage search criteria persistance (using save_lastsearch_values=1 on exit links and restore_lastsearch_values=1 in entry links) NEW: data files are now also parsed by phpunit for sql syntax diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index 9fbd6e6a4e0..1881ffd95a2 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -568,7 +568,7 @@ if ($action == 'updatecontent' || GETPOST('refreshsite') || GETPOST('refreshpage $tplcontent =''; $tplcontent.= " Date: Fri, 28 Jul 2017 12:07:05 +0200 Subject: [PATCH 029/112] Revert "Fix include fails" This reverts commit bfb904557f8a96b424c1046de8157dcc100bf854. --- ChangeLog | 8 +++----- htdocs/websites/index.php | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index bdc39167310..2417a7db682 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,11 +4,9 @@ English Dolibarr ChangeLog ***** ChangeLog for 6.0.0 compared to 5.0.* ***** +NEW: Add experimental BlockeLog module (to log business events in a non reversible log file). NEW: Add a payment module for Stripe. -NEW: Add "Non Reversible Logs" module as experimental (to log business events in a non reversible log file). -NEW: Add module "Product variant" as experimental (like red, blue for the product shoes) -NEW: Add module "Website" as experimental -NEW: Add module "Module Builder" as experimental +NEW: Add module "Product variant" (like red, blue for the product shoes) NEW: Accountancy - Activate multi-journal & Add journal_label to database (FEC) NEW: Add a tracking id into mass emailing. NEW: Tax system more compatible with the new tax roollout in India (IGST / CGST / SGST). @@ -117,7 +115,7 @@ NEW: Add hook "formatNotificationMessage" NEW: Add index and constraints keys on supplier proposal detail table NEW: Add phpunit to check the engine is defined into sql create files. NEW: Add project and Hook to Loan -NEW: Add more REST API (API to push a file, to manage supplier orders, to validate invoices) +NEW: Add REST API to push a file. NEW: Allow extrafields list select to be dependands on other standard list and not only other extrafields list NEW: Architecture to manage search criteria persistance (using save_lastsearch_values=1 on exit links and restore_lastsearch_values=1 in entry links) NEW: data files are now also parsed by phpunit for sql syntax diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index 1881ffd95a2..9fbd6e6a4e0 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -568,7 +568,7 @@ if ($action == 'updatecontent' || GETPOST('refreshsite') || GETPOST('refreshpage $tplcontent =''; $tplcontent.= " Date: Fri, 28 Jul 2017 12:11:20 +0200 Subject: [PATCH 030/112] Fix website css edition --- htdocs/websites/index.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index 0f1e813e3ed..0df4c97594d 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -300,7 +300,7 @@ if ($action == 'updatecss') $csscontent.= "\n*/ims', '', $csscontent); + $csscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $csscontent); $csscontent.= GETPOST('WEBSITE_CSS_INLINE'); if (! trim($csscontent)) $csscontent='/* CSS content (all pages) */'."\n".'body.bodywebsite { margin: 0; }'; $htmlheader = @file_get_contents($filehtmlheader); // Clean the php htmlheader file to remove php code and get only html part - $htmlheader = preg_replace('/<\?php \/\/ BEGIN PHP.*END PHP \?>\n*/ims', '', $htmlheader); + $htmlheader = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $htmlheader); if (! trim($htmlheader)) $htmlheader=''."\n".''."\n".''; else $htmlheader=''."\n".$htmlheader."\n".''; $robotcontent = @file_get_contents($filerobot); // Clean the php htmlheader file to remove php code and get only html part - $robotcontent = preg_replace('/<\?php \/\/ BEGIN PHP.*END PHP \?>\n*/ims', '', $robotcontent); + $robotcontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $robotcontent); if (! trim($robotcontent)) { $robotcontent.="# Robot file. Generated with ".DOL_APPLICATION_TITLE."\n"; @@ -1185,7 +1185,7 @@ if ($action == 'editcss') $htaccesscontent = @file_get_contents($filehtaccess); // Clean the php htmlheader file to remove php code and get only html part - $htaccesscontent = preg_replace('/<\?php \/\/ BEGIN PHP.*END PHP \?>\n*/ims', '', $htaccesscontent); + $htaccesscontent = preg_replace('/<\?php \/\/ BEGIN PHP[^\?]*END PHP \?>\n*/ims', '', $htaccesscontent); if (! trim($htaccesscontent)) { $htaccesscontent.="# Order allow,deny\n"; From ef3c002144a7e0ebb27002be4284ef246342df53 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 12:37:52 +0200 Subject: [PATCH 031/112] Module website not stable enough --- htdocs/core/modules/modWebsites.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modWebsites.class.php b/htdocs/core/modules/modWebsites.class.php index 57abe371314..f3564c31367 100644 --- a/htdocs/core/modules/modWebsites.class.php +++ b/htdocs/core/modules/modWebsites.class.php @@ -50,7 +50,7 @@ class modWebsites extends DolibarrModules // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i','',get_class($this)); $this->description = "Enable to build and serve public websites with CMS features"; - $this->version = 'experimental'; // 'experimental' or 'dolibarr' or version + $this->version = 'development'; // 'experimental' or 'dolibarr' or version // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) From 8d0f21866cb324f228a5e56417010dea986e06fb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 13:05:24 +0200 Subject: [PATCH 032/112] Fix head instead of header --- htdocs/websites/index.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index 0df4c97594d..15fed80ebf7 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -520,7 +520,7 @@ if ($action == 'updatemeta') $aliascontent = 'id.'.tpl.php\';'; + $aliascontent.= 'if (empty($dolibarr_main_data_root)) require \'./page'.$objectpage->id.'.tpl.php\'; '; $aliascontent.= 'else require $dolibarr_main_data_root.\'/websites/\'.$website->ref.\'/page'.$objectpage->id.'.tpl.php\';'."\n"; $aliascontent.= '?>'."\n"; $result = file_put_contents($filealias, $aliascontent); @@ -545,7 +545,7 @@ if ($action == 'updatemeta') $tplcontent.= "ob_start();\n"; $tplcontent.= "// END PHP ?>\n"; $tplcontent.= ''."\n"; - $tplcontent.= '
'."\n"; + $tplcontent.= ''."\n"; $tplcontent.= ''.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').''."\n"; $tplcontent.= ''."\n"; $tplcontent.= ''."\n"; @@ -560,7 +560,7 @@ if ($action == 'updatemeta') $tplcontent.= ''."\n"; $tplcontent.= ''."\n"; $tplcontent.= 'ref.'/htmlheader.html"); ?>'."\n"; - $tplcontent.= '
'."\n"; + $tplcontent.= ''."\n"; $tplcontent.= ''."\n"; $tplcontent.= ''."\n"; @@ -674,7 +674,7 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf $objectpage->content = GETPOST('PAGE_CONTENT'); // Clean data. We remove all the head section. - $objectpage->content = preg_replace('//s', '', $objectpage->content); + $objectpage->content = preg_replace('/.*<\/head>/s', '', $objectpage->content); /* $objectpage->content = preg_replace('//s', '', $objectpage->content); */ $res = $objectpage->update($user); @@ -743,7 +743,7 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf $tplcontent.= "ob_start();\n"; $tplcontent.= "// END PHP ?>\n"; $tplcontent.= ''."\n"; - $tplcontent.= '
'."\n"; + $tplcontent.= ''."\n"; $tplcontent.= ''.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').''."\n"; $tplcontent.= ''."\n"; $tplcontent.= ''."\n"; @@ -757,7 +757,7 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf $tplcontent.= ''."\n"; $tplcontent.= ''."\n"; $tplcontent.= 'ref.'/htmlheader.html"); ?>'."\n"; - $tplcontent.= '
'."\n"; + $tplcontent.= ''."\n"; $tplcontent.= ''."\n"; $tplcontent.= ''."\n"; From 46586f3055bfc86687f84e7e5c664ee0d9b24508 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 14:54:13 +0200 Subject: [PATCH 033/112] Can export Websites pages. Work on export to be able to use the generic declaration of fields. --- htdocs/core/commonfieldsinexport.inc.php | 60 ++++++++++++++++++ htdocs/core/extrafieldsinexport.inc.php | 6 +- htdocs/core/modules/DolibarrModules.class.php | 6 +- htdocs/core/modules/modStripe.class.php | 2 +- htdocs/core/modules/modWebsites.class.php | 19 +++++- htdocs/exports/class/export.class.php | 29 +++++---- htdocs/exports/export.php | 6 +- .../install/mysql/migration/6.0.0-7.0.0.sql | 5 ++ htdocs/install/mysql/tables/llx_website.sql | 3 +- .../install/mysql/tables/llx_website_page.sql | 5 +- htdocs/langs/en_US/website.lang | 4 +- .../template/class/myobject.class.php | 4 +- .../core/modules/modMyModule.class.php | 32 +++++----- htdocs/theme/eldy/img/object_website.png | Bin 0 -> 366 bytes htdocs/theme/md/img/object_website.png | Bin 0 -> 305 bytes htdocs/websites/class/websitepage.class.php | 26 +++++++- 16 files changed, 157 insertions(+), 50 deletions(-) create mode 100644 htdocs/core/commonfieldsinexport.inc.php create mode 100644 htdocs/theme/eldy/img/object_website.png create mode 100644 htdocs/theme/md/img/object_website.png diff --git a/htdocs/core/commonfieldsinexport.inc.php b/htdocs/core/commonfieldsinexport.inc.php new file mode 100644 index 00000000000..9a84ae6c199 --- /dev/null +++ b/htdocs/core/commonfieldsinexport.inc.php @@ -0,0 +1,60 @@ +db); + + // Add common fields + foreach($tmpobject->fields as $keyfield => $valuefield) + { + $fieldname = 't' . '.' . $keyfield; + $fieldlabel = ucfirst($valuefield['label']); + $typeFilter = "Text"; + $typefield=preg_replace('/\(.*$/', '', $valuefield['type']); // double(24,8) -> double + switch ($typefield) { + case 'int': + case 'integer': + case 'double': + case 'price': + $typeFilter = "Numeric"; + break; + case 'date': + case 'datetime': + case 'timestamp': + $typeFilter = "Date"; + break; + case 'boolean': + $typeFilter = "Boolean"; + break; + /* + * case 'sellist': + * $tmp=''; + * $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null + * if ($tmpparam['options'] && is_array($tmpparam['options'])) { + * $tmpkeys=array_keys($tmpparam['options']); + * $tmp=array_shift($tmpkeys); + * } + * if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp; + * break; + */ + } + if ($valuefield['enabled']) { + $this->export_fields_array[$r][$fieldname] = $fieldlabel; + $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; + $this->export_entities_array[$r][$fieldname] = $keyforelement; + } + } +} +else +{ + dol_print_error($this->db, 'Failed to find class '.$keyforclass.', even after the include of '.$keyforclassfile); +} +// End add common fields diff --git a/htdocs/core/extrafieldsinexport.inc.php b/htdocs/core/extrafieldsinexport.inc.php index 7f9cf523105..13b2d1ae520 100644 --- a/htdocs/core/extrafieldsinexport.inc.php +++ b/htdocs/core/extrafieldsinexport.inc.php @@ -18,15 +18,17 @@ if ($resql) // This can fail when class is used on old database (during migra $fieldname=$keyforaliasextra.'.'.$obj->name; $fieldlabel=ucfirst($obj->label); $typeFilter="Text"; - switch($obj->type) - { + $typefield=preg_replace('/\(.*$/', '', $obj->type); // double(24,8) -> double + switch ($typefield) { case 'int': + case 'integer': case 'double': case 'price': $typeFilter="Numeric"; break; case 'date': case 'datetime': + case 'timestamp': $typeFilter="Date"; break; case 'boolean': diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index a3f8676fb65..7ef1143b9f8 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -363,10 +363,6 @@ class DolibarrModules // Can not be abstract, because we need to insta - - - - /** * Constructor. Define names, constants, directories, boxes, permissions * @@ -381,6 +377,7 @@ class DolibarrModules // Can not be abstract, because we need to insta // a try catch on Fatal error to manage this correctly. // We need constructor into function unActivateModule into admin.lib.php + /** * Enables a module. * Inserts all informations into database @@ -2161,5 +2158,4 @@ class DolibarrModules // Can not be abstract, because we need to insta { return $this->_remove(array(), $options); } - } diff --git a/htdocs/core/modules/modStripe.class.php b/htdocs/core/modules/modStripe.class.php index e7e20be5b83..61fe75d8f2e 100644 --- a/htdocs/core/modules/modStripe.class.php +++ b/htdocs/core/modules/modStripe.class.php @@ -62,7 +62,7 @@ class modStripe extends DolibarrModules // Name of image file used for this module. // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue' // If file is in module/img directory, use this->picto=DOL_URL_ROOT.'/module/img/file.png' - $this->picto='stripe@stripe'; + $this->picto='stripe'; // Data directories to create when module is enabled. $this->dirs = array(); diff --git a/htdocs/core/modules/modWebsites.class.php b/htdocs/core/modules/modWebsites.class.php index 57abe371314..364e9e0fe26 100644 --- a/htdocs/core/modules/modWebsites.class.php +++ b/htdocs/core/modules/modWebsites.class.php @@ -71,7 +71,7 @@ class modWebsites extends DolibarrModules $this->depends = array('modFckeditor'); // List of modules id that must be enabled if this module is enabled $this->requiredby = array(); // List of modules id to disable if this one is disabled $this->conflictwith = array(); // List of modules id this module is in conflict with - $this->langfiles = array("websites"); + $this->langfiles = array("website"); // Constants //----------- @@ -122,5 +122,22 @@ class modWebsites extends DolibarrModules 'target'=>'', 'user'=>2); // 0=Menu for internal users, 1=external users, 2=both $r++; + + // Exports + $r=1; + + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]='MyWebsitePages'; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_icon[$r]='globe'; + $keyforclass = 'WebsitePage'; $keyforclassfile='/websites/class/websitepage.class.php'; $keyforelement='Website'; + include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php'; + //$keyforselect='myobject'; $keyforelement='myobject'; $keyforaliasextra='extra'; + //include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + //$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields) + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'website_page as t, '.MAIN_DB_PREFIX.'website as p'; + $this->export_sql_end[$r] .=' WHERE t.fk_website = p.rowid'; + $this->export_sql_end[$r] .=' AND p.entity IN ('.getEntity('website').')'; + $r++; } } diff --git a/htdocs/exports/class/export.class.php b/htdocs/exports/class/export.class.php index 4c9d6eaabb4..b1b9b42adc5 100644 --- a/htdocs/exports/class/export.class.php +++ b/htdocs/exports/class/export.class.php @@ -127,20 +127,23 @@ class Export // Test if permissions are ok $bool=true; - foreach($module->export_permission[$r] as $val) + if (isset($module->export_permission)) { - $perm=$val; - //print_r("$perm[0]-$perm[1]-$perm[2]
"); - if (! empty($perm[2])) - { - $bool=$user->rights->{$perm[0]}->{$perm[1]}->{$perm[2]}; - } - else - { - $bool=$user->rights->{$perm[0]}->{$perm[1]}; - } - if ($perm[0]=='user' && $user->admin) $bool=true; - if (! $bool) break; + foreach($module->export_permission[$r] as $val) + { + $perm=$val; + //print_r("$perm[0]-$perm[1]-$perm[2]
"); + if (! empty($perm[2])) + { + $bool=$user->rights->{$perm[0]}->{$perm[1]}->{$perm[2]}; + } + else + { + $bool=$user->rights->{$perm[0]}->{$perm[1]}; + } + if ($perm[0]=='user' && $user->admin) $bool=true; + if (! $bool) break; + } } //print $bool." $perm[0]"."
"; diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index 909db84fcb4..49c60078666 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -591,7 +591,7 @@ if ($step == 2 && $datatoexport) $i++; $entity=(! empty($objexport->array_export_entities[0][$code])?$objexport->array_export_entities[0][$code]:$objexport->array_export_icon[0]); - $entityicon=(! empty($entitytoicon[$entity])?$entitytoicon[$entity]:$entity); + $entityicon=strtolower(! empty($entitytoicon[$entity])?$entitytoicon[$entity]:$entity); $entitylang=(! empty($entitytolang[$entity])?$entitytolang[$entity]:$entity); print '
'; @@ -783,7 +783,7 @@ if ($step == 3 && $datatoexport) $i++; $entity=(! empty($objexport->array_export_entities[0][$code])?$objexport->array_export_entities[0][$code]:$objexport->array_export_icon[0]); - $entityicon=(! empty($entitytoicon[$entity])?$entitytoicon[$entity]:$entity); + $entityicon=strtolower(! empty($entitytoicon[$entity])?$entitytoicon[$entity]:$entity); $entitylang=(! empty($entitytolang[$entity])?$entitytolang[$entity]:$entity); print ''; @@ -978,7 +978,7 @@ if ($step == 4 && $datatoexport) print '
'; diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql index ba6be6291f6..be8bd9c2701 100644 --- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql +++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql @@ -32,6 +32,11 @@ ALTER TABLE llx_website_page MODIFY COLUMN pageurl varchar(255); ALTER TABLE llx_website_page ADD COLUMN lang varchar(6); ALTER TABLE llx_website_page ADD COLUMN fk_page integer; +ALTER TABLE llx_website_page MODIFY COLUMN status INTEGER DEFAULT 1; +UPDATE llx_website_page set status = 1 WHERE status IS NULL; + +ALTER TABLE llx_website ADD COLUMN import_key varchar(14); +ALTER TABLE llx_website_page ADD COLUMN import_key varchar(14); ALTER TABLE llx_fichinter ADD COLUMN import_key varchar(14); ALTER TABLE llx_livraison ADD COLUMN import_key varchar(14); ALTER TABLE llx_livraison ADD COLUMN extraparams varchar(255); diff --git a/htdocs/install/mysql/tables/llx_website.sql b/htdocs/install/mysql/tables/llx_website.sql index 84a9dd47188..7773aa469c5 100644 --- a/htdocs/install/mysql/tables/llx_website.sql +++ b/htdocs/install/mysql/tables/llx_website.sql @@ -29,5 +29,6 @@ CREATE TABLE llx_website fk_user_create integer, fk_user_modif integer, date_creation datetime, - tms timestamp + tms timestamp, + import_key varchar(14) -- import key ) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_website_page.sql b/htdocs/install/mysql/tables/llx_website_page.sql index 13ab3558c98..ec662e451f8 100644 --- a/htdocs/install/mysql/tables/llx_website_page.sql +++ b/htdocs/install/mysql/tables/llx_website_page.sql @@ -28,9 +28,10 @@ CREATE TABLE llx_website_page lang varchar(6), fk_page integer, content mediumtext, -- text is not enough in size - status integer, + status integer DEFAULT 1, fk_user_create integer, fk_user_modif integer, date_creation datetime, - tms timestamp + tms timestamp, + import_key varchar(14) -- import key ) ENGINE=innodb; diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index 82d0022b1f9..3e2d99d1503 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -40,4 +40,6 @@ ClonePage=Clone page/container CloneSite=Clone site ConfirmClonePage=Please enter code/alias of new page and if it is a translation of the cloned page. PageIsANewTranslation=The new page is a translation of the current page ? -LanguageMustNotBeSameThanClonedPage=You clone a page as a translation. The language of the new page must be different than language of source page. \ No newline at end of file +LanguageMustNotBeSameThanClonedPage=You clone a page as a translation. The language of the new page must be different than language of source page. +ParentPageId=Parent page ID +WebsiteId=Website ID \ No newline at end of file diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 83c7b6a4a61..daee7fcc879 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -61,8 +61,7 @@ class MyObject extends CommonObject /** * 'type' if the field format, 'label' the translation key, 'enabled' is a condition when the filed must be managed, * 'visible' says if field is visible in list (-1 means not shown by default but can be aded into list to be viewed) - * 'notnull' if not null in database - * 'index' if we want an index in database + * 'notnull' if not null in database, 'index' if we want an index in database * 'position' is the sort order of field * 'searchall' is 1 if we want to search in this field when making a search from the quick search button * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). @@ -86,7 +85,6 @@ class MyObject extends CommonObject 'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'notnull'=>true, 'position'=>500), 'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-1, 'position'=>500), //'fk_user_valid' =>array('type'=>'integer', 'label'=>'UserValid', 'enabled'=>1, 'visible'=>-1, 'position'=>500), - 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>true, 'position'=>500), 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-1, 'index'=>true, 'position'=>1000, 'nullifempty'=>1), ); // END MODULEBUILDER PROPERTIES diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index 5ee59c10f90..53bbfde0a70 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -276,23 +276,23 @@ class modMyModule extends DolibarrModules // Exports $r=1; - // Example: - /* BEGIN MODULEBUILDER EXPORT MYOBJECT + /* BEGIN MODULEBUILDER EXPORT MYOBJECT */ + /* + $langs->load("mymodule@mymodule"); $this->export_code[$r]=$this->rights_class.'_'.$r; - $this->export_label[$r]='MyModule'; // Translation key (used only if key ExportDataset_xxx_z not found) - $this->export_enabled[$r]='1'; // Condition to show export in list (ie: '$user->id==3'). Set to 1 to always show when module is enabled. - $this->export_icon[$r]='generic:MyModule'; // Put here code of icon then string for translation key of module name - //$this->export_permission[$r]=array(array("mymodule","level1","level2")); - $this->export_fields_array[$r]=array('t.rowid'=>"Id",'t.ref'=>'Ref','t.label'=>'Label','t.datec'=>"DateCreation",'t.tms'=>"DateUpdate"); - $this->export_TypeFields_array[$r]=array('t.rowid'=>'Numeric', 't.ref'=>'Text', 't.label'=>'Label', 't.datec'=>"Date", 't.tms'=>"Date"); - // $this->export_entities_array[$r]=array('t.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','s.fk_pays'=>'company','s.phone'=>'company','s.siren'=>'company','s.siret'=>'company','s.ape'=>'company','s.idprof4'=>'company','s.code_compta'=>'company','s.code_compta_fournisseur'=>'company','f.rowid'=>"invoice",'f.facnumber'=>"invoice",'f.datec'=>"invoice",'f.datef'=>"invoice",'f.total'=>"invoice",'f.total_ttc'=>"invoice",'f.tva'=>"invoice",'f.paye'=>"invoice",'f.fk_statut'=>'invoice','f.note'=>"invoice",'fd.rowid'=>'invoice_line','fd.description'=>"invoice_line",'fd.price'=>"invoice_line",'fd.total_ht'=>"invoice_line",'fd.total_tva'=>"invoice_line",'fd.total_ttc'=>"invoice_line",'fd.tva_tx'=>"invoice_line",'fd.qty'=>"invoice_line",'fd.date_start'=>"invoice_line",'fd.date_end'=>"invoice_line",'fd.fk_product'=>'product','p.ref'=>'product'); - // $this->export_dependencies_array[$r]=array('invoice_line'=>'fd.rowid','product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them - // $this->export_sql_start[$r]='SELECT DISTINCT '; - // $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'myobject as t'; - // $this->export_sql_order[$r] .=' ORDER BY t.ref'; - // $r++; - END MODULEBUILDER EXPORT MYOBJECT */ - + $this->export_label[$r]='MyObjectLines'; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_icon[$r]='myobject@mymodule'; + $keyforclass = 'MyObject'; $keyforclassfile='/mymobule/class/myobject.class.php'; $keyforelement='myobject'; + include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php'; + $keyforselect='myobject'; $keyforaliasextra='extra'; $keyforelement='myobject'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + //$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields) + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'myobject as t'; + $this->export_sql_end[$r] .=' WHERE 1 = 1'; + $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('myobject').')'; + $r++; */ + /* END MODULEBUILDER EXPORT MYOBJECT */ } /** diff --git a/htdocs/theme/eldy/img/object_website.png b/htdocs/theme/eldy/img/object_website.png new file mode 100644 index 0000000000000000000000000000000000000000..aae8bf6eba03015d44032e7fafb2450c05a19dda GIT binary patch literal 366 zcmV-!0g?WRP)8K(as|6!e|CXMMYM0o63^NB9)?xg%PAt5GI7U3tF}EGqiHmrf=E*ogN`4 zX7O7%p7(l=b6&@V#ITAxG;n~4f9FCUvbewtTKGmAZ}6i6_f)~MU!#T`&hdzMRqqL0 z(7{a{BY^^zv8LaLc*b@&a2#c|S;Q{pRmuLFMPAj;)Y+s{?sZm@qynvrw36DaSMJa7`{-Aa4Q#1ZTh^^Q%HRkkrvoJozl1?8$PZ@u zO=L+2kiu&)r&_3K2D^quoMKKD^Qz|QdhE<__c|~G@W z58s*iThj$=vt6$4nM|gus?;45dvQ+Ty&9z2);2y0UwjoNww9U_x2^rtlsmeo;pCN; zg=ISX!A1i!Kfo`4(XurHsM(A1C{%%`!W+4%Fp$fQgimsBg(pBJ+`voWF1Rl|$4#M6 zT6$4h>Rq23O6T4Q9iXZZ=bRiIoRY&U0Am|X%=`qu{XyH-5P-Usg-2dHdf=gudF;Qr zibTuG&Q$p3yYN|It^ujKaq`rifr?T!U41array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>true, 'index'=>true, 'position'=>1, 'comment'=>'Id'), + 'pageurl' =>array('type'=>'varchar(16)', 'label'=>'WEBSITE_PAGENAME', 'enabled'=>1, 'visible'=>1, 'notnull'=>true, 'index'=>true, 'position'=>10, 'searchall'=>1, 'comment'=>'Alias of page'), + 'title' =>array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1), + 'description' =>array('type'=>'varchar(255)', 'label'=>'Description', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1), + 'keywords' =>array('type'=>'varchar(255)', 'label'=>'Keywords', 'enabled'=>1, 'visible'=>1, 'position'=>45, 'searchall'=>0), + 'content' =>array('type'=>'mediumtext', 'label'=>'Content', 'enabled'=>1, 'visible'=>1, 'position'=>45, 'searchall'=>0), + 'lang' =>array('type'=>'varchar(6)', 'label'=>'Lang', 'enabled'=>1, 'visible'=>1, 'position'=>45, 'searchall'=>0), + //'status' =>array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'index'=>true, 'position'=>1000), + 'fk_website' =>array('type'=>'integer', 'label'=>'WebsiteId', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'searchall'=>0), + 'fk_page' =>array('type'=>'integer', 'label'=>'ParentPageId', 'enabled'=>1, 'visible'=>1, 'position'=>45, 'searchall'=>0), + 'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'notnull'=>true, 'position'=>500), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>true, 'position'=>500), + //'date_valid' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>500), + //'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'notnull'=>true, 'position'=>500), + //'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-1, 'position'=>500), + //'fk_user_valid' =>array('type'=>'integer', 'label'=>'UserValid', 'enabled'=>1, 'visible'=>-1, 'position'=>500), + 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-1, 'index'=>true, 'position'=>1000, 'nullifempty'=>1), + ); + // END MODULEBUILDER PROPERTIES /** @@ -142,7 +164,7 @@ class WebsitePage extends CommonObject $sql .= ' '.(! isset($this->lang)?'NULL':"'".$this->db->escape($this->lang)."'").','; $sql .= ' '.(empty($this->fk_page)?'NULL':$this->db->escape($this->fk_page)).','; $sql .= ' '.(! isset($this->status)?'NULL':$this->status).','; - $sql .= ' '.(! isset($this->date_creation) || dol_strlen($this->date_creation)==0?'NULL':"'".$this->db->idate($this->date_creation)."'").','; + $sql .= ' '.(! isset($this->date_creation) || dol_strlen($this->date_creation)==0?"'".$this->db->idate($now)."'":"'".$this->db->idate($this->date_creation)."'").','; $sql .= ' '.(! isset($this->date_modification) || dol_strlen($this->date_modification)==0?'NULL':"'".$this->db->idate($this->date_modification)."'"); $sql .= ')'; From 8bba9fa14941477717967bab97016cccbca07e5d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 15:32:15 +0200 Subject: [PATCH 034/112] Factorize duplicate code --- htdocs/websites/index.php | 165 ++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 89 deletions(-) diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index 15fed80ebf7..712a5a2dabb 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -529,52 +529,8 @@ if ($action == 'updatemeta') if (! $result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); - - // Now create the .tpl file (duplicate code with actions updatesource or updatecontent but we need this to save new header) - dol_syslog("We regenerate the tpl page filetpl=".$filetpl); - - dol_delete_file($filetpl); - - // TODO Same code than into updatesource updatecontent - $tplcontent =''; - $tplcontent.= "\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= 'ref.'/htmlheader.html"); ?>'."\n"; - $tplcontent.= ''."\n"; - - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= $objectpage->content."\n"; - $tplcontent.= ''."\n"; - - $tplcontent.= '"."\n"; - - //var_dump($filetpl);exit; - $result = file_put_contents($filetpl, $tplcontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filetpl, octdec($conf->global->MAIN_UMASK)); + // Save page of content + $result=dolSavePageContent($filetpl, $object, $objectpage); if ($result) { @@ -582,7 +538,12 @@ if ($action == 'updatemeta') //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); //exit; } - else setEventMessages('Failed to write file '.$filetpl, null, 'errors'); + else + { + setEventMessages('Failed to write file '.$filetpl, null, 'errors'); + //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + //exit; + } $action='preview'; } @@ -730,48 +691,8 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf if (! $result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); - // Now create the .tpl file with code to be able to make dynamic changes - dol_delete_file($filetpl); - - // TODO Same code than into updatemeta - $tplcontent =''; - $tplcontent.= "\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= 'ref.'/htmlheader.html"); ?>'."\n"; - $tplcontent.= ''."\n"; - - $tplcontent.= ''."\n"; - $tplcontent.= ''."\n"; - $tplcontent.= $objectpage->content."\n"; - $tplcontent.= ''."\n"; - - $tplcontent.= '"."\n"; - - //var_dump($filetpl);exit; - $result = file_put_contents($filetpl, $tplcontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filetpl, octdec($conf->global->MAIN_UMASK)); + // Save page content + $result=dolSavePageContent($filetpl, $object, $objectpage); if ($result) { @@ -1447,3 +1368,69 @@ if ($action == 'preview' || $action == 'createpagefromclone') llxFooter(); $db->close(); + + + + +/** + * Save content of a page on disk + * + * @param string $filetpl Full path of filename to generate + * @param Website $object Object website + * @param WebsitePage $objectpage Object websitepage + * @return boolean True if OK + */ +function dolSavePageContent($filetpl, $object, $objectpage) +{ + global $conf; + + // Now create the .tpl file (duplicate code with actions updatesource or updatecontent but we need this to save new header) + dol_syslog("We regenerate the tpl page filetpl=".$filetpl); + + dol_delete_file($filetpl); + + // TODO Same code than into updatemeta + $shortlangcode = ''; + if ($objectpage->lang) $shortlangcode=preg_replace('/[_-].*$/', '', $objectpage->lang); // en_US or en-US -> en + + $tplcontent =''; + $tplcontent.= "\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= 'ref.'/htmlheader.html"); ?>'."\n"; + $tplcontent.= ''."\n"; + + $tplcontent.= ''."\n"; + $tplcontent.= ''."\n"; + $tplcontent.= $objectpage->content."\n"; + $tplcontent.= ''."\n"; + + $tplcontent.= '"."\n"; + + //var_dump($filetpl);exit; + $result = file_put_contents($filetpl, $tplcontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filetpl, octdec($conf->global->MAIN_UMASK)); + + return $result; +} \ No newline at end of file From b0e62f9d248bb8cf677d12362f8f129ca6511a5d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 17:17:40 +0200 Subject: [PATCH 035/112] Enhance image replacement --- htdocs/core/lib/website.lib.php | 21 ++++++++++---- htdocs/langs/en_US/website.lang | 7 +++-- htdocs/public/websites/index.php | 2 +- htdocs/public/websites/styles.css.php | 2 ++ htdocs/websites/index.php | 40 +++++++++++++++++---------- 5 files changed, 49 insertions(+), 23 deletions(-) diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index 354da07c6f2..a60be612e2d 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -33,14 +33,16 @@ function dolWebsiteOutput($content) global $db, $langs, $conf, $user; global $dolibarr_main_url_root, $dolibarr_main_data_root; - dol_syslog("dolWebsiteOutput start"); + dol_syslog("dolWebsiteOutput start (mode=".(defined('USEDOLIBARRSERVER')?'USEDOLIBARRSERVER':'').')'); // Define $urlwithroot $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current - if (! defined('USEDOLIBARRSERVER')) + // Note: This seems never called when page is output inside the website editor (search 'REPLACEMENT OF LINKS When page called by website editor') + + if (! defined('USEDOLIBARRSERVER')) // REPLACEMENT OF LINKS When page called from virtual host { $symlinktomediaexists=1; @@ -52,6 +54,7 @@ function dolWebsiteOutput($content) if (! $symlinktomediaexists) { $content=preg_replace('/()/', '\1'.$urlwithroot.'/viewimage.php\2modulepart=medias\3file=\4\5', $content, -1, $nbrep); + $content=preg_replace('/(url\(["\']?)[^\)]*viewimage\.php([^\)]*)modulepart=medias([^\)]*)file=([^\)]*)(["\']?\))/', '\1'.$urlwithroot.'/viewimage.php\2modulepart=medias\3file=\4\5', $content, -1, $nbrep); } else { @@ -59,14 +62,22 @@ function dolWebsiteOutput($content) $content=preg_replace('/(url\(["\']?)[^\)]*viewimage\.php([^\)]*)modulepart=medias([^\)]*)file=([^\)]*)(["\']?\))/', '\1medias/\4\5', $content, -1, $nbrep); } } - else + else // REPLACEMENT OF LINKS When page called from dolibarr server { global $website; - // Replace relative link / with dolibarr URL + // Replace relative link / with dolibarr URL: ...href="/"... $content=preg_replace('/(href=")\/\"/', '\1'.DOL_URL_ROOT.'/public/websites/index.php?website='.$website->ref.'&pageid='.$website->fk_default_home.'"', $content, -1, $nbrep); - // Replace relative link /xxx.php with dolibarr URL + // Replace relative link /xxx.php with dolibarr URL: ...href="....php" $content=preg_replace('/(href=")\/?([^\"]*)(\.php\")/', '\1'.DOL_URL_ROOT.'/public/websites/index.php?website='.$website->ref.'&pageref=\2"', $content, -1, $nbrep); + + // Fix relative link /document.php with correct URL after the DOL_URL_ROOT: ...href="/document.php?modulepart=" + $content=preg_replace('/(href=")(\/?document\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1'.DOL_URL_ROOT.'\2\3"', $content, -1, $nbrep); + // Fix relative link /viewimage.php with correct URL after the DOL_URL_ROOT: ...href="/viewimage.php?modulepart=" + $content=preg_replace('/(href=")(\/?viewimage\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1'.DOL_URL_ROOT.'\2\3"', $content, -1, $nbrep); + + // Fix relative link into medias with correct URL after the DOL_URL_ROOT: ../url("medias/ + $content=preg_replace('/url\((["\']?)medias\//', 'url(\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep); } dol_syslog("dolWebsiteOutput end"); diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index 3e2d99d1503..9e0ded40602 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -33,13 +33,14 @@ PreviewSiteServedByWebServer=Preview %s in a new tab.

The %s will be serv PreviewSiteServedByDolibarr=Preview %s in a new tab.

The %s will be served by Dolibarr server so it does not need any extra web server (like Apache, Nginx, IIS) to be installed.
The inconvenient is that URL of pages are not user friendly and start with path of your Dolibarr.
URL served by Dolibarr:
%s

To use your own external web server to serve this web site, create a virtual host on your web server that point on directory
%s
then enter the name of this virtual server and click on the other preview button. VirtualHostUrlNotDefined=URL of the virtual host served by external web server not defined NoPageYet=No pages yet -SyntaxHelp=Help on code syntax +SyntaxHelp=Help on specific syntax tips YouCanEditHtmlSourceckeditor=You can edit HTML source code using the "Source" button in editor. -YouCanEditHtmlSource=You can include PHP code into this source using tags <?php ?>. The following global variables are available: $conf, $langs, $db, $mysoc, $user, $website.

You can also include content of another Page/Container with the following syntax: <?php dolIncludeHtmlContent($websitekey.'/contentaliastoinclude.php'); ?>

To include a link to download a file stored into the documents/medias directory, use syntax:
<a href="/document.php?modulepart=medias&file=filename.ext">. +YouCanEditHtmlSource=You can include PHP code into this source using tags <?php ?>. The following global variables are available: $conf, $langs, $db, $mysoc, $user, $website.

You can also include content of another Page/Container with the following syntax: <?php dolIncludeHtmlContent($websitekey.'/contentaliastoinclude.php'); ?>

To include a link to download a file stored into the documents directory, use the document.php wrapper:
Example, for a file into documents/ecm (need to be logged), syntax is:
<a href="/document.php?modulepart=ecm&file=reldir/filename.ext">.
for a file into documents/media (open access), syntax is:
<a href="/document.php?modulepart=medias&file=reldir/filename.ext">.

To include an image stored into the documents directory, use the viewimage.php wrapper:
Example, for an image into documents/media (open access), syntax is:
<a href="/viewimage.php?modulepart=medias&file=filename.ext">. ClonePage=Clone page/container CloneSite=Clone site ConfirmClonePage=Please enter code/alias of new page and if it is a translation of the cloned page. PageIsANewTranslation=The new page is a translation of the current page ? LanguageMustNotBeSameThanClonedPage=You clone a page as a translation. The language of the new page must be different than language of source page. ParentPageId=Parent page ID -WebsiteId=Website ID \ No newline at end of file +WebsiteId=Website ID + diff --git a/htdocs/public/websites/index.php b/htdocs/public/websites/index.php index 84e0a72f9fd..81b5f985186 100644 --- a/htdocs/public/websites/index.php +++ b/htdocs/public/websites/index.php @@ -190,7 +190,7 @@ if (! file_exists($original_file_osencoded)) // Output page content define('USEDOLIBARRSERVER', 1); -print ''."\n"; +print ''."\n"; include_once $original_file_osencoded; diff --git a/htdocs/public/websites/styles.css.php b/htdocs/public/websites/styles.css.php index 14014577cea..7fe80f9b66e 100644 --- a/htdocs/public/websites/styles.css.php +++ b/htdocs/public/websites/styles.css.php @@ -139,6 +139,8 @@ if (! file_exists($original_file_osencoded)) // Output page content +define('USEDOLIBARRSERVER', 1); +print '/* Page content '.$original_file.' : CSS content that was saved into tpl dir */'."\n"; require_once $original_file_osencoded; diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index 712a5a2dabb..3c64c0f287d 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -1304,31 +1304,24 @@ if ($action == 'preview' || $action == 'createpagefromclone') { // Ouput page under the Dolibarr top menu $objectpage->fetch($pageid); + $csscontent = @file_get_contents($filecss); $out = ''."\n"; $out.='
'."\n"; - $csscontent = @file_get_contents($filecss); + // REPLACEMENT OF LINKS When page called by website editor $out.=''."\n"; $out.='
'."\n"; - // Replace php code. Note $objectpage->content come from database and does not contains body tags. - $content = preg_replace('/<\?php[^\?]+\?>\n*/ims', '...php...', $objectpage->content); - - // Replace relative link / with dolibarr URL - $content = preg_replace('/(href=")\/\"/', '\1'.DOL_URL_ROOT.'/websites/index.php?website='.$object->ref.'&pageid='.$object->fk_default_home.'"', $content, -1, $nbrep); - // Replace relative link /xxx.php with dolibarr URL - $content = preg_replace('/(href=")\/?([^\"]*)(\.php\")/', '\1'.DOL_URL_ROOT.'/websites/index.php?website='.$object->ref.'&pageref=\2"', $content, -1, $nbrep); - - - $out.=$content."\n"; + $out.=dolWebsiteReplacementOfLinks($objectpage->content)."\n"; $out.='
'; + $out.='
'; $out.= "\n".''."\n\n"; @@ -1371,6 +1364,26 @@ $db->close(); +/** + * Save content of a page on disk + * + * @param string $content Content to replace + * @return boolean True if OK + */ +function dolWebsiteReplacementOfLinks($content) +{ + // Replace php code. Note $objectpage->content come from database and does not contains body tags. + $content = preg_replace('/<\?php[^\?]+\?>\n*/ims', '...php...', $content); + + // Replace relative link / with dolibarr URL + $content = preg_replace('/(href=")\/\"/', '\1'.DOL_URL_ROOT.'/websites/index.php?website='.$object->ref.'&pageid='.$object->fk_default_home.'"', $content, -1, $nbrep); + // Replace relative link /xxx.php with dolibarr URL + $content = preg_replace('/(href=")\/?([^\"]*)(\.php\")/', '\1'.DOL_URL_ROOT.'/websites/index.php?website='.$object->ref.'&pageref=\2"', $content, -1, $nbrep); + + $content = preg_replace('/url\((["\']?)medias\//', 'url(\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep); + + return $content; +} /** * Save content of a page on disk @@ -1389,7 +1402,6 @@ function dolSavePageContent($filetpl, $object, $objectpage) dol_delete_file($filetpl); - // TODO Same code than into updatemeta $shortlangcode = ''; if ($objectpage->lang) $shortlangcode=preg_replace('/[_-].*$/', '', $objectpage->lang); // en_US or en-US -> en @@ -1433,4 +1445,4 @@ function dolSavePageContent($filetpl, $object, $objectpage) @chmod($filetpl, octdec($conf->global->MAIN_UMASK)); return $result; -} \ No newline at end of file +} From 25c5ed8f7232d96d020898580bda8c2e050e74f7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 18:09:38 +0200 Subject: [PATCH 036/112] Fix for compatibility --- htdocs/core/lib/ajax.lib.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 705bcf6deab..76a1458b913 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -46,6 +46,12 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLengt { if (empty($minLength)) $minLength=1; + $dataforrenderITem='ui-autocomplete'; + $dataforitem='ui-autocomplete-item'; + // Allow two constant to use other values for backward compatibility + if (defined('JS_QUERY_AUTOCOMPLETE_RENDERITEM')) $dataforrenderITem=constant('JS_QUERY_AUTOCOMPLETE_RENDERITEM'); + if (defined('JS_QUERY_AUTOCOMPLETE_ITEM')) $dataforitem=constant('JS_QUERY_AUTOCOMPLETE_ITEM'); + // Input search_htmlname is original field // Input htmlname is a second input field used when using ajax autocomplete. $script = ''; @@ -185,10 +191,10 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLengt $("#search_'.$htmlname.'").trigger("change"); // We have changed value of the combo select, we must be sure to trigger all js hook binded on this event. This is required to trigger other javascript change method binded on original field by other code. } ,delay: 500 - }).data("ui-autocomplete")._renderItem = function( ul, item ) { + }).data("'.$dataforrenderITem.'")._renderItem = function( ul, item ) { return $("
  • ") - .data( "ui-autocomplete-item", item ) // jQuery UI > 1.10.0 + .data( "'.$dataforitem.'", item ) // jQuery UI > 1.10.0 .append( \'\' + item.label + "" ) .appendTo(ul); }; From 6253986ae510c0ef2d48b8ae5f869563b26e94fb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 23:32:29 +0200 Subject: [PATCH 037/112] Fix translation source --- htdocs/langs/en_US/multicurrency.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/multicurrency.lang b/htdocs/langs/en_US/multicurrency.lang index c53c3aef460..a1e5025fa9d 100644 --- a/htdocs/langs/en_US/multicurrency.lang +++ b/htdocs/langs/en_US/multicurrency.lang @@ -10,7 +10,7 @@ CurrencyLayerAccount=CurrencyLayer API CurrencyLayerAccount_help_to_synchronize=You sould create an account on their website to use this functionnality
    Get your API key
    If you use a free account you can't change the currency source (USD by default)
    But if your main currency isn't USD you can use the alternate currency source to force you main currency

    You are limited at 1000 synchronizations per month multicurrency_appId=API key multicurrency_appCurrencySource=Currency source -multicurrency_alternateCurrencySource= Alternate currency souce +multicurrency_alternateCurrencySource=Alternate currency source CurrenciesUsed=Currencies used CurrenciesUsed_help_to_add=Add the differents currencies and rates you need to use on you proposals, orders, etc. rate=rate From 5e17c2efb90cbdd0d6f3bb90529a15714cb489c6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 23:32:55 +0200 Subject: [PATCH 038/112] Fix into filters of time consumed --- htdocs/core/lib/project.lib.php | 4 +++ htdocs/projet/activity/perday.php | 43 ++++++++++++++++++++++----- htdocs/projet/activity/perweek.php | 47 ++++++++++++++++++++++++------ htdocs/projet/list.php | 4 +-- 4 files changed, 79 insertions(+), 19 deletions(-) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index c3583e72ac8..366413c376f 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -629,9 +629,11 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr print '
  • '; print $fuser->getNomUrl(1, 'withproject', 'time'); print ''; @@ -835,9 +837,11 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ print '
    '; print $fuser->getNomUrl(1, 'withproject', 'time'); print ''; diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index a7b243dd338..7b1f50bb50c 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -64,6 +64,7 @@ $day=GETPOST('reday')?GETPOST('reday'):(GETPOST("day","int")?GETPOST("day","int" $day = (int) $day; $week=GETPOST("week","int")?GETPOST("week","int"):date("W"); +$search_categ=GETPOST("search_categ",'alpha'); $search_usertoprocessid=GETPOST('search_usertoprocessid', 'int'); $search_task_ref=GETPOST('search_task_ref', 'alpha'); $search_task_label=GETPOST('search_task_label', 'alpha'); @@ -100,13 +101,14 @@ $object=new Task($db); if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers { $action = ''; + $search_categ=''; $search_usertoprocessid = ''; $search_task_ref = ''; $search_task_label = ''; $search_project_ref = ''; $search_thirdparty = ''; } -if (GETPOST("button_search_x") || GETPOST("button_search.x") || GETPOST("button_search")) +if (GETPOST("button_search_x",'alpha') || GETPOST("button_search.x",'alpha') || GETPOST("button_search",'alpha')) { $action = ''; } @@ -394,15 +396,41 @@ print ''; print '
    '; +$moreforfilter=''; + +// Filter on categories +/*if (! empty($conf->categorie->enabled)) +{ + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $moreforfilter.='
    '; + $moreforfilter.=$langs->trans('ProjectCategories'). ': '; + $moreforfilter.=$formother->select_categories('project', $search_categ, 'search_categ', 1, 1, 'maxwidth300'); + $moreforfilter.='
    '; +}*/ + +// If the user can view user other than himself +$moreforfilter.='
    '; +$moreforfilter.=$langs->trans('ProjectsWithThisUserAsContact'). ': '; +$includeonly='hierachyme'; +if (empty($user->rights->user->user->lire)) $includeonly=array($user->id); +$moreforfilter.=$form->select_dolusers($search_project_user?$search_project_user:$usertoprocess->id, 'search_usertoprocessid', 0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200'); +$moreforfilter.='
    '; + +if (! empty($moreforfilter)) +{ + print '
    '; + print $moreforfilter; + $parameters=array(); + $reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print '
    '; +} + + print '
    '; print ''."\n"; print ''; -print ''; print ''; print ''; print ''; @@ -422,7 +450,6 @@ print ''; print "\n"; print ''; -print ''; print ''; print ''; print ''; @@ -454,7 +481,7 @@ if (count($tasksarray) > 0) } else { - print ''; + print ''; } print "
    '; -$usersettoshow='hierarchyme'; -if ($user->rights->projet->all->lire) $usersettoshow=''; -print $form->select_dolusers($usertoprocess->id, 'search_usertoprocessid', 0, null, 0, $usersettoshow, 0, 0, 0, 1, '', 0, '', 'maxwidth150'); -print '
    '.$langs->trans("User").''.$langs->trans("RefTask").''.$langs->trans("LabelTask").''.$langs->trans("ProjectRef").'
    '.$langs->trans("NoTasks").'
    '.$langs->trans("NoTasks").'
    "; print '
    '; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index 5f3e9b1aa20..3410ba1d949 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -65,6 +65,7 @@ $day=GETPOST('reday')?GETPOST('reday','int'):(GETPOST("day")?GETPOST("day","int" $day = (int) $day; $week=GETPOST("week","int")?GETPOST("week","int"):date("W"); +$search_categ=GETPOST("search_categ",'alpha'); $search_usertoprocessid=GETPOST('search_usertoprocessid', 'int'); $search_task_ref=GETPOST('search_task_ref', 'alpha'); $search_task_label=GETPOST('search_task_label', 'alpha'); @@ -113,13 +114,14 @@ $object=new Task($db); if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers { $action = ''; + $search_categ=''; $search_usertoprocessid = ''; $search_task_ref = ''; $search_task_label = ''; $search_project_ref = ''; $search_thirdparty = ''; } -if (GETPOST("button_search_x") || GETPOST("button_search.x") || GETPOST("button_search")) +if (GETPOST("button_search_x",'alpha') || GETPOST("button_search.x",'alpha') || GETPOST("button_search",'alpha')) { $action = ''; } @@ -313,6 +315,7 @@ $morewherefilter=''; if ($search_task_ref) $morewherefilter.=natural_search("t.ref", $search_task_ref); if ($search_task_label) $morewherefilter.=natural_search("t.label", $search_task_label); if ($search_thirdparty) $morewherefilter.=natural_search("s.nom", $search_thirdparty); + $tasksarray=$taskstatic->getTasksArray(0, 0, ($project->id?$project->id:0), $socid, 0, $search_project_ref, $onlyopenedproject, $morewherefilter); // We want to see all task of opened project i am allowed to see, not only mine. Later only mine will be editable later. $projectsrole=$taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, 0, ($project->id?$project->id:0), 0, $onlyopenedproject); $tasksrole=$taskstatic->getUserRolesForProjectsOrTasks(0, $usertoprocess, ($project->id?$project->id:0), 0, $onlyopenedproject); @@ -387,15 +390,42 @@ print ''; print '
    '; +$moreforfilter=''; + +// Filter on categories +/* +if (! empty($conf->categorie->enabled)) +{ + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $moreforfilter.='
    '; + $moreforfilter.=$langs->trans('ProjectCategories'). ': '; + $moreforfilter.=$formother->select_categories('project', $search_categ, 'search_categ', 1, 1, 'maxwidth300'); + $moreforfilter.='
    '; +}*/ + +// If the user can view user other than himself +$moreforfilter.='
    '; +$moreforfilter.=$langs->trans('ProjectsWithThisUserAsContact'). ': '; +$includeonly='hierachyme'; +if (empty($user->rights->user->user->lire)) $includeonly=array($user->id); +$moreforfilter.=$form->select_dolusers($search_project_user?$search_project_user:$usertoprocess->id, 'search_usertoprocessid', 0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200'); +$moreforfilter.='
    '; + +if (! empty($moreforfilter)) +{ + print '
    '; + print $moreforfilter; + $parameters=array(); + $reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print '
    '; +} + + print '
    '; print ''."\n"; print ''; -print ''; print ''; print ''; print ''; @@ -416,7 +446,6 @@ print ''; print "\n"; print ''; -print ''; print ''; print ''; print ''; @@ -453,7 +482,7 @@ if (count($tasksarray) > 0) $level=0; projectLinesPerWeek($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask); - $colspan=8; + $colspan=7; if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) $colspan++; print ' @@ -470,7 +499,7 @@ if (count($tasksarray) > 0) } else { - print ''; + print ''; } print "
    '; -$usersettoshow='hierarchyme'; -if ($user->rights->projet->all->lire) $usersettoshow=''; -print $form->select_dolusers($usertoprocess->id, 'search_usertoprocessid', 0, null, 0, $usersettoshow, 0, 0, 0, 1, '', 0, '', 'maxwidth150'); -print '
    '.$langs->trans("User").''.$langs->trans("RefTask").''.$langs->trans("LabelTask").''.$langs->trans("ProjectRef").'
    '.$langs->trans("NoTasks").'
    '.$langs->trans("NoTasks").'
    "; print '
    '; diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 1bf65decd71..9e2971195e3 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -371,6 +371,7 @@ llxHeader("", $title, $help_url); $param=''; if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; +if ($search_all != '') $param.='&search_all='.$search_all; if ($search_sday) $param.='&search_sday='.$search_sday; if ($search_smonth) $param.='&search_smonth='.$search_smonth; if ($search_syear) $param.='&search_syear=' .$search_syear; @@ -378,7 +379,6 @@ if ($search_eday) $param.='&search_eday='.$search_eday; if ($search_emonth) $param.='&search_emonth='.$search_emonth; if ($search_eyear) $param.='&search_eyear=' .$search_eyear; if ($socid) $param.='&socid='.$socid; -if ($search_all != '') $param.='&search_all='.$search_all; if ($search_ref != '') $param.='&search_ref='.$search_ref; if ($search_label != '') $param.='&search_label='.$search_label; if ($search_societe != '') $param.='&search_societe='.$search_societe; @@ -451,7 +451,7 @@ if (! empty($conf->categorie->enabled)) // If the user can view user other than himself $moreforfilter.='
    '; $moreforfilter.=$langs->trans('ProjectsWithThisUserAsContact'). ': '; -$includeonly=''; +$includeonly='hierachyme'; if (empty($user->rights->user->user->lire)) $includeonly=array($user->id); $moreforfilter.=$form->select_dolusers($search_project_user?$search_project_user:'', 'search_project_user', 1, '', 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth200'); $moreforfilter.='
    '; From af63dc76c1c4d00f4e115e3f3ae6fd27cbbfefcf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 28 Jul 2017 23:46:11 +0200 Subject: [PATCH 039/112] Fix flex problems --- htdocs/theme/eldy/style.css.php | 2 +- htdocs/theme/md/style.css.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 7bd3d913782..cd2c0f95582 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2805,7 +2805,7 @@ div.tabBar .noborder { } .boxstats { padding: 3px; - width: 105px; + width: 103px; } .boxstats130 { width: 160px; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index b190a3fad67..cf787f09071 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2889,7 +2889,7 @@ div .tdtop { } .boxstats { padding: 3px; - width: 105px; + width: 100px; } .boxstats130 { width: 135px; From 8b82fc3c708ccb03b2fd1303ec5c3444b86646be Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 29 Jul 2017 00:28:41 +0200 Subject: [PATCH 040/112] Fix project edition on loan menu Fix translation on profit view of projects. --- htdocs/loan/card.php | 36 +++++++++++++++++++----------------- htdocs/loan/document.php | 34 ++++++++++++++++++++++++++++++++-- htdocs/loan/info.php | 34 ++++++++++++++++++++++++++++++++-- htdocs/loan/note.php | 34 ++++++++++++++++++++++++++++++++-- htdocs/projet/element.php | 32 ++++++++++++++++---------------- 5 files changed, 131 insertions(+), 39 deletions(-) diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 29cea1eb019..4f61aa833bf 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -41,6 +41,8 @@ $action=GETPOST('action','aZ09'); $confirm=GETPOST('confirm'); $cancel=GETPOST('cancel','alpha'); +$projectid = GETPOST('projectid','int'); + // Security check $socid = GETPOST('socid','int'); if ($user->societe_id) $socid=$user->societe_id; @@ -133,7 +135,7 @@ if (empty($reshook)) $object->rate = $rate; $object->note_private = GETPOST('note_private'); $object->note_public = GETPOST('note_public'); - $object->fk_project = GETPOST('fk_project'); + $object->fk_project = GETPOST('projectid','int'); $accountancy_account_capital = GETPOST('accountancy_account_capital'); $accountancy_account_insurance = GETPOST('accountancy_account_insurance'); @@ -215,7 +217,7 @@ if (empty($reshook)) if ($action == 'classin' && $user->rights->loan->write) { $object->fetch($id); - $result = $object->setProject(GETPOST('projectid')); + $result = $object->setProject($projectid); if ($result < 0) setEventMessages($object->error, $object->errors, 'errors'); } @@ -309,7 +311,7 @@ if ($action == 'create') print '
    '.$langs->trans("Project").''; - $numproject=$formproject->select_projects(-1,GETPOST("fk_project"),'fk_project',16,0,1,1); + $numproject=$formproject->select_projects(-1, $projectid, 'projectid', 16, 0, 1, 1); print '
    '.$langs->trans($newclassname).''.$name.''.$i.''; if ($tablename == 'expensereport_det') @@ -922,7 +922,7 @@ foreach ($listofreferent as $key => $value) print dol_print_date($element->datep,'dayhour'); if ($element->datef && $element->datef > $element->datep) print " - ".dol_print_date($element->datef,'dayhour'); } - else if (in_array($tablename, array('projet_task'))) + else if (in_array($tablename, array('projet_task'))) { $tmpprojtime = $element->getSumOfAmount($elementuser, $dates, $datee); // $element is a task. $elementuser may be empty print ''; @@ -1018,7 +1018,7 @@ foreach ($listofreferent as $key => $value) else { $othermessage=$form->textwithpicto($langs->trans("NotAvailable"), $langs->trans("ModuleSalaryToDefineHourlyRateMustBeEnabled")); - } + } } else { @@ -1074,8 +1074,8 @@ foreach ($listofreferent as $key => $value) $total_ht_by_third += $total_ht_by_line; $total_ttc_by_third += $total_ttc_by_line; - - $total_time = $total_time + $total_time_by_line; + + $total_time = $total_time + $total_time_by_line; } if (canApplySubtotalOn($tablename)) @@ -1115,7 +1115,7 @@ foreach ($listofreferent as $key => $value) //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print ''.$langs->trans("TotalHT").' : '.price($total_ht).''.$langs->trans("Total").' : '.price($total_ht).''; - if (empty($value['disableamount'])) + if (empty($value['disableamount'])) { if ($tablename != 'projet_task' || ! empty($conf->salaries->enabled)) print ''.$langs->trans("TotalHT").' : '.price($total_ht); } @@ -1123,7 +1123,7 @@ foreach ($listofreferent as $key => $value) //if (empty($value['disableamount']) && ! in_array($tablename, array('projet_task'))) print ''.$langs->trans("TotalTTC").' : '.price($total_ttc).''; - if (empty($value['disableamount'])) + if (empty($value['disableamount'])) { if ($tablename != 'projet_task' || ! empty($conf->salaries->enabled)) print $langs->trans("TotalTTC").' : '.price($total_ttc); } From cae21d3937684cb77488a4eda2012e30fcde2529 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 29 Jul 2017 01:59:26 +0200 Subject: [PATCH 041/112] Fix in agenda output per user/type (reduce memory usage) --- htdocs/comm/action/pertype.php | 61 ++++++++++++++----------- htdocs/comm/action/peruser.php | 81 ++++++++++++++++++--------------- htdocs/projet/ganttview.php | 42 ++++++++--------- htdocs/theme/eldy/style.css.php | 9 ++++ htdocs/theme/md/style.css.php | 11 +++++ 5 files changed, 120 insertions(+), 84 deletions(-) diff --git a/htdocs/comm/action/pertype.php b/htdocs/comm/action/pertype.php index cd96a4fa8ad..589a2731f1b 100644 --- a/htdocs/comm/action/pertype.php +++ b/htdocs/comm/action/pertype.php @@ -38,7 +38,7 @@ if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class if (! isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW=3; -$filter = GETPOST("filter",'',3); +$filter = GETPOST("filter",'alpha',3); $filtert = GETPOST("filtert","int",3); $usergroup = GETPOST("usergroup","int",3); //if (! ($usergroup > 0) && ! ($filtert > 0)) $filtert = $user->id; @@ -82,9 +82,9 @@ $month=GETPOST("month","int")?GETPOST("month","int"):date("m"); $week=GETPOST("week","int")?GETPOST("week","int"):date("W"); $day=GETPOST("day","int")?GETPOST("day","int"):date("d"); $pid=GETPOST("projectid","int",3); -$status=GETPOST("status"); -$type=GETPOST("type"); -$maxprint=(isset($_GET["maxprint"])?GETPOST("maxprint"):$conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); +$status=GETPOST("status",'alpha'); +$type=GETPOST("type",'alpha'); +$maxprint=((GETPOST("maxprint",'int')!='')?GETPOST("maxprint",'int'):$conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); // Set actioncode (this code must be same for setting actioncode into peruser, listacton and index) if (GETPOST('actioncode','array')) { @@ -97,18 +97,18 @@ else } if ($actioncode == '' && empty($actioncodearray)) $actioncode=(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE); -$dateselect=dol_mktime(0, 0, 0, GETPOST('dateselectmonth'), GETPOST('dateselectday'), GETPOST('dateselectyear')); +$dateselect=dol_mktime(0, 0, 0, GETPOST('dateselectmonth','int'), GETPOST('dateselectday','int'), GETPOST('dateselectyear','int')); if ($dateselect > 0) { - $day=GETPOST('dateselectday'); - $month=GETPOST('dateselectmonth'); - $year=GETPOST('dateselectyear'); + $day=GETPOST('dateselectday','int'); + $month=GETPOST('dateselectmonth','int'); + $year=GETPOST('dateselectyear','int'); } $tmp=empty($conf->global->MAIN_DEFAULT_WORKING_HOURS)?'9-18':$conf->global->MAIN_DEFAULT_WORKING_HOURS; $tmparray=explode('-',$tmp); -$begin_h = GETPOST('begin_h')!=''?GETPOST('begin_h','int'):($tmparray[0] != '' ? $tmparray[0] : 9); -$end_h = GETPOST('end_h')?GETPOST('end_h'):($tmparray[1] != '' ? $tmparray[1] : 18); +$begin_h = GETPOST('begin_h','int')!=''?GETPOST('begin_h','int'):($tmparray[0] != '' ? $tmparray[0] : 9); +$end_h = GETPOST('end_h','int')?GETPOST('end_h','int'):($tmparray[1] != '' ? $tmparray[1] : 18); if ($begin_h < 0 || $begin_h > 23) $begin_h = 9; if ($end_h < 1 || $end_h > 24) $end_h = 18; if ($end_h <= $begin_h) $end_h = $begin_h + 1; @@ -124,13 +124,13 @@ if (empty($action) && ! isset($_GET['action']) && ! isset($_POST['action'])) $ac if (GETPOST('viewcal') && $action != 'show_day' && $action != 'show_week' && $action != 'show_peruser') { $action='show_month'; $day=''; } // View by month -if (GETPOST('viewweek') || $action == 'show_week') { +if (GETPOST('viewweek','alpha') || $action == 'show_week') { $action='show_week'; $week=($week?$week:date("W")); $day=($day?$day:date("d")); } // View by week -if (GETPOST('viewday') || $action == 'show_day') { +if (GETPOST('viewday','alpha') || $action == 'show_day') { $action='show_day'; $day=($day?$day:date("d")); } // View by day -if (GETPOST('viewyear') || $action == 'show_year') { +if (GETPOST('viewyear','alpha') || $action == 'show_year') { $action='show_year'; } // View by year @@ -161,12 +161,12 @@ if ($action =='delete_action') * View */ -$help_url='EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda'; -llxHeader('',$langs->trans("Agenda"),$help_url); - $form=new Form($db); $companystatic=new Societe($db); +$help_url='EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda'; +llxHeader('',$langs->trans("Agenda"),$help_url); + $now=dol_now(); $nowarray=dol_getdate($now); $nowyear=$nowarray['year']; @@ -456,11 +456,14 @@ if ($resql) continue; } + $datep=$db->jdate($obj->datep); + $datep2=$db->jdate($obj->datep2); + // Create a new object action $event=new ActionComm($db); $event->id=$obj->id; - $event->datep=$db->jdate($obj->datep); // datep and datef are GMT date - $event->datef=$db->jdate($obj->datep2); + $event->datep=$datep; // datep and datef are GMT date + $event->datef=$datep2; $event->type_code=$obj->code; $event->type_color=$obj->color; //$event->libelle=$obj->label; // deprecated @@ -469,7 +472,6 @@ if ($resql) //$event->author->id=$obj->fk_user_author; // user id of creator $event->authorid=$obj->fk_user_author; // user id of creator $event->userownerid=$obj->fk_user_action; // user id of owner - $event->fetch_userassigned(); // This load $event->userassigned $event->priority=$obj->priority; $event->fulldayevent=$obj->fulldayevent; $event->location=$obj->location; @@ -487,15 +489,15 @@ if ($resql) // They are date start and end of action but modified to not be outside calendar view. if ($event->percentage <= 0) { - $event->date_start_in_calendar=$event->datep; - if ($event->datef != '' && $event->datef >= $event->datep) $event->date_end_in_calendar=$event->datef; - else $event->date_end_in_calendar=$event->datep; + $event->date_start_in_calendar=$datep; + if ($datep2 != '' && $datep2 >= $datep) $event->date_end_in_calendar=$datep2; + else $event->date_end_in_calendar=$datep; } else - { - $event->date_start_in_calendar=$event->datep; - if ($event->datef != '' && $event->datef >= $event->datep) $event->date_end_in_calendar=$event->datef; - else $event->date_end_in_calendar=$event->datep; + { + $event->date_start_in_calendar=$datep; + if ($datep2 != '' && $datep2 >= $datep) $event->date_end_in_calendar=$datep2; + else $event->date_end_in_calendar=$datep; } // Define ponctual property if ($event->date_start_in_calendar == $event->date_end_in_calendar) @@ -508,10 +510,14 @@ if ($resql) $event->date_start_in_calendar >= $lastdaytoshow) { // This record is out of visible range + unset($event); } else { - if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow; + //print $i.' - '.dol_print_date($this->date_start_in_calendar, 'dayhour').' - '.dol_print_date($this->date_end_in_calendar, 'dayhour').'
    '."\n"; + $event->fetch_userassigned(); // This load $event->userassigned + + if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow; if ($event->date_end_in_calendar >= $lastdaytoshow) $event->date_end_in_calendar=($lastdaytoshow - 1); // Add an entry in actionarray for each day @@ -928,6 +934,7 @@ function show_day_events_pertype($username, $day, $month, $year, $monthshown, $s } } + // Now output $casesX for ($h = $begin_h; $h < $end_h; $h++) { $color1='';$color2=''; diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index 7453b84d477..364e63d8a1b 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -38,7 +38,7 @@ if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class if (! isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW=3; -$filter = GETPOST("filter",'',3); +$filter = GETPOST("filter",'alpha',3); $filtert = GETPOST("filtert","int",3); $usergroup = GETPOST("usergroup","int",3); //if (! ($usergroup > 0) && ! ($filtert > 0)) $filtert = $user->id; @@ -82,9 +82,9 @@ $month=GETPOST("month","int")?GETPOST("month","int"):date("m"); $week=GETPOST("week","int")?GETPOST("week","int"):date("W"); $day=GETPOST("day","int")?GETPOST("day","int"):date("d"); $pid=GETPOST("projectid","int",3); -$status=GETPOST("status"); -$type=GETPOST("type"); -$maxprint=(isset($_GET["maxprint"])?GETPOST("maxprint"):$conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); +$status=GETPOST("status",'alpha'); +$type=GETPOST("type",'alpha'); +$maxprint=((GETPOST("maxprint",'int')!='')?GETPOST("maxprint",'int'):$conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); // Set actioncode (this code must be same for setting actioncode into peruser, listacton and index) if (GETPOST('actioncode','array')) { @@ -96,26 +96,26 @@ else $actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE)); } if ($actioncode == '' && empty($actioncodearray)) $actioncode=(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE); -$dateselect=dol_mktime(0, 0, 0, GETPOST('dateselectmonth'), GETPOST('dateselectday'), GETPOST('dateselectyear')); +$dateselect=dol_mktime(0, 0, 0, GETPOST('dateselectmonth','int'), GETPOST('dateselectday','int'), GETPOST('dateselectyear','int')); if ($dateselect > 0) { - $day=GETPOST('dateselectday'); - $month=GETPOST('dateselectmonth'); - $year=GETPOST('dateselectyear'); + $day=GETPOST('dateselectday','int'); + $month=GETPOST('dateselectmonth','int'); + $year=GETPOST('dateselectyear','int'); } $tmp=empty($conf->global->MAIN_DEFAULT_WORKING_HOURS)?'9-18':$conf->global->MAIN_DEFAULT_WORKING_HOURS; $tmparray=explode('-',$tmp); -$begin_h = GETPOST('begin_h')!=''?GETPOST('begin_h','int'):($tmparray[0] != '' ? $tmparray[0] : 9); -$end_h = GETPOST('end_h')?GETPOST('end_h'):($tmparray[1] != '' ? $tmparray[1] : 18); +$begin_h = GETPOST('begin_h','int')!=''?GETPOST('begin_h','int'):($tmparray[0] != '' ? $tmparray[0] : 9); +$end_h = GETPOST('end_h','int')?GETPOST('end_h','int'):($tmparray[1] != '' ? $tmparray[1] : 18); if ($begin_h < 0 || $begin_h > 23) $begin_h = 9; if ($end_h < 1 || $end_h > 24) $end_h = 18; if ($end_h <= $begin_h) $end_h = $begin_h + 1; $tmp=empty($conf->global->MAIN_DEFAULT_WORKING_DAYS)?'1-5':$conf->global->MAIN_DEFAULT_WORKING_DAYS; $tmparray=explode('-',$tmp); -$begin_d = GETPOST('begin_d')?GETPOST('begin_d','int'):($tmparray[0] != '' ? $tmparray[0] : 1); -$end_d = GETPOST('end_d')?GETPOST('end_d'):($tmparray[1] != '' ? $tmparray[1] : 5); +$begin_d = GETPOST('begin_d','int')?GETPOST('begin_d','int'):($tmparray[0] != '' ? $tmparray[0] : 1); +$end_d = GETPOST('end_d','int')?GETPOST('end_d','int'):($tmparray[1] != '' ? $tmparray[1] : 5); if ($begin_d < 1 || $begin_d > 7) $begin_d = 1; if ($end_d < 1 || $end_d > 7) $end_d = 7; if ($end_d < $begin_d) $end_d = $begin_d + 1; @@ -123,13 +123,13 @@ if ($end_d < $begin_d) $end_d = $begin_d + 1; if ($status == '' && ! isset($_GET['status']) && ! isset($_POST['status'])) $status=(empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS)?'':$conf->global->AGENDA_DEFAULT_FILTER_STATUS); if (empty($action) && ! isset($_GET['action']) && ! isset($_POST['action'])) $action=(empty($conf->global->AGENDA_DEFAULT_VIEW)?'show_month':$conf->global->AGENDA_DEFAULT_VIEW); -if (GETPOST('viewcal') && $action != 'show_day' && $action != 'show_week' && $action != 'show_peruser') { +if (GETPOST('viewcal','alpha') && $action != 'show_day' && $action != 'show_week' && $action != 'show_peruser') { $action='show_month'; $day=''; } // View by month -if (GETPOST('viewweek') || $action == 'show_week') { +if (GETPOST('viewweek','alpha') || $action == 'show_week') { $action='show_week'; $week=($week?$week:date("W")); $day=($day?$day:date("d")); } // View by week -if (GETPOST('viewday') || $action == 'show_day') { +if (GETPOST('viewday','alpha') || $action == 'show_day') { $action='show_day'; $day=($day?$day:date("d")); } // View by day @@ -160,12 +160,12 @@ if ($action =='delete_action') * View */ -$help_url='EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda'; -llxHeader('',$langs->trans("Agenda"),$help_url); - $form=new Form($db); $companystatic=new Societe($db); +$help_url='EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda'; +llxHeader('',$langs->trans("Agenda"),$help_url); + $now=dol_now(); $nowarray=dol_getdate($now); $nowyear=$nowarray['year']; @@ -418,14 +418,14 @@ else { // To limit array $sql.= " AND ("; - $sql.= " (a.datep BETWEEN '".$db->idate(dol_mktime(0,0,0,$month,1,$year)-(60*60*24*7))."'"; // Start 7 days before - $sql.= " AND '".$db->idate(dol_mktime(23,59,59,$month,28,$year)+(60*60*24*10))."')"; // End 7 days after + 3 to go from 28 to 31 + $sql.= " (a.datep BETWEEN '".$db->idate($firstdaytoshow-(60*60*24*2))."'"; // Start 2 day before $firstdaytoshow + $sql.= " AND '".$db->idate($lastdaytoshow+(60*60*24*2))."')"; // End 2 day after $lastdaytoshow $sql.= " OR "; - $sql.= " (a.datep2 BETWEEN '".$db->idate(dol_mktime(0,0,0,$month,1,$year)-(60*60*24*7))."'"; - $sql.= " AND '".$db->idate(dol_mktime(23,59,59,$month,28,$year)+(60*60*24*10))."')"; + $sql.= " (a.datep2 BETWEEN '".$db->idate($firstdaytoshow-(60*60*24*2))."'"; + $sql.= " AND '".$db->idate($lastdaytoshow+(60*60*24*2))."')"; $sql.= " OR "; - $sql.= " (a.datep < '".$db->idate(dol_mktime(0,0,0,$month,1,$year)-(60*60*24*7))."'"; - $sql.= " AND a.datep2 > '".$db->idate(dol_mktime(23,59,59,$month,28,$year)+(60*60*24*10))."')"; + $sql.= " (a.datep < '".$db->idate($firstdaytoshow-(60*60*24*2))."'"; + $sql.= " AND a.datep2 > '".$db->idate($lastdaytoshow+(60*60*24*2))."')"; $sql.= ')'; } if ($type) $sql.= " AND ca.id = ".$type; @@ -444,13 +444,14 @@ if ($filtert > 0 || $usergroup > 0) } // Sort on date $sql.= ' ORDER BY fk_user_action, datep'; //fk_user_action -//print $sql; +//print $sql;exit; dol_syslog("comm/action/peruser.php", LOG_DEBUG); $resql=$db->query($sql); if ($resql) { $num = $db->num_rows($resql); + $i=0; while ($i < $num) { @@ -463,11 +464,14 @@ if ($resql) continue; } + $datep=$db->jdate($obj->datep); + $datep2=$db->jdate($obj->datep2); + // Create a new object action $event=new ActionComm($db); $event->id=$obj->id; - $event->datep=$db->jdate($obj->datep); // datep and datef are GMT date - $event->datef=$db->jdate($obj->datep2); + $event->datep=$datep; // datep and datef are GMT date + $event->datef=$datep2; $event->type_code=$obj->code; $event->type_color=$obj->color; //$event->libelle=$obj->label; // deprecated @@ -476,7 +480,6 @@ if ($resql) //$event->author->id=$obj->fk_user_author; // user id of creator $event->authorid=$obj->fk_user_author; // user id of creator $event->userownerid=$obj->fk_user_action; // user id of owner - $event->fetch_userassigned(); // This load $event->userassigned $event->priority=$obj->priority; $event->fulldayevent=$obj->fulldayevent; $event->location=$obj->location; @@ -494,15 +497,15 @@ if ($resql) // They are date start and end of action but modified to not be outside calendar view. if ($event->percentage <= 0) { - $event->date_start_in_calendar=$event->datep; - if ($event->datef != '' && $event->datef >= $event->datep) $event->date_end_in_calendar=$event->datef; - else $event->date_end_in_calendar=$event->datep; + $event->date_start_in_calendar=$datep; + if ($datep2 != '' && $datep2 >= $datep) $event->date_end_in_calendar=$datep2; + else $event->date_end_in_calendar=$datep; } else { - $event->date_start_in_calendar=$event->datep; - if ($event->datef != '' && $event->datef >= $event->datep) $event->date_end_in_calendar=$event->datef; - else $event->date_end_in_calendar=$event->datep; + $event->date_start_in_calendar=$datep; + if ($datep2 != '' && $datep2 >= $datep) $event->date_end_in_calendar=$datep2; + else $event->date_end_in_calendar=$datep; } // Define ponctual property if ($event->date_start_in_calendar == $event->date_end_in_calendar) @@ -515,10 +518,14 @@ if ($resql) $event->date_start_in_calendar >= $lastdaytoshow) { // This record is out of visible range + unset($event); } else { - if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow; + //print $i.' - '.dol_print_date($this->date_start_in_calendar, 'dayhour').' - '.dol_print_date($this->date_end_in_calendar, 'dayhour').'
    '."\n"; + $event->fetch_userassigned(); // This load $event->userassigned + + if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow; if ($event->date_end_in_calendar >= $lastdaytoshow) $event->date_end_in_calendar=($lastdaytoshow - 1); // Add an entry in actionarray for each day @@ -548,6 +555,7 @@ if ($resql) $i++; } + $db->free($resql); } else { @@ -869,7 +877,7 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & $cases1 = array(); // Color first half hour $cases2 = array(); // Color second half hour - $curtime = dol_mktime(0, 0, 0, $month, $day, $year); + $curtime = dol_mktime(0, 0, 0, $month, $day, $year, false, 0); $i=0; $nummytasks=0; $numother=0; $numbirthday=0; $numical=0; $numicals=array(); $ymd=sprintf("%04d",$year).sprintf("%02d",$month).sprintf("%02d",$day); @@ -1029,6 +1037,7 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & } } + // Now output $casesX for ($h = $begin_h; $h < $end_h; $h++) { $color1='';$color2=''; diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index 7ec9dcf1a4b..ca3c0ba35e6 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -98,12 +98,12 @@ if ($id > 0 || ! empty($ref)) $param=($mode=='mine'?'&mode=mine':''); - + // Project card - + $linkback = ''.$langs->trans("BackToList").''; - + $morehtmlref='
    '; // Title $morehtmlref.=$object->title; @@ -113,29 +113,29 @@ if ($id > 0 || ! empty($ref)) $morehtmlref.='
    '.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1, 'project'); } $morehtmlref.='
    '; - + // Define a complementary filter for search of next/prev ref. if (! $user->rights->projet->all->lire) { $objectsListId = $object->getProjectsAuthorizedForUser($user,0,0); $object->next_prev_filter=" rowid in (".(count($objectsListId)?join(',',array_keys($objectsListId)):'0').")"; } - + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - - + + print '
    '; print '
    '; print '
    '; - + print ''; - + // Visibility print ''; - + // Date start - end print ''; - + // Budget print ''; - + // Other attributes $cols = 2; include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; - + print '
    '.$langs->trans("Visibility").''; if ($object->public) print $langs->trans('SharedProject'); else print $langs->trans('PrivateProject'); print '
    '.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").''; $start = dol_print_date($object->date_start,'dayhour'); @@ -145,45 +145,45 @@ if ($id > 0 || ! empty($ref)) print ($end?$end:'?'); if ($object->hasDelay()) print img_warning("Late"); print '
    '.$langs->trans("Budget").''; if (strcmp($object->budget_amount, '')) print price($object->budget_amount,'',$langs,1,0,0,$conf->currency); print '
    '; - + print '
    '; print '
    '; print '
    '; print '
    '; - + print ''; - + // Description print ''; - + // Categories if($conf->categorie->enabled) { print '"; } - + print '
    '.$langs->trans("Description").''; print nl2br($object->description); print '
    '.$langs->trans("Categories").''; print $form->showCategories($object->id,'project',1); print "
    '; - + print '
    '; print '
    '; print '
    '; - + print '
    '; - + dol_fiche_end(); } diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index cd2c0f95582..801911c0f5f 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -3425,6 +3425,15 @@ table.cal_event td.cal_event_right { padding: 4px 4px !important; } cursor:pointer; } +/* ============================================================================== */ +/* Gantt +/* ============================================================================== */ + +td.gtaskname { + overflow: hidden; + text-overflow: ellipsis; +} + /* ============================================================================== */ /* jQuery - jeditable */ diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index cf787f09071..5768a70bf18 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3508,6 +3508,17 @@ table.cal_event td.cal_event_right { padding: 4px 4px !important; } cursor:pointer; } + +/* ============================================================================== */ +/* Gantt +/* ============================================================================== */ + +td.gtaskname { + overflow: hidden; + text-overflow: ellipsis; +} + + /* ============================================================================== */ /* jQuery - jeditable */ /* ============================================================================== */ From 2a361668398cf44e0cefe49a05d5c30a8511f5d4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 29 Jul 2017 02:11:45 +0200 Subject: [PATCH 042/112] Fix error method on non object --- htdocs/comm/action/card.php | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 14ab91a2f31..16bb308c966 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -38,11 +38,8 @@ require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; -if (! empty($conf->projet->enabled)) -{ - require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; -} +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $langs->load("companies"); @@ -585,6 +582,8 @@ if ($action == 'mupdate') * View */ +$formproject=new FormProjets($db); + $help_url='EN:Module_Agenda_En|FR:Module_Agenda|ES:M&omodulodulo_Agenda'; llxHeader('',$langs->trans("Agenda"),$help_url); @@ -786,8 +785,6 @@ if ($action == 'create') // Project if (! empty($conf->projet->enabled)) { - $formproject=new FormProjets($db); - // Projet associe $langs->load("projects"); @@ -1133,8 +1130,6 @@ if ($id > 0) // Project if (! empty($conf->projet->enabled)) { - $formproject=new FormProjets($db); - $langs->load("projects"); print '
    '.$langs->trans("Project").''; From 837afa0e6560546e9bf92e6ae0820e459a508d24 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 29 Jul 2017 04:07:46 +0200 Subject: [PATCH 043/112] Fix better way to get info for contact/thirdparty on agenda --- htdocs/comm/action/pertype.php | 80 ++++++++++++++++++++++++++----- htdocs/comm/action/peruser.php | 86 ++++++++++++++++++++++++++++------ 2 files changed, 140 insertions(+), 26 deletions(-) diff --git a/htdocs/comm/action/pertype.php b/htdocs/comm/action/pertype.php index 589a2731f1b..b10ab8dc05b 100644 --- a/htdocs/comm/action/pertype.php +++ b/htdocs/comm/action/pertype.php @@ -30,10 +30,12 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php'; -if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; if (! isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW=3; @@ -55,7 +57,7 @@ $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page = GETPOST("page","int"); if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 -$limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; $offset = $limit * $page; if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="a.datec"; @@ -93,7 +95,7 @@ if (GETPOST('actioncode','array')) } else { - $actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE)); + $actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode","alpha")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE)); } if ($actioncode == '' && empty($actioncodearray)) $actioncode=(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE); @@ -354,7 +356,7 @@ $sql.= ' a.datep2,'; $sql.= ' a.percent,'; $sql.= ' a.fk_user_author,a.fk_user_action,'; $sql.= ' a.transparency, a.priority, a.fulldayevent, a.location,'; -$sql.= ' a.fk_soc, a.fk_contact, a.fk_element, a.elementtype,'; +$sql.= ' a.fk_soc, a.fk_contact, a.fk_element, a.elementtype, a.fk_project,'; $sql.= ' ca.code, ca.color'; $sql.= ' FROM '.MAIN_DB_PREFIX.'c_actioncomm as ca, '.MAIN_DB_PREFIX."actioncomm as a"; if (! $user->rights->societe->client->voir && ! $socid) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; @@ -477,6 +479,8 @@ if ($resql) $event->location=$obj->location; $event->transparency=$obj->transparency; + $event->fk_project=$obj->fk_project; + $event->socid=$obj->fk_soc; $event->contactid=$obj->fk_contact; //$event->societe->id=$obj->fk_soc; // deprecated @@ -887,11 +891,37 @@ function show_day_events_pertype($username, $day, $month, $year, $monthshown, $s } $cases1[$h][$event->id]['string'].=' - '.$event->label; $cases1[$h][$event->id]['typecode']=$event->type_code; - if ($event->socid) - { - //$cases1[$h][$event->id]['string'].='xxx'; - } $cases1[$h][$event->id]['color']=$color; + if ($event->fk_project > 0) + { + if (empty($cache_project[$event->fk_project])) + { + $tmpproj=new Project($db); + $tmpproj->fetch($event->fk_project); + $cache_project[$event->fk_project]=$tmpproj; + } + $cases1[$h][$event->id]['string'].=', '.$langs->trans("Project").': '.$cache_project[$event->fk_project]->ref.' - '.$cache_project[$event->fk_project]->title; + } + if ($event->socid > 0) + { + if (empty($cache_thirdparty[$event->socid])) + { + $tmpthirdparty=new Societe($db); + $tmpthirdparty->fetch($event->socid); + $cache_thirdparty[$event->socid]=$tmpthirdparty; + } + $cases1[$h][$event->id]['string'].=', '.$cache_thirdparty[$event->socid]->name; + } + if ($event->contactid > 0) + { + if (empty($cache_contact[$event->contactid])) + { + $tmpcontact=new Contact($db); + $tmpcontact->fetch($event->contactid); + $cache_contact[$event->contactid]=$tmpcontact; + } + $cases1[$h][$event->id]['string'].=', '.$cache_contact[$event->contactid]->getFullName($langs); + } } if ($event->date_start_in_calendar < $c && $dateendtouse > $b) { @@ -907,11 +937,37 @@ function show_day_events_pertype($username, $day, $month, $year, $monthshown, $s } $cases2[$h][$event->id]['string'].=' - '.$event->label; $cases2[$h][$event->id]['typecode']=$event->type_code; - if ($event->socid) - { - //$cases2[$h][$event->id]['string'].='xxx'; - } $cases2[$h][$event->id]['color']=$color; + if ($event->fk_project > 0) + { + if (empty($cache_project[$event->fk_project])) + { + $tmpproj=new Project($db); + $tmpproj->fetch($event->fk_project); + $cache_project[$event->fk_project]=$tmpproj; + } + $cases2[$h][$event->id]['string'].=', '.$langs->trans("Project").': '.$cache_project[$event->fk_project]->ref.' - '.$cache_project[$event->fk_project]->title; + } + if ($event->socid > 0) + { + if (empty($cache_thirdparty[$event->socid])) + { + $tmpthirdparty=new Societe($db); + $tmpthirdparty->fetch($event->socid); + $cache_thirdparty[$event->socid]=$tmpthirdparty; + } + $cases2[$h][$event->id]['string'].=', '.$cache_thirdparty[$event->socid]->name; + } + if ($event->contactid > 0) + { + if (empty($cache_contact[$event->contactid])) + { + $tmpcontact=new Contact($db); + $tmpcontact->fetch($event->contactid); + $cache_contact[$event->contactid]=$tmpcontact; + } + $cases2[$h][$event->id]['string'].=', '.$cache_contact[$event->contactid]->getFullName($langs); + } } } else diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index 364e63d8a1b..792d4f9760d 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -30,10 +30,12 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php'; -if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; if (! isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW=3; @@ -55,7 +57,7 @@ $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); $page = GETPOST("page","int"); if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 -$limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; $offset = $limit * $page; if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="a.datec"; @@ -93,9 +95,10 @@ if (GETPOST('actioncode','array')) } else { - $actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE)); + $actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode","alpha")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE)); } if ($actioncode == '' && empty($actioncodearray)) $actioncode=(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE); + $dateselect=dol_mktime(0, 0, 0, GETPOST('dateselectmonth','int'), GETPOST('dateselectday','int'), GETPOST('dateselectyear','int')); if ($dateselect > 0) { @@ -361,7 +364,7 @@ $sql.= ' a.datep2,'; $sql.= ' a.percent,'; $sql.= ' a.fk_user_author,a.fk_user_action,'; $sql.= ' a.transparency, a.priority, a.fulldayevent, a.location,'; -$sql.= ' a.fk_soc, a.fk_contact, a.fk_element, a.elementtype,'; +$sql.= ' a.fk_soc, a.fk_contact, a.fk_element, a.elementtype, a.fk_project,'; $sql.= ' ca.code, ca.color'; $sql.= ' FROM '.MAIN_DB_PREFIX.'c_actioncomm as ca, '.MAIN_DB_PREFIX."actioncomm as a"; if (! $user->rights->societe->client->voir && ! $socid) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; @@ -485,6 +488,8 @@ if ($resql) $event->location=$obj->location; $event->transparency=$obj->transparency; + $event->fk_project=$obj->fk_project; + $event->socid=$obj->fk_soc; $event->contactid=$obj->fk_contact; //$event->societe->id=$obj->fk_soc; // deprecated @@ -873,6 +878,7 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & global $theme_datacolor; // Array with a list of different we can use (come from theme) global $cachethirdparties, $cachecontacts, $colorindexused; global $begin_h, $end_h; + global $cache_project, $cache_thirdparty, $cache_contact; $cases1 = array(); // Color first half hour $cases2 = array(); // Color second half hour @@ -988,13 +994,39 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) $cases1[$h][$event->id]['string'].='-'.dol_print_date($event->date_end_in_calendar,'hour'); else $cases1[$h][$event->id]['string'].='-'.dol_print_date($event->date_end_in_calendar,'dayhour'); } - $cases1[$h][$event->id]['string'].=' - '.$event->label; + if ($event->label) $cases1[$h][$event->id]['string'].=' - '.$event->label; $cases1[$h][$event->id]['typecode']=$event->type_code; - if ($event->socid) - { - //$cases1[$h][$event->id]['string'].='xxx'; - } $cases1[$h][$event->id]['color']=$color; + if ($event->fk_project > 0) + { + if (empty($cache_project[$event->fk_project])) + { + $tmpproj=new Project($db); + $tmpproj->fetch($event->fk_project); + $cache_project[$event->fk_project]=$tmpproj; + } + $cases1[$h][$event->id]['string'].=', '.$langs->trans("Project").': '.$cache_project[$event->fk_project]->ref.' - '.$cache_project[$event->fk_project]->title; + } + if ($event->socid > 0) + { + if (empty($cache_thirdparty[$event->socid])) + { + $tmpthirdparty=new Societe($db); + $tmpthirdparty->fetch($event->socid); + $cache_thirdparty[$event->socid]=$tmpthirdparty; + } + $cases1[$h][$event->id]['string'].=', '.$cache_thirdparty[$event->socid]->name; + } + if ($event->contactid > 0) + { + if (empty($cache_contact[$event->contactid])) + { + $tmpcontact=new Contact($db); + $tmpcontact->fetch($event->contactid); + $cache_contact[$event->contactid]=$tmpcontact; + } + $cases1[$h][$event->id]['string'].=', '.$cache_contact[$event->contactid]->getFullName($langs); + } } if ($event->date_start_in_calendar < $c && $dateendtouse > $b) { @@ -1008,13 +1040,39 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) $cases2[$h][$event->id]['string'].='-'.dol_print_date($event->date_end_in_calendar,'hour'); else $cases2[$h][$event->id]['string'].='-'.dol_print_date($event->date_end_in_calendar,'dayhour'); } - $cases2[$h][$event->id]['string'].=' - '.$event->label; + if ($event->label) $cases2[$h][$event->id]['string'].=' - '.$event->label; $cases2[$h][$event->id]['typecode']=$event->type_code; - if ($event->socid) - { - //$cases2[$h][$event->id]['string'].='xxx'; - } $cases2[$h][$event->id]['color']=$color; + if ($event->fk_project > 0) + { + if (empty($cache_project[$event->fk_project])) + { + $tmpproj=new Project($db); + $tmpproj->fetch($event->fk_project); + $cache_project[$event->fk_project]=$tmpproj; + } + $cases2[$h][$event->id]['string'].=', '.$langs->trans("Project").': '.$cache_project[$event->fk_project]->ref.' - '.$cache_project[$event->fk_project]->title; + } + if ($event->socid > 0) + { + if (empty($cache_thirdparty[$event->socid])) + { + $tmpthirdparty=new Societe($db); + $tmpthirdparty->fetch($event->socid); + $cache_thirdparty[$event->socid]=$tmpthirdparty; + } + $cases2[$h][$event->id]['string'].=', '.$cache_thirdparty[$event->socid]->name; + } + if ($event->contactid > 0) + { + if (empty($cache_contact[$event->contactid])) + { + $tmpcontact=new Contact($db); + $tmpcontact->fetch($event->contactid); + $cache_contact[$event->contactid]=$tmpcontact; + } + $cases2[$h][$event->id]['string'].=', '.$cache_contact[$event->contactid]->getFullName($langs); + } } } else From bb8d4584680282b1f54b27be2c0a4a66d8a57521 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 30 Jul 2017 19:38:12 +0200 Subject: [PATCH 044/112] Fix menu editor --- htdocs/admin/menus/index.php | 11 ++++++----- htdocs/core/lib/treeview.lib.php | 6 +++--- .../template/core/modules/modMyModule.class.php | 6 +++--- htdocs/theme/eldy/style.css.php | 8 +++++++- htdocs/theme/md/style.css.php | 17 +++++++++++++---- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/htdocs/admin/menus/index.php b/htdocs/admin/menus/index.php index 5fb19b0b5ec..c3211fc2d75 100644 --- a/htdocs/admin/menus/index.php +++ b/htdocs/admin/menus/index.php @@ -296,7 +296,7 @@ if ($conf->use_javascript_ajax) //puis tous les elements enfants - $sql = "SELECT m.rowid, m.titre, m.langs, m.mainmenu, m.leftmenu, m.fk_menu, m.fk_mainmenu, m.fk_leftmenu, m.module"; + $sql = "SELECT m.rowid, m.titre, m.langs, m.mainmenu, m.leftmenu, m.fk_menu, m.fk_mainmenu, m.fk_leftmenu, m.position, m.module"; $sql.= " FROM ".MAIN_DB_PREFIX."menu as m"; $sql.= " WHERE menu_handler = '".$db->escape($menu_handler_to_search)."'"; $sql.= " AND entity = ".$conf->entity; @@ -323,6 +323,7 @@ if ($conf->use_javascript_ajax) 'leftmenu'=>$menu['leftmenu'], 'fk_mainmenu'=>$menu['fk_mainmenu'], 'fk_leftmenu'=>$menu['fk_leftmenu'], + 'position'=>$menu['position'], 'entry'=>''; @@ -376,7 +378,6 @@ if ($conf->use_javascript_ajax) print ''; print '
    '. '   '.$titre.''. ''. @@ -344,10 +345,11 @@ if ($conf->use_javascript_ajax) global $tree_recur_alreadyadded; // This var was def into tree_recur - // Appelle de la fonction recursive (ammorce) - // avec recherche depuis la racine. //var_dump($data); - tree_recur($data, $data[0], 0, 'iddivjstree'); // $data[0] is virtual record 'racine' + + // Appelle de la fonction recursive (ammorce) avec recherche depuis la racine. + //tree_recur($data, $data[0], 0, 'iddivjstree', 0, 1); // use this to get info on name and foreign keys of menu entry + tree_recur($data, $data[0], 0, 'iddivjstree', 0, 0); // $data[0] is virtual record 'racine' print '
    '; - foreach($remainingdata as $datar) { $father = array('rowid'=>$datar['rowid'],'title'=>"???",'mainmenu'=>$datar['fk_mainmenu'],'leftmenu'=>$datar['fk_leftmenu'],'fk_mainmenu'=>'','fk_leftmenu'=>''); diff --git a/htdocs/core/lib/treeview.lib.php b/htdocs/core/lib/treeview.lib.php index 944520d04d5..6c66079090a 100644 --- a/htdocs/core/lib/treeview.lib.php +++ b/htdocs/core/lib/treeview.lib.php @@ -182,7 +182,7 @@ function tree_recur($tab, $pere, $rang, $iddivjstree='iddivjstree', $donoresetal //print ' -> A '.$tab[$x]['rowid'].' mainmenu='.$tab[$x]['mainmenu'].' leftmenu='.$tab[$x]['leftmenu'].' fk_mainmenu='.$tab[$x]['fk_mainmenu'].' fk_leftmenu='.$tab[$x]['fk_leftmenu'].'
    '."\n"; $tree_recur_alreadyadded[$tab[$x]['rowid']]=($rang + 1); // And now we search all its sons of lower level - tree_recur($tab,$tab[$x],$rang+1); + tree_recur($tab, $tab[$x], $rang+1, 'iddivjstree', 0, $showfk); print ''; } elseif (! empty($tab[$x]['rowid']) && $tab[$x]['fk_menu'] == -1 && $tab[$x]['fk_mainmenu'] == $pere['mainmenu'] && $tab[$x]['fk_leftmenu'] == $pere['leftmenu']) @@ -206,7 +206,7 @@ function tree_recur($tab, $pere, $rang, $iddivjstree='iddivjstree', $donoresetal print '   '; print $tab[$x]['title']; print ''; - print '  (fk_mainmenu='.$tab[$x]['fk_mainmenu'].' fk_leftmenu='.$tab[$x]['fk_leftmenu'].')'; + print '  (mainmenu='.$tab[$x]['mainmenu'].' leftmenu='.$tab[$x]['leftmenu'].' - fk_mainmenu='.$tab[$x]['fk_mainmenu'].' fk_leftmenu='.$tab[$x]['fk_leftmenu'].')'; print '
    '; print $tab[$x]['buttons']; print '
    '; @@ -219,7 +219,7 @@ function tree_recur($tab, $pere, $rang, $iddivjstree='iddivjstree', $donoresetal $tree_recur_alreadyadded[$tab[$x]['rowid']]=($rang + 1); // And now we search all its sons of lower level //print 'Call tree_recur for x='.$x.' rowid='.$tab[$x]['rowid']." fk_mainmenu pere = ".$tab[$x]['fk_mainmenu']." fk_leftmenu pere = ".$tab[$x]['fk_leftmenu']."
    \n"; - tree_recur($tab,$tab[$x],$rang+1); + tree_recur($tab, $tab[$x], $rang+1, 'iddivjstree', 0, $showfk); print ''; } } diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index 3e217618d4a..8f8079b1d46 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -235,7 +235,7 @@ class modMyModule extends DolibarrModules 'leftmenu'=>'', 'url'=>'/mymodule/mymoduleindex.php', 'langs'=>'mymodule@mymodule', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. - 'position'=>1000, + 'position'=>1000+$r, 'enabled'=>'$conf->mymodule->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'target'=>'', @@ -252,7 +252,7 @@ class modMyModule extends DolibarrModules 'leftmenu'=>'mymodule', 'url'=>'/mymodule/myobject_list.php', 'langs'=>'mymodule@mymodule', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. - 'position'=>1100, + 'position'=>1000+$r, 'enabled'=>'$conf->mymodule->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'target'=>'', @@ -264,7 +264,7 @@ class modMyModule extends DolibarrModules 'leftmenu'=>'mymodule', 'url'=>'/mymodule/myobject_page.php?action=create', 'langs'=>'mymodule@mymodule', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. - 'position'=>1101, + 'position'=>1000+$r, 'enabled'=>'$conf->mymodule->enabled', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. 'perms'=>'1', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'target'=>'', diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 801911c0f5f..0fa905113ad 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2653,7 +2653,6 @@ div.liste_titre_bydiv, .liste_titre div.tagtr, tr.liste_titre, tr.liste_titre_se } tr.liste_titre th, tr.liste_titre td, th.liste_titre { -/* border-bottom: 1px solid #; */ border-bottom: 1px solid #888; } tr.liste_titre:first-child th, tr:first-child th.liste_titre { @@ -2779,6 +2778,13 @@ div.tabBar .noborder { border-bottom: 1px solid #ddd; } +ul.noborder li:nth-child(even):not(.liste_titre) { + background-color: rgb() !important; + background-color: rgb() !important; + background-color: rgb() !important; + background-color: rgb() !important; + background-color: rgb() !important; +} /* diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 5768a70bf18..741a08c4ac8 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -2623,6 +2623,15 @@ div.pagination li.paginationafterarrows { } */ +ul.noborder li:nth-child(odd):not(.liste_titre) { + background-color: rgb() !important; + background-color: rgb() !important; + background-color: rgb() !important; + background-color: rgb() !important; + background-color: rgb() !important; +} + + /* Set the color for hover lines */ .oddeven:hover, .evenodd:hover, .impair:hover, .pair:hover { @@ -2723,19 +2732,19 @@ tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, tabl { height: 26px !important; } -div.liste_titre, tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, table.dataTable thead tr +div.liste_titre_bydiv, .liste_titre div.tagtr, tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, table.dataTable thead tr { background: rgb(); font-weight: ; + border-bottom: 1px solid #FDFFFF; color: rgb(); font-family: ; - border-bottom: 1px solid #FDFFFF; text-align: ; } -tr.liste_titre th, tr.liste_titre td, th.liste_titre, form.liste_titre div, div.liste_titre +tr.liste_titre th, tr.liste_titre td, th.liste_titre { - border-bottom: 1px solid #; + border-bottom: 1px solid #aaa; } /* TODO Once title line is moved under title search, make border bottom of all th black and force to whit when it's first tr */ tr:first-child th.liste_titre { From 1897e3cbadf417748970e632b219f6272ccf7181 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 30 Jul 2017 20:43:18 +0200 Subject: [PATCH 045/112] Some fix for better compatibility --- htdocs/main.inc.php | 4 ++-- htdocs/public/test/test_arrays.php | 18 ++++++------------ htdocs/theme/eldy/style.css.php | 5 +++++ htdocs/theme/md/style.css.php | 6 ++++-- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 090a35d6c83..89b99a61041 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1199,7 +1199,7 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs print ''."\n"; if (defined('JS_JQUERY') && constant('JS_JQUERY')) print ''."\n"; else print ''."\n"; - if (! empty($conf->global->MAIN_FEATURES_LEVEL)) + if (! empty($conf->global->MAIN_FEATURES_LEVEL) && ! defined('JS_JQUERY_MIGRATE_DISABLED')) { if (defined('JS_JQUERY_MIGRATE') && constant('JS_JQUERY_MIGRATE')) print ''."\n"; else print ''."\n"; @@ -2002,7 +2002,7 @@ if (! function_exists("llxFooter")) } // Wrapper to manage dropdown - if ($conf->use_javascript_ajax) + if (! empty($conf->use_javascript_ajax) && ! defined('JS_JQUERY_DISABLE_DROPDOWN')) { print "\n\n"; print ' @@ -43,9 +40,6 @@ if (empty($usedolheader)) - - - @@ -74,7 +68,7 @@ else '/includes/pdfmake/vfs_fonts.js' ); */ - + llxHeader('','','','',0,0,$arrayjs,$arraycss); } @@ -92,7 +86,7 @@ This page is a sample of page using tables. It is designed to make test with
    - tablednd
    - +


    Example 0a : Table with div+div+div containg a select that should be overflowed and truncated => Use this to align text or form
    @@ -139,7 +133,7 @@ This page is a sample of page using tables. It is designed to make test with



    Example 1 : Standard table/thead/tbody/tr/th-td (no class pair/impair on td) => Use this if you need the drag and drop for lines or for long result tables
    - + - + - + " id="tablelines3"> @@ -243,7 +237,7 @@ if (! empty($moreforfilter))
    -'; @@ -280,8 +278,8 @@ if (!empty($conf->global->MAIN_EASTER_EGG_COMMITSTRIP)) { global->MAIN_HTML_FOOTER)) print $conf->global->MAIN_HTML_FOOTER; ?> resArray['options'])) { - foreach ($hookmanager->resArray['options'] as $format => $option) +if (! empty($morelogincontent) && is_array($morelogincontent)) { + foreach ($morelogincontent as $format => $option) { if ($format == 'js') { echo "\n".''; From d2b662c671d250c15fea77a38672ac8896811c5a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 31 Jul 2017 19:31:52 +0200 Subject: [PATCH 060/112] Add field fk_user in bookkeeping (the user who valiated the accounting document. Will be used for statistics purpose only). --- htdocs/install/mysql/migration/6.0.0-7.0.0.sql | 1 + htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql index be8bd9c2701..8dbd0341e07 100644 --- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql +++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql @@ -48,4 +48,5 @@ ALTER TABLE llx_accounting_bookkeeping ADD COLUMN import_key varchar(14); ALTER TABLE llx_accounting_bookkeeping ADD COLUMN extraparams varchar(255); ALTER TABLE llx_accounting_bookkeeping ADD COLUMN date_lim_reglement datetime; +ALTER TABLE llx_accounting_bookkeeping ADD COLUMN fk_user integer NULL; diff --git a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql index e9a4921a840..269e73987ee 100644 --- a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql +++ b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql @@ -45,9 +45,10 @@ CREATE TABLE llx_accounting_bookkeeping fk_user_modif integer, -- | user making last change date_creation datetime, -- FEC:EcritureDate | creation date tms timestamp, -- | date last modification + fk_user integer NULL -- The id of user that validate the accounting source document code_journal varchar(32) NOT NULL, -- FEC:JournalCode journal_label varchar(255), -- FEC:JournalLib - piece_num integer NOT NULL, -- FEC:EcritureNum + piece_num integer NOT NULL, -- FEC:EcritureNum | accounting source document validated tinyint DEFAULT 0 NOT NULL, -- | 0 line not validated / 1 line validated (No deleting / No modification) date_validated datetime -- FEC:ValidDate import_key varchar(14), From ba221650cf3e78337a7682ff1bb2d5519d003f5c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Aug 2017 01:25:30 +0200 Subject: [PATCH 061/112] Start to work on using the jquery date selector. --- htdocs/core/class/html.form.class.php | 87 ++++++++++++++++++--------- 1 file changed, 60 insertions(+), 27 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index cda39e3ca9d..b39208b9237 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4727,6 +4727,7 @@ class Form $smin = !isset($conf->global->MAIN_DEFAULT_DATE_MIN) ? '' : $conf->global->MAIN_DEFAULT_DATE_MIN; } + // You can set MAIN_POPUP_CALENDAR to 'eldy' or 'jquery' $usecalendar='combo'; if (! empty($conf->use_javascript_ajax) && (empty($conf->global->MAIN_POPUP_CALENDAR) || $conf->global->MAIN_POPUP_CALENDAR != "none")) $usecalendar=empty($conf->global->MAIN_POPUP_CALENDAR)?'eldy':$conf->global->MAIN_POPUP_CALENDAR; if ($conf->browser->phone) $usecalendar='combo'; @@ -4758,7 +4759,8 @@ class Form { $retstring.=''; + $retstring.=' onClick="showDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');"'; + $retstring.='>'.img_object($langs->trans("SelectDate"),'calendarday','class="datecallink"').''; } else $retstring.=''; @@ -4766,6 +4768,37 @@ class Form $retstring.=''."\n"; $retstring.=''."\n"; } + elseif ($usecalendar == 'jquery') + { + if (! $disabled) + { + print ""; + } + + // Zone de saisie manuelle de la date + $retstring.='trans("FormatDateShortJavaInput").'\'); "'; // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript + $retstring.='>'; + + // Icone calendrier + if (! $disabled) + { + //$retstring.=''; + } + else $retstring.=''; + + $retstring.=''."\n"; + $retstring.=''."\n"; + $retstring.=''."\n"; + } else { print "Bad value of MAIN_POPUP_CALENDAR"; @@ -6325,40 +6358,40 @@ class Form } return $out; } - + /** * Return HTML to show the select categories of expense category - * + * * @param string $selected preselected category * @param string $htmlname name of HTML select list * @param integer $useempty 1=Add empty line * @param array $excludeid id to exclude * @param string $target htmlname of target select to bind event * @param int $default_selected default category to select if fk_c_type_fees change = EX_KME - * @param array $params param to give + * @param array $params param to give * @return string */ function selectExpenseCategories($selected='', $htmlname='fk_c_exp_tax_cat', $useempty=0, $excludeid=array(), $target='', $default_selected=0, $params=array()) { global $db,$conf,$langs; - + $sql = 'SELECT rowid, label FROM '.MAIN_DB_PREFIX.'c_exp_tax_cat WHERE active = 1'; $sql.= ' AND entity IN (0,'.getEntity('').')'; if (!empty($excludeid)) $sql.= ' AND rowid NOT IN ('.implode(',', $excludeid).')'; $sql.= ' ORDER BY label'; - + $resql = $db->query($sql); if ($resql) { $out = ''; - + if (!empty($target)) { $sql = "SELECT c.id FROM ".MAIN_DB_PREFIX."c_type_fees as c WHERE c.code = 'EX_KME' AND c.active = 1"; @@ -6374,19 +6407,19 @@ class Form var current_val = $(this).val(); if (current_val == '.$obj->id.') {'; if (!empty($default_selected) || !empty($selected)) $out.= '$("select[name='.$htmlname.']").val("'.($default_selected > 0 ? $default_selected : $selected).'");'; - + $out.= ' $("select[name='.$htmlname.']").change(); } }); $("select[name='.$htmlname.']").change(function() { - + if ($("select[name='.$target.']").val() == '.$obj->id.') { // get price of kilometer to fill the unit price var data = '.json_encode($params).'; data.fk_c_exp_tax_cat = $(this).val(); - + $.ajax({ method: "POST", dataType: "json", @@ -6407,20 +6440,20 @@ class Form }); '; } - } + } } } else { dol_print_error($db); } - + return $out; } - + /** * Return HTML to show the select ranges of expense range - * + * * @param string $selected preselected category * @param string $htmlname name of HTML select list * @param integer $useempty 1=Add empty line @@ -6429,16 +6462,16 @@ class Form function selectExpenseRanges($selected='', $htmlname='fk_range', $useempty=0) { global $db,$conf,$langs; - + $sql = 'SELECT rowid, range_ik FROM '.MAIN_DB_PREFIX.'c_exp_tax_range'; $sql.= ' WHERE entity = '.$conf->entity.' AND active = 1'; - + $resql = $db->query($sql); if ($resql) { $out = ''; if ($useempty) $out.= ''; if ($allchoice) $out.= ''; - + $field = 'code'; if ($useid) $field = 'id'; - + while ($obj = $db->fetch_object($resql)) { $key = $langs->trans($obj->code); @@ -6491,9 +6524,9 @@ class Form { dol_print_error($db); } - + return $out; } - + } From ae444b57810cabc3d0d488ed758914b3f951086f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Aug 2017 01:28:07 +0200 Subject: [PATCH 062/112] Fix travis error --- htdocs/variants/class/ProductCombination.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index fd08ccf1b6a..d3e6964aea6 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -249,8 +249,8 @@ class ProductCombination /** * Deletes a product combination * - * @param User $user - * @return int <0 KO >0 OK + * @param User $user Object user + * @return int <0 if KO, >0 if OK */ public function delete(User $user) { From efd24cc1a2b27f613b0f29cb977410b1899615d7 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 1 Aug 2017 06:16:23 +0200 Subject: [PATCH 063/112] Fix: function length_accountg has been moved in getNomUrl --- htdocs/compta/bank/index.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index 9bc8608692d..6c0d1613943 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -492,12 +492,10 @@ foreach ($accounts as $key=>$type) // Account number if (! empty($arrayfields['b.account_number']['checked'])) { - include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; - $accountingaccount = new AccountingAccount($db); $accountingaccount->fetch('',$acc->account_number); - print ''; + print ''; if (! $i) $totalarray['nbfield']++; } From 9629a50853fb81953e17e012d4c7d84ae0be9c73 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 1 Aug 2017 06:21:19 +0200 Subject: [PATCH 064/112] Fix: SQL error in payment list --- htdocs/compta/paiement/list.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/paiement/list.php b/htdocs/compta/paiement/list.php index 4a7a2e3c81a..bddc5e9f500 100644 --- a/htdocs/compta/paiement/list.php +++ b/htdocs/compta/paiement/list.php @@ -3,8 +3,9 @@ * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2013 Cédric Salvador - * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2015 Juanjo Menent + * Copyright (C) 2017 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 @@ -31,14 +32,15 @@ require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php'; $langs->load("bills"); $langs->load("compta"); // Security check -$facid =GETPOST('facid','int'); -$socid =GETPOST('socid','int'); -$userid=GETPOST('userid','int'); +$facid = GETPOST('facid','int'); +$socid = GETPOST('socid','int'); +$userid = GETPOST('userid','int'); $day = GETPOST('day','int'); $month = GETPOST('month','int'); $year = GETPOST('year','int'); @@ -129,7 +131,7 @@ else $sql = "SELECT DISTINCT p.rowid, p.ref, p.datep as dp, p.amount,"; // DISTINCT is to avoid duplicate when there is a link to sales representatives $sql.= " p.statut, p.num_paiement,"; $sql.= " c.code as paiement_code,"; - $sql.= " ba.rowid as bid, ba.ref as bref, ba.label as blabel, ba.number, ba.account_number as account_number, ba.accountancy_journal as accountancy_journal,"; + $sql.= " ba.rowid as bid, ba.ref as bref, ba.label as blabel, ba.number, ba.account_number as account_number, ba.fk_accountancy_journal as accountancy_journal,"; $sql.= " s.rowid as socid, s.nom as name"; // Add fields for extrafields foreach ($extrafields->attribute_list as $key => $val) $sql.=",ef.".$key.' as options_'.$key; @@ -329,7 +331,11 @@ if ($resql) $accountstatic->label=$objp->blabel; $accountstatic->number=$objp->number; $accountstatic->account_number=$objp->account_number; - $accountstatic->accountancy_journal=$objp->accountancy_journal; + + $accountingjournal = new AccountingJournal($db); + $accountingjournal->fetch($objp->accountancy_journal); + $accountstatic->accountancy_journal = $accountingjournal->getNomUrl(0,1,1,'',1); + print $accountstatic->getNomUrl(1); } else print ' '; From 3c34add0d60c4351045fd1cdb221baa31724a961 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 1 Aug 2017 06:26:35 +0200 Subject: [PATCH 065/112] remove condition --- htdocs/compta/paiement/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/paiement/list.php b/htdocs/compta/paiement/list.php index bddc5e9f500..04dbaf8fc11 100644 --- a/htdocs/compta/paiement/list.php +++ b/htdocs/compta/paiement/list.php @@ -32,7 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; -if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php'; +require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; $langs->load("bills"); $langs->load("compta"); From e41543c22eefe9796b1bdf7be1e2e4b777554aad Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 1 Aug 2017 06:44:37 +0200 Subject: [PATCH 066/112] Fix v6: Debug various_payment --- htdocs/compta/bank/various_payment/card.php | 20 ++-- htdocs/compta/bank/various_payment/index.php | 103 +++++++++++++------ 2 files changed, 85 insertions(+), 38 deletions(-) diff --git a/htdocs/compta/bank/various_payment/card.php b/htdocs/compta/bank/various_payment/card.php index f75c111094d..9328b6f599b 100644 --- a/htdocs/compta/bank/various_payment/card.php +++ b/htdocs/compta/bank/various_payment/card.php @@ -28,6 +28,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/paymentvarious.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; +if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; $langs->loadLangs(array("compta", "banks", "bills", "users", "accountancy")); @@ -70,7 +71,7 @@ if (empty($reshook)) { if ($action != 'addlink') { - $urltogo=$backtopage?$backtopage:dol_buildpath('/mymodule/myobject_list.php',1); + $urltogo=$backtopage?$backtopage:dol_buildpath('/compta/bank/various_payment/index.php',1); header("Location: ".$urltogo); exit; } @@ -172,7 +173,7 @@ if (empty($reshook)) if ($result >= 0) { $db->commit(); - header("Location: ".DOL_URL_ROOT.'/compta/salaries/index.php'); + header("Location: ".DOL_URL_ROOT.'/compta/bank/various_payment/index.php'); exit; } else @@ -339,9 +340,9 @@ if ($id) print '
    '.length_accountg($accountingaccount->getNomUrl(0,1,1,'',1)).''.$accountingaccount->getNomUrl(0,1,1,'',1).'
    '; - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; - print ""; + print ""; print ''; @@ -349,11 +350,13 @@ if ($id) // Label print ''; + // Payment date print ""; print ''; + // Value date print ''; @@ -370,11 +373,10 @@ if ($id) print '\n"; print ''; + // Ref print ''; + // Label print ''; + // Date print ''; + // Type print ''; + // Account if (! empty($conf->banque->enabled)) { @@ -181,10 +189,15 @@ if ($result) $form->select_comptes($search_account,'search_account',0,'',1); print ''; } - // Amount - print ''; - // Sens - print ''; + + // Accounting account + if (! empty($conf->accounting->enabled)) print ''; + + // Debit + print ''; + + // Credit + print ''; print '\n"; + $totalarray=array(); while ($i < min($num,$limit)) { $obj = $db->fetch_object($result); @@ -201,50 +215,81 @@ if ($result) $variousstatic->id=$obj->rowid; $variousstatic->ref=$obj->rowid; + // Ref print "\n"; + // Label payment print "\n"; + // Date payment print '\n"; + // Type print ''; + // Account if (! empty($conf->banque->enabled)) { print ''; } - // Amount - print ""; - // Sens - if ($obj->sens == '1') $sens = $langs->trans("Credit"); else $sens = $langs->trans("Debit"); - print ""; - print ""; - print "\n"; - $total = $total + $obj->amount; + // Accounting account + if (! empty($conf->accounting->enabled)) { + $accountingaccount = new AccountingAccount($db); + $accountingaccount->fetch('',$obj->accountancy_code); + + print ''; + } + + // Debit + print ""; + + // Credit + print ""; + + print ""; $i++; } - $colspan=4; + $colspan=5; if (! empty($conf->banque->enabled)) $colspan++; print ''; print ''; - print '"; + print '"; + print '"; print ''; print ''; print ''; From ddee8023249105fe0c264e703752084bce3976f6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Aug 2017 10:22:09 +0200 Subject: [PATCH 067/112] Add second parameter in GETPOST --- htdocs/comm/propal/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 0fd9ddb4c7c..0f0f1ded0db 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -73,9 +73,9 @@ $search_zip=GETPOST('search_zip','alpha'); $search_state=trim(GETPOST("search_state")); $search_country=GETPOST("search_country",'int'); $search_type_thirdparty=GETPOST("search_type_thirdparty",'int'); -$viewstatut=GETPOST('viewstatut'); +$viewstatut=GETPOST('viewstatut','alpha'); $optioncss = GETPOST('optioncss','alpha'); -$object_statut=GETPOST('propal_statut'); +$object_statut=GETPOST('propal_statut','alpha'); $sall=GETPOST('sall', 'alphanohtml'); $mesg=(GETPOST("msg") ? GETPOST("msg") : GETPOST("mesg")); From adbb41799cd52c99a2fd9d12a33ce8595a022a32 Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio Date: Tue, 1 Aug 2017 11:08:58 +0200 Subject: [PATCH 068/112] FIX: calculate correct remain to pay for planned bank transactions --- htdocs/compta/bank/treso.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php index cbdb769789f..92c1a73cf4f 100644 --- a/htdocs/compta/bank/treso.php +++ b/htdocs/compta/bank/treso.php @@ -282,6 +282,8 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) $refcomp=$societestatic->getNomUrl(1,'',24); $paiement = $facturestatic->getSommePaiement(); // Payment already done + $paiement+= $facturestatic->getSumDepositsUsed(); + $paiement+= $facturestatic->getSumCreditNotesUsed(); } if ($obj->family == 'social_contribution') { From 03b3f54c2cc2c000a684d21e814653af0c8133ff Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Aug 2017 13:10:15 +0200 Subject: [PATCH 069/112] Fix class not found --- .../project/doc/pdf_beluga.modules.php | 82 ++++++++++++------- 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/htdocs/core/modules/project/doc/pdf_beluga.modules.php b/htdocs/core/modules/project/doc/pdf_beluga.modules.php index 2b58cd59c09..15fd0e5f615 100644 --- a/htdocs/core/modules/project/doc/pdf_beluga.modules.php +++ b/htdocs/core/modules/project/doc/pdf_beluga.modules.php @@ -33,16 +33,17 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; -if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; -if (! empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; -if (! empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; -if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; -if (! empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; -if (! empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; -if (! empty($conf->contrat->enabled)) require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; -if (! empty($conf->ficheinter->enabled)) require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; -if (! empty($conf->deplacement->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php'; -if (! empty($conf->agenda->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; +if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; +if (! empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +if (! empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; +if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; +if (! empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; +if (! empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; +if (! empty($conf->contrat->enabled)) require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; +if (! empty($conf->ficheinter->enabled)) require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; +if (! empty($conf->deplacement->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php'; +if (! empty($conf->expensereport->enabled)) require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; +if (! empty($conf->agenda->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; @@ -223,7 +224,7 @@ class pdf_beluga extends ModelePDFProjects $iniY = $tab_top + 7; $curY = $tab_top + 7; $nexY = $tab_top + 7; - + $listofreferent=array( 'propal'=>array( 'name'=>"Proposals", @@ -311,7 +312,7 @@ class pdf_beluga extends ModelePDFProjects 'margin'=>'minus', 'disableamount'=>1, 'test'=>$conf->expensereport->enabled && $user->rights->expensereport->lire, - 'lang'=>'trip'), + 'lang'=>'trip'), 'agenda'=>array( 'name'=>"Agenda", 'title'=>"ListActionsAssociatedProject", @@ -322,8 +323,8 @@ class pdf_beluga extends ModelePDFProjects 'test'=>$conf->agenda->enabled && $user->rights->agenda->allactions->read, 'lang'=>'agenda') ); - - + + foreach ($listofreferent as $key => $value) { $title=$value['title']; @@ -333,13 +334,13 @@ class pdf_beluga extends ModelePDFProjects $qualified=$value['test']; $langstoload=$value['lang']; $langs->load($langstoload); - + if ($qualified) { //var_dump("$key, $tablename, $datefieldname, $dates, $datee"); $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee); //var_dump($elementarray); - + $num = count($elementarray); if ($num >= 0) { @@ -347,7 +348,7 @@ class pdf_beluga extends ModelePDFProjects $curY = $nexY; $pdf->SetXY($this->posxref, $curY); $pdf->MultiCell($this->posxstatut - $this->posxref, 3, $outputlangs->transnoentities($title), 0, 'L'); - + $selectList = $formproject->select_element($tablename, $project->thirdparty->id); $nexY = $pdf->GetY() + 1; $curY = $nexY; @@ -356,7 +357,9 @@ class pdf_beluga extends ModelePDFProjects $pdf->SetXY($this->posxdate, $curY); $pdf->MultiCell($this->posxsociety - $this->posxdate, 3, $outputlangs->transnoentities("Date"), 1, 'C'); $pdf->SetXY($this->posxsociety, $curY); - $pdf->MultiCell($this->posxamountht - $this->posxsociety, 3, $outputlangs->transnoentities("ThirdParty"), 1, 'L'); + $titlethirdparty=$outputlangs->transnoentities("ThirdParty"); + if ($classname == 'ExpenseReport') $titlethirdparty=$langs->trans("User"); + $pdf->MultiCell($this->posxamountht - $this->posxsociety, 3, $titlethirdparty, 1, 'L'); if (empty($value['disableamount'])) { $pdf->SetXY($this->posxamountht, $curY); $pdf->MultiCell($this->posxamountttc - $this->posxamountht, 3, $outputlangs->transnoentities("AmountHTShort"), 1, 'R'); @@ -368,30 +371,39 @@ class pdf_beluga extends ModelePDFProjects } $pdf->SetXY($this->posxstatut, $curY); $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxstatut, 3, $outputlangs->transnoentities("Statut"), 1, 'R'); - + if (is_array($elementarray) && count($elementarray) > 0) { $nexY = $pdf->GetY(); $curY = $nexY; - + $total_ht = 0; $total_ttc = 0; $num = count($elementarray); for ($i = 0; $i < $num; $i ++) { + $idofelement=$elementarray[$i]; + if ($classname == 'ExpenseReport') + { + // We get id of expense report + $expensereportline=new ExpenseReportLine($this->db); + $expensereportline->fetch($idofelement); + $idofelement = $expensereportline->fk_expensereport; + } + $element = new $classname($this->db); - $element->fetch($elementarray[$i]); + $element->fetch($idofelement); $element->fetch_thirdparty(); // print $classname; - + $qualifiedfortotal = true; if ($key == 'invoice') { if ($element->close_code == 'replaced') $qualifiedfortotal = false; // Replacement invoice } - + $pdf->SetXY($this->posxref, $curY); $pdf->MultiCell($this->posxdate - $this->posxref, 3, $element->ref, 1, 'L'); - + // Date if ($tablename == 'commande_fournisseur' || $tablename == 'supplier_order') $date = $element->date_commande; @@ -404,15 +416,23 @@ class pdf_beluga extends ModelePDFProjects if (empty($date)) $date = $element->datev; // Fiche inter } - + $pdf->SetXY($this->posxdate, $curY); $pdf->MultiCell($this->posxsociety - $this->posxdate, 3, dol_print_date($date, 'day'), 1, 'C'); - + $pdf->SetXY($this->posxsociety, $curY); if (is_object($element->thirdparty)) + { $pdf->MultiCell($this->posxamountht - $this->posxsociety, 3, $element->thirdparty->name, 1, 'L'); - - // Amount without tax + } + elseif ($classname == 'ExpenseReport') + { + $fuser=new User($this->db); + $fuser->fetch($element->fk_user_author); + $pdf->MultiCell($this->posxamountht - $this->posxsociety, 3, $fuser->getFullName($outputlangs), 1, 'L'); + } + + // Amount without tax if (empty($value['disableamount'])) { $pdf->SetXY($this->posxamountht, $curY); $pdf->MultiCell($this->posxamountttc - $this->posxamountht, 3, (isset($element->total_ht) ? price($element->total_ht) : ' '), 1, 'R'); @@ -422,7 +442,7 @@ class pdf_beluga extends ModelePDFProjects $pdf->SetXY($this->posxamountht, $curY); $pdf->MultiCell($this->posxstatut - $this->posxamountht, 3, "", 1, 'R'); } - + // Status if ($element instanceof CommonInvoice) { // This applies for Facture and FactureFournisseur @@ -432,7 +452,7 @@ class pdf_beluga extends ModelePDFProjects } $pdf->SetXY($this->posxstatut, $curY); $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxstatut, 3, $outputstatut, 1, 'R', false, 1, '', '', true, 0, true); - + if ($qualifiedfortotal) { $total_ht = $total_ht + $element->total_ht; $total_ttc = $total_ttc + $element->total_ttc; @@ -440,7 +460,7 @@ class pdf_beluga extends ModelePDFProjects $nexY = $pdf->GetY(); $curY = $nexY; } - + if (empty($value['disableamount'])) { $curY = $nexY; $pdf->SetXY($this->posxref, $curY); From 19ba90f57780e1ed724e382d7ed3a4f3e5dc64f2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Aug 2017 13:17:27 +0200 Subject: [PATCH 070/112] Fix creation of leave request --- htdocs/holiday/card.php | 17 ++++++++++------- htdocs/holiday/class/holiday.class.php | 6 +++--- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index e50c880c0ee..8ee0fb64b40 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -60,7 +60,7 @@ if ($action == 'create') $object = new Holiday($db); // If no right to create a request - $fuserid = GETPOST('fuserid'); + $fuserid = GETPOST('fuserid','int'); if (($fuserid == $user->id && empty($user->rights->holiday->write)) || ($fuserid != $user->id && empty($user->rights->holiday->write_all))) { $error++; @@ -118,7 +118,7 @@ if ($action == 'create') } // Check if there is already holiday for this period - $verifCP = $object->verifDateHolidayCP($userID, $date_debut, $date_fin, $halfday); + $verifCP = $object->verifDateHolidayCP($fuserid, $date_debut, $date_fin, $halfday); if (! $verifCP) { setEventMessages($langs->trans("alreadyCPexist"), null, 'errors'); @@ -144,11 +144,9 @@ if ($action == 'create') $result = 0; - $result = 0; - if (! $error) { - $object->fk_user = $userid; + $object->fk_user = $fuserid; $object->description = $description; $object->date_debut = $date_debut; $object->date_fin = $date_fin; @@ -157,10 +155,15 @@ if ($action == 'create') $object->fk_type = $type; $result = $object->create($user); + if ($result <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } } // If no SQL error we redirect to the request card - if (! $error && $result > 0) + if (! $error) { $db->commit(); @@ -834,7 +837,7 @@ if (empty($id) || $action == 'add' || $action == 'request' || $action == 'create print $form->select_dolusers($fuserid, 'useridbis', 0, '', 1, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); print ''; } - else print $form->select_dolusers(GETPOST('fuserid')?GETPOST('fuserid'):$user->id,'fuserid',0,'',0); + else print $form->select_dolusers(GETPOST('fuserid','int')?GETPOST('fuserid','int'):$user->id,'fuserid',0,'',0); print ''; print ''; diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 9973223ba0f..4815bee4b00 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -125,9 +125,9 @@ class Holiday extends CommonObject $now=dol_now(); // Check parameters - if (empty($this->fk_user) || ! is_numeric($this->fk_user) || $this->fk_user < 0) { $this->error="ErrorBadParameter"; return -1; } - if (empty($this->fk_validator) || ! is_numeric($this->fk_validator) || $this->fk_validator < 0) { $this->error="ErrorBadParameter"; return -1; } - if (empty($this->fk_type) || ! is_numeric($this->fk_type) || $this->fk_type < 0) { $this->error="ErrorBadParameter"; return -1; } + if (empty($this->fk_user) || ! is_numeric($this->fk_user) || $this->fk_user < 0) { $this->error="ErrorBadParameterFkUser"; return -1; } + if (empty($this->fk_validator) || ! is_numeric($this->fk_validator) || $this->fk_validator < 0) { $this->error="ErrorBadParameterFkValidator"; return -1; } + if (empty($this->fk_type) || ! is_numeric($this->fk_type) || $this->fk_type < 0) { $this->error="ErrorBadParameterFkType"; return -1; } // Insert request $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday("; From f9dc628f0bb0d528f292a4b7a4bb5a7bebb1f73d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Aug 2017 15:53:22 +0200 Subject: [PATCH 071/112] Add tool to fix missing thumbs --- htdocs/core/lib/images.lib.php | 2 +- scripts/product/regenerate_thumbs.php | 106 ++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100755 scripts/product/regenerate_thumbs.php diff --git a/htdocs/core/lib/images.lib.php b/htdocs/core/lib/images.lib.php index d9d7d0d9730..e6f69da1d93 100644 --- a/htdocs/core/lib/images.lib.php +++ b/htdocs/core/lib/images.lib.php @@ -347,7 +347,7 @@ function dolRotateImage($file_path) * @param int $quality Quality of compression (0=worst, 100=best) * @param string $outdir Directory where to store thumb * @param int $targetformat New format of target (IMAGETYPE_GIF, IMAGETYPE_JPG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_WBMP ... or 0 to keep old format) - * @return string Full path of thumb or '' if it fails + * @return string Full path of thumb or '' if it fails or 'Error...' if it fails */ function vignette($file, $maxWidth = 160, $maxHeight = 120, $extName='_small', $quality=50, $outdir='thumbs', $targetformat=0) { diff --git a/scripts/product/regenerate_thumbs.php b/scripts/product/regenerate_thumbs.php new file mode 100755 index 00000000000..389dcf2222a --- /dev/null +++ b/scripts/product/regenerate_thumbs.php @@ -0,0 +1,106 @@ +#!/usr/bin/env php + + * Copyright (C) 2015 Jean Heimburger + * + * 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 scripts/product/migrate_picture_path.php + * \ingroup scripts + * \brief Migrate pictures from old system prior to 3.7 to new path for 3.7+ + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + exit(-1); +} + +@set_time_limit(0); // No timeout for this script +define('EVEN_IF_ONLY_LOGIN_ALLOWED',1); // Set this define to 0 if you want to lock your script when dolibarr setup is "locked to admin user only". + +// Include and load Dolibarr environment variables +require_once($path."../../htdocs/master.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/images.lib.php"); +// After this $db, $mysoc, $langs, $conf and $hookmanager are defined (Opened $db handler to database will be closed at end of file). +// $user is created but empty. + +//$langs->setDefaultLang('en_US'); // To change default language of $langs +$langs->load("main"); // To load language file for default language + + +// Global variables +$version=DOL_VERSION; +$error=0; +$forcecommit=0; + + +print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n"; +dol_syslog($script_file." launched with arg ".join(',',$argv)); + +if (empty($argv[1])) { + print "Usage: $script_file subdirtoscan\n"; + print "Example: $script_file produit\n"; + exit(-1); +} + +print '--- start'."\n"; + +$dir = DOL_DATA_ROOT; +$subdir=$argv[1]; +if (empty($dir) || empty($subdir)) +{ + dol_print_error('', 'dir not defined'); + exit(1); +} +if (! dol_is_dir($dir.'/'.$subdir)) +{ + print 'Directory '.$dir.'/'.$subdir.' not found.'."\n"; + exit(2); +} + +$filearray=dol_dir_list($dir.'/'.$subdir,"directories",0,'','temp$'); + +global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini; + +foreach($filearray as $keyf => $valf) +{ + $ref=basename($valf['name']); + $filearrayimg=dol_dir_list($valf['fullname'],"files",0,'(\.gif|\.png|\.jpg|\.jpeg|\.bmp)$','(\.meta|_preview.*\.png)$'); + foreach($filearrayimg as $keyi => $vali) + { + print 'Process image for ref '.$ref.' : '.$vali['name']."\n"; + + // Used on logon for example + $imgThumbSmall = vignette($vali['fullname'], $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs"); + if (preg_match('/Error/', $imgThumbSmall)) print $imgThumbSmall."\n"; + + // Create mini thumbs for image (Ratio is near 16/9) + // Used on menu or for setup page for example + $imgThumbMini = vignette($vali['fullname'], $maxwidthmini, $maxheightmini, '_mini', 50, "thumbs"); + if (preg_match('/Error/', $imgThumbMini)) print $imgThumbMini."\n"; + } +} + +$db->close(); // Close $db database opened handler + +exit($error); From 747719b3e8c93ed02a3770d5cb2127170f1c65ab Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Aug 2017 15:54:28 +0200 Subject: [PATCH 072/112] Code comment --- scripts/product/regenerate_thumbs.php | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/product/regenerate_thumbs.php b/scripts/product/regenerate_thumbs.php index 389dcf2222a..bc3e1f53a6b 100755 --- a/scripts/product/regenerate_thumbs.php +++ b/scripts/product/regenerate_thumbs.php @@ -90,6 +90,7 @@ foreach($filearray as $keyf => $valf) { print 'Process image for ref '.$ref.' : '.$vali['name']."\n"; + // Create small thumbs for image // Used on logon for example $imgThumbSmall = vignette($vali['fullname'], $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs"); if (preg_match('/Error/', $imgThumbSmall)) print $imgThumbSmall."\n"; From 71d49f1c6f5761b9e09e980eeedc457c2ff1555a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Aug 2017 18:32:21 +0200 Subject: [PATCH 073/112] Fix pb in ecm --- htdocs/core/ajax/ajaxdirpreview.php | 4 +- htdocs/core/class/html.form.class.php | 28 ++++++++----- htdocs/core/class/html.formfile.class.php | 6 +-- htdocs/core/lib/files.lib.php | 24 ++++++----- htdocs/core/lib/functions.lib.php | 2 +- htdocs/core/modules/modECM.class.php | 2 +- htdocs/ecm/class/ecmdirectory.class.php | 28 ++++++++++++- htdocs/ecm/docfile.php | 8 ++-- htdocs/ecm/docmine.php | 50 +++++++++++++++-------- htdocs/ecm/index.php | 4 +- 10 files changed, 104 insertions(+), 52 deletions(-) diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php index 709d07c0832..cee16f923f5 100644 --- a/htdocs/core/ajax/ajaxdirpreview.php +++ b/htdocs/core/ajax/ajaxdirpreview.php @@ -202,7 +202,7 @@ if ($type == 'directory') $upload_dir = $conf->ecm->dir_output.'/'.$relativepath; // If $section defined with value 0 - if ($section === '0') + if ($section === '0' || empty($section)) { $filearray=array(); } @@ -216,7 +216,7 @@ if ($type == 'directory') else if ($section === '0') $textifempty='
    '.$langs->trans("DirNotSynchronizedSyncFirst").'

    '; else $textifempty=($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("ECMSelectASection")); - $formfile->list_of_documents($filearray,'','ecm',$param,1,$relativepath,$user->rights->ecm->upload,1,$textifempty,$maxlengthname,'',$url); + $formfile->list_of_documents($filearray,'','ecm',$param,1,$relativepath,$user->rights->ecm->upload,1,$textifempty,$maxlengthname,'',$url); } } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 27115d12eb7..c7dd20547f4 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5890,18 +5890,22 @@ class Form $object->next_prev_filter.=$hookmanager->resPrint; } - //print "paramid=$paramid,morehtml=$morehtml,shownav=$shownav,$fieldid,$fieldref,$morehtmlref,$moreparam"; - $object->load_previous_next_ref((isset($object->next_prev_filter)?$object->next_prev_filter:''),$fieldid,$nodbprefix); - - $navurl = $_SERVER["PHP_SELF"]; - // Special case for project/task page - if ($paramid == 'project_ref') + $previous_ref = $next_ref = ''; + if ($shownav) { - $navurl = preg_replace('/\/tasks\/(task|contact|time|note|document).php/','/tasks.php',$navurl); - $paramid='ref'; + //print "paramid=$paramid,morehtml=$morehtml,shownav=$shownav,$fieldid,$fieldref,$morehtmlref,$moreparam"; + $object->load_previous_next_ref((isset($object->next_prev_filter)?$object->next_prev_filter:''),$fieldid,$nodbprefix); + + $navurl = $_SERVER["PHP_SELF"]; + // Special case for project/task page + if ($paramid == 'project_ref') + { + $navurl = preg_replace('/\/tasks\/(task|contact|time|note|document)\.php/','/tasks.php',$navurl); + $paramid='ref'; + } + $previous_ref = $object->ref_previous?'':''; + $next_ref = $object->ref_next?'':''; } - $previous_ref = $object->ref_previous?'':''; - $next_ref = $object->ref_next?'':''; //print "xx".$previous_ref."x".$next_ref; $ret.='
    '; @@ -5955,6 +5959,10 @@ class Form { $ret.=$object->label; } + else if ($object->element == 'ecm_directories') + { + $ret.=''; + } else if ($fieldref != 'none') $ret.=dol_htmlentities($object->$fieldref); diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 040ae1ba96e..c02d2b5c2be 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -1007,9 +1007,9 @@ class FormFile print '
    '.$langs->trans("Ref").''; print $form->showrefnav($object, 'id', $linkback, 1, 'rowid', 'ref', ''); print '
    '.$langs->trans("Label").''.$object->label.'
    '.$langs->trans("DatePayment").''; print dol_print_date($object->datep,'day'); print '
    '.$langs->trans("DateValue").''; print dol_print_date($object->datev,'day'); print '
    '; if (! empty($conf->accounting->enabled)) { - $accountancyaccount = new AccountingAccount($db); - $accountancyaccount->fetch('',$object->accountancy_code); + $accountingaccount = new AccountingAccount($db); + $accountingaccount->fetch('',$object->accountancy_code); - print $accountancyaccount->getNomUrl(1); - // print length_accountg($object->accountancy_code); + print $accountingaccount->getNomUrl(1); } else { print $object->accountancy_code; } @@ -411,7 +413,7 @@ if ($id) print '
    '."\n"; if ($object->rappro == 0) { - if (! empty($user->rights->banque->delete)) + if (! empty($user->rights->banque->modifier)) { print ''.$langs->trans("Delete").''; } diff --git a/htdocs/compta/bank/various_payment/index.php b/htdocs/compta/bank/various_payment/index.php index 5b2488cc5e8..101517df6fd 100644 --- a/htdocs/compta/bank/various_payment/index.php +++ b/htdocs/compta/bank/various_payment/index.php @@ -17,7 +17,7 @@ */ /** - * \file htdocs/compta/bank/various_payment/index.php + * \file htdocs/compta/bank/various_payment/index.php * \ingroup bank * \brief List of various payments */ @@ -25,10 +25,10 @@ require '../../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/paymentvarious.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; +if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php'; +if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php'; -$langs->load("compta"); -$langs->load("banks"); -$langs->load("bills"); +$langs->loadLangs(array("compta","banks","bills","accountancy")); // Security check $socid = GETPOST("socid","int"); @@ -41,7 +41,8 @@ $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $search_ref = GETPOST('search_ref','int'); $search_user = GETPOST('search_user','alpha'); $search_label = GETPOST('search_label','alpha'); -$search_amount = GETPOST('search_amount','alpha'); +$search_amount_deb = GETPOST('search_amount_deb','alpha'); +$search_amount_cred = GETPOST('search_amount_cred','alpha'); $search_account = GETPOST('search_account','int'); $sortfield = GETPOST("sortfield",'alpha'); @@ -75,7 +76,8 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x', { $search_ref=""; $search_label=""; - $search_amount=""; + $search_amount_deb=""; + $search_amount_cred=""; $search_account=''; $typeid=""; } @@ -90,8 +92,8 @@ $form = new Form($db); $variousstatic = new PaymentVarious($db); $accountstatic = new Account($db); -$sql = "SELECT v.rowid, v.amount, v.label, v.datep as datep, v.datev as datev, v.fk_typepayment as type, v.num_payment, v.fk_bank,"; -$sql.= " ba.rowid as bid, ba.ref as bref, ba.number as bnumber, ba.account_number, ba.fk_accountancy_journal, ba.label as blabel,"; +$sql = "SELECT v.rowid, v.amount, v.label, v.datep as datep, v.datev as datev, v.fk_typepayment as type, v.num_payment, v.fk_bank, v.accountancy_code, v.sens,"; +$sql.= " ba.rowid as bid, ba.ref as bref, ba.number as bnumber, ba.account_number as bank_account_number, ba.fk_accountancy_journal as accountancy_journal, ba.label as blabel,"; $sql.= " pst.code as payment_code"; $sql.= " FROM ".MAIN_DB_PREFIX."payment_various as v"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as pst ON v.fk_typepayment = pst.id"; @@ -102,7 +104,8 @@ $sql.= " WHERE v.entity = ".$conf->entity; // Search criteria if ($search_ref) $sql.=" AND v.rowid=".$search_ref; if ($search_label) $sql.=natural_search(array('v.label'), $search_label); -if ($search_amount) $sql.=natural_search("v.amount", $search_amount, 1); +if ($search_amount_deb) $sql.=natural_search("v.amount", $search_amount_deb, 1); +if ($search_amount_cred) $sql.=natural_search("v.amount", $search_amount_cred, 1); if ($search_account > 0) $sql .=" AND b.fk_account=".$search_account; if ($filtre) { $filtre=str_replace(":","=",$filtre); @@ -113,7 +116,6 @@ if ($typeid) { } $sql.= $db->order($sortfield,$sortorder); -//$sql.= " GROUP BY u.rowid, u.lastname, u.firstname, v.rowid, v.fk_user, v.amount, v.label, v.datev, v.fk_typepayment, v.num_payment, pst.code"; $totalnboflines=0; $result=$db->query($sql); if ($result) @@ -156,24 +158,30 @@ if ($result) print_liste_field_titre($langs->trans("DatePayment"),$_SERVER["PHP_SELF"],"v.datep","",$param,'align="center"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("PaymentMode"),$_SERVER["PHP_SELF"],"type","",$param,'align="left"',$sortfield,$sortorder); if (! empty($conf->banque->enabled)) print_liste_field_titre($langs->trans("BankAccount"),$_SERVER["PHP_SELF"],"ba.label","",$param,"",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Amount"),$_SERVER["PHP_SELF"],"v.amount","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Sens"),$_SERVER["PHP_SELF"],"v.sens","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("AccountAccounting"),$_SERVER["PHP_SELF"],"v.accountancy_code","",$param,'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Debit"),$_SERVER["PHP_SELF"],"v.amount","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Credit"),$_SERVER["PHP_SELF"],"v.amount","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre('',$_SERVER["PHP_SELF"],"",'','','',$sortfield,$sortorder,'maxwidthsearch '); print "
    '; print ''; print ' '; $form->select_types_paiements($typeid,'typeid','',0,0,1,16); print '  '; $searchpicto=$form->showFilterAndCheckAddButtons(0); @@ -193,6 +206,7 @@ if ($result) print "
    ".$variousstatic->getNomUrl(1)."".dol_trunc($obj->label,40)."'.dol_print_date($db->jdate($obj->datep),'day')."'.$langs->trans("PaymentTypeShort".$obj->payment_code).' '.$obj->num_payment.''; if ($obj->fk_bank > 0) { - //$accountstatic->fetch($obj->fk_bank); $accountstatic->id=$obj->bid; $accountstatic->ref=$obj->bref; $accountstatic->number=$obj->bnumber; - $accountstatic->accountancy_number=$obj->account_number; - $accountstatic->fk_accountancy_journal=$obj->fk_accountancy_journal; + + if (! empty($conf->accounting->enabled)) { + $accountstatic->account_number=$obj->bank_account_number; + + $accountingjournal = new AccountingJournal($db); + $accountingjournal->fetch($obj->accountancy_journal); + $accountstatic->accountancy_journal = $accountingjournal->getNomUrl(0,1,1,'',1); + } + $accountstatic->label=$obj->blabel; print $accountstatic->getNomUrl(1); } else print ' '; print '".price($obj->amount)."".$sens."
    '.$accountingaccount->getNomUrl(0,1,1,'',1).'"; + if ($obj->sens == 0) + { + print price($obj->amount); + $totalarray['totaldeb'] += $obj->amount; + } + print ""; + if ($obj->sens == 1) + { + print price($obj->amount); + $totalarray['totalcred'] += $obj->amount; + } + print "
    '.$langs->trans("Total").''.price($total)."'.price($totalarray['totaldeb'])."'.price($totalarray['totalcred'])."
    '."\n"; print ''; - print_liste_field_titre($langs->trans("Documents2"),$url,"name","",$param,'align="left"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Size"),$url,"size","",$param,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Date"),$url,"date","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre('Documents2',$url,"name","",$param,'align="left"',$sortfield,$sortorder); + print_liste_field_titre('Size',$url,"size","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre('Date',$url,"date","",$param,'align="center"',$sortfield,$sortorder); if (empty($useinecm)) print_liste_field_titre('',$url,"","",$param,'align="center"'); print_liste_field_titre(''); if (! $disablemove) print_liste_field_titre(''); diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 0b8282ad5b6..394b3e76778 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1349,14 +1349,15 @@ function dol_init_file_process($pathtoscan='', $trackid='') * * @param string $upload_dir Directory where to store uploaded file (note: used to forge $destpath = $upload_dir + filename) * @param int $allowoverwrite 1=Allow overwrite existing file - * @param int $donotupdatesession 1=Do no edit _SESSION variable + * @param int $donotupdatesession 1=Do no edit _SESSION variable but update database index. 0=Update _SESSION and not database index. * @param string $varfiles _FILES var name * @param string $savingdocmask Mask to use to define output filename. For example 'XXXXX-__YYYYMMDD__-__file__' * @param string $link Link to add (to add a link instead of a file) * @param string $trackid Track id (used to prefix name of session vars to avoid conflict) + * @param int $generatethumbs 1=Generate also thumbs for uploaded image files * @return int <=0 if KO, >0 if OK */ -function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesession=0, $varfiles='addedfile', $savingdocmask='', $link=null, $trackid='') +function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesession=0, $varfiles='addedfile', $savingdocmask='', $link=null, $trackid='', $generatethumbs=1) { global $db,$user,$conf,$langs; @@ -1407,16 +1408,19 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; // Generate thumbs. - if (image_format_supported($destfull) == 1) + if ($generatethumbs) { - // Create thumbs - // We can't use $object->addThumbs here because there is no $object known + if (image_format_supported($destfull) == 1) + { + // Create thumbs + // We can't use $object->addThumbs here because there is no $object known - // Used on logon for example - $imgThumbSmall = vignette($destfull, $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs"); - // Create mini thumbs for image (Ratio is near 16/9) - // Used on menu or for setup page for example - $imgThumbMini = vignette($destfull, $maxwidthmini, $maxheightmini, '_mini', 50, "thumbs"); + // Used on logon for example + $imgThumbSmall = vignette($destfull, $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs"); + // Create mini thumbs for image (Ratio is near 16/9) + // Used on menu or for setup page for example + $imgThumbMini = vignette($destfull, $maxwidthmini, $maxheightmini, '_mini', 50, "thumbs"); + } } // Update session diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 61093ebcc52..0b629c1f215 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1341,7 +1341,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r if (! empty($object->label)) $morehtmlref.='
    '.$object->label.'
    '; } - if ($object->element != 'product' && $object->element != 'bookmark') + if ($object->element != 'product' && $object->element != 'bookmark' && $object->element != 'ecm_directories') { $morehtmlref.='
    '; $morehtmlref.=$object->getBannerAddress('refaddress',$object); diff --git a/htdocs/core/modules/modECM.class.php b/htdocs/core/modules/modECM.class.php index b263b16e29e..bfe0e45e02c 100644 --- a/htdocs/core/modules/modECM.class.php +++ b/htdocs/core/modules/modECM.class.php @@ -63,7 +63,7 @@ class modECM extends DolibarrModules $this->picto='dir'; // Data directories to create when module is enabled - $this->dirs = array("/ecm/temp"); + $this->dirs = array("/ecm/My_First_Directory","/ecm/temp"); // Config pages. Put here list of php page names stored in admmin directory used to setup module $this->config_page_url = array('ecm.php'); diff --git a/htdocs/ecm/class/ecmdirectory.class.php b/htdocs/ecm/class/ecmdirectory.class.php index 31439fa5ba3..5f713bdab91 100644 --- a/htdocs/ecm/class/ecmdirectory.class.php +++ b/htdocs/ecm/class/ecmdirectory.class.php @@ -27,8 +27,9 @@ */ class EcmDirectory // extends CommonObject { - //public $element='ecm_directories'; //!< Id that identify managed objects + public $element='ecm_directories'; //!< Id that identify managed objects //public $table_element='ecm_directories'; //!< Name of table without prefix where object is stored + var $picto = 'dir'; var $id; @@ -514,6 +515,31 @@ class EcmDirectory // extends CommonObject } + /** + * Retourne le libelle du status d'un user (actif, inactif) + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label of status + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->status,$mode); + } + + /** + * Return the status + * + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 5=Long label + Picto + * @return string Label of status + */ + static function LibStatut($status,$mode=0) + { + global $langs; + return ''; + } + + /** * Reconstruit l'arborescence des categories sous la forme d'un tableau à partir de la base de donnée * Renvoi un tableau de tableau('id','id_mere',...) trie selon arbre et avec: diff --git a/htdocs/ecm/docfile.php b/htdocs/ecm/docfile.php index 31f9b6b11c2..577ac3e0262 100644 --- a/htdocs/ecm/docfile.php +++ b/htdocs/ecm/docfile.php @@ -78,7 +78,7 @@ if (! $urlfile) // Load ecm object $ecmdir = new EcmDirectory($db); -$result=$ecmdir->fetch(GETPOST("section")); +$result=$ecmdir->fetch(GETPOST("section",'alpha')); if (! $result > 0) { dol_print_error($db,$ecmdir->error); @@ -109,10 +109,10 @@ if (! empty($_GET["fileid"])) * Put here all code to do according to value of "action" parameter ********************************************************************/ -if ($action == 'cancel') +if ($action == 'cancel') { $action =''; - if ($backtourl) + if ($backtourl) { header("Location: ".$backtourl); exit; @@ -144,7 +144,7 @@ if ($action == 'update') //print $oldfile.' - '.$newfile; if ($newlabel != $oldlabel) { - $result=dol_move($oldfile,$newfile); + $result=dol_move($oldfile, $newfile); if (! $result) { $langs->load('errors'); diff --git a/htdocs/ecm/docmine.php b/htdocs/ecm/docmine.php index 48f39cb12f2..f418627d1be 100644 --- a/htdocs/ecm/docmine.php +++ b/htdocs/ecm/docmine.php @@ -191,15 +191,15 @@ if ($action == 'update' && ! GETPOST('cancel')) /******************************************************************* -* PAGE -* -* Put here all code to do according to value of "action" parameter +* View ********************************************************************/ -llxHeader(); - $form=new Form($db); +$object=new EcmDirectory($db); // Need to create a new one +$object->fetch($ecmdir->id); + +llxHeader(); // Built the file List $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); @@ -211,7 +211,8 @@ foreach($filearray as $key => $file) $head = ecm_prepare_head($ecmdir); -dol_fiche_head($head, 'card', $langs->trans("ECMSectionManual"), '', 'dir'); +dol_fiche_head($head, 'card', $langs->trans("ECMSectionManual"), -1, 'dir'); + if ($action == 'edit') { @@ -221,13 +222,11 @@ if ($action == 'edit') print ''; } -print '
    '; -print '
    '.$langs->trans("Ref").''; $s=''; -$tmpecmdir=new EcmDirectory($db); // Need to create a new one -$tmpecmdir->fetch($ecmdir->id); $result = 1; $i=0; +$tmpecmdir=new EcmDirectory($db); // Need to create a new one +$tmpecmdir->fetch($ecmdir->id); while ($tmpecmdir && $result > 0) { $tmpecmdir->ref=$tmpecmdir->label; @@ -248,10 +247,21 @@ while ($tmpecmdir && $result > 0) $i++; } +$morehtml=''; + +$morehtmlref = ''.$langs->trans("ECMRoot").' -> '.$s; + +dol_banner_tab($object, '', $morehtml, 0, '', '', $morehtmlref); + +print '
    '; + +print '
    '; +print ''; +/*print ''; -print '';*/ +print '
    '.$langs->trans("Ref").''; print img_picto('','object_dir').' '.$langs->trans("ECMRoot").' -> '; print $s; -print '
    '.$langs->trans("Description").''; +print '
    '.$langs->trans("Description").''; if ($action == 'edit') { print '