From 085efd0efa4c1dc9bc0ce923064e8ff810a5875d Mon Sep 17 00:00:00 2001 From: sparkyx Date: Tue, 10 Nov 2020 19:48:20 +0100 Subject: [PATCH] =?UTF-8?q?task=20#0001697:=20Extension=20usage=20des=20?= =?UTF-8?q?=C3=A9tiquettes=20,=20tag=20on=20operation=20+=20export=20CSV?= =?UTF-8?q?=20+=20filter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- html/ajax_misc.php | 10 +- html/js/acc_ledger.js | 26 ++- html/js/scripts.js | 142 ++++++++++++++- html/recherche.php | 12 +- include/ajax/ajax_ledger.php | 1 + include/ajax/ajax_operation_tag.php | 166 +++++++++++++++++ include/ajax/ajax_search_add_tag.php | 8 +- include/ajax/ajax_search_clear_tag.php | 4 +- include/ajax/ajax_search_display_tag.php | 23 ++- include/ajax/ajax_search_filter.php | 42 ++++- include/ajax/ajax_tag_list.php | 10 +- include/ajax/ajax_tag_select_search.php | 4 +- include/class/acc_ledger_search.class.php | 27 ++- include/class/follow_up.class.php | 1 + include/class/tag.class.php | 62 ++----- include/class/tag_action.class.php | 94 ++++++++++ include/class/tag_operation.class.php | 199 +++++++++++++++++++++ include/constant.php | 2 +- include/database/user_filter_sql.class.php | 5 + include/history_operation.inc.php | 13 +- include/sql/patch/upgrade150.sql | 15 ++ include/template/action_other_action.php | 8 +- include/template/action_search.php | 6 +- include/template/detail-action.php | 2 +- include/template/ledger_detail_bottom.php | 19 +- include/template/ledger_search.php | 37 +++- include/template/tag_select.php | 19 +- 27 files changed, 857 insertions(+), 100 deletions(-) create mode 100644 include/ajax/ajax_operation_tag.php create mode 100644 include/class/tag_action.class.php create mode 100644 include/class/tag_operation.class.php create mode 100644 include/sql/patch/upgrade150.sql diff --git a/html/ajax_misc.php b/html/ajax_misc.php index 2db616d12..a1dfd697c 100644 --- a/html/ajax_misc.php +++ b/html/ajax_misc.php @@ -240,6 +240,8 @@ $path = array( "save_filter"=>"ajax_search_filter", // Load a search filter "load_filter"=>"ajax_search_filter", + // display tag for filter + 'display_filter_tag'=>'ajax_search_filter', // search operation to reconcile 'search_op'=>'ajax_search_operation', // delete operation @@ -269,7 +271,13 @@ $path = array( // set the group for a tag 'tag_set_group'=>"ajax_tag_set_group", // Document_state - "document_state"=>"ajax_document_state" + "document_state"=>"ajax_document_state", + // Operations tag add + 'operation_tag_add'=>"ajax_operation_tag", + // Operations tag remove + 'operation_tag_remove'=>"ajax_operation_tag", + // Operations tag select + 'operation_tag_select'=>"ajax_operation_tag" ) ; if (array_key_exists($op, $path)) { diff --git a/html/js/acc_ledger.js b/html/js/acc_ledger.js index 33e959fc2..03116b7b5 100644 --- a/html/js/acc_ledger.js +++ b/html/js/acc_ledger.js @@ -1297,8 +1297,8 @@ function manage_search_filter(p_obj) { onSuccess:function(req) { remove_waiting_box(); var x=posX; - var y=posY-20; - create_div({'id':'boxfilter'+p_obj.div,'cssclass':'inner_box','html':req.responseText,'style':'top:'+y+'px;left:'+x+'px;position:absolute;width:400px'}); + var y=calcy(200) + create_div({'id':'boxfilter'+p_obj.div,'cssclass':'inner_box','html':req.responseText,'style':'top:'+y+'px;left:'+x+'px;position:absolute;width:400px',drag:1}); $('boxfilter'+p_obj.div).show(); } }); @@ -1315,8 +1315,9 @@ function manage_search_filter(p_obj) { function save_filter(p_div,p_dossier) { var elt=['ledger_type','nb_jrn','date_start','date_end', 'date_paid_start','date_paid_end','desc','amount_min','amount_max','qcode','accounting', - 'operation_filter']; + 'operation_filter','tag_option']; var eltValue={}; + var i =0; eltValue['gDossier']=p_dossier; eltValue['op']="save_filter"; eltValue['div']=p_div; @@ -1338,6 +1339,12 @@ function save_filter(p_div,p_dossier) { eltValue['r_jrn'+i]=$(idx).value } + } + //ledger's tags + var aTag=Array.from(document.getElementsByName(p_div+"tag[]")); + eltValue["tag[]"]=[]; + for (i=0 ; i < aTag.length;i++) { + eltValue["tag[]"][i]=aTag[i].value; } new Ajax.Request('ajax_misc.php', { method:"POST", @@ -1349,7 +1356,7 @@ function save_filter(p_div,p_dossier) { /*Add the new list to the selection */ var new_item=document.createElement('li'); new_item.innerHTML=answer.filter_name; - new_item.setAttribute("id","li"+p_div+"_"+answer.filter_id); + new_item.setAttribute("id","manageli"+p_div+"_"+answer.filter_id); $('manage'+p_div).appendChild(new_item); $(p_div+"filter_new").value=""; } else { @@ -1377,7 +1384,7 @@ function load_filter(p_div,p_dossier,p_filter_id) { var answer=req.responseJSON; console.log(answer); var elt=['ledger_type','date_start','date_end','date_paid_start','date_paid_end', - 'desc','amount_min','amount_max','qcode','accounting','operation_filter']; + 'desc','amount_min','amount_max','qcode','accounting','operation_filter','tag_option']; for (var i=0;iget("r_jrn","array"); @@ -135,6 +135,16 @@ if ( isset ($_GET['viewsearch'])) } } } + if (isset($_GET['tag'])) { + $http=new HttpInput(); + $aTag=$http->get("tag","array"); + foreach ($aTag as $k=>$v) { + // Protect : check that $k and $v are numeric + if (isNumber($k)&&isNumber($v)) { + $r.=HtmlInput::hidden('tag[]',$v); + } + } + } echo '
'; echo $r; echo HtmlInput::hidden('act','CSV:histo'); diff --git a/include/ajax/ajax_ledger.php b/include/ajax/ajax_ledger.php index 316a5a662..6eb4bcb09 100644 --- a/include/ajax/ajax_ledger.php +++ b/include/ajax/ajax_ledger.php @@ -42,6 +42,7 @@ require_once NOALYSS_INCLUDE.'/lib/idate.class.php'; require_once NOALYSS_INCLUDE.'/class/noalyss_parameter_folder.class.php'; require_once NOALYSS_INCLUDE.'/lib/iconcerned.class.php'; require_once NOALYSS_INCLUDE.'/lib/http_input.class.php'; +require_once NOALYSS_INCLUDE.'/class/tag_operation.class.php'; $http=new HttpInput(); /** diff --git a/include/ajax/ajax_operation_tag.php b/include/ajax/ajax_operation_tag.php new file mode 100644 index 000000000..7c0a0d21f --- /dev/null +++ b/include/ajax/ajax_operation_tag.php @@ -0,0 +1,166 @@ + + +if (!defined('ALLOWED')) + die('Appel direct ne sont pas permis'); +require_once NOALYSS_INCLUDE.'/class/tag.class.php'; +require_once NOALYSS_INCLUDE.'/class/tag_operation.class.php'; + +/** + * @file + * @brief manage the ajax calls for adding , deleting tag on operations + */ +try +{ + $op=$http->request('op'); + $jrn_id=$http->request('jrn_id', "number"); +} +catch (Exception $ex) +{ + echo $ex->getMessage(); +} + +// Security : check ledger accessible +global $g_user; +$ledger=$cn->get_value("select jr_def_id from jrn where jr_id=$1", [$jrn_id]); + +if ($g_user->get_ledger_access($ledger)!='W') +{ + record_log("AJT0001"); + return; +} +switch ($op) +{ + case 'operation_tag_select': + //-------------------------------------------------------------------------------------------------- + // Display a list of available tag + //-------------------------------------------------------------------------------------------------- + ob_start(); + $tag_operation=new Tag_Operation($cn); + echo $tag_operation->select($ctl); + + //------------------- Propose to add a tag + + $js=sprintf("onclick=\"show_tag('%s','%s','%s','j')\"", Dossier::id(), '', '-1'); + if ($g_user->check_action(TAGADD)==1) + { + echo HtmlInput::button("tag_add", _("Ajout d'un tag"), $js); + } + echo HtmlInput::button_close("tag_div"); + + $response=ob_get_clean(); + if (headers_sent()&&DEBUG) + { + echo $response; + } + else + { + header('Content-type: text/xml; charset=UTF-8'); + } + $html=escape_xml($response); + echo << + + + $html + +EOF; + return; + case 'operation_tag_add': + //-------------------------------------------------------------------------------------------------- + // Display all the tags attached to this operation + //-------------------------------------------------------------------------------------------------- + $tag_operation=new Tag_Operation($cn); + $tag_operation->set_jrn_id($jrn_id); + $pref=$http->request("ctl"); + + if ($http->request("isgroup")=='t') + { + $tag_operation->tag_add($http->request('t_id', "number")); + } + else + { + // Add all the tag from the group + $aTag=$cn->get_array("select t_id,t_tag ,t_color from jnt_tag_group_tag jtgt join tags on (tag_id=t_id) where tag_group_id=$1 order by 2 ", + [$http->request("t_id", "number")]); + $nb_atag=count($aTag); + if ($nb_atag>0) + { + for ($i=0; $i<$nb_atag; $i++) + { + $tag_operation->tag_add($aTag[$i]['t_id']); + } + } + } + + ob_start(); + + $tag_operation->tag_cell($ctl); + + $response=ob_get_clean(); + if (headers_sent()&&DEBUG) + { + echo $response; + } + else + { + header('Content-type: text/xml; charset=UTF-8'); + } + $html=escape_xml($response); + echo << + + +$html + +EOF; + return; + break; + case 'operation_tag_remove': + $tag_operation=new Tag_Operation($cn); + $tag_operation->set_jrn_id($jrn_id); + $pref=$http->request("ctl"); + $tag_operation->tag_remove($http->request("t_id", "number")); + + ob_start(); + + $tag_operation->tag_cell($pref); + + $response=ob_get_clean(); + if (headers_sent()&&DEBUG) + { + echo $response; + } + else + { + header('Content-type: text/xml; charset=UTF-8'); + } + $html=escape_xml($response); + echo << + + +$html + +EOF; + return; + break; +} \ No newline at end of file diff --git a/include/ajax/ajax_search_add_tag.php b/include/ajax/ajax_search_add_tag.php index d1e3b853c..b3697ae4e 100644 --- a/include/ajax/ajax_search_add_tag.php +++ b/include/ajax/ajax_search_add_tag.php @@ -25,18 +25,18 @@ if (!defined('ALLOWED')) * @brief add tag , used for follow up * @see Tag */ -require_once NOALYSS_INCLUDE.'/class/tag.class.php'; +require_once NOALYSS_INCLUDE.'/class/tag_action.class.php'; //Single Tag ob_start(); if ($_GET['clear']==1) { /* Add a clear button */ - echo Tag::add_clear_button($_GET['pref']); + echo Tag_Action::add_clear_button($_GET['pref']); } if ($http->request("obj")=='t') { - $tag=new Tag($cn, $http->get("id", "number")); + $tag=new Tag_Action($cn, $http->get("id", "number")); $tag->update_search_cell($http->get("pref")); } elseif ($http->request("obj")=="g") @@ -47,7 +47,7 @@ elseif ($http->request("obj")=="g") $pref=$http->get("pref"); if ( $nb_atag > 0) { for ($i=0;$i<$nb_atag;$i++){ - $tag=new Tag($cn,$aTag[$i]['t_id']); + $tag=new Tag_Action($cn,$aTag[$i]['t_id']); $tag->update_search_cell($pref); } } diff --git a/include/ajax/ajax_search_clear_tag.php b/include/ajax/ajax_search_clear_tag.php index 3904e0773..95ab181c5 100644 --- a/include/ajax/ajax_search_clear_tag.php +++ b/include/ajax/ajax_search_clear_tag.php @@ -24,9 +24,9 @@ if ( !defined ('ALLOWED') ) die('Appel direct ne sont pas permis'); *@see Tag */ -require_once NOALYSS_INCLUDE.'/class/tag.class.php'; +require_once NOALYSS_INCLUDE.'/class/tag_action.class.php'; ob_start(); -echo Tag::button_search($_GET['pref']); +echo Tag_Action::select_tag_search($_GET['pref']); $response= ob_get_clean(); $html=escape_xml($response); header('Content-type: text/xml; charset=UTF-8'); diff --git a/include/ajax/ajax_search_display_tag.php b/include/ajax/ajax_search_display_tag.php index b4295cc38..43efd2c92 100644 --- a/include/ajax/ajax_search_display_tag.php +++ b/include/ajax/ajax_search_display_tag.php @@ -24,10 +24,27 @@ if ( !defined ('ALLOWED') ) die('Appel direct ne sont pas permis'); *@see Tag */ -require_once NOALYSS_INCLUDE.'/class/tag.class.php'; -$tag=new Tag($cn); +require_once NOALYSS_INCLUDE.'/class/tag_action.class.php'; +require_once NOALYSS_INCLUDE.'/class/tag_operation.class.php'; -$response= $tag->select_search($_GET['pref']); +try { + $caller_obj=$http->request("caller_obj"); + $prefix=$http->request("pref"); +} catch (Exception $ex) { + echo $ex->getMessage(); + return; +} + +if ( $caller_obj == 'Tag_Action' ) { + $tag=new Tag_Action($cn); +}elseif ($caller_obj=='Tag_Operation') +{ + $tag=new Tag_Operation( $cn); +} else { + throw new Exception("AJD001 invalid caller [$caller_obj]"); +} + +$response= $tag->select_search($pref); $html=escape_xml($response); header('Content-type: text/xml; charset=UTF-8'); diff --git a/include/ajax/ajax_search_filter.php b/include/ajax/ajax_search_filter.php index 7f6a8eaa1..c27458f11 100644 --- a/include/ajax/ajax_search_filter.php +++ b/include/ajax/ajax_search_filter.php @@ -24,6 +24,7 @@ if (!defined('ALLOWED')) require NOALYSS_INCLUDE.'/database/user_filter_sql.class.php'; require NOALYSS_INCLUDE.'/class/acc_ledger_search.class.php'; +require_once NOALYSS_INCLUDE.'/class/tag_operation.class.php'; $cn=Dossier::connect(); $dossier_id=Dossier::id(); global $g_user; @@ -55,12 +56,19 @@ if ($op=='save_filter') $new->setp("amount_max", $http->post("amount_max", 'number', NULL)); $new->setp("qcode", $http->post("qcode", 'string', NULL)); $new->setp("accounting", $http->post("accounting", 'string', NULL)); + $new->setp("uf_tag_option",$http->post("tag_option","string",null)); $new->setp("date_paid_start", $http->post("date_paid_start", 'string', NULL)); $new->setp("date_paid_end", $http->post("date_paid_end", 'string', NULL)); $new->setp("ledger_type", $http->post("ledger_type", 'string')); $new->setp("operation_filter", $http->post("operation_filter", 'string', NULL)); $new->setp("filter_name", h($http->post("filter_name", 'string'))); + $tag=$http->post("tag","string",''); + + if (is_array($tag) ) + $new->setp("uf_tag",join(',',$tag)); + else + $new->setp("uf_tag",null); $aJrn=[]; $max=$http->post("nb_jrn"); for ($i=0; $i<$max; $i++) @@ -75,11 +83,11 @@ if ($op=='save_filter') $new->save(); $rmAction=sprintf("delete_filter('%s','%s','%s')", trim($http->post('div')), $dossier_id, $new->getp('id')); - $answer['filter_name']=sprintf(''.SMALLX.'' - ); - $answer['filter_name'].=sprintf("%s", + $answer['filter_name']=""; + $answer['filter_name'].=sprintf("%s", trim($http->post('div')), $dossier_id, $new->getp('id'), $new->getp("filter_name")); + $answer['filter_name'].='';; $answer['filter_id']=$new->getp("id"); $answer['status']='OK'; } @@ -108,7 +116,8 @@ if ($op=="load_filter") $record['desc']=$record['description']; $record['r_jrn']=explode(",", $record['r_jrn']); - + $record['tag']=explode(",",$record['uf_tag']); + $record['tag_option']=$record["uf_tag_option"]; $result=array_merge($answer, $record); @@ -148,7 +157,7 @@ if ($op=="display_search_filter") echo ""; echo "
  • "; - echo HtmlInput::anchor(_("Remise à zéro"), "", "onclick=\"reset_filter('$p_div');removeDiv('boxfilter{$p_div}')\""); + echo HtmlInput::anchor(_("Remise à zéro"), "", "style=\"text-decoration:underline\" onclick=\"reset_filter('$p_div');removeDiv('boxfilter{$p_div}')\""); echo "
  • "; // Link reset @@ -157,12 +166,11 @@ if ($op=="display_search_filter") printf('
  • ', $p_div, $result[$i]["id"]); $rmAction=sprintf("delete_filter('%s','%s','%s')", $p_div, $dossier_id, $result[$i]['id']); - printf(''.SMALLX.'' - ); - printf("", + printf("", $p_div, $dossier_id, $result[$i]["id"],$p_div); echo $result[$i]["filter_name"]; echo ''; + echo ''; printf("
  • "); } @@ -198,4 +206,22 @@ if ($op=="delete_search_operation") header('Content-Type: application/json;charset=utf-8'); echo json_encode($answer); return; +} +//--------------------------------------------------------------------------------------------------------------- +// display_filter_tag : transform uf_tag into a list of tag , and display those tags in cells +//---------------------------------------------------------------------------------------------------------------- +if ($op=='display_filter_tag') +{ + $tag=$http->request("uf_tag"); + $div=$http->request("div"); + $aTag=explode(',', $tag); + if (is_array($aTag)) + { + $nb_tag=count($aTag); + for ($j=0; $j<$nb_tag; $j++) + { + $tag_operation=new Tag_Operation($cn, $aTag[$j]); + $tag_operation->update_search_cell($div); + } + } } \ No newline at end of file diff --git a/include/ajax/ajax_tag_list.php b/include/ajax/ajax_tag_list.php index 5ce78c43f..794b21a88 100644 --- a/include/ajax/ajax_tag_list.php +++ b/include/ajax/ajax_tag_list.php @@ -23,9 +23,9 @@ */ if ( !defined ('ALLOWED') ) die('Appel direct ne sont pas permis'); -require_once NOALYSS_INCLUDE.'/class/tag.class.php'; +require_once NOALYSS_INCLUDE.'/class/tag_action.class.php'; ob_start(); -$tag=new Tag($cn); +$tag=new Tag_Action($cn); $tag->select(); //------------------- Propose to add a tag @@ -35,8 +35,12 @@ if ( $g_user->check_action(TAGADD) == 1) { echo HtmlInput::button("tag_add", _(" echo HtmlInput::button_close("tag_div"); $response= ob_get_clean(); +if (headers_sent() && DEBUG ){ + echo $response; +} else { + header('Content-type: text/xml; charset=UTF-8'); +} $html=escape_xml($response); -header('Content-type: text/xml; charset=UTF-8'); echo << diff --git a/include/ajax/ajax_tag_select_search.php b/include/ajax/ajax_tag_select_search.php index f5f9462b0..f103a4f43 100644 --- a/include/ajax/ajax_tag_select_search.php +++ b/include/ajax/ajax_tag_select_search.php @@ -23,9 +23,9 @@ if ( !defined ('ALLOWED') ) die('Appel direct ne sont pas permis'); *@brief Show the tags to select *@see Tag */ -require_once NOALYSS_INCLUDE.'/class/tag.class.php'; +require_once NOALYSS_INCLUDE.'/class/tag_action.class.php'; ob_start(); -$tag=new Tag($cn); +$tag=new Tag_Action($cn); $tag->select_search(); $response= ob_get_clean(); diff --git a/include/class/acc_ledger_search.class.php b/include/class/acc_ledger_search.class.php index 801e98b34..4989f61e6 100644 --- a/include/class/acc_ledger_search.class.php +++ b/include/class/acc_ledger_search.class.php @@ -21,6 +21,8 @@ // if (!defined('ALLOWED')) die('Appel direct ne sont pas permis'); +require_once NOALYSS_INCLUDE."/class/tag_operation.class.php"; + /** * @file * @brief search in ledger @@ -455,6 +457,7 @@ class Acc_Ledger_Search $fil_paid=''; $fil_date_paid=''; $fil_hide_operation=''; + $fil_tag=''; $and=''; $g_user=new User($this->cn); @@ -500,7 +503,27 @@ class Acc_Ledger_Search $and=''; } } - + //---- + // Search tags + if ( isset($p_array[$op."tag"] )) + { + $strTag=join(",", $p_array[$op."tag"]); + if ($p_array[$op."tag_option"] == 1){ + // any tag + $fil_tag=$and.' jr_id in (select jrn_id from operation_tag where tag_id in ('.sql_string($strTag).')) '; + } else { + // all tags + $aTag=$p_array[$op."tag"]; + $sub_tag=""; $nb_tag=count($aTag); + $and2=''; + for ($x=0;$x < $nb_tag;$x++) { + $sub_tag = " tag_id = ".sql_string($aTag[$x]); + $fil_tag=$and.' jr_id in (select jrn_id from operation_tag where '.$sub_tag.')' ; + $and=" and "; + } + } + $and=" and "; + } /* format the number */ $amount_min=abs(toNumber($amount_min)); $amount_max=abs(toNumber($amount_max)); @@ -620,7 +643,7 @@ class Acc_Ledger_Search " and uj_priv in ('R','W'))"; } $where=$fil_ledger.$fil_amount.$fil_date.$fil_desc.$fil_sec.$fil_amount. - $fil_qcode.$fil_paid.$fil_account.$fil_date_paid.$fil_hide_operation; + $fil_qcode.$fil_paid.$fil_account.$fil_date_paid.$fil_hide_operation.$fil_tag; $sql.=" where ".$where; // Q?? Why do we return where if it is included in SQL ? diff --git a/include/class/follow_up.class.php b/include/class/follow_up.class.php index e674ee1f1..f8c592989 100644 --- a/include/class/follow_up.class.php +++ b/include/class/follow_up.class.php @@ -42,6 +42,7 @@ require_once NOALYSS_INCLUDE.'/class/document_option.class.php'; require_once NOALYSS_INCLUDE.'/class/default_menu.class.php'; require_once NOALYSS_INCLUDE.'/lib/inplace_edit.class.php'; require_once NOALYSS_INCLUDE.'/lib/noalyss_csv.class.php'; +require_once NOALYSS_INCLUDE.'/class/tag_action.class.php'; /** * \file diff --git a/include/class/tag.class.php b/include/class/tag.class.php index aacd77728..5672adf08 100644 --- a/include/class/tag.class.php +++ b/include/class/tag.class.php @@ -38,7 +38,7 @@ class Tag return $this; } - /** + /** * Show the list of available tag * @return HTML */ @@ -48,19 +48,7 @@ class Tag if ( $this->cn->count($ret) == 0) return ""; require_once NOALYSS_TEMPLATE.'/tag_list.php'; } - /** - * let select a tag to add - */ - function select() - { - $ret=$this->data->seek("where t_actif='Y' order by t_tag"); - $ret=$this->cn->exec_sql(" select t_id,t_tag,t_description,'t' as tag_type ,t_color - from tags - where t_actif='Y' - union all - select tg_id,tg_name ,'G','g' ,1 from tag_group order by 2"); - require_once NOALYSS_TEMPLATE.'/tag_select.php'; - } + /** * Display a inner window with the detail of a tag */ @@ -93,43 +81,17 @@ class Tag $this->data->t_id=$p_array['t_id']; $this->data->delete(); } - /** - * Show a button to select tag for Search - * @return HTML + /*** + * query the active tag and returns the database handler */ - static function button_search($p_prefix) - { - $r=""; - $r.=HtmlInput::button("choose_tag", _("Etiquette"), 'onclick="search_display_tag('.Dossier::id().',\''.$p_prefix.'\')"', "smallbutton"); - return $r; - } - /** - * let select a tag to add to the search - */ - function select_search($p_prefix) - { - $res=""; - $ret=$this->data->seek(' order by t_tag'); - require_once NOALYSS_TEMPLATE.'/tag_search_select.php'; - return HtmlInput::title_box('Tag', $p_prefix.'tag_div').$res; - } - /** - * In the screen search add this data to the cell - */ - function update_search_cell($p_prefix) { - echo ''; - echo h($this->data->t_tag); - echo HtmlInput::hidden($p_prefix.'tag[]', $this->data->t_id); - $js=sprintf("$('sp_".$p_prefix.$this->data->t_id."').remove();"); - echo Icon_Action::trash(uniqid(), $js); - echo ''; - } - /** - * clear the search cell - */ - static function add_clear_button($p_prefix) { - $clear=HtmlInput::button('clear', 'X', 'onclick="search_clear_tag('.Dossier::id().',\''.$p_prefix.'\');"', 'smallbutton'); - return $clear; + function query_active_tag() + { + $ret=$this->cn->exec_sql(" select t_id,t_tag,t_description,'t' as tag_type ,t_color + from tags + where t_actif='Y' + union all + select tg_id,tg_name ,'G','g' ,1 from tag_group order by 2"); + return $ret; } } diff --git a/include/class/tag_action.class.php b/include/class/tag_action.class.php new file mode 100644 index 000000000..41521d471 --- /dev/null +++ b/include/class/tag_action.class.php @@ -0,0 +1,94 @@ + + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + * + * Author : Dany De Bontridder danydb@noalyss.eu + * + */ + +require_once NOALYSS_INCLUDE.'/class/tag.class.php'; + +/** + * @file + * @brief concerns the tags linked to an action + */ +class Tag_Action extends Tag +{ + function __construct($p_cn, $p_id=-1 ) + { + parent::__construct($p_cn, $p_id); + } + + /** + * let select a tag to add + */ + function select($p_prefix="") + { + $ret=parent::query_active_tag(); + require_once NOALYSS_TEMPLATE.'/tag_select.php'; + } + + /** + * Show a button to select tag for Search + * @return HTML + */ + static function select_tag_search($p_prefix) + { + $r=""; + $r.=HtmlInput::button("choose_tag", _("Etiquette"), + 'onclick="search_display_tag('.Dossier::id().',\''.$p_prefix.'\',\'Tag_Action\')"', "smallbutton"); + return $r; + } + + /** + * clear the search cell + */ + static function add_clear_button($p_prefix) + { + $clear=HtmlInput::button('clear', 'X', 'onclick="search_clear_tag('.Dossier::id().',\''.$p_prefix.'\');"', + 'smallbutton'); + return $clear; + } + + /** + * In the screen search add this data to the cell + */ + function update_search_cell($p_prefix) + { + $data=$this->get_data(); + echo ''; + echo h($data->t_tag); + echo HtmlInput::hidden($p_prefix.'tag[]', $data->t_id); + $js=sprintf("$('sp_".$p_prefix.$data->t_id."').remove();"); + echo Icon_Action::trash(uniqid(), $js); + echo ''; + } + + /** + * let select a tag to add to the search + */ + function select_search($p_prefix) + { + $res=""; + $ret=$this->get_data()->seek(' order by t_tag'); + require_once NOALYSS_TEMPLATE.'/tag_search_select.php'; + return HtmlInput::title_box('Tag', $p_prefix.'tag_div').$res; + } + +} diff --git a/include/class/tag_operation.class.php b/include/class/tag_operation.class.php new file mode 100644 index 000000000..af89bd9f5 --- /dev/null +++ b/include/class/tag_operation.class.php @@ -0,0 +1,199 @@ + + +if (!defined('ALLOWED')) + die('Appel direct ne sont pas permis'); + +/** + * @file + * @brief concerns the tags linked to an accountancy writing + */ +class Tag_Operation extends Tag +{ + + private $jrn_id=-1; + + function __construct($p_cn, $p_id=-1) + { + parent::__construct($p_cn, $p_id); + } + + public function get_jrn_id() + { + return $this->jrn_id; + } + + public function set_jrn_id($jrn_id) + { + $this->jrn_id=$jrn_id; + return $this; + } + + /** + * let select a tag to add + */ + function select($p_prefix="") + { + $ret=parent::query_active_tag(); + require_once NOALYSS_TEMPLATE.'/tag_select.php'; + } + + /** + * Show a button to select tag for Search + * @param $p_jr jr_id of the operation + * @param $p_div prefix of the dialog box + * @return HTML + */ + static function button_search($p_jr, $p_div) + { + $r=""; + $js=sprintf("onclick=\"new operation_tag('%s').select('%s','%s')\"", $p_div, dossier::id(), $p_jr); + $r.=HtmlInput::button('tag_bt', _('Ajout étiquette'), $js, 'smallbutton'); + return $r; + } + + /** + * clear the search cell + */ + static function add_clear_button($p_prefix) + { + $clear=HtmlInput::button('clear', 'X', 'onclick="search_clear_tag('.Dossier::id().',\''.$p_prefix.'\');"', + 'smallbutton'); + return $clear; + } + + /** + * In the screen search add this data to the cell + */ + function update_search_cell($p_prefix) + { + $data=$this->get_data(); + echo ''; + echo h($data->t_tag); + echo HtmlInput::hidden($p_prefix.'tag[]', $data->t_id); + $js=sprintf("$('sp_".$p_prefix.$data->t_id."').remove();"); + echo Icon_Action::trash(uniqid(), $js); + echo ''; + } + + /** + * Links a tag to an operation + * @param int $p_tag_id tag.t_id + */ + function tag_add($p_tag_id) + { + if ($this->jrn_id==-1) + { + throw new Exception("TO99 jrn_id unset"); + } + $count=$this->cn->get_value('select count(*) from operation_tag'. + ' where jrn_id=$1 and tag_id=$2', array($this->jrn_id, $p_tag_id)); + if ($count>0) + return; + $sql=' insert into operation_tag (jrn_id,tag_id) values ($1,$2)'; + $this->cn->exec_sql($sql, array($this->jrn_id, $p_tag_id)); + } + + /** + * @brief show the cell content in Display for the tags + * @param $div prefix of the DOM id + * called also by ajax + */ + function tag_cell($p_div) + { + global $g_user; + $a_tag=$this->tag_get(); + $c=count($a_tag); + $ledger=$this->cn->get_value("select jr_def_id from jrn where jr_id=$1", [$this->jrn_id]); + $access=$g_user->get_ledger_access($ledger); + for ($e=0; $e<$c; $e++) + { + echo ''; + echo $a_tag[$e]['t_tag']; + if ($access=='W') + { + $js_remove=sprintf("new operation_tag('%s').remove('%s','%s','%s')", $p_div, dossier::id(), + $this->jrn_id, $a_tag[$e]['t_id']); + echo Icon_Action::trash(uniqid(), $js_remove); + } + echo ''; + echo ' '; + echo ' '; + } + } + + /** + * @brief get the tags of the current objet + * @return an array idx [ag_id,t_id,at_id,t_tag] + */ + function tag_get() + { + if ($this->jrn_id==-1) + { + throw new Exception("TO01 jrn_id unset"); + } + $sql='select b.jrn_id,a.t_id,a.t_id,a.t_tag,a.t_color' + .' from ' + .' tags as a join operation_tag as b on (a.t_id=b.tag_id)' + .' where jrn_id=$1 ' + .' order by a.t_tag'; + $array=$this->cn->get_array($sql, array($this->jrn_id)); + return $array; + } + + /** + * Remove a tag + * @param int $p_tag_id tag id + */ + function tag_remove($p_tag_id) + { + if ($this->jrn_id==-1) + { + throw new Exception("TO01 jrn_id unset"); + } + $this->cn->exec_sql("delete from operation_tag where jrn_id=$1 and tag_id=$2", [$this->jrn_id, $p_tag_id]); + } + + /** + * let select a tag to add to the search + */ + function select_search($p_prefix) + { + $res=""; + $ret=$this->get_data()->seek(' order by t_tag'); + require_once NOALYSS_TEMPLATE.'/tag_search_select.php'; + return HtmlInput::title_box('Tag', $p_prefix.'tag_div').$res; + } + /** + * Show a button to select tag for Search + * @return HTML + */ + static function select_tag_search($p_prefix) + { + $r=""; + $r.=HtmlInput::button("choose_tag", _("Etiquette"), + 'onclick="search_display_tag('.Dossier::id().',\''.$p_prefix.'\',\'Tag_Operation\')"', "smallbutton"); + return $r; + } + +} + +?> \ No newline at end of file diff --git a/include/constant.php b/include/constant.php index 7d08aea22..92046e50d 100644 --- a/include/constant.php +++ b/include/constant.php @@ -107,7 +107,7 @@ if ( !defined ("NOALYSS_PACKAGE_REPOSITORY")) { if ( ! defined ("SYSINFO_DISPLAY")) { define ("SYSINFO_DISPLAY",TRUE); } -define ("DBVERSION",150); +define ("DBVERSION",151); define ("MONO_DATABASE",25); define ("DBVERSIONREPO",18); define ('NOTFOUND','--not found--'); diff --git a/include/database/user_filter_sql.class.php b/include/database/user_filter_sql.class.php index 72ebb83c9..55b59beab 100644 --- a/include/database/user_filter_sql.class.php +++ b/include/database/user_filter_sql.class.php @@ -56,6 +56,9 @@ class User_filter_SQL extends Noalyss_SQL , "all_ledger"=>"all_ledger" ,"operation_filter"=>"operation_filter" ,'filter_name'=>"filter_name" + ,'uf_tag'=>'uf_tag' + ,'uf_tag_option'=>'uf_tag_option' + ); /* * Type of columns @@ -78,6 +81,8 @@ class User_filter_SQL extends Noalyss_SQL , "all_ledger"=>"numeric" ,"operation_filter"=>"text" ,"filter_name"=>"text" + ,'uf_tag'=>'text' + ,'uf_tag_option'=>'numeric' ); diff --git a/include/history_operation.inc.php b/include/history_operation.inc.php index 5e7aac3e0..d61658e67 100644 --- a/include/history_operation.inc.php +++ b/include/history_operation.inc.php @@ -175,17 +175,28 @@ echo ''; */ $r = HtmlInput::get_to_hidden(array('l', 'date_paid_start','date_paid_end', 'date_start', 'date_end', 'desc', 'amount_min', 'amount_max', 'qcode','operation_filter', - 'accounting', 'unpaid', 'gDossier', 'ledger_type', 'p_action')); + 'accounting', 'unpaid', 'gDossier', 'ledger_type', 'p_action','search_optag_option')); if (isset($_GET['search_opr_jrn'])) { foreach ($a_search_opr_jrn as $k => $v) if (isNumber($v)) $r.=HtmlInput::hidden('r_jrn[' . $k . ']', $v); } +$r.=HtmlInput::hidden("tag_option",$http->request("search_optag_option","string",0)); if (isset($_GET['r_jrn'])) { foreach ($a_rjn as $k => $v) if (isNumber($v)) $r.=HtmlInput::hidden('r_jrn[' . $k . ']', $v); } +if (isset($_GET['search_optag'])) { + $http=new HttpInput(); + $aTag=$http->get("search_optag","array"); + foreach ($aTag as $k=>$v) { + // Protect : check that $k and $v are numeric + if (isNumber($k)&&isNumber($v)) { + $r.=HtmlInput::hidden('tag[]',$v); + } + } +} echo '
    '; echo $r; echo HtmlInput::hidden('act', 'CSV:histo'); diff --git a/include/sql/patch/upgrade150.sql b/include/sql/patch/upgrade150.sql new file mode 100644 index 000000000..b3a879b3a --- /dev/null +++ b/include/sql/patch/upgrade150.sql @@ -0,0 +1,15 @@ +begin; +alter table tags add column t_color int; +alter table tags alter t_color set default 1; +update tags set t_color=1; +create table operation_tag (opt_id bigserial primary key, jrn_id bigint , tag_id int); +alter table operation_tag add constraint opt_jrnx foreign key (jrn_id) references jrn (jr_id) on update cascade on delete cascade; +alter table operation_tag add constraint opt_tag_id foreign key (tag_id) references tags (t_id) on update cascade on delete cascade; +comment on table operation_tag is 'Tag attached to an operation'; +ALTER TABLE public.user_filter ADD uf_tag text ; +alter table user_filter add uf_tag_option int; + +COMMENT ON COLUMN public.user_filter.uf_tag IS 'Tag list'; +COMMENT ON COLUMN public.user_filter.uf_tag_option IS '0 : all tags must be present, 1: at least one'; +insert into version (val,v_description) values (151,'Tag with color and operation'); +commit; diff --git a/include/template/action_other_action.php b/include/template/action_other_action.php index 4759467c3..19d510441 100644 --- a/include/template/action_other_action.php +++ b/include/template/action_other_action.php @@ -33,16 +33,16 @@ echo HtmlInput::request_to_hidden(array("closed_action","remind_date_end","remin
  • value="ETIADD";echo $radio->input(); ?> - - + +
  • value="ETIREM";echo $radio->input(); ?> - - + +
  • diff --git a/include/template/action_search.php b/include/template/action_search.php index 20f3a436b..00d11ec39 100644 --- a/include/template/action_search.php +++ b/include/template/action_search.php @@ -129,14 +129,14 @@

    - + get("searchtag","array",array()); for ($i=0;$iupdate_search_cell('search'); } } diff --git a/include/template/detail-action.php b/include/template/detail-action.php index 821cb62b6..d930f531c 100644 --- a/include/template/detail-action.php +++ b/include/template/detail-action.php @@ -160,7 +160,7 @@ $uniq=uniqid("tab",TRUE); Dossier / Etiquette - + tag_cell($p_view); ?> diff --git a/include/template/ledger_detail_bottom.php b/include/template/ledger_detail_bottom.php index f62975a17..3675ad2d1 100644 --- a/include/template/ledger_detail_bottom.php +++ b/include/template/ledger_detail_bottom.php @@ -44,6 +44,7 @@ $a_tab['linked_operation_div']=array('id'=>'linked_operation_div'.$div,'label'=> $a_tab['document_operation_div']=array('id'=>'document_operation_div'.$div,'label'=>_('Document').'('.$nb_document.')','display'=>'block'); $a_tab['linked_action_div']=array('id'=>'linked_action_div'.$div,'label'=>_('Actions Gestion').'('.count($a_followup).')','display'=>'none'); $a_tab['analytic_div']=array('id'=>'analytic_div'.$div,'label'=>_('Comptabilité Analytique'),'display'=>'none'); +$a_tab['tag_operation_div']=array('id'=>'tag_operation_div'.$div,'label'=>_('Etiquette'),'display'=>'none'); // show tabs @@ -308,7 +309,23 @@ require_once NOALYSS_TEMPLATE.'/ledger_detail_file.php'; - +

    +
    + set_jrn_id($obj->det->jr_id); + $tag_operation->tag_cell($div); + ?> + +
    + det->jr_id,$div);} + ?> +

    '; diff --git a/include/template/ledger_search.php b/include/template/ledger_search.php index a6a1e00e5..7461998eb 100644 --- a/include/template/ledger_search.php +++ b/include/template/ledger_search.php @@ -87,5 +87,40 @@ echo $f_accounting->input(); ?> input(); ?> - + + + + + div."tag_option"); + $iselect->value=array( + array("value"=>0,"label"=>_("Toutes les étiquettes")), + array("value"=>1,"label"=>_("Au moins une étiquette")) + ); + + $iselect->set_value($http->request($this->div."tag_option","number",0)); + echo $iselect->input(); + + ?> + div); + ?> + + + + request($this->div."tag","string",0); + if (is_array($aTag) ) { + $nb_tag=count($aTag); + for ($j=0;$j< $nb_tag;$j++) { + $tag_operation=new Tag_Operation($this->cn,$aTag[$j]); + $tag_operation->update_search_cell($this->div); + } + } + ?> + + + + + diff --git a/include/template/tag_select.php b/include/template/tag_select.php index 59732c3f2..4263df1ba 100644 --- a/include/template/tag_select.php +++ b/include/template/tag_select.php @@ -27,15 +27,28 @@ if ( $max == 0 ) { request("ag_id","number"); -if (isNumber($ag_id) == 0 ) die ('ERROR : parameters invalid'); +$id="none"; + +if ( get_class($this) == 'Tag_Action' ) { + $id=$http->request("ag_id","number"); + } elseif (get_class($this)=='Tag_Operation') +{ + $id=$http->request("jrn_id"); +} + +if (isNumber($id) == 0 ) die ('ERROR : parameters invalid'); for ($i=0;$i<$max;$i++): $row=Database::fetch_array($ret, $i); ?>