noalyss-commit
[Top][All Lists]
Advanced

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

[Noalyss-commit] [noalyss] 65/323: Task #0001530: Réécriture PRINTJRN,


From: Dany De Bontridder
Subject: [Noalyss-commit] [noalyss] 65/323: Task #0001530: Réécriture PRINTJRN, Base + Sale
Date: Wed, 14 Mar 2018 17:38:19 -0400 (EDT)

sparkyx pushed a commit to branch master
in repository noalyss.

commit 7f5e25e33b20678244f8d569d1aa12bba9d54a95
Author: Dany De Bontridder <address@hidden>
Date:   Sun Jan 21 12:36:51 2018 +0100

    Task #0001530: Réécriture PRINTJRN,
    Base +  Sale
---
 include/class/acc_ledger.class.php                 | 538 +--------------
 include/class/acc_ledger_history.class.php         | 283 ++++++++
 .../class/acc_ledger_history_financial.class.php   |  28 +
 include/class/acc_ledger_history_generic.class.php | 737 +++++++++++++++++++++
 .../class/acc_ledger_history_purchase.class.php    |  26 +
 include/class/acc_ledger_history_sale.class.php    | 222 +++++++
 include/impress_jrn.inc.php                        | 344 ++--------
 .../template/acc_history_ledger_sale_oneline.php   | 134 ++++
 .../template/acc_ledger_history_sale_detail.php    | 180 +++++
 .../template/acc_ledger_history_sale_extended.php  | 171 +++++
 scenario/acc_ledger_historyTest.php                |  68 ++
 11 files changed, 1911 insertions(+), 820 deletions(-)

diff --git a/include/class/acc_ledger.class.php 
b/include/class/acc_ledger.class.php
index d2d3e3a..1f32a0d 100644
--- a/include/class/acc_ledger.class.php
+++ b/include/class/acc_ledger.class.php
@@ -381,236 +381,10 @@ class Acc_Ledger extends jrn_def_sql
         return $ret['jrn_def_name'];
     }
 
-    /**
-     * @brief  Get The data
-     *
-     *
-     * @paramp_from from periode
-     * @paramp_to to periode
-     * @paramp_limit starting line
-     * @paramp_offset number of lines
-     * \return Array with the asked data
-     *
-     */
-    function get_row($p_from, $p_to, $p_limit=-1, $p_offset=-1)
-    {
-        global $g_user;
-        $periode=sql_filter_per($this->db, $p_from, $p_to, 'p_id', 
'jr_tech_per');
-
-        $cond_limite=($p_limit!=-1)?" limit ".$p_limit." offset ".$p_offset:"";
-        // retrieve the type
-        $this->get_type();
-        // Grand livre == 0
-        if ($this->id!=0)
-        {
-            $Res=$this->db->exec_sql("select jr_id,j_id,j_id as 
int_j_id,to_char(j_date,'DD.MM.YYYY') as j_date,
-                                     jr_internal,
-                                     case j_debit when 't' then 
j_montant::text else '   ' end as deb_montant,
-                                     case j_debit when 'f' then 
j_montant::text else '   ' end as cred_montant,
-                                     j_debit as debit,j_poste as 
poste,j_qcode,jr_montant , ".
-                    "case when j_text='' or j_text is null then pcm_lib else 
j_text end as description,j_grpt as grp,
-                                     jr_comment||' ('||jr_internal||')'  as 
jr_comment,
-                                    jr_pj_number,
-                                     j_qcode,
-                                     jr_rapt as oc, j_tech_per as periode
-                                     from jrnx left join jrn on ".
-                    "jr_grpt_id=j_grpt ".
-                    " left join tmp_pcmn on pcm_val=j_poste ".
-                    " where j_jrn_def=".$this->id.
-                    " and ".$periode." order by j_date::date 
asc,substring(jr_pj_number,'[0-9]+$')::numeric asc,j_grpt,j_debit desc ".
-                    $cond_limite);
-        }
-        else
-        {
-            $Res=$this->db->exec_sql("select jr_id,j_id,j_id as 
int_j_id,to_char(j_date,'DD.MM.YYYY') as j_date,
-                                     jr_internal,
-                                     case j_debit when 't' then 
j_montant::text else '   ' end as deb_montant,
-                                     case j_debit when 'f' then 
j_montant::text else '   ' end as cred_montant,
-                                     j_debit as debit,j_poste as 
poste,j_qcode,".
-                    "case when j_text='' or j_text is null then pcm_lib else 
j_text end as description,j_grpt as grp,
-                                     jr_comment||' ('||jr_internal||')' as 
jr_comment,
-                                    jr_pj_number,
-                                     jr_montant,
-                                     j_qcode,
-                                     jr_rapt as oc, j_tech_per as periode from 
jrnx left join jrn on ".
-                    "jr_grpt_id=j_grpt left join tmp_pcmn on pcm_val=j_poste
-                                                                               
 join jrn_def on (jr_def_id=jrn_def_id)
-                                                                               
 where ".
-                    $g_user->get_ledger_sql()." and ".
-                    "  ".$periode." order by 
j_date::date,substring(jr_pj_number,'[0-9]+$') asc,j_grpt,j_debit desc   ".
-                    $cond_limite);
-        }
-
-
-        $array=array();
-        $Max=Database::num_row($Res);
-        if ($Max==0)
-            return null;
-        $case="";
-        $tot_deb=0;
-        $tot_cred=0;
-        $row=Database::fetch_all($Res);
-        for ($i=0; $i<$Max; $i++)
-        {
-            $fiche=new Fiche($this->db);
-            $line=$row[$i];
-            $mont_deb=($line['deb_montant']!=0)?sprintf("% 8.2f",
-                            $line['deb_montant']):"";
-            $mont_cred=($line['cred_montant']!=0)?sprintf("% 8.2f",
-                            $line['cred_montant']):"";
-            $jr_montant=($line['jr_montant']!=0)?sprintf("% 8.2f",
-                            $line['jr_montant']):"";
-            $tot_deb+=$line['deb_montant'];
-            $tot_cred+=$line['cred_montant'];
-            $tot_op=$line['jr_montant'];
-
-            /* Check first if there is a quickcode */
-            if 
(strlen(trim($line['description']))==0&&strlen(trim($line['j_qcode']))
-                    !=0)
-            {
-                if ($fiche->get_by_qcode($line['j_qcode'], false)==0)
-                {
-                    $line['description']=$fiche->strAttribut(ATTR_DEF_NAME);
-                }
-            }
-            if ($case!=$line['grp'])
-            {
-                $case=$line['grp'];
-                // for financial, we show if the amount is or not in negative
-                if ($this->type=='FIN')
-                {
-                    $amount=$this->db->get_value('select qf_amount from 
quant_fin where jr_id=$1',
-                            array($line['jr_id']));
-                    /*  if nothing is found */
-                    if ($this->db->count()==0)
-                        $tot_op=$jr_montant;
-                    else if ($amount<0)
-                    {
-                        $tot_op=$amount;
-                    }
-                }
-                $array[]=array(
-                    'jr_id'=>$line['jr_id'],
-                    'int_j_id'=>$line['int_j_id'],
-                    'j_id'=>$line['j_id'],
-                    'j_date'=>$line['j_date'],
-                    'internal'=>$line['jr_internal'],
-                    'deb_montant'=>'',
-                    'cred_montant'=>' ',
-                    'description'=>'<b><i>'.h($line['jr_comment']).' 
['.$tot_op.'] </i></b>',
-                    'poste'=>$line['oc'],
-                    'j_qcode'=>$line['j_qcode'],
-                    'periode'=>$line['periode'],
-                    'jr_pj_number'=>$line ['jr_pj_number']);
-
-                $array[]=array(
-                    'jr_id'=>'',
-                    'int_j_id'=>$line['int_j_id'],
-                    'j_id'=>'',
-                    'j_date'=>'',
-                    'internal'=>'',
-                    'deb_montant'=>$mont_deb,
-                    'cred_montant'=>$mont_cred,
-                    'description'=>$line['description'],
-                    'poste'=>$line['poste'],
-                    'j_qcode'=>$line['j_qcode'],
-                    'periode'=>$line['periode'],
-                    'jr_pj_number'=>''
-                );
-            }
-            else
-            {
-                $array[]=array(
-                    'jr_id'=>$line['jr_id'],
-                    'int_j_id'=>$line['int_j_id'],
-                    'j_id'=>'',
-                    'j_date'=>'',
-                    'internal'=>'',
-                    'deb_montant'=>$mont_deb,
-                    'cred_montant'=>$mont_cred,
-                    'description'=>$line['description'],
-                    'poste'=>$line['poste'],
-                    'j_qcode'=>$line['j_qcode'],
-                    'periode'=>$line['periode'],
-                    'jr_pj_number'=>'');
-            }
-        }
-        $this->row=$array;
-        $a=array($array, $tot_deb, $tot_cred);
-        return $a;
-    }
-
-    /** @brief  Get simplified row from ledger
-     *
-     * @param p_from periode
-     * @param p_to periode
-     * @param p_limit starting line
-     * @param p_offset number of lines
-     * @param trunc if data must be truncated (pdf export)
-     *
-     * \return an Array with the asked data
-     */
-    function get_rowSimple($p_from, $p_to, $trunc=0, $p_limit=-1, $p_offset=-1)
-    {
-        global $g_user;
-        // Grand-livre : id= 0
-        //---
-        $jrn=($this->id==0 )?"and ".$g_user->get_ledger_sql():"and jrn_def_id 
= ".$this->id;
-
-        $periode=sql_filter_per($this->db, $p_from, $p_to, 'p_id', 
'jr_tech_per');
-
-        $cond_limite=($p_limit!=-1)?" limit ".$p_limit." offset ".$p_offset:"";
-        //---
-        $sql="
-             SELECT jrn.jr_id as jr_id ,
-             jrn.jr_id as num ,
-             jrn.jr_def_id as jr_def_id,
-             jrn.jr_montant as montant,
-             substr(jrn.jr_comment,1,35) as comment,
-             to_char(jrn.jr_date,'DD-MM-YYYY') as date,
-             to_char(jrn.jr_date_paid,'DD-MM-YYYY') as date_paid,
-             jr_pj_number,
-             jr_internal,
-             jrn.jr_grpt_id as grpt_id,
-             jrn.jr_pj_name as pj,
-             jrn_def_type,
-             jrn.jr_tech_per
-             FROM jrn join jrn_def on (jrn_def_id=jr_def_id)
-             WHERE $periode $jrn order by 
jr_date,substring(jrn.jr_pj_number,'[0-9]+$')::numeric asc  $cond_limite";
-
-        $Res=$this->db->exec_sql($sql);
-        $Max=Database::num_row($Res);
-        if ($Max==0)
-        {
-            return null;
-        }
-        $type=$this->get_type();
-        // for type ACH and Ven we take more info
-        if ($type=='ACH'||$type=='VEN')
-        {
-            $a_ParmCode=$this->db->get_array('select p_code,p_value from 
parm_code');
-            $a_TVA=$this->db->get_array('select tva_id,tva_label,tva_poste
-                                        from tva_rate where tva_rate != 0 
order by tva_rate,tva_label,tva_id ');
-            for ($i=0; $i<$Max; $i++)
-            {
-                $array[$i]=Database::fetch_array($Res, $i);
-                $p=$this->get_detail($array[$i], $type, $trunc, $a_TVA,
-                        $a_ParmCode);
-                if ($array[$i]['dep_priv']!=0.0)
-                {
-                    $array[$i]['comment'].="(priv. 
".$array[$i]['dep_priv'].")";
-                }
-            }
-        }
-        else
-        {
-            $array=Database::fetch_all($Res);
-        }
+    
 
-        return $array;
-    }
+    
 
-// end function get_rowSimple
 
     /**
      * @brief guess what  the next pj should be
@@ -626,313 +400,7 @@ class Acc_Ledger extends jrn_def_sql
     
 
     
-    /**
-     * @brief get_detail gives the detail of row
-     * this array must contains at least the field
-     *       <ul>
-     *       <li> montant</li>
-     *       <li> grpt_id
-     *       </ul>
-     * the following field will be added
-     *       <ul>
-     *       <li> HTVA
-     *       <li> TVAC
-     *       <li> TVA array with
-     *          <ul>
-     *          <li> field 0 idx
-     *          <li> array containing tva_id,tva_label and tva_amount
-     *          </ul>
-     *       </ul>
-     *
-     * @paramp_array the structure is set in get_rowSimple, this array is
-     *        modified,
-     @verbatim
-             jrn.jr_id as jr_id ,
-             jrn.jr_id as num ,
-             jrn.jr_def_id as jr_def_id,
-             jrn.jr_montant as montant,
-             substr(jrn.jr_comment,1,35) as comment,
-             to_char(jrn.jr_date,'DD-MM-YYYY') as date,
-             to_char(jrn.jr_date_paid,'DD-MM-YYYY') as date_paid,
-             jr_pj_number,
-             jr_internal,
-             jrn.jr_grpt_id as grpt_id,
-             jrn.jr_pj_name as pj,
-             jrn_def_type,
-             jrn.jr_tech_per
-     @endverbatim
-     * 
-     * @param $trunc if the data must be truncated, usefull for pdf export
-     * @paramp_jrn_type is the type of the ledger (ACH or VEN)
-     * @param $a_TVA TVA Array (default null)
-     * @param $a_ParmCode Array (default null)
-     * \return p_array
-     */
-    function get_detail(&$p_array, $p_jrn_type, $trunc=0, $a_TVA=null,
-            $a_ParmCode=null)
-    {
-        bcscale(2);
-
-        if ($a_TVA==null)
-        {
-            //Load TVA array
-            $a_TVA=$this->db->get_array('select tva_id,tva_label,tva_poste
-                                        from tva_rate where tva_rate != 0 
order by tva_rate,tva_label,tva_id');
-        }
-        if ($a_ParmCode==null)
-        {
-            //Load Parm_code
-            $a_ParmCode=$this->db->get_array('select p_code,p_value from 
parm_code');
-        }
-        // init
-        $p_array['client']="";
-        $p_array['TVAC']=0;
-        $p_array['HTVA']=0;
-        $p_array['TVA']=array();
-        $p_array['AMOUNT_TVA']=0.0;
-        $p_array['dep_priv']=0;
-        $p_array['dna']=0;
-        $p_array['tva_dna']=0;
-        $p_array['tva_np']=0;
-        $dep_priv=0.0;
-      
-       
-        // if using the QUANT_* tables then get there the needed info
-        //
-        if (  
$this->use_quant_table($p_array['grpt_id'],$p_array['jrn_def_type']) == TRUE)
-        {
-             // Initialize amount for VAT
-            $nb_tva=count($a_TVA);
-            for ($i=0;$i<$nb_tva;$i++) {
-                $p_array['TVA'][$i]=array($i,
-                    array(
-                        $a_TVA[$i]['tva_id'],
-                        $a_TVA[$i]['tva_label'],
-                        0)
-                    );
-            }
-            switch ($p_array['jrn_def_type'])
-            {
-                case "ACH":
-                    $sql="select 
-                            sum(coalesce(qp_price,0)) as htva,
-                            sum(coalesce(qp_vat)) as  vat,
-                            sum(coalesce(qp_nd_tva)) as  nd_tva,
-                            sum(coalesce(qp_nd_tva_recup)) as  nd_tva_recup,
-                            sum(coalesce(qp_dep_priv)) as dep_priv,
-                            qp_vat_code as tva_code,
-                            qp_supplier as fiche_id,
-                            qp_vat_sided as tva_sided
-                        from 
-                            quant_purchase 
-                        where 
-                            qp_internal=$1 
-                            group by qp_supplier,qp_vat_code,qp_vat_sided ";
-                    break;
-                case "VEN":
-                    $sql="select 
-                            sum(coalesce(qs_price,0)) as htva,
-                            sum(coalesce(qs_vat)) as  vat,
-                            sum(0) as  nd_tva,
-                            sum(0) as  nd_tva_recup,
-                            sum(0) as dep_priv,
-                            qs_vat_code as tva_code,
-                            qs_client as fiche_id,
-                            qs_vat_sided as tva_sided
-                        from 
-                            quant_sold
-                        where 
-                            qs_internal=$1 
-                            group by qs_client,qs_vat_code,qs_vat_sided ";
-                    break;
-
-                default:
-                    break;
-            }
-            
$a_detail=$this->db->get_array($sql,array($p_array['jr_internal']));
-            $nb_detail=count($a_detail);
-            for ($x=0;$x<$nb_detail;$x++) {
-                $p_array['HTVA']=bcadd($p_array['HTVA'],$a_detail[$x]['htva']);
-                
$p_array['tva_dna']=bcadd($p_array['tva_dna'],$a_detail[$x]['nd_tva_recup']);
-                
$p_array['tva_dna']=bcadd($p_array['tva_dna'],$a_detail[$x]['nd_tva']);
-                $p_array['TVAC']=bcadd($p_array['TVAC'],$a_detail[$x]['htva']);
-                if ( $a_detail[$x]['tva_sided'] == 0)
-                    
$p_array['TVAC']=bcadd($p_array['TVAC'],$a_detail[$x]['vat']);
-                
$p_array['TVAC']=bcadd($p_array['TVAC'],$a_detail[$x]['nd_tva']);
-                
$p_array['TVAC']=bcadd($p_array['TVAC'],$a_detail[$x]['nd_tva_recup']);
-                
$p_array['dep_priv']=bcadd($p_array['dep_priv'],$a_detail[$x]['dep_priv']);
-                $xdx=$a_detail[$x]['tva_code'];
-                // 
$p_array['TVA'][$xdx]=bcadd($p_array['TVA'][$xdx],$a_detail[$x]['vat']);
-                //--- Put VAT in the right place in the array $a_TVA
-                $nb_tva=count($a_TVA);
-                for ($j=0;$j<$nb_tva;$j++) { 
-                    if ( $xdx == $p_array['TVA'][$j][1][0]) {
-                        
$p_array['TVA'][$j][1][2]=bcadd($p_array['TVA'][$j][1][2],$a_detail[$x]['vat']);
-                        
-                    }
-                }
-            }
-            $fiche=new Fiche($this->db,$a_detail[0]['fiche_id']);
-            
$p_array['client']=($trunc==0)?$fiche->getName():mb_substr($fiche->getName(),0, 
20);
-            return $p_array;
-        }
-        //
-        // Retrieve data from jrnx
-        // Order is important for TVA autoreversed
-        $sql="select j_id,j_poste,j_montant, j_debit,j_qcode from jrnx where ".
-                " j_grpt=$1 order by 1 desc";
-        $Res2=$this->db->exec_sql($sql, array($p_array['grpt_id']));
-        $data_jrnx=Database::fetch_all($Res2);
-        $c=0;
-
-        // Parse data from jrnx and fill diff. field
-        foreach ($data_jrnx as $code)
-        {
-            $idx_tva=0;
-            $poste=new Acc_Account_Ledger($this->db, $code['j_poste']);
-
-            // if card retrieve name if the account is not a VAT account
-            if (strlen(trim($code['j_qcode']))!=0&&$poste->isTva()==0)
-            {
-                $fiche=new Fiche($this->db);
-                $fiche->get_by_qcode(trim($code['j_qcode']), false);
-                $fiche_def_id=$fiche->get_fiche_def_ref_id();
-                // Customer or supplier
-                if ($fiche_def_id==FICHE_TYPE_CLIENT||
-                        
$fiche_def_id==FICHE_TYPE_FOURNISSEUR||$fiche_def_id==FICHE_TYPE_ADM_TAX)
-                {
-                    $p_array['TVAC']=$code['j_montant'];
-
-                    
$p_array['client']=($trunc==0)?$fiche->getName():mb_substr($fiche->getName(),
-                                    0, 20);
-                    $p_array['reversed']=false;
-                    if 
($fiche_def_id==FICHE_TYPE_CLIENT&&$code['j_debit']=='f')
-                    {
-                        $p_array['reversed']=true;
-                        $p_array['TVAC']*=-1;
-                    }
-                    if 
($fiche_def_id==FICHE_TYPE_ADM_TAX&&$code['j_debit']=='f')
-                    {
-                        $p_array['reversed']=true;
-                        $p_array['TVAC']*=-1;
-                    }
-                    if 
($fiche_def_id==FICHE_TYPE_FOURNISSEUR&&$code['j_debit']=='t')
-                    {
-                        $p_array['reversed']=true;
-                        $p_array['TVAC']*=-1;
-                    }
-                }
-                else
-                {
-                    // if we use the ledger ven / ach for others card than 
supplier and customer
-                    if ($fiche_def_id!=FICHE_TYPE_VENTE&&
-                            $fiche_def_id!=FICHE_TYPE_ACH_MAR&&
-                            $fiche_def_id!=FICHE_TYPE_ACH_SER&&
-                            $fiche_def_id!=FICHE_TYPE_ACH_MAT
-                    )
-                    {
-                        $p_array['TVAC']=$code['j_montant'];
-
-                        
$p_array['client']=($trunc==0)?$fiche->getName():mb_substr($fiche->getName(),
-                                        0, 20);
-                        $p_array['reversed']=false;
-                        if ($p_jrn_type=='ACH'&&$code['j_debit']=='t')
-                        {
-                            $p_array['reversed']=true;
-                            $p_array['TVAC']*=-1;
-                        }
-                        if ($p_jrn_type=='VEN'&&$code['j_debit']=='f')
-                        {
-                            $p_array['reversed']=true;
-                            $p_array['TVAC']*=-1;
-                        }
-                    }
-                }
-            }
-            // if TVA, load amount, tva id and rate in array
-            foreach ($a_TVA as $line_tva)
-            {
-                list($tva_deb, $tva_cred)=explode(',', $line_tva['tva_poste']);
-                if ($code['j_poste']==$tva_deb||
-                        $code['j_poste']==$tva_cred)
-                {
-
-                    // For the reversed operation
-                    if ($p_jrn_type=='ACH'&&$code['j_debit']=='f')
-                    {
-                        $code['j_montant']=-1*$code['j_montant'];
-                    }
-                    if ($p_jrn_type=='VEN'&&$code['j_debit']=='t')
-                    {
-                        $code['j_montant']=-1*$code['j_montant'];
-                    }
-
-                    $p_array['AMOUNT_TVA']+=$code['j_montant'];
-
-                    $p_array['TVA'][$c]=array($idx_tva, 
array($line_tva['tva_id'],
-                            $line_tva['tva_label'], $code['j_montant']));
-                    $c++;
-
-                    $idx_tva++;
-                }
-            }
-
-            // isDNA
-            // If operation is reversed then  amount are negatif
-            /* if ND */
-            if ($p_array['jrn_def_type']=='ACH')
-            {
-                $purchase=new Gestion_Purchase($this->db);
-                $purchase->search_by_jid($code['j_id']);
-                $purchase->load();
-                $dep_priv+=$purchase->qp_dep_priv;
-                $p_array['dep_priv']=$dep_priv;
-                $p_array['dna']=bcadd($p_array['dna'], 
$purchase->qp_nd_amount);
-                $p_array['tva_dna']=bcadd($p_array['tva_dna'],
-                        bcadd($purchase->qp_nd_tva, 
$purchase->qp_nd_tva_recup));
-                $p_array['tva_np']=bcadd($purchase->qp_vat_sided,
-                        $p_array['tva_np']);
-            }
-            if ($p_array['jrn_def_type']=='VEN')
-            {
-                $sold=new gestion_sold($this->db);
-                $sold->search_by_jid($code['j_id']);
-                $sold->load();
-                $p_array['tva_np']=bcadd($sold->qs_vat_sided, 
$p_array['tva_np']);
-            }
-        }
-        $p_array['TVAC']=sprintf('% 10.2f', $p_array['TVAC']);
-        $p_array['HTVA']=sprintf('% 10.2f',
-                $p_array['TVAC']-$p_array['AMOUNT_TVA']-$p_array['tva_dna']);
-        $r="";
-        $a_tva_amount=array();
-        // inline TVA (used for the PDF)
-        foreach ($p_array['TVA'] as $linetva)
-        {
-            foreach ($a_TVA as $tva)
-            {
-                if ($tva['tva_id']==$linetva[1][0])
-                {
-                    $a=$tva['tva_id'];
-                    $a_tva_amount[$a]=$linetva[1][2];
-                }
-            }
-        }
-        foreach ($a_TVA as $line_tva)
-        {
-            $a=$line_tva['tva_id'];
-            if (isset($a_tva_amount[$a]))
-            {
-                $tmp=sprintf("% 10.2f", $a_tva_amount[$a]);
-                $r.="$tmp";
-            }
-            else
-                $r.=sprintf("% 10.2f", 0);
-        }
-        $p_array['TVA_INLINE']=$r;
-
-        return $p_array;
-    }
+   
 
 // retrieve data from jrnx
     /**
diff --git a/include/class/acc_ledger_history.class.php 
b/include/class/acc_ledger_history.class.php
new file mode 100644
index 0000000..61f0c1b
--- /dev/null
+++ b/include/class/acc_ledger_history.class.php
@@ -0,0 +1,283 @@
+<?php
+
+/*
+ * Copyright (C) 2018 Dany De Bontridder <address@hidden>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+/***
+ * @file 
+ * @brief Display history of operation
+ *
+ */
+require_once NOALYSS_INCLUDE."/class/acc_ledger_history_generic.class.php";
+require_once NOALYSS_INCLUDE."/class/acc_ledger_history_sale.class.php";
+/**
+ * @brief Display history of operation
+ */
+abstract class Acc_Ledger_History
+{
+
+    protected $m_from; //!< Starting Periode : periode.p_id
+    protected $m_to;   //!< Ending Periode : periode.p_id
+    protected $ma_ledger; //!< Array of ledger id : jrn_def.jrn_def_id
+    protected $m_mode; //!< mode of export L : one line, E accounting writing 
, D : Detail
+    public $db; //!< database connx
+
+    function __construct(Database $cn, $pa_ledger, $p_from, $p_to, $p_mode)
+    {
+        $this->db=$cn;
+        $this->ma_ledger=$pa_ledger;
+        $this->m_from=$p_from;
+        $this->m_to=$p_to;
+        $this->m_mode=$p_mode;
+    }
+    /**
+     * setter / getter
+     * @returns m_from (periode id)
+     */
+    public function get_from()
+    {
+        return $this->m_from;
+    }
+    /**
+     * setter / getter
+     * @returns m_to (periode id)
+     */
+    public function get_to()
+    {
+        return $this->m_to;
+    }
+    /**
+     * setter / getter
+     * @returns ma_ledger (array)
+     */
+    public function get_ledger()
+    {
+        return $this->ma_ledger;
+    }
+    /**
+     * setter / getter
+     * @returns m_mode (A,L,E,D)
+     */
+    public function get_mode()
+    {
+        return $this->m_mode;
+    }
+    /**
+     * setter m_from (periode id)
+     */
+    public function set_from($m_from)
+    {
+        $this->m_from=$m_from;
+        return $this;
+    }
+    /**
+     * setter m_to (periode id)
+     */
+    public function set_to($m_to)
+    {
+        $this->m_to=$m_to;
+        return $this;
+    }
+    /**
+     * setter ma_ledger (array of jrn_def_id)
+     */
+    public function set_a_ledger($ma_ledger)
+    {
+        if (is_array($ma_ledger)==FALSE)
+            throw new Exception(_("invalid parameter"), EXC_PARAM_VALUE);
+        $this->ma_ledger=$ma_ledger;
+        return $this;
+    }
+    /**
+     * Setter
+     * @param  $m_mode D,A,L,E
+     * @return $this
+     * @throws Exception
+     */
+    public function set_m_mode($m_mode)
+    {
+        if ($m_mode!='E'&&$m_mode!='D'&&$m_mode!='L'&&$m_mode!='A')
+            throw new Exception(_("invalid parameter"), EXC_PARAM_VALUE);
+        $this->m_mode=$m_mode;
+        return $this;
+    }
+
+    /**
+     * Build the right object 
+     * @return 
\Acc_Ledger_History_Generic|\Acc_Ledger_History_Sale|\Acc_Ledger_History_Financial|\Acc_Ledger_History_Purchase
+     */
+    static function factory(Database $cn, $pa_ledger, $p_from, $p_to, $p_mode)
+    {
+        // For Accounting writing , we use Acc_Ledger_History
+        if ($p_mode=="E")
+        {
+            $ret=new Acc_Ledger_History_Generic($cn, $pa_ledger, $p_from, 
$p_to,
+                    $p_mode);
+            return $ret;
+        }
+        $nb_ledger=count($pa_ledger);
+        $ledger=new Acc_Ledger($cn, $pa_ledger[0]);
+        $type=$ledger->get_type();
+
+        // If first one is ODS so Acc_Ledger_History
+        if ($type=="ODS")
+        {
+            $ret=new Acc_Ledger_History_Generic($cn, $pa_ledger, $p_from, 
$p_to,
+                    $p_mode);
+            return $ret;
+        }
+        // If all of the same type then use the corresponding class
+
+        for ($i=0; $i<$nb_ledger; $i++)
+        {
+            $ledger=new Acc_Ledger($cn, $pa_ledger[$i]);
+            $type_next=$ledger->get_type();
+
+            // If type different then we go back to the generic
+            if ($type_next!=$type)
+            {
+                $ret=new Acc_Ledger_History_Generic($cn, $pa_ledger, $p_from,
+                        $p_to, $p_mode);
+                return $ret;
+            }
+        }
+        switch ($type)
+        {
+            case "ACH":
+                $ret=new Acc_Ledger_History_Purchase($cn, $pa_ledger, $p_from,
+                        $p_to, $p_mode);
+                return $ret;
+                break;
+            case "FIN":
+                $ret=new Acc_Ledger_History_Financial($cn, $pa_ledger, $p_from,
+                        $p_to, $p_mode);
+                return $ret;
+                break;
+            case "VEN":
+                $ret=new Acc_Ledger_History_Sale($cn, $pa_ledger, $p_from,
+                        $p_to, $p_mode);
+                return $ret;
+                break;
+
+            default:
+                break;
+        }
+    }
+
+    /**
+     * Retrieve the third : supplier for purchase, customer for sale, bank for 
fin,
+     * @param $p_jrn_type type of the ledger FIN, VEN ACH or ODS
+     * @param $jr_id jrn.jr_id
+     * @todo duplicate function , also in Acc_Ledger::get_tiers, remove one
+     */
+    function get_tiers($p_jrn_type, $jr_id)
+    {
+        if ($p_jrn_type=='ODS')
+            return ' ';
+        $tiers=$this->get_tiers_id($p_jrn_type, $jr_id);
+        if ($tiers==0)
+            return "";
+
+        $name=$this->db->get_value('select ad_value from fiche_detail where 
ad_id=1 and f_id=$1',
+                array($tiers));
+        $first_name=$this->db->get_value('select ad_value from fiche_detail 
where ad_id=32 and f_id=$1',
+                array($tiers));
+        return $name.' '.$first_name;
+    }
+
+    /**
+     * @brief Return the f_id of the tiers , called by get_tiers
+     * @param $p_jrn_type type of the ledger FIN, VEN ACH or ODS
+     * @param $jr_id jrn.jr_id
+    */
+    function get_tiers_id($p_jrn_type, $jr_id)
+    {
+        $tiers=0;
+        switch ($p_jrn_type)
+        {
+            case 'VEN':
+                $tiers=$this->db->get_value('select max(qs_client) from 
quant_sold join jrnx using (j_id) join jrn on (jr_grpt_id=j_grpt) where 
jrn.jr_id=$1',
+                        array($jr_id));
+                break;
+            case 'ACH':
+                $tiers=$this->db->get_value('select max(qp_supplier) from 
quant_purchase join jrnx using (j_id) join jrn on (jr_grpt_id=j_grpt) where 
jrn.jr_id=$1',
+                        array($jr_id));
+
+                break;
+            case 'FIN':
+                $tiers=$this->db->get_value('select qf_other from quant_fin 
where jr_id=$1',
+                        array($jr_id));
+                break;
+        }
+        if ($this->db->count()==0)
+            return 0;
+        return $tiers;
+    }
+
+    /**
+     * Prepare the query for fetching the linked operation
+     * @staticvar int $prepare
+     */
+    protected function prepare_reconcile_date()
+    {
+        static $prepare=0;
+        if ($prepare==0)
+        {
+            $this->db->prepare('reconcile_date',
+                    'select  * 
+                         from 
+                           jrn 
+                         where 
+                           jr_id in 
+                               (select 
+                                   jra_concerned 
+                                   from 
+                                   jrn_rapt 
+                                   where jr_id = $1 
+                                union all 
+                                select 
+                                jr_id 
+                                from jrn_rapt 
+                                where jra_concerned=$1)');
+        }
+        $prepare=1;
+    }
+    /**
+     * display accounting of operations m_mode=A
+     */
+    abstract function export_accounting_html();
+    /**
+     * display detail of operations m_mode=D
+     */
+    abstract function export_detail_html();
+    /**
+     * display extended details of operation m_mode=E
+     */
+    abstract function export_extended_html();
+    /**
+     * display operation on one line m_mode=L
+     */
+    abstract function export_oneline_html();
+    /**
+     * call the right function , depending of m_mode
+     */
+    abstract function export_html();
+
+    abstract function get_row($p_limit, $p_offset);
+}
diff --git a/include/class/acc_ledger_history_financial.class.php 
b/include/class/acc_ledger_history_financial.class.php
new file mode 100644
index 0000000..07e0ec1
--- /dev/null
+++ b/include/class/acc_ledger_history_financial.class.php
@@ -0,0 +1,28 @@
+<?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 (2018) Author Dany De Bontridder <address@hidden>
+
+
+/**
+ * @file
+ * @brief 
+ * @param type $name Descriptionara
+ */
+?>
diff --git a/include/class/acc_ledger_history_generic.class.php 
b/include/class/acc_ledger_history_generic.class.php
new file mode 100644
index 0000000..714dc95
--- /dev/null
+++ b/include/class/acc_ledger_history_generic.class.php
@@ -0,0 +1,737 @@
+<?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 (2018) Author Dany De Bontridder <address@hidden>
+
+/**
+ * @file
+ * @brief class for Ledger's history, list of operation for MISC, FIN, ACH and 
VEN
+ * 
+ */
+
+/**
+ * @brief manage the list of operation when we need several ledger with a 
different
+ * type or from Misceleaneous ledger 
+ * @include acc_ledger_historyTest.php
+ */
+class Acc_Ledger_History_Generic extends Acc_Ledger_History
+{
+
+    private $data; //!< array of rows
+    /**
+     * Constructor
+     * @param Database $cn
+     * @param type $pa_ledger
+     * @param type $p_from
+     * @param type $p_to
+     * @param type $p_mode
+     * @example acc_ledger_historyTest.php
+     */
+    function __construct(Database $cn, $pa_ledger, $p_from, $p_to, $p_mode)
+    {
+        parent::__construct($cn, $pa_ledger, $p_from, $p_to, $p_mode);
+        $this->data=[];
+    }
+
+    /**
+     * @brief get_detail gives the detail of row
+     * this array must contains at least the field
+     *       <ul>
+     *       <li> montant</li>
+     *       <li> grpt_id
+     *       </ul>
+     * the following field will be added
+     *       <ul>
+     *       <li> HTVA
+     *       <li> TVAC
+     *       <li> TVA array with
+     *          <ul>
+     *          <li> field 0 idx
+     *          <li> array containing tva_id,tva_label and tva_amount
+     *          </ul>
+     *       </ul>
+     *
+     * @paramp_array the structure is set in get_rowSimple, this array is
+     *        modified,
+      @verbatim
+      jrn.jr_id as jr_id ,
+      jrn.jr_id as num ,
+      jrn.jr_def_id as jr_def_id,
+      jrn.jr_montant as montant,
+      substr(jrn.jr_comment,1,35) as comment,
+      to_char(jrn.jr_date,'DD-MM-YYYY') as date,
+      to_char(jrn.jr_date_paid,'DD-MM-YYYY') as date_paid,
+      jr_pj_number,
+      jr_internal,
+      jrn.jr_grpt_id as grpt_id,
+      jrn.jr_pj_name as pj,
+      jrn_def_type,
+      jrn.jr_tech_per
+      @endverbatim
+     * 
+     * @param $trunc if the data must be truncated, usefull for pdf export
+     * @paramp_jrn_type is the type of the ledger (ACH or VEN)
+     * @param $a_TVA TVA Array (default null)
+     * @param $a_ParmCode Array (default null)
+     * 
+     * @todo useless since only 2 modes are supported : oneline and extended 
(accounting writing) but
+     * can be used for ledger before 2007
+     * \return p_array
+     */
+    function get_detail(&$p_array, $p_jrn_type, $trunc=0, $a_TVA=null,
+            $a_ParmCode=null)
+    {
+        bcscale(2);
+
+        if ($a_TVA==null)
+        {
+            //Load TVA array
+            $a_TVA=$this->db->get_array('select tva_id,tva_label,tva_poste
+                                        from tva_rate where tva_rate != 0 
order by tva_rate,tva_label,tva_id');
+        }
+        if ($a_ParmCode==null)
+        {
+            //Load Parm_code
+            $a_ParmCode=$this->db->get_array('select p_code,p_value from 
parm_code');
+        }
+        // init
+        $p_array['client']="";
+        $p_array['TVAC']=0;
+        $p_array['HTVA']=0;
+        $p_array['TVA']=array();
+        $p_array['AMOUNT_TVA']=0.0;
+        $p_array['dep_priv']=0;
+        $p_array['dna']=0;
+        $p_array['tva_dna']=0;
+        $p_array['tva_np']=0;
+        $dep_priv=0.0;
+
+
+        // if using the QUANT_* tables then get there the needed info
+        //
+        if ($this->use_quant_table($p_array['grpt_id'], 
$p_array['jrn_def_type'])
+                ==TRUE)
+        {
+            // Initialize amount for VAT
+            $nb_tva=count($a_TVA);
+            for ($i=0; $i<$nb_tva; $i++)
+            {
+                $p_array['TVA'][$i]=array($i,
+                    array(
+                        $a_TVA[$i]['tva_id'],
+                        $a_TVA[$i]['tva_label'],
+                        0)
+                );
+            }
+            switch ($p_array['jrn_def_type'])
+            {
+                case "ACH":
+                    $sql="select 
+                            sum(coalesce(qp_price,0)) as htva,
+                            sum(coalesce(qp_vat)) as  vat,
+                            sum(coalesce(qp_nd_tva)) as  nd_tva,
+                            sum(coalesce(qp_nd_tva_recup)) as  nd_tva_recup,
+                            sum(coalesce(qp_dep_priv)) as dep_priv,
+                            qp_vat_code as tva_code,
+                            qp_supplier as fiche_id,
+                            qp_vat_sided as tva_sided
+                        from 
+                            quant_purchase 
+                        where 
+                            qp_internal=$1 
+                            group by qp_supplier,qp_vat_code,qp_vat_sided ";
+                    break;
+                case "VEN":
+                    $sql="select 
+                            sum(coalesce(qs_price,0)) as htva,
+                            sum(coalesce(qs_vat)) as  vat,
+                            sum(0) as  nd_tva,
+                            sum(0) as  nd_tva_recup,
+                            sum(0) as dep_priv,
+                            qs_vat_code as tva_code,
+                            qs_client as fiche_id,
+                            qs_vat_sided as tva_sided
+                        from 
+                            quant_sold
+                        where 
+                            qs_internal=$1 
+                            group by qs_client,qs_vat_code,qs_vat_sided ";
+                    break;
+
+                default:
+                    break;
+            }
+            $a_detail=$this->db->get_array($sql, 
array($p_array['jr_internal']));
+            $nb_detail=count($a_detail);
+            for ($x=0; $x<$nb_detail; $x++)
+            {
+                $p_array['HTVA']=bcadd($p_array['HTVA'], 
$a_detail[$x]['htva']);
+                $p_array['tva_dna']=bcadd($p_array['tva_dna'],
+                        $a_detail[$x]['nd_tva_recup']);
+                $p_array['tva_dna']=bcadd($p_array['tva_dna'],
+                        $a_detail[$x]['nd_tva']);
+                $p_array['TVAC']=bcadd($p_array['TVAC'], 
$a_detail[$x]['htva']);
+                if ($a_detail[$x]['tva_sided']==0)
+                    $p_array['TVAC']=bcadd($p_array['TVAC'],
+                            $a_detail[$x]['vat']);
+                $p_array['TVAC']=bcadd($p_array['TVAC'], 
$a_detail[$x]['nd_tva']);
+                $p_array['TVAC']=bcadd($p_array['TVAC'],
+                        $a_detail[$x]['nd_tva_recup']);
+                $p_array['dep_priv']=bcadd($p_array['dep_priv'],
+                        $a_detail[$x]['dep_priv']);
+                $xdx=$a_detail[$x]['tva_code'];
+                // 
$p_array['TVA'][$xdx]=bcadd($p_array['TVA'][$xdx],$a_detail[$x]['vat']);
+                //--- Put VAT in the right place in the array $a_TVA
+                $nb_tva=count($a_TVA);
+                for ($j=0; $j<$nb_tva; $j++)
+                {
+                    if ($xdx==$p_array['TVA'][$j][1][0])
+                    {
+                        
$p_array['TVA'][$j][1][2]=bcadd($p_array['TVA'][$j][1][2],
+                                $a_detail[$x]['vat']);
+                    }
+                }
+            }
+            $fiche=new Fiche($this->db, $a_detail[0]['fiche_id']);
+            
$p_array['client']=($trunc==0)?$fiche->getName():mb_substr($fiche->getName(),
+                            0, 20);
+            return $p_array;
+        }
+        //
+        // Retrieve data from jrnx
+        // Order is important for TVA autoreversed
+        $sql="select j_id,j_poste,j_montant, j_debit,j_qcode from jrnx where ".
+                " j_grpt=$1 order by 1 desc";
+        $Res2=$this->db->exec_sql($sql, array($p_array['grpt_id']));
+        $data_jrnx=Database::fetch_all($Res2);
+        $c=0;
+
+        // Parse data from jrnx and fill diff. field
+        foreach ($data_jrnx as $code)
+        {
+            $idx_tva=0;
+            $poste=new Acc_Account_Ledger($this->db, $code['j_poste']);
+
+            // if card retrieve name if the account is not a VAT account
+            if (strlen(trim($code['j_qcode']))!=0&&$poste->isTva()==0)
+            {
+                $fiche=new Fiche($this->db);
+                $fiche->get_by_qcode(trim($code['j_qcode']), false);
+                $fiche_def_id=$fiche->get_fiche_def_ref_id();
+                // Customer or supplier
+                if ($fiche_def_id==FICHE_TYPE_CLIENT||
+                        
$fiche_def_id==FICHE_TYPE_FOURNISSEUR||$fiche_def_id==FICHE_TYPE_ADM_TAX)
+                {
+                    $p_array['TVAC']=$code['j_montant'];
+
+                    
$p_array['client']=($trunc==0)?$fiche->getName():mb_substr($fiche->getName(),
+                                    0, 20);
+                    $p_array['reversed']=false;
+                    if 
($fiche_def_id==FICHE_TYPE_CLIENT&&$code['j_debit']=='f')
+                    {
+                        $p_array['reversed']=true;
+                        $p_array['TVAC']*=-1;
+                    }
+                    if 
($fiche_def_id==FICHE_TYPE_ADM_TAX&&$code['j_debit']=='f')
+                    {
+                        $p_array['reversed']=true;
+                        $p_array['TVAC']*=-1;
+                    }
+                    if 
($fiche_def_id==FICHE_TYPE_FOURNISSEUR&&$code['j_debit']=='t')
+                    {
+                        $p_array['reversed']=true;
+                        $p_array['TVAC']*=-1;
+                    }
+                }
+                else
+                {
+                    // if we use the ledger ven / ach for others card than 
supplier and customer
+                    if ($fiche_def_id!=FICHE_TYPE_VENTE&&
+                            $fiche_def_id!=FICHE_TYPE_ACH_MAR&&
+                            $fiche_def_id!=FICHE_TYPE_ACH_SER&&
+                            $fiche_def_id!=FICHE_TYPE_ACH_MAT
+                    )
+                    {
+                        $p_array['TVAC']=$code['j_montant'];
+
+                        
$p_array['client']=($trunc==0)?$fiche->getName():mb_substr($fiche->getName(),
+                                        0, 20);
+                        $p_array['reversed']=false;
+                        if ($p_jrn_type=='ACH'&&$code['j_debit']=='t')
+                        {
+                            $p_array['reversed']=true;
+                            $p_array['TVAC']*=-1;
+                        }
+                        if ($p_jrn_type=='VEN'&&$code['j_debit']=='f')
+                        {
+                            $p_array['reversed']=true;
+                            $p_array['TVAC']*=-1;
+                        }
+                    }
+                }
+            }
+            // if TVA, load amount, tva id and rate in array
+            foreach ($a_TVA as $line_tva)
+            {
+                list($tva_deb, $tva_cred)=explode(',', $line_tva['tva_poste']);
+                if ($code['j_poste']==$tva_deb||
+                        $code['j_poste']==$tva_cred)
+                {
+
+                    // For the reversed operation
+                    if ($p_jrn_type=='ACH'&&$code['j_debit']=='f')
+                    {
+                        $code['j_montant']=-1*$code['j_montant'];
+                    }
+                    if ($p_jrn_type=='VEN'&&$code['j_debit']=='t')
+                    {
+                        $code['j_montant']=-1*$code['j_montant'];
+                    }
+
+                    $p_array['AMOUNT_TVA']+=$code['j_montant'];
+
+                    $p_array['TVA'][$c]=array($idx_tva, 
array($line_tva['tva_id'],
+                            $line_tva['tva_label'], $code['j_montant']));
+                    $c++;
+
+                    $idx_tva++;
+                }
+            }
+
+            // isDNA
+            // If operation is reversed then  amount are negatif
+            /* if ND */
+            if ($p_array['jrn_def_type']=='ACH')
+            {
+                $purchase=new Gestion_Purchase($this->db);
+                $purchase->search_by_jid($code['j_id']);
+                $purchase->load();
+                $dep_priv+=$purchase->qp_dep_priv;
+                $p_array['dep_priv']=$dep_priv;
+                $p_array['dna']=bcadd($p_array['dna'], 
$purchase->qp_nd_amount);
+                $p_array['tva_dna']=bcadd($p_array['tva_dna'],
+                        bcadd($purchase->qp_nd_tva, 
$purchase->qp_nd_tva_recup));
+                $p_array['tva_np']=bcadd($purchase->qp_vat_sided,
+                        $p_array['tva_np']);
+            }
+            if ($p_array['jrn_def_type']=='VEN')
+            {
+                $sold=new gestion_sold($this->db);
+                $sold->search_by_jid($code['j_id']);
+                $sold->load();
+                $p_array['tva_np']=bcadd($sold->qs_vat_sided, 
$p_array['tva_np']);
+            }
+        }
+        $p_array['TVAC']=sprintf('% 10.2f', $p_array['TVAC']);
+        $p_array['HTVA']=sprintf('% 10.2f',
+                $p_array['TVAC']-$p_array['AMOUNT_TVA']-$p_array['tva_dna']);
+        $r="";
+        $a_tva_amount=array();
+        // inline TVA (used for the PDF)
+        foreach ($p_array['TVA'] as $linetva)
+        {
+            foreach ($a_TVA as $tva)
+            {
+                if ($tva['tva_id']==$linetva[1][0])
+                {
+                    $a=$tva['tva_id'];
+                    $a_tva_amount[$a]=$linetva[1][2];
+                }
+            }
+        }
+        foreach ($a_TVA as $line_tva)
+        {
+            $a=$line_tva['tva_id'];
+            if (isset($a_tva_amount[$a]))
+            {
+                $tmp=sprintf("% 10.2f", $a_tva_amount[$a]);
+                $r.="$tmp";
+            }
+            else
+                $r.=sprintf("% 10.2f", 0);
+        }
+        $p_array['TVA_INLINE']=$r;
+
+        return $p_array;
+    }
+
+    /**
+     * @brief depending on the mode will call the right function
+     *  - export_oneline_html for one line (mode=L)
+     *  - export_accounting_html for accounting (mode=A,D,E)
+     */
+    function export_html()
+    {
+        switch ($this->m_mode)
+        {
+            case "E":
+                $this->export_accounting_html();
+                break;
+            case "D":
+                $this->export_accounting_html();
+                break;
+            case "L":
+                $this->export_oneline_html();
+                break;
+            case "A":
+                $this->export_accounting_html();
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * @brief  Get simplified row from ledger
+     *
+     * @param p_from periode
+     * @param p_to periode
+     * @param p_limit starting line
+     * @param p_offset number of lines
+     * @param trunc if data must be truncated (pdf export)
+     * @todo  Prévoir aussi les journaux sans tables quant < 2007
+     * @return numbe of rows found
+     */
+    function get_rowSimple($trunc=0, $p_limit=-1, $p_offset=-1)
+    {
+        global $g_user;
+        $jrn=" jrn_def_id in (".join($this->ma_ledger, ",").")" ;
+
+        $periode=sql_filter_per($this->db, $this->m_from, $this->m_to, 'p_id',
+                'jr_tech_per');
+
+        $cond_limite=($p_limit!=-1)?" limit ".$p_limit." offset ".$p_offset:"";
+        //---
+        $sql="
+             SELECT jrn.jr_id as jr_id ,
+             jrn.jr_id as num ,
+             jrn.jr_def_id as jr_def_id,
+             jrn.jr_montant as montant,
+             substr(jrn.jr_comment,1,35) as comment,
+             to_char(jrn.jr_date,'DD-MM-YYYY') as date,
+             to_char(jrn.jr_date_paid,'DD-MM-YYYY') as date_paid,
+             jr_pj_number,
+             jr_internal,
+             jrn.jr_grpt_id as grpt_id,
+             jrn.jr_pj_name as pj,
+             jrn_def_type,
+             jrn.jr_tech_per
+             FROM jrn join jrn_def on (jrn_def_id=jr_def_id)
+             WHERE $periode and $jrn order by 
jr_date,substring(jrn.jr_pj_number,'[0-9]+$')::numeric asc  $cond_limite";
+        $Res=$this->db->exec_sql($sql);
+        $Max=Database::num_row($Res);
+        if ($Max==0)
+        {
+            return 0;
+        }
+//        @todo Pas nécessaire puisqu'on ne traite que les journaux 
d'opération diverses, 
+//        Il faudrait p-e prévoir un système pour les journaux avant 2007 qui 
n'utilisaient
+//        pas les tables quant
+//        
+//        $type=$this->get_type();
+//        // for type ACH and Ven we take more info
+//        if ($type=='ACH'||$type=='VEN')
+//        {
+//            $a_ParmCode=$this->db->get_array('select p_code,p_value from 
parm_code');
+//            $a_TVA=$this->db->get_array('select tva_id,tva_label,tva_poste
+//                                        from tva_rate where tva_rate != 0 
order by tva_rate,tva_label,tva_id ');
+//            for ($i=0; $i<$Max; $i++)
+//            {
+//                $array[$i]=Database::fetch_array($Res, $i);
+//                $p=$this->get_detail($array[$i], $type, $trunc, $a_TVA,
+//                        $a_ParmCode);
+//                if ($array[$i]['dep_priv']!=0.0)
+//                {
+//                    $array[$i]['comment'].="(priv. 
".$array[$i]['dep_priv'].")";
+//                }
+//            }
+//        }
+//        else
+//        {
+        $array=Database::fetch_all($Res);
+//        }
+
+        $this->data=$array;
+        return $Max;
+    }
+
+    /**
+     * @brief  set $this->data with the array of rows
+     *
+     *
+     * @param p_limit starting line
+     * @param p_offset number of lines
+     * @returns nb of rows found
+     *
+     */
+    function get_row($p_limit=-1, $p_offset=-1)
+    {
+        global $g_user;
+        $periode=sql_filter_per($this->db, $this->m_from, $this->m_to, 'p_id',
+                'jr_tech_per');
+
+        $cond_limite=($p_limit!=-1)?" limit ".$p_limit." offset ".$p_offset:"";
+
+        $ledger_list=join($this->ma_ledger, ",");
+// Grand livre == 0
+        $Res=$this->db->exec_sql("select jr_id,j_id,j_id as 
int_j_id,to_char(j_date,'DD.MM.YYYY') as j_date,
+                                     jr_internal,
+                                     case j_debit when 't' then 
j_montant::text else '   ' end as deb_montant,
+                                     case j_debit when 'f' then 
j_montant::text else '   ' end as cred_montant,
+                                     j_debit as debit,j_poste as 
poste,j_qcode,jr_montant , ".
+                "case when j_text='' or j_text is null then pcm_lib else 
j_text end as description,j_grpt as grp,
+                                     jr_comment||' ('||jr_internal||')'  as 
jr_comment,
+                                    jr_pj_number,
+                                     j_qcode,
+                                     jrn_def_type,
+                                     jr_rapt as oc, j_tech_per as periode
+                                     from jrnx left join jrn on 
+                   jr_grpt_id=j_grpt 
+                   left join tmp_pcmn on pcm_val=j_poste 
+                   join jrn_def on (jrn_def_id=jr_def_id)
+                    where j_jrn_def in (".$ledger_list.") 
+                    and ".$periode."
+                    order by j_date::date 
asc,substring(jr_pj_number,'[0-9]+$')::numeric asc,j_grpt,j_debit desc ".
+                $cond_limite);
+
+        $array=array();
+        $Max=Database::num_row($Res);
+        if ($Max==0)
+            return 0;
+        $case="";
+        $tot_deb=0;
+        $tot_cred=0;
+        $row=Database::fetch_all($Res);
+        bcscale(2);
+        for ($i=0; $i<$Max; $i++)
+        {
+
+            $line=$row[$i];
+            $tot_deb=bcadd($tot_deb, $line['deb_montant']);
+            $tot_cred=bcadd($tot_cred, $line['cred_montant']);
+            $tot_op=$line['jr_montant'];
+
+            /* Check first if there is a quickcode */
+            if 
(strlen(trim($line['description']))==0&&strlen(trim($line['j_qcode']))
+                    !=0)
+            {
+                $fiche=new Fiche($this->db);
+                if ($fiche->get_by_qcode($line['j_qcode'], false)==0)
+                {
+                    $line['description']=$fiche->strAttribut(ATTR_DEF_NAME);
+                }
+            }
+            if ($case!=$line['grp'])
+            {
+                $case=$line['grp'];
+                // for financial, we show if the amount is or not in negative
+                if ($line['jrn_def_type']=='FIN')
+                {
+                    $amount=$this->db->get_value('select qf_amount from 
quant_fin where jr_id=$1',
+                            array($line['jr_id']));
+                    /*  if nothing is found */
+                    if ($this->db->count()==0)
+                        $tot_op=$line['jr_montant'];
+                    else if ($amount<0)
+                    {
+                        $tot_op=$amount;
+                    }
+                }
+                $array[]=array(
+                    'jr_id'=>$line['jr_id'],
+                    'int_j_id'=>$line['int_j_id'],
+                    'j_id'=>$line['j_id'],
+                    'j_date'=>$line['j_date'],
+                    'internal'=>$line['jr_internal'],
+                    'deb_montant'=>'',
+                    'cred_montant'=>' ',
+                    'description'=>'<b><i>'.h($line['jr_comment']).' 
['.$tot_op.'] </i></b>',
+                    'poste'=>$line['oc'],
+                    'j_qcode'=>$line['j_qcode'],
+                    'periode'=>$line['periode'],
+                    'jr_pj_number'=>$line ['jr_pj_number'],
+                    "ledger_type"=>$line['jrn_def_type']);
+
+                $array[]=array(
+                    'jr_id'=>'',
+                    'int_j_id'=>$line['int_j_id'],
+                    'j_id'=>'',
+                    'j_date'=>'',
+                    'internal'=>'',
+                    'deb_montant'=>$line['deb_montant'],
+                    'cred_montant'=>$line['cred_montant'],
+                    'description'=>$line['description'],
+                    'poste'=>$line['poste'],
+                    'j_qcode'=>$line['j_qcode'],
+                    'periode'=>$line['periode'],
+                    'jr_pj_number'=>'',
+                    "ledger_type"=>$line['jrn_def_type']
+                );
+            }
+            else
+            {
+                $array[]=array(
+                    'jr_id'=>$line['jr_id'],
+                    'int_j_id'=>$line['int_j_id'],
+                    'j_id'=>'',
+                    'j_date'=>'',
+                    'internal'=>'',
+                    'deb_montant'=>$line['deb_montant'],
+                    'cred_montant'=>$line['cred_montant'],
+                    'description'=>$line['description'],
+                    'poste'=>$line['poste'],
+                    'j_qcode'=>$line['j_qcode'],
+                    'periode'=>$line['periode'],
+                    'jr_pj_number'=>'',
+                    "ledger_type"=>$line['jrn_def_type']);
+            }
+        }
+        $this->data=array($array, $tot_deb, $tot_cred);
+        return $Max;
+    }
+    /**
+     * display in  html the detail the list of operation
+     */
+    public function export_detail_html()
+    {
+        $this->export_accounting_html();
+    }
+    /**
+     * display in  html with extended detail the list of operation
+     */
+    public function export_extended_html()
+    {
+        $this->export_accounting_html();
+    }
+    /**
+     * display in  html the accounting of the list of operations
+     */
+    public function export_accounting_html()
+    {
+    
+        $this->get_row();
+        echo '<TABLE class="result">';
+// detailled printing
+//---
+        foreach ($this->data[0] as $op)
+        {
+            $class="";
+            if ($op['j_date']!='')
+            {
+                $class="odd";
+            }
+
+            echo "<TR  class=\"$class\">";
+
+            echo "<TD>".$op['j_date']."</TD>";
+            echo "<TD >".$op['jr_pj_number']."</TD>";
+
+
+            if ($op['internal']!='')
+                echo "<TD>".HtmlInput::detail_op($op['jr_id'], 
$op['internal'])."</TD>";
+            else
+                echo td();
+
+            echo "<TD >".$op['poste']."</TD>".
+            "<TD  >".$op['description']."</TD>".
+            "<TD   
style=\"text-align:right\">".nbm($op['deb_montant'])."</TD>".
+            "<TD style=\"text-align:right\">".nbm($op['cred_montant'])."</TD>".
+            "</TR>";
+        }// end loop
+        echo "</table>";
+
+// show the saldo
+//@todo use <li> instead of <br>
+        echo _("solde débiteur:").$this->data[1]."<br>";
+        echo _("solde créditeur:").$this->data[2];
+    }
+    /**
+     * @brief list operation on one line per operation
+     */
+    public function export_oneline_html()
+    {
+        $this->get_rowSimple();
+        echo '<TABLE class="result">';
+        echo "<TR>".
+        th(_("Date")).
+        th(_("n° pièce")).
+        th(_("internal")).
+        th(_("Tiers")).
+        th(_("Commentaire")).
+        th(_("Total opération")).
+        "</TR>";
+        // set a filter for the FIN
+        $i=0; $tot_amount=0;
+        bcscale(2);
+        foreach ($this->data as $line)
+        {
+            $i++;
+            $class=($i%2==0)?' class="even" ':' class="odd" ';
+            echo "<tr $class>";
+            echo "<TD>".$line['date']."</TD>";
+            echo "<TD>".h($line['jr_pj_number'])."</TD>";
+            echo "<TD>".HtmlInput::detail_op($line['jr_id'],
+                    $line['jr_internal'])."</TD>";
+            $tiers=$this->get_tiers($line['jrn_def_type'], $line['jr_id']);
+            echo td($tiers);
+            echo "<TD>".h($line['comment'])."</TD>";
+
+
+            //   echo "<TD>".$line['pj']."</TD>";
+            // If the ledger is financial :
+            // the credit must be negative and written in red
+            // Get the jrn type
+            if ($line['jrn_def_type']=='FIN')
+            {
+                $positive=$this->db->get_value("select qf_amount from 
quant_fin where jr_id=$1",
+                        array($line['jr_id']));
+                if ($this->db->count()==0)
+                    $positive=1;
+                else
+                    $positive=($positive>0)?1:0;
+
+                echo "<TD align=\"right\">";
+                echo ( $positive==0 )?"<font color=\"red\">  - 
".nbm($line['montant'])."</font>":nbm($line['montant']);
+                echo "</TD>";
+                if ($positive==1)
+                {
+                    $tot_amount=bcadd($tot_amount, $line['montant']);
+                }
+                else
+                {
+                    $tot_amount=bcsub($tot_amount, $line['montant']);
+                }
+            }
+            else
+            {
+                echo "<TD align=\"right\">".nbm($line['montant'])."</TD>";
+                $tot_amount=bcadd($tot_amount, $line['montant']);
+            }
+
+            echo "</tr>";
+        }
+        echo '<tr class="highlight">';
+        echo '<td>'._('Totaux').'</td>';
+        echo td().td().td().td();
+        echo '<td class="num">'.nbm($tot_amount).'</td>';
+        echo '</tr>';
+        echo "</table>";
+    }
+
+}
diff --git a/include/class/acc_ledger_history_purchase.class.php 
b/include/class/acc_ledger_history_purchase.class.php
new file mode 100644
index 0000000..64b9b55
--- /dev/null
+++ b/include/class/acc_ledger_history_purchase.class.php
@@ -0,0 +1,26 @@
+<?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 (2018) Author Dany De Bontridder <address@hidden>
+
+/**
+ * @file
+ * @brief 
+ */
+?>
diff --git a/include/class/acc_ledger_history_sale.class.php 
b/include/class/acc_ledger_history_sale.class.php
new file mode 100644
index 0000000..217b184
--- /dev/null
+++ b/include/class/acc_ledger_history_sale.class.php
@@ -0,0 +1,222 @@
+<?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 (2018) Author Dany De Bontridder <address@hidden>
+
+/**
+ * @file
+ * @brief Acc_Ledger_History : Manage the list (history) of operations for 
display
+ */
+require_once NOALYSS_INCLUDE."/class/acc_ledger_history.class.php";
+
+/**
+ * @brief Acc_Ledger_History : Manage the list (history) of operations for 
display
+ */
+class Acc_Ledger_History_Sale extends Acc_Ledger_History
+{
+
+    private $data; //!< Contains rows from SQL
+
+    public function __construct(\Database $cn, $pa_ledger, $p_from, $p_to,
+            $p_mode)
+    {
+        parent::__construct($cn, $pa_ledger, $p_from, $p_to, $p_mode);
+    }
+    /**
+     * Display the operation of sales with detailled VAT
+     */
+    public function export_detail_html()
+    {
+        $own=new Noalyss_Parameter_Folder($this->db);
+
+        $this->get_row();
+        $this->add_vat_info();
+        $this->prepare_reconcile_date();
+        include NOALYSS_TEMPLATE."/acc_ledger_history_sale_detail.php";
+    }
+    /**
+     * @brief display the accounting 
+     */
+    public function export_accounting_html()
+    {
+        $ledger_history=new Acc_Ledger_History_Generic($this->db,
+                $this->ma_ledger, $this->m_from, $this->m_to, $this->m_mode);
+        $ledger_history->export_accounting_html();
+    }
+    /**
+     * display the operation with detailled vat per item
+     */
+    public function export_extended_html()
+    {
+       $this->get_row();
+       $this->add_vat_info();
+       $this->prepare_detail();
+       include NOALYSS_TEMPLATE."/acc_ledger_history_sale_extended.php";
+    }
+    /**
+     * Prepare the query for fetching detail of an operation
+     * @staticvar int $prepare
+     */
+    private function prepare_detail()
+    {
+        static $prepare=0;
+        if ( $prepare == 0) 
+        {
+            $this->db->prepare("detail_sale","
+                with card_name as 
+                (select f_id,ad_value as name 
+                    from fiche_detail where ad_id=1),
+                card_qcode as  
+                (select f_id,ad_value as qcode 
+                from fiche_detail where ad_id=23)
+                select         
qs_price,qs_quantite,qs_vat,qs_vat_code,qs_unit,qs_vat_sided,name,qcode,tva_label,
+                qs_price+qs_vat-qs_vat_sided as tvac
+                from 
+                    quant_sold
+                    join jrnx using (j_id)              
+                    join card_name on (card_name.f_id=qs_fiche)
+                    join card_qcode on (card_qcode.f_id=qs_fiche)
+                    join tva_rate on ( qs_vat_code=tva_id)
+                where
+                    qs_internal=$1
+                
+            ");
+        }
+        $prepare=1;        
+    }
+    /**
+     * Get the rows from jrnx and quant* tables
+     * @param int $p_limit max of rows to returns
+     * @param int $p_offset the number of rows to skip
+     */
+    public function get_row($p_limit=-1, $p_offset="")
+    {
+        $periode=sql_filter_per($this->db, $this->m_from, $this->m_to, 'p_id',
+                'jr_tech_per');
+
+        $cond_limite=($p_limit!=-1)?" limit ".$p_limit." offset ".$p_offset:"";
+
+        $ledger_list=join(",", $this->ma_ledger);
+        $sql="
+            with row_sale as 
+                (select qs_internal,
+                    qs_client,sum(qs_price) as novat,
+                    sum(qs_vat) as vat ,
+                    sum(qs_vat_sided) as tva_sided 
+                 from 
+                    quant_sold group by qs_client,qs_internal),
+              client_detail as (
+              select x.f_id as f_id,
+                (select ad_value from fiche_detail where ad_id=1 and 
f_id=x.f_id) as name,
+                (select ad_value from fiche_detail where ad_id=32 and 
f_id=x.f_id) as first_name,
+                (select ad_value from fiche_detail where ad_id=23 and 
f_id=x.f_id) as qcode
+              from 
+              fiche as x)
+            select   
+                    name,
+                    first_name,
+                    qcode,
+                    jr_id,
+                    jr_pj_number,
+                    jr_date,
+                    jr_date_paid,
+                    jr_internal,
+                    qs_client,
+                    jrn.jr_comment,
+                    jr_pj_name,
+                    vat,
+                    tva_sided,
+                    novat,
+                    novat+vat-tva_sided as tvac
+            from
+                jrn
+                join row_sale on (qs_internal=jr_internal)
+                join client_detail on (qs_client=f_id)
+            where
+                jr_def_id in ({$ledger_list})
+                and {$periode}
+                {$cond_limite}";
+        $this->data=$this->db->get_array($sql);
+        
+    }
+    /**
+     * @brief preprare the query for fetching the detailed VAT of an operation
+     * @staticvar int $prepare
+     */
+    private function add_vat_info()
+    {
+        static $prepare=0;
+        if ( $prepare==0) {
+            $this->db->prepare("vat_info","
+                select 
+                    sum(qs_vat) vat_amount , 
+                    qs_vat_code 
+                from 
+                    quant_sold 
+                where 
+                    qs_internal = $1 
+                group by qs_vat_code,qs_internal order by qs_vat_code");
+             
+        }
+        
+        $prepare=1;
+        $nb_row=count($this->data);
+        for ($i=0;$i<$nb_row;$i++)
+        {
+            
$ret=$this->db->execute("vat_info",array($this->data[$i]["jr_internal"]));
+            $array=Database::fetch_all($ret);
+            $this->data[$i]["detail_vat"]=$array;
+        }
+    }
+    /**
+     * @brief display in HTML following the mode 
+     */
+    function export_html()
+    {
+        switch ($this->m_mode)
+        {
+            case "E":
+                $this->export_extended_html();
+                break;
+            case "D":
+                $this->export_detail_html();
+                break;
+            case "L":
+                $this->export_oneline_html();
+                break;
+            case "A":
+                $this->export_accounting_html();
+                break;
+            default:
+                break;
+        }
+    }
+   
+    /**
+     * display in HTML one operation by line
+     */
+    public function export_oneline_html()
+    {
+        $this->get_row();
+        $this->prepare_reconcile_date();
+        require_once NOALYSS_TEMPLATE.'/acc_history_ledger_sale_oneline.php';
+        
+    }
+
+}
diff --git a/include/impress_jrn.inc.php b/include/impress_jrn.inc.php
index c9589a3..f359495 100644
--- a/include/impress_jrn.inc.php
+++ b/include/impress_jrn.inc.php
@@ -27,14 +27,21 @@ require_once NOALYSS_INCLUDE.'/lib/iselect.class.php';
 require_once NOALYSS_INCLUDE.'/lib/icheckbox.class.php';
 require_once NOALYSS_INCLUDE.'/class/exercice.class.php';
 require_once NOALYSS_INCLUDE.'/class/dossier.class.php';
-load_all_script();
+require_once NOALYSS_INCLUDE.'/class/acc_ledger_history.class.php';
+require_once NOALYSS_INCLUDE.'/lib/database.class.php';
 $gDossier = dossier::id();
 global $g_user,$http;
+
+/**
+ * Get exercice
+ */
+$user_exercice=$g_user->get_exercice();
+$exercice =$http->get("exercice","string",$user_exercice);
+
+
 //-----------------------------------------------------
 // Show the ledger and date
 //-----------------------------------------------------
-require_once NOALYSS_INCLUDE.'/lib/database.class.php';
-
 if ($g_user->Admin() == 0 && $g_user->is_local_admin() == 0  && 
$g_user->get_status_security_ledger()==1)
 {
        $sql = "select jrn_def_id,jrn_def_name
@@ -44,34 +51,45 @@ if ($g_user->Admin() == 0 && $g_user->is_local_admin() == 0 
 && $g_user->get_sta
          uj_login=$1
          and uj_priv in ('R','W')
                 order by jrn_def_name
+         and ( jrn_enable=1 
+                or 
+                exists (select 1 from jrn where jr_tech_per in (select p_id 
from parm_periode where p_exercice=$2))
          ";
-       $ret = $cn->make_array($sql,0,array($g_user->login));
+       $ret = $cn->make_array($sql,0,array($g_user->login,$exercice));
 }
 else
 {
        $ret = $cn->make_array("select jrn_def_id,jrn_def_name
                          from jrn_def join jrn_type on jrn_def_type=jrn_type_id
+                         where
+                         jrn_enable=1 or exists(select 1 from jrn where 
jr_tech_per in (select p_id from parm_periode where p_exercice=$1))
                                                 order by jrn_def_name
-                                                ");
-    // Count the forbidden journaux
-//    $NoPriv = $cn->count_sql("select 
jrn_def_id,jrn_def_name,jrn_def_class_deb,jrn_def_class_cred,jrn_type_id,jrn_desc,uj_priv,
-//                           jrn_deb_max_line,jrn_cred_max_line
-//                           from jrn_def join jrn_type on 
jrn_def_type=jrn_type_id
-//                           join  user_sec_jrn on uj_jrn_id=jrn_def_id
-//                           where
-//                           uj_login=$1
-//                           and uj_priv ='X'
-//                           ",array($g_user->id));
+                                                ",0,[$exercice]);
 }
+
 /*
  * Show all the available ledgers
  */
 $a = count($ret);
+if (count($ret) < 1)   NoAccess();
+
 $all = array('value' => 0, 'label' => _('Tous les journaux disponibles'));
 $ret[$a] = $all;
-if (count($ret) < 1)
-       NoAccess();
-$exercice = (isset($_GET['exercice'])) ? $_GET['exercice'] : 
$g_user->get_exercice();
+
+// Get the from_periode and to_periode
+$from_periode=$http->get("from_periode","number","");
+$to_periode=$http->get("to_periode","number","");
+
+// if from_periode empty, then set to first and last 
+// periode of the exercice (from preference)
+
+if ($from_periode=="" || $to_periode=="")
+{
+    $t_periode=new Periode($cn);
+    list($per_min,$per_max)=$t_periode->get_limit($exercice);
+    $from_periode=$per_min->p_id;
+    $to_periode=$per_max->p_id;
+}
 
 //-----------------------------------------------------
 // Form
@@ -108,10 +126,6 @@ print '</TR>';
 print '<TR>';
 // filter on the current year
 $filter_year = " where p_exercice='" . sql_string($exercice) . "'";
-// Get the from_periode and to_periode
-$from_periode=$http->get("from_periode","number","");
-$to_periode=$http->get("to_periode","number","");
-
 $periode_start = $cn->make_array("select p_id,to_char(p_start,'DD-MM-YYYY') 
from parm_periode $filter_year order by p_start,p_end");
 $w->selected =  $from_periode ;
 
@@ -124,16 +138,14 @@ $w->selected =  $to_periode ;
 
 // By default , show last day of exercice
 if ($w->selected== '' ){
-        $t_periode=new Periode($cn);
-        list($per_max,$per_min)=$t_periode->get_limit($exercice);
-        $w->selected=$per_min->p_id;
+        $w->selected=$per_max->p_id;
 }
 print td('Jusque ') . $w->input('to_periode', $periode_end);
 print "</TR><TR>";
 $a = array(
-       array('value' => 1, 'label' => _('Liste opérations')),
-       array('value' => 0, 'label' => _('Ecriture comptable')),
-       array('value' => 2, 'label' => _('Avec Détails opérations '))
+       array('value' => 'L', 'label' => _('Liste opérations')),
+       array('value' => 'E', 'label' => _('Ecriture comptable')),
+       array('value' => 'D', 'label' => _('Avec Détails opérations '))
 );
 $w->selected = 1;
 print '</TR>';
@@ -157,267 +169,29 @@ echo '<hr>';
 if (isset($_REQUEST['bt_html']))
 {
     // Type of report : listing=1 , Accounting writing=0, detail =2
-    $simple=$http->get("p_simple","number");
-    
+    $simple=$http->get("p_simple","string");
     $jrn_id=$http->get("jrn_id","number");
     
-       require_once NOALYSS_INCLUDE.'/class/acc_ledger.class.php';
-            $Jrn = new Acc_Ledger($cn, $jrn_id);
-            $Jrn->get_name();
-            $ledger_type=$Jrn->get_type() ;
-            switch ($simple)
-            {
-                    case "0":
-                        // List of accounting writing
-                            $Row = $Jrn->get_row($from_periode, $to_periode);
-                            break;
-                    case "1":
-                        // simple list of operations, one row / operation
-                            $Row = $Jrn->get_rowSimple($from_periode, 
$to_periode);
-                        
-                    case "2":
-                        // Detail for each operation
-                            $Row = $Jrn->get_rowSimple($from_periode, 
$to_periode);
-                            break;
-                    default:
-                            die(__FILE__ . ":" . __LINE__ . " error unknown 
style [$simple ] ");
-            }
-            $rep = "";
-            $hid = new IHidden();
-            echo '<div class="content">';
-            echo '<h2 class="info">' . h($Jrn->name) . '</h2>';
-            echo "<table>";
-            echo '<TR>';
-            echo '<TD><form method="GET" ACTION="?">' . dossier::hidden() .
-            $hid->input("type", "jrn") . $hid->input('p_action', 'impress') . 
"</form></TD>";
-
-            echo '<TD><form method="GET" ACTION="export.php">' . 
dossier::hidden() .
-            HtmlInput::submit('bt_pdf', "Export PDF") .
-            HtmlInput::hidden('act', 'PDF:ledger') .
-            $hid->input("type", "jrn") .
-            $hid->input("jrn_id", $Jrn->id) .
-            $hid->input("from_periode", $from_periode) .
-            $hid->input("to_periode", $to_periode);
-            echo $hid->input("p_simple", $simple);
-            echo HtmlInput::get_to_hidden(array('ac', 'type'));
-            echo "</form></TD>";
-
-            echo '<TD><form method="GET" ACTION="export.php">' . 
dossier::hidden() .
-            HtmlInput::submit('bt_csv', "Export CSV") .
-            HtmlInput::hidden('act', 'CSV:ledger') .
-            $hid->input("type", "jrn") .
-            $hid->input("jrn_id", $Jrn->id) .
-            $hid->input("from_periode", $from_periode) .
-            $hid->input("to_periode", $to_periode);
-            echo $hid->input("p_simple", $simple);
-            echo HtmlInput::get_to_hidden(array('ac', 'type'));
-            echo "</form></TD>";
-
-            echo '<td style="vertical-align:top">';
-            echo HtmlInput::print_window();
-            echo '</td>';
-            echo "</TR>";
-
-            echo "</table>";
-            if (count($Jrn->row) == 0
-                            && $Row == null)
-                    exit;
-        
-
-
-       
/////////////////////////////////////////////////////////////////////////////////////
-       // Ecriture comptable
-       
/////////////////////////////////////////////////////////////////////////////////////
-       if ($simple== 0)
-       {
-               echo '<TABLE class="result">';
-               // detailled printing
-               //---
-               foreach ($Jrn->row as $op)
-               {
-                       $class = "";
-                       if ($op['j_date'] != '')
-                       {
-                               $class = "odd";
-                       }
-
-                       echo "<TR  class=\"$class\">";
-
-                       echo "<TD>" . $op['j_date'] . "</TD>";
-                       echo "<TD >" . $op['jr_pj_number'] . "</TD>";
-
-
-                       if ($op['internal'] != '')
-                               echo "<TD>" . 
HtmlInput::detail_op($op['jr_id'], $op['internal']) . "</TD>";
-                       else
-                               echo td();
-
-                       echo "<TD >" . $op['poste'] . "</TD>" .
-                       "<TD  >" . $op['description'] . "</TD>" .
-                       "<TD   style=\"text-align:right\">" . 
nbm($op['deb_montant']) . "</TD>" .
-                       "<TD style=\"text-align:right\">" . 
nbm($op['cred_montant']) . "</TD>" .
-                       "</TR>";
-               }// end loop
-               echo "</table>";
-               // show the saldo
-
-               $solde = $Jrn->get_solde($from_periode, $to_periode);
-               echo "solde d&eacute;biteur:" . $solde[0] . "<br>";
-               echo "solde cr&eacute;diteur:" . $solde[1];
-       } // if
-       
/////////////////////////////////////////////////////////////////////////////////////
-       // Liste opérations
-       
/////////////////////////////////////////////////////////////////////////////////////
-       elseif ($simple == 1)
-       {
-            if ( $Jrn->get_type() != 'ACH' && $Jrn->get_type() != 'VEN')
-            {
-               // Simple printing
-               //---
-               echo '<TABLE class="result">';
-               echo "<TR>" .
-               "<th>Date</th>" .
-               "<th> n° de pièce </th>" .
-               "<th>internal</th>" .
-               th('Tiers') .
-               "<th>Commentaire</th>" .
-               "<th>Total opération</th>" .
-               "</TR>";
-               // set a filter for the FIN
-               $i = 0;$tot_amount=0;
-                bcscale(2);
-               foreach ($Row as $line)
-               {
-                       $i++;
-                       $class = ($i % 2 == 0) ? ' class="even" ' : ' 
class="odd" ';
-                       echo "<tr $class>";
-                       echo "<TD>" . $line['date'] . "</TD>";
-                       echo "<TD>" . h($line['jr_pj_number']) . "</TD>";
-                       echo "<TD>" . HtmlInput::detail_op($line['jr_id'], 
$line['jr_internal']) . "</TD>";
-                       $tiers = $Jrn->get_tiers($line['jrn_def_type'], 
$line['jr_id']);
-                       echo td($tiers);
-                       echo "<TD>" . h($line['comment']) . "</TD>";
-
-
-                       //        echo "<TD>".$line['pj']."</TD>";
-                       // If the ledger is financial :
-                       // the credit must be negative and written in red
-                       // Get the jrn type
-                       if ($line['jrn_def_type'] == 'FIN')
-                       {
-                               $positive = $cn->get_value("select qf_amount 
from quant_fin where jr_id=$1", array($line['jr_id']));
-                               if ($cn->count() == 0)
-                                       $positive = 1;
-                               else
-                                       $positive = ($positive > 0) ? 1 : 0;
-
-                               echo "<TD align=\"right\">";
-                               echo ( $positive == 0 ) ? "<font color=\"red\"> 
 - " . nbm($line['montant']) . "</font>" : nbm($line['montant']);
-                               echo "</TD>";
-                                if ( $positive == 1 ) {
-                                    
$tot_amount=bcadd($tot_amount,$line['montant']);
-                                } else {
-                                    
$tot_amount=bcsub($tot_amount,$line['montant']);
-                                }
-                       }
-                       else
-                       {
-                               echo "<TD align=\"right\">" . 
nbm($line['montant']) . "</TD>";
-                                
$tot_amount=bcadd($tot_amount,$line['montant']);
-                       }
-
-                       echo "</tr>";
-               }
-                echo '<tr class="highlight">';
-                echo '<td>'._('Totaux').'</td>';
-                echo td().td().td().td();
-                echo '<td class="num">'.nbm($tot_amount).'</td>';
-                echo '</tr>';
-               echo "</table>";
-            } else {
-                /*
-                 * Ledger ACH or VEN
-                 */
-                $own=new Noalyss_Parameter_Folder($cn);
-                require_once NOALYSS_TEMPLATE.'/print_ledger_simple.php';
-                
-            }
-       }
-       
/////////////////////////////////////////////////////////////////////////////////////
-       // Détaillé
-       
/////////////////////////////////////////////////////////////////////////////////////
-       elseif ($simple == 2)
-       {
-               foreach ($Row as $line)
-               {
-                       echo '<div 
style="margin-top:2px;margin-bottom:10px;border:solid 1px black">';
-                       $class = ' class="odd" style="font-stretch: 
expanded;font-size:1em;"';
-                       echo '<table class="result" style="font-weight: 
bolder;font-variant: small-caps;width:100%;">';
-                       echo "<tr $class>";
-                       echo '<TD style="width:5%">' . $line['date'] . "</TD>";
-                       echo '<TD style="width:10%">' . 
h($line['jr_pj_number']) . "</TD>";
-                       echo '<TD style="width:5%">' . 
HtmlInput::detail_op($line['jr_id'], $line['jr_internal']) . "</TD>";
-                       $tiers = $Jrn->get_tiers($line['jrn_def_type'], 
$line['jr_id']);
-                       $ledger_name = $cn->get_value("select jrn_def_name from 
jrn_def where jrn_def_id=$1", array($line['jr_def_id']));
-                       echo '<TD style="width:20%">' . h($ledger_name) . ' 
</td>';
-                       echo '<TD style="width:20%">' . h($tiers) . ' </td>';
-                       echo '<TD style="width:30%">' . h($line['comment']) . 
"</TD>";
-                       echo '<TD style="text-align:right">';
-                       if ($line['jrn_def_type'] == 'FIN')
-                       {
-                               $positive = $cn->get_value("select qf_amount 
from quant_fin where jr_id=$1", array($line['jr_id']));
-                               if ($cn->count() == 0)
-                                       $positive = 1;
-                               else
-                                       $positive = ($positive > 0) ? 1 : 0;
-
-                               echo ( $positive == 0 ) ? "<font color=\"red\"> 
 - " . nbm($line['montant']) . "</font>" : nbm($line['montant']);
-                       }
-                       else
-                       {
-                               if ( isset ($line['TVAC'])) {
-                                    echo  ( nbm($line['TVAC'])  < 0 ) ? "<font 
color=\"red\">  - " . nbm($line['TVAC']) . "</font>" : nbm($line['TVAC']);
-                                } else
-                                {
-                                    echo  nbm($line['montant']) ;
-                                }
-                       }
-                       echo  "</TD>";
-                       echo "</tr>";
-                       echo '</table>';
-                       
//////////////////////////////////////////////////////////////////////////////////////////////////////
-                       // Add detail for each operation
-                       
//////////////////////////////////////////////////////////////////////////////////////////////////////
-                       $op = new Acc_Operation($cn);
-                       $op->jr_id = $line['jr_id'];
-                       $op->get();
-                       $obj = $op->get_quant();
-                       switch ($obj->signature)
-                       {
-                               case 'FIN':
-                                       require 
NOALYSS_TEMPLATE.'/operation_detail_fin.php';
-                                       break;
-                               case 'ACH':
-                                       require 
NOALYSS_TEMPLATE.'/operation_detail_ach.php';
-                                       break;
-                               case 'VEN':
-                                       require 
NOALYSS_TEMPLATE.'/operation_detail_ven.php';
-                                       break;
-                               case 'ODS':
-                                       require 
NOALYSS_TEMPLATE.'/operation_detail_misc.php';
-                                       break;
-                               default:
-                                       die("unknown type of ledger");
-                                       break;
-                       }
-                       echo '</div>';
-                       //echo '<div style="display:block;height:15px"></div>';
-               } // end loop
-       }
+    /*
+     * Compute an array with all the usable ledger
+     */
+    $a_ledger=[];
+    if ( $jrn_id == 0) {
+        $nb_ret=count($ret);
+        for ($i=0;$i<$nb_ret;$i++) {
+            if ($ret[$i]['value']!=0) 
+                $a_ledger[$i]=$ret[$i]['value'];
+        }
+    } else {
+        $a_ledger=[$jrn_id];
+    }
+    
+    
$ledger_history=Acc_Ledger_History::factory($cn,$a_ledger,$from_periode,$to_periode,$simple);
+    
+    $ledger_history->export_html();
+    
 
-       echo "</div>";
-       exit;
 }
 
 echo '</div>';
-?>
+?>
\ No newline at end of file
diff --git a/include/template/acc_history_ledger_sale_oneline.php 
b/include/template/acc_history_ledger_sale_oneline.php
new file mode 100644
index 0000000..f3cfa48
--- /dev/null
+++ b/include/template/acc_history_ledger_sale_oneline.php
@@ -0,0 +1,134 @@
+<?php
+
+/*
+ * Copyright (C) 2018 Dany De Bontridder <address@hidden>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+/***
+ * @file 
+ * @brief
+ * @todo prévoir aussi pour les non assujetti : faire disparaître les montants 
TVA
+ */
+
+?>
+<table class="result">
+    <tr>
+        <th>
+            <?=_('Date')?>
+        </th>
+        <th>
+            <?=_('Date paiement')?>
+        </th>
+        <th>
+            <?=_('Pièce')?>
+        </th>
+        <th>
+            <?=_('Interne')?>
+        </th>
+        <th>
+            <?=_('Client')?>
+        </th>
+        <th>
+            <?=_('Description')?>
+        </th>
+        <th>
+            <?=_('HTVA')?>
+        </th>
+        <th>
+            <?=_('TVA')?>
+        </th>
+        <th>
+            <?=_('TVAC')?>
+        </th>
+    </tr>
+<?php 
+$nb_data=count($this->data);
+$tot_amount_novat=0;
+$tot_amount_vat=0;
+$tot_amount_tvac=0;
+for ($i=0;$i<$nb_data;$i++):
+    $odd=($i%2==0)?' class="even" ':' class="odd" ';
+    $tot_amount_novat=bcadd($tot_amount_novat,$this->data[$i]['novat']);
+    $tot_amount_vat=bcadd($tot_amount_vat,$this->data[$i]['vat']);
+    $tot_amount_vat=bcsub($tot_amount_vat,$this->data[$i]['tva_sided']);
+    $tot_amount_tvac=bcadd($tot_amount_tvac,$this->data[$i]['tvac']);
+?>
+    <tr <?=$odd?> >
+        <td>
+            <?=$this->data[$i]['jr_date']?>
+        </td>
+        <td>
+            <?=$this->data[$i]['jr_date_paid']?>
+        </td>
+        <td>
+            <?=$this->data[$i]['jr_pj_number']?>
+        </td>
+        <td>
+            <?=$this->data[$i]['jr_internal']?>
+        </td>
+        <td>
+            
<?=HtmlInput::history_card($this->data[$i]['qs_client'],h($this->data[$i]['name'].'
 '.$this->data[$i]['first_name']." [ {$this->data[$i]['qcode']} ]"))?>
+        </td>
+        <td>
+            <?=h($this->data[$i]['jr_comment'])?>
+        </td>
+        <td class="num">
+            <?=nbm($this->data[$i]['novat'])?>
+        </td>
+        <td class="num">
+            
<?=nbm(bcsub($this->data[$i]['vat'],$this->data[$i]['tva_sided']))?>
+        </td>
+        <td class="num">
+            <?=nbm($this->data[$i]['tvac'])?>
+        </td>
+        <td>
+            
+        <?php
+         
$ret_reconcile=$this->db->execute('reconcile_date',array($this->data[$i]['jr_id']));
+         $max=Database::num_row($ret_reconcile);
+        if ($max > 0) {
+            $sep="";
+            for ($e=0;$e<$max;$e++) {
+                $row=Database::fetch_array($ret_reconcile, $e);
+                echo $sep.HtmlInput::detail_op($row['jr_id'],$row['jr_date'].' 
'. $row['jr_internal']);
+                $sep=' ,';
+        }
+    } ?>
+        </td>
+    </tr>
+<?php 
+    endfor;
+?>
+    <tfoot>
+        <tr class="highlight">
+            <td>
+                <?=_("Totaux")?>
+            </td>
+            <td></td>
+            <td></td>
+            <td></td>
+            <td></td>
+            <td></td>
+            <td class="num"><?=nbm($tot_amount_novat)?></td>
+            <td class="num"><?=nbm($tot_amount_vat)?></td>
+            <td class="num"><?=nbm($tot_amount_tvac)?></td>
+            <td></td>
+            <td></td>
+        </tr>
+    </tfoot>
+</table>
\ No newline at end of file
diff --git a/include/template/acc_ledger_history_sale_detail.php 
b/include/template/acc_ledger_history_sale_detail.php
new file mode 100644
index 0000000..cfa9bf2
--- /dev/null
+++ b/include/template/acc_ledger_history_sale_detail.php
@@ -0,0 +1,180 @@
+<?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 (2018) Author Dany De Bontridder <address@hidden>
+
+if (!defined('ALLOWED'))
+    die('Appel direct ne sont pas permis');
+
+/**
+ * @file
+ * @brief from Acc_Ledger_History_Sale::export_html_oneline
+ * @todo prévoir aussi pour les non assujetti : faire disparaître les montants 
TVA
+ */
+?>
+<TABLE class="result">
+    <tr>
+        <th><?php echo _("Pièce")?></th>
+        <th><?php echo _("Date")?></th>
+        <th><?php echo _("Paiement")?></th>
+        <th><?php echo _("Ref")?></th>
+        <th><?php echo _("Client")?></th>
+        <th><?php echo _("Description")?></th>
+        <th style="text-align:right">HTVA</th>
+        
+        
+<?php
+$col_tva="";
+
+ if ( $own->MY_TVA_USE=='Y')
+        {
+            $a_Tva=$this->db->get_array("select tva_id,tva_label from tva_rate 
where tva_rate != 0.0000 order by tva_id");
+            foreach($a_Tva as $line_tva)
+            {
+                $col_tva.='<th style="text-align:right">Tva 
'.$line_tva['tva_label'].'</th>';
+            }
+        }
+echo $col_tva;      
+?>
+        <th style="text-align:right">TVAC</th>
+        <th><?php echo _("Opérations rapprochées")?></th>
+    </tr>
+<?php
+$i = 0;
+$tot['htva']=0;
+$tot['dep_priv']=0;
+$tot['dna']=0;
+$tot['tva_nd']=0;
+$tot['tvac']=0;
+$tot['tva']=array();
+bcscale(4);
+foreach ($this->data as $line) {
+    $i++;
+    /*
+     * Get date of reconcile operation
+     */
+    $ret_reconcile=$this->db->execute('reconcile_date',array($line['jr_id']));
+    $class = ($i % 2 == 0) ? ' class="even" ' : ' class="odd" ';
+    echo "<tr $class>";
+    
+    // Receipt number
+    echo "<TD>" . h($line['jr_pj_number']) . "</TD>";
+    
+    // Date
+    echo "<TD>" . smaller_date($line['jr_date']) . "</TD>";
+    echo "<TD>" . smaller_date($line['jr_date_paid']) . "</TD>";
+    
+    // Internal with detail
+    echo "<TD>" . HtmlInput::detail_op($line['jr_id'], $line['jr_internal']) . 
"</TD>";
+    
+    // find the tiers (normally in $Row ! 
+    $tiers =HtmlInput::history_card($line['qs_client'],h($line['name'].' 
'.$line['first_name'])."[{$line['qcode']}]");
+
+    echo td($tiers);
+    
+    // Label
+    echo "<TD>" . h($line['jr_comment']) . "</TD>";
+    
+
+    // HTVA amount 
+    echo "<TD class=\"num\">" . nbm(round($line['novat'],2),2) . "</TD>";
+    $tot['htva']=bcadd($tot['htva'],  round(floatval($line['novat']),2));
+    
+    
//--------------------------------------------------------------------------
+    // If VAT then display it
+    
//--------------------------------------------------------------------------
+    if ($own->MY_TVA_USE == 'Y' )
+    {
+        $a_tva_amount=array();
+        
+        foreach ($line['detail_vat'] as $lineTVA)
+        {
+                foreach ($a_Tva as $idx=>$line_tva)
+                {
+
+                    if ($line_tva['tva_id'] == $lineTVA['qs_vat_code'])
+                    {
+                        $a=$line_tva['tva_id'];
+                        $a_tva_amount[$a]=$lineTVA["vat_amount"];
+                    }
+                }
+            }
+        foreach ($a_Tva as $line_tva)
+        {
+            $a=$line_tva['tva_id'];
+            if ( isset($a_tva_amount[$a]) && $a_tva_amount[$a] != 0) {
+                echo '<td 
class="num">'.nbm(round($a_tva_amount[$a],2)).'</td>';
+                
$tot['tva'][$a]=(isset($tot['tva'][$a]))?bcadd($tot['tva'][$a],round(floatval($a_tva_amount[$a]),2)):round(floatval($a_tva_amount[$a]),2);
+            }
+            else
+                printf("<td class=\"num\"></td>");
+        }
+    }
+    
+    echo '<td class="num">'.nbm($line['tvac'],2).'</td>';
+    $tot['tvac']=bcadd($tot['tvac'], round(floatval($line['tvac']),2));
+    /*
+     * If reconcile print them
+     */
+    echo '<td>';
+    $max=Database::num_row($ret_reconcile);
+    if ($max > 0) {
+        $sep="";
+        for ($e=0;$e<$max;$e++) {
+            $row=Database::fetch_array($ret_reconcile, $e);
+            echo $sep.HtmlInput::detail_op($row['jr_id'],$row['jr_date'].' '. 
$row['jr_internal']);
+            $sep=' ,';
+        }
+    }
+    echo '</td>';
+    echo "</tr>";
+}
+/** 
+ * summary
+ */
+?>
+    <tr class="highlight">
+        <td>
+            <?php echo _('Totaux')?>
+        </td>
+        <td></td>
+        <td></td>
+        <td></td>
+        <td></td>
+        <td></td>
+        <td class="num"><?php echo nbm($tot['htva']); ?></td>
+        <?php if ($own->MY_TVA_USE == 'Y' ): ?>
+            <?php  foreach ($a_Tva as $line_tva) :
+                        $a=$line_tva['tva_id'];
+                        if ( isset($tot['tva'][$a])) :
+                    ?>
+                        <td class="num"><?php echo nbm($tot['tva'][$a])?></td>
+                    <?php else : ?>
+                        <td>
+
+                        </td>
+                    <?php endif; ?>
+                <?php endforeach;?>
+        <?php endif; ?>
+        <td class="num"><?php echo nbm($tot['tvac'])?></td>
+        <td></td>
+    </tr>
+        
+        
+</table>
\ No newline at end of file
diff --git a/include/template/acc_ledger_history_sale_extended.php 
b/include/template/acc_ledger_history_sale_extended.php
new file mode 100644
index 0000000..fdaa472
--- /dev/null
+++ b/include/template/acc_ledger_history_sale_extended.php
@@ -0,0 +1,171 @@
+<?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 (2018) Author Dany De Bontridder <address@hidden>
+
+
+/**
+ * @file
+ * @brief detail of the list of operation with VAT and items
+ */
+?>
+<table class="result">
+    <tr>
+        <th>
+            <?=_('Date')?>
+        </th>
+        <th>
+            <?=_('Date paiement')?>
+        </th>
+        <th>
+            <?=_('Pièce')?>
+        </th>
+        <th>
+            <?=_('Interne')?>
+        </th>
+        <th>
+            <?=_('Client')?>
+        </th>
+        <th>
+            <?=_('Description')?>
+        </th>
+        <th>
+            <?=_('HTVA')?>
+        </th>
+        <th>
+            <?=_('TVA')?>
+        </th>
+        <th>
+            <?=_('TVAC')?>
+        </th>
+    </tr>
+<?php 
+$nb_data=count($this->data);
+$tot_amount_novat=0;
+$tot_amount_vat=0;
+$tot_amount_tvac=0;
+for ($i=0;$i<$nb_data;$i++):
+    $odd=' class="odd" ';
+    $tot_amount_novat=bcadd($tot_amount_novat,$this->data[$i]['novat']);
+    $tot_amount_vat=bcadd($tot_amount_vat,$this->data[$i]['vat']);
+    $tot_amount_vat=bcsub($tot_amount_vat,$this->data[$i]['tva_sided']);
+    $tot_amount_tvac=bcadd($tot_amount_tvac,$this->data[$i]['tvac']);
+?>
+    <tr <?=$odd?> >
+        <td>
+            <?=$this->data[$i]['jr_date']?>
+        </td>
+        <td>
+            <?=$this->data[$i]['jr_date_paid']?>
+        </td>
+        <td>
+            <?=$this->data[$i]['jr_pj_number']?>
+        </td>
+        <td>
+            <?=$this->data[$i]['jr_internal']?>
+        </td>
+        <td>
+            
<?=HtmlInput::history_card($this->data[$i]['qs_client'],h($this->data[$i]['name'].'
 '.$this->data[$i]['first_name']))?>
+        </td>
+        <td>
+            <?=h($this->data[$i]['jr_comment'])?>
+        </td>
+        <td class="num">
+            <?=nbm($this->data[$i]['novat'])?>
+        </td>
+        <td class="num">
+            
<?=nbm(bcsub($this->data[$i]['vat'],$this->data[$i]['tva_sided']))?>
+        </td>
+        <td class="num">
+            <?=nbm($this->data[$i]['tvac'])?>
+        </td>
+        <td>
+            
+        <?php
+         
$ret_reconcile=$this->db->execute('reconcile_date',array($this->data[$i]['jr_id']));
+         $max=Database::num_row($ret_reconcile);
+        if ($max > 0) {
+            $sep="";
+            for ($e=0;$e<$max;$e++) {
+                $row=Database::fetch_array($ret_reconcile, $e);
+                echo $sep.HtmlInput::detail_op($row['jr_id'],$row['jr_date'].' 
'. $row['jr_internal']);
+                $sep=' ,';
+        }
+    } ?>
+        </td>
+    </tr>
+    <tr>
+        <td class="width:auto" colspan="8">
+<?php
+    /// Detail opération
+$det=$this->db->execute("detail_sale",array($this->data[$i]['jr_internal']));
+$a_detail=Database::fetch_all($det);
+?>
+            <table style="width: 100%">
+                <tr>
+                    <th><?=_("Item")?></th>
+                    <th class="num"><?=_("Prix Uni")?></th>
+                    <th class="num"><?=_("Quantité")?></th>
+                    <th class="num"><?=_("HTVA")?></th>
+                    <th class="num"><?=_("TVA")?></th>
+                    <th class="num"><?=_("Code TVA")?></th>
+                    <th class="num"><?=_("TVAC")?></th>
+                </tr>
+<?php
+$nb_detail=count($a_detail);
+for ($j=0;$j<$nb_detail;$j++):
+?>  
+                <tr>
+                    <td><?=$a_detail[$j]['qcode']?>  
+                        <?=$a_detail[$j]['name']?>  </td>
+                    <td class="num" 
style="width:10%"><?=$a_detail[$j]['qs_quantite']?>  </td>
+                    <td class="num" 
style="width:10%"><?=$a_detail[$j]['qs_unit']?>  </td>
+                    <td class="num" 
style="width:10%"><?=nbm($a_detail[$j]['qs_price'])?>  </td>
+                    <td class="num" 
style="width:10%"><?=nbm($a_detail[$j]['qs_vat'])?>  </td>
+                    <td class="num" 
style="width:10%"><?=$a_detail[$j]['tva_label']?>  </td>
+                    <td class="num" 
style="width:10%"><?=nbm($a_detail[$j]['tvac'])?>  </td>
+                </tr>
+<?php
+endfor;
+?>
+                
+            </table>
+        </td>
+    </tr>    
+<?php 
+    endfor;
+?>
+    <tfoot>
+        <tr class="highlight">
+            <td>
+                <?=_("Totaux")?>
+            </td>
+            <td></td>
+            <td></td>
+            <td></td>
+            <td></td>
+            <td></td>
+            <td><?=nbm($tot_amount_novat)?></td>
+            <td><?=nbm($tot_amount_vat)?></td>
+            <td><?=nbm($tot_amount_tvac)?></td>
+            <td></td>
+            <td></td>
+        </tr>
+    </tfoot>
+</table>
\ No newline at end of file
diff --git a/scenario/acc_ledger_historyTest.php 
b/scenario/acc_ledger_historyTest.php
new file mode 100644
index 0000000..b0863ba
--- /dev/null
+++ b/scenario/acc_ledger_historyTest.php
@@ -0,0 +1,68 @@
+<?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 (2018) Author Dany De Bontridder <address@hidden>
+
+
+
+/**
+ * @file
+ * @brief Test of ledger_history 
+ */
+require_once NOALYSS_INCLUDE."/class/acc_ledger_history.class.php";
+
+$ledger=[1,2,3,4];
+echo Dossier::hidden();
+global $cn, $g_user, $g_succeed, $g_failed;
+$cn=Dossier::connect();
+
+$ledger_history=Acc_Ledger_History::factory($cn, $ledger, 216, 217, "E");
+echo h1("Detailled Accounting");
+echo h2(_("export detail html all ledgers result = Detailled Accounting"));
+$ledger_history->export_detail_html();
+
+echo h2(_("Set mode to D etailled all_ledgers result = Detailled Accounting" 
));
+$ledger_history->set_m_mode("D");
+$ledger_history->export_html();
+
+echo h2(_("Only VEN"));
+$ledger_history=Acc_Ledger_History::factory($cn, [2], 216, 217, "L");
+$ledger_history->export_detail_html();
+
+echo h1("One line");
+echo h2(_("Only VEN one line"));
+$ledger_history->set_a_ledger([2]);
+$ledger_history->set_m_mode("L");
+$ledger_history->export_html();
+
+echo h2(_("Only VEN Detailled"));
+$ledger_history->set_a_ledger([2]);
+$ledger_history->set_m_mode("D");
+$ledger_history->export_html();
+
+echo h2(_("Only VEN Extended"));
+$ledger_history->set_a_ledger([2]);
+$ledger_history->set_m_mode("E");
+$ledger_history->export_html();
+
+echo h2("VEN + ACH");
+$ledger_history=Acc_Ledger_History::factory($cn, [3,2], 216, 217, "L");
+
+$ledger_history->export_oneline_html();
+



reply via email to

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