diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index f8ac87fcb3e..eb1efd3211b 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -80,7 +80,10 @@ $pageprev = $page - 1; $pagenext = $page + 1; $search_country_id = GETPOST('search_country_id','int'); -if($search_country_id == '') $search_country_id = $mysoc->country_id; +if ($search_country_id == '' && ($id == 2 || $id == 3 || $id == 10)) // Not a so good idea to force on current country for all dictionaries. Some tables have entries that are for all countries, we must be able to see them, so this is done for dedicated dictionaries only. +{ + $search_country_id = $mysoc->country_id; +} $search_code = GETPOST('search_code','alpha'); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context @@ -90,7 +93,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,35,36,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,24,28,17,35,36,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(); @@ -282,6 +285,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_ik,fk_c_exp_tax_cat"; @@ -1010,6 +1015,11 @@ if ($id) $sql.=$db->plimit($listlimit+1,$offset); //print $sql; + if (empty($tabfield[$id])) + { + dol_print_error($db, 'The table with id '.$id.' has no array tabfield defined'); + exit; + } $fieldlist=explode(',',$tabfield[$id]); print '
'; @@ -1393,6 +1403,7 @@ if ($id) foreach ($fieldlist as $field => $value) { + //var_dump($fieldlist); $showfield=1; $align="left"; $valuetoshow=$obj->{$fieldlist[$field]}; @@ -1750,7 +1761,7 @@ $db->close(); * @param Object $obj If we show a particular record, obj is filled with record fields * @param string $tabname Name of SQL table * @param string $context 'add'=Output field for the "add form", 'edit'=Output field for the "edit form", 'hide'=Output field for the "add form" but we dont want it to be rendered - * @return string '' or value of entity into table + * @return string '' or value of entity into table */ function fieldList($fieldlist, $obj='', $tabname='', $context='') { diff --git a/htdocs/admin/workflow.php b/htdocs/admin/workflow.php index c730760898d..511188e55df 100644 --- a/htdocs/admin/workflow.php +++ b/htdocs/admin/workflow.php @@ -27,8 +27,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -$langs->load("admin"); -$langs->load("workflow"); +$langs->loadLangs(array("admin","workflow","propal","workflow","orders","supplier_proposals")); if (! $user->admin) accessforbidden(); @@ -68,21 +67,26 @@ print "
"; // List of workflow we can enable -print ''."\n"; - clearstatcache(); $workflowcodes=array( // Automatic creation 'WORKFLOW_PROPAL_AUTOCREATE_ORDER'=>array('family'=>'create', 'position'=>10, 'enabled'=>'! empty($conf->propal->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'order'), 'WORKFLOW_ORDER_AUTOCREATE_INVOICE'=>array('family'=>'create', 'position'=>20, 'enabled'=>'! empty($conf->commande->enabled) && ! empty($conf->facture->enabled)', 'picto'=>'bill'), - // Automatic classification - 'WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL'=>array('family'=>'classify', 'position'=>30, 'enabled'=>'! empty($conf->propal->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'order','warning'=>''), - 'WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL'=>array('family'=>'classify', 'position'=>30, 'enabled'=>'! empty($conf->propal->enabled) && ! empty($conf->facture->enabled)', 'picto'=>'order','warning'=>''), + 'separator1'=>array('family'=>'separator', 'position'=>25), + // Automatic classification proposal + 'WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL'=>array('family'=>'classify_proposal', 'position'=>30, 'enabled'=>'! empty($conf->propal->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'propal','warning'=>''), + 'WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL'=>array('family'=>'classify_proposal', 'position'=>31, 'enabled'=>'! empty($conf->propal->enabled) && ! empty($conf->facture->enabled)', 'picto'=>'propal','warning'=>''), + // Automatic classification invoice + 'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING'=>array('family'=>'classify_order', 'position'=>40, 'enabled'=>'! empty($conf->expedition->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'order'), // For the following 2 options, if module invoice is disabled, they does not exists, so "Classify billed" for order must be done manually from order card. - 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER'=>array('family'=>'classify', 'position'=>50, 'enabled'=>'! empty($conf->facture->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'bill','warning'=>''), - 'WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER'=>array('family'=>'classify', 'position'=>40, 'enabled'=>'! empty($conf->facture->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'bill','warning'=>''), - 'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING'=>array('family'=>'classify', 'position'=>30, 'enabled'=>'! empty($conf->expedition->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'order'), + 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER'=>array('family'=>'classify_order', 'position'=>41, 'enabled'=>'! empty($conf->facture->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'order','warning'=>''), + //Moved as hidden feature: 'WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER'=>array('family'=>'classify_order', 'position'=>42, 'enabled'=>'! empty($conf->facture->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'order','warning'=>''), + 'separator2'=>array('family'=>'separator', 'position'=>50), + // Automatic classification supplier proposal + 'WORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL'=>array('family'=>'classify_supplier_proposal', 'position'=>60, 'enabled'=>'! empty($conf->supplier_proposal->enabled) && ! empty($conf->fournisseur->enabled)', 'picto'=>'propal','warning'=>''), + // Automatic classification supplier order + 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER'=>array('family'=>'classify_supplier_order', 'position'=>62, 'enabled'=>'! empty($conf->fournisseur->enabled)', 'picto'=>'order','warning'=>''), ); if (! empty($conf->modules_parts['workflow']) && is_array($conf->modules_parts['workflow'])) @@ -93,27 +97,53 @@ if (! empty($conf->modules_parts['workflow']) && is_array($conf->modules_parts[' } } -// TODO We must sort on position here +// Sort on position +$workflowcodes = dol_sort_array($workflowcodes, 'position'); $nbqualified=0; $oldfamily=''; +print '
'."\n"; + foreach($workflowcodes as $key => $params) { $picto=$params['picto']; $enabled=$params['enabled']; $family=$params['family']; - if (! verifCond($enabled)) continue; + + if ($family == 'separator') + { + print '

'; + print ''."\n"; + + continue; + } + + if (! verifCond($enabled)) continue; $nbqualified++; + if ($oldfamily != $family) { print ''."\n"; print ' '; print ' '; print "\n"; diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 431ac1b5569..4cbb0d929fc 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -392,7 +392,7 @@ if (! empty($conf->use_javascript_ajax)) // If javascript on $s.='' . "\n"; // Local calendar - $s.='
' . $langs->trans("LocalAgenda").'  
'; + $s.='
' . $langs->trans("LocalAgenda").'  
'; // External calendars if (is_array($showextcals) && count($showextcals) > 0) @@ -409,12 +409,12 @@ if (! empty($conf->use_javascript_ajax)) // If javascript on foreach ($showextcals as $val) { $htmlname = md5($val['name']); - $s.='
' . $val['name'] . '  
'; + $s.='
' . $val['name'] . '  
'; } } // Birthdays - $s.='
'.$langs->trans("AgendaShowBirthdayEvents").'  
'; + $s.='
'.$langs->trans("AgendaShowBirthdayEvents").'  
'; // Calendars from hooks $parameters=array(); $object=null; @@ -1375,7 +1375,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print '>'; print '
'; - if ($family == 'create') print $langs->trans("AutomaticCreation"); - elseif ($family == 'classify') print $langs->trans("AutomaticClassification"); - else print $langs->trans("Description"); + if ($family == 'create') + { + print $langs->trans("AutomaticCreation"); + } + elseif (preg_match('/classify_(.*)/', $family, $reg)) + { + print $langs->trans("AutomaticClassification"); + if ($reg[1] == 'proposal') print ' - '.$langs->trans('Proposal'); + if ($reg[1] == 'order') print ' - '.$langs->trans('Order'); + if ($reg[1] == 'supplier_proposal') print ' - '.$langs->trans('SupplierProposal'); + if ($reg[1] == 'supplier_order') print ' - '.$langs->trans('SupplierOrder'); + } + else + { + print $langs->trans("Description"); + } print ''.$langs->trans("Status").'
use_javascript_ajax)?GETPOST("showbirthday","int"):1; +$contextpage='actioncommlist'; + +$extrafields = new ExtraFields($db); +// fetch optionals attributes and labels +$extralabels = $extrafields->fetch_name_optionals_label('actioncomm'); +$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_'); // If not choice done on calendar owner, we filter on user. if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS)) { @@ -112,6 +118,27 @@ if (! $user->rights->agenda->allactions->read || $filter=='mine') // If no permi // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('agendalist')); +$arrayfields=array( + 'a.id'=>array('label'=>"Ref", 'checked'=>1), + 'owner'=>array('label'=>"Owner", 'checked'=>1), + 'a.label'=>array('label'=>"Title", 'checked'=>1), + 'c.libelle'=>array('label'=>"Type", 'checked'=>1), + 'a.datep'=>array('label'=>"DateStart", 'checked'=>1), + 'a.datep2'=>array('label'=>"DateEnd", 'checked'=>1), + 's.nom'=>array('label'=>"ThirdParty", 'checked'=>1), + 'a.fk_contact'=>array('label'=>"Contact", 'checked'=>1), + 'a.fk_element'=>array('label'=>"LinkedObject", 'checked'=>$checkedsuppliercode, 'enabled'=>(! empty($conf->global->AGENDA_SHOW_LINKED_OBJECT))), + 'a.percent'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000), + +); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + } +} /* * Actions @@ -136,6 +163,8 @@ $parameters=array('id'=>$socid); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +// Selection of new fields +include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; // Purge search criteria 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 { @@ -143,6 +172,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x', $search_title=''; $datestart=''; $dateend=''; + $search_array_options=array(); } @@ -191,6 +221,13 @@ if (GETPOST('datestartyear','int')) $param.='&datestartyear='.GETPOST('datestart if (GETPOST('dateendday','int')) $param.='&dateendday='.GETPOST('dateendday','int'); if (GETPOST('dateendmonth','int')) $param.='&dateendmonth='.GETPOST('dateendmonth','int'); if (GETPOST('dateendyear','int')) $param.='&dateendyear='.GETPOST('dateendyear','int'); +// Add $param from extra fields +foreach ($search_array_options as $key => $val) +{ + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); +} $sql = "SELECT"; if ($usergroup > 0) $sql.=" DISTINCT"; @@ -201,10 +238,14 @@ $sql.= " a.fk_contact, a.note, a.percent as percent,"; $sql.= " a.fk_element, a.elementtype,"; $sql.= " c.code as type_code, c.libelle as type_label,"; $sql.= " sp.lastname, sp.firstname"; -$sql.= " FROM ".MAIN_DB_PREFIX."c_actioncomm as c, ".MAIN_DB_PREFIX."actioncomm as a"; +// Add fields from extrafields +foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : ''); +$sql.= " FROM ".MAIN_DB_PREFIX."actioncomm as a"; +$sql.=" LEFT JOIN ".MAIN_DB_PREFIX."actioncomm_extrafields as ef ON (a.id = ef.fk_object) "; if (! $user->rights->societe->client->voir && ! $socid) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as sp ON a.fk_contact = sp.rowid"; +$sql.=" ,".MAIN_DB_PREFIX."c_actioncomm as c"; // We must filter on resource table if ($resourceid > 0) $sql.=", ".MAIN_DB_PREFIX."element_resources as r"; // We must filter on assignement table @@ -238,7 +279,7 @@ if (! empty($actioncode)) else { $sql.=" AND c.code IN ('".implode("','", explode(',', $actioncode))."')"; - } + } } } } @@ -269,6 +310,20 @@ if ($filtert > 0 || $usergroup > 0) if ($dateselect > 0) $sql.= " AND ((a.datep2 >= '".$db->idate($dateselect)."' AND a.datep <= '".$db->idate($dateselect+3600*24-1)."') OR (a.datep2 IS NULL AND a.datep > '".$db->idate($dateselect-3600)."' AND a.datep <= '".$db->idate($dateselect+3600*24-1)."'))"; if ($datestart > 0) $sql.= " AND a.datep BETWEEN '".$db->idate($datestart)."' AND '".$db->idate($datestart+3600*24-1)."'"; if ($dateend > 0) $sql.= " AND a.datep2 BETWEEN '".$db->idate($dateend)."' AND '".$db->idate($dateend+3600*24-1)."'"; +// Add where from extra fields +foreach ($search_array_options as $key => $val) +{ + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $typ=$extrafields->attribute_type[$tmpkey]; + $mode_search=0; + if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric + if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int + if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) + { + $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search); + } +} $sql.= $db->order($sortfield,$sortorder); $nbtotalofrecords = ''; @@ -376,27 +431,70 @@ if ($resql) $moreforfilter=''; + $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; + $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields + if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1); $i = 0; print '
'; print '
'."\n"; print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - if (! empty($conf->global->AGENDA_SHOW_LINKED_OBJECT)) print ''; - print ''; + if (! empty($arrayfields['a.id']['checked'])) print ''; + if (! empty($arrayfields['owner']['checked'])) print ''; + if (! empty($arrayfields['c.libelle']['checked'])) print ''; + if (! empty($arrayfields['a.label']['checked'])) print ''; + if (! empty($arrayfields['a.datep']['checked'])) { + print ''; + } + if (! empty($arrayfields['a.datep2']['checked'])) { + print ''; + } + if (! empty($arrayfields['s.nom']['checked'])) print ''; + if (! empty($arrayfields['a.fk_contact']['checked'])) print ''; + if (! empty($arrayfields['a.fk_element']['checked'])) print ''; + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $typeofextrafield=$extrafields->attribute_type[$key]; + print ''; + } + } + } + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + + + if (! empty($arrayfields['a.percent']['checked'])) { + print ''; + } // Action column print '\n"; print ''; - print_liste_field_titre("Ref",$_SERVER["PHP_SELF"],"a.id",$param,"","",$sortfield,$sortorder); - print_liste_field_titre("ActionsOwnedByShort",$_SERVER["PHP_SELF"],"",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.id']['checked'])) print_liste_field_titre($arrayfields['a.id']['label'] , $_SERVER["PHP_SELF"],"a.id",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['owner']['checked'])) print_liste_field_titre($arrayfields['owner']['label'] , $_SERVER["PHP_SELF"],"",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['c.libelle']['checked'])) print_liste_field_titre($arrayfields['c.libelle']['label'] , $_SERVER["PHP_SELF"],"c.libelle",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.label']['checked'])) print_liste_field_titre($arrayfields['a.label']['label'] , $_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder); //if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) - print_liste_field_titre("Type",$_SERVER["PHP_SELF"],"c.libelle",$param,"","",$sortfield,$sortorder); - print_liste_field_titre("Label",$_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder); - print_liste_field_titre("DateStart",$_SERVER["PHP_SELF"],"a.datep",$param,'','align="center"',$sortfield,$sortorder); - print_liste_field_titre("DateEnd",$_SERVER["PHP_SELF"],"a.datep2",$param,'','align="center"',$sortfield,$sortorder); - print_liste_field_titre("ThirdParty",$_SERVER["PHP_SELF"],"s.nom",$param,"","",$sortfield,$sortorder); - print_liste_field_titre("Contact",$_SERVER["PHP_SELF"],"a.fk_contact",$param,"","",$sortfield,$sortorder); - if (! empty($conf->global->AGENDA_SHOW_LINKED_OBJECT)) print_liste_field_titre("LinkedObject",$_SERVER["PHP_SELF"],"a.fk_element",$param,"","",$sortfield,$sortorder); - print_liste_field_titre("Status",$_SERVER["PHP_SELF"],"a.percent",$param,"",'align="center"',$sortfield,$sortorder); - print_liste_field_titre(""); + if (! empty($arrayfields['a.datep']['checked'])) print_liste_field_titre($arrayfields['a.datep']['label'] , $_SERVER["PHP_SELF"],"a.datep",$param,'','align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['a.datep2']['checked'])) print_liste_field_titre($arrayfields['a.datep2']['label'] , $_SERVER["PHP_SELF"],"a.datep2",$param,'','align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'] , $_SERVER["PHP_SELF"],"s.nom",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.fk_contact']['checked'])) print_liste_field_titre($arrayfields['a.fk_contact']['label'], $_SERVER["PHP_SELF"],"a.fk_contact",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.fk_element']['checked'])) print_liste_field_titre($arrayfields['a.fk_element']['label'], $_SERVER["PHP_SELF"],"a.fk_element",$param,"","",$sortfield,$sortorder); + + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $sortonfield = "ef.".$key; + if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],$sortonfield,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields,'param'=>$param,'sortfield'=>$sortfield,'sortorder'=>$sortorder); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['a.percent']['checked']))print_liste_field_titre("Status",$_SERVER["PHP_SELF"],"a.percent",$param,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; $contactstatic = new Contact($db); @@ -448,103 +565,138 @@ if ($resql) print ''; - // Ref - print ''; + if (! empty($arrayfields['a.id']['checked'])) { + // Ref + print ''; + } // User owner - print ''; + } + if (! empty($arrayfields['c.libelle']['checked'])) { + // Type + print ''; + } + if (! empty($arrayfields['a.label']['checked'])) { + // Label + print ''; } - else print ' '; - print ''; - // Type - print ''; + } + if (! empty($arrayfields['a.datep2']['checked'])) { + // End date + print ''; + } + if (! empty($arrayfields['s.nom']['checked'])) { + // Third party + print ''; + } + if (! empty($arrayfields['a.fk_contact']['checked'])) { + // Contact + print ''; + } + if (! empty($arrayfields['a.fk_element']['checked'])) { + // Linked object + print ''; + + } + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { - if ($actionstatic->type_picto) print img_picto('', $actionstatic->type_picto); - else { - if ($actionstatic->type_code == 'AC_RDV') print img_picto('', 'object_group').' '; - if ($actionstatic->type_code == 'AC_TEL') print img_picto('', 'object_phoning').' '; - if ($actionstatic->type_code == 'AC_FAX') print img_picto('', 'object_phoning_fax').' '; - if ($actionstatic->type_code == 'AC_EMAIL') print img_picto('', 'object_email').' '; - } + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + print 'getAlignFlag($key); + if ($align) print ' align="'.$align.'"'; + print '>'; + $tmpkey='options_'.$key; + print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); + print ''; + if (! $i) $totalarray['nbfield']++; + } + } } - $labeltype=$obj->type_code; - if (empty($conf->global->AGENDA_USE_EVENT_TYPE) && empty($arraylist[$labeltype])) $labeltype='AC_OTH'; - if (! empty($arraylist[$labeltype])) $labeltype=$arraylist[$labeltype]; - print dol_trunc($labeltype,28); - print ''; + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; - // Label - print ''; - - // Start date - print ''; - - // End date - print ''; - - // Third party - print ''; } - else print ' '; - print ''; - - // Contact - print ''; - - // Linked object - if (! empty($conf->global->AGENDA_SHOW_LINKED_OBJECT)) { - print ''; - } - - // Status/Percent - $datep=$db->jdate($obj->datep); - print ''; - print ''; print "\n"; diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 97ea07bf7e6..36a5c9a780d 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -493,7 +493,7 @@ class Proposals extends DolibarrApi $result = $this->propal->valid(DolibarrApiAccess::$user, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error); @@ -535,7 +535,7 @@ class Proposals extends DolibarrApi $result = $this->propal->cloture(DolibarrApiAccess::$user, $status, $note_private, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already closed'); + throw new RestException(304, 'Error nothing done. May be object is already closed'); } if ($result < 0) { throw new RestException(500, 'Error when closing Commercial Proposal: '.$this->propal->error); diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 086379a3989..e5228185657 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -396,16 +396,16 @@ class Orders extends DolibarrApi * @return int */ function put($id, $request_data = NULL) { - if(! DolibarrApiAccess::$user->rights->commande->creer) { + if (! DolibarrApiAccess::$user->rights->commande->creer) { throw new RestException(401); } $result = $this->commande->fetch($id); - if( ! $result ) { + if (! $result) { throw new RestException(404, 'Order not found'); } - if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) { + if (! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach($request_data as $field => $value) { @@ -414,12 +414,12 @@ class Orders extends DolibarrApi } // Update availability - if( isset($this->commande->availability_id) && !empty($this->commande->availability_id) ) { - if($this->commande->availability($this->commande->availability_id) < 0) + if (!empty($this->commande->availability_id)) { + if ($this->commande->availability($this->commande->availability_id) < 0) throw new RestException(400, 'Error while updating availability'); } - if($this->commande->update($id, DolibarrApiAccess::$user, 1, '', '', 'update')) + if ($this->commande->update($id, DolibarrApiAccess::$user, 1, '', '', 'update')) return $this->get($id); return false; @@ -493,10 +493,10 @@ class Orders extends DolibarrApi $result = $this->commande->valid(DolibarrApiAccess::$user, $idwarehouse, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { - throw new RestException(304, 'Error when validating Order: '.$this->commande->error); + throw new RestException(500, 'Error when validating Order: '.$this->commande->error); } $result = $this->commande->fetch($id); if( ! $result ) { @@ -537,7 +537,7 @@ class Orders extends DolibarrApi $result = $this->commande->cloture(DolibarrApiAccess::$user, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already closed'); + throw new RestException(304, 'Error nothing done. May be object is already closed'); } if ($result < 0) { throw new RestException(500, 'Error when closing Order: '.$this->commande->error); @@ -555,12 +555,13 @@ class Orders extends DolibarrApi * Set an order to draft * * @param int $id Order ID + * @param int $idwarehouse Warehouse ID to use for stock change (Used only if option STOCK_CALCULATE_ON_VALIDATE_ORDER is on) * * @url POST {id}/settodraft * * @return array */ - function settodraft($id) + function settodraft($id, $idwarehouse=-1) { if(! DolibarrApiAccess::$user->rights->commande->creer) { throw new RestException(401); @@ -574,7 +575,7 @@ class Orders extends DolibarrApi throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - $result = $this->commande->set_draft(DolibarrApiAccess::$user); + $result = $this->commande->set_draft(DolibarrApiAccess::$user, $idwarehouse); if ($result == 0) { throw new RestException(304, 'Nothing done. May be object is already closed'); } @@ -582,7 +583,7 @@ class Orders extends DolibarrApi throw new RestException(500, 'Error when closing Order: '.$this->commande->error); } - $result = $this->commande->fetch($id); + $result = $this->commande->fetch($id); if( ! $result ) { throw new RestException(404, 'Order not found'); } diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 04ba162cb9e..26674818027 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -416,7 +416,7 @@ class Commande extends CommonOrder * Set draft status * * @param User $user Object user that modify - * @param int $idwarehouse Id warehouse to use for stock change. + * @param int $idwarehouse Warehouse ID to use for stock change (Used only if option STOCK_CALCULATE_ON_VALIDATE_ORDER is on) * @return int <0 if KO, >0 if OK */ function set_draft($user, $idwarehouse=-1) diff --git a/htdocs/contrat/class/api_contracts.class.php b/htdocs/contrat/class/api_contracts.class.php index 0bc02458869..45595712b68 100644 --- a/htdocs/contrat/class/api_contracts.class.php +++ b/htdocs/contrat/class/api_contracts.class.php @@ -479,7 +479,7 @@ class Contracts extends DolibarrApi $result = $this->contract->validate(DolibarrApiAccess::$user, '', $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when validating Contract: '.$this->contract->error); @@ -525,7 +525,7 @@ class Contracts extends DolibarrApi $result = $this->contract->closeAll(DolibarrApiAccess::$user, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already close'); + throw new RestException(304, 'Error nothing done. May be object is already close'); } if ($result < 0) { throw new RestException(500, 'Error when closing Contract: '.$this->contract->error); diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php index 7db6ec3331a..3fcf4a15bdd 100644 --- a/htdocs/core/class/html.formactions.class.php +++ b/htdocs/core/class/html.formactions.class.php @@ -205,12 +205,12 @@ class FormActions print '
'; print '
'; - print $form->select_date($datestart, 'datestart', 0, 0, 1, '', 1, 0, 1); - print ''; - print $form->select_date($dateend, 'dateend', 0, 0, 1, '', 1, 0, 1); - print ''; - print $formactions->form_select_status_action('formaction',$status,1,'status',1,2); - print ''; + print $form->select_date($datestart, 'datestart', 0, 0, 1, '', 1, 0, 1); + print ''; + print $form->select_date($dateend, 'dateend', 0, 0, 1, '', 1, 0, 1); + print ''; + if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select')) && empty($extrafields->attribute_computed[$key])) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $searchclass=''; + if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; + if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; + print ''; + } + else + { + // for the type as 'checkbox', 'chkbxlst', 'sellist' we should use code instead of id (example: I declare a 'chkbxlst' to have a link with dictionnairy, I have to extend it with the 'code' instead 'rowid') + echo $extrafields->showInputField($key, $search_array_options['search_options_'.$key], '', '', 'search_'); + } + print ''; + print $formactions->form_select_status_action('formaction',$status,1,'status',1,2); + print ''; $searchpicto=$form->showFilterButtons(); @@ -405,18 +503,37 @@ if ($resql) print "
'; - print $actionstatic->getNomUrl(1,-1); - print ''; + print $actionstatic->getNomUrl(1,-1); + print ''; - if ($obj->fk_user_action > 0) + if (! empty($arrayfields['owner']['checked'])) { - $userstatic->fetch($obj->fk_user_action); - print $userstatic->getNomUrl(-1); + print ''; + if ($obj->fk_user_action > 0) + { + $userstatic->fetch($obj->fk_user_action); + print $userstatic->getNomUrl(-1); + } + else print ' '; + print ''; + if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) + { + if ($actionstatic->type_picto) print img_picto('', $actionstatic->type_picto); + else { + if ($actionstatic->type_code == 'AC_RDV') print img_picto('', 'object_group').' '; + if ($actionstatic->type_code == 'AC_TEL') print img_picto('', 'object_phoning').' '; + if ($actionstatic->type_code == 'AC_FAX') print img_picto('', 'object_phoning_fax').' '; + if ($actionstatic->type_code == 'AC_EMAIL') print img_picto('', 'object_email').' '; + } + } + $labeltype=$obj->type_code; + if (empty($conf->global->AGENDA_USE_EVENT_TYPE) && empty($arraylist[$labeltype])) $labeltype='AC_OTH'; + if (! empty($arraylist[$labeltype])) $labeltype=$arraylist[$labeltype]; + print dol_trunc($labeltype,28); + print ''; + print $actionstatic->label; + print ''; - if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) + if (! empty($arrayfields['a.datep']['checked'])) { + // Start date + print ''; + print dol_print_date($db->jdate($obj->dp),"dayhour"); + $late=0; + if ($obj->percent == 0 && $obj->dp && $db->jdate($obj->dp) < ($now - $delay_warning)) $late=1; + if ($obj->percent == 0 && ! $obj->dp && $obj->dp2 && $db->jdate($obj->dp) < ($now - $delay_warning)) $late=1; + if ($obj->percent > 0 && $obj->percent < 100 && $obj->dp2 && $db->jdate($obj->dp2) < ($now - $delay_warning)) $late=1; + if ($obj->percent > 0 && $obj->percent < 100 && ! $obj->dp2 && $obj->dp && $db->jdate($obj->dp) < ($now - $delay_warning)) $late=1; + if ($late) print img_warning($langs->trans("Late")).' '; + print ''; + print dol_print_date($db->jdate($obj->dp2),"dayhour"); + print ''; + if ($obj->socid) + { + $societestatic->id=$obj->socid; + $societestatic->client=$obj->client; + $societestatic->name=$obj->societe; + print $societestatic->getNomUrl(1,'',28); + } + else print ' '; + print ''; + if ($obj->fk_contact > 0) + { + $contactstatic->lastname=$obj->lastname; + $contactstatic->firstname=$obj->firstname; + $contactstatic->id=$obj->fk_contact; + print $contactstatic->getNomUrl(1,'',28); + } + else + { + print " "; + } + print ''; + if ($obj->fk_element > 0 && ! empty($obj->elementtype)) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + print dolGetElementUrl($obj->fk_element,$obj->elementtype,1); + } else { + print " "; + } + print ''; - print $actionstatic->label; - print ''; - print dol_print_date($db->jdate($obj->dp),"dayhour"); - $late=0; - if ($obj->percent == 0 && $obj->dp && $db->jdate($obj->dp) < ($now - $delay_warning)) $late=1; - if ($obj->percent == 0 && ! $obj->dp && $obj->dp2 && $db->jdate($obj->dp) < ($now - $delay_warning)) $late=1; - if ($obj->percent > 0 && $obj->percent < 100 && $obj->dp2 && $db->jdate($obj->dp2) < ($now - $delay_warning)) $late=1; - if ($obj->percent > 0 && $obj->percent < 100 && ! $obj->dp2 && $obj->dp && $db->jdate($obj->dp) < ($now - $delay_warning)) $late=1; - if ($late) print img_warning($langs->trans("Late")).' '; - print ''; - print dol_print_date($db->jdate($obj->dp2),"dayhour"); - print ''; - if ($obj->socid) - { - $societestatic->id=$obj->socid; - $societestatic->client=$obj->client; - $societestatic->name=$obj->societe; - print $societestatic->getNomUrl(1,'',28); + if (! empty($arrayfields['a.percent']['checked'])) { + // Status/Percent + $datep=$db->jdate($obj->datep); + print ''.$actionstatic->LibStatut($obj->percent,3,0,$datep).''; - if ($obj->fk_contact > 0) - { - $contactstatic->lastname=$obj->lastname; - $contactstatic->firstname=$obj->firstname; - $contactstatic->id=$obj->fk_contact; - print $contactstatic->getNomUrl(1,'',28); - } - else - { - print " "; - } - print ''; - if ($obj->fk_element > 0 && ! empty($obj->elementtype)) { - include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - print dolGetElementUrl($obj->fk_element,$obj->elementtype,1); - } else { - print " "; - } - print ''.$actionstatic->LibStatut($obj->percent,3,0,$datep).'
'; print ''; - print getTitleFieldOfList('Ref', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); - print getTitleFieldOfList('By', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); - print getTitleFieldOfList('Type', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); - print getTitleFieldOfList('Action', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); - print getTitleFieldOfList('Date', 0, $_SERVER["PHP_SELF"], 'a.datep', $page, $param, 'align="center"', $sortfield, $sortorder, '', 1); - print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', $page, $param, 'align="right"', $sortfield, $sortorder, '', 1); + print getTitleFieldOfList('Ref', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); + print getTitleFieldOfList('By', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); + print getTitleFieldOfList('Type', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); + print getTitleFieldOfList('Title', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); + print getTitleFieldOfList('Date', 0, $_SERVER["PHP_SELF"], 'a.datep', $page, $param, 'align="center"', $sortfield, $sortorder, '', 1); + print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', $page, $param, 'align="right"', $sortfield, $sortorder, '', 1); print ''; print "\n"; diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php index c25e1ae9ad7..3c9880ef4ec 100644 --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php @@ -167,7 +167,58 @@ class InterfaceWorkflowManager extends DolibarrTriggers } return $ret; } + } + // classify billed order & billed propososal + if ($action == 'BILL_SUPPLIER_VALIDATE') + { + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); + + // First classify billed the order to allow the proposal classify process + if (! empty($conf->fournisseur->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER)) + { + $object->fetchObjectLinked('','order_supplier',$object->id,$object->element); + if (! empty($object->linkedObjects)) + { + $totalonlinkedelements=0; + foreach($object->linkedObjects['order_supplier'] as $element) + { + if ($element->statut == CommandeFournisseur::STATUS_ACCEPTED || $element->statut == CommandeFournisseur::STATUS_ORDERSENT || $element->statut == CommandeFournisseur::STATUS_RECEIVED_PARTIALLY || $element->statut == CommandeFournisseur::STATUS_RECEIVED_COMPLETELY) $totalonlinkedelements += $element->total_ht; + } + dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) + { + foreach($object->linkedObjects['order_supplier'] as $element) + { + $ret=$element->classifyBilled($user); + } + } + } + return $ret; + } + + // Second classify billed the proposal. + if (! empty($conf->supplier_proposal->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_SUPPLIER_PROPOSAL)) + { + $object->fetchObjectLinked('','supplier_proposal',$object->id,$object->element); + if (! empty($object->linkedObjects)) + { + $totalonlinkedelements=0; + foreach($object->linkedObjects['supplier_proposal'] as $element) + { + if ($element->statut == SupplierProposal::STATUS_SIGNED || $element->statut == SupplierProposal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht; + } + dol_syslog( "Amount of linked supplier proposals = ".$totalonlinkedelements.", of supplier invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) + { + foreach($object->linkedObjects['supplier_proposal'] as $element) + { + $ret=$element->classifyBilled($user); + } + } + } + return $ret; + } } // Invoice classify billed order diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 1d7efb236a2..e60fdccd4ad 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -312,7 +312,7 @@ class SupplierInvoices extends DolibarrApi $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error); diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index 22cd4eb191c..74b5bbe43b3 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -316,7 +316,7 @@ class SupplierOrders extends DolibarrApi $result = $this->order->valid(DolibarrApiAccess::$user, $idwarehouse, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when validating Order: '.$this->order->error); 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 c185d3c9afd..396ab94938f 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 @@ -392,8 +392,23 @@ ALTER TABLE llx_extrafields MODIFY COLUMN langs varchar(64); ALTER TABLE llx_holiday_config MODIFY COLUMN name varchar(128); ALTER TABLE llx_holiday_config ADD UNIQUE INDEX idx_holiday_config (name); +ALTER TABLE llx_societe MODIFY COLUMN ref_ext varchar(255); +ALTER TABLE llx_socpeople MODIFY COLUMN ref_ext varchar(255); +ALTER TABLE llx_actioncomm MODIFY COLUMN ref_ext varchar(255); +ALTER TABLE llx_expedition MODIFY COLUMN ref_ext varchar(255); +ALTER TABLE llx_livraison MODIFY COLUMN ref_ext varchar(255); +ALTER TABLE llx_contrat MODIFY COLUMN ref_ext varchar(255); + ALTER TABLE llx_actioncomm MODIFY COLUMN label varchar(255) NOT NULL; +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_user_action (fk_user_action); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_project (fk_project); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_datep (datep); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_datep2 (datep2); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_recurid (recurid); + +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_ref_ext (ref_ext); + ALTER TABLE llx_payment_various ADD COLUMN fk_projet integer DEFAULT NULL after accountancy_code; UPDATE llx_const set name = 'ONLINE_PAYMENT_MESSAGE_OK' where name = 'PAYPAL_MESSAGE_OK'; diff --git a/htdocs/install/mysql/tables/llx_actioncomm.key.sql b/htdocs/install/mysql/tables/llx_actioncomm.key.sql index 64162dbbc73..257eb22a240 100644 --- a/htdocs/install/mysql/tables/llx_actioncomm.key.sql +++ b/htdocs/install/mysql/tables/llx_actioncomm.key.sql @@ -1,5 +1,5 @@ -- ============================================================================ --- Copyright (C) 2005-2013 Laurent Destailleur +-- Copyright (C) 2005-2017 Laurent Destailleur -- Copyright (C) 2011 Regis Houssin -- -- This program is free software; you can redistribute it and/or modify @@ -22,3 +22,10 @@ ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_soc (fk_soc); ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_contact (fk_contact); ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_code (code); ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_element (fk_element); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_user_action (fk_user_action); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_project (fk_project); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_datep (datep); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_datep2 (datep2); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_recurid (recurid); + +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_ref_ext (ref_ext); diff --git a/htdocs/install/mysql/tables/llx_actioncomm.sql b/htdocs/install/mysql/tables/llx_actioncomm.sql index fdde835ad51..8203b027567 100644 --- a/htdocs/install/mysql/tables/llx_actioncomm.sql +++ b/htdocs/install/mysql/tables/llx_actioncomm.sql @@ -1,6 +1,6 @@ -- ======================================================================== -- Copyright (C) 2001-2003 Rodolphe Quiedeville --- Copyright (C) 2005-2010 Laurent Destailleur +-- Copyright (C) 2005-2017 Laurent Destailleur -- Copyright (C) 2011 Regis Houssin -- -- This program is free software; you can redistribute it and/or modify @@ -23,8 +23,8 @@ create table llx_actioncomm ( id integer AUTO_INCREMENT PRIMARY KEY, - ref_ext varchar(128), - entity integer DEFAULT 1 NOT NULL, -- multi company id + ref_ext varchar(255), -- reference into an external system (not used by dolibarr). Example: An id coming from google calendar has length between 5 and 1024 chars. An event id must follow rule: chars used in base32hex encoding (i.e. lowercase letters a-v and digits 0-9, see section 3.1.2 in RFC2938) + entity integer DEFAULT 1 NOT NULL, -- multi company id datep datetime, -- date start datep2 datetime, -- date end @@ -64,7 +64,7 @@ create table llx_actioncomm email_tobcc varchar(255), -- when event was an email, we store here the email_tobcc errors_to varchar(255), -- when event was an email, we store here the erros_to - recurid varchar(128), -- used to store event id to link each other all the repeating event record + recurid varchar(128), -- used to store event id to link each other all the repeating event record. It can be the "iCalUID" as in RFC5545 (an id similar for all the same serie) recurrule varchar(128), -- contains string with ical format recurring rule like 'FREQ=MONTHLY;INTERVAL=2;BYMONTHDAY=19' or 'FREQ=WEEKLY;BYDAY=MO' recurdateend datetime, -- no more recurring event after this date diff --git a/htdocs/install/mysql/tables/llx_commande_fournisseur.sql b/htdocs/install/mysql/tables/llx_commande_fournisseur.sql index bb060afca67..930a675c5e1 100644 --- a/htdocs/install/mysql/tables/llx_commande_fournisseur.sql +++ b/htdocs/install/mysql/tables/llx_commande_fournisseur.sql @@ -26,7 +26,7 @@ create table llx_commande_fournisseur ref varchar(255) NOT NULL, -- order number entity integer DEFAULT 1 NOT NULL, -- multi company id - ref_ext varchar(64), -- reference into an external system (not used by dolibarr) + ref_ext varchar(255), -- reference into an external system (not used by dolibarr) ref_supplier varchar(255), fk_soc integer NOT NULL, diff --git a/htdocs/install/mysql/tables/llx_contrat.sql b/htdocs/install/mysql/tables/llx_contrat.sql index 606c0e78f8f..ac6f56631ec 100644 --- a/htdocs/install/mysql/tables/llx_contrat.sql +++ b/htdocs/install/mysql/tables/llx_contrat.sql @@ -21,10 +21,10 @@ create table llx_contrat ( rowid integer AUTO_INCREMENT PRIMARY KEY, - ref varchar(50), -- contrat reference - ref_customer varchar(50), -- customer contract ref - ref_supplier varchar(50), -- supplier contract ref - ref_ext varchar(50), -- external contract ref + ref varchar(255), -- contrat reference + ref_customer varchar(255), -- customer contract ref + ref_supplier varchar(255), -- supplier contract ref + ref_ext varchar(255), -- external contract ref entity integer DEFAULT 1 NOT NULL, -- multi company id tms timestamp, datec datetime, -- creation date diff --git a/htdocs/install/mysql/tables/llx_expedition.sql b/htdocs/install/mysql/tables/llx_expedition.sql index cdf3f253892..e252783ac94 100644 --- a/htdocs/install/mysql/tables/llx_expedition.sql +++ b/htdocs/install/mysql/tables/llx_expedition.sql @@ -28,9 +28,9 @@ create table llx_expedition fk_soc integer NOT NULL, fk_projet integer DEFAULT NULL, - ref_ext varchar(30), -- reference into an external system (not used by dolibarr) - ref_int varchar(30), -- reference into an internal system (used by dolibarr to store extern id like paypal info) - ref_customer varchar(30), -- customer number + ref_ext varchar(255), -- reference into an external system (not used by dolibarr) + ref_int varchar(255), -- reference into an internal system (used by dolibarr to store extern id like paypal info) + ref_customer varchar(255), -- customer number date_creation datetime, -- date de creation fk_user_author integer, -- author of creation diff --git a/htdocs/install/mysql/tables/llx_livraison.sql b/htdocs/install/mysql/tables/llx_livraison.sql index d5848eb708e..32e9de8b2a7 100644 --- a/htdocs/install/mysql/tables/llx_livraison.sql +++ b/htdocs/install/mysql/tables/llx_livraison.sql @@ -25,9 +25,9 @@ create table llx_livraison entity integer DEFAULT 1 NOT NULL, -- multi company id fk_soc integer NOT NULL, - ref_ext varchar(30), -- reference into an external system (not used by dolibarr) - ref_int varchar(30), -- reference into an internal system (used by dolibarr to store extern id like paypal info) - ref_customer varchar(30), -- customer number + ref_ext varchar(255), -- reference into an external system (not used by dolibarr) + ref_int varchar(255), -- reference into an internal system (used by dolibarr to store extern id like paypal info) + ref_customer varchar(255), -- customer number date_creation datetime, -- date de creation fk_user_author integer, -- createur du bon de livraison diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql index a6a1e51a22b..4d74e411260 100644 --- a/htdocs/install/mysql/tables/llx_societe.sql +++ b/htdocs/install/mysql/tables/llx_societe.sql @@ -25,11 +25,11 @@ create table llx_societe ( rowid integer AUTO_INCREMENT PRIMARY KEY, nom varchar(128), -- company reference name (should be same length than adherent.societe) - name_alias varchar(128) NULL, - entity integer DEFAULT 1 NOT NULL, -- multi company id + name_alias varchar(128) NULL, + entity integer DEFAULT 1 NOT NULL, -- multi company id - ref_ext varchar(128), -- reference into an external system (not used by dolibarr) - ref_int varchar(60), -- reference into an internal system (deprecated) + ref_ext varchar(255), -- reference into an external system (not used by dolibarr) + ref_int varchar(255), -- reference into an internal system (deprecated) statut tinyint DEFAULT 0, -- statut parent integer, diff --git a/htdocs/install/mysql/tables/llx_socpeople.sql b/htdocs/install/mysql/tables/llx_socpeople.sql index b9aad05b956..51848b33b48 100644 --- a/htdocs/install/mysql/tables/llx_socpeople.sql +++ b/htdocs/install/mysql/tables/llx_socpeople.sql @@ -25,7 +25,7 @@ create table llx_socpeople tms timestamp, fk_soc integer, -- lien vers la societe entity integer DEFAULT 1 NOT NULL, -- multi company id - ref_ext varchar(128), -- reference into an external system (not used by dolibarr) + ref_ext varchar(255), -- reference into an external system (not used by dolibarr) civility varchar(6), lastname varchar(50), firstname varchar(50), diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 94a7651af49..294de90d900 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -882,7 +882,7 @@ DictionaryTypeContact=Contact/Address types DictionaryEcotaxe=Ecotax (WEEE) DictionaryPaperFormat=Paper formats DictionaryFormatCards=Cards formats -DictionaryFees=Types of fees +DictionaryFees=Expense report - Types of expense report lines DictionarySendingMethods=Shipping methods DictionaryStaff=Staff DictionaryAvailability=Delivery delay @@ -896,8 +896,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 +DictionaryExpenseTaxCat=Expense report - Transportation categories +DictionaryExpenseTaxRange=Expense report - Range by transportation category SetupSaved=Setup saved SetupNotSaved=Setup not saved BackToModuleList=Back to modules list diff --git a/htdocs/langs/en_US/workflow.lang b/htdocs/langs/en_US/workflow.lang index a477790b01b..eba04cc44d1 100644 --- a/htdocs/langs/en_US/workflow.lang +++ b/htdocs/langs/en_US/workflow.lang @@ -7,11 +7,14 @@ descWORKFLOW_PROPAL_AUTOCREATE_ORDER=Automatically create a customer order after descWORKFLOW_PROPAL_AUTOCREATE_INVOICE=Automatically create a customer invoice after a commercial proposal is signed (new invoice will have same amount than proposal) descWORKFLOW_CONTRACT_AUTOCREATE_INVOICE=Automatically create a customer invoice after a contract is validated descWORKFLOW_ORDER_AUTOCREATE_INVOICE=Automatically create a customer invoice after a customer order is closed (new invoice will have same amount than order) -# Autoclassify +# Autoclassify customer proposal or order descWORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL=Classify linked source proposal(s) to billed when customer order is set to billed (and if amount of the order is same than total amount of signed linked proposals) descWORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL=Classify linked source proposal(s) to billed when customer invoice is validated (and if amount of the invoice is same than total amount of signed linked proposals) descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER=Classify linked source customer order(s) to billed when customer invoice is validated (and if amount of the invoice is same than total amount of linked orders) descWORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER=Classify linked source customer order(s) to billed when customer invoice is set to paid (and if amount of the invoice is same than total amount of linked orders) -descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING=Classify linked source order to shipped when a shipment is validated (and if quantity shipped by all shipments is the same as in the order to update) +descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING=Classify linked source customer order to shipped when a shipment is validated (and if quantity shipped by all shipments is the same as in the order to update) +# Autoclassify supplier order +descWORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL=Classify linked source supplier proposal(s) to billed when supplier invoice is validated (and if amount of the invoice is same than total amount of linked proposals) +descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER=Classify linked source supplier order(s) to billed when supplier invoice is validated (and if amount of the invoice is same than total amount of linked orders) AutomaticCreation=Automatic creation AutomaticClassification=Automatic classification \ No newline at end of file diff --git a/htdocs/projet/class/api_projects.class.php b/htdocs/projet/class/api_projects.class.php index 6fcdfde7ca2..f6364eb0544 100644 --- a/htdocs/projet/class/api_projects.class.php +++ b/htdocs/projet/class/api_projects.class.php @@ -513,7 +513,7 @@ class Projects extends DolibarrApi $result = $this->project->setValid(DolibarrApiAccess::$user, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when validating Project: '.$this->project->error); diff --git a/htdocs/projet/class/api_tasks.class.php b/htdocs/projet/class/api_tasks.class.php index f00a536df87..fc006706d81 100644 --- a/htdocs/projet/class/api_tasks.class.php +++ b/htdocs/projet/class/api_tasks.class.php @@ -529,7 +529,7 @@ class Tasks extends DolibarrApi $result = $this->task->addTimeSpent(DolibarrApiAccess::$user, 0); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when adding time: '.$this->task->error); diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index c57f19d676b..c24caf2f22b 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -3009,6 +3009,9 @@ span.dashboardlineko { .boxtablenobottom { border-bottom-width: 0 !important; } +.boxtable .fichehalfright, .boxtable .fichehalfleft { + min-width: 300px; +} .tdboxstats { text-align: center; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 066cf1e7d72..dd568d9ba60 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3103,6 +3103,9 @@ span.dashboardlineko { .boxtablenobottom { border-bottom-width: 0 !important; } +.boxtable .fichehalfright, .boxtable .fichehalfleft { + min-width: 300px; +} .tdboxstats { text-align: center; }