diff --git a/html/css/style-classic7.css b/html/css/style-classic7.css index 9b7d338f2..42a46484a 100644 --- a/html/css/style-classic7.css +++ b/html/css/style-classic7.css @@ -4089,4 +4089,16 @@ h2.h-section { */ .bt-error { color:var(--color-red); +} + + + + +#jrn_note_td { + + background-color: lightyellow; +} + +.font-small { + font-size: 0.90rem; } \ No newline at end of file diff --git a/html/js/noalyss_script.js b/html/js/noalyss_script.js index 943328823..4590e6b7a 100644 --- a/html/js/noalyss_script.js +++ b/html/js/noalyss_script.js @@ -21,7 +21,8 @@ /** * - * javascript script, always added to every page + * javascript script, always added to every page, it is the first script and + * should contain all the global variables * */ var ask_reload = 0; @@ -34,6 +35,16 @@ var layer=0; var viewport = document.viewport.getDimensions(); // Gets the viewport as an object literal var width = viewport.width; // Usable window width var height = viewport.height; +var g_enable_tinymce=true; +/** + * if browser < 2021, function window.crypto.randomUUID is not implemented + * so we tinyMCE cannot work +*/ +if ( ! window.crypto.randomUUID) { + console.info("too old browser: implement function randomUUID") + g_enable_tinymce=false; +} + /** * return undefined if nothing is found , otherwise return the DOM elemnt, try to find an DOM Element inside p_element @@ -4726,6 +4737,7 @@ Noalyss = function () { */ Noalyss.prototype.activate_tinymce=function (domid,mode,p_height) { + if ( ! g_enable_tinymce ) return; tinymce.remove('#'+domid); if (! p_height) p_height=500; if ( mode == 'minimal' || ! mode ) @@ -4800,5 +4812,130 @@ Noalyss.prototype.activate_tinymce=function (domid,mode,p_height) { } } +/** + * Input NOTE on operation from Detail Operation + * @param {int} dossier_id + * @param {int} jrn_id + * @param {string} div_prefix + * @returns {undefined} + */ +Noalyss.prototype.input_note=function (dossier_id,jrn_id,div_prefix) +{ + + try + { + var dgbox = "box_input_note"+div_prefix; + waiting_box(); + removeDiv(dgbox); + var queryString = { + op:'ledger' + ,act:'note_input' + ,jr_id:jrn_id + ,div:div_prefix + ,gDossier:dossier_id + ,tinymce:g_enable_tinymce + }; + var action = new Ajax.Request( + "ajax_misc.php", + { + method: 'get', + parameters: queryString, + onFailure: ajax_misc_failure, + onSuccess: function (req) { + remove_waiting_box(); + if (req.responseText == 'NOCONX') { + reconnect(); + return; + } + var y = calcy(15); + var div_style = "position:absolute;" + ";top:" + y + "px"; + add_div({id: dgbox, cssclass: 'inner_box2', html: loading(), style: div_style, drag: true}); + let response=req.responseXML; + let html=getNodeText(response.getElementsByTagName("code")[0]) + let ctl=getNodeText(response.getElementsByTagName("ctl")[0]); + $(dgbox).update(html); + + } + } + ); + } catch (e) + { + alert_box(e.message); + } +} +/** + * Save note, call from ajax_ledger.php act = note_input + * @param {DOMObjet} dom_form + * @returns {undefined} + */ +Noalyss.prototype.save_note=function (dom_form) +{ + try + { + waiting_box(); + let queryString=dom_form.serialize(true); + console.debug(queryString) + if ( g_enable_tinymce ) { + queryString['note_html'] = tinymce.get(queryString['input_html']).getContent(); + }else{ + queryString['note_html'] =$F($F('input_html')) + } + queryString['op'] = 'ledger'; + var x=this; + var action = new Ajax.Request( + "ajax_misc.php", + { + method: 'POST', + parameters: queryString, + onFailure: ajax_misc_failure, + onSuccess: function (req) { + remove_waiting_box(); + if (req.responseText == 'NOCONX') { + reconnect(); + return; + } + let response=req.responseXML; + let html=getNodeText(response.getElementsByTagName("code")[0]) + let ctl=getNodeText(response.getElementsByTagName("ctl")[0]); + console.debug(response); + $('note_html'+ctl).update(html); + x.refresh_note(queryString['jr_id'],queryString['gDossier']); + removeDiv('box_input_note'+queryString['div']); + } + } + ); + } catch (e) + { + alert_box(e.message); + } + +} +Noalyss.prototype.refresh_note=function(jrn_id,dossier_id) +{ + if ( document.getElementById("als_note"+jrn_id)) { + new Ajax.Updater('als_note'+jrn_id,'ajax_misc.php',{ + method:'get', + parameters:{ + op:'ledger' + ,'act':'note_refresh' + ,jr_id:jrn_id + ,gDossier:dossier_id + ,div:'not-set' + } + }) + } else if ( document.getElementById("jrn_note_td")) { + new Ajax.Updater('jrn_note_td','ajax_misc.php',{ + method:'get', + parameters:{ + op:'ledger' + ,'act':'note_refresh' + ,jr_id:jrn_id + ,gDossier:dossier_id + ,div:'not-set' + } + }) + } + +} noalyss=new Noalyss(); diff --git a/include/ajax/ajax_ledger.php b/include/ajax/ajax_ledger.php index c26cf593a..f988848b6 100644 --- a/include/ajax/ajax_ledger.php +++ b/include/ajax/ajax_ledger.php @@ -412,8 +412,7 @@ switch ($action) { from jrnx join jrn on (j_grpt=jr_grpt_id) where jr_id=$1) ', array($jr_id)); - $cn->exec_sql("select comptaproc.jrn_add_note($1,$2)", - array($jr_id, $http->post('jrn_note'))); + $rapt = $http->post('rapt'); if ($g_parameter->MY_UPDLAB == 'Y' && isset ($_POST['j_id'])) { @@ -556,6 +555,66 @@ switch ($action) { break; +//------------------------------------------------ +// Display note +//------------------------------------------------ + case 'note_input': + $acc_operation_note= Acc_Operation_Note::build_jrn_id($jr_id); + try { + $ctl="box_input_note".$div; + $html=HtmlInput::title_box(_("Note"), $ctl); + $textarea= Acc_Operation_Note::build_textarea($div); + if ( $http->get('tinymce')=='true') + $textarea->value=$acc_operation_note->getJrnNoteSql()->get("n_html"); + else { + $textarea->set_enrichText('plain'); + $textarea->value=$acc_operation_note->getJrnNoteSql()->get("n_text"); + } + + // start FORM + $html.=sprintf('
', + $div); + + $html.=$textarea->input(); + + $html.=HtmlInput::hidden('gDossier', $gDossier); + $html.=HtmlInput::hidden('div', $div); + $html.=HtmlInput::hidden('jr_id', $jr_id); + $html.=HtmlInput::hidden('act', 'note_save'); + $html.=HtmlInput::submit("save", _("Sauve")); + $html.=HtmlInput::hidden("input_html", $textarea->id); + $html.=HtmlInput::button_close($ctl); + // end form + $html.="
"; + } catch (Exception $exc) { + echo $exc->getTraceAsString(); + } + + break; + case 'note_save': +//------------------------------------------------ +// save note +//------------------------------------------------ + + /** + * received parameters + * - gDossier + * - div + * - jr_id + * - note_html + */ + $ctl="box_input_note".$div; + $acc_operation_note= Acc_Operation_Note::build_jrn_id($jr_id); + $acc_operation_note->setOperation_id($jr_id); + $acc_operation_note->setNote($http->post("note_html",'raw')); + $acc_operation_note->save(); + $html=$http->post("note_html","raw"); + break; + case 'note_refresh': + $acc_operation_note= Acc_Operation_Note::build_jrn_id($jr_id); + echo $acc_operation_note->getNote(); + + return; } $html = escape_xml($html); if (!headers_sent()) { diff --git a/include/class/acc_ledger_sale.class.php b/include/class/acc_ledger_sale.class.php index 5d3f554c8..81d4521fe 100644 --- a/include/class/acc_ledger_sale.class.php +++ b/include/class/acc_ledger_sale.class.php @@ -1026,7 +1026,7 @@ class Acc_Ledger_Sale extends Acc_Ledger { $r.=' ' . _('Client') . ' ' . HtmlInput::card_detail($e_client).":".hb( $client_name) . ''; $r.=''; $r.=''; - $r.='
'._('Note').' '.h($p_array['jrn_note_input']).'
'; + $r.='
'._('Note').'
'.$p_array['jrn_note_input'].'
'; $r.=''; $r.='
'; $r.='
'; diff --git a/include/class/acc_ledger_search.class.php b/include/class/acc_ledger_search.class.php index 625c02e36..8ff7c4d81 100644 --- a/include/class/acc_ledger_search.class.php +++ b/include/class/acc_ledger_search.class.php @@ -343,6 +343,7 @@ class Acc_Ledger_Search p_closed, jr_pj_number, n_text, + n_html, (select string_agg(a,' ') from (select ''||t_tag||'' a from operation_tag ot join tags t on(ot.tag_id=t.t_id) @@ -943,7 +944,14 @@ class Acc_Ledger_Search if ( $row['analytic_op'] != "") $r.=sprintf(''); $r.=""; - $r.=td(h($row['n_text']), ' style="font-size:0.87em%"'); + // Note + $r.=''; + $r.=''; + $r.= $row['n_text']; + $r.=''; + $r.=''; + $r.=''; + // Amount // If the ledger is financial : // the credit must be negative and written in red diff --git a/include/class/acc_operation.class.php b/include/class/acc_operation.class.php index e4175573b..f7ed26821 100644 --- a/include/class/acc_operation.class.php +++ b/include/class/acc_operation.class.php @@ -1117,9 +1117,15 @@ class Acc_Detail extends Acc_Operation { $this->det->$key=$val; } - $sql="select n_text from jrn_note where jr_id=$1"; - $this->det->note=$this->db->get_value($sql,array($this->jr_id)); - $this->det->note=strip_tags($this->det->note); + $sql="select n_text,n_html from jrn_note where jr_id=$1"; + $a=$this->db->get_row($sql,array($this->jr_id)); + if ( empty($a)) { + $this->det->note=""; + $this->det->note_html=null; + } else { + $this->det->note=strip_tags($a['n_text']); + $this->det->note_html=($a['n_html'] == "")?$a['n_text']:$a['n_html']; + } } /** * diff --git a/include/class/acc_operation_note.class.php b/include/class/acc_operation_note.class.php index c6188b6e8..2d72c6fef 100644 --- a/include/class/acc_operation_note.class.php +++ b/include/class/acc_operation_note.class.php @@ -35,7 +35,7 @@ class Acc_Operation_Note private $id; private $operation_id; //!< jrn.jr_id private $jrn_note_sql; - + function __construct(Jrn_Note_SQL $p_Jrn_Note_SQL) { $this->jrn_note_sql = $p_Jrn_Note_SQL; @@ -79,12 +79,18 @@ class Acc_Operation_Note { $cn=Dossier::connect(); $this->jrn_note_sql->setp("jr_id",$this->operation_id); - $this->jrn_note_sql->setp("n_text",$this->note); + $this->jrn_note_sql->setp("n_text", strip_tags($this->note)); if ( empty($this->jrn_note_sql->n_text) && $this->id > -1 ) { $this->jrn_note_sql->delete(); return $this; } + // forbid the tag script, iframe and A + $n=str_ireplace('note); + $n=str_ireplace('jrn_note_sql->setp("n_html", $n); $this->jrn_note_sql->save(); $this->id=$this->jrn_note_sql->n_id; return $this; @@ -121,6 +127,19 @@ class Acc_Operation_Note } function print() { - echo ''; + echo ''; + } + /** + * @brief create a TEXTAREA to show HTML Note + * @param type $div_id + * @returns ITextarea + */ + static function build_textarea($div_id) + { + $inote = new ITextarea('jrn_note'); + $inote->id="{$div_id}_jrn_note"; + $inote->set_enrichText("no-toolbar"); + $inote->heigh=500; + return $inote; } } \ No newline at end of file diff --git a/include/database/jrn_note_sql.class.php b/include/database/jrn_note_sql.class.php index 08604a4a5..77d72c8bc 100644 --- a/include/database/jrn_note_sql.class.php +++ b/include/database/jrn_note_sql.class.php @@ -44,6 +44,7 @@ class Jrn_Note_SQL extends Table_Data_SQL "n_id"=>"n_id" , "jr_id"=>"jr_id" ,"n_text"=>"n_text" + ,"n_html"=>"n_html" ); /* * Type of columns @@ -52,6 +53,7 @@ class Jrn_Note_SQL extends Table_Data_SQL "n_id"=>"number" , "jr_id"=>"number" ,"n_text"=>"text" + ,"n_html"=>"text" ); diff --git a/include/lib/itextarea.class.php b/include/lib/itextarea.class.php index f594a38e6..edaee3692 100644 --- a/include/lib/itextarea.class.php +++ b/include/lib/itextarea.class.php @@ -85,7 +85,7 @@ class ITextarea extends HtmlInput EOF; diff --git a/include/template/acc_operation_note-input.php b/include/template/acc_operation_note-input.php index 2860e8e10..607f0b19a 100644 --- a/include/template/acc_operation_note-input.php +++ b/include/template/acc_operation_note-input.php @@ -21,15 +21,24 @@ * \brief display input textarea for operation note * \see Acc_Operation_Note */ +//@var $note (itextarea); + +$note=new ITextarea("jrn_note_input"); +$note->set_enrichText("no-toolbar"); +$note->heigh=130; +$note->value=$p_current; + ?>