noalyss  Version-6.7.2
 All Data Structures Namespaces Files Functions Variables Enumerations
class_acc_ledger.php
Go to the documentation of this file.
00001 <?php
00002 /*
00003  *   This file is part of NOALYSS.
00004  *
00005  *   NOALYSS is free software; you can redistribute it and/or modify
00006  *   it under the terms of the GNU General Public License as published by
00007  *   the Free Software Foundation; either version 2 of the License, or
00008  *   (at your option) any later version.
00009  *
00010  *   NOALYSS is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details.
00014  *
00015  *   You should have received a copy of the GNU General Public License
00016  *   along with NOALYSS; if not, write to the Free Software
00017  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 // Copyright Author Dany De Bontridder danydb@aevalys.eu
00020 require_once("class_iselect.php");
00021 require_once("class_icard.php");
00022 require_once("class_ispan.php");
00023 require_once("class_ihidden.php");
00024 require_once("class_idate.php");
00025 require_once("class_itext.php");
00026 require_once("class_icheckbox.php");
00027 require_once('class_iperiod.php');
00028 require_once('class_fiche.php');
00029 require_once('class_user.php');
00030 require_once ('class_dossier.php');
00031 require_once ('class_anc_operation.php');
00032 require_once ('class_acc_operation.php');
00033 require_once ('class_acc_account_ledger.php');
00034 require_once ('class_pre_op_advanced.php');
00035 require_once ('class_acc_reconciliation.php');
00036 require_once ('class_periode.php');
00037 require_once ('class_gestion_purchase.php');
00038 require_once ('class_acc_account.php');
00039 require_once('ac_common.php');
00040 require_once('class_inum.php');
00041 require_once('class_lettering.php');
00042 require_once 'class_sort_table.php';
00043 require_once 'class_jrn_def_sql.php';
00044 require_once 'class_acc_payment.php';
00045 /** \file
00046  * @brief Class for jrn,  class acc_ledger for manipulating the ledger
00047  */
00048 
00049 /** @brief Class for jrn,  class acc_ledger for manipulating the ledger
00050  *
00051  */
00052 
00053 class Acc_Ledger extends jrn_def_sql
00054 {
00055 
00056         var $id;   /**< jrn_def.jrn_def_id */
00057         var $name;   /**< jrn_def.jrn_def_name */
00058         var $db;   /**< database connextion */
00059         var $row;   /**< row of the ledger */
00060         var $type;   /**< type of the ledger ACH ODS FIN
00061           VEN or GL */
00062         var $nb;   /**< default number of rows by
00063           default 10 */
00064 
00065         /**
00066          * @param $p_cn database connexion
00067          * @param $p_id jrn.jrn_def_id
00068          */
00069         function __construct($p_cn, $p_id)
00070         {
00071                 $this->id = $p_id;
00072                 $this->name = &$this->jrn_def_name;
00073                 $this->jrn_def_id = &$this->id;
00074                 $this->db = $p_cn;
00075                 $this->row = null;
00076                 $this->nb = MAX_ARTICLE;
00077         }
00078 
00079         function get_last_pj()
00080         {
00081                 if ($this->db->exist_sequence("s_jrn_pj" . $this->id))
00082                 {
00083                         $ret = $this->db->get_array("select last_value,is_called from s_jrn_pj" . $this->id);
00084                         $last = $ret[0]['last_value'];
00085                         /**
00086                          * \note  With PSQL sequence , the last_value column is 1 when before   AND after the first call, to make the difference between them
00087                          * I have to check whether the sequence has been already called or not */
00088                         if ($ret[0]['is_called'] == 'f')
00089                                 $last--;
00090                         return $last;
00091                 }
00092                 else
00093                         $this->db->create_sequence("s_jrn_pj" . $this->id);
00094                 return 0;
00095         }
00096 
00097         /**
00098          * @brief Return the type of a ledger (ACH,VEN,ODS or FIN) or GL
00099          *
00100          */
00101 
00102         function get_type()
00103         {
00104                 if ($this->id == 0)
00105                 {
00106                         $this->name = _(" Tous les journaux");
00107                         $this->type = "GL";
00108                         return "GL";
00109                 }
00110 
00111                 $Res = $this->db->exec_sql("select jrn_def_type from " .
00112                                 " jrn_def where jrn_def_id=" .
00113                                 $this->id);
00114                 $Max = Database::num_row($Res);
00115                 if ($Max == 0)
00116                         return null;
00117                 $ret = Database::fetch_array($Res, 0);
00118                 $this->type = $ret['jrn_def_type'];
00119                 return $ret['jrn_def_type'];
00120         }
00121 
00122         /**
00123          * let you delete a operation
00124          * @note by cascade it will delete also in
00125          * - jrnx
00126          * - stock
00127          * - quant_purchase
00128          * - quant_fin
00129          * - quant_sold
00130          * - operation_analytique
00131          * - letter
00132          * - reconciliation
00133          * @bug the attached document is not deleted
00134          */
00135         function delete()
00136         {
00137                 if ($this->id == 0)
00138                         return;
00139                 $grpt_id = $this->db->get_value('select jr_grpt_id from jrn where jr_id=$1', array($this->jr_id));
00140                 if ($this->db->count() == 0)
00141                         return;
00142                 $this->db->exec_sql('delete from jrnx where j_grpt=$1', array($grpt_id));
00143                 $this->db->exec_sql('delete from jrn where jr_id=$1', array($this->jr_id));
00144         }
00145 
00146         /**
00147          * Display warning contained in an array
00148          * @return string with error message
00149          */
00150         function display_warning($pa_msg, $p_warning)
00151         {
00152                 $str = '<p class="notice"> ' . $p_warning;
00153                 $str.="<ol class=\"notice\">";
00154                 for ($i = 0; $i < count($pa_msg); $i++)
00155                 {
00156                         $str.="<li>" . $pa_msg[$i] . "</li>";
00157                 }
00158                 $str.='</ol>';
00159                 $str.='</p>';
00160                 return $str;
00161         }
00162 
00163         /**
00164          * reverse the operation by creating the opposite one,
00165          * the result is to avoid it
00166          * it must be done in
00167          * - jrn
00168          * - jrnx
00169          * - quant_fin
00170          * - quant_sold
00171          * - quant_purchase
00172          * - stock
00173          * - ANC
00174          * @param $p_date is the date of the reversed op
00175          * @exception if date is invalid or other prob
00176          * @note automatically create a reconciliation between operation
00177          * You must set the ledger_id $this->jrn_def_id
00178          */
00179         function reverse($p_date)
00180         {
00181                 global $g_user;
00182                 try
00183                 {
00184                         $this->db->start();
00185                         if (!isset($this->jr_id) || $this->jr_id == '')
00186                                 throw new Exception(_("this->jr_id is not set ou opération inconnue"));
00187 
00188                         /* check if the date is valid */
00189                         if (isDate($p_date) == null)
00190                                 throw new Exception(_('Date invalide') . $p_date);
00191 
00192                         // if the operation is in a closed or centralized period
00193                         // the operation is voided thanks the opposite operation
00194                         $grp_new = $this->db->get_next_seq('s_grpt');
00195                         $seq = $this->db->get_next_seq("s_jrn");
00196                         $p_internal = $this->compute_internal_code($seq);
00197                         $this->jr_grpt_id = $this->db->get_value('select jr_grpt_id from jrn where jr_id=$1', array($this->jr_id));
00198                         if ($this->db->count() == 0)
00199                                 throw new Exception(_("Cette opération n'existe pas"));
00200                         $this->jr_internal = $this->db->get_value('select jr_internal from jrn where jr_id=$1', array($this->jr_id));
00201                         if ($this->db->count() == 0 || trim($this->jr_internal) == '')
00202                                 throw new Exception(_("Cette opération n'existe pas"));
00203 
00204                         /* find the periode thanks the date */
00205                         $per = new Periode($this->db);
00206                         $per->jrn_def_id = $this->id;
00207                         $per->find_periode($p_date);
00208 
00209                         if ($per->is_open() == 0)
00210                                 throw new Exception(_('PERIODE FERMEE'));
00211 
00212 
00213 
00214 
00215 
00216                         // Mark the operation invalid into the ledger
00217                         // to avoid to nullify twice the same op.
00218                         $sql = "update jrn set jr_comment='Annule : '||jr_comment where jr_id=$1";
00219                         $Res = $this->db->exec_sql($sql, array($this->jr_id));
00220 
00221                         // Check return code
00222                         if ($Res == false)
00223                                 throw (new Exception(__FILE__ . __LINE__ . "sql a echoue [ $sql ]"));
00224 
00225                         //////////////////////////////////////////////////
00226                         // Reverse in jrnx* tables
00227                         //////////////////////////////////////////////////
00228                         $a_jid = $this->db->get_array("select j_id,j_debit from jrnx where j_grpt=$1", array($this->jr_grpt_id));
00229                         for ($l = 0; $l < count($a_jid); $l++)
00230                         {
00231                                 $row = $a_jid[$l]['j_id'];
00232                                 // Make also the change into jrnx
00233                                 $sql = "insert into jrnx (
00234                   j_date,j_montant,j_poste,j_grpt,
00235                   j_jrn_def,j_debit,j_text,j_internal,j_tech_user,j_tech_per,j_qcode
00236                   ) select to_date($1,'DD.MM.YYYY'),j_montant,j_poste,$2,
00237                   j_jrn_def,not (j_debit),j_text,$3,$4,$5,
00238                   j_qcode
00239                   from
00240                   jrnx
00241                   where   j_id=$6 returning j_id";
00242                                 $Res = $this->db->exec_sql($sql, array($p_date, $grp_new, $p_internal, $g_user->id, $per->p_id, $row));
00243                                 // Check return code
00244                                 if ($Res == false)
00245                                         throw (new Exception(__FILE__ . __LINE__ . "SQL ERROR [ $sql ]"));
00246                                 $aj_id = $this->db->fetch(0);
00247                                 $j_id = $aj_id['j_id'];
00248 
00249                                 /* automatic lettering */
00250                                 $let = new Lettering($this->db);
00251                                 $let->insert_couple($j_id, $row);
00252 
00253                                 // reverse in QUANT_SOLD
00254                                 $Res = $this->db->exec_sql("INSERT INTO quant_sold(
00255                                      qs_internal, qs_fiche, qs_quantite, qs_price, qs_vat,
00256                                      qs_vat_code, qs_client, qs_valid, j_id)
00257                                      SELECT $1, qs_fiche, qs_quantite*(-1), qs_price*(-1), qs_vat*(-1),
00258                                      qs_vat_code, qs_client, qs_valid, $2
00259                                      FROM quant_sold where j_id=$3", array($p_internal, $j_id, $row));
00260 
00261                                 if ($Res == false)
00262                                         throw (new Exception(__FILE__ . __LINE__ . "sql a echoue [ $sql ]"));
00263                                 $Res = $this->db->exec_sql("INSERT INTO quant_purchase(
00264                                      qp_internal, j_id, qp_fiche, qp_quantite, qp_price, qp_vat,
00265                                      qp_vat_code, qp_nd_amount, qp_nd_tva, qp_nd_tva_recup, qp_supplier,
00266                                      qp_valid, qp_dep_priv)
00267                                      SELECT  $1, $2, qp_fiche, qp_quantite*(-1), qp_price*(-1), qp_vat*(-1),
00268                                      qp_vat_code, qp_nd_amount*(-1), qp_nd_tva*(-1), qp_nd_tva_recup*(-1), qp_supplier,
00269                                      qp_valid, qp_dep_priv*(-1)
00270                                      FROM quant_purchase where j_id=$3", array($p_internal, $j_id, $row));
00271 
00272                                 if ($Res == false)
00273                                         throw (new Exception(__FILE__ . __LINE__ . "SQL ERROR [ $sql ]"));
00274                         }
00275                         $sql = "insert into jrn (
00276               jr_id,
00277               jr_def_id,
00278               jr_montant,
00279               jr_comment,
00280               jr_date,
00281               jr_grpt_id,
00282               jr_internal
00283               ,jr_tech_per, jr_valid
00284               )
00285               select $1,jr_def_id,jr_montant,'Annulation '||jr_comment,
00286               to_date($2,'DD.MM.YYYY'),$3,$4,
00287               $5, true
00288               from
00289               jrn
00290               where   jr_id=$6";
00291                                 $Res = $this->db->exec_sql($sql, array($seq, $p_date, $grp_new, $p_internal, $per->p_id, $this->jr_id));
00292                                 // Check return code
00293                                 if ($Res == false)
00294                                         throw (new Exception(__FILE__ . __LINE__ . "SQL ERROR [ $sql ]"));
00295                         // reverse in QUANT_FIN table
00296                         $Res = $this->db->exec_sql("  INSERT INTO quant_fin(
00297                                  qf_bank,  qf_other, qf_amount,jr_id)
00298                                  SELECT  qf_bank,  qf_other, qf_amount*(-1),$1
00299                                  FROM quant_fin where jr_id=$2", array($seq, $this->jr_id));
00300                         if ($Res == false)
00301                                 throw (new Exception(__FILE__ . __LINE__ . "SQL ERROR[ $sql ]"));
00302 
00303                         // Add a "concerned operation to bound these op.together
00304                         //
00305         $rec = new Acc_Reconciliation($this->db);
00306                         $rec->set_jr_id($seq);
00307                         $rec->insert($this->jr_id);
00308 
00309                         // Check return code
00310                         if ($Res == false)
00311                         {
00312                                 throw (new Exception(__FILE__ . __LINE__ . "SQL ERROR [ $sql ]"));
00313                         }
00314 
00315 
00316 
00317                         // the table stock must updated
00318                         // also in the stock table
00319                         $sql = "delete from stock_goods where sg_id = any ( select sg_id
00320              from stock_goods natural join jrnx  where j_grpt=" . $this->jr_grpt_id . ")";
00321                         $Res = $this->db->exec_sql($sql);
00322                         if ($Res == false)
00323                                 throw (new Exception(__FILE__ . __LINE__ . "SQL ERROR [ $sql ]"));
00324                 }
00325                 catch (Exception $e)
00326                 {
00327                         $this->db->rollback();
00328                         throw $e;
00329                 }
00330         }
00331 
00332         /**
00333          * @brief Return the name of a ledger
00334          *
00335          */
00336 
00337         function get_name()
00338         {
00339                 if ($this->id == 0)
00340                 {
00341                         $this->name = _("Grand Livre");
00342                         return $this->name;
00343                 }
00344 
00345                 $Res = $this->db->exec_sql("select jrn_def_name from " .
00346                                 " jrn_def where jrn_def_id=$1", array($this->id));
00347                 $Max = Database::num_row($Res);
00348                 if ($Max == 0)
00349                         return null;
00350                 $ret = Database::fetch_array($Res, 0);
00351                 $this->name = $ret['jrn_def_name'];
00352                 return $ret['jrn_def_name'];
00353         }
00354 
00355         /** \function  get_row
00356          * @brief  Get The data
00357          *
00358          *
00359          * @paramp_from from periode
00360          * @paramp_to to periode
00361          * @paramp_limit starting line
00362          * @paramp_offset number of lines
00363          * \return Array with the asked data
00364          *
00365          */
00366 
00367         function get_row($p_from, $p_to, $p_limit = -1, $p_offset = -1)
00368         {
00369                 global $g_user;
00370                 $periode = sql_filter_per($this->db, $p_from, $p_to, 'p_id', 'jr_tech_per');
00371 
00372                 $cond_limite = ($p_limit != -1) ? " limit " . $p_limit . " offset " . $p_offset : "";
00373                 // retrieve the type
00374                 $this->get_type();
00375                 // Grand livre == 0
00376                 if ($this->id != 0)
00377                 {
00378                         $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,
00379                                      jr_internal,
00380                                      case j_debit when 't' then j_montant::text else '   ' end as deb_montant,
00381                                      case j_debit when 'f' then j_montant::text else '   ' end as cred_montant,
00382                                      j_debit as debit,j_poste as poste,jr_montant , " .
00383                                         "case when j_text='' or j_text is null then pcm_lib else j_text end as description,j_grpt as grp,
00384                                      jr_comment||' ('||jr_internal||')'  as jr_comment,
00385                                      jr_pj_number,
00386                                      j_qcode,
00387                                      jr_rapt as oc, j_tech_per as periode
00388                                      from jrnx left join jrn on " .
00389                                         "jr_grpt_id=j_grpt " .
00390                                         " left join tmp_pcmn on pcm_val=j_poste " .
00391                                         " where j_jrn_def=" . $this->id .
00392                                         " and " . $periode . " order by j_date::date asc,substring(jr_pj_number,'[0-9]+$')::numeric asc,j_grpt,j_debit desc " .
00393                                         $cond_limite);
00394                 }
00395                 else
00396                 {
00397                         $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,
00398                                      jr_internal,
00399                                      case j_debit when 't' then j_montant::text else '   ' end as deb_montant,
00400                                      case j_debit when 'f' then j_montant::text else '   ' end as cred_montant,
00401                                      j_debit as debit,j_poste as poste," .
00402                                         "case when j_text='' or j_text is null then pcm_lib else j_text end as description,j_grpt as grp,
00403                                      jr_comment||' ('||jr_internal||')' as jr_comment,
00404                                      jr_pj_number,
00405                                      jr_montant,
00406                                      j_qcode,
00407                                      jr_rapt as oc, j_tech_per as periode from jrnx left join jrn on " .
00408                                         "jr_grpt_id=j_grpt left join tmp_pcmn on pcm_val=j_poste
00409                                                                                  join jrn_def on (jr_def_id=jrn_def_id)
00410                                                                                  where " .
00411                                         $g_user->get_ledger_sql() . " and " .
00412                                         "  " . $periode . " order by j_date::date,substring(jr_pj_number,'[0-9]+$') asc,j_grpt,j_debit desc   " .
00413                                         $cond_limite);
00414                 }
00415 
00416 
00417                 $array = array();
00418                 $Max = Database::num_row($Res);
00419                 if ($Max == 0)
00420                         return null;
00421                 $case = "";
00422                 $tot_deb = 0;
00423                 $tot_cred = 0;
00424                 $row = Database::fetch_all($Res);
00425                 for ($i = 0; $i < $Max; $i++)
00426                 {
00427                         $fiche = new Fiche($this->db);
00428                         $line = $row[$i];
00429                         $mont_deb = ($line['deb_montant'] != 0) ? sprintf("% 8.2f", $line['deb_montant']) : "";
00430                         $mont_cred = ($line['cred_montant'] != 0) ? sprintf("% 8.2f", $line['cred_montant']) : "";
00431                         $jr_montant = ($line['jr_montant'] != 0) ? sprintf("% 8.2f", $line['jr_montant']) : "";
00432                         $tot_deb+=$line['deb_montant'];
00433                         $tot_cred+=$line['cred_montant'];
00434                         $tot_op = $line['jr_montant'];
00435 
00436                         /* Check first if there is a quickcode */
00437                         if (strlen(trim($line['description'])) == 0 && strlen(trim($line['j_qcode'])) != 0)
00438                         {
00439                                 if ($fiche->get_by_qcode($line['j_qcode'], false) == 0)
00440                                 {
00441                                         $line['description'] = $fiche->strAttribut(ATTR_DEF_NAME);
00442                                 }
00443                         }
00444                         if ($case != $line['grp'])
00445                         {
00446                                 $case = $line['grp'];
00447                                 // for financial, we show if the amount is or not in negative
00448                                 if ($this->type == 'FIN')
00449                                 {
00450                                         $amount = $this->db->get_value('select qf_amount from quant_fin where jr_id=$1', array($line['jr_id']));
00451                                         /*  if nothing is found */
00452                                         if ($this->db->count() == 0)
00453                                                 $tot_op = $jr_montant;
00454                                         else if ($amount < 0)
00455                                         {
00456                                                 $tot_op = $amount;
00457                                         }
00458                                 }
00459                                 $array[] = array(
00460                                         'jr_id' => $line['jr_id'],
00461                                         'int_j_id' => $line['int_j_id'],
00462                                         'j_id' => $line['j_id'],
00463                                         'j_date' => $line['j_date'],
00464                                         'internal' => $line['jr_internal'],
00465                                         'deb_montant' => '',
00466                                         'cred_montant' => ' ',
00467                                         'description' => '<b><i>' . h($line['jr_comment']) . ' [' . $tot_op . '] </i></b>',
00468                                         'poste' => $line['oc'],
00469                                         'qcode' => $line['j_qcode'],
00470                                         'periode' => $line['periode'],
00471                                         'jr_pj_number' => $line ['jr_pj_number']);
00472 
00473                                 $array[] = array(
00474                                         'jr_id' => '',
00475                                         'int_j_id' => $line['int_j_id'],
00476                                         'j_id' => '',
00477                                         'j_date' => '',
00478                                         'internal' => '',
00479                                         'deb_montant' => $mont_deb,
00480                                         'cred_montant' => $mont_cred,
00481                                         'description' => $line['description'],
00482                                         'poste' => $line['poste'],
00483                                         'qcode' => $line['j_qcode'],
00484                                         'periode' => $line['periode'],
00485                                         'jr_pj_number' => ''
00486                                 );
00487                         }
00488                         else
00489                         {
00490                                 $array[] = array(
00491                                         'jr_id' => $line['jr_id'],
00492                                         'int_j_id' => $line['int_j_id'],
00493                                         'j_id' => '',
00494                                         'j_date' => '',
00495                                         'internal' => '',
00496                                         'deb_montant' => $mont_deb,
00497                                         'cred_montant' => $mont_cred,
00498                                         'description' => $line['description'],
00499                                         'poste' => $line['poste'],
00500                                         'qcode' => $line['j_qcode'],
00501                                         'periode' => $line['periode'],
00502                                         'jr_pj_number' => '');
00503                         }
00504                 }
00505                 $this->row = $array;
00506                 $a = array($array, $tot_deb, $tot_cred);
00507                 return $a;
00508         }
00509 
00510         /** @brief  Get simplified row from ledger
00511          *
00512          * @param p_from periode
00513          * @param p_to periode
00514          * @param p_limit starting line
00515          * @param p_offset number of lines
00516          * @param trunc if data must be truncated (pdf export)
00517          *
00518          * \return an Array with the asked data
00519          */
00520 
00521         function get_rowSimple($p_from, $p_to, $trunc = 0, $p_limit = -1, $p_offset = -1)
00522         {
00523                 global $g_user;
00524                 // Grand-livre : id= 0
00525                 //---
00526                 $jrn = ($this->id == 0 ) ? "and " . $g_user->get_ledger_sql() : "and jrn_def_id = " . $this->id;
00527 
00528                 $periode = sql_filter_per($this->db, $p_from, $p_to, 'p_id', 'jr_tech_per');
00529 
00530                 $cond_limite = ($p_limit != -1) ? " limit " . $p_limit . " offset " . $p_offset : "";
00531                 //---
00532                 $sql = "
00533              SELECT jrn.jr_id as jr_id ,
00534              jrn.jr_id as num ,
00535              jrn.jr_def_id as jr_def_id,
00536              jrn.jr_montant as montant,
00537              substr(jrn.jr_comment,1,35) as comment,
00538              to_char(jrn.jr_date,'DD-MM-YYYY') as date,
00539              to_char(jrn.jr_date_paid,'DD-MM-YYYY') as date_paid,
00540              jr_pj_number,
00541              jr_internal,
00542              jrn.jr_grpt_id as grpt_id,
00543              jrn.jr_pj_name as pj,
00544              jrn_def_type,
00545              jrn.jr_tech_per
00546              FROM jrn join jrn_def on (jrn_def_id=jr_def_id)
00547              WHERE $periode $jrn order by jr_date,substring(jrn.jr_pj_number,'[0-9]+$')::numeric asc  $cond_limite";
00548 
00549                 $Res = $this->db->exec_sql($sql);
00550                 $Max = Database::num_row($Res);
00551                 if ($Max == 0)
00552                 {
00553                         return null;
00554                 }
00555                 $type = $this->get_type();
00556                 // for type ACH and Ven we take more info
00557                 if ($type == 'ACH' || $type == 'VEN')
00558                 {
00559                         $a_ParmCode = $this->db->get_array('select p_code,p_value from parm_code');
00560                         $a_TVA = $this->db->get_array('select tva_id,tva_label,tva_poste
00561                                         from tva_rate where tva_rate != 0 order by tva_rate,tva_label,tva_id ');
00562                         for ($i = 0; $i < $Max; $i++)
00563                         {
00564                                 $array[$i] = Database::fetch_array($Res, $i);
00565                                 $p = $this->get_detail($array[$i], $type, $trunc, $a_TVA, $a_ParmCode);
00566                                 if ($array[$i]['dep_priv'] != 0.0)
00567                                 {
00568                                         $array[$i]['comment'].="(priv. " . $array[$i]['dep_priv'] . ")";
00569                                 }
00570                         }
00571                 }
00572                 else
00573                 {
00574                         $array = Database::fetch_all($Res);
00575                 }
00576 
00577                 return $array;
00578         }
00579 
00580 // end function get_rowSimple
00581 
00582         /**
00583          * @brief guess what  the next pj should be
00584          */
00585 
00586         function guess_pj()
00587         {
00588                 $prop = $this->get_propertie();
00589                 $pj_pref = $prop["jrn_def_pj_pref"];
00590                 $pj_seq = $this->get_last_pj() + 1;
00591                 return $pj_pref . $pj_seq;
00592         }
00593 
00594         /**
00595          * @brief Show all the operation
00596          * @param$sql is the sql stmt, normally created by build_search_sql
00597          * @param$offset the offset
00598          * @param$p_paid if we want to see info about payment
00599           \code
00600           // Example
00601           // Build the sql
00602           list($sql,$where)=$Ledger->build_search_sql($_GET);
00603           // Count nb of line
00604           $max_line=$this->db->count_sql($sql);
00605 
00606           $step=$_SESSION['g_pagesize'];
00607           $page=(isset($_GET['offset']))?$_GET['page']:1;
00608           $offset=(isset($_GET['offset']))?$_GET['offset']:0;
00609           // create the nav. bar
00610           $bar=navigation_bar($offset,$max_line,$step,$page);
00611           // show a part
00612           list($count,$html)= $Ledger->list_operation($sql,$offset,0);
00613           echo $html;
00614           // show nav bar
00615           echo $bar;
00616 
00617           \endcode
00618          * \see build_search_sql
00619          * \see display_search_form
00620          * \see search_form
00621 
00622          * \return HTML string
00623          */
00624 
00625         public function list_operation_to_reconcile($sql)
00626         {
00627                 global $g_parameter, $g_user;
00628                 $gDossier = dossier::id();
00629                 $limit = " LIMIT ".MAX_RECONCILE;
00630                 // Sort
00631                 // Count
00632                 $count = $this->db->count_sql($sql);
00633                 // Add the limit
00634                 $sql.=" order by jr_date asc " . $limit;
00635 
00636                 // Execute SQL stmt
00637                 $Res = $this->db->exec_sql($sql);
00638 
00639                 //starting from here we can refactor, so that instead of returning the generated HTML,
00640                 //this function returns a tree structure.
00641 
00642                 $r = "";
00643 
00644 
00645                 $Max = Database::num_row($Res);
00646 
00647                 if ($Max == 0)
00648                         return array(0, _("Aucun enregistrement trouvé"));
00649 
00650                 $r.='<table class="result">';
00651 
00652 
00653                 $r.="<tr >";
00654                 $r.="<th>"._("Selection")."</th>";
00655                 $r.="<th>"._("Internal")."</th>";
00656 
00657                 if ($this->type == 'ALL')
00658                 {
00659                         $r.=th(_('Journal'));
00660                 }
00661 
00662                 $r.='<th>'._("Date").'</th>';
00663                 $r.='<th>'._("Pièce").'</td>';
00664                 $r.=th(_('tiers'));
00665                 $r.='<th>'._("Description").'</th>';
00666                 $r.=th(_('Notes'), ' ');
00667                 $r.='<th>'._("Montant").'</th>';
00668                 $r.="<th>" . _('Concerne') . "</th>";
00669                 $r.="</tr>";
00670                 // Total Amount
00671                 $tot = 0.0;
00672                 $gDossier = dossier::id();
00673                 $str_dossier = Dossier::id();
00674                 for ($i = 0; $i < $Max; $i++)
00675                 {
00676 
00677 
00678                         $row = Database::fetch_array($Res, $i);
00679 
00680                         if ($i % 2 == 0)
00681                                 $tr = '<TR class="odd">';
00682                         else
00683                                 $tr = '<TR class="even">';
00684                         $r.=$tr;
00685                         // Radiobox
00686                         //
00687 
00688                         $r.='<td><INPUT TYPE="CHECKBOX" name="jr_concerned' . $row['jr_id'] . '" ID="jr_concerned' . $row['jr_id'] . '"> </td>';
00689                         //internal code
00690                         // button  modify
00691                         $r.="<TD>";
00692                         // If url contains
00693                         //
00694 
00695             $href = basename($_SERVER['PHP_SELF']);
00696 
00697 
00698                         $r.=sprintf('<A class="detail" style="text-decoration:underline" HREF="javascript:modifyOperation(\'%s\',\'%s\')" >%s </A>', $row['jr_id'], $gDossier, $row['jr_internal']);
00699                         $r.="</TD>";
00700                         if ($this->type == 'ALL')
00701                                 $r.=td($row['jrn_def_name']);
00702                         // date
00703                         $r.="<TD>";
00704                         $r.=$row['str_jr_date'];
00705                         $r.="</TD>";
00706 
00707                         // pj
00708                         $r.="<TD>";
00709                         $r.=$row['jr_pj_number'];
00710                         $r.="</TD>";
00711 
00712                         // Tiers
00713                         $other = ($row['quick_code'] != '') ? '[' . $row['quick_code'] . '] ' . $row['name'] . ' ' . $row['first_name'] : '';
00714                         $r.=td($other);
00715                         // comment
00716                         $r.="<TD>";
00717                         $tmp_jr_comment = h($row['jr_comment']);
00718                         $r.=$tmp_jr_comment;
00719                         $r.="</TD>";
00720                         $r.=td(h($row['n_text']), ' style="font-size:0.87em"');
00721                         // Amount
00722                         // If the ledger is financial :
00723                         // the credit must be negative and written in red
00724                         $positive = 0;
00725 
00726                         // Check ledger type :
00727                         if ($row['jrn_def_type'] == 'FIN')
00728                         {
00729                                 $positive = $this->db->get_value("select qf_amount from quant_fin where jr_id=$1", array($row['jr_id']));
00730                                 if ($this->db->count() != 0)
00731                                         $positive = ($positive < 0) ? 1 : 0;
00732                         }
00733                         $r.="<TD align=\"right\">";
00734 
00735                         $r.=( $positive != 0 ) ? "<font color=\"red\">  - " . nbm($row['jr_montant']) . "</font>" : nbm($row['jr_montant']);
00736                         $r.="</TD>";
00737 
00738 
00739 
00740                         // Rapprochement
00741                         $rec = new Acc_Reconciliation($this->db);
00742                         $rec->set_jr_id($row['jr_id']);
00743                         $a = $rec->get();
00744                         $r.="<TD>";
00745                         if ($a != null)
00746                         {
00747 
00748                                 foreach ($a as $key => $element)
00749                                 {
00750                                         $operation = new Acc_Operation($this->db);
00751                                         $operation->jr_id = $element;
00752                                         $l_amount = $this->db->get_value("select jr_montant from jrn " .
00753                                                         " where jr_id=$element");
00754                                         $r.= "<A class=\"detail\" HREF=\"javascript:modifyOperation('" . $element . "'," . $gDossier . ")\" > " . $operation->get_internal() . "[" . nbm($l_amount) . "]</A>";
00755                                 }//for
00756                         }// if ( $a != null ) {
00757                         $r.="</TD>";
00758 
00759                         if ($row['jr_valid'] == 'f')
00760                         {
00761                                 $r.="<TD>"._("Opération annulée")."</TD>";
00762                         }
00763                         // end row
00764                         $r.="</tr>";
00765                 }
00766                 $r.='</table>';
00767                 return array($count, $r);
00768         }
00769 
00770         /**
00771          * @brief Show all the operation
00772          * @param$sql is the sql stmt, normally created by build_search_sql
00773          * @param$offset the offset
00774          * @param$p_paid if we want to see info about payment
00775           \code
00776           // Example
00777           // Build the sql
00778           list($sql,$where)=$Ledger->build_search_sql($_GET);
00779           // Count nb of line
00780           $max_line=$cn->count_sql($sql);
00781 
00782           $step=$_SESSION['g_pagesize'];
00783           $page=(isset($_GET['offset']))?$_GET['page']:1;
00784           $offset=(isset($_GET['offset']))?$_GET['offset']:0;
00785           // create the nav. bar
00786           $bar=navigation_bar($offset,$max_line,$step,$page);
00787           // show a part
00788           list($count,$html)= $Ledger->list_operation($sql,$offset,0);
00789           echo $html;
00790           // show nav bar
00791           echo $bar;
00792 
00793           \endcode
00794          * \see build_search_sql
00795          * \see display_search_form
00796          * \see search_form
00797 
00798          * \return HTML string
00799          */
00800 
00801         public function list_operation($sql, $offset, $p_paid = 0)
00802         {
00803                 global $g_parameter, $g_user;
00804                 bcscale(2);
00805                 $table = new Sort_Table();
00806                 $gDossier = dossier::id();
00807                 $amount_paid = 0.0;
00808                 $amount_unpaid = 0.0;
00809                 $limit = ($_SESSION['g_pagesize'] != -1) ? " LIMIT " . $_SESSION['g_pagesize'] : "";
00810                 $offset = ($_SESSION['g_pagesize'] != -1) ? " OFFSET " . Database::escape_string($offset) : "";
00811                 $order = "  order by jr_date_order asc,jr_internal asc";
00812                 // Sort
00813                 $url = "?" . CleanUrl();
00814                 $str_dossier = dossier::get();
00815                 $table->add(_("Date"), $url, 'order by jr_date asc,substring(jr_pj_number,\'[0-9]+$\')::numeric asc', 'order by  jr_date desc,substring(jr_pj_number,\'[0-9]+$\')::numeric desc', "da", "dd");
00816                 $table->add(_('Echeance'), $url, " order by  jr_ech asc", " order by  jr_ech desc", 'ea', 'ed');
00817                 $table->add(_('Paiement'), $url, " order by  jr_date_paid asc", " order by  jr_date_paid desc", 'eap', 'edp');
00818                 $table->add(_('Pièce'), $url, ' order by  substring(jr_pj_number,\'[0-9]+$\')::numeric asc ', ' order by  substring(jr_pj_number,\'[0-9]+$\')::numeric desc ', "pja", "pjd");
00819                 $table->add(_('Tiers'), $url, " order by  name asc", " order by  name desc", 'na', 'nd');
00820                 $table->add(_('Montant'), $url, " order by jr_montant asc", " order by jr_montant desc", "ma", "md");
00821                 $table->add(_("Description"), $url, "order by jr_comment asc", "order by jr_comment desc", "ca", "cd");
00822 
00823                 $ord = (!isset($_GET['ord'])) ? 'da' : $_GET['ord'];
00824                 $order = $table->get_sql_order($ord);
00825 
00826                 // Count
00827                 $count = $this->db->count_sql($sql);
00828                 // Add the limit
00829                 $sql.=$order . $limit . $offset;
00830                 // Execute SQL stmt
00831                 $Res = $this->db->exec_sql($sql);
00832 
00833                 //starting from here we can refactor, so that instead of returning the generated HTML,
00834                 //this function returns a tree structure.
00835 
00836                 $r = "";
00837 
00838 
00839                 $Max = Database::num_row($Res);
00840 
00841                 if ($Max == 0)
00842                         return array(0, _("Aucun enregistrement trouvé"));
00843 
00844                 $r.='<table class="result">';
00845 
00846 
00847                 $r.="<tr >";
00848                 $r.="<th>"._("n° interne")."</th>";
00849                 if ($this->type == 'ALL')
00850                 {
00851                         $r.=th('Journal');
00852                 }
00853                 $r.='<th>' . $table->get_header(0) . '</th>';
00854                 $r.='<th>' . $table->get_header(1) . '</td>';
00855                 $r.='<th>' . $table->get_header(2) . '</th>';
00856                 $r.='<th>' . $table->get_header(3) . '</th>';
00857                 $r.='<th>' . $table->get_header(4) . '</th>';
00858                 $r.='<th>' . $table->get_header(6) . '</th>';
00859                 $r.=th('Notes', ' style="width:15%"');
00860                 $r.='<th>' . $table->get_header(5) . '</th>';
00861                 // if $p_paid is not equal to 0 then we have a paid column
00862                 if ($p_paid != 0)
00863                 {
00864                         $r.="<th> " . _('Payé') . "</th>";
00865                 }
00866                 $r.="<th>" . _('Concerne') . "</th>";
00867                 $r.="<th>" . _('Document') . "</th>";
00868                 $r.="</tr>";
00869                 // Total Amount
00870                 $tot = 0.0;
00871                 $gDossier = dossier::id();
00872                 for ($i = 0; $i < $Max; $i++)
00873                 {
00874 
00875 
00876                         $row = Database::fetch_array($Res, $i);
00877 
00878                         if ($i % 2 == 0)
00879                                 $tr = '<TR class="odd">';
00880                         else
00881                                 $tr = '<TR class="even">';
00882                         $r.=$tr;
00883                         //internal code
00884                         // button  modify
00885                         $r.="<TD>";
00886                         // If url contains
00887                         //
00888 
00889             $href = basename($_SERVER['PHP_SELF']);
00890 
00891 
00892                         $r.=sprintf('<A class="detail" style="text-decoration:underline" HREF="javascript:modifyOperation(\'%s\',\'%s\')" >%s </A>', $row['jr_id'], $gDossier, $row['jr_internal']);
00893                         $r.="</TD>";
00894                         if ($this->type == 'ALL')
00895                                 $r.=td($row['jrn_def_name']);
00896                         // date
00897                         $r.="<TD>";
00898                         $r.=$row['str_jr_date'];
00899                         $r.="</TD>";
00900                         // echeance
00901                         $r.="<TD>";
00902                         $r.=$row['str_jr_ech'];
00903                         $r.="</TD>";
00904                         $r.="<TD>";
00905                         $r.=$row['str_jr_date_paid'];
00906                         $r.="</TD>";
00907 
00908                         // pj
00909                         $r.="<TD>";
00910                         $r.=$row['jr_pj_number'];
00911                         $r.="</TD>";
00912 
00913                         // Tiers
00914                         $other = ($row['quick_code'] != '') ? '[' . $row['quick_code'] . '] ' . $row['name'] . ' ' . $row['first_name'] : '';
00915                         $r.=td($other);
00916                         // comment
00917                         $r.="<TD>";
00918                         $tmp_jr_comment = h($row['jr_comment']);
00919                         $r.=$tmp_jr_comment;
00920                         $r.="</TD>";
00921                         $r.=td(h($row['n_text']), ' style="font-size:0.87em%"');
00922                         // Amount
00923                         // If the ledger is financial :
00924                         // the credit must be negative and written in red
00925                         $positive = 0;
00926 
00927                         // Check ledger type :
00928                         if ($row['jrn_def_type'] == 'FIN')
00929                         {
00930                                 $positive = $this->db->get_value("select qf_amount from quant_fin where jr_id=$1", array($row['jr_id']));
00931                                 if ($this->db->count() != 0)
00932                                         $positive = ($positive < 0) ? 1 : 0;
00933                         }
00934                         $r.="<TD align=\"right\">";
00935                         $t_amount=$row['jr_montant'];
00936                         if ($row['total_invoice'] != null && $row['total_invoice'] != $row['jr_montant'])
00937                                 $t_amount=$row['total_invoice'];
00938                         $tot = ($positive != 0) ? bcsub($tot , $t_amount ): bcadd($tot , $t_amount);
00939                         //STAN $positive always == 0
00940                         if ($row [ 'jrn_def_type']=='FIN')
00941                         {
00942                                 $r.=( $positive != 0 ) ? "<font color=\"red\">  - " . nbm($t_amount) . "</font>" : nbm($t_amount);
00943                         }
00944                         else
00945                         {
00946                                 $r.=( $t_amount <  0 ) ? "<font color=\"red\">  " . nbm($t_amount) . "</font>" : nbm($t_amount);
00947                         }
00948                         $r.="</TD>";
00949 
00950 
00951                         // Show the paid column if p_paid is not null
00952                         if ($p_paid != 0)
00953                         {
00954                                 $w = new ICheckBox();
00955                                 $w->name = "rd_paid" . $row['jr_id'];
00956                                 $w->selected = ($row['jr_rapt'] == 'paid') ? true : false;
00957                                 // if p_paid == 2 then readonly
00958                                 $w->readonly = ( $p_paid == 2) ? true : false;
00959                                 $h = new IHidden();
00960                                 $h->name = "set_jr_id" . $row['jr_id'];
00961                                 $r.='<TD>' . $w->input() . $h->input() . '</TD>';
00962                                 if ($row['jr_rapt'] == 'paid')
00963                                         $amount_paid=bcadd($amount_paid,$t_amount);
00964                                 else
00965                                         $amount_unpaid=bcadd($amount_unpaid,$t_amount);
00966                         }
00967 
00968                         // Rapprochement
00969                         $rec = new Acc_Reconciliation($this->db);
00970                         $rec->set_jr_id($row['jr_id']);
00971                         $a = $rec->get();
00972                         $r.="<TD>";
00973                         if ($a != null)
00974                         {
00975 
00976                                 foreach ($a as $key => $element)
00977                                 {
00978                                         $operation = new Acc_Operation($this->db);
00979                                         $operation->jr_id = $element;
00980                                         $l_amount = $this->db->get_value("select jr_montant from jrn " .
00981                                                         " where jr_id=$element");
00982                                         $r.= "<A class=\"detail\" HREF=\"javascript:modifyOperation('" . $element . "'," . $gDossier . ")\" > " . $operation->get_internal() . "[" . nbm($l_amount) . "]</A>";
00983                                 }//for
00984                         }// if ( $a != null ) {
00985                         $r.="</TD>";
00986 
00987                         if ($row['jr_valid'] == 'f')
00988                         {
00989                                 $r.="<TD>"._("Opération annulée")."</TD>";
00990                         }
00991                         else
00992                         {
00993 
00994                         } // else
00995                         //document
00996                         if ($row['jr_pj_name'] != "")
00997                         {
00998                                 $image = '<IMG SRC="image/insert_table.gif" title="' . $row['jr_pj_name'] . '" border="0">';
00999                                 $r.="<TD>" . sprintf('<A class="detail" HREF="show_pj.php?jrn=%s&jr_grpt_id=%s&%s">%s</A>', $row['jrn_def_id'], $row['jr_grpt_id'], $str_dossier, $image)
01000                                                 . "</TD>";
01001                         }
01002                         else
01003                                 $r.="<TD></TD>";
01004 
01005                         // end row
01006                         $r.="</tr>";
01007                 }
01008                 $amount_paid = round($amount_paid, 4);
01009                 $amount_unpaid = round($amount_unpaid, 4);
01010                 $tot = round($tot, 4);
01011                 $r.="<TR>";
01012                 $r.='<TD COLSPAN="5">Total</TD>';
01013                 $r.='<TD ALIGN="RIGHT">' . nbm($tot) . "</TD>";
01014                 $r.="</tr>";
01015                 if ($p_paid != 0)
01016                 {
01017                         $r.="<TR>";
01018                         $r.='<TD COLSPAN="5">'._("Payé").'</TD>';
01019                         $r.='<TD ALIGN="RIGHT">' . nbm($amount_paid) . "</TD>";
01020                         $r.="</tr>";
01021                         $r.="<TR>";
01022                         $r.='<TD COLSPAN="5">'._("Non payé").'</TD>';
01023                         $r.='<TD ALIGN="RIGHT">' . nbm($amount_unpaid) . "</TD>";
01024                         $r.="</tr>";
01025                 }
01026                 $r.="</table>";
01027 
01028                 return array($count, $r);
01029         }
01030 
01031         /**
01032          * @brief get_detail gives the detail of row
01033          * this array must contains at least the field
01034          *       <ul>
01035          *       <li> montant</li>
01036          *       <li> grpt_id
01037          *       </ul>
01038          * the following field will be added
01039          *       <ul>
01040          *       <li> HTVA
01041          *       <li> TVAC
01042          *       <li> TVA array with
01043          *          <ul>
01044          *          <li> field 0 idx
01045          *          <li> array containing tva_id,tva_label and tva_amount
01046          *          </ul>
01047          *       </ul>
01048          *
01049          * @paramp_array the structure is set in get_rowSimple, this array is
01050          *        modified,
01051          * @param $trunc if the data must be truncated, usefull for pdf export
01052          * @paramp_jrn_type is the type of the ledger (ACH or VEN)
01053          * @param $a_TVA TVA Array (default null)
01054          * @param $a_ParmCode Array (default null)
01055          * \return p_array
01056          */
01057 
01058         function get_detail(&$p_array, $p_jrn_type, $trunc = 0, $a_TVA = null, $a_ParmCode = null)
01059         {
01060                 if ($a_TVA == null)
01061                 {
01062                         //Load TVA array
01063                         $a_TVA = $this->db->get_array('select tva_id,tva_label,tva_poste
01064                                         from tva_rate where tva_rate != 0 order by tva_rate,tva_label,tva_id');
01065                 }
01066                 if ($a_ParmCode == null)
01067                 {
01068                         //Load Parm_code
01069                         $a_ParmCode = $this->db->get_array('select p_code,p_value from parm_code');
01070                 }
01071                 // init
01072                 $p_array['client'] = "";
01073                 $p_array['TVAC'] = 0;
01074                 $p_array['TVA'] = array();
01075                 $p_array['AMOUNT_TVA'] = 0.0;
01076                 $p_array['dep_priv'] = 0;
01077                 $p_array['dna'] = 0;
01078                 $p_array['tva_dna'] = 0;
01079                 $dep_priv = 0.0;
01080                 
01081                 //
01082                 // Retrieve data from jrnx
01083                 $sql = "select j_id,j_poste,j_montant, j_debit,j_qcode from jrnx where " .
01084                                 " j_grpt=" . $p_array['grpt_id'];
01085                 $Res2 = $this->db->exec_sql($sql);
01086                 $data_jrnx = Database::fetch_all($Res2);
01087                 $c = 0;
01088 
01089                 // Parse data from jrnx and fill diff. field
01090                 foreach ($data_jrnx as $code)
01091                 {
01092                         $idx_tva = 0;
01093                         $poste = new Acc_Account_Ledger($this->db, $code['j_poste']);
01094 
01095                         // if card retrieve name if the account is not a VAT account
01096                         if (strlen(trim($code['j_qcode'])) != 0 && $poste->isTva() == 0)
01097                         {
01098                                 $fiche = new Fiche($this->db);
01099                                 $fiche->get_by_qcode(trim($code['j_qcode']), false);
01100                                 $fiche_def_id = $fiche->get_fiche_def_ref_id();
01101                                 // Customer or supplier
01102                                 if ($fiche_def_id == FICHE_TYPE_CLIENT ||
01103                                                 $fiche_def_id == FICHE_TYPE_FOURNISSEUR
01104                                         ||$fiche_def_id == FICHE_TYPE_ADM_TAX)
01105                                 {
01106                                         $p_array['TVAC'] = $code['j_montant'];
01107 
01108                                         $p_array['client'] = ($trunc == 0) ? $fiche->getName() : mb_substr($fiche->getName(), 0, 20);
01109                                         $p_array['reversed'] = false;
01110                                         if ($fiche_def_id == FICHE_TYPE_CLIENT && $code['j_debit'] == 'f')
01111                                         {
01112                                                 $p_array['reversed'] = true;
01113                                                 $p_array['TVAC']*=-1;
01114                                         }
01115                                         if ($fiche_def_id == FICHE_TYPE_ADM_TAX && $code['j_debit'] == 'f')
01116                                         {
01117                                                 $p_array['reversed'] = true;
01118                                                 $p_array['TVAC']*=-1;
01119                                         }
01120                                         if ($fiche_def_id == FICHE_TYPE_FOURNISSEUR && $code['j_debit'] == 't')
01121                                         {
01122                                                 $p_array['reversed'] = true;
01123                                                 $p_array['TVAC']*=-1;
01124                                         }
01125                                 }
01126                                 else
01127                                 {
01128                                         // if we use the ledger ven / ach for others card than supplier and customer
01129                                         if ($fiche_def_id != FICHE_TYPE_VENTE &&
01130                                                         $fiche_def_id != FICHE_TYPE_ACH_MAR &&
01131                                                         $fiche_def_id != FICHE_TYPE_ACH_SER  &&
01132                                                         $fiche_def_id != FICHE_TYPE_ACH_MAT
01133                                            )                                                
01134                                         {
01135                                                 $p_array['TVAC'] = $code['j_montant'];
01136 
01137                                                 $p_array['client'] = ($trunc == 0) ? $fiche->getName() : mb_substr($fiche->getName(), 0, 20);
01138                                                 $p_array['reversed'] = false;
01139                                                 if ($p_jrn_type == 'ACH' && $code['j_debit'] == 't')
01140                                                 {
01141                                                         $p_array['reversed'] = true;
01142                                                         $p_array['TVAC']*=-1;
01143                                                 }
01144                                                 if ($p_jrn_type == 'VEN' && $code['j_debit'] == 'f')
01145                                                 {
01146                                                         $p_array['reversed'] = true;
01147                                                         $p_array['TVAC']*=-1;
01148                                                 }
01149                                         }
01150                                 }
01151                         }
01152                         // if TVA, load amount, tva id and rate in array
01153                         foreach ($a_TVA as $line_tva)
01154                         {
01155                                 list($tva_deb, $tva_cred) = explode(',', $line_tva['tva_poste']);
01156                                 if ($code['j_poste'] == $tva_deb ||
01157                                                 $code['j_poste'] == $tva_cred)
01158                                 {
01159 
01160                                         // For the reversed operation
01161                                         if ($p_jrn_type == 'ACH' && $code['j_debit'] == 'f')
01162                                         {
01163                                                 $code['j_montant'] = -1 * $code['j_montant'];
01164                                         }
01165                                         if ($p_jrn_type == 'VEN' && $code['j_debit'] == 't')
01166                                         {
01167                                                 $code['j_montant'] = -1 * $code['j_montant'];
01168                                         }
01169 
01170                                         $p_array['AMOUNT_TVA']+=$code['j_montant'];
01171 
01172                                         $p_array['TVA'][$c] = array($idx_tva, array($line_tva['tva_id'], $line_tva['tva_label'], $code['j_montant']));
01173                                         $c++;
01174 
01175                                         $idx_tva++;
01176                                 }
01177                         }
01178 
01179                         // isDNA
01180                         // If operation is reversed then  amount are negatif
01181                         /* if ND */
01182                         if ($p_array['jrn_def_type'] == 'ACH')
01183                         {
01184                                 $purchase = new Gestion_Purchase($this->db);
01185                                 $purchase->search_by_jid($code['j_id']);
01186                                 $purchase->load();
01187                                 $dep_priv+=$purchase->qp_dep_priv;
01188                                 $p_array['dep_priv'] = $dep_priv;
01189                                 $p_array['dna']=bcadd($p_array['dna'],$purchase->qp_nd_amount);
01190                                 $p_array['tva_dna']=bcadd($p_array['tva_dna'],bcadd($purchase->qp_nd_tva,$purchase->qp_nd_tva_recup));
01191                         }
01192                         
01193                 }
01194                 $p_array['TVAC'] = sprintf('% 10.2f', $p_array['TVAC'] );
01195                 $p_array['HTVA'] = sprintf('% 10.2f', $p_array['TVAC'] - $p_array['AMOUNT_TVA']);
01196                 $r = "";
01197                 $a_tva_amount = array();
01198                 // inline TVA (used for the PDF)
01199                 foreach ($p_array['TVA'] as $linetva)
01200                 {
01201                         foreach ($a_TVA as $tva)
01202                         {
01203                                 if ($tva['tva_id'] == $linetva[1][0])
01204                                 {
01205                                         $a = $tva['tva_id'];
01206                                         $a_tva_amount[$a] = $linetva[1][2];
01207                                 }
01208                         }
01209                 }
01210                 foreach ($a_TVA as $line_tva)
01211                 {
01212                         $a = $line_tva['tva_id'];
01213                         if (isset($a_tva_amount[$a]))
01214                         {
01215                                 $tmp = sprintf("% 10.2f", $a_tva_amount[$a]);
01216                                 $r.="$tmp";
01217                         }
01218                         else
01219                                 $r.=sprintf("% 10.2f", 0);
01220                 }
01221                 $p_array['TVA_INLINE'] = $r;
01222 
01223                 return $p_array;
01224         }
01225 
01226 // retrieve data from jrnx
01227         /**
01228          * @brief  Get the properties of a journal
01229          *
01230          * \return an array containing properties
01231          *
01232          */
01233 
01234         function get_propertie()
01235         {
01236                 if ($this->id == 0)
01237                         return;
01238 
01239                 $Res = $this->db->exec_sql("select jrn_Def_id,jrn_def_name,jrn_def_class_deb,jrn_def_class_cred,jrn_def_type,
01240                                  jrn_deb_max_line,jrn_cred_max_line,jrn_def_ech,jrn_def_ech_lib,jrn_def_code,
01241                                  jrn_def_fiche_deb,jrn_def_fiche_cred,jrn_def_pj_pref
01242                                  from jrn_Def
01243                                  where jrn_def_id=$1", array($this->id));
01244                 $Count = Database::num_row($Res);
01245                 if ($Count == 0)
01246                 {
01247                         echo '<DIV="redcontent"><H2 class="error">' . _('Parametres journaux non trouves') . '</H2> </DIV>';
01248                         return null;
01249                 }
01250                 return Database::fetch_array($Res, 0);
01251         }
01252 
01253         /** \function GetDefLine
01254          * @brief Get the number of lines of a journal
01255          * @param$p_cred deb or cred
01256          *
01257          * \return an integer
01258          */
01259 
01260         function GetDefLine()
01261         {
01262                 $sql_cred = 'jrn_deb_max_line';
01263                 $sql = "select jrn_deb_max_line as value from jrn_def where jrn_def_id=$1";
01264                 $r = $this->db->exec_sql($sql, array($this->id));
01265                 $Res = Database::fetch_all($r);
01266                 if (sizeof($Res) == 0)
01267                         return 1;
01268                 return $Res[0]['value'];
01269         }
01270 
01271         /**
01272          * @brief get the saldo of a ledger for a specific period
01273          * @param$p_from start period
01274          * @param$p_to end period
01275          */
01276 
01277         function get_solde($p_from, $p_to)
01278         {
01279                 $ledger = "";
01280                 if ($this->id != 0)
01281                 {
01282                         $ledger = " and j_jrn_def = " . $this->id;
01283                 }
01284 
01285                 $periode = sql_filter_per($this->db, $p_from, $p_to, 'p_id', 'j_tech_per');
01286                 $sql = 'select j_montant as montant,j_debit as deb from jrnx where '
01287                                 . $periode . $ledger;
01288 
01289                 $ret = $this->db->exec_sql($sql);
01290                 $array = Database::fetch_all($ret);
01291                 $deb = 0.0;
01292                 $cred = 0.0;
01293                 foreach ($array as $line)
01294                 {
01295 
01296                         if ($line['deb'] == 't')
01297                                 $deb+=$line['montant'];
01298                         else
01299                                 $cred+=$line['montant'];
01300                 }
01301                 $response = array($deb, $cred);
01302                 return $response;
01303         }
01304 
01305         /**
01306          * @brief Show a select list   of the ledgers you can access in
01307          * writing, reading or simply accessing.
01308          * @param$p_type = ALL or the type of the ledger (ACH,VEN,FIN,ODS)
01309          * @param$p_access =3 for READ and WRITE, 2 for write and 1 for readonly
01310          * \return     object HtmlInput select
01311          */
01312 
01313         function select_ledger($p_type = "ALL", $p_access = 3)
01314         {
01315                 global $g_user;
01316                 $array = $g_user->get_ledger($p_type, $p_access);
01317 
01318                 if ($array == null)
01319                         return null;
01320                 $idx = 0;
01321                 $ret = array();
01322 
01323                 foreach ($array as $value)
01324                 {
01325                         $ret[$idx]['value'] = $value['jrn_def_id'];
01326                         $ret[$idx]['label'] = h($value['jrn_def_name']);
01327                         $idx++;
01328                 }
01329 
01330                 $select = new ISelect();
01331                 $select->name = 'p_jrn';
01332                 $select->value = $ret;
01333                 $select->selected = $this->id;
01334                 return $select;
01335         }
01336 
01337         /**
01338          * @brief retrieve the jrn_def_fiche and return them into a array
01339          *        index deb, cred
01340          * \param
01341          * \param
01342          * \param
01343          *
01344          *
01345          * \return return an array ('deb'=> ,'cred'=>)
01346          */
01347 
01348         function get_fiche_def()
01349         {
01350                 $sql = "select jrn_def_fiche_deb as deb,jrn_def_fiche_cred as cred " .
01351                                 " from jrn_def where " .
01352                                 " jrn_def_id = $1 ";
01353 
01354                 $r = $this->db->exec_sql($sql, array($this->id));
01355 
01356                 $res = Database::fetch_all($r);
01357                 if (empty($res))
01358                         return null;
01359 
01360                 return $res[0];
01361         }
01362 
01363         /**
01364          * @brief retrieve the jrn_def_class_deb and return it
01365          *
01366          *
01367          * \return return an string
01368          */
01369 
01370         function get_class_def()
01371         {
01372                 $sql = "select jrn_def_class_deb  " .
01373                                 " from jrn_def where " .
01374                                 " jrn_def_id = $1";
01375 
01376                 $r = $this->db->exec_sql($sql, array($this->id));
01377 
01378                 $res = Database::fetch_all($r);
01379 
01380                 if (empty($res))
01381                         return null;
01382 
01383                 return $res[0];
01384         }
01385 
01386         /**
01387          * @brief show the result of the array to confirm
01388          * before inserting
01389          * @param$p_array array from the form
01390          * \return string
01391          */
01392 
01393         function confirm($p_array, $p_readonly = false)
01394         {
01395                 global $g_parameter;
01396                 $msg = array();
01397                 if (!$p_readonly)
01398                         $msg = $this->verify($p_array);
01399                 $this->id = $p_array['p_jrn'];
01400                 if (empty($p_array))
01401                         return 'Aucun r&eacute;sultat';
01402                 $anc = null;
01403                 extract($p_array);
01404                 $lPeriode = new Periode($this->db);
01405                 if ($this->check_periode() == true)
01406                 {
01407                         $lPeriode->p_id = $period;
01408                 }
01409                 else
01410                 {
01411                         $lPeriode->find_periode($e_date);
01412                 }
01413                 $total_deb = 0;
01414                 $total_cred = 0;
01415                 bcscale(2);
01416 
01417                 $ret = "";
01418                 if (!empty($msg))
01419                 {
01420                         $ret.=$this->display_warning($msg, _("Attention : il vaut mieux utiliser les fiches que les postes comptables"));
01421                 }
01422                 $ret.="<table >";
01423                 $ret.="<tr><td>" . _('Date') . " : </td><td>$e_date</td></tr>";
01424                 /* display periode */
01425                 $date_limit = $lPeriode->get_date_limit();
01426                 $ret.='<tr> ' . td(_('Période Comptable')) . td($date_limit['p_start'] . '-' . $date_limit['p_end']) . '</tr>';
01427                 $ret.="<tr><td>" . _('Libellé') . " </td><td>" . h($desc) . "</td></tr>";
01428                 $ret.="<tr><td>" . _('PJ Num') . " </td><td>" . h($e_pj) . "</td></tr>";
01429                 $ret.='</table>';
01430                 $ret.="<table class=\"result\">";
01431                 $ret.="<tr>";
01432                 $ret.="<th>" . _('Quick Code ou ');
01433                 $ret.=_("Poste") . " </th>";
01434                 $ret.="<th style=\"text-align:left\"> " . _("Libellé") . " </th>";
01435                 $ret.="<th style=\"text-align:right\">" . _("Débit") . "</th>";
01436                 $ret.="<th style=\"text-align:right\">" . _("Crédit") . "</th>";
01437                 /* if we use the AC */
01438                 if ($g_parameter->MY_ANALYTIC != 'nu')
01439                 {
01440                         $anc = new Anc_Plan($this->db);
01441                         $a_anc = $anc->get_list();
01442                         $x = count($a_anc);
01443                         /* set the width of the col */
01444                         $ret.='<th colspan="' . $x . '" style="width:auto;text-align:center" >' . _('Compt. Analytique') . '</th>';
01445 
01446                         /* add hidden variables pa[] to hold the value of pa_id */
01447                         $ret.=Anc_Plan::hidden($a_anc);
01448                 }
01449                 $ret.="</tr>";
01450 
01451                 $ret.=HtmlInput::hidden('e_date', $e_date);
01452                 $ret.=HtmlInput::hidden('desc', $desc);
01453                 $ret.=HtmlInput::hidden('period', $lPeriode->p_id);
01454                 $ret.=HtmlInput::hidden('e_pj', $e_pj);
01455                 $ret.=HtmlInput::hidden('e_pj_suggest', $e_pj_suggest);
01456                 $mt = microtime(true);
01457                 $ret.=HtmlInput::hidden('mt', $mt);
01458                 // For predefined operation
01459                 $ret.=HtmlInput::hidden('e_comm', $desc);
01460                 $ret.=HtmlInput::hidden('jrn_type', $this->get_type());
01461                 $ret.=HtmlInput::hidden('p_jrn', $this->id);
01462                 $ret.=HtmlInput::hidden('nb_item', $nb_item);
01463                 if ($this->with_concerned == true)
01464                 {
01465                         $ret.=HtmlInput::hidden('jrn_concerned', $jrn_concerned);
01466                 }
01467                 $ret.=dossier::hidden();
01468                 $count = 0;
01469                 for ($i = 0; $i < $nb_item; $i++)
01470                 {
01471                         if ($p_readonly == true)
01472                         {
01473                                 if (!isset(${'qc_' . $i}))
01474                                         ${'qc_' . $i} = '';
01475                                 if (!isset(${'poste' . $i}))
01476                                         ${'poste' . $i} = '';
01477                                 if (!isset(${'amount' . $i}))
01478                                         ${'amount' . $i} = '';
01479                         }
01480                         $ret.="<tr>";
01481                         if (trim(${'qc_' . $i}) != "")
01482                         {
01483                                 $oqc = new Fiche($this->db);
01484                                 $oqc->get_by_qcode(${'qc_' . $i}, false);
01485                                 $strPoste = $oqc->strAttribut(ATTR_DEF_ACCOUNT);
01486                                 $ret.="<td>" .
01487                                                 ${'qc_' . $i} . ' - ' .
01488                                                 $oqc->strAttribut(ATTR_DEF_NAME) . HtmlInput::hidden('qc_' . $i, ${'qc_' . $i}) .
01489                                                 '</td>';
01490                         }
01491 
01492                         if (trim(${'qc_' . $i}) == "" && trim(${'poste' . $i}) != "")
01493                         {
01494                                 $oposte = new Acc_Account_Ledger($this->db, ${'poste' . $i});
01495                                 $strPoste = $oposte->id;
01496                                 $ret.="<td>" . h(${"poste" . $i} . " - " .
01497                                                                 $oposte->get_name()) . HtmlInput::hidden('poste' . $i, ${'poste' . $i}) .
01498                                                 '</td>';
01499                         }
01500 
01501                         if (trim(${'qc_' . $i}) == "" && trim(${'poste' . $i}) == "")
01502                                 continue;
01503                         $ret.="<td>" . h(${"ld" . $i}) . HtmlInput::hidden('ld' . $i, ${'ld' . $i}) . "</td>";
01504                         if (isset(${"ck$i"}))
01505                         {
01506                                 $ret.="<td class=\"num\">" . nbm(${"amount" . $i}) . HtmlInput::hidden('amount' . $i, ${'amount' . $i}) . "</td>" . td("");
01507                                 $total_deb = bcadd($total_deb, ${'amount' . $i});
01508                         }
01509                         else
01510                         {
01511                                 $ret.=td("") . "<td class=\"num\">" . nbm(${"amount" . $i}) . HtmlInput::hidden('amount' . $i, ${'amount' . $i}) . "</td>";
01512                                 $total_cred = bcadd($total_cred, ${"amount" . $i});
01513                         }
01514                         $ret.="<td>";
01515                         $ret.=(isset(${"ck$i"})) ? HtmlInput::hidden('ck' . $i, ${'ck' . $i}) : "";
01516                         $ret.="</td>";
01517                         // CA
01518 
01519                         if ($g_parameter->MY_ANALYTIC != 'nu') // use of AA
01520                         {
01521                                 if (preg_match("/^[6,7]+/", $strPoste) == 1)
01522                                 {
01523                                         // show form
01524                                         $op = new Anc_Operation($this->db);
01525                                         $null = ($g_parameter->MY_ANALYTIC == 'op') ? 1 : 0;
01526                                         $p_array['pa_id'] = $a_anc;
01527                                         /* op is the operation it contains either a sequence or a jrnx.j_id */
01528                                         $ret.=HtmlInput::hidden('op[]=', $i);
01529 
01530                                         $ret.='<td style="text-align:center">';
01531                                         $read = ($p_readonly == true) ? 0 : 1;
01532                                         $ret.=$op->display_form_plan($p_array, $null, $read, $count, round(${'amount' . $i}, 2));
01533                                         $ret.='</td>';
01534                                         $count++;
01535                                 }
01536                         }
01537 
01538 
01539 
01540                         $ret.="</tr>";
01541                 }
01542                 $ret.=tr(td('') . td(_('Totaux')) . td($total_deb, 'class="num"') . td($total_cred, 'class="num"'), 'class="footer"');
01543                 $ret.="</table>";
01544                 if ($g_parameter->MY_ANALYTIC != 'nu' && $p_readonly == false)
01545                         $ret.='<input type="button" class="button" value="' . _('verifie Imputation Analytique') . '" onClick="verify_ca(\'\');">';
01546                 return $ret;
01547         }
01548         function get_min_row()
01549         {
01550                 $row=$this->db->get_value("select jrn_deb_max_line from jrn_def where jrn_def_id=$1",array($this->id));
01551                 return $row;
01552         }
01553         /**
01554          * @brief Show the form to encode your operation
01555          * @param$p_array if you correct or use a predef operation (default = null)
01556          * @param$p_readonly 1 for readonly 0 for writable (default 0)
01557          *
01558          * \return a string containing the form
01559          */
01560 
01561         function input($p_array = null, $p_readonly = 0)
01562         {
01563                 global $g_parameter, $g_user;
01564                 $this->nb=$this->get_min_row();
01565                 if ($p_readonly == 1)
01566                         return $this->confirm($p_array);
01567 
01568                 if ($p_array != null)
01569                         extract($p_array);
01570                 $add_js = "";
01571                 if ($g_parameter->MY_PJ_SUGGEST == 'Y')
01572                 {
01573                         $add_js = "update_pj();";
01574                 }
01575                 if ($g_parameter->MY_DATE_SUGGEST=='Y')
01576                 {
01577                         $add_js.='get_last_date();';
01578                 }
01579                 $add_js.='update_row("quick_item");';
01580                 $ret = "";
01581                 if ($g_user->check_action(FICADD) == 1)
01582                 {
01583                         /* Add button */
01584                         $f_add_button = new IButton('add_card');
01585                         $f_add_button->label = _('Créer une nouvelle fiche');
01586                         $f_add_button->set_attribute('ipopup', 'ipop_newcard');
01587                         $f_add_button->set_attribute('jrn', $this->id);
01588                         $f_add_button->javascript = " this.jrn=\$('p_jrn').value;select_card_type(this);";
01589                         $f_add_button->input();
01590                 }
01591                 $wLedger = $this->select_ledger('ODS', 2);
01592                 if ($wLedger == null)
01593                         exit(_('Pas de journal disponible'));
01594                 $wLedger->javascript = "onChange='update_name();update_predef(\"ods\",\"t\",\"".$_REQUEST['ac']."\");$add_js'";
01595                 $label = " Journal " . HtmlInput::infobulle(2);
01596 
01597                 $ret.=$label . $wLedger->input();
01598 
01599 
01600                 // Load the javascript
01601                 //
01602         $ret.="<table>";
01603                 $ret.= '<tr ><td colspan="2" style="width:auto">';
01604                 $wDate = new IDate('e_date');
01605                 $wDate->readonly = $p_readonly;
01606                 $e_date = (isset($e_date) && trim($e_date) != '') ? $e_date : '';
01607                 $wDate->value = $e_date;
01608 
01609                 $ret.=_("Date") . ' : ' . $wDate->input();
01610                 $ret.= '</td>';
01611                 /* insert periode if needed */
01612                 // Periode
01613                 //--
01614                 if ($this->check_periode() == true)
01615                 {
01616                         $l_user_per = $g_user->get_periode();
01617                         $def = (isset($periode)) ? $periode : $l_user_per;
01618 
01619                         $period = new IPeriod("period");
01620                         $period->user = $g_user;
01621                         $period->cn = $this->db;
01622                         $period->value = $def;
01623                         $period->type = OPEN;
01624                         try
01625                         {
01626                                 $l_form_per = $period->input();
01627                         }
01628                         catch (Exception $e)
01629                         {
01630                                 if ($e->getCode() == 1)
01631                                 {
01632                                         echo _("Aucune période ouverte");
01633                                         exit();
01634                                 }
01635                         }
01636                         $label = HtmlInput::infobulle(3);
01637                         $f_periode = _("Période comptable") . " $label " . $l_form_per;
01638                         $ret.=td($f_periode);
01639                 }
01640                 $wPJ = new IText('e_pj');
01641                 $wPJ->readonly = false;
01642                 $wPJ->size = 10;
01643 
01644                 /* suggest PJ ? */
01645                 $default_pj = '';
01646                 if ($g_parameter->MY_PJ_SUGGEST == 'Y')
01647                 {
01648                         $default_pj = $this->guess_pj();
01649                 }
01650                 $wPJ->value = (isset($e_pj)) ? $e_pj : $default_pj;
01651                 $ret.= '</tr>';
01652                 $ret.='<tr >';
01653                 $ret.='<td colspan="2" style="width:auto"> ' . _('Pièce') . ' : ' . $wPJ->input();
01654                 $ret.=HtmlInput::hidden('e_pj_suggest', $default_pj);
01655                 $ret.= '</tr>';
01656                 $ret.= '</td>';
01657 
01658                 $ret.= '<tr>';
01659                 $ret.='<td colspan="2" style="width:auto">';
01660                 $ret.=_('Libellé');
01661                 $wDescription = new IText('desc');
01662                 $wDescription->readonly = $p_readonly;
01663                 $wDescription->size = "50";
01664                 $wDescription->value = (isset($desc)) ? $desc : '';
01665 
01666                 $ret.=$wDescription->input();
01667                 $ret.= '</td>';
01668                 $ret.='</tr>';
01669 
01670                 $ret.= '</table>';
01671                 $nb_row = (isset($nb_item) ) ? $nb_item : $this->nb;
01672 
01673                 $ret.=HtmlInput::hidden('nb_item', $nb_row);
01674                 $ret.=dossier::hidden();
01675 
01676                 $ret.=dossier::hidden();
01677 
01678                 $ret.=HtmlInput::hidden('jrn_type', $this->get_type());
01679                 $info = HtmlInput::infobulle(0);
01680                 $info_poste = HtmlInput::infobulle(9);
01681                 if ($g_user->check_action(FICADD) == 1)
01682                         $ret.=$f_add_button->input();
01683                 $ret.='<table id="quick_item" style="width:100%">';
01684                 $ret.='<tr>' .
01685                                 '<th style="text-align:left">Quickcode' . $info . '</th>' .
01686                                 '<th style="text-align:left">' . _('Poste') . $info_poste . '</th>' .
01687                                 '<th style="text-align:left">' . _('Libellé') . '</th>' .
01688                                 '<th style="text-align:left">' . _('Montant') . '</th>' .
01689                                 '<th style="text-align:left">' . _('Débit') . '</th>' .
01690                                 '</tr>';
01691 
01692 
01693                 for ($i = 0; $i < $nb_row; $i++)
01694                 {
01695                         // Quick Code
01696                         $quick_code = new ICard('qc_' . $i);
01697                         $quick_code->set_dblclick("fill_ipopcard(this);");
01698                         $quick_code->set_attribute('ipopup', 'ipopcard');
01699 
01700                         // name of the field to update with the name of the card
01701                         $quick_code->set_attribute('label', "ld" . $i);
01702 
01703                         // name of the field to update with the name of the card
01704                         $quick_code->set_attribute('typecard', 'filter');
01705 
01706                         // Add the callback function to filter the card on the jrn
01707                         $quick_code->set_callback('filter_card');
01708                         $quick_code->set_function('fill_data');
01709                         $quick_code->javascript = sprintf(' onchange="fill_data_onchange(\'%s\');" ', $quick_code->name);
01710 
01711                         $quick_code->value = (isset(${'qc_' . $i})) ? ${'qc_' . $i} : "";
01712                         $quick_code->readonly = $p_readonly;
01713 
01714                         $label = '';
01715                         if ($quick_code->value != '')
01716                         {
01717                                 $Fiche = new Fiche($this->db);
01718                                 $Fiche->get_by_qcode($quick_code->value);
01719                                 $label = $Fiche->strAttribut(ATTR_DEF_NAME);
01720                         }
01721 
01722 
01723                         // Account
01724                         $poste = new IPoste();
01725                         $poste->name = 'poste' . $i;
01726                         $poste->set_attribute('jrn', $this->id);
01727                         $poste->set_attribute('ipopup', 'ipop_account');
01728                         $poste->set_attribute('label', 'ld' . $i);
01729                         $poste->set_attribute('account', 'poste' . $i);
01730                         $poste->set_attribute('dossier', Dossier::id());
01731 
01732                         $poste->value = (isset(${'poste' . $i})) ? ${"poste" . $i} : ''
01733                         ;
01734                         $poste->dbl_click_history();
01735 
01736                         $poste->readonly = $p_readonly;
01737 
01738                         if ($poste->value != '')
01739                         {
01740                                 $Poste = new Acc_Account($this->db);
01741                                 $Poste->set_parameter('value', $poste->value);
01742                                 $label = $Poste->get_lib();
01743                         }
01744 
01745                         // Description of the line
01746                         $line_desc = new IText();
01747                         $line_desc->name = 'ld' . $i;
01748                         $line_desc->size = 30;
01749                         $line_desc->value = (isset(${"ld" . $i})) ? ${"ld" . $i} :
01750                                         $label;
01751 
01752                         // Amount
01753                         $amount = new INum();
01754                         $amount->size = 10;
01755                         $amount->name = 'amount' . $i;
01756                         $amount->value = (isset(${'amount' . $i})) ? ${"amount" . $i} : ''
01757                         ;
01758                         $amount->readonly = $p_readonly;
01759                         $amount->javascript = ' onChange="format_number(this);checkTotalDirect()"';
01760                         // D/C
01761                         $deb = new ICheckBox();
01762                         $deb->name = 'ck' . $i;
01763                         $deb->selected = (isset(${'ck' . $i})) ? true : false;
01764                         $deb->readonly = $p_readonly;
01765                         $deb->javascript = ' onChange="checkTotalDirect()"';
01766 
01767                         $ret.='<tr>';
01768                         $ret.='<td>' . $quick_code->input() . $quick_code->search() . '</td>';
01769                         $ret.='<td>' . $poste->input() .
01770                                         '<script> document.getElementById(\'poste' . $i . '\').onblur=function(){ if (trim(this.value) !=\'\') {document.getElementById(\'qc_' . $i . '\').value="";}}</script>' .
01771                                         '</td>';
01772                         $ret.='<td>' . $line_desc->input() . '</td>';
01773                         $ret.='<td>' . $amount->input() . '</td>';
01774                         $ret.='<td>' . $deb->input() . '</td>';
01775                         $ret.='</tr>';
01776                         // If readonly == 1 then show CA
01777                 }
01778                 $ret.='</table>';
01779                 if (isset($this->with_concerned) && $this->with_concerned == true)
01780                 {
01781                         $oRapt = new Acc_Reconciliation($this->db);
01782                         $w = $oRapt->widget();
01783                         $w->name = 'jrn_concerned';
01784                         $w->value = (isset($jrn_concerned)) ? $jrn_concerned : "";
01785                         $ret.="R&eacute;conciliation/rapprochements : " . $w->input();
01786                 }
01787                 $ret.= create_script("$('".$wDate->id."').focus()");
01788                 return $ret;
01789         }
01790 
01791         /**
01792          * @brief
01793          * check if the current ledger is closed
01794          * \return 1 for yes, otherwise 0
01795          * \see Periode::is_closed
01796          */
01797 
01798         function is_closed($p_periode)
01799         {
01800                 $per = new Periode($this->db);
01801                 $per->set_jrn($this->id);
01802                 $per->set_periode($p_periode);
01803                 $ret = $per->is_closed();
01804                 return $ret;
01805         }
01806 
01807         /**
01808          * @brief verify that the operation can be saved
01809          * @param$p_array array of data same layout that the $_POST from show_form
01810          *
01811          *
01812          * \throw  the getcode  value is 1 incorrect balance,  2 date
01813          * invalid, 3 invalid amount,  4 the card is not in the range of
01814          * permitted card, 5 not in the user's period, 6 closed period
01815          *
01816          */
01817 
01818         function verify($p_array)
01819         {
01820                 extract($p_array);
01821                 global $g_user;
01822                 $tot_cred = 0;
01823                 $tot_deb = 0;
01824                 $msg = array();
01825 
01826                 /* check if we can write into this ledger */
01827                 if ($g_user->check_jrn($p_jrn) != 'W')
01828                         throw new Exception(_('Accès interdit'), 20);
01829 
01830                 /* check for a double reload */
01831                 if (isset($mt) && $this->db->count_sql('select jr_mt from jrn where jr_mt=$1', array($mt)) != 0)
01832                         throw new Exception('Double Encodage', 5);
01833 
01834                 // Check the periode and the date
01835                 if (isDate($e_date) == null)
01836                 {
01837                         throw new Exception('Date invalide', 2);
01838                 }
01839                 $periode = new Periode($this->db);
01840                 /* find the periode  if we have enabled the check_periode */
01841                 if ($this->check_periode() == false)
01842                 {
01843                         $periode->find_periode($e_date);
01844                 }
01845                 else
01846                 {
01847                         $periode->p_id = $period;
01848                         list ($min, $max) = $periode->get_date_limit();
01849                         if (cmpDate($e_date, $min) < 0 ||
01850                                         cmpDate($e_date, $max) > 0)
01851                                 throw new Exception(_('Date et periode ne correspondent pas'), 6);
01852                 }
01853 
01854 
01855 
01856                 // Periode ferme
01857                 if ($this->is_closed($periode->p_id) == 1)
01858                 {
01859                         throw new Exception('Periode fermee', 6);
01860                 }
01861                 /* check if we are using the strict mode */
01862                 if ($this->check_strict() == true)
01863                 {
01864                         /* if we use the strict mode, we get the date of the last
01865                           operation */
01866                         $last_date = $this->get_last_date();
01867                         if ($last_date != null && cmpDate($e_date, $last_date) < 0)
01868                                 throw new Exception(_('Vous utilisez le mode strict la dernière operation est la date du ')
01869                                                 . $last_date . ' ' . _('vous ne pouvez pas encoder à une date antérieure'), 15);
01870                 }
01871 
01872                 for ($i = 0; $i < $nb_item; $i++)
01873                 {
01874                         $err = 0;
01875 
01876                         // Check the balance
01877                         if (!isset(${'amount' . $i}))
01878                                 continue;
01879 
01880                         $amount = round(${'amount' . $i}, 2);
01881                         $tot_deb+=(isset(${'ck' . $i})) ? $amount : 0;
01882                         $tot_cred+=(!isset(${'ck' . $i})) ? $amount : 0;
01883 
01884                         // Check if the card is permitted
01885                         if (isset(${'qc_' . $i}) && trim(${'qc_' . $i}) != "")
01886                         {
01887                                 $f = new Fiche($this->db);
01888                                 $f->quick_code = ${'qc_' . $i};
01889                                 if ($f->belong_ledger($p_jrn) < 0)
01890                                         throw new Exception("La fiche quick_code = " .
01891                                                         $f->quick_code . " n'est pas dans ce journal", 4);
01892                                 if (strlen(trim(${'qc_' . $i})) != 0 && isNumber(${'amount' . $i}) == 0)
01893                                         throw new Exception('Montant invalide', 3);
01894 
01895                                 $strPoste = $f->strAttribut(ATTR_DEF_ACCOUNT);
01896                                 if ($strPoste == '')
01897                                         throw new Exception(sprintf(_("La fiche %s n'a pas de poste comptable"), ${"qc_" . $i}));
01898 
01899                                 $p = new Acc_Account_Ledger($this->db, $strPoste);
01900                                 if ($p->do_exist() == 0)
01901                                         throw new Exception(_('Poste Inexistant pour la fiche [' . ${'qc_' . $i} . ']'), 4);
01902                         }
01903 
01904                         // Check if the account is permitted
01905                         if (isset(${'poste' . $i}) && strlen(trim(${'poste' . $i})) != 0)
01906                         {
01907                                 $p = new Acc_Account_Ledger($this->db, ${'poste' . $i});
01908                                 if ($p->belong_ledger($p_jrn) < 0)
01909                                         throw new Exception(_("Le poste") . " " . $p->id . " " . _("n'est pas dans ce journal"), 5);
01910                                 if (strlen(trim(${'poste' . $i})) != 0 && isNumber(${'amount' . $i}) == 0)
01911                                         throw new Exception(_('Poste invalide [' . ${'poste' . $i} . ']'), 3);
01912                                 if ($p->do_exist() == 0)
01913                                         throw new Exception(_('Poste Inexistant [' . ${'poste' . $i} . ']'), 4);
01914                                 $card_id = $p->find_card();
01915                                 if (!empty($card_id))
01916                                 {
01917                                         $str_msg = " Le poste " . $p->id . " appartient à " . count($card_id) . " fiche(s) dont :";
01918                                         $max = (count($card_id) > MAX_COMPTE_CARD) ? MAX_COMPTE_CARD : count($card_id);
01919                                         for ($x = 0; $x < $max; $x++)
01920                                         {
01921                                                 $card = new Fiche($this->db, $card_id[$x]['f_id']);
01922                                                 $str_msg.=HtmlInput::card_detail($card->strAttribut(ATTR_DEF_QUICKCODE), $card->strAttribut(ATTR_DEF_NAME), 'style="color:red;display:inline;text-decoration:underline"');
01923                                                 $str_msg.=" ";
01924                                         }
01925                                         $msg[] = $str_msg;
01926                                 }
01927                         }
01928                 }
01929                 $tot_deb = round($tot_deb, 4);
01930                 $tot_cred = round($tot_cred, 4);
01931                 if ($tot_deb != $tot_cred)
01932                 {
01933                         throw new Exception(_("Balance incorrecte ") . " debit = $tot_deb credit=$tot_cred ", 1);
01934                 }
01935 
01936                 return $msg;
01937         }
01938 
01939         /**
01940          * @brief compute the internal code of the saved operation and set the $this->jr_internal to
01941          *  the computed value
01942          *
01943          * @param$p_grpt id in jr_grpt_
01944          *
01945          * \return string internal_code
01946          *      -
01947          *
01948          */
01949 
01950         function compute_internal_code($p_grpt)
01951         {
01952                 if ($this->id == 0)
01953                         return;
01954                 $num = $this->db->get_next_seq('s_internal');
01955                 $atype = $this->get_propertie();
01956                 $type = substr($atype['jrn_def_code'], 0, 1);
01957                 $internal_code = sprintf("%s%06X", $type, $num);
01958                 $this->jr_internal = $internal_code;
01959                 return $internal_code;
01960         }
01961 
01962         /**
01963          * @brief save the operation into the jrnx,jrn, ,
01964          *  CA and pre_def
01965          * @param$p_array
01966          *
01967          * \return array with [0] = false if failed otherwise true, [1] error
01968          * code
01969          */
01970 
01971         function save($p_array = null)
01972         {
01973                 if ($p_array == null)
01974                         throw new Exception('save cannot use a empty array');
01975                 global $g_parameter;
01976                 extract($p_array);
01977                 try
01978                 {
01979                         $msg = $this->verify($p_array);
01980                         if (!empty($msg))
01981                         {
01982                                 echo $this->display_warning($msg, _("Attention : il vaut mieux utiliser les fiches que les postes comptables "));
01983                         }
01984                         $this->db->start();
01985 
01986                         $seq = $this->db->get_next_seq('s_grpt');
01987                         $internal = $this->compute_internal_code($seq);
01988 
01989                         $group = $this->db->get_next_seq("s_oa_group");
01990                         $tot_amount = 0;
01991                         $tot_deb = 0;
01992                         $tot_cred = 0;
01993                         $oPeriode = new Periode($this->db);
01994                         $check_periode = $this->check_periode();
01995                         if ($check_periode == false)
01996                         {
01997                                 $oPeriode->find_periode($e_date);
01998                         }
01999                         else
02000                         {
02001                                 $oPeriode->id = $period;
02002                         }
02003 
02004                         $count = 0;
02005                         for ($i = 0; $i < $nb_item; $i++)
02006                         {
02007                                 if (!isset(${'qc_' . $i}) && !isset(${'poste' . $i}))
02008                                         continue;
02009                                 $acc_op = new Acc_Operation($this->db);
02010                                 $quick_code = "";
02011                                 // First we save the jrnx
02012                                 if (isset(${'qc_' . $i}))
02013                                 {
02014                                         $qc = new Fiche($this->db);
02015                                         $qc->get_by_qcode(${'qc_' . $i}, false);
02016                                         $sposte = $qc->strAttribut(ATTR_DEF_ACCOUNT);
02017                                         /*  if there are 2 accounts take following the deb or cred */
02018                                         if (strpos($sposte, ',') != 0)
02019                                         {
02020                                                 $array = explode(",", $sposte);
02021                                                 $poste = (isset(${'ck' . $i})) ? $array[0] : $array[1];
02022                                         }
02023                                         else
02024                                         {
02025                                                 $poste = $sposte;
02026                                                 if ($poste == '')
02027                                                         throw new Exception(sprintf(_("La fiche %s n'a pas de poste comptable"), ${"qc_" . $i}));
02028                                         }
02029                                         $quick_code = ${'qc_' . $i};
02030                                 }
02031                                 else
02032                                 {
02033                                         $poste = ${'poste' . $i};
02034                                 }
02035 
02036                                 $acc_op->date = $e_date;
02037                                 // compute the periode is do not check it
02038                                 if ($check_periode == false)
02039                                         $acc_op->periode = $oPeriode->p_id;
02040                                 $acc_op->desc = null;
02041                                 if (strlen(trim(${'ld' . $i})) != 0)
02042                                         $acc_op->desc = ${'ld' . $i};
02043                                 $acc_op->amount = round(${'amount' . $i}, 2);
02044                                 $acc_op->grpt = $seq;
02045                                 $acc_op->poste = $poste;
02046                                 $acc_op->jrn = $this->id;
02047                                 $acc_op->type = (isset(${'ck' . $i})) ? 'd' : 'c';
02048                                 $acc_op->qcode = $quick_code;
02049                                 $j_id = $acc_op->insert_jrnx();
02050                                 $tot_amount+=round($acc_op->amount, 2);
02051                                 $tot_deb+=($acc_op->type == 'd') ? $acc_op->amount : 0;
02052                                 $tot_cred+=($acc_op->type == 'c') ? $acc_op->amount : 0;
02053                                 if ($g_parameter->MY_ANALYTIC != "nu")
02054                                 {
02055                                         if (preg_match("/^[6,7]+/", $poste) == 1)
02056                                         {
02057 
02058                                                 // for each item, insert into operation_analytique */
02059                                                 $op = new Anc_Operation($this->db);
02060                                                 $op->oa_group = $group;
02061                                                 $op->j_id = $j_id;
02062                                                 $op->oa_date = $e_date;
02063                                                 $op->oa_debit = ($acc_op->type == 'd' ) ? 't' : 'f';
02064                                                 $op->oa_description = $desc;
02065                                                 $op->save_form_plan($p_array, $count, $j_id);
02066                                                 $count++;
02067                                         }
02068                                 }
02069                         }// loop for each item
02070                         $acc_end = new Acc_Operation($this->db);
02071                         $acc_end->amount = $tot_deb;
02072                         if ($check_periode == false)
02073                                 $acc_end->periode = $oPeriode->p_id;
02074                         $acc_end->date = $e_date;
02075                         $acc_end->desc = $desc;
02076                         $acc_end->grpt = $seq;
02077                         $acc_end->jrn = $this->id;
02078                         $acc_end->mt = $mt;
02079                         $jr_id = $acc_end->insert_jrn();
02080                         $this->jr_id = $jr_id;
02081                         if ($jr_id == false)
02082                                 throw new Exception(_('Balance incorrecte'));
02083                         $acc_end->pj = $e_pj;
02084 
02085                         /* if e_suggest != e_pj then do not increment sequence */
02086                         if (strcmp($e_pj, $e_pj_suggest) == 0 && strlen(trim($e_pj)) != 0)
02087                         {
02088                                 $this->inc_seq_pj();
02089                         }
02090 
02091                         $this->pj = $acc_end->set_pj();
02092 
02093                         $this->db->exec_sql("update jrn set jr_internal='" . $internal . "' where " .
02094                                         " jr_grpt_id = " . $seq);
02095                         $this->internal = $internal;
02096                         // Save now the predef op
02097                         //------------------------
02098                         if (isset ($opd_name) && trim($opd_name) != "" ){
02099                                 $opd = new Pre_Op_Advanced($this->db);
02100                                 $opd->get_post();
02101                                 $opd->save();
02102                         }
02103 
02104                         if (isset($this->with_concerned) && $this->with_concerned == true)
02105                         {
02106                                 $orap = new acc_reconciliation($this->db);
02107                                 $orap->jr_id = $jr_id;
02108 
02109                                 $orap->insert($jrn_concerned);
02110                         }
02111                 }
02112                 catch (Exception $a)
02113                 {
02114                         throw $a;
02115                 }
02116                 catch (Exception $e)
02117                 {
02118                         $this->db->rollback();
02119                         echo _('OPERATION ANNULEE ');
02120                         echo '<hr>';
02121                         echo __FILE__ . __LINE__ . $e->getMessage();
02122                         exit();
02123                 }
02124                 $this->db->commit();
02125                 return true;
02126         }
02127 
02128         /**
02129          * @brief get all the data from request and build the object
02130          */
02131 
02132         function get_request()
02133         {
02134                 $this->id = $_REQUEST['p_jrn'];
02135         }
02136 
02137         /**
02138          * @brief retrieve the next number for this type of ledger
02139          * @paramp_cn connx
02140          * @paramp_type ledger type
02141          *
02142          * \return the number
02143          *
02144          *
02145          */
02146 
02147         static function next_number($p_cn, $p_type)
02148         {
02149 
02150                 $Ret = $p_cn->count_sql("select * from jrn_def where jrn_def_type='" . $p_type . "'");
02151                 return $Ret + 1;
02152         }
02153 
02154         /**
02155          * @brief get the first ledger
02156          * @paramthe type
02157          * \return the j_id
02158          */
02159 
02160         public function get_first($p_type, $p_access = 3)
02161         {
02162                 global $g_user;
02163                 $all = $g_user->get_ledger($p_type, $p_access);
02164                 return $all[0];
02165         }
02166 
02167         /**
02168          * @brief Update the paiment  in the list of operation
02169          * @param$p_array is normally $_GET
02170          */
02171 
02172         function update_paid($p_array)
02173         {
02174                 // reset all the paid flag because the checkbox is post only
02175                 // when checked
02176                 foreach ($p_array as $name => $paid)
02177                 {
02178                         list($ad) = sscanf($name, "set_jr_id%d");
02179                         if ($ad == null)
02180                                 continue;
02181                         $sql = "update jrn set jr_rapt='' where jr_id=$ad";
02182                         $Res = $this->db->exec_sql($sql);
02183                 }
02184                 // set a paid flag for the checked box
02185                 foreach ($p_array as $name => $paid)
02186                 {
02187                         list ($id) = sscanf($name, "rd_paid%d");
02188                         if ($id == null)
02189                                 continue;
02190 
02191                         $sql = "update jrn set jr_rapt='paid' where jr_id=$id";
02192                         $Res = $this->db->exec_sql($sql);
02193                 }
02194         }
02195 
02196         function update_internal_code($p_internal)
02197         {
02198                 if (!isset($this->grpt_id))
02199                         exit('ERREUR ' . __FILE__ . ":" . __LINE__);
02200                 $Res = $this->db->exec_sql("update jrn set jr_internal='" . $p_internal . "' where " .
02201                                 " jr_grpt_id = " . $this->grpt_id);
02202         }
02203 
02204         /**
02205          * @brief retrieve all the card for this type of ledger, make them
02206          * into a string separated by comma
02207          * @paramnone
02208          * \return all the card or null is nothing is found
02209          */
02210 
02211         function get_all_fiche_def()
02212         {
02213                 $sql = "select jrn_def_fiche_deb as deb,jrn_def_fiche_cred as cred " .
02214                                 " from jrn_def where " .
02215                                 " jrn_def_id = $1 ";
02216 
02217                 $r = $this->db->exec_sql($sql, array($this->id));
02218 
02219                 $res = Database::fetch_all($r);
02220                 if (empty($res))
02221                         return null;
02222                 $card = "";
02223                 $comma = '';
02224                 foreach ($res as $item)
02225                 {
02226                         if (strlen(trim($item['deb'])) != 0)
02227                         {
02228                                 $card.=$comma . $item['deb'];
02229                                 $comma = ',';
02230                         }
02231                         if (strlen(trim($item['cred'])) != '')
02232                         {
02233                                 $card.=$comma . $item['cred'];
02234                                 $comma = ',';
02235                         }
02236                 }
02237 
02238                 return $card;
02239         }
02240 
02241         /**
02242          * @brief get the saldo of an exercice, used for the opening of a folder
02243          * @param$p_exercice is the exercice we want
02244          * \return an array
02245          * index =
02246          * - solde (debit > 0 ; credit < 0)
02247          * - j_poste
02248          * - j_qcode
02249          */
02250 
02251         function get_saldo_exercice($p_exercice)
02252         {
02253                 $sql = "select sum(a.montant) as solde, j_poste, j_qcode
02254              from
02255              (select j_id, case when j_debit='t' then j_montant
02256              else j_montant * (-1) end  as montant
02257              from jrnx) as a
02258              join jrnx using (j_id)
02259              join parm_periode on (j_tech_per = p_id )
02260              where
02261              p_exercice=$1
02262              and j_poste::text not like '7%'
02263              and j_poste::text not like '6%'
02264              group by j_poste,j_qcode
02265              having (sum(a.montant) != 0 )";
02266                 $res = $this->db->get_array($sql, array($p_exercice));
02267                 return $res;
02268         }
02269 
02270         /**
02271          * @brief Check if a Dossier is using the strict mode or not
02272          * \return true if we are using the strict_mode
02273          */
02274 
02275         function check_strict()
02276         {
02277                 global $g_parameter;
02278                 if ($g_parameter->MY_STRICT == 'Y')
02279                         return true;
02280                 if ($g_parameter->MY_STRICT == 'N')
02281                         return false;
02282                 exit("Valeur invalid " . __FILE__ . ':' . __LINE__);
02283         }
02284 
02285         /**
02286          * @brief Check if a Dossier is using the check on the periode, if true than the user has to enter the date
02287          * and the periode, it is a security check
02288          * \return true if we are using the double encoding (date+periode)
02289          */
02290 
02291         function check_periode()
02292         {
02293                 global $g_parameter;
02294                 if ($g_parameter->MY_CHECK_PERIODE == 'Y')
02295                         return true;
02296                 if ($g_parameter->MY_CHECK_PERIODE == 'N')
02297                         return false;
02298                 exit("Valeur invalid " . __FILE__ . ':' . __LINE__);
02299         }
02300 
02301         /**
02302          * @brief get the date of the last operation
02303          */
02304 
02305         function get_last_date()
02306         {
02307                 if ($this->id == 0)
02308                         throw new Exception(__FILE__ . ":" . __LINE__ . "Journal incorrect ");
02309                 $sql = "select to_char(max(jr_date),'DD.MM.YYYY') from jrn where jr_def_id=$1";
02310                 $date = $this->db->get_value($sql, array($this->id));
02311                 return $date;
02312         }
02313 
02314         /**
02315          * @brief retrieve the jr_id thanks the internal code, do not change
02316          * anything to the current object
02317          * @paramthe internal code
02318          * \return the jr_id or 0 if not found
02319          */
02320 
02321         function get_id($p_internal)
02322         {
02323                 $sql = 'select jr_id from jrn where jr_internal=$1';
02324                 $value = $this->db->get_value($sql, array($p_internal));
02325                 if ($value == '')
02326                         $value = 0;
02327                 return $value;
02328         }
02329 
02330         /**
02331          * @brief create the invoice and saved it as attachment to the
02332          * operation,
02333          * @param$internal is the internal code
02334          * @param$p_array is normally the $_POST
02335          * \return a string
02336          */
02337 
02338         function create_document($internal, $p_array)
02339         {
02340                 extract($p_array);
02341                 $doc = new Document($this->db);
02342                 $doc->f_id = $e_client;
02343                 $doc->md_id = $gen_doc;
02344                 $doc->ag_id = 0;
02345                 $p_array['e_pj']=$this->pj;
02346                 $filename="";
02347                 $doc->Generate($p_array,$p_array['e_pj']);
02348                 // Move the document to the jrn
02349                 $doc->MoveDocumentPj($internal);
02350                 // Update the comment with invoice number, if the comment is empty
02351                 if (!isset($e_comm) || strlen(trim($e_comm)) == 0)
02352                 {
02353                         $sql = "update jrn set jr_comment=' document " . $doc->d_number . "' where jr_internal='$internal'";
02354                         $this->db->exec_sql($sql);
02355                 }
02356                 return h($doc->d_name . ' (' . $doc->d_filename . ')');
02357         }
02358 
02359         /**
02360          * @brief check if the payment method is valid
02361          * @param$e_mp is the value and $e_mp_qcode is the quickcode
02362          * \return nothing throw an Exception
02363          */
02364 
02365         public function check_payment($e_mp, $e_mp_qcode)
02366         {
02367                 /*   Check if the "paid by" is empty, */
02368                 if ($e_mp != 0)
02369                 {
02370                         /* the paid by is not empty then check if valid */
02371                         $empl = new Fiche($this->db);
02372                         $empl->get_by_qcode($e_mp_qcode);
02373                         if ($empl->empty_attribute(ATTR_DEF_ACCOUNT) == true)
02374                         {
02375                                 throw new Exception(_("Celui qui paie n' a pas de poste comptable"), 20);
02376                         }
02377                         /* get the account and explode if necessary */
02378                         $sposte = $empl->strAttribut(ATTR_DEF_ACCOUNT);
02379                         // if 2 accounts, take only the debit one for customer
02380                         if (strpos($sposte, ',') != 0)
02381                         {
02382                                 $array = explode(',', $sposte);
02383                                 $poste_val = $array[0];
02384                         }
02385                         else
02386                         {
02387                                 $poste_val = $sposte;
02388                         }
02389                         $poste = new Acc_Account_Ledger($this->db, $poste_val);
02390                         if ($poste->load() == false)
02391                         {
02392                                 throw new Exception(sprintf(_("Pour la fiche %s le poste comptable [%s] n'existe pas"),$empl->quick_code,$poste->id  ), 9);
02393                         }
02394                 }
02395         }
02396 
02397         /**
02398          * @brief increment the sequence for the pj */
02399 
02400         function inc_seq_pj()
02401         {
02402                 $sql = "select nextval('s_jrn_pj" . $this->id . "')";
02403                 $this->db->exec_sql($sql);
02404         }
02405 
02406         /**
02407          * @brief return a HTML string with the form for the search
02408          * @param $p_type if the type of ledger possible values=ALL,VEN,ACH,ODS,FIN
02409          * @param $all_type_ledger
02410          *       values :
02411          *         - 1 means all the ledger of this type
02412          *         - 0 No have the "Tous les journaux" availables
02413          * @param $div is the div (for reconciliation)
02414          * @return a HTML String without the tag FORM or DIV
02415          *
02416          * @see build_search_sql
02417          * @see display_search_form
02418          * @see list_operation
02419          */
02420 
02421         function search_form($p_type, $all_type_ledger = 1, $div = "")
02422         {
02423             global $g_user;
02424             $r="";
02425                 $bledger_param=  json_encode(array(
02426                     'dossier'=>$_REQUEST['gDossier'],
02427                     'type'=>$p_type,
02428                     'all_type'=>$all_type_ledger,
02429                     'div'=>$div
02430                     ));
02431                 
02432                 $bledger_param=  str_replace('"', "'", $bledger_param);
02433                 $bledger=new ISmallButton('l');
02434                 $bledger->label="choix des journaux";
02435                 $bledger->javascript=" show_ledger_choice($bledger_param)";
02436                 $f_ledger=$bledger->input();
02437                 $hid_jrn="";
02438                 if ( isset ($_REQUEST[$div.'nb_jrn']) ){
02439                     for ($i=0;$i < $_REQUEST[$div.'nb_jrn'];$i++) {
02440                         if ( isset ($_REQUEST[$div."r_jrn"][$i]))
02441                             $hid_jrn.=HtmlInput::hidden($div.'r_jrn['.$i.']',$_REQUEST[$div."r_jrn"][$i]);
02442                     }
02443                     $hid_jrn.=HtmlInput::hidden($div.'nb_jrn',$_REQUEST[$div.'nb_jrn']);
02444                 } else {
02445                     $hid_jrn=HtmlInput::hidden($div.'nb_jrn',0);
02446                 }
02447                 /* Compute date for exercice */
02448                 $period = $g_user->get_periode();
02449                 $per = new Periode($this->db, $period);
02450                 $exercice = $per->get_exercice();
02451                 list($per_start, $per_end) = $per->get_limit($exercice);
02452                 $date_end = $per_end->last_day();
02453                 $date_start=$per_start->first_day();
02454                         
02455                 /* widget for date_start */
02456                 $f_date_start = new IDate('date_start');
02457                 /* all periode or only the selected one */
02458                 if (isset($_REQUEST['date_start']))
02459                 {
02460                         $f_date_start->value = $_REQUEST['date_start'];
02461                 }
02462                 else
02463                 {
02464                         $f_date_start->value=$date_start;
02465                 }
02466 
02467                 /* widget for date_end */
02468                 $f_date_end = new IDate('date_end');
02469                 /* all date or only the selected one */
02470                 if (isset($_REQUEST['date_end']))
02471                 {
02472                         $f_date_end->value = $_REQUEST['date_end'];
02473                 }
02474                 else
02475                 {
02476                         $f_date_end->value = $date_end;
02477                 }
02478                 /* widget for date term */
02479                 $f_date_paid_start=new IDate('date_paid_start');
02480                 $f_date_paid_end=new IDate('date_paid_end');
02481                 
02482                 $f_date_paid_start->value=(isset($_REQUEST['date_paid_start']))?$_REQUEST['date_paid_start']:'';
02483                 $f_date_paid_end->value=(isset($_REQUEST['date_paid_end']))?$_REQUEST['date_paid_end']:'';
02484                 
02485                 /* widget for desc */
02486                 $f_descript = new IText('desc');
02487                 $f_descript->size = 40;
02488                 if (isset($_REQUEST['desc']))
02489                 {
02490                         $f_descript->value = $_REQUEST['desc'];
02491                 }
02492 
02493                 /* widget for amount */
02494                 $f_amount_min = new INum('amount_min');
02495                 $f_amount_min->value = (isset($_REQUEST['amount_min'])) ? abs($_REQUEST['amount_min']) : 0;
02496                 $f_amount_max = new INum('amount_max');
02497                 $f_amount_max->value = (isset($_REQUEST['amount_max'])) ? abs($_REQUEST['amount_max']) : 0;
02498 
02499                 /* input quick code */
02500                 $f_qcode = new ICard('qcode' . $div);
02501 
02502                 $f_qcode->set_attribute('typecard', 'all');
02503                 /*        $f_qcode->set_attribute('p_jrn','0');
02504 
02505                   $f_qcode->set_callback('filter_card');
02506                  */
02507                 $f_qcode->set_dblclick("fill_ipopcard(this);");
02508                 // Add the callback function to filter the card on the jrn
02509                 //$f_qcode->set_callback('filter_card');
02510                 $f_qcode->set_function('fill_data');
02511                 $f_qcode->javascript = sprintf(' onchange="fill_data_onchange(%s);" ', $f_qcode->name);
02512                 $f_qcode->value = (isset($_REQUEST['qcode' . $div])) ? $_REQUEST['qcode' . $div] : '';
02513 
02514                 /*        $f_txt_qcode=new IText('qcode');
02515                   $f_txt_qcode->value=(isset($_REQUEST['qcode']))?$_REQUEST['qcode']:'';
02516                  */
02517 
02518                 /* input poste comptable */
02519                 $f_accounting = new IPoste('accounting');
02520                 $f_accounting->value = (isset($_REQUEST['accounting'])) ? $_REQUEST['accounting'] : '';
02521                 if ($this->id == -1)
02522                         $jrn = 0;
02523                 else
02524                         $jrn = $this->id;
02525                 $f_accounting->set_attribute('jrn', $jrn);
02526                 $f_accounting->set_attribute('ipopup', 'ipop_account');
02527                 $f_accounting->set_attribute('label', 'ld');
02528                 $f_accounting->set_attribute('account', 'accounting');
02529                 $info = HtmlInput::infobulle(13);
02530 
02531                 $f_paid = new ICheckbox('unpaid');
02532                 $f_paid->selected = (isset($_REQUEST['unpaid'])) ? true : false;
02533 
02534                 $r.=dossier::hidden();
02535                 $r.=HtmlInput::hidden('ledger_type', $this->type);
02536                 $r.=HtmlInput::hidden('ac', $_REQUEST['ac']);
02537                 ob_start();
02538                 require_once('template/ledger_search.php');
02539                 $r.=ob_get_contents();
02540                 ob_end_clean();
02541                 return $r;
02542         }
02543 
02544         /**
02545          * @brief this function will create a sql stmt to use to create the list for
02546          * the ledger,
02547          * @param$p_array is usually the $_GET,
02548          * @param$p_order the order of the row
02549          * @param$p_where is the sql condition if not null then the $p_array will not be used
02550          * \note the p_action will be used to filter the ledger but gl means ALL
02551          * struct array $p_array
02552           \verbatim
02553           (
02554           [gDossier] => 13
02555           [p_jrn] => -1
02556           [date_start] =>
02557           [date_end] =>
02558           [amount_min] => 0
02559           [amount_max] => 0
02560           [desc] =>
02561           [search] => Rechercher
02562           [p_action] => ven
02563           [sa] => l
02564           )
02565           \endverbatim
02566          * \return an array with a valid sql statement, an the where clause => array[sql] array[where]
02567          * \see list_operation
02568          * \see display_search_form
02569          * \see search_form
02570          */
02571 
02572         public function build_search_sql($p_array, $p_order = "", $p_where = "")
02573         {
02574                 $sql = "select jr_id    ,
02575              jr_montant,
02576              substr(jr_comment,1,60) as jr_comment,
02577              to_char(jr_ech,'DD.MM.YY') as str_jr_ech,
02578              to_char(jr_date,'DD.MM.YY') as str_jr_date,
02579              jr_date as jr_date_order,
02580              jr_grpt_id,
02581              jr_rapt,
02582              jr_internal,
02583              jrn_def_id,
02584              jrn_def_name,
02585              jrn_def_ech,
02586              jrn_def_type,
02587              jr_valid,
02588              jr_tech_per,
02589              jr_pj_name,
02590              p_closed,
02591              jr_pj_number,
02592              n_text,
02593              case
02594              when jrn_def_type='VEN' then
02595                  (select ad_value from fiche_detail where ad_id=1
02596                  and f_id=(select max(qs_client) from quant_sold join jrnx using (j_id) join jrn as e on (e.jr_grpt_id=j_grpt) where e.jr_id=x.jr_id))
02597             when jrn_def_type = 'ACH' then
02598                 (select ad_value from fiche_detail where ad_id=1
02599                 and f_id=(select max(qp_supplier) from quant_purchase join jrnx using (j_id) join jrn as e on (e.jr_grpt_id=j_grpt) where e.jr_id=x.jr_id))
02600             when jrn_def_type = 'FIN' then
02601                 (select ad_value from fiche_detail where ad_id=1
02602                 and f_id=(select qf_other from quant_fin where quant_fin.jr_id=x.jr_id))
02603             end as name,
02604            case
02605              when jrn_def_type='VEN' then (select ad_value from fiche_detail where ad_id=32 and f_id=(select max(qs_client) from quant_sold join jrnx using (j_id) join jrn as e on (e.jr_grpt_id=j_grpt) where e.jr_id=x.jr_id))
02606             when jrn_def_type = 'ACH' then (select ad_value from fiche_detail where ad_id=32 and f_id=(select max(qp_supplier) from quant_purchase join jrnx using (j_id) join jrn as e on (e.jr_grpt_id=j_grpt) where e.jr_id=x.jr_id))
02607             when jrn_def_type = 'FIN' then (select ad_value from fiche_detail where ad_id=32 and f_id=(select qf_other from quant_fin where quant_fin.jr_id=x.jr_id))
02608             end as first_name,
02609             case
02610              when jrn_def_type='VEN' then (select ad_value from fiche_detail where ad_id=23 and f_id=(select max(qs_client) from quant_sold join jrnx using (j_id) join jrn as e on (e.jr_grpt_id=j_grpt) where e.jr_id=x.jr_id))
02611             when jrn_def_type = 'ACH' then (select ad_value from fiche_detail where ad_id=23 and f_id=(select max(qp_supplier) from quant_purchase join jrnx using (j_id) join jrn as e on (e.jr_grpt_id=j_grpt) where e.jr_id=x.jr_id))
02612             when jrn_def_type = 'FIN' then (select ad_value from fiche_detail where ad_id=23 and f_id=(select qf_other from quant_fin where quant_fin.jr_id=x.jr_id))
02613             end as quick_code,
02614             case
02615              when jrn_def_type='VEN' then
02616                      (select sum(qs_price)+sum(vat) from
02617                                 (select qs_internal,qs_price,case when qs_vat_sided<>0 then 0 else qs_vat end as vat from quant_sold where qs_internal=X.jr_internal) as ven_invoice
02618                           )
02619             when jrn_def_type = 'ACH' then
02620                         (
02621                                 select sum(qp_price)+sum(vat)+sum(qp_nd_tva)+sum(qp_nd_tva_recup)
02622                                 from
02623                                  (select qp_internal,qp_price,qp_nd_tva,qp_nd_tva_recup,case when qp_vat_sided<>0 then 0 else qp_vat end as vat from quant_purchase where qp_internal=X.jr_internal) as invoice_purchase
02624                         )
02625                 else null
02626                 end as total_invoice,
02627             jr_date_paid,
02628             to_char(jr_date_paid,'DD.MM.YY') as str_jr_date_paid
02629              from
02630              jrn as X left join jrn_note using(jr_id)
02631              join jrn_def on jrn_def_id=jr_def_id
02632              join parm_periode on p_id=jr_tech_per";
02633 
02634                 if (!empty($p_array))
02635                         extract($p_array);
02636 
02637                 if (isset($op) ) 
02638                     $r_jrn = (isset(${$op."r_jrn"})) ? ${$op."r_jrn"} : -1;
02639                 else
02640                 {
02641                     $r_jrn = (isset($r_jrn)) ? $r_jrn : -1;
02642                     
02643                 }
02644 
02645                 /* if no variable are set then give them a default
02646                  * value */
02647                 if ($p_array == null || empty($p_array) || !isset($amount_min))
02648                 {
02649                         $amount_min = 0;
02650                         $amount_max = 0;
02651 
02652                         $desc = '';
02653                         $qcode = (isset($qcode)) ? $qcode : "";
02654                         if (isset($qcodesearch_op))
02655                                 $qcode = $qcodesearch_op;
02656                         $accounting = (isset($accounting)) ? $accounting : "";
02657                         $periode = new Periode($this->db);
02658                         $g_user = new User($this->db);
02659                         $p_id = $g_user->get_periode();
02660                         if ($p_id != null)
02661                         {
02662                                 list($date_start, $date_end) = $periode->get_date_limit($p_id);
02663                         }
02664                 }
02665 
02666                 /* if p_jrn : 0 if means all ledgers, if -1 means all ledger of this
02667                  *  type otherwise only one ledger */
02668                 $fil_ledger = '';
02669                 $fil_amount = '';
02670                 $fil_date = '';
02671                 $fil_desc = '';
02672                 $fil_sec = '';
02673                 $fil_qcode = '';
02674                 $fil_account = '';
02675                 $fil_paid = '';
02676                 $fil_date_paid='';
02677 
02678                 $and = '';
02679                 $g_user = new User($this->db);
02680                 $p_action = $ledger_type;
02681                 if ($p_action == '')
02682                         $p_action = 'ALL';
02683                 if ($r_jrn == -1)
02684                 {
02685 
02686                         /* from compta.php the p_action is quick_writing instead of ODS  */
02687                         if ($p_action == 'quick_writing')
02688                                 $p_action = 'ODS';
02689 
02690 
02691                         $fil_ledger = $g_user->get_ledger_sql($p_action, 3);
02692                         $and = ' and ';
02693                 }
02694                 else
02695                 {
02696 
02697                         if ($p_action == 'quick_writing')
02698                                 $p_action = 'ODS';
02699 
02700                         $aLedger = $g_user->get_ledger($p_action, 3);
02701                         $fil_ledger = '';
02702                         $sp = '';
02703                         for ($i = 0; $i < count($r_jrn); $i++)
02704                         {
02705                                 if (isset($r_jrn[$i]) )
02706                                 {
02707                                     $a=$r_jrn[$i];
02708                                     $fil_ledger.=$sp . $a;
02709                                     $sp = ',';
02710                                 }
02711                         }
02712                         $fil_ledger = ' jrn_def_id in (' . $fil_ledger . ')';
02713                         $and = ' and ';
02714 
02715                         /* no ledger selected */
02716                         if ($sp == '')
02717                         {
02718                                 $fil_ledger = '';
02719                                 $and = '';
02720                         }
02721                 }
02722 
02723                 /* format the number */
02724                 $amount_min = abs(toNumber($amount_min));
02725                 $amount_max = abs(toNumber($amount_max));
02726                 if ($amount_min > 0 && isNumber($amount_min))
02727                 {
02728                         $fil_amount = $and . ' jr_montant >=' . $amount_min;
02729                         $and = ' and ';
02730                 }
02731                 if ($amount_max > 0 && isNumber($amount_max))
02732                 {
02733                         $fil_amount.=$and . ' jr_montant <=' . $amount_max;
02734                         $and = ' and ';
02735                 }
02736                 /* -------------------------------------------------------------------------- *
02737                  * if both amount are the same then we need to search into the detail
02738                  * and we reset the fil_amount
02739                  * -------------------------------------------------------------------------- */
02740                 if (isNumber($amount_min) &&
02741                                 isNumber($amount_max) &&
02742                                 $amount_min > 0 &&
02743                                 bccomp($amount_min, $amount_max, 2) == 0)
02744                 {
02745                         $fil_amount = $and . 'jr_grpt_id in  ( select distinct j_grpt from jrnx where j_montant = ' . $amount_min . ')';
02746                         $and = " and ";
02747                 }
02748                 // date
02749                 if (isset($date_start) && isDate($date_start) != null)
02750                 {
02751                         $fil_date = $and . " jr_date >= to_date('" . $date_start . "','DD.MM.YYYY')";
02752                         $and = " and ";
02753                 }
02754                 if (isset($date_end) && isDate($date_end) != null)
02755                 {
02756                         $fil_date.=$and . " jr_date <= to_date('" . $date_end . "','DD.MM.YYYY')";
02757                         $and = " and ";
02758                 }
02759                 // date paiement
02760                 if (isset($date_paid_start) && isDate($date_paid_start) != null)
02761                 {
02762                         $fil_date_paid = $and . " jr_date_paid >= to_date('" . $date_paid_start . "','DD.MM.YYYY')";
02763                         $and = " and ";
02764                 }
02765                 if (isset($date_paid_end) && isDate($date_paid_end) != null)
02766                 {
02767                         $fil_date_paid.=$and . " jr_date_paid <= to_date('" . $date_paid_end . "','DD.MM.YYYY')";
02768                         $and = " and ";
02769                 }
02770                 // comment
02771                 if (isset($desc) && $desc != null)
02772                 {
02773                         $desc = sql_string($desc);
02774                         $fil_desc = $and . " ( upper(jr_comment) like upper('%" . $desc . "%') or upper(jr_pj_number) like upper('%" . $desc . "%') " .
02775                                         " or upper(jr_internal)  like upper('%" . $desc . "%')
02776                           or jr_grpt_id in (select j_grpt from jrnx where j_text ~* '" . $desc . "')
02777                           or jr_id in (select jr_id from jrn_info where ji_value is not null and ji_value ~* '$desc')
02778                           )";
02779                         $and = " and ";
02780                 }
02781                 //    Poste
02782                 if (isset($accounting) && $accounting != null)
02783                 {
02784                         $fil_account = $and . "  jr_grpt_id in (select j_grpt
02785                          from jrnx where j_poste::text like '" . sql_string($accounting) . "%' )  ";
02786                         $and = " and ";
02787                 }
02788                 // Quick Code
02789                 if (isset($qcodesearch_op))
02790                         $qcode = $qcodesearch_op;
02791                 if (isset($qcode) && $qcode != null)
02792                 {
02793                         $fil_qcode = $and . "  jr_grpt_id in ( select j_grpt from
02794                        jrnx where trim(j_qcode) = upper(trim('" . sql_string($qcode) . "')))";
02795                         $and = " and ";
02796                 }
02797 
02798                 // Only the unpaid
02799                 if (isset($unpaid))
02800                 {
02801                         $fil_paid = $and . SQL_LIST_UNPAID_INVOICE;
02802                         $and = " and ";
02803                 }
02804 
02805                 $g_user = new User(new Database());
02806                 $g_user->Check();
02807                 $g_user->check_dossier(dossier::id());
02808 
02809                 if ($g_user->admin == 0 && $g_user->is_local_admin() == 0)
02810                 {
02811                         $fil_sec = $and . " jr_def_id in ( select uj_jrn_id " .
02812                                         " from user_sec_jrn where " .
02813                                         " uj_login='" . $_SESSION['g_user'] . "'" .
02814                                         " and uj_priv in ('R','W'))";
02815                 }
02816                 $where = $fil_ledger . $fil_amount . $fil_date . $fil_desc . $fil_sec . $fil_amount . $fil_qcode . $fil_paid . $fil_account.$fil_date_paid;
02817                 $sql.=" where " . $where;
02818                 return array($sql, $where);
02819         }
02820 
02821         /**
02822          * @brief return a html string with the search_form
02823          * \return a HTML string with the FORM
02824          * \see build_search_sql
02825          * \see search_form
02826          * \see list_operation
02827          */
02828 
02829         function display_search_form()
02830         {
02831                 $r = '';
02832                 $type = $this->type;
02833 
02834                 if ($type == "")
02835                         $type = 'ALL';
02836                 $r.='<div id="search_form" style="display:none">';
02837                 $r.=HtmlInput::anchor_hide('Fermer', '$(\'search_form\').style.display=\'none\';');
02838                 $r.=h2('Recherche','class="title"');
02839                 $r.='<FORM METHOD="GET">';
02840                 $r.=$this->search_form($type);
02841                 $r.=HtmlInput::submit('search', _('Rechercher'));
02842                 $r.=HtmlInput::hidden('ac', $_REQUEST['ac']);
02843 
02844                 /*  when called from commercial.php some hidden values are needed */
02845                 if (isset($_REQUEST['sa']))
02846                         $r.= HtmlInput::hidden("sa", $_REQUEST['sa']);
02847                 if (isset($_REQUEST['sb']))
02848                         $r.= HtmlInput::hidden("sb", $_REQUEST['sb']);
02849                 if (isset($_REQUEST['sc']))
02850                         $r.= HtmlInput::hidden("sc", $_REQUEST['sc']);
02851                 if (isset($_REQUEST['f_id']))
02852                         $r.=HtmlInput::hidden("f_id", $_REQUEST['f_id']);
02853                 $r.=HtmlInput::button_anchor(_('Fermer'), 'javascript:void(0)', 'fsearch_form', 'onclick="$(\'search_form\').style.display=\'none\';"','smallbutton');
02854 
02855                 $r.='</FORM>';
02856 
02857                 $r.='</div>';
02858                 $button = new IButton('tfs');
02859                 $button->label = _("Filtrer");
02860                 $button->javascript = "toggleHideShow('search_form','tfs');";
02861 
02862                 $r.=$button->input();
02863                 $r.='<hr>';
02864                 return $r;
02865         }
02866 
02867         /**
02868          * @brief return the last p_limit operation into an array
02869          * @param$p_limit is the max of operation to return
02870          * \return $p_array of Follow_Up object
02871          */
02872 
02873         function get_last($p_limit)
02874         {
02875                 global $g_user;
02876                 $filter_ledger = $g_user->get_ledger_sql('ALL', 3);
02877                 $filter_ledger = str_replace('jrn_def_id', 'jr_def_id', $filter_ledger);
02878                 $sql = "
02879                         select jr_id,jr_pj_number,jr_date,to_char(jr_date,'DD.MM.YYYY') as jr_date_fmt,jr_montant, jr_comment,jr_internal,jrn_def_code
02880                         from jrn
02881                         join jrn_def on (jrn_def_id=jr_def_id)
02882                          where $filter_ledger
02883                         order by jr_date desc limit $p_limit";
02884                 $array = $this->db->get_array($sql);
02885                 return $array;
02886         }
02887 
02888         /**
02889          * @brief retreive the jr_grpt_id from a ledger
02890          * @param $p_what the column to seek
02891          *    possible values are
02892          *   - internal
02893          * @param $p_value the value of the col.
02894          */
02895         function search_group($p_what, $p_value)
02896         {
02897                 switch ($p_what)
02898                 {
02899                         case 'internal':
02900                                 return $this->db->get_value('select jr_grpt_id from jrn where jr_internal=$1', array($p_value));
02901                 }
02902         }
02903 
02904         /**
02905          * @brief retrieve operation from  jrn
02906          * @param $p_from periode (id)
02907          * @param $p_to periode (id)
02908          * @return an array
02909          */
02910         function get_operation($p_from, $p_to)
02911         {
02912                 global $g_user;
02913                 $jrn = ($this->id == 0) ? 'and ' . $g_user->get_ledger_sql() : ' and jr_def_id = ' . $this->id;
02914                 $sql = "select jr_id as id ,jr_internal as internal, " .
02915                                 "jr_pj_number as pj,jr_grpt_id," .
02916                                 " to_char(jr_date,'DDMMYY') as date_fmt, " .
02917                                 " jr_comment as comment, jr_montant as montant ," .
02918                                 " jr_grpt_id,jr_def_id" .
02919                                 " from jrn join jrn_def on (jr_def_id=jrn_def_id) where  " .
02920                                 " jr_date >= (select p_start from parm_periode where p_id = $1)
02921                                  and  jr_date <= (select p_end from parm_periode where p_id  = $2)" .
02922                                 '  ' . $jrn . ' order by jr_date,substring(jr_pj_number,\'[0-9]+$\')::numeric asc';
02923                 $ret = $this->db->get_array($sql, array($p_from, $p_to));
02924                 return $ret;
02925         }
02926 
02927         /**
02928          * @brief return the used VAT code with a rate > 0
02929          * @return an array of tva_id,tva_label,tva_poste
02930          */
02931         public function existing_vat()
02932         {
02933                 if ($this->type == 'ACH')
02934                 {
02935                         $array = $this->db->get_array("select tva_id,tva_label,tva_poste from tva_rate where tva_rate != 0.0000 " .
02936                                         " and  exists (select qp_vat_code from quant_purchase
02937                                         where  qp_vat_code=tva_id and  exists (select j_id from jrnx where j_jrn_def = $1)) order by tva_id", array($this->id));
02938                 }
02939                 if ($this->type == 'VEN')
02940                 {
02941                         $array = $this->db->get_array("select tva_id,tva_label,tva_poste from tva_rate where tva_rate != 0.0000 " .
02942                                         " and  exists (select qs_vat_code from quant_sold
02943                                         where  qs_vat_code=tva_id and  exists (select j_id from jrnx where j_jrn_def = $1)) order by tva_id", array($this->id));
02944                 }
02945                 return $array;
02946         }
02947 
02948         /**
02949          * @brief get the amount of vat for a given jr_grpt_id from the table
02950          * quant_purchase
02951          * @param the jr_grpt_id
02952          * @return array price=htva, [1] =  vat,
02953          * @note
02954          * @see
02955           @code
02956           array
02957           'price' => string '91.3500' (length=7)
02958           'vat' => string '0.0000' (length=6)
02959           'priv' => string '0.0000' (length=6)
02960           'tva_nd_recup' => string '0.0000' (length=6)
02961 
02962           @endcode
02963          */
02964         function get_other_amount($p_jr_id)
02965         {
02966                 if ($this->type == 'ACH')
02967                 {
02968                         $array = $this->db->get_array('select sum(qp_price) as price,sum(qp_vat) as vat ' .
02969                                         ',coalesce(sum(qp_nd_amount),0)+coalesce(sum(qp_dep_priv),0) as priv' .
02970                                         ',sum(qp_nd_tva_recup)+sum(qp_nd_tva) as tva_nd' .
02971                                         '  from quant_purchase join jrnx using(j_id)
02972                                         where  j_grpt=$1 ', array($p_jr_id));
02973                         $ret = $array[0];
02974                 }
02975                 if ($this->type == 'VEN')
02976                 {
02977                         $array = $this->db->get_array('select sum(qs_price) as price,sum(qs_vat) as vat ' .
02978                                         ',0 as priv' .
02979                                         ',0 as tva_nd' .
02980                                         '  from quant_sold join jrnx using(j_id)
02981                                         where  j_grpt=$1 ', array($p_jr_id));
02982                         $ret = $array[0];
02983                 }
02984                 return $ret;
02985         }
02986 
02987         /**
02988          * @brief get the amount of vat for a given jr_grpt_id from the table
02989          * quant_purchase
02990          * @param the jr_grpt_id
02991          * @return array of sum_vat, tva_label
02992          * @note
02993          * @see
02994           @code
02995 
02996           @endcode
02997          */
02998         function vat_operation($p_jr_id)
02999         {
03000                 if ($this->type == 'ACH')
03001                 {
03002                         $array = $this->db->get_array('select coalesce(sum(qp_vat),0) as sum_vat,tva_id
03003                                         from quant_purchase as p right join tva_rate on (qp_vat_code=tva_id)  join jrnx using(j_id)
03004                                         where tva_rate !=0.0 and j_grpt=$1 group by tva_id', array($p_jr_id));
03005                 }
03006                 if ($this->type == 'VEN')
03007                 {
03008                         $array = $this->db->get_array('select coalesce(sum(qs_vat),0) as sum_vat,tva_id
03009                                         from quant_sold as p right join tva_rate on (qs_vat_code=tva_id)  join jrnx using(j_id)
03010                                         where tva_rate !=0.0 and j_grpt=$1 group by tva_id', array($p_jr_id));
03011                 }
03012                 return $array;
03013         }
03014 
03015         /**
03016          * @brief retrieve amount of previous periode
03017          * @param $p_to frmo the start of the exercise until $p_to
03018          * @return $array with vat, price,other_amount
03019          * @note
03020          * @see
03021           @code
03022           array
03023           'price' => string '446.1900' (length=8)
03024           'vat' => string '21.7600' (length=7)
03025           'priv' => string '0.0000' (length=6)
03026           'tva_nd_recup' => string '0.0000' (length=6)
03027           'tva' =>
03028           array
03029           0 =>
03030           array
03031           'sum_vat' => string '13.7200' (length=7)
03032           'tva_id' => string '1' (length=1)
03033           1 =>
03034           array
03035           'sum_vat' => string '8.0400' (length=6)
03036           'tva_id' => string '3' (length=1)
03037           2 =>
03038           array
03039           'sum_vat' => string '0.0000' (length=6)
03040           'tva_id' => string '4' (length=1)
03041 
03042           @endcode
03043          */
03044         function previous_amount($p_to)
03045         {
03046                 /* get the first periode of exercise */
03047                 $periode = new Periode($this->db, $p_to);
03048                 $exercise = $periode->get_exercice();
03049                 list ($min, $max) = $periode->get_limit($exercise);
03050                 // min periode
03051                 if ($this->type == 'ACH')
03052                 {
03053                         /*  get all amount exclude vat */
03054                         $sql = "select coalesce(sum(qp_price),0) as price" .
03055                                         " ,coalesce(sum(qp_vat),0) as vat " .
03056                                         ',coalesce(sum(qp_dep_priv),0) as priv' .
03057                                         ',coalesce(sum(qp_nd_tva_recup),0)+coalesce(sum(qp_nd_tva),0) as tva_nd' .
03058                                         '  from quant_purchase join jrnx using(j_id) ' .
03059                                         ' where j_tech_per >= $1 and j_tech_per < $2';
03060                         $array = $this->db->get_array($sql, array($min->p_id, $p_to));
03061 
03062                         $ret = $array[0];
03063                         /* retrieve all vat code */
03064                         $array = $this->db->get_array('select coalesce(sum(qp_vat),0) as sum_vat,tva_id
03065                                         from quant_purchase as p right join tva_rate on (qp_vat_code=tva_id)  join jrnx using(j_id)
03066                                         where tva_rate !=0 and j_tech_per >= $1 and j_tech_per < $2 group by tva_id', array($min->p_id, $p_to));
03067                         $ret['tva'] = $array;
03068                 }
03069                 if ($this->type == 'VEN')
03070                 {
03071                         /*  get all amount exclude vat */
03072                         $sql = "select coalesce(sum(qs_price),0) as price" .
03073                                         " ,coalesce(sum(qs_vat),0) as vat " .
03074                                         ',0 as priv' .
03075                                         ',0 as tva_nd' .
03076                                         '  from quant_sold join jrnx using(j_id) ' .
03077                                         ' where j_tech_per >= $1 and j_tech_per < $2';
03078                         $array = $this->db->get_array($sql, array($min->p_id, $p_to));
03079                         $ret = $array[0];
03080                         /* retrieve all vat code */
03081                         $array = $this->db->get_array('select coalesce(sum(qs_vat),0) as sum_vat,tva_id
03082                                         from quant_sold as p right join tva_rate on (qs_vat_code=tva_id)  join jrnx using(j_id)
03083                                         where tva_rate !=0 and j_tech_per >= $1 and j_tech_per < $2 group by tva_id', array($min->p_id, $p_to));
03084                         $ret['tva'] = $array;
03085                 }
03086                 return $ret;
03087         }
03088 
03089         ////////////////////////////////////////////////////////////////////////////////
03090         // TEST MODULE
03091         ////////////////////////////////////////////////////////////////////////////////
03092         /**
03093          * @brief this function is intended to test this class
03094          */
03095         static function test_me($pCase = '')
03096         {
03097                 if ($pCase == '')
03098                 {
03099                         echo Acc_Reconciliation::$javascript;
03100                         html_page_start();
03101                         $cn = new Database(dossier::id());
03102                         $_SESSION['g_user'] = 'phpcompta';
03103                         $_SESSION['g_pass'] = 'phpcompta';
03104 
03105                         $id = (isset($_REQUEST['p_jrn'])) ? $_REQUEST['p_jrn'] : -1;
03106                         $a = new Acc_Ledger($cn, $id);
03107                         $a->with_concerned = true;
03108                         // Vide
03109                         echo '<FORM method="post">';
03110                         echo $a->select_ledger()->input();
03111                         echo HtmlInput::submit('go', 'Test it');
03112                         echo '</form>';
03113                         if (isset($_POST['go']))
03114                         {
03115                                 echo "Ok ";
03116                                 echo '<form method="post">';
03117                                 echo $a->show_form();
03118                                 echo HtmlInput::submit('post_id', 'Try me');
03119                                 echo '</form>';
03120                                 // Show the predef operation
03121                                 // Don't forget the p_jrn
03122                                 echo '<form>';
03123                                 echo dossier::hidden();
03124                                 echo '<input type="hidden" value="' . $id . '" name="p_jrn">';
03125                                 $op = new Pre_operation($cn);
03126                                 $op->p_jrn = $id;
03127                                 $op->od_direct = 't';
03128                                 if ($op->count() != 0)
03129                                 {
03130                                         echo HtmlInput::submit('use_opd', 'Utilisez une opération pr&eacute;d&eacute;finie',"","smallbutton");
03131                                         echo $op->show_button();
03132                                 }
03133                                 echo '</form>';
03134                                 exit();
03135                         }
03136 
03137                         if (isset($_POST['post_id']))
03138                         {
03139 
03140                                 echo '<form method="post">';
03141                                 echo $a->show_form($_POST, 1);
03142                                 echo HtmlInput::button('add', 'Ajout d\'une ligne', 'onClick="quick_writing_add_row()"');
03143                                 echo HtmlInput::submit('save_it', "Sauver");
03144                                 echo '</form>';
03145                                 exit();
03146                         }
03147                         if (isset($_POST['save_it']))
03148                         {
03149                                 print 'saving';
03150                                 $array = $_POST;
03151                                 $array['save_opd'] = 1;
03152                                 try
03153                                 {
03154                                         $a->save($array);
03155                                 }
03156                                 catch (Exception $e)
03157                                 {
03158                                         alert($e->getMessage());
03159                                         echo '<form method="post">';
03160 
03161                                         echo $a->show_form($_POST);
03162                                         echo HtmlInput::submit('post_id', 'Try me');
03163                                         echo '</form>';
03164                                 }
03165                                 exit();
03166                         }
03167                         // The GET at the end because automatically repost when you don't
03168                         // specify the url in the METHOD field
03169                         if (isset($_GET['use_opd']))
03170                         {
03171                                 $op = new Pre_op_advanced($cn);
03172                                 $op->set_od_id($_REQUEST['pre_def']);
03173                                 //$op->p_jrn=$id;
03174 
03175                                 $p_post = $op->compute_array();
03176 
03177                                 echo '<FORM method="post">';
03178 
03179                                 echo $a->show_form($p_post);
03180                                 echo HtmlInput::submit('post_id', 'Use predefined operation');
03181                                 echo '</form>';
03182                                 exit();
03183                         }
03184                 }// if case = ''
03185                 ///////////////////////////////////////////////////////////////////////////
03186                 // search
03187                 if ($pCase == 'search')
03188                 {
03189                         html_page_start();
03190                         $cn = new Database(dossier::id());
03191                         $ledger = new Acc_Ledger($cn, 0);
03192                         $_SESSION['g_user'] = 'phpcompta';
03193                         $_SESSION['g_pass'] = 'phpcompta';
03194                         echo $ledger->search_form('ALL');
03195                 }
03196                 ///////////////////////////////////////////////////////////////////////////
03197                 // reverse
03198                 // Give yourself the var and check in your tables
03199                 ///////////////////////////////////////////////////////////////////////////
03200                 if ($pCase == 'reverse')
03201                 {
03202                         $cn = new Database(dossier::id());
03203                         $jr_internal = 'OD-01-272';
03204                         try
03205                         {
03206                                 $cn->start();
03207                                 $jrn_def_id = $cn->get_value('select jr_def_id from jrn where jr_internal=$1', array($jr_internal));
03208                                 $ledger = new Acc_Ledger($cn, $jrn_def_id);
03209                                 $ledger->jr_id = $cn->get_value('select jr_id from jrn where jr_internal=$1', array($jr_internal));
03210 
03211                                 echo "Ouvrez le fichier " . __FILE__ . " à la ligne " . __LINE__ . " pour changer jr_internal et vérifier le résultat de l'extourne";
03212 
03213                                 $ledger->reverse('01.07.2010');
03214                         }
03215                         catch (Exception $e)
03216                         {
03217                                 $cn->rollback();
03218                                 var_dump($e);
03219                         }
03220                         $cn->commit();
03221                 }
03222         }
03223 
03224         /**
03225          * create an array of the existing cat, to be used in a checkbox form
03226          *
03227          */
03228         static function array_cat()
03229         {
03230                 $r = array(
03231                         array('cat' => 'VEN', 'name' => _("Journaux de vente")),
03232                         array('cat' => 'ACH', 'name' => _("'Journaux d'achat")),
03233                         array('cat' => 'FIN', 'name' => _("'Journaux Financier")),
03234                         array('cat' => 'ODS', 'name' => _("'Journaux d'Opérations diverses"))
03235                 );
03236                 return $r;
03237         }
03238 
03239         /**
03240          * Retrieve the third : supplier for purchase, customer for sale, bank for fin,
03241          * @param $p_jrn_type type of the ledger FIN, VEN ACH or ODS
03242          */
03243         function get_tiers($p_jrn_type, $jr_id)
03244         {
03245                 if ($p_jrn_type == 'ODS')
03246                         return ' ';
03247                 $tiers = '';
03248                 switch ($p_jrn_type)
03249                 {
03250                         case 'VEN':
03251                                 $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));
03252                                 break;
03253                         case 'ACH':
03254                                 $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));
03255 
03256                                 break;
03257                         case 'FIN':
03258                                 $tiers = $this->db->get_value('select qf_other from quant_fin where jr_id=$1', array($jr_id));
03259                                 break;
03260                 }
03261                 if ($this->db->count() == 0)
03262                         return '';
03263                 $name = $this->db->get_value('select ad_value from fiche_detail where ad_id=1 and f_id=$1', array($tiers));
03264                 $first_name = $this->db->get_value('select ad_value from fiche_detail where ad_id=32 and f_id=$1', array($tiers));
03265                 return $name . ' ' . $first_name;
03266         }
03267 
03268         /**
03269          * @brief listing of all ledgers
03270          * @return HTML string
03271          */
03272         function listing()
03273         {
03274                 $str_dossier = dossier::get();
03275                 $base_url = "?" . dossier::get() . "&ac=" . $_REQUEST['ac'];
03276 
03277                 $r = "";
03278                 $r.='<TABLE>';
03279                 $r.='<TR><TD class="mtitle"><A class="mtitle" HREF="' . $base_url . '&sa=add">' . _('Création') . ' </A></TD></TR>';
03280                 $ret = $this->db->exec_sql("select distinct jrn_def_id,jrn_def_name,
03281                        jrn_def_class_deb,jrn_def_class_cred,jrn_def_type
03282                        from jrn_def order by jrn_def_name");
03283                 $Max = Database::num_row($ret);
03284 
03285 
03286                 for ($i = 0; $i < $Max; $i++)
03287                 {
03288                         $l_line = Database::fetch_array($ret, $i);
03289                         $url = $base_url . "&sa=detail&p_jrn=" . $l_line['jrn_def_id'];
03290                         $r.=sprintf('<TR><TD class="mtitle"><A class="mtitle" HREF="%s">%s</A></TD></TR>', $url, h($l_line['jrn_def_name']));
03291                 }
03292                 $r.= "</TABLE>";
03293                 return $r;
03294         }
03295 
03296         /**
03297          * display detail of a ledger
03298          *
03299          */
03300         function display_ledger()
03301         {
03302                 if ($this->load() == -1)
03303                 {
03304                         throw new Exception(_("Journal n'existe pas"), -1);
03305                 }
03306                 $type = $this->jrn_def_type;
03307                 $name = $this->jrn_def_name;
03308                 $code = $this->jrn_def_code;
03309                 $str_add_button="";
03310                 /* widget for searching an account */
03311                 $wSearch = new IPoste();
03312                 $wSearch->set_attribute('ipopup', 'ipop_account');
03313                 $wSearch->set_attribute('account', 'p_jrn_class_deb');
03314                 $wSearch->set_attribute('no_overwrite', '1');
03315                 $wSearch->set_attribute('noquery', '1');
03316                 $wSearch->table = 3;
03317                 $wSearch->name = "p_jrn_class_deb";
03318                 $wSearch->size = 20;
03319                 $wSearch->value = $this->jrn_def_class_deb;
03320                 $search = $wSearch->input();
03321 
03322                 $wPjPref = new IText();
03323                 $wPjPref->name = 'jrn_def_pj_pref';
03324                 $wPjPref->value = $this->jrn_def_pj_pref;
03325                 $pj_pref = $wPjPref->input();
03326 
03327                 $wPjSeq = new INum();
03328                 $wPjSeq->value = 0;
03329                 $wPjSeq->name = 'jrn_def_pj_seq';
03330                 $pj_seq = $wPjSeq->input();
03331                 $last_seq = $this->get_last_pj();
03332                 $name = $this->jrn_def_name;
03333 
03334                 $hidden = HtmlInput::hidden('p_jrn', $this->id);
03335                 $hidden.= HtmlInput::hidden('sa', 'detail');
03336                 $hidden.= dossier::hidden();
03337                 $hidden.=HtmlInput::hidden('p_jrn_deb_max_line', 10);
03338                 $hidden.=HtmlInput::hidden('p_ech_lib', 'echeance');
03339                 $hidden.=HtmlInput::hidden('p_jrn_type', $type);
03340 
03341                 $min_row = new INum("min_row",$this->jrn_deb_max_line);
03342                 $min_row->prec=0;
03343                 
03344                 $description=new ITextarea('p_description');
03345                 $description->value=$this->jrn_def_description;
03346                 $str_description=$description->input();
03347 
03348                 /* Load the card */
03349                 $card = $this->get_fiche_def();
03350                 $rdeb = explode(',', $card['deb']);
03351                 $rcred = explode(',', $card['cred']);
03352                 /* Numbering (only FIN) */
03353                 $num_op = new ICheckBox('numb_operation');
03354                 if ($this->jrn_def_num_op == 1)
03355                         $num_op->selected = true;
03356                 /* bank card */
03357                 $qcode_bank = '';
03358                 if ($type == 'FIN')
03359                 {
03360                         $f_id = $this->jrn_def_bank;
03361                         if (isNumber($f_id) == 1)
03362                         {
03363                                 $fBank = new Fiche($this->db, $f_id);
03364                                 $qcode_bank = $fBank->get_quick_code();
03365                         }
03366                 }
03367                 $new = 0;
03368                 $cn = $this->db;
03369                 echo $hidden;
03370                 require_once('template/param_jrn.php');
03371         }
03372 
03373         /**
03374          * Verify before update
03375          *
03376          * @param type $array
03377          *   'p_jrn' => string '3' (length=1)
03378           'sa' => string 'detail' (length=6)
03379           'gDossier' => string '82' (length=2)
03380           'p_jrn_deb_max_line' => string '10' (length=2)
03381           'p_ech_lib' => string 'echeance' (length=8)
03382           'p_jrn_type' => string 'ACH' (length=3)
03383           'p_jrn_name' => string 'Achat' (length=5)
03384           'jrn_def_pj_pref' => string 'ACH' (length=3)
03385           'jrn_def_pj_seq' => string '0' (length=1)
03386           'FICHECRED' =>
03387           array
03388           0 => string '4' (length=1)
03389           'FICHEDEB' =>
03390           array
03391           0 => string '7' (length=1)
03392           1 => string '5' (length=1)
03393           2 => string '13' (length=2)
03394           'update' => string 'Sauve' (length=5
03395          * @exception is throw is test are not valid
03396          */
03397         function verify_ledger($array)
03398         {
03399                 extract($array);
03400                 try
03401                 {
03402                         if (isNumber($p_jrn) == 0)
03403                                 throw new Exception("Id invalide");
03404                         if (isNumber($p_jrn_deb_max_line) == 0)
03405                                 throw new Exception(_("Nombre de ligne incorrect"));
03406                         if (trim($p_jrn_name) == "")
03407                                 throw new Exception("Nom de journal invalide");
03408                         if ($this->db->get_value("select count(*) from jrn_def where jrn_def_name=$1 and jrn_Def_id<>$2", array($p_jrn_name, $p_jrn)) > 0)
03409                                 throw new Exception(_("Un journal avec ce nom existe déjà"));
03410                         if ($p_jrn_type == 'FIN')
03411                         {
03412                                 $a = new Fiche($this->db);
03413                                 $result = $a->get_by_qcode(trim(strtoupper($_POST['bank'])), false);
03414                                 if ($result == 1)
03415                                         throw new Exception(_("Aucun compte en banque n'est donné"));
03416                         }
03417                 }
03418                 catch (Exception $e)
03419                 {
03420                         throw $e;
03421                 }
03422         }
03423 
03424         /**
03425          * update a ledger
03426          * @param type $array  normally post
03427          * @see verify_ledger
03428          */
03429         function update($array = '')
03430         {
03431                 if ($array == null)
03432                         throw new Exception('save cannot use a empty array');
03433 
03434                 extract($array);
03435                 $this->jrn_def_id = $p_jrn;
03436                 $this->jrn_def_name = $p_jrn_name;
03437                 $this->jrn_def_ech_lib = $p_ech_lib;
03438                 $this->jrn_def_max_line_deb = ($p_jrn_deb_max_line<1)?1:$p_jrn_deb_max_line;
03439                 $this->jrn_def_type = $p_jrn_type;
03440                 $this->jrn_def_pj_pref = $jrn_def_pj_pref;
03441                 $this->jrn_def_fiche_deb = (isset($FICHEDEB)) ? join($FICHEDEB, ',') : "";
03442                 $this->jrn_deb_max_line=($min_row<1)?1:$min_row;
03443                 $this->jrn_def_description=$p_description;
03444                 switch ($this->jrn_def_type)
03445                 {
03446                         case 'ACH':
03447                         case 'VEN':
03448                                 $this->jrn_def_fiche_cred = (isset($FICHECRED)) ? join($FICHECRED, ',') : '';
03449                                 break;
03450                         case 'ODS':
03451                                 $this->jrn_def_class_deb = $p_jrn_class_deb;
03452                                 $this->jrn_def_fiche_cred=null;
03453                                 break;
03454                         case 'FIN':
03455                                 $a = new Fiche($this->db);
03456                                 $result = $a->get_by_qcode(trim(strtoupper($_POST['bank'])), false);
03457                                 $bank = $a->id;
03458                                 $this->jrn_def_bank = $bank;
03459                                 if ($result == -1)
03460                                         throw new Exception(_("Aucun compte en banque n'est donné"));
03461                                 $this->jrn_def_num_op = (isset($numb_operation)) ? 1 : 0;
03462                                 break;
03463                 }
03464 
03465                 parent::update();
03466                 //Reset sequence if needed
03467                 if ($jrn_def_pj_seq != 0)
03468                 {
03469                         $Res = $this->db->alter_seq("s_jrn_pj" . $p_jrn, $jrn_def_pj_seq);
03470                 }
03471         }
03472 
03473         function input_paid()
03474         {
03475                 $r = '';
03476                 $r.='<div id="payment"> ';
03477                 $r.='<h2> ' . _('Payé par') . ' </h2>';
03478                 $mp = new Acc_Payment($this->db);
03479                 $mp->set_parameter('ledger_source', $this->id);
03480                 $r.=$mp->select();
03481                 $r.='</div>';
03482                 return $r;
03483         }
03484 
03485         /**
03486          * display screen to enter a new ledger
03487          */
03488         function input_new()
03489         {
03490                 global $g_user;
03491                 $f_add_button=new ISmallButton('add_card');
03492                 $f_add_button->label=_('Créer une nouvelle fiche');
03493                 $f_add_button->tabindex=-1;
03494                 $f_add_button->set_attribute('jrn',-1);
03495                 $f_add_button->javascript=" this.jrn=-1;select_card_type({type_cat:4});";
03496 
03497                 $str_add_button="";
03498                 if ($g_user->check_action(FICADD)==1)
03499                 {
03500                         $str_add_button=$f_add_button->input();
03501                 }
03502                 $wSearch = new IPoste();
03503                 $wSearch->table = 3;
03504                 $wSearch->set_attribute('ipopup', 'ipop_account');
03505                 $wSearch->set_attribute('account', 'p_jrn_class_deb');
03506                 $wSearch->set_attribute('no_overwrite', '1');
03507                 $wSearch->set_attribute('noquery', '1');
03508 
03509                 $wSearch->name = "p_jrn_class_deb";
03510                 $wSearch->size = 20;
03511 
03512                 $search = $wSearch->input();
03513 
03514                 /* construct all the hidden */
03515                 $hidden = HtmlInput::hidden('p_jrn', -1);
03516                 $hidden.= HtmlInput::hidden('p_action', 'jrn');
03517                 $hidden.= HtmlInput::hidden('sa', 'add');
03518                 $hidden.= dossier::hidden();
03519                 $hidden.=HtmlInput::hidden('p_jrn_deb_max_line', 10);
03520                 $hidden.=HtmlInput::hidden('p_ech_lib', 'echeance');
03521 
03522                 /* properties of the ledger */
03523                 $name = "";
03524                 $code = "";
03525                 $wType = new ISelect();
03526                 $a_jrn= $this->db->make_array("select '-1',' -- "._("choix du type de journal")." -- ' union select jrn_type_id,jrn_desc from jrn_type");
03527                 $wType->selected='-1';
03528                 $wType->value =$a_jrn;
03529                 $wType->name = "p_jrn_type";
03530                 $wType->id= "p_jrn_type_select_id";
03531                 $wType->javascript=' onchange="show_ledger_div()"';
03532                 $type = $wType->input();
03533                 $rcred = $rdeb = array();
03534                 $wPjPref = new IText();
03535                 $wPjPref->name = 'jrn_def_pj_pref';
03536                 $pj_pref = $wPjPref->input();
03537                 $pj_seq = '';
03538                 $last_seq = 0;
03539                 $new = 1;
03540                 $description=new ITextarea('p_description');
03541                 $description->value="";
03542                 $str_description=$description->input();
03543                 /* bank card */
03544                 $qcode_bank = '';
03545                 /* Numbering (only FIN) */
03546                 $num_op = new ICheckBox('numb_operation');
03547                 echo dossier::hidden();
03548                 echo HtmlInput::hidden('ac', $_REQUEST['ac']);
03549                 echo $hidden;
03550                 
03551                 $cn = $this->db;
03552                 $min_row = new INum("min_row",MAX_ARTICLE);
03553                 $min_row->prec=0;
03554                 require_once('template/param_jrn.php');
03555         }
03556 
03557         /**
03558          * Insert a new ledger
03559          * @param type $array normally $_POST
03560          * @see verify_ledger
03561          */
03562         function save_new($array)
03563         {
03564                 $this->load();
03565                 extract($array);
03566                 $this->jrn_def_id = -1;
03567                 $this->jrn_def_name = $p_jrn_name;
03568                 $this->jrn_def_ech_lib = $p_ech_lib;
03569                 $this->jrn_def_max_line_deb = $p_jrn_deb_max_line;
03570                 $this->jrn_def_type = $p_jrn_type;
03571                 $this->jrn_def_pj_pref = $jrn_def_pj_pref;
03572                 $this->jrn_def_fiche_deb = (isset($FICHEDEB)) ? join($FICHEDEB, ',') : "";
03573                 $this->jrn_deb_max_line=$min_row;
03574                 $this->jrn_def_code = sprintf("%s%02d", trim(substr($this->jrn_def_type, 0, 1)), Acc_Ledger::next_number($this->db, $this->jrn_def_type));
03575                 $this->jrn_def_description=$p_description;
03576                 switch ($this->jrn_def_type)
03577                 {
03578                         case 'ACH':
03579                         case 'VEN':
03580                                 $this->jrn_def_fiche_cred = (isset($FICHECRED)) ? join($FICHECRED, ',') : '';
03581 
03582                                 break;
03583                         case 'ODS':
03584                                 $this->jrn_def_class_deb = $p_jrn_class_deb;
03585                                 $this->jrn_def_fiche_cred = null;
03586                                 break;
03587                         case 'FIN':
03588                                 $a = new Fiche($this->db);
03589                                 $result = $a->get_by_qcode(trim(strtoupper($_POST['bank'])), false);
03590                                 $bank = $a->id;
03591                                 $this->jrn_def_bank = $bank;
03592                                 if ($result == -1)
03593                                         throw new Exception(_("Aucun compte en banque n'est donné"));
03594                                 $this->jrn_def_num_op = (isset($numb_operation)) ? 1 : 0;
03595                                 break;
03596                 }
03597 
03598                 parent::insert();
03599         }
03600 
03601         /**
03602          * delete a ledger IF is not already used
03603          * @exeption : cannot delete
03604          */
03605         function delete_ledger()
03606         {
03607                 try
03608                 {
03609                         if ($this->db->get_value("select count(jr_id) from jrn where jr_def_id=$1", array($this->jrn_def_id)) > 0)
03610                                 throw new Exception(_("Impossible d'effacer un journal qui contient des opérations"));
03611                         parent::delete();
03612                 }
03613                 catch (Exception $e)
03614                 {
03615                         throw $e;
03616                 }
03617         }
03618 
03619         function get_operation_date($p_date,$p_ledger_type,$sql_op)
03620         {
03621                 global $g_user;
03622                 switch ($p_ledger_type)
03623                 {
03624                         case 'ACH':
03625                                 $filter=$g_user->get_ledger_sql('ACH',3);
03626                                 break;
03627                         case 'VEN':
03628                                 $filter=$g_user->get_ledger_sql('VEN',3);
03629                                 break;
03630                         default:
03631                                 throw new Exception ('Ledger_type invalid : '.$p_ledger_type);
03632                 }
03633 
03634 
03635                 $sql = "select jr_id, jr_internal, jr_date, jr_comment,jr_comment,jr_montant
03636                                 from jrn
03637                                 join jrn_def on (jrn_def_id=jr_def_id)
03638                                 where
03639                                 jr_ech is not null
03640                                 and jr_ech $sql_op to_date($1,'DD.MM.YYYY')
03641                                 and coalesce (jr_rapt,'xx') <> 'paid'
03642                                 and $filter
03643                                 ";
03644                 $array=$this->db->get_array($sql,array($p_date));
03645                 return $array;
03646         }
03647         /**
03648          * @brief get info from supplier to pay today
03649          */
03650         function get_supplier_now()
03651         {
03652                 $array=$this->get_operation_date(Date('d.m.Y'), 'ACH', '=');
03653                 return $array;
03654         }
03655         /**
03656          * @brief get info from supplier not yet paid
03657          */
03658         function get_supplier_late()
03659         {
03660                 $array=$this->get_operation_date(Date('d.m.Y'), 'ACH', '<');
03661                 return $array;
03662         }
03663         /**
03664          * @brief get info from customer to pay today
03665          */
03666         function get_customer_now()
03667         {
03668                 $array=$this->get_operation_date(Date('d.m.Y'), 'VEN', '=');
03669                 return $array;
03670         }
03671         /**
03672          * @brief get info from customer not yet paid
03673          */
03674         function get_customer_late()
03675         {
03676                 $array=$this->get_operation_date(Date('d.m.Y'), 'VEN', '<');
03677                 return $array;
03678         }
03679         function convert_from_follow($p_ag_id)
03680         {
03681             global $g_user;
03682             if (isNumber($p_ag_id)==0) return null;
03683             if (! $g_user->can_read_action($p_ag_id)) die (_('Action non accessible'));
03684             $array=array();
03685             
03686             // retrieve info from action_gestion
03687             $tiers_id=$this->db->get_value('select f_id_dest from action_gestion where ag_id=$1',array($p_ag_id));
03688             if ( $this->db->size() !=0 )
03689                 $qcode=$this->db->get_value('select j_qcode from vw_poste_qcode where f_id=$1',array($tiers_id));
03690             else
03691                 $qcode="";
03692             
03693             $comment=$this->db->get_value('select ag_title from action_gestion where ag_id=$1',array($p_ag_id));
03694             $array['e_client']=$qcode;
03695             $array['e_comm']=$comment;
03696             
03697             // retrieve info from action_detail
03698             $a_item=$this->db->get_array('select f_id,ad_text,ad_pu,ad_quant,ad_tva_id,ad_tva_amount,j_qcode 
03699                     from 
03700                   action_detail 
03701                   left join vw_poste_qcode using(f_id)
03702                   where
03703                     ag_id=$1',array($p_ag_id));
03704             
03705             $array['nb_item']=($this->nb > count($a_item))?$this->nb:count($a_item);
03706             for ($i=0;$i<count($a_item);$i++)
03707             {
03708                 $array['e_march'.$i]=$a_item[$i]['j_qcode'];
03709                 $array['e_march'.$i.'_label']=$a_item[$i]['ad_text'];
03710                 $array['e_march'.$i.'_price']=$a_item[$i]['ad_pu'];
03711                 $array['e_march'.$i.'_tva_id']=$a_item[$i]['ad_tva_id'];
03712                 $array['e_march'.$i.'_tva_amount']=$a_item[$i]['ad_tva_amount'];
03713                 $array['e_quant'.$i]=$a_item[$i]['ad_quant'];
03714                 
03715             }
03716             return $array;
03717                        
03718         }
03719         /**
03720          * Retrieve the label of an accounting
03721          * @param $p_value tmp_pcmn.pcm_val
03722          * @return string
03723          */
03724         protected function find_label($p_value)
03725         {
03726             $lib=$this->db->get_value('select pcm_lib from tmp_pcmn where pcm_val=$1',array($p_value));
03727             return $lib;
03728         }
03729 
03730 }
03731 ?>
 All Data Structures Namespaces Files Functions Variables Enumerations