db=$p_cn; } /*! * \brief return a string with the form for selecting the periode and * the type of bilan * \param $p_filter_year filter on a year * * \return a string */ function display_form($p_filter_year="") { $r=""; $r.=dossier::hidden(); $r.= ''; $r.=''; // filter on the current year $w=new widget("select"); $w->table=1; $periode_start=make_array($this->db,"select p_id,to_char(p_start,'DD-MM-YYYY') from parm_periode $p_filter_year order by p_start,p_end"); $periode_end=make_array($this->db,"select p_id,to_char(p_end,'DD-MM-YYYY') from parm_periode $p_filter_year order by p_start,p_end"); $w->label="Depuis"; $w->value=$this->from; $w->selected=$this->from; $r.= $w->IOValue('from_periode',$periode_start); $w->label=" jusque "; $w->value=$this->to; $w->selected=$this->to; $r.= $w->IOValue('to_periode',$periode_end); $r.= ""; $r.=""; $mod=new widget('select'); $mod->table=1; $mod->value=make_array($this->db,"select b_id, b_name from bilan order by b_name"); $mod->label="Choix du bilan"; $r.=$mod->IOValue('b_id'); $r.=""; $r.= '
'; return $r; } /*!\brief check and warn if an accound has the wrong saldo * \param $p_message legend of the fieldset * \param $p_type type of the Acccount ACT actif, ACTINV... * \param $p_type the saldo must debit or credit */ private function warning($p_message,$p_type,$p_deb) { $sql="select pcm_val,pcm_lib from tmp_pcmn where pcm_type='$p_type'"; $res=ExecSql($this->db,$sql); if ( pg_NumRows($res) ==0 ) return; $count=0; $nRow=pg_NumRows($res); $ret=""; $obj=new Acc_Account_Ledger($this->db,0); for ($i=0;$i<$nRow;$i++) { $line=pg_fetch_array($res); /* set the periode filter */ $sql=sql_filter_per($this->db,$this->from,$this->to,'p_id','j_tech_per'); $obj->id=$line['pcm_val']; $solde=$obj->get_solde_detail($sql); $solde_signed=$solde['debit']-$solde['credit']; if ( ($solde_signed < 0 && $p_deb == 'D' ) || ($solde_signed > 0 && $p_deb == 'C' ) ) { $ret.= '
  • Anomalie pour le compte '.$line['pcm_val']. $line['pcm_lib']. " D: ".$solde['debit']. " C: ".$solde['credit']." diff ".$solde['solde']; $count++; } } echo '
    '; echo ''.$p_message.''; if ( $count <> 0 ) { echo '
      '.$ret.'
    '; echo 'Nbres anomalies : '.$count.''; } else echo " Pas d'anomalie détectée"; echo '
    '; } /*!\brief verify that the saldo is good for the type of account */ function verify() { echo '

    Comptes normaux

    '; $this->warning('Actif avec un solde crediteur','ACT','D'); $this->warning('Passif avec un solde debiteur','PAS','C'); $this->warning('Compte de resultat : Charge avec un solde crediteur','CHA','D'); $this->warning('Compte de resultat : produit avec un solde debiteur','PRO','C'); echo '
    '; echo '

    Comptes inverses

    '; $this->warning('Compte inverse : actif avec un solde debiteur','ACTINV','C'); $this->warning('Compte inverse : passif avec un solde crediteur','PASINV','D'); $this->warning('Compte inverse : Charge avec un solde debiteur','CHAINV','C'); $this->warning('Compte inverse : produit avec un solde crediteur','PROINV','D'); echo '

    Solde

    '; /* set the periode filter */ $sql_periode=sql_filter_per($this->db,$this->from,$this->to,'p_id','j_tech_per'); /* debit Actif */ $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)". " where j_debit='t' and (pcm_type='ACT' or pcm_type='ACTINV')"; $sql.="and $sql_periode"; $debit_actif=getDbValue($this->db,$sql); /* Credit Actif */ $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)". " where j_debit='f' and (pcm_type='ACT' or pcm_type='ACTINV')"; $sql.="and $sql_periode"; $credit_actif=getDbValue($this->db,$sql); $total_actif=abs($debit_actif-$credit_actif); echo 'Total actif '.$total_actif; echo '
    '; /* debit passif */ $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)". " where j_debit='t' and (pcm_type='PAS' or pcm_type='PASINV') "; $sql.="and $sql_periode"; $debit_passif=getDbValue($this->db,$sql); /* Credit Actif */ $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)". " where j_debit='f' and (pcm_type='PAS' or pcm_type='PASINV') "; $sql.="and $sql_periode"; $credit_passif=getDbValue($this->db,$sql); $total_passif=abs($debit_passif-$credit_passif); echo 'Total passif '.$total_passif; echo '
    '; /* debit charge */ $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)". " where j_debit='t' and (pcm_type='CHA' or pcm_type='CHAINV')"; $sql.="and $sql_periode"; $debit_charge=getDbValue($this->db,$sql); /* Credit charge */ $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)". " where j_debit='f' and (pcm_type='CHA' or pcm_type='CHAINV')"; $sql.="and $sql_periode"; $credit_charge=getDbValue($this->db,$sql); $total_charge=abs($debit_charge-$credit_charge); echo 'Total charge '.$total_charge; echo '
    '; /* debit prod */ $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)". " where j_debit='t' and (pcm_type='PRO' or pcm_type='PROINV')"; $sql.="and $sql_periode"; $debit_pro=getDbValue($this->db,$sql); /* Credit prod */ $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)". " where j_debit='f' and (pcm_type='PRO' or pcm_type='PROINV')"; $sql.="and $sql_periode"; $credit_pro=getDbValue($this->db,$sql); $total_pro=abs($debit_pro-$credit_pro); echo 'Total produit '.$total_pro; echo '
    '; if ( $total_actif != $total_passif ) { $diff=$total_actif-$total_passif; echo 'Difference Actif - Passif = '.$diff.''; echo '
    '; } $diff=$total_pro-$total_charge; echo ''; echo "Difference Produit - Charge ".$diff; echo ''; } /*! * \brief get data from the $_GET * */ function get_request_get() { $this->id=(isset($_GET['b_id']))?$_GET['b_id']:""; $this->from=( isset ($_GET['from_periode']))?$_GET['from_periode']:-1; $this->to=( isset ($_GET['to_periode']))?$_GET['to_periode']:-1; } /*!\brief load from the database the document data */ function load(){ try { if ( $this->id=="") throw new Exception("le formulaire id n'est pas donnee"); $sql="select b_name,b_file_template,b_file_form,lower(b_type) as b_type from bilan where". " b_id = ".$this->id; $res=ExecSql($this->db,$sql); if ( pg_NumRows($res)==0) throw new Exception ('Aucun enregistrement trouve'); $array=pg_fetch_array($res,0); foreach ($array as $name=>$value) $this->$name=$value; }catch(Exception $Ex) { echo $Ex->getMessage(); exit(); } } /*!\brief open the file of the form */ /*\return an handle to this file */ function file_open_form() { $form=fopen($this->b_file_form,'r'); if ( $form == false) { echo 'Cannot Open'; exit(); } return $form; } /*!\brief open the file with the template */ /*\return an handle to this file */ function file_open_template() { $templ=fopen($this->b_file_template,'r'); if ( $templ == false) { echo 'Cannot Open'; exit(); } return $templ; } /*! * \brief Compute all the formula * \param $p_handle the handle to the file * \param * \param * * * \return */ function compute_formula($p_handle) { while (! feof ($p_handle)) { $buffer=trim(fgets($p_handle)); echo_debug(__FILE__.":".__LINE__." get buffer = ",$buffer); // $a=(CheckFormula($buffer) == true)?"$buffer ok
    ":''.'Pas ok '.$buffer."
    "; // echo $a; // blank line are skipped if (strlen(trim($buffer))==0) continue; // skip comment if ( strpos($buffer,'#') === true ) continue; // buffer contains a formula A$=.... // We need to eval it //ereg("\\$[a-zA-Z]+[0-9]*=",$buffer,$e); // echo $e[0]; //echo "
    ".$form; $a=ParseFormula($this->db,"$buffer",$buffer,$this->from,$this->to,false); echo_debug(__FILE__.":".__LINE__." evaluate \$a",$a); $b=str_replace("$","\$this->",$a); echo_debug(__FILE__.":".__LINE__." evaluate \$b",$b); if ( eval("$b;") === false ) echo_debug(__FILE__,__LINE__,"Code failed with $b"); }// end read form line per line echo_debug(__FILE__.':'.__LINE__," End of reading form"); } /*!\brief generate the ods document * \param the handle to the template file * \return the xml */ function generate_odt() { // create a temp directory in /tmp to unpack file and to parse it $dirname=tempnam($_ENV['TMP'],'bilan_'); unlink($dirname); mkdir ($dirname); chdir($dirname); echo_debug(__FILE__.':'.__LINE__.'- ','dirname is ',$dirname); $file_base=dirname($_SERVER['SCRIPT_FILENAME']).DIRECTORY_SEPARATOR.$this->b_file_template; echo_debug(__FILE__.':'.__LINE__.'-','$file_base',$file_base); echo_debug(__FILE__.':'.__LINE__.'- ','this is ',$this->b_file_template); $work_file=basename($file_base); if ( copy ($file_base,$work_file) == false ) { echo "Je ne peux pas ouvrir ce fichier "; exit(); } ob_start(); system('unzip "'.$work_file.'"'); ob_end_clean(); unlink($work_file); // remove the zip file $p_file=fopen('content.xml','r'); if ( $p_file == false) { echo 'Cannot Open'; exit(); } $r=""; $regex="<<\\$[A-Z]*[0-9]*>>"; $lt="<"; $gt=">"; while ( !feof($p_file) ) { echo_debug(__FILE__.':'.__LINE__.'- ','read line OD FILE'); $line_rtf=fgets($p_file); // echo_debug(__FILE__.':'.__LINE__.'-','$line_rtf',$line_rtf); if ( ereg('<<header>>',$line_rtf) ) { // Create the header $line_rtf=str_replace('<<header>>',header_txt($this->db),$line_rtf); $r.=$line_rtf; echo_debug(__FILE__.':'.__LINE__.'- ','Header : '); continue; } // echo_debug(__FILE__.':'.__LINE__.'- ','$r',$r); // the line contains the magic << $tmp=""; while (ereg($regex,$line_rtf,$f2) == true) { // DEBUG // echo $r.'
    '; echo_debug(__FILE__.':'.__LINE__.'- ','Pattern found',$f2); // the f2 array contains all the magic << in the line foreach ($f2 as $f2_str) { echo_debug(__FILE__.':'.__LINE__.'- ','f2_str',$f2_str); // DEBUG // echo "single_f2 = $f2_str
    "; // replace single_f2 by its value $to_remove=$f2_str; $f2_value=str_replace("<","",$f2_str); $f2_value=str_replace(">","",$f2_value); $f2_value=str_replace("$","",$f2_value); // DEBUG //echo "f2_value=$f2_value"; // $a=${"$f2_value"}; $a=$this->$f2_value; if ( $a=='-0' ) $a=0; echo_debug(__FILE__.':'.__LINE__.'- $a =',$a); // DEBUG echo " a = $a"; $line_rtf=str_replace($f2_str,$a,$line_rtf); }// foreach end } $r.=$line_rtf; }// rtf file is read // DEBUG // fwrite($out,$r); // echo $r; return $r; } /*! * \brief generate the plain file (rtf,txt, or html) * \param the handle to the template file */ function generate_plain($p_file) { $r=""; if ( $this->b_type=='html') { $lt='<';$gt='>'; } else { $lt='<';$gt='>'; } while ( !feof($p_file) ) { $line_rtf=fgets($p_file); echo_debug(__FILE__.':'.__LINE__.'-','$line_rtf',$line_rtf); if ( ereg($lt.$lt.'header'.$gt.$gt,$line_rtf) ) { // Create the header $line_rtf=str_replace($lt.$lt.'header'.$gt.$gt,header_txt($this->db),$line_rtf); $r.=$line_rtf; continue; } echo_debug(__FILE__.':'.__LINE__.'- ','$r',$r); // the line contains the magic << if (ereg($lt.$lt."\\$[a-zA-Z]*[0-9]*".$gt.$gt,$line_rtf,$f2) == true) { // DEBUG // echo $r.'
    '; echo_debug(__FILE__.':'.__LINE__.'- ','Pattern found',$f2); // the f2 array contains all the magic << in the line foreach ($f2 as $f2_str) { // DEBUG // echo "single_f2 = $f2_str
    "; // replace single_f2 by its value $f2_value=str_replace($lt,"",$f2_str); $f2_value=str_replace($gt,"",$f2_value); $f2_value=str_replace("$","",$f2_value); // DEBUG //echo "f2_value=$f2_value"; // $a=${"$f2_value"}; $a=$this->$f2_value; // DEBUG echo " a = $a"; echo_debug(__FILE__.':'.__LINE__.'- $a =',$a); if ( $a=='-0' ) $a=0; $line_rtf=str_replace($f2_str,$a,$line_rtf); }// foreach end } $r.=$line_rtf; }// rtf file is read // DEBUG // fwrite($out,$r); return $r; } /*!\brief generate the document and send it to the browser */ function generate() { // Load the data $this->load(); // Open the files $form=$this->file_open_form(); // Compute all the formula and add the value to this $this->compute_formula($form); fclose($form); // open the form $templ=$this->file_open_template(); switch ($this->b_type) { case 'rtf': $result=$this->generate_plain($templ); $this->send($result); break; case 'txt': $result=$this->generate_plain($templ); $this->send($result); case 'html': $result=$this->generate_plain($templ); $this->send($result); break; case 'odt': case 'ods': $result=$this->generate_odt($templ); $this->send($result); break; } fclose($templ); } /*!\brief send the result of generate plain to the browser * \param $p_result is the string returned by generate_... */ function send($p_result) { switch ($this->b_type) { case 'rtf': // A rtf file is generated header('Content-type: application/rtf'); header('Content-Disposition: attachment; filename="'.$this->b_name.'.rtf"'); echo $p_result; break; case 'txt': // A txt file is generated header('Content-type: application/txt'); header('Content-Disposition: attachment; filename="'.$this->b_name.'.txt"'); echo $p_result; break; case 'html': // A txt file is generated header('Content-type: application/html'); header('Content-Disposition: attachment; filename="'.$this->b_name.'.html"'); echo $p_result; break; case 'odt': case 'ods': /* header("Pragma: public"); header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Cache-Control: must-revalidate"); header('Content-type: "application/vnd.oasis.opendocument.text"'); header('Content-Disposition: attachment;filename="'.$this->b_name.'.odt"',FALSE); header("Accept-Ranges: bytes"); */ ob_start(); // save the file in a temp folder // create a temp directory in /tmp to unpack file and to parse it $dirname=tempnam($_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.'tmp','bilan_'); unlink($dirname); mkdir ($dirname); chdir($dirname); echo_debug(__FILE__.':'.__LINE__.'- ','dirname is ',$dirname); // create a temp directory in /tmp to unpack file and to parse it $file_base=dirname($_SERVER['SCRIPT_FILENAME']).DIRECTORY_SEPARATOR.$this->b_file_template; echo_debug(__FILE__.':'.__LINE__.'-','$file_base',$file_base); echo_debug(__FILE__.':'.__LINE__.'- ','this is ',$this->b_file_template); $work_file=basename($file_base); if ( copy ($file_base,$work_file) == false ) { echo "Je ne peux pas ouvrir ce fichier "; echo_debug(__FILE__.':'.__LINE__.'- Je ne peux pas ouvrir ce fichier '); exit(); } system('unzip "'.$work_file.'"'); // remove the zip file unlink ($work_file); // replace the file $p_file=fopen($dirname.DIRECTORY_SEPARATOR.'content.xml','wb'); if ( $p_file == false ){ echo_debug(__FILE__.':'.__LINE__.'- Je ne peux pas ouvrir content.xml '); exit('Je ne peux pas ouvrir content.xml'); } $a=fwrite($p_file,$p_result); if ( $a==false) { echo "Je ne peux pas ecrire dans content.xml"; echo_debug(__FILE__.':'.__LINE__.'- Je ne peux pas ecrire dans content.xml '); exit(); } // repack system ('zip -r "'.$this->b_name.'.'.$this->b_type.'" *'); ob_end_clean(); fclose($p_file); echo_debug(__FILE__.':'.__LINE__.'- ','Send the file'); $fdoc=fopen($dirname.DIRECTORY_SEPARATOR.$this->b_name.'.'.$this->b_type,'r'); if ( $fdoc == false ){ echo_debug(__FILE__.':'.__LINE__.'- Je ne peux pas ouvrir ce document'); exit('Je ne peux pas ouvrir ce document'); } $buffer=fread ($fdoc,filesize($dirname.DIRECTORY_SEPARATOR.$this->b_name.'.'.$this->b_type)); echo $buffer; break; // and send } } static function test_me() { if ( isset($_GET['result'])) { ob_start(); $cn=DbConnect(dossier::id()); $a=new Acc_Bilan($cn); $a->get_request_get(); $a->load(); $form=$a->file_open_form(); $a->compute_formula($form); fclose($form); // open the form $templ=$a->file_open_template(); $r=$a->generate_odt($templ); fclose($templ); ob_end_clean(); // echo_debug(__FILE__.':'.__LINE__,"resutl ",$r); $a->send($r); } else { $cn=DbConnect(dossier::id()); $a=new Acc_Bilan($cn); $a->get_request_get(); echo '
    '; echo $a->display_form(); echo '
    '; } } }