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