db=$p_cn; $this->id=$p_id; } /** *@brief get the row thanks the resource *@return double array (j_date,deb_montant,cred_montant,description,jrn_name,j_debit,jr_internal) * (tot_deb,tot_credit) * @deprecated since version 6920 */ private function get_row_sql_deprecated($Res) { $array=array(); $tot_cred=0.0; $tot_deb=0.0; $Max=Database::num_row($Res); if ( $Max == 0 ) return null; for ($i=0;$i<$Max;$i++) { $array[]=Database::fetch_array($Res,$i); if ($array[$i]['j_debit']=='t') { $tot_deb+=$array[$i]['deb_montant'] ; } else { $tot_cred+=$array[$i]['cred_montant'] ; } } $this->row=$array; $this->tot_deb=$tot_deb; $this->tot_cred=$tot_cred; return array($array,$tot_deb,$tot_cred); } /*! * \brief Get data for accounting entry between 2 periode * * \param $p_from periode from * \param $p_to end periode * \return double array (j_date,deb_montant,cred_montant,description,jrn_name,j_debit,jr_internal) * (tot_deb,tot_credit * */ function get_row($p_from,$p_to) { $periode=sql_filter_per($this->db,$p_from,$p_to,'p_id','jr_tech_per'); $this->row=$this->db->get_array("select distinct j_id,jr_id,to_char(j_date,'DD.MM.YYYY') as j_date_fmt,j_date,". "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,". " jr_comment as description,jrn_def_name as jrn_name,". "j_debit, jr_internal,jr_pj_number ". " from jrnx left join jrn_def on jrn_def_id=j_jrn_def ". " left join jrn on jr_grpt_id=j_grpt". " where j_poste=$1 and $periode ". " order by j_date",array($this->id)); $res_saldo = $this->db->exec_sql( "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 left join jrn_def on jrn_def_id=j_jrn_def left join jrn on jr_grpt_id=j_grpt where j_poste=$1 and $periode ) as m ",array($this->id)); $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); } /*! * \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 j_id in (select j_id from letter_cred union all select j_id from letter_deb)'; break; case '2': $sql_let=' and 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(" with sqlletter as (select j_id,jl_id from letter_cred union all select j_id , jl_id from letter_deb ) select j_id,jr_id,to_char(j_date,'DD.MM.YYYY') as j_date_fmt,j_date, j_qcode ,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, case when j_text is null or j_text = '' then jr_comment else jr_comment||' '||j_text end as description,jrn_def_name as jrn_name, j_debit, jr_internal,jr_pj_number ,(select distinct jl_id from sqlletter where sqlletter.j_id=j1.j_id ) as letter ,pcm_lib ,jr_optype ,jr_tech_per ,p_exercice ,jrn_def_name ,jrn_def_code ,(with cred as (select jl_id, sum(j_montant) as amount_cred from letter_cred left join jrnx using (j_id) group by jl_id ), deb as (select jl_id, sum(j_montant) as amount_deb from letter_deb left join jrnx using (j_id) group by jl_id ) select amount_deb-amount_cred from cred full join deb using (jl_id) where jl_id=(select distinct jl_id from sqlletter where sqlletter.j_id=j1.j_id )) as delta_letter from jrnx as j1 join jrn_def on (jrn_def_id=j_jrn_def ) join jrn on (jr_grpt_id=j_grpt) join tmp_pcmn on (j_poste=pcm_val) join parm_periode on (p_id=jr_tech_per) 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 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 (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 join jrn_def on (jrn_def_id=j_jrn_def ) join jrn on (jr_grpt_id=j_grpt) join tmp_pcmn on (j_poste=pcm_val) join parm_periode on (p_id=jr_tech_per) 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); } return array($this->row,$this->tot_deb,$this->tot_cred); } /*!\brief Return the name of a account * it doesn't change any data member * \return string with the pcm_lib */ function get_name() { $ret=$this->db->exec_sql( "select pcm_lib from tmp_pcmn where pcm_val=$1",array($this->id)); if ( Database::num_row($ret) != 0) { $r=Database::fetch_array($ret); $this->name=$r['pcm_lib']; } else { $this->name=_("Poste inconnu"); } return $this->name; } /*!\brief check if the poste exist in the tmp_pcmn *\return the number of line (normally 1 or 0) */ function do_exist() { $sql="select pcm_val from tmp_pcmn where pcm_val= $1"; $ret=$this->db->exec_sql($sql,array($this->id)); return Database::num_row($ret) ; } /*!\brief Get all the value for this object from the database * the data member are set * \return false if this account doesn't exist otherwise true */ function load() { $ret=$this->db->exec_sql("select pcm_lib,pcm_val_parent from tmp_pcmn where pcm_val=$1",array($this->id)); $r=Database::fetch_all($ret); if ( ! $r ) return false; $this->label=$r[0]['pcm_lib']; $this->parent=$r[0]['pcm_val_parent']; return true; } /*!\brief Get all the value for this object from the database * the data member are set * \return false if this account doesn't exist otherwise true */ function get() { echo "OBSOLETE Acc_Account_Ledger->get(), a remplacer par Acc_Account_Ledger->load()"; return $this->load(); } /*! * \brief give the balance of an account * * \return * balance of the account * */ function get_solde($p_cond=" true ") { $Res=$this->db->exec_sql("select sum(deb) as sum_deb, sum(cred) as sum_cred from ( select j_poste, case when j_debit='t' then j_montant else 0 end as deb, case when j_debit='f' then j_montant else 0 end as cred from jrnx join tmp_pcmn on j_poste=pcm_val where j_poste::text like ('$this->id'::text) and $p_cond ) as m "); $Max=Database::num_row($Res); if ($Max==0) return 0; $r=Database::fetch_array($Res,0); return abs($r['sum_deb']-$r['sum_cred']); } /*! * \brief give the balance of an account * \return * balance of the account * */ function get_solde_detail($p_cond="") { if ( $p_cond != "") $p_cond=" and ".$p_cond; $sql="select sum(deb) as sum_deb, sum(cred) as sum_cred from ( select j_poste, case when j_debit='t' then j_montant else 0 end as deb, case when j_debit='f' then j_montant else 0 end as cred from jrnx where j_poste::text like ('$this->id'::text) $p_cond ) as m "; $Res=$this->db->exec_sql($sql); $Max=Database::num_row($Res); if ($Max==0) { return array('debit'=>0, 'credit'=>0, 'solde'=>0) ; } $r=Database::fetch_array($Res,0); // if p_start is < p_end the query returns null to avoid any problem // we set it to 0 if ($r['sum_deb']=='') $r['sum_deb']=0.0; if ($r['sum_cred']=='') $r['sum_cred']=0.0; return array('debit'=>$r['sum_deb'], 'credit'=>$r['sum_cred'], 'solde'=>abs(bcsub($r['sum_deb'],$r['sum_cred']))); } /*! * \brief isTva tell is a poste is used for VAT * \param none * * * \return 1 is Yes otherwise 0 */ function isTVA() { // Load TVA array $a_TVA=$this->db->get_array('select tva_poste from tva_rate'); foreach ( $a_TVA as $line_tva) { if ( $line_tva['tva_poste'] == '' ) continue; list($tva_deb,$tva_cred)=explode(',',$line_tva['tva_poste']); if ( $this->id == $tva_deb || $this->id == $tva_cred ) { return 1; } } return 0; } /*! * \brief HtmlTable, display a HTML of a poste for the asked period * \param $p_array array for filter * \param $let lettering of operation 0 * \return -1 if nothing is found otherwise 0 */ function HtmlTable($p_array=null,$let=0 , $from_div=0) { if ( $p_array==null)$p_array=$_REQUEST; $this->get_name(); list($array,$tot_deb,$tot_cred)=$this->get_row_date( $p_array['from_periode'], $p_array['to_periode'],$let ); if ( count($this->row ) == 0 ) return -1; $rep=""; if ( $from_div == 1) echo ""; else echo "
"; echo ''; echo "". "". "". "". "". "". "". "". "". "". th('Prog.','style="text-align:right"'). th('Let.','style="text-align:right"'); "" ; $progress=0;$sum_deb=0;$sum_cred=0; bcscale(2); $old_exercice=""; $idx=0; $operation=new Acc_Operation($this->db); foreach ( $this->row as $op ) { $tiers=$operation->find_tiers($op['jr_id'],$op['j_id'],$op['j_qcode']); $vw_operation = sprintf('%s', $op['jr_id'], dossier::id(), $op['jr_internal']); $let = ''; $html_let = ""; if ($op['letter'] != 0) { $let = strtoupper(base_convert($op['letter'], 10, 36)); $html_let = HtmlInput::show_reconcile($from_div, $let); if ( $op['delta_letter'] != 0) $html_let=''.$html_let; } $tmp_diff=bcsub($op['deb_montant'],$op['cred_montant']); /* * reset prog. balance to zero if we change of exercice */ if ( $old_exercice != $op['p_exercice']) { if ( $old_exercice != '') { $progress=bcsub($sum_deb,$sum_cred); $side=" ".$this->get_amount_side($progress); echo "". "". "".td().td().td(). "".td(""). "". "". td(nbm(abs($progress)).$side,'style="text-align:right"'). td(''). ""; $sum_cred=0; $sum_deb=0; $progress=0; } } $progress=bcadd($progress,$tmp_diff); $side=" ".$this->get_amount_side($progress); $sum_cred=bcadd($sum_cred,$op['cred_montant']); $sum_deb=bcadd($sum_deb,$op['deb_montant']); if ($idx%2 == 0) $class='class="odd"'; else $class=' class="even"'; $idx++; echo "" . "". td(h($op['jr_pj_number'])). "". "". "". "". td($op['jr_optype']). "". "". td(nbm(abs($progress)).$side,'style="text-align:right"'). td($html_let, ' style="color:red;text-align:right"') . ""; $old_exercice=$op['p_exercice']; } echo ''; $solde_type=($sum_deb>$sum_cred)?_("solde débiteur"):_("solde créditeur"); $diff=bcsub($sum_deb,$sum_cred); $side=" ".$this->get_amount_side($diff); echo "". td($op['p_exercice']). td().td().td().td(). "".td(""). "". "". "". td(). ""; echo "". "". ""; echo ''; echo ''; echo "
"._('Date')." "._('n° de pièce')." "._('QuickCode').""._('Code interne')." "._('Tiers')." "._('Description').""._('Type').""._('Débit').""._("Crédit")."
$old_exercice"._("Totaux")."".nbm($sum_deb)."".nbm($sum_cred)."
".smaller_date(format_date($op['j_date']))."".h($op['j_qcode'])."".$vw_operation."".$tiers."".h($op['description'])."".nbm($op['deb_montant'])."".nbm($op['cred_montant'])."
Totaux".nbm($sum_deb)."".nbm($sum_cred)."".nbm(abs($diff)).$side."
$solde_type".nbm(abs($diff))."
"; return; } /** * return the letter C if amount is > 0, D if < 0 or = * @param type $p_amount * @return string */ function get_amount_side($p_amount) { if ($p_amount == 0) return "="; if ($p_amount < 0) return "C"; if ($p_amount > 0) return "D"; } /*! * \brief Display HTML Table Header (button) * * \return none */ static function HtmlTableHeader($actiontarget="poste") { switch($actiontarget) { case 'poste': $action_csv='CSV:postedetail'; $action_pdf='PDF:postedetail'; break; case 'gl_comptes': $action_csv='CSV:glcompte'; $action_pdf='PDF:glcompte'; break; default: throw new Exception(" Fonction HtmlTableHeader argument actiontarget invalid"); } $hid=new IHidden(); echo ""; echo ''; $str_ople=(isset($_REQUEST['ople']))?HtmlInput::hidden('ople',$_REQUEST['ople']):''; if ($actiontarget=='poste') { echo '"; } echo '"; echo '"; echo ""; echo ''; echo ''; echo "
'. dossier::hidden(). HtmlInput::submit('bt_other',"Autre poste"). $hid->input("type","poste").$hid->input('ac',$_REQUEST['ac'])."
'. dossier::hidden(). HtmlInput::submit('bt_pdf',"Export PDF"). HtmlInput::hidden('act',$action_pdf). $hid->input("type","poste").$str_ople. $hid->input('p_action','impress'). $hid->input("from_periode",$_REQUEST['from_periode']). $hid->input("to_periode",$_REQUEST['to_periode']) ; if ( isset($_REQUEST['letter'] )) echo HtmlInput::hidden('letter','2'); if ( isset($_REQUEST['solded'] )) echo HtmlInput::hidden('solded','1'); if (isset($_REQUEST['from_poste'])) echo HtmlInput::hidden('from_poste',$_REQUEST['from_poste']); if (isset($_REQUEST['to_poste'])) echo HtmlInput::hidden('to_poste',$_REQUEST['to_poste']); if (isset($_REQUEST['poste_id'])) echo HtmlInput::hidden("poste_id",$_REQUEST['poste_id']); if (isset($_REQUEST['poste_fille'])) echo $hid->input('poste_fille','on'); if (isset($_REQUEST['oper_detail'])) echo $hid->input('oper_detail','on'); echo "
'. dossier::hidden(). HtmlInput::submit('bt_csv',"Export CSV"). HtmlInput::hidden('act',$action_csv). $hid->input("type","poste").$str_ople. $hid->input('p_action','impress'). $hid->input("from_periode",$_REQUEST['from_periode']). $hid->input("to_periode",$_REQUEST['to_periode']); if (isset($_REQUEST['from_poste'])) echo HtmlInput::hidden('from_poste',$_REQUEST['from_poste']); if (isset($_REQUEST['to_poste'])) echo HtmlInput::hidden('to_poste',$_REQUEST['to_poste']); if (isset($_REQUEST['poste_id'])) echo HtmlInput::hidden("poste_id",$_REQUEST['poste_id']); if ( isset($_REQUEST['letter'] )) echo HtmlInput::hidden('letter','2'); if ( isset($_REQUEST['solded'] )) echo HtmlInput::hidden('solded','1'); if (isset($_REQUEST['poste_fille'])) echo $hid->input('poste_fille','on'); if (isset($_REQUEST['oper_detail'])) echo $hid->input('oper_detail','on'); if (isset($_REQUEST['poste_id'])) echo $hid->input("poste_id",$_REQUEST['poste_id']); echo "
'; echo HtmlInput::print_window(); echo '
"; } /*! * \brief verify that the accounting belong to a ledger * * \return 0 ok, -1 no */ function belong_ledger($p_jrn) { $filter=$this->db->get_value("select jrn_def_class_cred from jrn_def where jrn_def_id=$1", array($p_jrn)); if ( trim ($filter) == '') return 0; $valid_cred=explode(" ",$filter); $sql="select count(*) as poste from tmp_pcmn where "; // Creation query $or=""; $SqlFilter=""; $SqlArray = array(); $SqlArrayN = 1; foreach ( $valid_cred as $item_cred) { if ( strlen (trim($item_cred))) { if ( strstr($item_cred,"*") == true ) { $SqlItem=$or . 'pcm_val::text like $' . $SqlArrayN++; array_push($SqlArray, strtr($item_cred,"*","%")); $or=" or "; } else { $SqlItem=$or . 'pcm_val::text = $' . $SqlArrayN++; array_push($SqlArray, $item_cred); $or=" or "; } $SqlFilter=$SqlFilter.$SqlItem; } }//foreach $sql.=$SqlFilter . ' and pcm_val::text=$' . $SqlArrayN++; array_push($SqlArray, $this->id); $max=$this->db->get_value($sql, $SqlArray); if ($max > 0 ) return 0; else return -1; } /*!\brief With the id of the ledger, get the col jrn_def_class_deb *\param $p_jrn jrn_id *\return array of value, or an empty array if nothing is found *\note *\see */ function get_account_ledger($p_jrn) { $l=new Acc_Ledger($this->db,$p_jrn); $row=$l->get_propertie(); if ( strlen(trim($row['jrn_def_class_deb'])) == 0 ) return array(); $valid_account=explode(" ",$row['jrn_def_class_deb']); return $valid_account; } /*!\brief build a sql statement thanks a array found with get_account_ledger * *\param $p_jrn jrn_id *\return an emty string if nothing is found or a valid SQL statement like \code pcm_val like ... or pcm_val like ... \endcode *\note *\see get_account_ledger */ function build_sql_account($p_jrn) { $array=$this->get_account_ledger($p_jrn); if ( empty($array) ) return ""; $sql=""; foreach ( $array as $item_cred) { if ( strlen (trim($item_cred))>0 ) { if ( strstr($item_cred,"*") == true ) { $item_cred=strtr($item_cred,"*","%"); $sql_tmp=" pcm_val::text like '$item_cred' or"; } else { $sql_tmp=" pcm_val::text = '$item_cred' or"; } $sql.=$sql_tmp; } }//foreach /* remove the last or */ $sql=substr($sql,0,strlen($sql)-2); return $sql; } /** * Find the id of the cards which are using the current account * * @return an array of f_id */ function find_card() { $sql="select f_id from fiche_detail where ad_id=$1 and ad_value=$2"; $account=$this->db->get_array($sql,array(ATTR_DEF_ACCOUNT,$this->id)); return $account; } /** * @brief Return a string with the HTML code to display a button to export the * history in CSV * @param type $p_from from date (DD.MM.YYYY) * @param type $p_to to date (DD.MM.YYYY) * @return HTML string */ function button_csv($p_from,$p_to) { $href="export.php?".http_build_query( array( "gDossier"=>Dossier::id(), "poste_id"=>$this->id, "ople"=>0, "type"=>"poste", "from_periode"=>$p_from, "to_periode"=>$p_to, "act"=>"CSV:postedetail" ) ); return ''._("Export CSV").''; } /** * @brief Return a string with the HTML code to display a button to export the * history in PDF * @param type $p_from from date (DD.MM.YYYY) * @param type $p_to to date (DD.MM.YYYY) * @return HTML string */ function button_pdf($p_from,$p_to) { $href="export.php?".http_build_query( array( "gDossier"=>Dossier::id(), "poste_id"=>$this->id, "ople"=>0, "type"=>"poste", "from_periode"=>$p_from, "to_periode"=>$p_to, "act"=>"PDF:postedetail" ) ); return ''._("Export PDF").''; } /** * @brief Filter in javascript the table with the history * @param type $p_table_id id of the table containting the data to filter * @return html string */ 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); } }