noalyss-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Noalyss-commit] [noalyss] 06/10: Task #0001904: Previsions et budgets R


From: Dany De Bontridder
Subject: [Noalyss-commit] [noalyss] 06/10: Task #0001904: Previsions et budgets Réécriture prévision
Date: Sun, 28 Mar 2021 09:22:04 -0400 (EDT)

sparkyx pushed a commit to branch master
in repository noalyss.

commit d0274f5bed8f9ecd152409414eecb04f0c86bdec
Author: Dany wm De Bontridder <danydb@noalyss.eu>
AuthorDate: Tue Mar 23 10:52:01 2021 +0100

    Task #0001904: Previsions et budgets
    Réécriture prévision
---
 html/ajax_misc.php                                 |   8 +-
 html/js/forecast.js                                |  25 -
 html/js/managetable.js                             |   1 +
 include/ajax/ajax_forecast.php                     |  77 +++
 include/ajax/ajax_forecast_category.php            |  60 +++
 include/ajax/ajax_forecast_item.php                |  59 +++
 include/class/anticipation.class.php               | 572 ++++++++-------------
 include/class/forecast_cat.class.php               | 172 -------
 include/class/forecast_category_mtable.class.php   | 118 +++++
 include/class/forecast_item.class.php              | 165 ------
 include/class/forecast_item_mtable.class.php       | 200 +++++++
 include/database/forecast_category_sql.class.php   |  67 +++
 include/database/forecast_item_sql.class.php       |  77 +++
 include/database/forecast_sql.class.php            |  67 +++
 include/forecast.inc.php                           | 385 ++++----------
 include/lib/function_javascript.php                |   1 -
 include/lib/impress.class.php                      |  42 +-
 include/lib/manage_table_sql.class.php             |  13 +-
 ...orecast_result.php => anticipation-display.php} |  54 +-
 include/template/anticipation-input_title.php      |  74 +++
 include/template/forecast-new.php                  |  90 ++++
 .../{forecast_cat.php => forecast_cat-delete.php}  |   0
 .../forecast_item_mtable-display_table.php         |  71 +++
 include/template/forecast_item_mtable-input.php    | 150 ++++++
 sql/upgrade.sql                                    |   2 +
 25 files changed, 1505 insertions(+), 1045 deletions(-)

diff --git a/html/ajax_misc.php b/html/ajax_misc.php
index 8674b22..4b83100 100644
--- a/html/ajax_misc.php
+++ b/html/ajax_misc.php
@@ -283,7 +283,13 @@ $path = array(
     // Operations tag remove
     'operation_tag_remove'=>"ajax_operation_tag",
     // Operations tag select
-    'operation_tag_select'=>"ajax_operation_tag"
+    'operation_tag_select'=>"ajax_operation_tag",
+    // add or update forecast_item
+    "forecast_item"=>"ajax_forecast_item",
+    // add or update forecast_category
+    "forecast_category"=>"ajax_forecast_category",
+    // manage forecast
+    "forecast"=>"ajax_forecast"
 )    ;
 
 if (array_key_exists($op, $path)) {
diff --git a/html/js/forecast.js b/html/js/forecast.js
deleted file mode 100644
index 8195bd1..0000000
--- a/html/js/forecast.js
+++ /dev/null
@@ -1,25 +0,0 @@
-
-/*
- *   This file is part of NOALYSS.
- *
- *   NOALYSS 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.
- *
- *   NOALYSS 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 NOALYSS; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-/* $Revision$ */
-
-// Copyright Author Dany De Bontridder danydb@aevalys.eu
-
-/*!\file
- * \brief 
- */
diff --git a/html/js/managetable.js b/html/js/managetable.js
index 2150671..ba54f18 100644
--- a/html/js/managetable.js
+++ b/html/js/managetable.js
@@ -199,6 +199,7 @@ var ManageTable = function (p_table_name)
             answer['html'] = getNodeText(html[0]);
             return answer;
         } catch (e) {
+            console.error("managetable:parseXML")
             throw e;
         }
     };
diff --git a/include/ajax/ajax_forecast.php b/include/ajax/ajax_forecast.php
new file mode 100644
index 0000000..fc6f204
--- /dev/null
+++ b/include/ajax/ajax_forecast.php
@@ -0,0 +1,77 @@
+<?php
+/*
+*   This file is part of NOALYSS.
+*
+*   NOALYSS 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.
+*
+*   NOALYSS 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 NOALYSS; if not, write to the Free Software
+*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+// Copyright Author Dany De Bontridder danydb@noalyss.eu
+
+require_once NOALYSS_INCLUDE . "/database/forecast_sql.class.php";
+
+$http = new HttpInput();
+$input = $http->request("input");
+$action = $http->request("ieaction", "string", "display");
+
+if ($action == "display") {
+    $ajax = Inplace_Edit::build($input);
+    $f_id = $http->request("f_id", "number");
+
+    $ajax->set_callback("ajax_misc.php");
+    $ajax->add_json_param("op", "forecast");
+    $ajax->add_json_param("gDossier", Dossier::id());
+    $ajax->add_json_param("f_id", $f_id);
+    echo $ajax->ajax_input();
+}
+if ($action == "ok") {
+    $f_id = $http->request("f_id", "number");
+    $ajax = Inplace_Edit::build($input);
+    $ajax->set_callback("ajax_misc.php");
+    $ajax->add_json_param("op", "forecast");
+    $ajax->add_json_param("gDossier", Dossier::id());
+    $ajax->add_json_param("f_id", $f_id);
+
+    $value = $http->request("value");
+    $ajax->set_value($value);
+    $input = $ajax->get_input();
+
+    $data_sql = new Forecast_SQL($cn, $f_id);
+    switch ($input->name) {
+        case 'f_name':
+            $data_sql->setp($input->name, $value);
+            break;
+        case 'p_start':
+            $data_sql->setp("f_start_date", $value);
+            break;
+        case 'p_end':
+            $data_sql->setp("f_end_date", $value);
+            break;
+    }
+
+    $data_sql->update();
+    echo $ajax->value();
+}
+if ($action == "cancel") {
+    $ajax = Inplace_Edit::build($input);
+    $f_id = $http->request("f_id", "number");
+
+    $ajax->set_callback("ajax_misc.php");
+    $ajax->add_json_param("op", "forecast");
+    $ajax->add_json_param("gDossier", Dossier::id());
+    $f_id = $http->request("f_id", "number");
+    $ajax->add_json_param("f_id", $f_id);
+
+    echo $ajax->value();
+}
diff --git a/include/ajax/ajax_forecast_category.php 
b/include/ajax/ajax_forecast_category.php
new file mode 100644
index 0000000..018344b
--- /dev/null
+++ b/include/ajax/ajax_forecast_category.php
@@ -0,0 +1,60 @@
+<?php
+/*
+ *   This file is part of NOALYSS.
+ *
+ *   NOALYSS 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.
+ *
+ *   NOALYSS 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 NOALYSS; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+// Copyright Author Dany De Bontridder danydb@noalyss.eu
+/**
+ *@file
+ *@brief Manage the forecast item
+ */
+
+if (!defined('ALLOWED'))     die('Appel direct ne sont pas permis');
+
+require_once NOALYSS_INCLUDE."/class/forecast_category_mtable.class.php";
+global $g_user;
+
+if ($g_user->check_module("FORECAST")==0) die();
+
+$http=new HttpInput();
+try {
+    $table=$http->request('table');
+    $action=$http->request('action');
+    $p_id=$http->request('p_id', "number");
+    $ctl_id=$http->request('ctl');
+
+} catch(Exception $e) {
+    echo $e->getMessage();
+    return;
+}
+$forecast_category =  Forecast_Category_MTable::build($p_id);
+$forecast_category->set_object_name($ctl_id);
+if ($action=="input")
+{
+    $forecast_category->send_header();
+    $forecast_category->set_forecast_id($http->request("forecast_id"));
+    echo $forecast_category->ajax_input()->saveXML();
+    return;
+}elseif ($action == "save") {
+    $forecast_category->send_header();
+    $forecast_category->set_forecast_id($http->request("forecast_id"));
+    echo $forecast_category->ajax_save()->saveXML();
+    return;
+} elseif ($action == "delete") {
+    $forecast_category->send_header();
+    echo $forecast_category->ajax_delete()->saveXML();
+    return;
+}
\ No newline at end of file
diff --git a/include/ajax/ajax_forecast_item.php 
b/include/ajax/ajax_forecast_item.php
new file mode 100644
index 0000000..5b92b78
--- /dev/null
+++ b/include/ajax/ajax_forecast_item.php
@@ -0,0 +1,59 @@
+<?php
+/*
+ *   This file is part of NOALYSS.
+ *
+ *   NOALYSS 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.
+ *
+ *   NOALYSS 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 NOALYSS; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+// Copyright Author Dany De Bontridder danydb@noalyss.eu
+/**
+ *@file
+ *@brief Manage the forecast item
+ */
+
+if (!defined('ALLOWED'))     die('Appel direct ne sont pas permis');
+
+require_once NOALYSS_INCLUDE."/class/forecast_item_mtable.class.php";
+global $g_user;
+
+if ($g_user->check_module("FORECAST")==0) die();
+
+$http=new HttpInput();
+try {
+    $table=$http->request('table');
+    $action=$http->request('action');
+    $p_id=$http->request('p_id', "number");
+    $ctl_id=$http->request('ctl');
+
+} catch(Exception $e) {
+    echo $e->getMessage();
+    return;
+}
+$forecast_item =  Forecast_Item_MTable::build($p_id);
+$forecast_item->set_object_name($ctl_id);
+if ($action=="input")
+{
+    $forecast_item->send_header();
+    $forecast_item->set_forecast_id($http->request("forecast_id"));
+    echo $forecast_item->ajax_input()->saveXML();
+    return;
+}elseif ($action == "save") {
+    $forecast_item->send_header();
+    echo $forecast_item->ajax_save()->saveXML();
+    return;
+} elseif ($action == "delete") {
+    $forecast_item->send_header();
+    echo $forecast_item->ajax_delete()->saveXML();
+    return;
+}
\ No newline at end of file
diff --git a/include/class/anticipation.class.php 
b/include/class/anticipation.class.php
index 711fda9..67360c1 100644
--- a/include/class/anticipation.class.php
+++ b/include/class/anticipation.class.php
@@ -25,426 +25,286 @@
  *
  */
 /**
- *@brief Manage the anticipation of expense, sales,...
- *@see Forecast Forecast_Cat Forecast_Item
+ * @brief Manage the anticipation of expense, sales,...
+ * @see Forecast Forecast_Cat Forecast_Item
  *
  */
-require_once NOALYSS_INCLUDE.'/class/forecast.class.php';
-require_once NOALYSS_INCLUDE.'/class/forecast_cat.class.php';
-require_once NOALYSS_INCLUDE.'/class/forecast_item.class.php';
-require_once NOALYSS_INCLUDE.'/class/fiche.class.php';
-require_once NOALYSS_INCLUDE.'/class/acc_account_ledger.class.php';
-require_once NOALYSS_INCLUDE.'/class/periode.class.php';
-require_once NOALYSS_INCLUDE.'/lib/impress.class.php';
+require_once NOALYSS_INCLUDE . '/class/forecast.class.php';
+require_once NOALYSS_INCLUDE . '/class/fiche.class.php';
+require_once NOALYSS_INCLUDE . '/class/acc_account_ledger.class.php';
+require_once NOALYSS_INCLUDE . '/class/periode.class.php';
+require_once NOALYSS_INCLUDE . '/lib/impress.class.php';
+require_once NOALYSS_INCLUDE . '/database/forecast_sql.class.php';
+require_once NOALYSS_INCLUDE . '/class/forecast_category_mtable.class.php';
 
 class Anticipation
 {
     /* example private $variable=array("val1"=>1,"val2"=>"Seconde 
valeur","val3"=>0); */
-    private static $variable=array ("id"=>"f_id","name"=>"f_name");
     private $cn;
-    var $cat; /*!< array of object categorie (forecast_cat)*/
+    var $cat; /*!< array of object categorie (forecast_category)*/
     var $item; /*< array of object item (forecast_item) */
+    private $forecast_id; //!< forecast.f_id
+
     /**
      * @brief constructor
      * @param $p_init Database object
      */
-    function __construct ($p_init,$p_id=0)
+    function __construct($p_init, $p_id = 0)
     {
-        $this->cn=$p_init;
-        $this->f_id=$p_id;
+        $this->cn = $p_init;
+        $this->forecast_id = $p_id;
     }
-    public function get_parameter($p_string)
+
+    /**
+     * @return mixed
+     */
+    public function getCat()
     {
-        if ( array_key_exists($p_string,self::$variable) )
-        {
-            $idx=self::$variable[$p_string];
-            return $this->$idx;
-        }
-        else
-            throw new Exception("Attribut inexistant $p_string");
+        return $this->cat;
     }
-    public function set_parameter($p_string,$p_value)
+
+    /**
+     * @param mixed $cat
+     */
+    public function setCat($cat)
     {
-        if ( array_key_exists($p_string,self::$variable) )
-        {
-            $idx=self::$variable[$p_string];
-            $this->$idx=$p_value;
-        }
-        else
-            throw new Exception("Attribut inexistant $p_string");
+        $this->cat = $cat;
+    }
 
+    /**
+     * @return mixed
+     */
+    public function getItem()
+    {
+        return $this->item;
+    }
 
+    /**
+     * @param mixed $item
+     */
+    public function setItem($item)
+    {
+        $this->item = $item;
     }
-    public function get_info()
+
+    /**
+     * @return int|mixed
+     */
+    public function getForecastId()
     {
-        return var_export(self::$variable,true);
+        return $this->forecast_id;
     }
-    public function verify()
+
+    /**
+     * @param int|mixed $forecast_id
+     */
+    public function setForecastId($forecast_id)
     {
-        // Verify that the elt we want to add is correct
-        // the f_name must be unique (case insensitive)
-        return 0;
+        $this->forecast_id = $forecast_id;
     }
-    public function save()
+
+    public function input_title()
     {
-        /* please adapt */
-        if (  $this->get_parameter("id") == 0 )
-            $this->insert();
-        else
-            $this->update();
+        require_once NOALYSS_TEMPLATE . "/anticipation-input_title.php";
     }
 
-    public function insert()
+    public function input_category()
     {
-        if ( $this->verify() != 0 ) return;
+        $visible=uniqid();
+        echo '<h2>';
+        echo _("Catégorie");
+        echo '<span style="margin-left:5em;font-style:normal;font-size:150%">';
+        echo Icon_Action::less($visible, "");
+        echo '</span>';
+        echo '</h2>';
+        
+        echo '<div id="anticipation_input_category" >';
+        $forecast_category = Forecast_Category_MTable::build();
+        $forecast_category->set_forecast_id($this->forecast_id);
+        $forecast_category->display_table(" where f_id = $1"
+            . " order by fc_order",
+            [$this->forecast_id]);
+        echo $forecast_category->create_js_script();
+        echo '</div>';
+        echo <<<EOF
+        <script>
+        var visible=true;
+        var icon=document.getElementById('{$visible}');
+icon.onclick=function () {
+    
+   if ( visible ) { visible = false; 
$("anticipation_input_category").hide();icon.innerHTML="&#xe824;"}
+    else { visible = 
true;$("anticipation_input_category").show();icon.innerHTML="&#xe827;"}
+    }
+</script>
+EOF;
+
     }
 
-    public function update()
-{}
+    /**
+     * @brief  display the detail for the forecast , for modifying item, 
category or name
+     *
+     */
+    public function input_form()
+    {
+        $this->input_title();
+            
+        $this->input_category();
+        $http=new HttpInput();
+        $ac=$http->request("ac");
+        echo h2(_("Eléments"));
+        $forecast_item = Forecast_Item_MTable::build();
+        $forecast_item->set_forecast_id($this->forecast_id);
+        $forecast_item->display_table();
+        echo '<hr>';
+        $href="do.php?".http_build_query(array('ac'=>$ac, 
'sa'=>'vw','gDossier'=>Dossier::id(),'f_id'=>$this->forecast_id));
+        
+        
+        $form=dossier::hidden();
+        $form.=HtmlInput::hidden('action', '');
+        $form.=HtmlInput::hidden('f_id', $this->getForecastId());
+        $form.=HtmlInput::hidden('ac', $ac);
+        
+        echo  '<form method="get" id="form_del" onsubmit="return 
confirm_box(this,content[\'47\'])" style="display:inline">';
+        echo $form;
+        echo HtmlInput::hidden("action","del");
+        echo HtmlInput::submit('del_bt', _('Effacer'));
+        echo '</form>';
+        
+        echo  '<form method="get" id="form_clone" onsubmit="return 
confirm_box(this,content[\'47\']) " style="display:inline" >';
+        echo $form;
+        echo HtmlInput::hidden("action","clone");
+        echo HtmlInput::submit("clone_bt",_("Clone"));
+        echo '</form>';
+        
+        echo HtmlInput::button_anchor(_("Retour"), $href);
+                
+    }
 
-    public function load()
-    {}
     /**
-     *@brief Display the result of the forecast
-     *@param $p_periode
-     *@return HTML String with the code
+     * @brief Display the result of the forecast
+     * @param $p_periode
+     * @return HTML String with the code
      */
     public function display()
     {
-               bcscale(4);
-        $forecast=new Forecast($this->cn,$this->f_id);
+        bcscale(4);
+        $forecast = new Forecast_SQL($this->cn, $this->forecast_id);
         $forecast->load();
-        $str_name=h($forecast->get_parameter('name'));
+        $str_name = h($forecast->getp('f_name'));
 
-       $start=$forecast->get_parameter('start_date');
-       $end=$forecast->get_parameter('end_date');
+        $start = $forecast->getp('f_start_date');
+        $end = $forecast->getp('f_end_date');
 
-       if ( $start=='') throw new Exception (_('Période de début non 
valable'));
-       if ( $end=='') throw new Exception (_('Période de fin non valable'));
+        if ($start == '') throw new Exception (_('Période de début non 
valable'));
+        if ($end == '') throw new Exception (_('Période de fin non valable'));
 
-       $per=new Periode($this->cn,$start);
-       $str_start=format_date($per->first_day());
+        $per = new Periode($this->cn, $start);
+        $str_start = format_date($per->first_day());
 
-       $per=new Periode($this->cn,$end);
-       $str_end=format_date($per->last_day());
+        $per = new Periode($this->cn, $end);
+        $str_end = format_date($per->last_day());
 
 
-        $r="";
-        $aCat=$this->cn->get_array('select fc_id,fc_desc from forecast_cat 
where f_id=$1 order by fc_order',array($this->f_id));
-        $aItem=array();
-        $aReal=array();
-        $poste=new Acc_Account_Ledger($this->cn,0);
-        $fiche=new Fiche($this->cn);
-        $aPeriode=$this->cn->get_array("select p_id,to_char(p_start,'MM.YYYY') 
as myear from parm_periode
+        $r = "";
+        $aCat = $this->cn->get_array('select fc_id,fc_desc from 
forecast_category where f_id=$1 order by fc_order',
+                array($this->forecast_id));
+        $aItem = array();
+        $aReal = array();
+        $poste = new Acc_Account_Ledger($this->cn, 0);
+        $fiche = new Fiche($this->cn);
+        $aPeriode = $this->cn->get_array("select 
p_id,to_char(p_start,'MM.YYYY') as myear from parm_periode
                                         where p_start >= (select p_start from 
parm_periode where p_id=$start)
                                          and p_end <= (select p_end from 
parm_periode where p_id=$end)
                                         order by p_start;");
-       $error=array();
-        for($j=0;$j<count($aCat);$j++)
-        {
-            $aItem[$j]=$this->cn->get_array('select 
fi_card,fi_account,fi_text,fi_amount,fi_debit from forecast_item where fc_id=$1 
 and fi_pid=0 order by fi_order ',array($aCat[$j]['fc_id']));
-            $aPerMonth[$j]=$this->cn->get_array('select 
fi_pid,fi_card,fi_account,fi_text,fi_amount,fi_debit from forecast_item where 
fc_id=$1 and fi_pid !=0 order by fi_order ',array($aCat[$j]['fc_id']));
+        $error = array();
+        for ($j = 0; $j < count($aCat); $j++) {
+            
+            // Item of the category, estimation for a specific month
+            $aItem[$j] = $this->cn->get_array('select 
fi_card,fi_account,fi_text,fi_amount,fi_debit 
+                   from forecast_item where fc_id=$1  and fi_pid=0 order by 
fi_order ', 
+                    array($aCat[$j]['fc_id']));
+            
+            // Item of the category, montly estimation
+            $aPerMonth[$j] = $this->cn->get_array('select 
fi_pid,fi_card,fi_account,fi_text,fi_amount,fi_debit 
+                    from forecast_item where fc_id=$1 and fi_pid !=0 order by 
fi_order ', 
+                    array($aCat[$j]['fc_id']));
 
             /* compute the real amount for periode */
-            for($k=0;$k<count($aItem[$j]);$k++)
-            {
+            for ($k = 0; $k < count($aItem[$j]); $k++) {
                 /* for each periode */
-                for ($l=0;$l<count($aPeriode);$l++)
-                {
-                    if ($aItem[$j][$k]['fi_account']=='')
-                    {
-                        $fiche->id=$aItem[$j][$k]['fi_card'];
-                        $amount=$fiche->get_solde_detail("j_tech_per = 
".$aPeriode[$l]['p_id']);
-                       if ($aItem[$j][$k]['fi_debit']=='C' && 
$amount['debit']>$amount['credit'])  $amount['solde']=$amount["solde"]*(-1);
-                       if ($aItem[$j][$k]['fi_debit']=='D' && 
$amount['debit']<$amount['credit'])  $amount['solde']=$amount["solde"]*(-1);
-
-                    }
-                    else
-                    {
-                        $poste->id=$aItem[$j][$k]['fi_account'];
-                       
$aresult=Impress::parse_formula($this->cn,"OK",$poste->id,$aPeriode[$l]['p_id'],$aPeriode[$l]['p_id']);
-                        $tmp_label=$aresult['desc'];
-                       $amount['solde']=$aresult['montant'];
-
-                       if ( $tmp_label != 'OK') $error[]="<li> 
".$aItem[$j][$k]['fi_text'].$poste->id.'</li>';
+                for ($l = 0; $l < count($aPeriode); $l++) {
+                    if ($aItem[$j][$k]['fi_account'] == '') {
+                        $fiche->id = $aItem[$j][$k]['fi_card'];
+                        $amount = $fiche->get_solde_detail("j_tech_per = " . 
$aPeriode[$l]['p_id']);
+                        
+                        if ($aItem[$j][$k]['fi_debit'] == 'C' && 
$amount['debit'] > $amount['credit']) 
+                        {
+                            $amount['solde'] = $amount["solde"] * (-1);
+                        }
+                        if ($aItem[$j][$k]['fi_debit'] == 'D' && 
$amount['debit'] < $amount['credit']) 
+                        {
+                            $amount['solde'] = $amount["solde"] * (-1);
+                        }
+
+                    } else {
+                        $poste->id = $aItem[$j][$k]['fi_account'];
+                        $aresult = Impress::parse_formula($this->cn, "OK", 
$poste->id, $aPeriode[$l]['p_id'], $aPeriode[$l]['p_id']);
+                        $tmp_label = $aresult['desc'];
+                        $amount['solde'] = $aresult['montant'];
+
+                        if ($tmp_label != 'OK') { 
+                            $error[] = "<li> " . $aItem[$j][$k]['fi_text'] . 
$poste->id . '</li>';
+                        }
                     }
-                    $aReal[$j][$k][$l]=$amount['solde'];
+                    $aReal[$j][$k][$l] = $amount['solde'];
                 }
             }
 
         }
-        ob_start();
-        require_once NOALYSS_TEMPLATE.'/forecast_result.php';
-        $r.=ob_get_contents();
-        ob_end_clean();
+        if ( DEBUGNOALYSS < 2 ) { ob_start(); }
+        require_once NOALYSS_TEMPLATE . '/anticipation-display.php';
+        $r .= ob_get_contents();
+        if ( DEBUGNOALYSS < 2 )  { ob_end_clean(); }
         return $r;
     }
+
     public static function div()
     {
-        $r='<div id="div_anti" style="display:none">';
-        $r.= '</div>';
+        $r = '<div id="div_anti" style="display:none">';
+        $r .= '</div>';
         return $r;
     }
-    public function delete()
-    {}
-    /**
-     *@brief Display a form for modifying the name or/and the category of an 
existing
-     * anticipation
-     *@return html string with the form
-     */
-    private function form_cat_mod()
-    {
-        global $g_user;
-        $a=new Forecast($this->cn,$this->f_id);
-        $a->load();
-        $name=new IText('an_name');
-        $name->value=$a->get_parameter("name");
-        $str_name=$name->input();
-        $str_action=_('Modification');
-
-       $start_date=new IPeriod('start_date');
-       $start_date->type=ALL;
-       $start_date->cn=$this->cn;
-       $start_date->show_end_date=false;
-       $start_date->show_start_date=true;
-       $start_date->user=$g_user;
-       $start_date->filter_year=false;
-
-       $end_date=new IPeriod('end_date');
-       $end_date->type=ALL;
-       $end_date->cn=$this->cn;
-       $end_date->show_end_date=true;
-       $end_date->show_start_date=false;
-       $end_date->user=$g_user;
-       $end_date->filter_year=false;
-
-       $start_date->value=$a->f_start_date;
-       $end_date->value=$a->f_end_date;
-
-       $str_start_date=$start_date->input();
-       $str_end_date=$end_date->input();
 
-
-        $r=HtmlInput::hidden('f_id',$this->f_id);
-        $array=Forecast_Cat::load_all($this->cn,$this->f_id);
-
-        for ($i=0;$i<MAX_CAT;$i++)
-        {
-            /* category name */
-            
$name_name=(isset($array[$i]['fc_id']))?'fr_cat'.$array[$i]['fc_id']:'fr_cat_new'.$i;
-            $name=new IText($name_name);
-            $name->value=(isset 
($array[$i]['fc_desc']))?$array[$i]['fc_desc']:'';
-            $aCat[$i]['name']=$name->input();
-
-
-            /* category order */
-            
$order_name=(isset($array[$i]['fc_id']))?'fc_order'.$array[$i]['fc_id']:'fc_order_new'.$i;
-            $order=new IText($order_name);
-            
$order->value=(isset($array[$i]['fc_order']))?$array[$i]['fc_order']:$i+1;
-            $aCat[$i]['order']=$order->input();
-        }
-
-        ob_start();
-        require_once NOALYSS_TEMPLATE.'/forecast_cat.php';
-        $r.=ob_get_contents();
-        ob_end_clean();
-        return $r;
-    }
     /**
-     *@brief Display a form for adding an new anticipation
-     *@return html string with the form
+     * Clone completely Forecast and returns the new forecast_id
+     * @return type
      */
-    private function form_cat_new()
+    public function object_clone()
     {
-     global $g_user;
-      $r="";
-        $str_action=_('Nouveau');
-
-        $name=new IText('an_name');
-        $str_name=$name->input();
-
-       $start_date=new IPeriod('start_date');
-       $start_date->type=ALL;
-       $start_date->cn=$this->cn;
-       $start_date->show_end_date=false;
-       $start_date->show_start_date=true;
-       $start_date->user=$g_user;
-       $start_date->filter_year=false;
-
-       $end_date=new IPeriod('end_date');
-       $end_date->type=ALL;
-       $end_date->cn=$this->cn;
-       $end_date->show_end_date=true;
-       $end_date->show_start_date=false;
-       $end_date->user=$g_user;
-       $end_date->filter_year=false;
-
-       $period=$g_user->get_periode();
-       $per=new Periode($this->cn,$period);
-       $year=$per->get_exercice();
-
-       list($per_start,$per_end)=$per->get_limit($year);
-       $start_date->value=$per_start->p_id;
-       $end_date->value=$per_end->p_id;
-
-       $str_start_date=$start_date->input();
-       $str_end_date=$end_date->input();
-
-        $aLabel=array(_('Ventes'),_('Dépense'),_('Banque'));
-        $aCat=array();
-
-        for ($i=0;$i<MAX_CAT;$i++)
-        {
-            /* category name */
-            $name=new IText('fr_cat'.$i);
-            $name->value=(isset($aLabel[$i]))?$aLabel[$i]:'';
-            $aCat[$i]['name']=$name->input();
-
-
-            /* category order */
-            $order=new IText('fr_order'.$i);
-            $order->value=$i+1;
-            $aCat[$i]['order']=$order->input();
+        $this->cn->start();
+        /* save into the table forecast */
+        $sql = "insert into forecast(f_name,f_start_date,f_end_date) select 
'clone '||f_name,f_start_date,f_end_date 
+                from forecast 
+                where f_id=$1 returning f_id";
+        $new = $this->cn->get_value($sql, array($this->forecast_id));
+
+        /* save into forecast_cat */
+        $sql = "insert into forecast_category(fc_desc,f_id,fc_order) 
+                select fc_desc,$1,fc_order 
+                from forecast_category
+                where f_id=$2 returning fc_id";
+        $array = $this->cn->get_array($sql, array($new, $this->forecast_id));
+
+        $old = $this->cn->get_array("select fc_id from forecast_category where 
f_id=$1", array($this->forecast_id));
+        /* save into forecast_item */
+        for ($i = 0; $i < count($array); $i++) {
+            $this->cn->exec_sql("insert into forecast_item 
(fi_text,fi_account,fi_card,fi_order,fc_id,
+                           fi_amount,fi_debit,fi_pid) " .
+                " select 
fi_text,fi_account,fi_card,fi_order,$1,fi_amount,fi_debit,fi_pid " .
+                " from forecast_item where fc_id=$2", 
array($array[$i]['fc_id'], $old[$i]['fc_id']));
         }
-
-        ob_start();
-        require_once NOALYSS_TEMPLATE.'/forecast_cat.php';
-        $r.=ob_get_contents();
-        ob_end_clean();
-        return $r;
-
-    }
-    /**
-     * @brief create an empty object anticipation
-     * @return html string with the form
-     */
-    public  function form_cat()
-    {
-        if ($this->f_id != 0)
-            return $this->form_cat_mod();
-        else
-            return $this->form_cat_new();
-    }
-    /**
-     *@brief display a form for modifying or add a forecast
-     *@return HTML code
-     */
-    public function form_item()
-    {
-        $forecast=new Forecast($this->cn,$this->f_id);
-        $forecast->load();
-        $str_name=$forecast->get_parameter('name');
-        $str_start=$forecast->get_parameter('start_date');
-        $str_end=$forecast->get_parameter('end_date');
-
-
-        $r="";
-        $str_action=_("Elements");
-        $cat=new Forecast_Cat($this->cn);
-        $array=$cat->make_array($this->f_id);
-        $periode=new Periode($this->cn);
-        $aPeriode=$this->cn->make_array("select 
p_id,to_char(p_start,'MM.YYYY') as label from parm_periode
-                                  where p_start >= (select p_start from 
parm_periode where p_id=$str_start)
-                                   and p_end <= (select p_end from 
parm_periode where p_id=$str_end)
-                                  order by p_start");
-        $aPeriode[]=array('value'=>0,'label'=>'Mensuel');
-        $value=$this->cn->get_array("select 
fi_id,fi_text,fi_account,fi_card,fc_id,fi_amount,fi_debit,fi_pid ".
-                                    " from forecast_item ".
-                                    "  where fc_id in (select fc_id from 
forecast_cat where f_id = $1)",array($this->f_id));
-        $max=(count($value) < 
MAX_FORECAST_ITEM)?MAX_FORECAST_ITEM:count($value);
-        $r.=HtmlInput::hidden('nbrow',$max);
-
-        for ($i=0;$i<$max;$i++)
-        {
-            if (isset($value[$i]['fi_id']))
-            {
-                $r.=HtmlInput::hidden('fi_id'.$i,$value[$i]['fi_id']);
-            }
-            /* category*/
-            $category=new ISelect();
-            $category->name='an_cat'.$i;
-            $category->value=$array;
-            
$category->selected=(isset($value[$i]["fc_id"]))?$value[$i]["fc_id"]:-1;
-            $aCat[$i]['cat']=$category->input();
-
-            /* amount   */
-            $amount=new INum('an_cat_amount'.$i);
-            
$amount->value=(isset($value[$i]["fi_amount"]))?$value[$i]["fi_amount"]:0;
-            $aCat[$i]['amount']=$amount->input();
-
-            /* Accounting*/
-            $account=new IPoste('an_cat_acc'.$i);
-            $account->set_attribute('ipopup','ipop_account');
-           //            $account->set_attribute('label','an_label'.$i);
-            $account->set_attribute('account','an_cat_acc'.$i);
-           $account->set_attribute('bracket',1);
-           $account->set_attribute('no_overwrite',1);
-           $account->set_attribute('noquery',1);
-           $account->css_size="85%";
-            
$account->value=(isset($value[$i]["fi_account"]))?$value[$i]["fi_account"]:"";
-            $aCat[$i]['account']=$account->input();
-            /*Quick Code */
-            $qc=new ICard('an_qc'.$i);
-            // If double click call the javascript fill_ipopcard
-            $qc->set_dblclick("fill_ipopcard(this);");
-
-            // This attribute is mandatory, it is the name of the IPopup
-            $qc->set_attribute('ipopup','ipopcard');
-
-            // name of the field to update with the name of the card
-            $qc->set_attribute('label','an_label'.$i);
-
-            // Type of card : all
-            $qc->set_attribute('typecard','all');
-            $qc->set_attribute('jrn',0);
-            $qc->extra='all';
-
-            // when value selected in the autcomplete
-            $qc->set_function('fill_data');
-            if (isset($value[$i]["fi_card"]))
-            {
-                $f=new Fiche($this->cn,$value[$i]["fi_card"]);
-                $qc->value=$f->strAttribut(ATTR_DEF_QUICKCODE);
-                ;
-            }
-
-            $aCat[$i]['qc']=$qc->search().$qc->input();
-            /* Label */
-            $label=new IText('an_label'.$i);
-            
$label->value=(isset($value[$i]["fi_text"]))?$value[$i]["fi_text"]:"";
-            $aCat[$i]['name']=$label->input();
-
-            //Deb or Cred
-            $deb=new ISelect('an_deb'.$i);
-            
$deb->selected=(isset($value[$i]["fi_debit"]))?$value[$i]["fi_debit"]:-1;
-            $deb->value=array(array('value'=>'D','label'=>_('Débit')),
-                              array('value'=>'C','label'=>_('Crédit'))
-                             );
-            $aCat[$i]['deb']=$deb->input();
-            //Periode
-            $isPeriode=new ISelect('month'.$i);
-            $isPeriode->value=$aPeriode;
-            
$isPeriode->selected=(isset($value[$i]["fi_pid"]))?$value[$i]["fi_pid"]:0;
-            $aCat[$i]['per']=$isPeriode->input();
-        }
-        $add_row=new IButton('add_row');
-        $add_row->label=_('Ajouter une ligne');
-        $add_row->javascript='for_add_row(\'fortable\')';
-        $f_add_row=$add_row->input();
-        ob_start();
-        require_once NOALYSS_TEMPLATE.'/forecast-detail.php';
-        $r.=ob_get_contents();
-        ob_end_clean();
-        return $r;
-    }
-    /**
-     * @brief unit test
-     */
-    static function test_me()
-    {
-        $cn=Dossier::connect();
-        $test=new Anticipation($cn);
-
+        $this->cn->commit();
+        return $new;
     }
 
 }
diff --git a/include/class/forecast_cat.class.php 
b/include/class/forecast_cat.class.php
deleted file mode 100644
index 2b7188e..0000000
--- a/include/class/forecast_cat.class.php
+++ /dev/null
@@ -1,172 +0,0 @@
-<?php
-/*
- *   This file is part of NOALYSS.
- *
- *   NOALYSS 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.
- *
- *   NOALYSS 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 NOALYSS; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-// Copyright Author Dany De Bontridder danydb@aevalys.eu
-
-/**
-* @file
- * @brief  manage the table forecast_cat, this table contains the categories 
of forecast
- *  as expense, asset, sales...
- */
-/**
- *@brief this class is called normally from forecast, a forecast contains 
category
- * like sales, expenses, each category contains items
- *@see Forecast
- *
- */
-class Forecast_Cat
-{
-    /* example private $variable=array("val1"=>1,"val2"=>"Seconde 
valeur","val3"=>0); */
-    private static $variable=array 
("id"=>"fc_id","order"=>"fc_order","desc"=>"fc_desc","forecast"=>"f_id");
-    private $cn;
-    /**
-     * @brief constructor
-     * @param $p_init Database object
-     */
-    function __construct ($p_init,$p_id=0)
-    {
-        $this->cn=$p_init;
-        $this->fc_id=$p_id;
-    }
-    public function get_parameter($p_string)
-    {
-        if ( array_key_exists($p_string,self::$variable) )
-        {
-            $idx=self::$variable[$p_string];
-            return $this->$idx;
-        }
-        else
-           throw new Exception("Attribut inexistant $p_string");
-    }
-    public function set_parameter($p_string,$p_value)
-    {
-        if ( array_key_exists($p_string,self::$variable) )
-        {
-            $idx=self::$variable[$p_string];
-            $this->$idx=$p_value;
-        }
-        else
-          throw new Exception("Attribut inexistant $p_string");
-
-
-    }
-    public function get_info()
-    {
-        return var_export(self::$variable,true);
-    }
-    public function verify()
-    {
-        if (strlen(trim($this->fc_order))==0)
-        {
-            $this->fc_order="1";
-        }
-        // Verify that the elt we want to add is correct
-        // the f_name must be unique (case insensitive)
-        return 0;
-    }
-    public function save()
-    {
-        if (  $this->get_parameter("id") == 0 )
-            $this->insert();
-        else
-            $this->update();
-    }
-
-    public function insert()
-    {
-        if ( $this->verify() != 0 ) return;
-
-        $sql="insert into forecast_cat (fc_desc,fc_order,f_id) ".
-             " values ($1,$2,$3)  returning fc_id";
-        $res=$this->cn->exec_sql(
-                 $sql,
-                 array($this->fc_desc,$this->fc_order,$this->f_id)
-             );
-        $this->fc_id=Database::fetch_result($res,0,0);
-    }
-
-    public function update()
-    {
-        if ( $this->verify() != 0 ) return;
-
-        $sql="update forecast_cat set fc_desc=$1,f_id=$2,fc_order=$3 ".
-             " where fc_id = $4";
-        $res=$this->cn->exec_sql(
-                 $sql,
-                 array($this->fc_desc,$this->f_id, 
$this->fc_order,$this->fc_id)
-             );
-    }
-    /**
-     *@brief Load all the cat. for a given forecast and return them into a 
array
-     *@param $p_cn database connx
-     *@param $p_id is the forecast id (f_id)
-     *@return an array with all the data
-     */
-    public static function load_all($p_cn,$p_id)
-    {
-        $sql="select fc_id,fc_desc,fc_order from forecast_cat where f_id=$1";
-
-        $res=$p_cn->get_array($sql,array($p_id));
-
-        return $res;
-    }
-    public function load()
-    {
-
-        $sql="select fc_desc, f_id,fc_order from forecast_cat where fc_id=$1";
-
-        $res=$this->cn->exec_sql(
-                 $sql,
-                 array($this->fc_id)
-             );
-
-        if ( Database::num_row($res) == 0 ) return;
-        $row=Database::fetch_array($res,0);
-        foreach ($row as $idx=>$value)
-        {
-            $this->$idx=$value;
-        }
-
-    }
-    /**
-     *@brief Make a array for a ISelect of the available cat
-     *@param $id is forecast::f_id
-     *@return array for ISelect
-     *@see ISelect
-     */
-    public function make_array($id)
-    {
-        $sql="select fc_id,fc_desc from forecast_cat where f_id=$id";
-        $ret=$this->cn->make_array($sql);
-        return $ret;
-    }
-    public function delete()
-    {
-        $sql="delete from forecast_cat where fc_id=$1";
-        $res=$this->cn->exec_sql($sql,array($this->fc_id));
-    }
-    /**
-     * @brief unit test
-     */
-    static function test_me()
-    {}
-
-}
-
-?>
\ No newline at end of file
diff --git a/include/class/forecast_category_mtable.class.php 
b/include/class/forecast_category_mtable.class.php
new file mode 100644
index 0000000..983190f
--- /dev/null
+++ b/include/class/forecast_category_mtable.class.php
@@ -0,0 +1,118 @@
+<?php
+
+/*
+ *   This file is part of NOALYSS.
+ *
+ *   NOALYSS 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.
+ *
+ *   NOALYSS 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 NOALYSS; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+// Copyright Author Dany De Bontridder danydb@aevalys.eu
+
+/**
+ * \file
+ * \brief display, add, delete and modify forecast category
+ *
+ */
+
+require_once NOALYSS_INCLUDE."/database/forecast_category_sql.class.php";
+require_once NOALYSS_INCLUDE."/lib/manage_table_sql.class.php";
+
+class Forecast_Category_MTable extends Manage_Table_SQL
+{
+    private $forecast_id;
+    public function __construct(Data_SQL $p_table)
+    {
+        parent::__construct($p_table);
+        $this->forecast_id=-1;
+    }
+    static function  build($p_id=-1)
+    {
+        $cn=Dossier::connect();
+        $forecast_category_sql=new Forecast_Category_SQL($cn,$p_id);
+        $forecast_category=new 
Forecast_Category_MTable($forecast_category_sql);
+        $forecast_category->add_json_param("ac",'FORECAST');
+        $forecast_category->add_json_param("op",'forecast_category');
+        $forecast_category->set_callback("ajax_misc.php");
+        $forecast_category->set_col_label("fc_desc", _("Nom"));
+        $forecast_category->set_col_label("fc_order", _("Ordre"));
+        $forecast_category->set_col_type("fc_order","numeric");
+        $forecast_category->set_sort_column("fc_order");
+        $forecast_category->set_col_type("fc_order","numeric");
+        $forecast_category->set_button_add_top(false);
+        $forecast_category->set_order(["fc_order","fc_desc"]);
+        if ( $p_id != -1 ) {
+            $forecast_id=$cn->get_value("select f_id 
+                            from 
+                                 forecast_category fc 
+                            where 
+                            fc_id=$1",array($p_id));
+            $forecast_category->set_forecast_id($forecast_id);
+        }
+        return $forecast_category;
+    }
+    /**
+     * @return int
+     */
+    public function get_forecast_id(): int
+    {
+        return $this->forecast_id;
+    }
+
+    /**
+     * @param int $forecast_id
+     */
+    public function set_forecast_id($forecast_id)
+    {
+        $this->forecast_id = $forecast_id;
+        $this->add_json_param("forecast_id", $forecast_id);
+        $this->get_table()->setp("f_id",$forecast_id);
+    }
+
+    function input()
+    {
+        parent::input();
+        $cn=$this->get_table()->cn;
+        $nb_element=$cn->get_value("select count(*) from forecast_item where 
fc_id=$1",
+                [$this->get_table()->getp("fc_id")]);
+        printf(_("Utilisation %s"),$nb_element);
+        echo '<p></p>';
+    }
+
+    function check()
+    {
+        $err=0;
+         $cn=$this->get_table()->cn;
+        $object=$this->get_table();
+        if (trim ($object->getp("fc_desc") ) == "" ) {
+            $this->set_error("fc_desc", _("Nom ne peut être vide"));
+            $err++;
+        }
+        $dupl=$cn->get_value("select count(*) from forecast_category 
+                 where 
+                 upper(replace (fc_desc,' ',''))= upper(replace ($2,' ',''))  
+                 and fc_id != $1 and 
f_id=$3",[$object->fc_id,$object->fc_desc,$this->forecast_id]);
+        
+        if ( $dupl > 0) {
+            $this->set_error("fc_desc", _("Ce nom existe déjà"));
+            $err++;
+        }
+        if ( trim($object->fc_order) =='') {
+            $object->fc_order=$cn->get_value("select max(fc_order) from 
forecast_category where f_id=$1",
+                    [$object->f_id])+10;
+        }
+        if ( $err > 0 ) { return false;}
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/include/class/forecast_item.class.php 
b/include/class/forecast_item.class.php
deleted file mode 100644
index 0081532..0000000
--- a/include/class/forecast_item.class.php
+++ /dev/null
@@ -1,165 +0,0 @@
-<?php
-/*
- *   This file is part of NOALYSS.
- *
- *   NOALYSS 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.
- *
- *   NOALYSS 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 NOALYSS; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-// Copyright Author Dany De Bontridder danydb@aevalys.eu
-
-/**
-* @file
- * @brief manage the table forecast_item  contains the items, the item are 
part of category of forecast_cat, which are
- *  part of Forecast
- */
-/**
- *@brief manage the table forecast_item  contains the items, the item are part 
of category of forecast_cat, which are
- *  part of Forecast
- * @see Forecast Forecast_Cat
- *
- *
- */
-class Forecast_Item
-{
-    /* example private $variable=array("val1"=>1,"val2"=>"Seconde 
valeur","val3"=>0); */
-    private static $variable=array 
("id"=>"fi_id","text"=>"fi_text","account"=>"fi_account",
-                                    
"card"=>"fi_card","order"=>"fi_order","cat_id"=>"fc_id","amount"=>"fi_amount","debit"=>"fi_debit","periode"=>"fi_pid");
-    private $cn;
-    /**
-     * @brief constructor
-     * @param $p_init Database object
-     */
-    function __construct ($p_init,$p_id=0)
-    {
-        $this->cn=$p_init;
-        $this->fi_id=$p_id;
-    }
-    public function get_parameter($p_string)
-    {
-        if ( array_key_exists($p_string,self::$variable) )
-        {
-            $idx=self::$variable[$p_string];
-            return $this->$idx;
-        }
-        else
-            throw new Exception("Attribut inexistant $p_string");
-    }
-    public function set_parameter($p_string,$p_value)
-    {
-        if ( array_key_exists($p_string,self::$variable) )
-        {
-            $idx=self::$variable[$p_string];
-            $this->$idx=$p_value;
-        }
-        else
-        throw new Exception("Attribut inexistant $p_string");
-
-
-    }
-    public function get_info()
-    {
-        return var_export(self::$variable,true);
-    }
-    public function verify()
-    {
-               $this->fi_account=  str_replace(" ", "", $this->fi_account);
-        // Verify that the elt we want to add is correct
-        // the f_name must be unique (case insensitive)
-        return 0;
-    }
-    public function save()
-    {
-        /* please adapt */
-        if (  $this->get_parameter("id") == 0 )
-            $this->insert();
-        else
-            $this->update();
-    }
-
-    public function insert()
-    {
-        if ( $this->verify() != 0 ) return;
-
-        $sql="INSERT INTO forecast_item(
-             fi_text, fi_account, fi_card, fi_order, fc_id, fi_amount,
-             fi_debit,fi_pid)
-             VALUES ($1, $2, $3, $4, $5, $6, $7,$8) returning fi_id;";
-        $res=$this->cn->exec_sql(
-                 $sql,
-                 
array($this->fi_text,$this->fi_account,$this->fi_card,$this->fi_order,$this->fc_id,$this->fi_amount,$this->fi_debit,$this->fi_pid)
-             );
-        $this->fi_id=Database::fetch_result($res,0,0);
-    }
-
-    public function update()
-    {
-        if ( $this->verify() != 0 ) return;
-
-        $sql="UPDATE forecast_item
-             SET  fi_text=$1, fi_account=$2, fi_card=$3, fi_order=$4, fc_id=$5,
-             fi_amount=$6, fi_debit=$7,fi_pid=$8
-             WHERE fi_id=$9;";
-        $res=$this->cn->exec_sql($sql,
-                                 array($this->fi_text,
-                                       $this->fi_account,
-                                       $this->fi_card,
-                                       $this->fi_order,
-                                       $this->fc_id,
-                                       $this->fi_amount,
-                                       $this->fi_debit,
-                                       $this->fi_pid,
-                                       $this->fi_id)
-                                );
-
-    }
-
-    public function load()
-    {
-
-        $sql="SELECT fi_id, fi_text, fi_account, fi_card, fi_order, fc_id, 
fi_amount,
-             fi_debit,fi_pid
-             FROM forecast_item where fi_id=$1";
-
-        $res=$this->cn->exec_sql(
-                 $sql,
-                 array($this->fi_id)
-             );
-
-        if ( Database::num_row($res) == 0 ) return;
-        $row=Database::fetch_array($res,0);
-        foreach ($row as $idx=>$value)
-        {
-            $this->$idx=$value;
-        }
-
-    }
-
-
-
-
-    public function delete()
-    {
-        $sql="delete from forecast_item where fi_id=$1";
-        $res=$this->cn->exec_sql($sql,array($this->fi_id));
-    }
-    /**
-     * @brief unit test
-     */
-    static function test_me()
-    {}
-
-}
-
-?>
\ No newline at end of file
diff --git a/include/class/forecast_item_mtable.class.php 
b/include/class/forecast_item_mtable.class.php
new file mode 100644
index 0000000..f659134
--- /dev/null
+++ b/include/class/forecast_item_mtable.class.php
@@ -0,0 +1,200 @@
+<?php
+/*
+*   This file is part of NOALYSS.
+*
+*   NOALYSS 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.
+*
+*   NOALYSS 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 NOALYSS; if not, write to the Free Software
+*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+// Copyright Author Dany De Bontridder danydb@noalyss.eu
+
+/**
+ * @file
+ * @brief display the item for forecast
+ */
+
+
+/**
+ * @file
+ * @brief display the item for forecast
+ */
+
+require_once NOALYSS_INCLUDE . "/lib/manage_table_sql.class.php";
+require_once NOALYSS_INCLUDE . "/database/forecast_item_sql.class.php";
+require_once NOALYSS_INCLUDE . "/database/forecast_sql.class.php";
+
+class Forecast_Item_MTable extends Manage_Table_SQL
+{
+    private $forecast_id;
+
+    public function __construct(Data_SQL $p_table)
+    {
+        parent::__construct($p_table);
+        $this->forecast_id = -1;
+    }
+
+    static function build($p_id = -1)
+    {
+        $cn = Dossier::connect();
+        $forecast_sql = new Forecast_Item_SQL($cn, $p_id);
+        $forecast_item = new Forecast_Item_MTable($forecast_sql);
+        $forecast_item->add_json_param('ac', 'FORECAST');
+        $forecast_item->add_json_param("op", "forecast_item");
+        $forecast_item->set_callback("ajax_misc.php");
+        if ( $p_id != -1 ) {
+            $forecast_id=$cn->get_value("select f_id 
+                            from forecast_item fi
+                                join forecast_category fc on 
(fi.fc_id=fc.fc_id) 
+                            where 
+                            fi_id=$1",array($p_id));
+            $forecast_item->set_forecast_id($forecast_id);
+        }
+        return $forecast_item;
+
+    }
+
+    /**
+     * @return int
+     */
+    public function get_forecast_id(): int
+    {
+        return $this->forecast_id;
+    }
+
+    /**
+     * @param int $forecast_id
+     */
+    public function set_forecast_id(int $forecast_id): void
+    {
+        $this->forecast_id = $forecast_id;
+        $this->add_json_param("forecast_id", $forecast_id);
+    }
+    function count_category()
+    {
+        $object=$this->get_table();
+        $nCategory = $object->cn->get_value("select count(*) from 
forecast_category where f_id=$1",[$this->forecast_id]);
+        return $nCategory;
+        
+    }
+    /**
+     * Display list of items, if there is no category the list is empty and 
you cannot add new ones
+     * @param type $p_string
+     * @param type $p_array
+     */
+    public function display_table($p_string = "", $p_array = NULL)
+    {
+        
+        $sql = "select fi_id,fi_text,fi_account,
+                case when fi_card is null then fi_account 
+                    else  (select ad_value from fiche_detail where ad_id=23 
and f_id=fi_card) end str_account_card,
+                fc_desc,
+                fi_card,
+                fi.fi_amount ,
+                (select p_start from parm_periode pp where pp.p_id=fi.fi_pid) 
as str_periode
+                from forecast_item fi join forecast_category fc on 
(fi.fc_id=fc.fc_id)
+                where fc.f_id =$1
+                order by fc_desc,fi_text ";
+        $a_row = $this->get_table()->cn->get_array($sql, 
array($this->forecast_id));
+        require_once NOALYSS_TEMPLATE . 
"/forecast_item_mtable-display_table.php";
+    }
+
+    public function display_row($p_row)
+    {
+        if ( ! isset($p_row['fc_desc'])) {
+            $cn=$this->get_table()->cn;
+         $sql=   "select fi_id,fi_text,fi_account,
+                case when fi_card is null then fi_account 
+                    else  (select ad_value from fiche_detail where ad_id=23 
and f_id=fi_card) end str_account_card,
+                fc_desc,
+                fi_card,
+                fi.fi_amount ,
+                (select p_start from parm_periode pp where pp.p_id=fi.fi_pid) 
as str_periode
+                from forecast_item fi join forecast_category fc on 
(fi.fc_id=fc.fc_id)
+                where fi_id=$1";
+            $p_row=$cn->get_row($sql,[$p_row['fi_id']]);
+
+        }
+        if ( ! isset ($p_row['str_account_card'])) {
+            $p_row['str_account_card']="";
+        }
+        if ( !isset ($p_row['str_periode'])){
+            $p_row['str_periode']="";
+        }
+        printf('<tr  id="%s_%s">', $this->object_name, $p_row['fi_id']);
+        print td($p_row['fc_desc']);
+        print td($p_row['fi_text']);
+        print td($p_row['str_account_card']);
+        print td(nbm($p_row['fi_amount']));
+        print td($p_row['str_periode']);
+
+
+        $jsdel = sprintf("%s.remove('%s','%s');",
+            $this->object_name,
+            $p_row['fi_id'],
+            $this->object_name
+        );
+        $jsupd = sprintf("%s.input('%s','%s');",
+            $this->object_name,
+            $p_row['fi_id'],
+            $this->object_name
+        );
+        echo '<td>' . Icon_Action::modify(uniqid(), $jsupd);
+        echo '</td>';
+        echo '<td>';
+        echo Icon_Action::trash(uniqid(), $jsdel);
+        echo '</td>';
+        echo '</tr>';
+
+    }
+
+    public function input()
+    {
+        $object=$this->get_table();
+        require_once NOALYSS_TEMPLATE."/forecast_item_mtable-input.php";
+    }
+
+    /**
+     * forecast_id: 14
+    p_id: 143
+    action: save
+    ctl: tbl6058da883ded6
+    fc_id: 88
+    fi_text: Gérant
+    fi_card:
+    fi_account: [4160%]-[4890%]
+    fi_amount: 3000.0000
+    fi_pid: 0
+     */
+    public function from_request()
+    {
+        $http=new HttpInput();
+        $this->set_forecast_id($http->post("forecast_id","number"));
+        $object_sql=$this->get_table();
+        $object_sql->setp("fi_text",$http->post("fi_text"));
+        $object_sql->setp("fc_id",$http->post('fc_id',"number"));
+        $object_sql->setp("fi_account",$http->post('fi_account'));
+        $object_sql->setp("fi_amount",$http->post('fi_amount',"number"));
+        $object_sql->setp("fi_pid",$http->post('fi_pid',"number"));
+        $object_sql->setp("fi_debit",$http->post('fi_debit'));
+        $card=trim($http->post("fi_card"));
+        if ( $card !="") {
+            $f_id=$object_sql->cn->get_value("select f_id from fiche_detail 
where ad_value=upper($1) and ad_id=23",[$card]);
+            if ( $f_id !="") {
+                $object_sql->setp("fi_card",$f_id);
+            }
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git a/include/database/forecast_category_sql.class.php 
b/include/database/forecast_category_sql.class.php
new file mode 100644
index 0000000..f35594f
--- /dev/null
+++ b/include/database/forecast_category_sql.class.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * Autogenerated file
+ *   This file is part of NOALYSS.
+ *
+ *   NOALYSS 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.
+ *
+ *   NOALYSS 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 NOALYSS; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+require_once NOALYSS_INCLUDE . '/lib/noalyss_sql.class.php';
+require_once NOALYSS_INCLUDE . '/class/database.class.php';
+
+
+/**
+ * class_forecast_category_sql.php
+ *
+ * @file
+ * @brief abstract of the table public.forecast_category
+ */
+class Forecast_Category_SQL extends Noalyss_SQL
+{
+
+    function __construct(DatabaseCore $p_cn, $p_id = -1)
+    {
+        $this->table = "public.forecast_category";
+        $this->primary_key = "fc_id";
+        /*
+         * List of columns
+         */
+        $this->name = array(
+            "fc_id" => "fc_id"
+        , "fc_desc" => "fc_desc"
+        , "f_id" => "f_id"
+        , "fc_order" => "fc_order"
+        );
+        /*
+         * Type of columns
+         */
+        $this->type = array(
+            "fc_id" => "numeric"
+        , "fc_desc" => "text"
+        , "f_id" => "numeric"
+        , "fc_order" => "numeric"
+        );
+
+
+        $this->default = array(
+            "fc_id" => "auto"
+        );
+
+        $this->date_format = "DD.MM.YYYY";
+        parent::__construct($p_cn, $p_id);
+    }
+
+
+}
\ No newline at end of file
diff --git a/include/database/forecast_item_sql.class.php 
b/include/database/forecast_item_sql.class.php
new file mode 100644
index 0000000..a86063a
--- /dev/null
+++ b/include/database/forecast_item_sql.class.php
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * Autogenerated file
+ *   This file is part of NOALYSS.
+ *
+ *   NOALYSS 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.
+ *
+ *   NOALYSS 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 NOALYSS; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+require_once NOALYSS_INCLUDE . '/lib/noalyss_sql.class.php';
+require_once NOALYSS_INCLUDE . '/class/database.class.php';
+
+
+/**
+ * class_forecast_item_sql.php
+ *
+ * @file
+ * @brief abstract of the table public.forecast_item
+ */
+class Forecast_Item_SQL extends Noalyss_SQL
+{
+
+    function __construct(DatabaseCore $p_cn, $p_id = -1)
+    {
+        $this->table = "public.forecast_item";
+        $this->primary_key = "fi_id";
+        /*
+         * List of columns
+         */
+        $this->name = array(
+            "fi_id" => "fi_id"
+        , "fi_text" => "fi_text"
+        , "fi_account" => "fi_account"
+        , "fi_card" => "fi_card"
+        , "fi_order" => "fi_order"
+        , "fc_id" => "fc_id"
+        , "fi_amount" => "fi_amount"
+        , "fi_debit" => "fi_debit"
+        , "fi_pid" => "fi_pid"
+        );
+        /*
+         * Type of columns
+         */
+        $this->type = array(
+            "fi_id" => "numeric"
+        , "fi_text" => "text"
+        , "fi_account" => "text"
+        , "fi_card" => "numeric"
+        , "fi_order" => "numeric"
+        , "fc_id" => "numeric"
+        , "fi_amount" => "numeric"
+        , "fi_debit" => "char"
+        , "fi_pid" => "numeric"
+        );
+
+
+        $this->default = array(
+            "fi_id" => "auto"
+        );
+
+        $this->date_format = "DD.MM.YYYY";
+        parent::__construct($p_cn, $p_id);
+    }
+
+
+}
\ No newline at end of file
diff --git a/include/database/forecast_sql.class.php 
b/include/database/forecast_sql.class.php
new file mode 100644
index 0000000..31e5153
--- /dev/null
+++ b/include/database/forecast_sql.class.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * Autogenerated file
+ *   This file is part of NOALYSS.
+ *
+ *   NOALYSS 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.
+ *
+ *   NOALYSS 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 NOALYSS; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+require_once NOALYSS_INCLUDE . '/lib/noalyss_sql.class.php';
+require_once NOALYSS_INCLUDE . '/class/database.class.php';
+
+
+/**
+ * class_forecast_sql.php
+ *
+ * @file
+ * @brief abstract of the table public.forecast
+ */
+class Forecast_SQL extends Noalyss_SQL
+{
+
+    function __construct(DatabaseCore $p_cn, $p_id = -1)
+    {
+        $this->table = "public.forecast";
+        $this->primary_key = "f_id";
+        /*
+         * List of columns
+         */
+        $this->name = array(
+            "f_id" => "f_id"
+        , "f_name" => "f_name"
+        , "f_start_date" => "f_start_date"
+        , "f_end_date" => "f_end_date"
+        );
+        /*
+         * Type of columns
+         */
+        $this->type = array(
+            "f_id" => "numeric"
+        , "f_name" => "text"
+        , "f_start_date" => "numeric"
+        , "f_end_date" => "numeric"
+        );
+
+
+        $this->default = array(
+            "f_id" => "auto"
+        );
+
+        $this->date_format = "DD.MM.YYYY";
+        parent::__construct($p_cn, $p_id);
+    }
+
+
+}
\ No newline at end of file
diff --git a/include/forecast.inc.php b/include/forecast.inc.php
index 80e716f..86791c8 100644
--- a/include/forecast.inc.php
+++ b/include/forecast.inc.php
@@ -1,5 +1,4 @@
 <?php
-
 /*
  *   This file is part of NOALYSS.
  *
@@ -20,307 +19,100 @@
 
 // Copyright Author Dany De Bontridder danydb@aevalys.eu
 
-/**\file
+/**
+ * \file
  * \brief display, add, delete and modify forecast
  */
+if (!defined('ALLOWED'))
+    die('Appel direct ne sont pas permis');
 
-if ( ! defined ('ALLOWED') ) die('Appel direct ne sont pas permis');
 require_once NOALYSS_INCLUDE.'/class/anticipation.class.php';
+require_once NOALYSS_INCLUDE."/database/forecast_sql.class.php";
+require_once NOALYSS_INCLUDE."/database/forecast_item_sql.class.php";
+require_once NOALYSS_INCLUDE."/database/forecast_category_sql.class.php";
+require_once NOALYSS_INCLUDE."/class/forecast_item_mtable.class.php";
+
+
 global $http;
-$action=$http->get("action","string","");
+
+$action=$http->get("action", "string", "");
+$ac=$http->request("ac");
+$forecast_id=$http->request('f_id', 'number',-1);
 
 echo '<div class="content">';
-$sa=$http->request("sa","string","list");
+$sa=$http->request("sa", "string", "list");
 /* * ********************************************************************
  * Remove a anticipation
  *
  *
  * ******************************************************************** */
-if ( $action == 'del' )
+if ($action=='del')
 {
-    $f_id=$http->get("f_id","number");
-    $forecast = new Forecast($cn, $f_id);
+    $f_id=$http->get("f_id", "number");
+    $forecast=new Forecast_SQL($cn, $f_id);
     $forecast->delete();
 }
-/*
+/* * *******************************************************************
  * Cloning
- */
-if ( $action == 'clone' )
+ * ******************************************************************* */
+if ($action=='clone')
 {
     echo "<h2> cloning</h2>";
     /*
      * We need to clone the forecast
      */
-    $f_id=$http->get("f_id","number");
-    $anti = new Forecast($cn, $f_id);
-    $anti->object_clone();
-    $sa="list";
+    $f_id=$http->get("f_id", "number");
+    $anti=new Anticipation($cn, $f_id);
+    $forecast_id=$anti->object_clone();
+    $action="mod_view";
 }
-/* * ********************************************************************
- * Save the modification mod_cat_save
- *
- *
- * ******************************************************************** */
-if (isset($_POST['mod_cat_save']))
-{
-    /*
-     * We save the forecast
-     */
-    $f_id=$http->post("f_id","number");
-    $an_name=$http->post("an_name");
-    $start_date=$http->post("start_date");
-    $end_date=$http->post("end_date");
-    $anti = new Forecast($cn,$f_id);
-    try
-    {
-       $cn->start();
-       /* Save forecast */
-       $anti->set_parameter('name', $an_name);
-       $anti->set_parameter('start_date', $start_date);
-       $anti->set_parameter('end_date', $end_date);
 
-       $anti->save();
-
-       /* add new category */
-       for ($i = 0; $i < MAX_CAT; $i++)
-       {
-           if (isset($_POST['fr_cat_new' . $i]))
-           {
-                $fr_cat_name=$http->post("fr_cat_new".$i);
-               if (strlen(trim($fr_cat_name)) != 0)
-               {
-                    $order=$http->post("fc_order_new".$i);
-                    $desc=$http->post('fr_cat_new' . $i);
-                    $f_id=$http->post("f_id","number");
-                   $c = new Forecast_Cat($cn);
-                   $c->set_parameter('order',$order);
-                   $c->set_parameter('desc', $desc);
-                   $c->set_parameter('forecast', $f_id);
-                   $c->save();
-               }
-           }
-       }
-
-       /* update existing cat */
-       foreach ($_POST as $key => $value)
-       {
-           $var = sscanf($key, 'fr_cat%d');
-           $idx = sprintf("fr_cat%d", $var[0]);
-           if (isset($_POST[$idx]))
-           {
-               $fc = new Forecast_Cat($cn, $var[0]);
-               if (strlen(trim($_POST[$idx])) == 0)
-               {
-                   $fc->delete();
-               }
-               else
-               {
-                     $order=$http->post("fc_order".$var[0]);
-                    $desc=$http->post('fr_cat' . $var[0]);
-                    $f_id=$http->post("f_id","number");
-                   $fc->set_parameter('order', $order);
-                   $fc->set_parameter('desc', $desc);
-                   $fc->set_parameter('forecast', $f_id);
-                   $fc->save();
-               }
-           }
-       }
-
-       $cn->commit();
-    }
-    catch (Exception $e)
-    {
-       alert($e->getMessage());
-       $cn->rollback();
-    }
-    $sa = 'vw';
-}
 /* * ********************************************************************
  * Save first the data for new
  *
  *
  * ******************************************************************** */
-if ($sa == 'new' || isset($_POST['step3']))
-{
-    $correct = 0;
-    if (isset($_POST['step3']))
-    {
-       /* save all the items */
-       try
-       {
-           $cn->start();
-            $nb_row=$http->post("nbrow");
-           for ($i = 0; $i < $nb_row; $i++)
-           {
-
-               // Delete if needed
-               if (isset($_POST['fi_id' . $i]))
-               {
-                   if (strlen(trim($_POST['an_cat_acc' . $i])) == 0 && 
strlen(trim($_POST['an_qc' . $i])) == 0)
-                   {
-                       $e = new Forecast_item($cn);
-                       $e->set_parameter("id", $_POST['fi_id' . $i]);
-                       $e->delete();
-                   }
-               }
-
-               if (strlen(trim($_POST['an_cat_acc' . $i])) != 0 || 
strlen(trim($_POST['an_qc' . $i])) != 0)
-               {
-                   /* we save only if there is something */
-                   $e = new Forecast_item($cn);
-                   if (isset($_POST['fi_id' . $i]))
-                   {
-                       $e->set_parameter("id", $_POST['fi_id' . $i]);
-                   }
-                   $e->set_parameter('text', $_POST['an_label' . $i]);
-                   $e->set_parameter('amount', $_POST['an_cat_amount' . $i]);
-                   $e->set_parameter('debit', $_POST['an_deb' . $i]);
-                   $e->set_parameter('cat_id', $_POST['an_cat' . $i]);
-                   $e->set_parameter('account', $_POST['an_cat_acc' . $i]);
-                   $e->set_parameter('periode', $_POST['month' . $i]);
-                   $f = new Fiche($cn);
-                   if ($f->get_by_qcode($_POST['an_qc' . $i], false) == 0)
-                       $e->set_parameter('card', $f->id);
-                   else
-                       $e->set_parameter('card', null);
-                   $e->set_parameter('order', $i);
-                   $e->save();
-               }
-           }
-           $cn->commit();
-           $sa = 'vw'; // to avoid to restart the add of new anticipation
-       }
-       catch (Exception $e)
-       {
-           $cn->rollback();
-           alert($e->getMessage());
-           $correct = 1;
-       }
-    }
-    /* Second step : we save the name and category
-     * and propose the items we add the item */
-    if ($correct == 2 || isset($_POST['step2']))
-    {
-       try
-       {
-           $cn->start();
-           /* Save forecast */
-           $a = new Forecast($cn);
-           $a->set_parameter('name', $_POST['an_name']);
-           $a->set_parameter('start_date', $_POST['start_date']);
-           $a->set_parameter('end_date', $_POST['end_date']);
-
-
-           $a->save();
-           $id = $a->get_parameter("id");
-           /* save cat */
-           for ($i = 0; $i < MAX_CAT; $i++)
-           {
-               if (strlen(trim($_POST['fr_cat' . $i])) != 0)
-               {
-                   $c = new Forecast_Cat($cn);
-                   $c->set_parameter('order', $_POST['fr_order' . $i]);
-                   $c->set_parameter('desc', $_POST['fr_cat' . $i]);
-                   $c->set_parameter('forecast', $id);
-                   $c->save();
-               }
-           }
-           $cn->commit();
-       }
-       catch (Exception $e)
-       {
-           alert($e->getMessage());
-           $correct = 1;
-           unset($_POST['step2']);
-           $cn->rollback();
-       }
-    }
-}
-
-/* * ********************************************************************
- * Ask for a new anticipation (forecast)
- *
- *
- * ******************************************************************** */
-if ($sa == 'new')
+if ($sa=='new')
 {
-    /* Second step : we save the name and category
-     * and propose the items we add the item */
-    if ($correct == 2 || isset($_POST['step2']))
+    try
     {
-       /* Propose a form for the items
-        */
-       $anticip = new Anticipation($cn, $a->get_parameter("id"));
-       echo '<div class="content">';
-
-       echo '<form method="post" action="?">';
-       echo dossier::hidden();
-       echo HtmlInput::hidden('sa', 'new');
-       echo HtmlInput::hidden('ac', $_REQUEST['ac']);
-       echo HtmlInput::hidden('f_id', $id);
-       echo $anticip->form_item();
-       echo HtmlInput::submit('step3', _('Sauver'));
-       echo '</form>';
-       echo '</div>';
+        $f_name=$http->post("f_name");
+        $p_start=$http->post("p_start","number");
+        $p_end=$http->post("p_end","number");
+        if ( $f_name == "") {
+            throw new Exception(_("Le nom ne peut pas être vide"));
+        }
+        $forecast_sql=new Forecast_SQL($cn);
+        $forecast_sql->setp("f_name",$f_name);
+        $forecast_sql->setp("f_start_date",$p_start);
+        $forecast_sql->setp("f_end_date",$p_end);
+        $forecast_sql->save();
+        $action="mod_item";
+        $forecast_id=$forecast_sql->getp("f_id");
+        
     }
-    /* First step, the name and the category */
-    if (!isset($_POST['step2']) || $correct == 1)
+    catch (Exception $exc)
     {
-       $anc = new Anticipation($cn);
-       echo '<div class="content">';
-       /* display a blank form for name and category */
-       echo '<form method="post" action="?">';
-       echo dossier::hidden();
-       echo HtmlInput::hidden('sa', 'new');
-       echo HtmlInput::hidden('ac', $_REQUEST['ac']);
-       echo $anc->form_cat();
-       echo HtmlInput::submit('step2', _('Sauver'));
-       echo '</form>';
-       echo '</div>';
+        echo_warning($exc->getMessage());
+        $sa="list";
     }
 }
-/* * ********************************************************************
- * If we request to modify the category or the name
- *
- *
- * ******************************************************************** */
-if ( $action == 'mod_cat')
-{
-    $anc = new Anticipation($cn, $_GET['f_id']);
-    echo '<div class="content">';
-    /* display a blank form for name and category */
-    echo '<form method="post" action="?">';
-    echo dossier::hidden();
-    echo HtmlInput::hidden('sa', 'mod');
-    echo HtmlInput::hidden('ac', $_REQUEST['ac']);
-    echo $anc->form_cat();
-    echo HtmlInput::submit('mod_cat_save', _('Sauver'));
 
-    echo '</form>';
-    echo '</div>';
-    return;
-}
 /* * ********************************************************************
  * If we request to modify the items
  *
  *
  * ******************************************************************** */
-if ($action == 'mod_item' )
+if ($action=='mod_item')
 {
 
     /* Propose a form for the items
      */
-    $anticip = new Anticipation($cn, $_GET['f_id']);
-    echo '<div class="content">';
-    echo '<form method="post" action="?">';
-    echo dossier::hidden();
-    echo HtmlInput::hidden('sa', 'new');
-    echo HtmlInput::hidden('ac', $_REQUEST['ac']);
-    echo HtmlInput::hidden('f_id', $_GET['f_id']);
-    echo $anticip->form_item();
-    echo HtmlInput::submit('step3', _('Sauver'));
-    echo '</form>';
-    echo '</div>';
+    $anticipation=new Anticipation($cn, $forecast_id);
+    $anticipation->input_form();
+
+
+
     return;
 }
 /* * ********************************************************************
@@ -328,46 +120,47 @@ if ($action == 'mod_item' )
  *
  *
  * ******************************************************************** */
-if (isset($_REQUEST['f_id']) && $sa == "vw")
+if ($sa=="vw")
 {
     echo '<div class="content">';
-    $forecast = new Anticipation($cn);
-    $forecast->set_parameter("id", $_REQUEST['f_id']);
+    $forecast=new Anticipation($cn);
+    
+
+    $forecast->setForecastId($forecast_id);
     try
     {
-       echo $forecast->display();
-       echo '<div class="noprint">';
-       echo '<form id="forecast_frm" method="get">';
-       echo dossier::hidden();
-        echo HtmlInput::hidden('action','');
-       echo HtmlInput::hidden('f_id', $_REQUEST['f_id']);
-       echo HtmlInput::submit('mod_cat_bt', _('Modifier nom ou 
catégories'),'onclick="$(\'action\').value=\'mod_cat\';"');
-       echo HtmlInput::submit('mod_item_bt', _('Modifier 
éléments'),'onclick="$(\'action\').value=\'mod_item\';"');
-       //echo HtmlInput::submit('cvs',_('Export CVS'));
-       echo HtmlInput::submit('del_bt', _('Effacer'), 
'onclick="$(\'action\').value=\'del\';return confirm_box(\'forecast_frm\',\'' . 
_('Vous confirmez l\\\' effacement') . '\')"');
-       echo HtmlInput::submit('clone_bt', _('Cloner'), 
'onclick="$(\'action\').value=\'clone\';return confirm_box(\'forecast_frm\',\'' 
. _('Vous confirmez le clonage ') . '\')"');
-       echo HtmlInput::hidden('ac', $_REQUEST['ac']);
-        
$href=http_build_query(array('ac'=>$_REQUEST['ac'],'gDossier'=>$_REQUEST['gDossier']));
+        echo $forecast->display();
+        echo '<div class="noprint">';
+        echo '<form id="forecast_frm" method="get">';
+        echo dossier::hidden();
+        echo HtmlInput::hidden('action', '');
+        echo HtmlInput::hidden('f_id', $forecast_id);
+        echo HtmlInput::submit('mod_item_bt', _('Modifier éléments'), 
'onclick="$(\'action\').value=\'mod_item\';"');
+        //echo HtmlInput::submit('cvs',_('Export CVS'));
+    
+        echo HtmlInput::hidden('ac', $ac);
+        $href=http_build_query(array('ac'=>$ac, 'gDossier'=>Dossier::id()));
         echo '<a style="display:inline" class="smallbutton" 
href="do.php?'.$href.'">'._('Retour').'</a>';
-       echo '</form>';
-       echo '</div>';
-       echo '</div>';
-       return;
+        echo '</form>';
+        echo '</div>';
+        echo '</div>';
+        return;
     }
     catch (Exception $e)
     {
-       echo "<div class=\"error\"><p>" . _("Erreur")." : " . $e->getMessage() 
. '</p><p>' . _('Vous devez corriger') . '</p></div>';
-       $anc = new Anticipation($cn, $_GET['f_id']);
-       echo '<div class="content">';
-       /* display a blank form for name and category */
-       echo '<form method="post" action="?">';
-       echo dossier::hidden();
-       echo HtmlInput::hidden('sa', 'mod');
-       echo HtmlInput::hidden('ac', $_REQUEST['ac']);
-       echo $anc->form_cat();
-       echo HtmlInput::submit('mod_cat_save', _('Sauver'));
-       echo '</form>';
-       echo '</div>';
+        echo "<div class=\"error\"><p>"._("Erreur")." : ".$e->getMessage().
+        '</p><p>'._('Vous devez corriger').'</p></div>';
+        $anc=new Anticipation($cn, $forecast_id);
+        echo '<div class="content">';
+        /* display a blank form for name and category */
+        echo '<form method="post" action="?">';
+        echo dossier::hidden();
+        echo HtmlInput::hidden('sa', 'mod');
+        echo HtmlInput::hidden('ac', $ac);
+        echo $anc->form_cat();
+        echo HtmlInput::submit('mod_cat_save', _('Sauver'));
+        echo '</form>';
+        echo '</div>';
     }
 }
 /* * ********************************************************************
@@ -378,19 +171,23 @@ if (isset($_REQUEST['f_id']) && $sa == "vw")
 // display button add and list of forecast to display
 if ($sa=='list')
 {
+
+
     $aForecast=Forecast::load_all($cn);
     $menu=array();
     $get_dossier=dossier::get();
+    require_once NOALYSS_TEMPLATE."/forecast-new.php";
 
     echo '<div class="content">';
     echo _('Filtre')." ".HtmlInput::filter_table("forecast_table_id", '0', 1);
     echo '<TABLE id="forecast_table_id" class="vert_mtitle">';
-    $href="?ac=".$_REQUEST['ac']."&sa=new&".$get_dossier;
-    echo '<TR><TD class="first"><A HREF="'.$href.'">'._("Ajout d'une 
prévision").'</A></TD></TR>';
-    $def=(isset($_REQUEST['f_id']))?$_REQUEST['f_id']:-1;
+    $href="?ac=".$ac."&sa=new&".$get_dossier;
+    echo '<TR><TD class="first"><A HREF="#" 
onclick="document.getElementById(\'forecast_new_div\').show()">'._("Ajout d'une 
prévision").'</A></TD></TR>';
+    $forecast_id=$http->request('f_id', 'number', -1);
+
     for ($i=0; $i<count($aForecast); $i++)
     {
-        
$href="?ac=".$_REQUEST['ac']."&sa=vw&".$get_dossier.'&f_id='.$aForecast[$i]['f_id'];
+        
$href="?ac=".$ac."&sa=vw&".$get_dossier.'&f_id='.$aForecast[$i]['f_id'];
         $name=h($aForecast[$i]['f_name']);
         $menu[]=array($href, $name, $name, $aForecast[$i]['f_id']);
         echo '<TR><TD><A HREF="'.$href.'">'.h($name).'</A></TD></TR>';
diff --git a/include/lib/function_javascript.php 
b/include/lib/function_javascript.php
index 0b8ce6c..c6afeeb 100644
--- a/include/lib/function_javascript.php
+++ b/include/lib/function_javascript.php
@@ -2775,7 +2775,6 @@ function load_all_script()
     echo js_include('card.js');
     echo js_include('compute_direct.js');
     echo js_include('compute.js');
-    echo js_include('forecast.js');
     echo js_include('gestion.js');
     echo js_include('todo_list.js');
     echo js_include('anc_script.js');
diff --git a/include/lib/impress.class.php b/include/lib/impress.class.php
index 8ea617f..e03a1a4 100644
--- a/include/lib/impress.class.php
+++ b/include/lib/impress.class.php
@@ -57,7 +57,7 @@ class Impress
         else
             $cond="( j_date >= to_date('$p_start','DD.MM.YYYY') and j_date <= 
to_date('$p_end','DD.MM.YYYY'))";
 
-        while (preg_match_all("(\[[0-9]*[A-Z]*%*c*d*s*\])",$p_formula,$e) == 
true)
+        while (preg_match_all("(\[[0-9]*[A-Z]*%*c*d*s*S*\])",$p_formula,$e) == 
true)
           {
             // remove the [ ]
             $x=$e[0];
@@ -70,11 +70,14 @@ class Impress
                   $compute='cred';
                 if ( strpos($line,'s') != 0 )
                   $compute='signed';
+                if ( strpos($line,'S') != 0 )
+                  $compute='cdsigned';
                 $line=str_replace ("[","",$line);
                 $line=str_replace ("]","",$line);
                 $line=str_replace ("d","",$line);
                 $line=str_replace ("c","",$line);
                 $line=str_replace ("s","",$line);
+                $line=str_replace ("S","",$line);
                 // If there is a FROM clause we must recompute
                 // the time cond
 
@@ -145,7 +148,9 @@ class Impress
                 if ( $compute=='cred')
                   $i=$detail['credit'];
                 if ( $compute=='signed')
-                  $i=$detail['debit']-$detail['credit'];
+                  $i=bcsub($detail['debit'],$detail['credit'],4);
+                if ( $compute=='cdsigned')
+                  $i=bcsub($detail['credit'],$detail['debit'],4);
                 $p_formula=str_replace($x[0],$i,$p_formula);
               }
           }
@@ -215,28 +220,29 @@ class Impress
         $p_string=str_replace("c","",$p_string);
         $p_string=str_replace("d","",$p_string);
         $p_string=str_replace("s","",$p_string);
+        $p_string=str_replace("S","",$p_string);
         // Remove T,t
         $p_string=str_replace("t","",$p_string);
 
-               // remove date
-               $p_string=  preg_replace("/FROM*=*[0-9]+/", "", $p_string);
-               // remove comment
-               $p_string=  preg_replace("/#.*/", "", $p_string);
-               // remove $C=
-               $p_string=  preg_replace('/\$[a-z]*[A-Z]*[0-9]*[A-Z]*[a-z]*/', 
"", $p_string);
-               $p_string=  preg_replace('/=/', "", $p_string);
+        // remove date
+        $p_string=  preg_replace("/FROM*=*[0-9]+/", "", $p_string);
+        // remove comment
+        $p_string=  preg_replace("/#.*/", "", $p_string);
+        // remove $C=
+        $p_string=  preg_replace('/\$[a-z]*[A-Z]*[0-9]*[A-Z]*[a-z]*/', "", 
$p_string);
+        $p_string=  preg_replace('/=/', "", $p_string);
 
-               // remove account
-               $p_string=  preg_replace("/\[[0-9]*[A-Z]*%*\]/", "", $p_string);
+        // remove account
+        $p_string=  preg_replace("/\[[0-9]*[A-Z]*%*\]/", "", $p_string);
 
-               $p_string=  preg_replace("/\+|-|\/|\*/", "", $p_string);
-               $p_string=  preg_replace("/[0-9]*\.*[0-9]/", "", $p_string);
+        $p_string=  preg_replace("/\+|-|\/|\*/", "", $p_string);
+        $p_string=  preg_replace("/[0-9]*\.*[0-9]/", "", $p_string);
 
-               
//********************************************************************************************************************
-               // If the string is empty then formula should be good
-               //
-               
//********************************************************************************************************************
-               if ($p_string == '')
+        
//********************************************************************************************************************
+        // If the string is empty then formula should be good
+        //
+        
//********************************************************************************************************************
+        if ($p_string == '')
         {
             return true;
         }
diff --git a/include/lib/manage_table_sql.class.php 
b/include/lib/manage_table_sql.class.php
index 8962ca1..fc14cb0 100644
--- a/include/lib/manage_table_sql.class.php
+++ b/include/lib/manage_table_sql.class.php
@@ -354,7 +354,7 @@ function check()
      * select must supply an array of possible values [val=> , label=>] with
      * the variable $this->key_name->a_value
      * @param $p_key col name
-     * @param $p_type is SELECT NUMERIC TEXT , DATE  or custom 
+     * @param $p_type is "text", "numeric", "date", "select", 
"timestamp","custom"
      * @param $p_array if type is  SELECT an array is expected
      * @note if $p_type is custom  then a function named 
input_custom($p_key,$p_value) must be implemented 
      * in the class
@@ -918,9 +918,16 @@ function check()
                 $td=($i == $this->col_sort ) ? sprintf('<td sort_value="X%s" 
>',$p_row[$v]):"<td>";
                 echo $td.HtmlInput::anchor($p_row[$v], "", $js).'</td>';
             }
-            elseif ( $i == $this->col_sort && $this->get_property_visible($v))
+            elseif ( $i == $this->col_sort && $this->get_property_visible($v) )
             {
-                echo td($p_row[$v],sprintf(' sort_value="X%s" ',$p_row[$v]));
+                if (  $this->get_col_type($v) == 'text') {
+                    echo td($p_row[$v],sprintf(' sort_value="X%s" 
',$p_row[$v]));
+                } elseif ( $this->get_col_type($v) == 'numeric') {
+                    echo td($p_row[$v],sprintf(' sort_value="%s" 
',$p_row[$v]));
+                } else {
+                    echo td($p_row[$v],sprintf(' sort_value="X%s" 
',$p_row[$v]));
+                    
+                }
             }
             elseif ( ! $this->get_property_visible($v)) { 
                 continue;
diff --git a/include/template/forecast_result.php 
b/include/template/anticipation-display.php
similarity index 62%
rename from include/template/forecast_result.php
rename to include/template/anticipation-display.php
index f272f93..393df5a 100644
--- a/include/template/forecast_result.php
+++ b/include/template/anticipation-display.php
@@ -41,15 +41,48 @@ Période du <?php echo $str_start?> à <?php echo $str_end;?>
 $amount=$aItem[$i][$e]['fi_amount'];
 if (count($aPerMonth[$i]) != 0 ){
        for ($x=0;$x<count($aPerMonth[$i]);$x++) {
-               $amount=$aItem[$i][$e]['fi_amount'];
-               if ($aPeriode[$h]['p_id']==$aPerMonth[$i][$x]['fi_pid'] &&
-                       
$aItem[$i][$e]['fi_card']==$aPerMonth[$i][$x]['fi_card'] &&
-                       
$aItem[$i][$e]['fi_account']==$aPerMonth[$i][$x]['fi_account']
-                       )
-                       {
-                               $amount=$aPerMonth[$i][$x]['fi_amount'];
-                               break;
-                       }
+            if (DEBUGNOALYSS>2) {
+                printf (" \$aItem [$i] [$e] = %s",$aItem[$i][$e]['fi_amount']);
+                echo  p("\$aPeriode[$h]['p_id']==\$aPerMonth[$i][$x]['fi_pid'] 
".
+                        
$aPeriode[$h]['p_id']."==".$aPerMonth[$i][$x]['fi_pid'] );
+                
+               echo p("        
\$aItem[$i][$e]['fi_card']==\$aPerMonth[$i][$x]['fi_card'] ".
+                               
$aItem[$i][$e]['fi_card']."==".$aPerMonth[$i][$x]['fi_card'] );
+                echo p( "      
\$aItem[$i][$e]['fi_account']==\$aPerMonth[$i][$x]['fi_account']".
+                        
$aItem[$i][$e]['fi_account']."==".$aPerMonth[$i][$x]['fi_account']);
+                if ($aPeriode[$h]['p_id']==$aPerMonth[$i][$x]['fi_pid']) {
+                    echo 
p("\$aPeriode[$h]['p_id']==\$aPerMonth[$i][$x]['fi_pid'] YES");
+                } else {
+                    echo 
p("\$aPeriode[$h]['p_id']==\$aPerMonth[$i][$x]['fi_pid'] NO");
+                }
+                if ( $aItem[$i][$e]['fi_card']==$aPerMonth[$i][$x]['fi_card']){
+                    echo 
"\$aItem[$i][$e]['fi_card']==\$aPerMonth[$i][$x]['fi_card'] YES";
+                } else {
+                    echo 
"\$aItem[$i][$e]['fi_card']==\$aPerMonth[$i][$x]['fi_card'] NO";
+                    
+                }
+                if 
($aItem[$i][$e]['fi_account']==$aPerMonth[$i][$x]['fi_account']) {
+                    echo 
p("\$aItem[$i][$e]['fi_account']==\$aPerMonth[$i][$x]['fi_account']YES");
+                } else {
+                    echo 
p("\$aItem[$i][$e]['fi_account']==\$aPerMonth[$i][$x]['fi_account']NO");
+                }
+                echo p("\$aItem[$i][$e]['fi_account'] 
[".$aItem[$i][$e]['fi_account']."]");
+                echo p("\$aPerMonth[$i][$x]['fi_account'] 
[".$aPerMonth[$i][$x]['fi_account']."]");
+            }
+            $amount=$aItem[$i][$e]['fi_amount'];
+            if (
+                $aPeriode[$h]['p_id']==$aPerMonth[$i][$x]['fi_pid'] &&
+                
trim($aItem[$i][$e]['fi_card'])==trim($aPerMonth[$i][$x]['fi_card']) &&
+                
trim($aItem[$i][$e]['fi_account'])==trim($aPerMonth[$i][$x]['fi_account'])
+                )
+                {
+                    $amount=$aPerMonth[$i][$x]['fi_amount'];
+                    if ( DEBUGNOALYSS > 1 ){
+                        echo 
p("\$aPerMonth[$i][$x]['fi_amount']".$aPerMonth[$i][$x]['fi_amount']);
+                        echo "\$amount = $amount ";
+                    }
+                    break;
+                }
        }
 }
 $estm[$i][$e][$h]=$amount;
@@ -72,7 +105,8 @@ $tot_cat_estm=bcadd($amount,$tot_cat_estm);
 </td>
 <?php for ($h=0;$h<count($aPeriode);$h++):?>
 <td align="right">
-   <?php echo nbm(  
$aReal[$i][$e][$h]);$tot_cat_real=bcadd($tot_cat_real,$aReal[$i][$e][$h]);$tot=bcadd($tot,$aReal[$i][$e][$h]);?>
+   <?php echo nbm(  
$aReal[$i][$e][$h]);$tot_cat_real=bcadd($tot_cat_real,$aReal[$i][$e][$h]);
+   $tot=bcadd($tot,$aReal[$i][$e][$h]);?>
 </td>
 <?php endfor;?>
 <td align="right">
diff --git a/include/template/anticipation-input_title.php 
b/include/template/anticipation-input_title.php
new file mode 100644
index 0000000..2bb823d
--- /dev/null
+++ b/include/template/anticipation-input_title.php
@@ -0,0 +1,74 @@
+<?php
+/*
+ *   This file is part of NOALYSS.
+ *
+ *   NOALYSS 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.
+ *
+ *   NOALYSS 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 NOALYSS; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+// Copyright Author Dany De Bontridder danydb@aevalys.eu
+
+/**
+ * @file
+ * @brief  Display a form for the title of a forecast
+ *
+ */
+$forecast_sql = new Forecast_SQL($this->cn, $this->forecast_id);
+$fc_name = new IText("f_name", $forecast_sql->getp("f_name"));
+$fc_name->id="fc_name";
+$is_start = new ISelect("p_start");
+$is_start->value = $this->cn->make_array("select p_id,p_start from 
parm_periode order by p_start");
+$is_end = new ISelect("p_end");
+$is_end->value = $this->cn->make_array("select p_id,p_end from parm_periode 
order by p_end");
+
+$is_start->selected = $forecast_sql->getp("f_start_date");
+$is_end->selected = $forecast_sql->getp("f_end_date");
+$is_start->id=uniqid("sel");
+$is_end->id=uniqid("sel");
+
+
+$ip_name = new Inplace_Edit($fc_name);
+$ip_start = new Inplace_Edit($is_start);
+$ip_end = new Inplace_Edit($is_end);
+
+$ip_name->add_json_param("op", "forecast");
+$ip_start->add_json_param("op", "forecast");
+$ip_end->add_json_param("op", "forecast");
+
+$ip_name->add_json_param("gDossier", Dossier::id());
+$ip_start->add_json_param("gDossier", Dossier::id());
+$ip_end->add_json_param("gDossier", Dossier::id());
+
+$ip_name->add_json_param("f_id", $this->forecast_id);
+$ip_start->add_json_param("f_id", $this->forecast_id);
+$ip_end->add_json_param("f_id", $this->forecast_id);
+
+$ip_name->set_callback("ajax_misc.php");
+$ip_start->set_callback("ajax_misc.php");
+$ip_end->set_callback("ajax_misc.php");
+
+?>
+<h1>
+    <?php
+    echo $ip_name->input();
+    ?>
+</h1>
+<div class="form-group">
+
+<label for="p_start" class="form-group"><?= _("Début") ?></label>
+<?= $ip_start->input(); ?>
+<label for="p_end" class="form-group"><?= _("Fin") ?></label>
+<?= $ip_end->input() ?>
+
+</div>
diff --git a/include/template/forecast-new.php 
b/include/template/forecast-new.php
new file mode 100644
index 0000000..2150d89
--- /dev/null
+++ b/include/template/forecast-new.php
@@ -0,0 +1,90 @@
+<?php
+/*
+ *   This file is part of NOALYSS.
+ *
+ *   PhpCompta 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.
+ *
+ *   PhpCompta 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 PhpCompta; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+// Copyright (2002-2020) Author Dany De Bontridder <danydb@noalyss.eu>
+
+if (!defined('ALLOWED'))
+    die('Appel direct ne sont pas permis');
+
+/**
+ * @file
+ * @brief form to enter a new Forecast
+ */
+$cn=Dossier::connect();
+global $g_user;
+$exercice=$g_user->get_exercice();
+$t_periode=new Periode($cn);
+list($per_max, $per_min)=$t_periode->get_limit($exercice);
+
+
+$fc_name=new IText("f_name");
+$fc_name->id="fc_name";
+$is_start=new ISelect("p_start");
+$is_start->value=$cn->make_array("select p_id,p_start from parm_periode order 
by p_start");
+$is_start->selected=$per_max->p_id;
+$is_end=new ISelect("p_end");
+$is_end->selected=$per_min->p_id;
+$is_end->value=$cn->make_array("select p_id,p_end from parm_periode order by 
p_end");
+?>
+<div id="forecast_new_div" class="inner_box" style="display: 
none;width:30rem;">
+
+    <?= HtmlInput::title_box(_("Nouvelle prévision"), "forecast_new_div", 
"hide") ?>
+    <form method="POST" style="padding:0px">
+        <?php
+        echo HtmlInput::hidden("sa", "new");
+        echo HtmlInput::array_to_hidden(['f_id', 'ac', 'gDossier'], $_REQUEST);
+        ?>
+
+        <div class="form-group row">
+            <div class="col">
+
+                <label for="fc_name" class="form-group"><?= _("Nom") ?></label>
+            </div>
+            <div class="col">
+                <input type="text" class="input_text" name="f_name" 
placeholder="<?= _("Nom") ?>">
+            </div>
+
+        </div>
+
+        <div class="form-group row">
+            <div class="col">
+
+                <label for="p_start" class="form-group"><?= _("Début") 
?></label>
+            </div>
+            <div class="col">
+
+                <?= $is_start->input(); ?>
+
+            </div>
+        </div>
+
+        <div class="form-group row">
+            <div class="col">
+
+                <label for="p_end" class="form-group"><?= _("Fin") ?></label>
+            </div>
+            <div class="col">
+
+                <?= $is_end->input() ?>
+            </div>
+        </div>
+        <input type="submit" class="smallbutton" value="<?= _("Sauver") ?>">
+        <?= HtmlInput::button_hide("forecast_new_div") ?>
+
+    </form>
+</div>
diff --git a/include/template/forecast_cat.php 
b/include/template/forecast_cat-delete.php
similarity index 100%
rename from include/template/forecast_cat.php
rename to include/template/forecast_cat-delete.php
diff --git a/include/template/forecast_item_mtable-display_table.php 
b/include/template/forecast_item_mtable-display_table.php
new file mode 100644
index 0000000..ab515be
--- /dev/null
+++ b/include/template/forecast_item_mtable-display_table.php
@@ -0,0 +1,71 @@
+<?php
+/*
+*   This file is part of NOALYSS.
+*
+*   NOALYSS 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.
+*
+*   NOALYSS 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 NOALYSS; if not, write to the Free Software
+*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+// Copyright Author Dany De Bontridder danydb@noalyss.eu
+
+/**
+ * \file
+ * \brief display, add, delete and modify forecast_item, All rows are in $a_row
+ * \see Forecast_Item_MTable
+ */
+
+echo HtmlInput::filter_table("tb" . $this->object_name, '0,1,2,3,4', 1);
+?>
+<table id="<?= "tb" . $this->object_name ?>" class="result">
+    <thead>
+    <tr>
+
+        <th>
+            <?= _("Catégorie") ?>
+        </th>
+        <th>
+            <?= _("Texte") ?>
+        </th>
+        <th>
+            <?= _("Formule") ?>
+        </th>
+        <th>
+            <?= _("Montant") ?>
+        </th>
+        <th>
+            <?= _("Période") ?>
+        </th>
+        <th></th>
+    </tr>
+    </thead>
+    <tbdoy>
+        <?php
+        $nb_row = count($a_row);
+        for ($i = 0; $i < $nb_row; $i++):
+            $class = ($i % 2 == 0) ? "even" : "odd";
+            $this->display_row($a_row[$i]);
+        endfor; // end for i
+        ?>
+    </tbdoy>
+</table>
+<?php
+$this->create_js_script();
+?>
+<?php
+echo HtmlInput::button_action(" " . _("Ajout"),
+    sprintf("%s.input('-1','%s')",
+        $this->object_name,
+        $this->object_name), "xx", "smallbutton", BUTTONADD);
+?>
+<script>alternate_row_color('<?="tb" . $this->object_name?>')</script>
diff --git a/include/template/forecast_item_mtable-input.php 
b/include/template/forecast_item_mtable-input.php
new file mode 100644
index 0000000..4a72c98
--- /dev/null
+++ b/include/template/forecast_item_mtable-input.php
@@ -0,0 +1,150 @@
+<?php
+/*
+*   This file is part of NOALYSS.
+*
+*   NOALYSS 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.
+*
+*   NOALYSS 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 NOALYSS; if not, write to the Free Software
+*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+// Copyright Author Dany De Bontridder danydb@noalyss.eu
+
+/**
+ * \file
+ * \brief display, add, delete and modify forecast_item, All rows are in $a_row
+ * \see Forecast_Item_MTable::input
+ */
+if ( $this->count_category() == 0 ) {
+    echo span(_("Sans catégorie il n'est pas possible d'ajouter de nouveaux 
éléments"),'class="notice"');
+    return;
+}
+
+$cn = $object->cn;
+$forecast = new Forecast_SQL($cn, $this->get_forecast_id());
+$forecast->load();
+$str_name = $forecast->getp('f_name');
+$str_start = $forecast->getp('f_start_date');
+$str_end = $forecast->getp('f_end_date');
+
+$aPeriode = $cn->make_array("select p_id,to_char(p_start,'MM.YYYY') as label 
from parm_periode
+                                   where p_start >= (select p_start from 
parm_periode where p_id=$str_start)
+                                    and p_end <= (select p_end from 
parm_periode where p_id=$str_end)
+                                    order by p_start");
+$aPeriode[] = array('value' => 0, 'label' => 'Mensuel');
+$category = new ISelect("fc_id");
+$category->value = $cn->make_array("select fc_id,fc_desc from 
+                          forecast_category 
+            where f_id=$1 order by 2",
+    0, [$this->get_forecast_id()]);
+$category->selected = $object->getp("fc_id");
+
+$amount = new INum("fi_amount");
+$amount->value = $object->getp("fi_amount");
+$amount->value=($amount->value=="")?0:$amount->value;
+
+$forecast_text = new IText("fi_text");
+$forecast_text->value = $object->getp("fi_text");
+
+/* Accounting*/
+$account = new IPoste('fi_account');
+$account->nb_row=3;
+$account->extra=' style = "margin-left:0px;width:100%;" class="input_text"';
+$account->set_attribute('account', 'fi_account');
+$account->set_attribute('bracket', 1);
+$account->set_attribute('no_overwrite', 1);
+$account->set_attribute('noquery', 1);
+$account->value = $object->getp("fi_account");
+$account->size="80rem";
+/*Quick Code */
+$qc = new ICard("fi_card");
+// If double click call the javascript fill_ipopcard
+$qc->set_dblclick("fill_ipopcard(this);");
+
+// name of the field to update with the name of the card
+$qc->set_attribute('label', 'an_label');
+
+// Type of card : all
+$qc->set_attribute('typecard', 'all');
+$qc->set_attribute('jrn', 0);
+$qc->extra = 'all';
+
+// when value selected in the autcomplete
+$qc->set_function('fill_data');
+if ($object->getp("fi_card") != "") {
+
+    $qc->value = $cn->get_value("select ad_value 
+    from fiche_detail 
+    where
+          ad_id=23 and f_id = $1", [$object->getp("fi_card")]);
+}
+
+$isDebit=new ISelect("fi_debit");
+$isDebit->value=array(
+        array("label"=>_("Crédit"),"value"=>'C'),
+        array("label"=>_("Débit"),"value"=>'D')
+    );
+$isDebit->selected=$object->getp("fi_debit");
+
+$isPeriode = new ISelect('fi_pid');
+$isPeriode->value = $aPeriode;
+$isPeriode->selected = $object->getp("fi_pid");
+?>
+<table style="width:50rem">
+    <tr>
+        <td><?= _("Categorie") ?></td>
+        <td><?= $category->input(); ?></td>
+    </tr>
+    
+    <tr>
+        <td>
+            <?= _("Periode") ?>
+        </td>
+        <td>
+            <?= $isPeriode->input() ?>
+        </td>
+    </tr>
+    
+    <tr>
+        <td><?= _("Intitulé") ?></td>
+        <td><?= $forecast_text->input(); ?></td>
+    </tr>
+    <tr>
+        <td>
+            <?= _("Fiche") ?>
+        </td>
+        <td>
+            <?= $qc->input(); ?><?=$qc->search()?>
+            <span id="an_label"></span>
+        </td>
+    </tr>  
+    <tr>
+        <td><?= _("Positif") ?><?= Icon_Action::tips(_("Ne concerne que les 
fiches"))?></td>
+        <td><?=$isDebit->input(); ?></td>
+    </tr>
+    <tr>
+        <td>
+            <?= _("Formule") ?>
+           ( <a 
href="https://wiki.noalyss.eu/doku.php?id=tutoriaux:les_rapports#un_mot_d_explication";
 target="_blank">
+                Aide</a> )
+            
+        </td>
+        <td>
+            <?= $account->input() ?>
+        </td>
+    </tr>
+    <tr>
+        <td><?= _("Montant") ?></td>
+        <td><?= $amount->input(); ?></td>
+    </tr>
+
+</table>
diff --git a/sql/upgrade.sql b/sql/upgrade.sql
index e69de29..fc4f704 100644
--- a/sql/upgrade.sql
+++ b/sql/upgrade.sql
@@ -0,0 +1,2 @@
+alter table forecast_cat rename to forecast_category;
+alter table forecast_category  alter f_id set not null;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]