diff --git a/include/class/acc_account_ledger.class.php b/include/class/acc_account_ledger.class.php index eb51c051b..f496d3be0 100644 --- a/include/class/acc_account_ledger.class.php +++ b/include/class/acc_account_ledger.class.php @@ -111,55 +111,18 @@ class Acc_Account_Ledger } return array($this->row,$this->tot_deb,$this->tot_cred); } - /*! - * \brief Get data for accounting entry between 2 date - * - *\param $p_from date from DD.MM.YYYY - *\param $p_to end date DD.MM.YYYY - *\param $let 0 means all rows, 1 only lettered, 2 only unlettered - *\param $solded 0 means all account, 1 means only accounts with a saldo <> 0 - *\note the data are filtered by the access of the current user - * \return double array (j_date,deb_montant,cred_montant,description,jrn_name,j_debit,jr_internal) - * (tot_deb,tot_credit - * + /** + * @brief build the SQL for get_row_data + * @param $p_from date d.m.Y start date + * @param $p_to date d.m.Y until date + * @param $sql_let sql string for getting lettering info + * @param $filter_sql string SQL for filtering the ledgers , to respect security on ledgers + * @return sql SELECT */ - function get_row_date($p_from,$p_to,$let=0,$solded=0) + function make_sql_accounting_detail($p_from,$p_to,$sql_let,$filter_sql) { - global $g_user; - $filter_sql=$g_user->get_ledger_sql('ALL',3); - $sql_let=''; - switch ($let) - { - case 0: - break; - case 1: - $sql_let=' and j1.j_id in (select j_id from letter_cred union all select j_id from letter_deb)'; - break; - case '2': - $sql_let=' and j1.j_id not in (select j_id from letter_cred union all select j_id from letter_deb) '; - break; - } - if ( $solded == 1) - { - $filter=str_replace('jrn_def_id','jr_def_id',$filter_sql); - $bal_sql="select sum(amount_deb) as s_deb,sum(amount_cred) as s_cred, j_poste - from - (select case when j_debit='t' then j_montant else 0 end as amount_deb, - case when j_debit='f' then j_montant else 0 end as amount_cred, - j_poste - from jrnx join jrn on (j_grpt = jr_grpt_id) - where - j_poste=$1 and - $filter and - ( to_date($2,'DD.MM.YYYY') <= j_date and - to_date($3,'DD.MM.YYYY') >= j_date )) as signed_amount - group by j_poste - "; - $r=$this->db->get_array($bal_sql,array($this->id,$p_from,$p_to)); - if ( $this->db->count() == 0 ) return array(); - if ($r[0]['s_deb']==$r[0]['s_cred']) return array(); - } - $this->row=$this->db->get_array(" + + $sql = " with sqlletter as (select j_id,jl_id from letter_cred union all select j_id , jl_id from letter_deb ) select j1.j_id,jr_id,to_char(j_date,'DD.MM.YYYY') as j_date_fmt,j_date, j_qcode @@ -200,8 +163,43 @@ class Acc_Account_Ledger ( to_date($2,'DD.MM.YYYY') <= j_date and to_date($3,'DD.MM.YYYY') >= j_date ) and $filter_sql $sql_let - order by j_date,substring(jr_pj_number,'[0-9]+$') asc",array($this->id,$p_from,$p_to)); - $res_saldo = $this->db->exec_sql("select sum(deb_montant),sum(cred_montant) from + order by j_date,substring(jr_pj_number,'[0-9]+$') asc"; + return $sql; + } + + /** + * @brief make the SQL for the balanced accounting + * @param $filter filter to respect the security on ledger + * @return sql SELECT + */ + public function make_sql_not_balanced_account($filter) + { + $bal_sql="select sum(amount_deb) as s_deb,sum(amount_cred) as s_cred, j_poste + from + (select case when j_debit='t' then j_montant else 0 end as amount_deb, + case when j_debit='f' then j_montant else 0 end as amount_cred, + j_poste + from jrnx join jrn on (j_grpt = jr_grpt_id) + where + j_poste=$1 and + $filter and + ( to_date($2,'DD.MM.YYYY') <= j_date and + to_date($3,'DD.MM.YYYY') >= j_date )) as signed_amount + group by j_poste + "; + return $bal_sql; + } + + /** + * @brief make the SQL for the balance of an accounting + * @param $filter_sql filter to respect the security on ledger + * @param $sql_let string for getting lettering info + * @return sql SELECT + * + */ + public function make_sql_saldo_account($filter_sql,$sql_let) + { + $sql_saldo="select sum(deb_montant),sum(cred_montant) from (select case when j_debit='t' then j_montant else 0 end as deb_montant, case when j_debit='f' then j_montant else 0 end as cred_montant from jrnx j1 @@ -212,14 +210,73 @@ class Acc_Account_Ledger where j_poste=$1 and ( to_date($2,'DD.MM.YYYY') <= j_date and to_date($3,'DD.MM.YYYY') >= j_date ) - and $filter_sql $sql_let ) as m",array($this->id,$p_from,$p_to)); - $this->tot_deb=$this->tot_cred=0; - - if ( Database::num_row($res_saldo) > 0 ) { - $this->tot_deb=Database::fetch_result($res_saldo, 0, 0); - $this->tot_cred=Database::fetch_result($res_saldo, 0, 1); + and $filter_sql $sql_let ) as m"; + return $sql_saldo; + } + /*! + * \brief Get data for accounting entry between 2 date + * + *\param $p_from date from DD.MM.YYYY + *\param $p_to end date DD.MM.YYYY + *\param $let 0 means all rows, 1 only lettered, 2 only unlettered + *\param $solded 0 means all account, 1 means only accounts with a saldo <> 0 + *\note the data are filtered by the access of the current user + * \return double array (j_date,deb_montant,cred_montant,description,jrn_name,j_debit,jr_internal) + * (tot_deb,tot_credit + * + */ + function get_row_date($p_from, $p_to, $let = 0, $solded = 0) + { + global $g_user; + $filter_sql = $g_user->get_ledger_sql('ALL', 3); + $sql_let = ''; + switch ($let) { + case 0: + break; + case 1: + $sql_let = ' and j1.j_id in (select j_id from letter_cred union all select j_id from letter_deb)'; + break; + case '2': + $sql_let = ' and j1.j_id not in (select j_id from letter_cred union all select j_id from letter_deb) '; + break; } - return array($this->row,$this->tot_deb,$this->tot_cred); + // if accounting is balanced , D = C then returns an empty array + if ($solded == 1) { + if ($this->db->is_prepare("not_balanced_account") == false) { + $filter = str_replace('jrn_def_id', 'jr_def_id', $filter_sql); + $sql_balanced = $this->make_sql_not_balanced_account($filter); + $this->db->prepare("not_balanced_account", $sql_balanced); + } + + $ret_balanced = $this->db->execute("not_balanced_account", array($this->id, $p_from, $p_to)); + + $r = Database::fetch_all($ret_balanced); + if (empty($r)) return array(); + if ($r[0]['s_deb'] == $r[0]['s_cred']) return array(); + } + + // get the detail of accouting + if (!$this->db->is_prepare("sql_accounting_detail")) { + $sql = $this->make_sql_accounting_detail($p_from, $p_to, $sql_let, $filter_sql); + $this->db->prepare("sql_accounting_detail", $sql); + + } + $ret = $this->db->execute("sql_accounting_detail", array($this->id, $p_from, $p_to)); + $this->row = Database::fetch_all($ret); + + // $this->row=$this->db->get_array(,array($this->id,$p_from,$p_to)); + if ($this->db->is_prepare("saldo_account") == false) { + $sql_saldo = $this->make_sql_saldo_account($filter_sql, $sql_let); + $this->db->prepare("saldo_account", $sql_saldo); + } + $res_saldo = $this->db->execute("saldo_account", array($this->id, $p_from, $p_to)); + $this->tot_deb = $this->tot_cred = 0; + + if (Database::num_row($res_saldo) > 0) { + $this->tot_deb = Database::fetch_result($res_saldo, 0, 0); + $this->tot_cred = Database::fetch_result($res_saldo, 0, 1); + } + return array($this->row, $this->tot_deb, $this->tot_cred); } @@ -784,5 +841,34 @@ class Acc_Account_Ledger function filter_history($p_table_id) { return _('Filtre rapide').' '.HtmlInput::filter_table($p_table_id, '0,1,2,3,4,5,6,7,8,9,10', 1); } - + + public static function get_used_accounting($from_date, $to_date, $from_accounting, $to_accounting) + { + // check date + if (isDate($from_date) != $from_date || isDate($to_date) != $to_date) { + return array(); + } + // build query + $sql = "select pcm_val,pcm_lib from tmp_pcmn + where pcm_val in + (select j_poste from jrnx where j_date >= to_date('$from_date','DD.MM.YYYY') + and j_date <= to_date('$to_date','DD.MM.YYYY') ) "; + $cond_poste=""; + if ($from_accounting != '') { + $cond_poste .= "and pcm_val >= upper ('" . Database::escape_string($from_accounting) . "')"; + } + + if ($to_accounting != '') { + $cond_poste .= " and pcm_val <= upper ('" . Database::escape_string($to_accounting) . "')"; + } + + $sql = $sql . $cond_poste . ' order by pcm_val::text'; + + // get array + $cn=Dossier::connect(); + $a_poste = $cn->get_array($sql); + // return array + return $a_poste; + + } } diff --git a/include/export/export_gl_csv.php b/include/export/export_gl_csv.php index 995a68d79..98a7411da 100644 --- a/include/export/export_gl_csv.php +++ b/include/export/export_gl_csv.php @@ -53,33 +53,12 @@ $gDossier=dossier::id(); $cn=Dossier::connect(); $export=new Noalyss_Csv(_('grandlivre')); -$poste_id=$http->get('poste_id',"string",""); +$accounting_item_id=$http->get('poste_id',"string",""); $export->send_header(); - $cond_poste=''; - $sql="select pcm_val from tmp_pcmn "; - if ($from_poste != '') - { - $cond_poste = ' where '; - $cond_poste .=" pcm_val >= upper ('".Database::escape_string($from_poste)."')"; - } - if ( $to_poste != '') - { - if ( $cond_poste == '') - { - $cond_poste = " where pcm_val <= upper ('".Database::escape_string($to_poste)."')"; - } - else - { - $cond_poste.=" and pcm_val <= upper ('".Database::escape_string($to_poste)."')"; - } - } +$a_accounting=Acc_Account_Ledger::get_used_accounting($from_periode,$to_periode,$from_poste,$to_poste); - $sql=$sql.$cond_poste.' order by pcm_val::text'; - - $a_poste=$cn->get_array($sql); - -if ( count($a_poste) == 0 ) +if ( count($a_accounting) == 0 ) { echo _('Aucun résultat'); printf("\n"); @@ -92,13 +71,13 @@ $header = array( _("Date"), _("Référence"), _("Libellé"), _("Pièce"),_("Lett $l=(isset($_GET['letter']))?2:0; $s=(isset($_REQUEST['solded']))?1:0; -foreach ($a_poste as $poste) +foreach ($a_accounting as $accounting_item) { - $Poste=new Acc_Account_Ledger($cn,$poste['pcm_val']); + $acc_account_ledger=new Acc_Account_Ledger($cn,$accounting_item['pcm_val']); - $array1=$Poste->get_row_date($from_periode,$to_periode,$l,$s); + $array1=$acc_account_ledger->get_row_date($from_periode,$to_periode,$l,$s); // don't print empty account if ( count($array1) == 0 ) { @@ -114,7 +93,7 @@ foreach ($a_poste as $poste) continue; } - $export->add(sprintf("%s - %s ",$Poste->id,$Poste->get_name())); + $export->add(sprintf("%s - %s ",$accounting_item['pcm_val'],$accounting_item['pcm_lib'])); $export->write(); $export->write_header($header); @@ -123,7 +102,7 @@ foreach ($a_poste as $poste) $solde_c = 0.0; bcscale(2); $current_exercice=""; - foreach ($Poste->row as $detail) + foreach ($acc_account_ledger->row as $detail) { /* @@ -148,7 +127,7 @@ foreach ($a_poste as $poste) $export->add($current_exercice); $export->add(""); $export->add(""); - $export->add(_('Total')." ".$Poste->id); + $export->add(_('Total')." ".$acc_account_ledger->id); if ( $solde_d > 0 ) { $export->add($solde_d,"number"); } else { @@ -200,7 +179,7 @@ foreach ($a_poste as $poste) else $export->add(""); $export->add(abs($solde),"number"); - $export->add($Poste->get_amount_side($solde),"text"); + $export->add($acc_account_ledger->get_amount_side($solde),"text"); $export->write(); } @@ -210,7 +189,7 @@ foreach ($a_poste as $poste) $export->add($current_exercice); $export->add(""); $export->add(""); - $export->add(_('Total').$Poste->id); + $export->add(_('Total').$acc_account_ledger->id); if ($solde_d > 0 ) $export->add($solde_d,"number"); else $export->add(""); if ($solde_c > 0 ) $export->add($solde_c,"number"); else $export->add(""); $export->add(abs($solde_c-$solde_d),"number"); diff --git a/include/export/export_gl_pdf.php b/include/export/export_gl_pdf.php index 531a9ef9d..24578f883 100644 --- a/include/export/export_gl_pdf.php +++ b/include/export/export_gl_pdf.php @@ -41,29 +41,7 @@ $cn=Dossier::connect(); $g_user->Check(); $g_user->check_dossier($gDossier); -$sql="select pcm_val from tmp_pcmn "; - -$cond_poste=""; -if ($from_poste != '') - { - $cond_poste = ' where '; - $cond_poste .=' pcm_val >= upper (\''.Database::escape_string($from_poste).'\')'; - } - -if ( $to_poste != '') - { - if ( $cond_poste == '') - { - $cond_poste = ' where pcm_val <= upper (\''.Database::escape_string($to_poste).'\')'; - } - else - { - $cond_poste.=' and pcm_val <= upper (\''.Database::escape_string($to_poste).'\')'; - } - } - -$sql=$sql.$cond_poste.' order by pcm_val::text'; -$a_poste=$cn->get_array($sql); +$a_accounting=Acc_Account_Ledger::get_used_accounting($from_periode,$to_periode,$from_poste,$to_poste); $pdf = new PDF($cn); $pdf->setDossierInfo(_(" Periode : ").$from_periode." - ".$to_periode); @@ -72,7 +50,7 @@ $pdf->AddPage(); $pdf->setTitle("Grand Livre",true); $pdf->SetAuthor('NOALYSS'); -if ( count($a_poste) == 0 ) +if ( count($a_accounting) == 0 ) { $pdf->Output(); return; @@ -87,13 +65,12 @@ $width = array( 13 , 20 , 60 , 15 , 12 , 20 , 20 $l=(isset($_REQUEST['letter']))?2:0; $s=(isset($_REQUEST['solded']))?1:0; -foreach ($a_poste as $poste) +foreach ($a_accounting as $accounting_item) { - $Poste=new Acc_Account_Ledger($cn,$poste['pcm_val']); - - - $array1=$Poste->get_row_date($from_periode,$to_periode,$l,$s); + $acc_account_ledger=new Acc_Account_Ledger($cn,$accounting_item['pcm_val']); + + $array1=$acc_account_ledger->get_row_date($from_periode,$to_periode,$l,$s); // don't print empty account if (empty($array1) || count($array1[0]) == 0 ) { @@ -104,7 +81,7 @@ foreach ($a_poste as $poste) $tot_cred=$array1[2]; $pdf->SetFont('DejaVuCond','',10); - $Libelle=sprintf("%s - %s ",$Poste->id,$Poste->get_name()); + $Libelle=sprintf("%s - %s ",$accounting_item['pcm_val'],$accounting_item['pcm_lib']); $pdf->write_cell(0, 7, $Libelle, 1, 1, 'C'); $pdf->SetFont('DejaVuCond','',6); @@ -119,7 +96,7 @@ foreach ($a_poste as $poste) $solde_d = 0.0; $solde_c = 0.0; $current_exercice=""; - foreach ($Poste->row as $detail) + foreach ($acc_account_ledger->row as $detail) { /* @@ -151,7 +128,7 @@ foreach ($a_poste as $poste) $i++; $pdf->write_cell($width[$i], 6, '', 0, 0, $lor[$i]); $i++; - $pdf->write_cell($width[$i], 6, 'Total du compte '.$Poste->id, 0, 0, 'R'); + $pdf->write_cell($width[$i], 6, 'Total du compte '.$acc_account_ledger->id, 0, 0, 'R'); $i++; $pdf->write_cell($width[$i], 6, ($solde_d > 0 ? nbm($solde_d) : ''), 0, 0, $lor[$i]); $i++; @@ -184,7 +161,7 @@ foreach ($a_poste as $poste) } $i = 0; - $side=" ".$Poste->get_amount_side($solde); + $side=" ".$acc_account_ledger->get_amount_side($solde); $pdf->LongLine($width[$i], 6, shrink_date($detail['j_date_fmt']), 0, $lor[$i]); $i++; $pdf->LongLine($width[$i], 6, $detail['jr_internal'], 0, $lor[$i] ); @@ -220,7 +197,7 @@ foreach ($a_poste as $poste) $i++; $pdf->write_cell($width[$i], 6, '', 0, 0, $lor[$i]); $i++; - $pdf->write_cell($width[$i], 6, 'Total du compte '.$Poste->id, 0, 0, 'R'); + $pdf->write_cell($width[$i], 6, 'Total du compte '.$acc_account_ledger->id, 0, 0, 'R'); $i++; $pdf->write_cell($width[$i], 6, ($solde_d > 0 ? nbm($solde_d) : ''), 0, 0, $lor[$i]); $i++; diff --git a/include/impress_gl_comptes.inc.php b/include/impress_gl_comptes.inc.php index d9122c232..84e0855bb 100644 --- a/include/impress_gl_comptes.inc.php +++ b/include/impress_gl_comptes.inc.php @@ -104,44 +104,29 @@ echo ''; //----------------------------------------------------- if ( isset( $_REQUEST['bt_html'] ) ) { + if ( DEBUGNOALYSS > 1 ) \Noalyss\Dbg::timer_start(); + echo '
'; echo Acc_Account_Ledger::HtmlTableHeader("gl_comptes"); echo '
'; - $sql='select pcm_val from tmp_pcmn '; - $cond_poste=''; + try { + $from_periode=$http->request("from_periode","date"); + $to_periode=$http->request("to_periode","date"); - if ($from_poste->value != '') - { - $cond_poste = ' where '; - $cond_poste .=' pcm_val >= upper (\''.Database::escape_string($from_poste->value).'\')'; - } - - if ( $to_poste->value != '') - { - if ( $cond_poste == '') - { - $cond_poste = ' where pcm_val <= upper (\''.Database::escape_string($to_poste->value).'\')'; - } - else - { - $cond_poste.=' and pcm_val <= upper (\''.Database::escape_string($to_poste->value).'\')'; - } - } - - $sql=$sql.$cond_poste.' order by pcm_val::text'; - - $a_poste=$cn->get_array($sql); - - if ( sizeof($a_poste) == 0 ) - { - die("Nothing here. Strange."); - exit; - } - if ( isDate($_REQUEST['from_periode'])==null || isDate($_REQUEST['to_periode'])==null) - { + } catch (Exception $e) { echo alert(_('Date malformée, désolée')); return; } + + + $a_accounting=Acc_Account_Ledger::get_used_accounting($from_periode,$to_periode,$from_poste->value,$to_poste->value); + + if ( sizeof($a_accounting) == 0 ) + { + echo_warning(_("Aucune donnée")); + return; + } + echo '
'; @@ -150,14 +135,12 @@ if ( isset( $_REQUEST['bt_html'] ) ) $s=(isset($_REQUEST['solded']))?1:0; - foreach ($a_poste as $poste_id ) + foreach ($a_accounting as $accounting_id ) { - $Poste=new Acc_Account_Ledger ($cn, $poste_id['pcm_val']); - $Poste->load(); + $acc_account_ledger=new Acc_Account_Ledger ($cn, $accounting_id['pcm_val']); - - $Poste->get_row_date( $_GET['from_periode'], $_GET['to_periode'],$l,$s); - if ( empty($Poste->row)) + $acc_account_ledger->get_row_date( $from_periode, $to_periode,$l,$s); + if ( empty($acc_account_ledger->row)) { continue; } @@ -165,7 +148,7 @@ if ( isset( $_REQUEST['bt_html'] ) ) echo ' -

'. $poste_id['pcm_val'].' '.h($Poste->label).'

+

'. $accounting_id['pcm_val'].' '.h($accounting_id['pcm_lib']).'

'; @@ -188,7 +171,7 @@ if ( isset( $_REQUEST['bt_html'] ) ) $i=0; $current_exercice=""; - foreach ($Poste->row as $detail) + foreach ($acc_account_ledger->row as $detail) { /* * separation per exercice @@ -199,7 +182,7 @@ if ( isset( $_REQUEST['bt_html'] ) ) echo ' '.$current_exercice.' '.''.' - '._("Total du compte").$poste_id['pcm_val'].' + '._("Total du compte").$accounting_id['pcm_val'].' '.''.''.td(""). ''.($solde_d > 0 ? nbm( $solde_d) : '').' '.($solde_c > 0 ? nbm( $solde_c) : '').' @@ -232,7 +215,7 @@ if ( isset( $_REQUEST['bt_html'] ) ) $solde = bcadd($solde,$detail['deb_montant']); $solde_d = bcadd($solde_d,$detail['deb_montant']); } - $side=" ".$Poste->get_amount_side($solde); + $side=" ".$acc_account_ledger->get_amount_side($solde); $letter=""; $html_let=""; if ($detail['letter'] > 0) { @@ -256,7 +239,7 @@ if ( isset( $_REQUEST['bt_html'] ) ) echo ' '.$current_exercice.' '.''.' - '.''.'Total du compte '.$poste_id['pcm_val'].''.' + '.''.'Total du compte '.$accounting_id['pcm_val'].''.' '.''.''.td(""). ''.''.($solde_d > 0 ? nbm( $solde_d) : '').''.' '.''.($solde_c > 0 ? nbm( $solde_c) : '').''.' @@ -272,6 +255,7 @@ if ( isset( $_REQUEST['bt_html'] ) ) echo ''; echo Acc_Account_Ledger::HtmlTableHeader("gl_comptes"); echo "
"; - exit; + if ( DEBUGNOALYSS > 1 ) \Noalyss\Dbg::timer_show(); + return; } ?> diff --git a/unit-test/include/class/acc_account_ledger.Test.php b/unit-test/include/class/acc_account_ledgerTest.php similarity index 91% rename from unit-test/include/class/acc_account_ledger.Test.php rename to unit-test/include/class/acc_account_ledgerTest.php index 309524755..5021476cd 100644 --- a/unit-test/include/class/acc_account_ledger.Test.php +++ b/unit-test/include/class/acc_account_ledgerTest.php @@ -451,5 +451,34 @@ class Acc_Account_LedgerTest extends TestCase $result=$this->object->find_card(); $this->assertEquals($p_card, $result[0]['f_id']); } + public function dataGet_used_accounting() + { + $array=array( + ["01.01.2020","31.12.2020",5,7,4] + ,["01.01.2019","31.12.2020",5,7,10] + ,["01.01.2019","31.12.2020",5,6,3] + ,["01.01.2019","31.12.2020",5,5,0] + ,["01.01.2019","31.12.2020",5,2,0] + ,["01.01.2019","31.12.2020",5,2,0] + ,["01.01.2019","31.14.2020",5,7,0] + ,["01.13.2019","31.14.2020",5,7,0] + ); + return $array; + } + /** + * @brief test function Acc_Account_Ledger::get_used_accounting + * @covers Acc_Account_Ledger::get_used_accounting + * @dataProvider dataGet_used_accounting + */ + public function testGet_UsedAcccounting($from_date,$to_date,$from_accounting,$to_accounting,$nb_accounting) + { + $a_result=Acc_Account_Ledger::get_used_accounting(from_date:$from_date + ,to_date:$to_date + ,from_accounting:$from_accounting + ,to_accounting:$to_accounting); + $this->assertEquals($nb_accounting,count($a_result) + ,"number of accounting incorrect for (\$from_date,\$to_date,\$from_accounting,\$to_accounting,\$nb_accounting : ($from_date,$to_date,$from_accounting,$to_accounting,$nb_accounting"); + + } }