00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 require_once("class_iselect.php");
00027 require_once ('class_database.php');
00028 require_once ('class_dossier.php');
00029 require_once ('class_impress.php');
00030 require_once ('header_print.php');
00031 require_once ('class_acc_account_ledger.php');
00032
00033
00034
00035
00036
00037 class Acc_Bilan
00038 {
00039 var $db;
00040 var $b_id;
00041 var $from;
00042 var $to;
00043
00044 function Acc_Bilan($p_cn)
00045 {
00046 $this->db=$p_cn;
00047 }
00048
00049
00050
00051
00052
00053
00054
00055 function display_form($p_filter_year="")
00056 {
00057 $r="";
00058 $r.=dossier::hidden();
00059 $r.= '<TABLE>';
00060
00061 $r.='<TR>';
00062
00063 $w=new ISelect();
00064 $w->table=1;
00065
00066 $periode_start=$this->db->make_array("select p_id,to_char(p_start,'DD-MM-YYYY') from parm_periode $p_filter_year order by p_start,p_end");
00067
00068 $periode_end=$this->db->make_array("select p_id,to_char(p_end,'DD-MM-YYYY') from parm_periode $p_filter_year order by p_end,p_start");
00069
00070 $w->label=_("Depuis");
00071 $w->value=$this->from;
00072 $w->selected=$this->from;
00073 $r.= td($w->input('from_periode',$periode_start));
00074 $w->label=_(" jusque ");
00075 $w->value=$this->to;
00076 $w->selected=$this->to;
00077 $r.= td($w->input('to_periode',$periode_end));
00078 $r.= "</TR>";
00079 $r.="<tr>";
00080 $mod=new ISelect();
00081 $mod->table=1;
00082 $mod->value=$this->db->make_array("select b_id, b_name from bilan order by b_name");
00083 $mod->label=_("Choix du bilan");
00084 $r.=td($mod->input('b_id'));
00085 $r.="</tr>";
00086 $r.= '</TABLE>';
00087 return $r;
00088 }
00089
00090
00091
00092
00093
00094
00095 private function warning($p_message,$p_type,$p_deb)
00096 {
00097 $sql="select pcm_val,pcm_lib from tmp_pcmn where pcm_type='$p_type'";
00098 $res=$this->db->exec_sql($sql);
00099 if ( Database::num_row($res) ==0 )
00100 return;
00101 $count=0;
00102 $nRow=Database::num_row($res);
00103
00104 $ret="";
00105 $obj=new Acc_Account_Ledger($this->db,0);
00106 for ($i=0;$i<$nRow;$i++)
00107 {
00108
00109 $line=Database::fetch_array($res,$i);
00110
00111 $sql=sql_filter_per($this->db,$this->from,$this->to,'p_id','j_tech_per');
00112 $obj->id=$line['pcm_val'];
00113
00114 $solde=$obj->get_solde_detail($sql);
00115 $solde_signed=bcsub($solde['debit'],$solde['credit']);
00116
00117 if (
00118 ($solde_signed < 0 && $p_deb == 'D' ) ||
00119 ($solde_signed > 0 && $p_deb == 'C' )
00120 )
00121 {
00122 $ret.= '<li> '.HtmlInput::history_account($line['pcm_val'],'Anomalie pour le compte '.$line['pcm_val'].' '.h($line['pcm_lib']).
00123 " D: ".$solde['debit'].
00124 " C: ".$solde['credit']." diff ".$solde['solde']);
00125 $count++;
00126 }
00127
00128 }
00129
00130 echo '<fieldset>';
00131 echo '<legend>'.$p_message.'</legend>';
00132 if ( $count <> 0 )
00133 {
00134 echo '<ol>'.$ret.'</ol>';
00135 echo '<span class="error">'._("Nbres anomalies").' : '.$count.'</span>';
00136 }
00137 else
00138 echo _("Pas d'anomalie détectée");
00139 echo '</fieldset>';
00140
00141
00142 }
00143
00144 function verify()
00145 {
00146 bcscale(2);
00147 echo '<h3>'._("Comptes normaux").'</h3>';
00148 $this->warning(_('Actif avec un solde crediteur'),'ACT','D');
00149 $this->warning(_('Passif avec un solde debiteur'),'PAS','C');
00150 $this->warning(_('Compte de resultat : Charge avec un solde crediteur'),'CHA','D');
00151 $this->warning(_('Compte de resultat : produit avec un solde debiteur'),'PRO','C');
00152 echo '<hr>';
00153 echo '<h3>'._("Comptes inverses").' </h3>';
00154 $this->warning(_('Compte inverse : actif avec un solde debiteur'),'ACTINV','C');
00155 $this->warning(_('Compte inverse : passif avec un solde crediteur'),'PASINV','D');
00156 $this->warning(_('Compte inverse : Charge avec un solde debiteur'),'CHAINV','C');
00157 $this->warning(_('Compte inverse : produit avec un solde crediteur'),'PROINV','D');
00158 echo '<h3'._("Solde").' </h3>';
00159
00160 $sql_periode=sql_filter_per($this->db,$this->from,$this->to,'p_id','j_tech_per');
00161
00162 $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)".
00163 " where j_debit='t' and (pcm_type='ACT' or pcm_type='ACTINV')";
00164 $sql.="and $sql_periode";
00165 $debit_actif=$this->db->get_value($sql);
00166
00167
00168 $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)".
00169 " where j_debit='f' and (pcm_type='ACT' or pcm_type='ACTINV')";
00170
00171 $sql.="and $sql_periode";
00172
00173 $credit_actif=$this->db->get_value($sql);
00174 $total_actif=abs(bcsub($debit_actif,$credit_actif));
00175 echo '<table >';
00176 echo tr(td(_('Total actif')).td($total_actif,'style="text-align:right"'));
00177
00178
00179 $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)".
00180 " where j_debit='t' and (pcm_type='PAS' or pcm_type='PASINV') ";
00181 $sql.="and $sql_periode";
00182
00183 $debit_passif=$this->db->get_value($sql);
00184
00185
00186 $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)".
00187 " where j_debit='f' and (pcm_type='PAS' or pcm_type='PASINV') ";
00188 $sql.="and $sql_periode";
00189 $credit_passif=$this->db->get_value($sql);
00190 $total_passif=abs(bcsub($debit_passif,$credit_passif));
00191
00192
00193 echo tr(td(_('Total passif')).td($total_passif,'style="text-align:right"'));
00194 if ( $total_actif != $total_passif )
00195 {
00196 $diff=bcsub($total_actif,$total_passif);
00197 echo tr(td(' Difference Actif - Passif ').td($diff,'style="text-align:right"'),'style="font-weight:bolder"');
00198 }
00199
00200
00201 $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)".
00202 " where j_debit='t' and (pcm_type='CHA' or pcm_type='CHAINV')";
00203 $sql.="and $sql_periode";
00204 $debit_charge=$this->db->get_value($sql);
00205
00206
00207 $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)".
00208 " where j_debit='f' and (pcm_type='CHA' or pcm_type='CHAINV')";
00209 $sql.="and $sql_periode";
00210 $credit_charge=$this->db->get_value($sql);
00211 $total_charge=abs(bcsub($debit_charge,$credit_charge));
00212 echo tr(td(_('Total charge ')).td($total_charge,'style="text-align:right"'));
00213
00214
00215
00216 $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)".
00217 " where j_debit='t' and (pcm_type='PRO' or pcm_type='PROINV')";
00218 $sql.="and $sql_periode";
00219 $debit_pro=$this->db->get_value($sql);
00220
00221
00222 $sql="select sum(j_montant) from jrnx join tmp_pcmn on (j_poste=pcm_val)".
00223 " where j_debit='f' and (pcm_type='PRO' or pcm_type='PROINV')";
00224 $sql.="and $sql_periode";
00225 $credit_pro=$this->db->get_value($sql);
00226 $total_pro=abs(bcsub($debit_pro,$credit_pro));
00227 echo tr(td(_('Total produit')).td($total_pro,'style="text-align:right"'));
00228
00229 $diff=bcsub($total_pro,$total_charge);
00230
00231 echo tr( td(_("Difference Produit - Charge"),'style="padding-right:20px"').td($diff,'style="text-align:right"'),'style="font-weight:bolder"');
00232 echo '</table>';
00233 }
00234
00235
00236
00237
00238 function get_request_get()
00239 {
00240 $this->b_id=(isset($_GET['b_id']))?$_GET['b_id']:"";
00241 $this->from=( isset ($_GET['from_periode']))?$_GET['from_periode']:-1;
00242 $this->to=( isset ($_GET['to_periode']))?$_GET['to_periode']:-1;
00243 }
00244
00245 function load()
00246 {
00247 try
00248 {
00249 if ( $this->b_id=="")
00250 throw new Exception(_("le formulaire id n'est pas donnee"));
00251
00252 $sql="select b_name,b_file_template,b_file_form,lower(b_type) as b_type from bilan where".
00253 " b_id = ".$this->b_id;
00254 $res=$this->db->exec_sql($sql);
00255
00256 if ( Database::num_row($res)==0)
00257 throw new Exception (_('Aucun enregistrement trouve'));
00258 $array=Database::fetch_array($res,0);
00259 foreach ($array as $name=>$value)
00260 $this->$name=$value;
00261
00262 }
00263 catch(Exception $Ex)
00264 {
00265 echo $Ex->getMessage();
00266 throw $Ex;
00267 }
00268 }
00269
00270
00271 function file_open_form()
00272 {
00273 $form=fopen($this->b_file_form,'r');
00274 if ( $form == false)
00275 {
00276 echo 'Cannot Open';
00277 throw new Exception(_('Echec ouverture fichier '.$this->b_file_form));
00278 }
00279 return $form;
00280 }
00281
00282
00283 function file_open_template()
00284 {
00285 $templ=fopen($this->b_file_template,'r');
00286 if ( $templ == false)
00287 {
00288 echo 'Cannot Open';
00289 throw new Exception(_('Echec ouverture fichier '.$this->b_file_template));
00290 }
00291 return $templ;
00292
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 function compute_formula($p_handle)
00304 {
00305 while (! feof ($p_handle))
00306 {
00307 $buffer=trim(fgets($p_handle));
00308
00309
00310
00311 if (strlen(trim($buffer))==0)
00312 continue;
00313
00314 if ( strpos($buffer,'#') === true )
00315 continue;
00316
00317
00318 $a=Impress::parse_formula($this->db,"$buffer",$buffer,$this->from,$this->to,false);
00319 $b=str_replace("$","\$this->",$a);
00320 if ( eval("$b;") === false )
00321 echo_debug(__FILE__,__LINE__,"Code failed with $b");
00322
00323
00324 }
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 function generate_odt()
00336 {
00337
00338 $dirname=tempnam($_ENV['TMP'],'bilan_');
00339
00340
00341 unlink($dirname);
00342 mkdir ($dirname);
00343 chdir($dirname);
00344
00345 $file_base=dirname($_SERVER['SCRIPT_FILENAME']).DIRECTORY_SEPARATOR.$this->b_file_template;
00346 $work_file=basename($file_base);
00347 if ( copy ($file_base,$work_file) == false )
00348 {
00349 echo _("erreur Ouverture fichier");
00350 throw new Exception(_('Echec ouverture fichier '.$file_base));
00351 }
00352 ob_start();
00353
00354 $zip = new Zip_Extended;
00355 if ($zip->open($work_file) === TRUE)
00356 {
00357 $zip->extractTo($dirname.DIRECTORY_SEPARATOR);
00358 $zip->close();
00359 } else
00360 {
00361 echo __FILE__.":".__LINE__."cannot unzip model ".$filename;
00362 }
00363
00364 ob_end_clean();
00365 unlink($work_file);
00366
00367 $p_file=fopen('content.xml','r');
00368
00369 if ( $p_file == false)
00370 {
00371 throw new Exception(_('Echec ouverture fichier '.$p_file));
00372 }
00373
00374 $r="";
00375 $regex="/<<\\$[A-Z]*[0-9]*>>/";
00376 $lt="<";
00377 $gt=">";
00378 $header_txt=header_txt($this->db);
00379
00380 while ( !feof($p_file) )
00381 {
00382 $line_rtf=fgets($p_file);
00383
00384
00385
00386
00387 $line_rtf=preg_replace('/<<header>>/',$header_txt,$line_rtf);
00388
00389
00390
00391 $tmp="";
00392
00393
00394 while (preg_match_all($regex,$line_rtf,$f2) > 0 )
00395 {
00396
00397 foreach ($f2 as $f2_array)
00398 {
00399 foreach ($f2_array as $f2_str)
00400 {
00401 $to_remove=$f2_str;
00402 $f2_value=str_replace("<","",$f2_str);
00403 $f2_value=str_replace(">","",$f2_value);
00404 $f2_value=str_replace("$","",$f2_value);
00405
00406
00407
00408
00409 if( ! isset($this->$f2_value))
00410 {
00411
00412 $a = "!!".$f2_value."!!";
00413 if( substr($f2_value, 0, 1) == "N" )
00414 {
00415 $ret = $this->db->get_array("SELECT pcm_lib AS acct_name FROM tmp_pcmn WHERE pcm_val::text LIKE ".
00416 " substr($1, 2)||'%' ORDER BY pcm_val ASC LIMIT 1",array($f2_value));
00417 if($ret[0]['acct_name'])
00418 {
00419 $a = $ret[0]['acct_name'];
00420 $a=str_replace('<','<',$a);
00421 $a=str_replace('>','>',$a);
00422 }
00423 }
00424 }
00425 else
00426 {
00427 $a=$this->$f2_value;
00428 }
00429 if ( $a=='-0' ) $a=0;
00430
00431
00432 if ( is_numeric($a) )
00433 {
00434 $searched='office:value-type="string"><text:p>'.$f2_str;
00435 $replaced='office:value-type="float" office:value="'.$a.'"><text:p>'.$f2_str;
00436 $line_rtf=str_replace($searched, $replaced, $line_rtf);
00437 }
00438
00439
00440 $line_rtf=str_replace($f2_str,$a,$line_rtf);
00441
00442 }
00443 }
00444 }
00445 $r.=$line_rtf;
00446
00447 }
00448
00449 return $r;
00450
00451 }
00452
00453
00454
00455
00456
00457 function generate_plain($p_file)
00458 {
00459 $r="";
00460 if ( $this->b_type=='html')
00461 {
00462 $lt='<';
00463 $gt='>';
00464 $pattern='/<<header>>/';
00465 }
00466 else
00467 {
00468 $lt='<';
00469 $gt='>';
00470 $pattern='/<<header>>/';
00471 }
00472
00473 $header_txt=header_txt($this->db);
00474
00475 while ( !feof($p_file) )
00476 {
00477 $line_rtf=fgets($p_file);
00478
00479 $line_rtf=preg_replace($pattern,$header_txt,$line_rtf);
00480
00481
00482
00483 if (preg_match_all("/".$lt.$lt."\\$[a-zA-Z]*[0-9]*".$gt.$gt."/",$line_rtf,$f2) > 0)
00484 {
00485
00486
00487
00488 foreach ($f2 as $f2_str)
00489 {
00490
00491
00492
00493 $f2_value=str_replace($lt,"",$f2_str);
00494 $f2_value=str_replace($gt,"",$f2_value);
00495 $f2_value=str_replace("$","",$f2_value);
00496 $f2_value=$f2_value[0];
00497
00498
00499 if( ! isset($this->$f2_value))
00500 {
00501 $a = "!!".$f2_value."!!";
00502 if( substr($f2_value, 0, 1) == "N" )
00503 {
00504 $ret = $this->db->get_array("SELECT pcm_lib AS acct_name FROM tmp_pcmn WHERE ".
00505 " pcm_val::text LIKE substr($1, 2)||'%' ORDER BY pcm_val ASC LIMIT 1",
00506 array($f2_value));
00507 if($ret[0]['acct_name'])
00508 {
00509
00510 $a = utf8_decode($ret[0]['acct_name']);
00511 }
00512 }
00513 }
00514 else
00515 {
00516
00517
00518
00519 $a=$this->$f2_value;
00520 }
00521
00522 if ( $a=='-0' ) $a=0;
00523 $line_rtf=str_replace($f2_str,$a,$line_rtf);
00524
00525 }
00526 }
00527 $r.=$line_rtf;
00528
00529 }
00530
00531
00532
00533 return $r;
00534
00535
00536
00537
00538 }
00539
00540
00541 function generate()
00542 {
00543
00544 $this->load();
00545
00546 $form=$this->file_open_form();
00547
00548
00549 $this->compute_formula($form);
00550 fclose($form);
00551
00552 $templ=$this->file_open_template();
00553 switch ($this->b_type)
00554 {
00555 case 'rtf':
00556 $result=$this->generate_plain($templ);
00557 $this->send($result);
00558 break;
00559 case 'txt':
00560 $result=$this->generate_plain($templ);
00561 $this->send($result);
00562 case 'html':
00563 $result=$this->generate_plain($templ);
00564 $this->send($result);
00565
00566 break;
00567 case 'odt':
00568 case 'ods':
00569 $result=$this->generate_odt($templ);
00570 $this->send($result);
00571 break;
00572
00573 }
00574 fclose($templ);
00575 }
00576
00577
00578
00579 function send($p_result)
00580 {
00581 switch ($this->b_type)
00582 {
00583 case 'rtf':
00584
00585 header('Content-type: application/rtf');
00586 header('Content-Disposition: attachment; filename="'.$this->b_name.'.rtf"');
00587 echo $p_result;
00588 break;
00589
00590 case 'txt':
00591
00592 header('Content-type: application/txt');
00593 header('Content-Disposition: attachment; filename="'.$this->b_name.'.txt"');
00594
00595 echo $p_result;
00596 break;
00597 case 'html':
00598
00599 header('Content-type: application/html');
00600 header('Content-Disposition: attachment; filename="'.$this->b_name.'.html"');
00601
00602 echo $p_result;
00603 break;
00604 case 'odt':
00605 case 'ods':
00606 header("Pragma: public");
00607 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
00608 header("Cache-Control: must-revalidate");
00609 if ( $this->b_type == 'odt' )
00610 {
00611 header('Content-type: application/vnd.oasis.opendocument.text');
00612 header('Content-Disposition: attachment;filename="'.$this->b_name.'.odt"',FALSE);
00613 }
00614 if ( $this->b_type == 'ods' )
00615 {
00616 header('Content-type: application/vnd.oasis.opendocument.spreadsheet');
00617 header('Content-Disposition: attachment;filename="'.$this->b_name.'.ods"',FALSE);
00618 }
00619
00620 header("Accept-Ranges: bytes");
00621 ob_start();
00622
00623
00624 $dirname=tempnam($_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.'tmp','bilan_');
00625
00626
00627 unlink($dirname);
00628 mkdir ($dirname);
00629 chdir($dirname);
00630
00631 $file_base=dirname($_SERVER['SCRIPT_FILENAME']).DIRECTORY_SEPARATOR.$this->b_file_template;
00632 $work_file=basename($file_base);
00633 if ( copy ($file_base,$work_file) == false )
00634 {
00635 throw new Exception ( _("Ouverture fichier impossible"));
00636 }
00637
00638
00639
00640 ob_start();
00641 $zip = new Zip_Extended;
00642 if ($zip->open($work_file) === TRUE)
00643 {
00644 $zip->extractTo($dirname.DIRECTORY_SEPARATOR);
00645 $zip->close();
00646 }
00647 else
00648 {
00649 echo __FILE__.":".__LINE__."cannot unzip model ".$filename;
00650 }
00651
00652
00653 unlink ($work_file);
00654
00655
00656
00657 $p_file=fopen($dirname.DIRECTORY_SEPARATOR.'content.xml','wb');
00658 if ( $p_file == false )
00659 {
00660 throw new Exception ( _("erreur Ouverture fichier").' content.xml');
00661
00662 }
00663 $a=fwrite($p_file,$p_result);
00664 if ( $a==false)
00665 {
00666 throw new Exception ( _("erreur écriture fichier").' content.xml');
00667 }
00668
00669 $zip = new Zip_Extended;
00670 $res = $zip->open($this->b_name.".".$this->b_type, ZipArchive::CREATE);
00671 if($res !== TRUE)
00672 {
00673 throw new Exception (__FILE__.":".__LINE__."cannot recreate zip");
00674 }
00675 $zip->add_recurse_folder($dirname.DIRECTORY_SEPARATOR);
00676 $zip->close();
00677
00678 ob_end_clean();
00679 fclose($p_file);
00680 $fdoc=fopen($dirname.DIRECTORY_SEPARATOR.$this->b_name.'.'.$this->b_type,'r');
00681 if ( $fdoc == false )
00682 {
00683 throw new Exception (_("erreur Ouverture fichier"));
00684 }
00685 $buffer=fread ($fdoc,filesize($dirname.DIRECTORY_SEPARATOR.$this->b_name.'.'.$this->b_type));
00686 echo $buffer;
00687
00688 break;
00689
00690 }
00691
00692 }
00693 static function test_me()
00694 {
00695
00696 if ( isset($_GET['result']))
00697 {
00698 ob_start();
00699 $cn=new Database(dossier::id());
00700 $a=new Acc_Bilan($cn);
00701 $a->get_request_get();
00702
00703 $a->load();
00704 $form=$a->file_open_form();
00705 $a->compute_formula($form);
00706 fclose($form);
00707
00708 $templ=$a->file_open_template();
00709 $r=$a->generate_odt($templ);
00710 fclose($templ);
00711 ob_end_clean();
00712
00713 $a->send($r);
00714 }
00715 else
00716 {
00717 $cn=new Database(dossier::id());
00718 $a=new Acc_Bilan($cn);
00719 $a->get_request_get();
00720
00721 echo '<form method="get">';
00722 echo $a->display_form();
00723 echo HtmlInput::hidden('test_select',$_GET['test_select']).dossier::hidden();
00724 echo HtmlInput::submit('result','Sauve');
00725 echo '</form>';
00726 }
00727 }
00728 }
00729