1. Remplace le caractère x pour enlever des opérations par une constante 2. Ajoute les numéros de pièces dans le tableau de bord pour client, fournisseur et dernières opérations 3. Enlève les boutons "Ajout tag" et ajout concernés si l'utilisateur n'a pas accès
3950 lines
No EOL
122 KiB
PHP
3950 lines
No EOL
122 KiB
PHP
<?php
|
|
/*
|
|
* This file is part of NOALYSS.
|
|
*
|
|
* NOALYSS is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* NOALYSS is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with NOALYSS; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
// Copyright Author Dany De Bontridder danydb@aevalys.eu
|
|
require_once("class_iselect.php");
|
|
require_once("class_icard.php");
|
|
require_once("class_ispan.php");
|
|
require_once("class_ihidden.php");
|
|
require_once("class_idate.php");
|
|
require_once("class_itext.php");
|
|
require_once("class_icheckbox.php");
|
|
require_once('class_iperiod.php');
|
|
require_once('class_fiche.php');
|
|
require_once('class_user.php');
|
|
require_once ('class_dossier.php');
|
|
require_once ('class_anc_operation.php');
|
|
require_once ('class_acc_operation.php');
|
|
require_once ('class_acc_account_ledger.php');
|
|
require_once ('class_pre_op_advanced.php');
|
|
require_once ('class_acc_reconciliation.php');
|
|
require_once ('class_periode.php');
|
|
require_once ('class_gestion_purchase.php');
|
|
require_once ('class_gestion_sold.php');
|
|
require_once ('class_acc_account.php');
|
|
require_once('ac_common.php');
|
|
require_once('class_inum.php');
|
|
require_once('class_lettering.php');
|
|
require_once 'class_sort_table.php';
|
|
require_once 'class_jrn_def_sql.php';
|
|
require_once 'class_acc_payment.php';
|
|
/** \file
|
|
* @brief Class for jrn, class acc_ledger for manipulating the ledger
|
|
*/
|
|
|
|
/** @brief Class for jrn, class acc_ledger for manipulating the ledger
|
|
*
|
|
*/
|
|
|
|
class Acc_Ledger extends jrn_def_sql
|
|
{
|
|
|
|
var $id; /**< jrn_def.jrn_def_id */
|
|
var $name; /**< jrn_def.jrn_def_name */
|
|
var $db; /**< database connextion */
|
|
var $row; /**< row of the ledger */
|
|
var $type; /**< type of the ledger ACH ODS FIN
|
|
VEN or GL */
|
|
var $nb; /**< default number of rows by
|
|
default 10 */
|
|
|
|
/**
|
|
* @param $p_cn database connexion
|
|
* @param $p_id jrn.jrn_def_id
|
|
*/
|
|
function __construct($p_cn, $p_id)
|
|
{
|
|
$this->id = $p_id;
|
|
$this->name = &$this->jrn_def_name;
|
|
$this->jrn_def_id = &$this->id;
|
|
$this->db = $p_cn;
|
|
$this->row = null;
|
|
$this->nb = MAX_ARTICLE;
|
|
}
|
|
|
|
function get_last_pj()
|
|
{
|
|
if ($this->db->exist_sequence("s_jrn_pj" . $this->id))
|
|
{
|
|
$ret = $this->db->get_array("select last_value,is_called from s_jrn_pj" . $this->id);
|
|
$last = $ret[0]['last_value'];
|
|
/**
|
|
* \note With PSQL sequence , the last_value column is 1 when before AND after the first call, to make the difference between them
|
|
* I have to check whether the sequence has been already called or not */
|
|
if ($ret[0]['is_called'] == 'f')
|
|
$last--;
|
|
return $last;
|
|
}
|
|
else
|
|
$this->db->create_sequence("s_jrn_pj" . $this->id);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Return the type of a ledger (ACH,VEN,ODS or FIN) or GL
|
|
*
|
|
*/
|
|
|
|
function get_type()
|
|
{
|
|
if ($this->id == 0)
|
|
{
|
|
$this->name = _(" Tous les journaux");
|
|
$this->type = "GL";
|
|
return "GL";
|
|
}
|
|
|
|
$Res = $this->db->exec_sql("select jrn_def_type from " .
|
|
" jrn_def where jrn_def_id=" .
|
|
$this->id);
|
|
$Max = Database::num_row($Res);
|
|
if ($Max == 0)
|
|
return null;
|
|
$ret = Database::fetch_array($Res, 0);
|
|
$this->type = $ret['jrn_def_type'];
|
|
return $ret['jrn_def_type'];
|
|
}
|
|
|
|
/**
|
|
* let you delete a operation
|
|
* @note by cascade it will delete also in
|
|
* - jrnx
|
|
* - stock
|
|
* - quant_purchase
|
|
* - quant_fin
|
|
* - quant_sold
|
|
* - operation_analytique
|
|
* - letter
|
|
* - reconciliation
|
|
* @bug the attached document is not deleted
|
|
* @bug Normally it should be named delete_operation, cause the id is the ledger_id
|
|
* (jrn_def_id) and not the operation id
|
|
*/
|
|
function delete()
|
|
{
|
|
if ($this->id == 0)
|
|
return;
|
|
$grpt_id = $this->db->get_value('select jr_grpt_id from jrn where jr_id=$1', array($this->jr_id));
|
|
if ($this->db->count() == 0)
|
|
return;
|
|
$this->db->exec_sql('delete from jrnx where j_grpt=$1', array($grpt_id));
|
|
$this->db->exec_sql('delete from jrn where jr_id=$1', array($this->jr_id));
|
|
}
|
|
|
|
/**
|
|
* Display warning contained in an array
|
|
* @return string with error message
|
|
*/
|
|
function display_warning($pa_msg, $p_warning)
|
|
{
|
|
$str = '<p class="notice"> ' . $p_warning;
|
|
$str.="<ol class=\"notice\">";
|
|
for ($i = 0; $i < count($pa_msg); $i++)
|
|
{
|
|
$str.="<li>" . $pa_msg[$i] . "</li>";
|
|
}
|
|
$str.='</ol>';
|
|
$str.='</p>';
|
|
return $str;
|
|
}
|
|
|
|
/**
|
|
* reverse the operation by creating the opposite one,
|
|
* the result is to avoid it
|
|
* it must be done in
|
|
* - jrn
|
|
* - jrnx
|
|
* - quant_fin
|
|
* - quant_sold
|
|
* - quant_purchase
|
|
* - stock
|
|
* - ANC
|
|
* @param $p_date is the date of the reversed op
|
|
* @exception if date is invalid or other prob
|
|
* @note automatically create a reconciliation between operation
|
|
* You must set the ledger_id $this->jrn_def_id
|
|
* This function should be in operation or call an acc_operation object
|
|
*
|
|
*/
|
|
function reverse($p_date)
|
|
{
|
|
global $g_user;
|
|
try
|
|
{
|
|
$this->db->start();
|
|
if (!isset($this->jr_id) || $this->jr_id == '')
|
|
throw new Exception(_("this->jr_id is not set ou opération inconnue"));
|
|
|
|
/* check if the date is valid */
|
|
if (isDate($p_date) == null)
|
|
throw new Exception(_('Date invalide') . $p_date);
|
|
|
|
// if the operation is in a closed or centralized period
|
|
// the operation is voided thanks the opposite operation
|
|
$grp_new = $this->db->get_next_seq('s_grpt');
|
|
$seq = $this->db->get_next_seq("s_jrn");
|
|
$p_internal = $this->compute_internal_code($seq);
|
|
$this->jr_grpt_id = $this->db->get_value('select jr_grpt_id from jrn where jr_id=$1', array($this->jr_id));
|
|
if ($this->db->count() == 0)
|
|
throw new Exception(_("Cette opération n'existe pas"));
|
|
$this->jr_internal = $this->db->get_value('select jr_internal from jrn where jr_id=$1', array($this->jr_id));
|
|
if ($this->db->count() == 0 || trim($this->jr_internal) == '')
|
|
throw new Exception(_("Cette opération n'existe pas"));
|
|
|
|
/* find the periode thanks the date */
|
|
$per = new Periode($this->db);
|
|
$per->jrn_def_id = $this->id;
|
|
$per->find_periode($p_date);
|
|
|
|
if ($per->is_open() == 0)
|
|
throw new Exception(_('PERIODE FERMEE'));
|
|
|
|
|
|
|
|
|
|
|
|
// Mark the operation invalid into the ledger
|
|
// to avoid to nullify twice the same op.
|
|
$sql = "update jrn set jr_comment='extourne : '||jr_comment where jr_id=$1";
|
|
$Res = $this->db->exec_sql($sql, array($this->jr_id));
|
|
|
|
// Check return code
|
|
if ($Res == false)
|
|
throw (new Exception(__FILE__ . __LINE__ . "sql a echoue [ $sql ]"));
|
|
|
|
//////////////////////////////////////////////////
|
|
// Reverse in jrnx* tables
|
|
//////////////////////////////////////////////////
|
|
$a_jid = $this->db->get_array("select j_id,j_debit from jrnx where j_grpt=$1", array($this->jr_grpt_id));
|
|
for ($l = 0; $l < count($a_jid); $l++)
|
|
{
|
|
$row = $a_jid[$l]['j_id'];
|
|
// Make also the change into jrnx
|
|
$sql = "insert into jrnx (
|
|
j_date,j_montant,j_poste,j_grpt,
|
|
j_jrn_def,j_debit,j_text,j_internal,j_tech_user,j_tech_per,j_qcode
|
|
) select to_date($1,'DD.MM.YYYY'),j_montant,j_poste,$2,
|
|
j_jrn_def,not (j_debit),j_text,$3,$4,$5,
|
|
j_qcode
|
|
from
|
|
jrnx
|
|
where j_id=$6 returning j_id";
|
|
$Res = $this->db->exec_sql($sql, array($p_date, $grp_new, $p_internal, $g_user->id, $per->p_id, $row));
|
|
// Check return code
|
|
if ($Res == false)
|
|
throw (new Exception(__FILE__ . __LINE__ . "SQL ERROR [ $sql ]"));
|
|
$aj_id = $this->db->fetch(0);
|
|
$j_id = $aj_id['j_id'];
|
|
|
|
/* automatic lettering */
|
|
$let = new Lettering($this->db);
|
|
$let->insert_couple($j_id, $row);
|
|
|
|
// reverse in QUANT_SOLD
|
|
$Res = $this->db->exec_sql("INSERT INTO quant_sold(
|
|
qs_internal, qs_fiche, qs_quantite, qs_price, qs_vat,
|
|
qs_vat_code, qs_client, qs_valid, j_id)
|
|
SELECT $1, qs_fiche, qs_quantite*(-1), qs_price*(-1), qs_vat*(-1),
|
|
qs_vat_code, qs_client, qs_valid, $2
|
|
FROM quant_sold where j_id=$3", array($p_internal, $j_id, $row));
|
|
|
|
if ($Res == false)
|
|
throw (new Exception(__FILE__ . __LINE__ . "sql a echoue [ $sql ]"));
|
|
$Res = $this->db->exec_sql("INSERT INTO quant_purchase(
|
|
qp_internal, j_id, qp_fiche, qp_quantite, qp_price, qp_vat,
|
|
qp_vat_code, qp_nd_amount, qp_nd_tva, qp_nd_tva_recup, qp_supplier,
|
|
qp_valid, qp_dep_priv)
|
|
SELECT $1, $2, qp_fiche, qp_quantite*(-1), qp_price*(-1), qp_vat*(-1),
|
|
qp_vat_code, qp_nd_amount*(-1), qp_nd_tva*(-1), qp_nd_tva_recup*(-1), qp_supplier,
|
|
qp_valid, qp_dep_priv*(-1)
|
|
FROM quant_purchase where j_id=$3", array($p_internal, $j_id, $row));
|
|
|
|
if ($Res == false)
|
|
throw (new Exception(__FILE__ . __LINE__ . "SQL ERROR [ $sql ]"));
|
|
}
|
|
$sql = "insert into jrn (
|
|
jr_id,
|
|
jr_def_id,
|
|
jr_montant,
|
|
jr_comment,
|
|
jr_date,
|
|
jr_grpt_id,
|
|
jr_internal
|
|
,jr_tech_per, jr_valid
|
|
)
|
|
select $1,jr_def_id,jr_montant,jr_comment,
|
|
to_date($2,'DD.MM.YYYY'),$3,$4,
|
|
$5, true
|
|
from
|
|
jrn
|
|
where jr_id=$6";
|
|
$Res = $this->db->exec_sql($sql, array($seq, $p_date, $grp_new, $p_internal, $per->p_id, $this->jr_id));
|
|
// Check return code
|
|
if ($Res == false)
|
|
throw (new Exception(__FILE__ . __LINE__ . "SQL ERROR [ $sql ]"));
|
|
// reverse in QUANT_FIN table
|
|
$Res = $this->db->exec_sql(" INSERT INTO quant_fin(
|
|
qf_bank, qf_other, qf_amount,jr_id)
|
|
SELECT qf_bank, qf_other, qf_amount*(-1),$1
|
|
FROM quant_fin where jr_id=$2", array($seq, $this->jr_id));
|
|
if ($Res == false)
|
|
throw (new Exception(__FILE__ . __LINE__ . "SQL ERROR[ $sql ]"));
|
|
|
|
// Add a "concerned operation to bound these op.together
|
|
//
|
|
$rec = new Acc_Reconciliation($this->db);
|
|
$rec->set_jr_id($seq);
|
|
$rec->insert($this->jr_id);
|
|
|
|
// Check return code
|
|
if ($Res == false)
|
|
{
|
|
throw (new Exception(__FILE__ . __LINE__ . "SQL ERROR [ $sql ]"));
|
|
}
|
|
|
|
|
|
|
|
// the table stock must updated
|
|
// also in the stock table
|
|
$sql = "delete from stock_goods where sg_id = any ( select sg_id
|
|
from stock_goods natural join jrnx where j_grpt=" . $this->jr_grpt_id . ")";
|
|
$Res = $this->db->exec_sql($sql);
|
|
if ($Res == false)
|
|
throw (new Exception(__FILE__ . __LINE__ . "SQL ERROR [ $sql ]"));
|
|
$this->db->commit();
|
|
}
|
|
catch (Exception $e)
|
|
{
|
|
$this->db->rollback();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Return the name of a ledger
|
|
*
|
|
*/
|
|
|
|
function get_name()
|
|
{
|
|
if ($this->id == 0)
|
|
{
|
|
$this->name = _("Grand Livre");
|
|
return $this->name;
|
|
}
|
|
|
|
$Res = $this->db->exec_sql("select jrn_def_name from " .
|
|
" jrn_def where jrn_def_id=$1", array($this->id));
|
|
$Max = Database::num_row($Res);
|
|
if ($Max == 0)
|
|
return null;
|
|
$ret = Database::fetch_array($Res, 0);
|
|
$this->name = $ret['jrn_def_name'];
|
|
return $ret['jrn_def_name'];
|
|
}
|
|
|
|
/** \function get_row
|
|
* @brief Get The data
|
|
*
|
|
*
|
|
* @paramp_from from periode
|
|
* @paramp_to to periode
|
|
* @paramp_limit starting line
|
|
* @paramp_offset number of lines
|
|
* \return Array with the asked data
|
|
*
|
|
*/
|
|
|
|
function get_row($p_from, $p_to, $p_limit = -1, $p_offset = -1)
|
|
{
|
|
global $g_user;
|
|
$periode = sql_filter_per($this->db, $p_from, $p_to, 'p_id', 'jr_tech_per');
|
|
|
|
$cond_limite = ($p_limit != -1) ? " limit " . $p_limit . " offset " . $p_offset : "";
|
|
// retrieve the type
|
|
$this->get_type();
|
|
// Grand livre == 0
|
|
if ($this->id != 0)
|
|
{
|
|
$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,
|
|
jr_internal,
|
|
case j_debit when 't' then j_montant::text else ' ' end as deb_montant,
|
|
case j_debit when 'f' then j_montant::text else ' ' end as cred_montant,
|
|
j_debit as debit,j_poste as poste,jr_montant , " .
|
|
"case when j_text='' or j_text is null then pcm_lib else j_text end as description,j_grpt as grp,
|
|
jr_comment||' ('||jr_internal||')' as jr_comment,
|
|
jr_pj_number,
|
|
j_qcode,
|
|
jr_rapt as oc, j_tech_per as periode
|
|
from jrnx left join jrn on " .
|
|
"jr_grpt_id=j_grpt " .
|
|
" left join tmp_pcmn on pcm_val=j_poste " .
|
|
" where j_jrn_def=" . $this->id .
|
|
" and " . $periode . " order by j_date::date asc,substring(jr_pj_number,'[0-9]+$')::numeric asc,j_grpt,j_debit desc " .
|
|
$cond_limite);
|
|
}
|
|
else
|
|
{
|
|
$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,
|
|
jr_internal,
|
|
case j_debit when 't' then j_montant::text else ' ' end as deb_montant,
|
|
case j_debit when 'f' then j_montant::text else ' ' end as cred_montant,
|
|
j_debit as debit,j_poste as poste," .
|
|
"case when j_text='' or j_text is null then pcm_lib else j_text end as description,j_grpt as grp,
|
|
jr_comment||' ('||jr_internal||')' as jr_comment,
|
|
jr_pj_number,
|
|
jr_montant,
|
|
j_qcode,
|
|
jr_rapt as oc, j_tech_per as periode from jrnx left join jrn on " .
|
|
"jr_grpt_id=j_grpt left join tmp_pcmn on pcm_val=j_poste
|
|
join jrn_def on (jr_def_id=jrn_def_id)
|
|
where " .
|
|
$g_user->get_ledger_sql() . " and " .
|
|
" " . $periode . " order by j_date::date,substring(jr_pj_number,'[0-9]+$') asc,j_grpt,j_debit desc " .
|
|
$cond_limite);
|
|
}
|
|
|
|
|
|
$array = array();
|
|
$Max = Database::num_row($Res);
|
|
if ($Max == 0)
|
|
return null;
|
|
$case = "";
|
|
$tot_deb = 0;
|
|
$tot_cred = 0;
|
|
$row = Database::fetch_all($Res);
|
|
for ($i = 0; $i < $Max; $i++)
|
|
{
|
|
$fiche = new Fiche($this->db);
|
|
$line = $row[$i];
|
|
$mont_deb = ($line['deb_montant'] != 0) ? sprintf("% 8.2f", $line['deb_montant']) : "";
|
|
$mont_cred = ($line['cred_montant'] != 0) ? sprintf("% 8.2f", $line['cred_montant']) : "";
|
|
$jr_montant = ($line['jr_montant'] != 0) ? sprintf("% 8.2f", $line['jr_montant']) : "";
|
|
$tot_deb+=$line['deb_montant'];
|
|
$tot_cred+=$line['cred_montant'];
|
|
$tot_op = $line['jr_montant'];
|
|
|
|
/* Check first if there is a quickcode */
|
|
if (strlen(trim($line['description'])) == 0 && strlen(trim($line['j_qcode'])) != 0)
|
|
{
|
|
if ($fiche->get_by_qcode($line['j_qcode'], false) == 0)
|
|
{
|
|
$line['description'] = $fiche->strAttribut(ATTR_DEF_NAME);
|
|
}
|
|
}
|
|
if ($case != $line['grp'])
|
|
{
|
|
$case = $line['grp'];
|
|
// for financial, we show if the amount is or not in negative
|
|
if ($this->type == 'FIN')
|
|
{
|
|
$amount = $this->db->get_value('select qf_amount from quant_fin where jr_id=$1', array($line['jr_id']));
|
|
/* if nothing is found */
|
|
if ($this->db->count() == 0)
|
|
$tot_op = $jr_montant;
|
|
else if ($amount < 0)
|
|
{
|
|
$tot_op = $amount;
|
|
}
|
|
}
|
|
$array[] = array(
|
|
'jr_id' => $line['jr_id'],
|
|
'int_j_id' => $line['int_j_id'],
|
|
'j_id' => $line['j_id'],
|
|
'j_date' => $line['j_date'],
|
|
'internal' => $line['jr_internal'],
|
|
'deb_montant' => '',
|
|
'cred_montant' => ' ',
|
|
'description' => '<b><i>' . h($line['jr_comment']) . ' [' . $tot_op . '] </i></b>',
|
|
'poste' => $line['oc'],
|
|
'qcode' => $line['j_qcode'],
|
|
'periode' => $line['periode'],
|
|
'jr_pj_number' => $line ['jr_pj_number']);
|
|
|
|
$array[] = array(
|
|
'jr_id' => '',
|
|
'int_j_id' => $line['int_j_id'],
|
|
'j_id' => '',
|
|
'j_date' => '',
|
|
'internal' => '',
|
|
'deb_montant' => $mont_deb,
|
|
'cred_montant' => $mont_cred,
|
|
'description' => $line['description'],
|
|
'poste' => $line['poste'],
|
|
'qcode' => $line['j_qcode'],
|
|
'periode' => $line['periode'],
|
|
'jr_pj_number' => ''
|
|
);
|
|
}
|
|
else
|
|
{
|
|
$array[] = array(
|
|
'jr_id' => $line['jr_id'],
|
|
'int_j_id' => $line['int_j_id'],
|
|
'j_id' => '',
|
|
'j_date' => '',
|
|
'internal' => '',
|
|
'deb_montant' => $mont_deb,
|
|
'cred_montant' => $mont_cred,
|
|
'description' => $line['description'],
|
|
'poste' => $line['poste'],
|
|
'qcode' => $line['j_qcode'],
|
|
'periode' => $line['periode'],
|
|
'jr_pj_number' => '');
|
|
}
|
|
}
|
|
$this->row = $array;
|
|
$a = array($array, $tot_deb, $tot_cred);
|
|
return $a;
|
|
}
|
|
|
|
/** @brief Get simplified row from ledger
|
|
*
|
|
* @param p_from periode
|
|
* @param p_to periode
|
|
* @param p_limit starting line
|
|
* @param p_offset number of lines
|
|
* @param trunc if data must be truncated (pdf export)
|
|
*
|
|
* \return an Array with the asked data
|
|
*/
|
|
|
|
function get_rowSimple($p_from, $p_to, $trunc = 0, $p_limit = -1, $p_offset = -1)
|
|
{
|
|
global $g_user;
|
|
// Grand-livre : id= 0
|
|
//---
|
|
$jrn = ($this->id == 0 ) ? "and " . $g_user->get_ledger_sql() : "and jrn_def_id = " . $this->id;
|
|
|
|
$periode = sql_filter_per($this->db, $p_from, $p_to, 'p_id', 'jr_tech_per');
|
|
|
|
$cond_limite = ($p_limit != -1) ? " limit " . $p_limit . " offset " . $p_offset : "";
|
|
//---
|
|
$sql = "
|
|
SELECT jrn.jr_id as jr_id ,
|
|
jrn.jr_id as num ,
|
|
jrn.jr_def_id as jr_def_id,
|
|
jrn.jr_montant as montant,
|
|
substr(jrn.jr_comment,1,35) as comment,
|
|
to_char(jrn.jr_date,'DD-MM-YYYY') as date,
|
|
to_char(jrn.jr_date_paid,'DD-MM-YYYY') as date_paid,
|
|
jr_pj_number,
|
|
jr_internal,
|
|
jrn.jr_grpt_id as grpt_id,
|
|
jrn.jr_pj_name as pj,
|
|
jrn_def_type,
|
|
jrn.jr_tech_per
|
|
FROM jrn join jrn_def on (jrn_def_id=jr_def_id)
|
|
WHERE $periode $jrn order by jr_date,substring(jrn.jr_pj_number,'[0-9]+$')::numeric asc $cond_limite";
|
|
|
|
$Res = $this->db->exec_sql($sql);
|
|
$Max = Database::num_row($Res);
|
|
if ($Max == 0)
|
|
{
|
|
return null;
|
|
}
|
|
$type = $this->get_type();
|
|
// for type ACH and Ven we take more info
|
|
if ($type == 'ACH' || $type == 'VEN')
|
|
{
|
|
$a_ParmCode = $this->db->get_array('select p_code,p_value from parm_code');
|
|
$a_TVA = $this->db->get_array('select tva_id,tva_label,tva_poste
|
|
from tva_rate where tva_rate != 0 order by tva_rate,tva_label,tva_id ');
|
|
for ($i = 0; $i < $Max; $i++)
|
|
{
|
|
$array[$i] = Database::fetch_array($Res, $i);
|
|
$p = $this->get_detail($array[$i], $type, $trunc, $a_TVA, $a_ParmCode);
|
|
if ($array[$i]['dep_priv'] != 0.0)
|
|
{
|
|
$array[$i]['comment'].="(priv. " . $array[$i]['dep_priv'] . ")";
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$array = Database::fetch_all($Res);
|
|
}
|
|
|
|
return $array;
|
|
}
|
|
|
|
// end function get_rowSimple
|
|
|
|
/**
|
|
* @brief guess what the next pj should be
|
|
*/
|
|
|
|
function guess_pj()
|
|
{
|
|
$prop = $this->get_propertie();
|
|
$pj_pref = $prop["jrn_def_pj_pref"];
|
|
$pj_seq = $this->get_last_pj() + 1;
|
|
return $pj_pref . $pj_seq;
|
|
}
|
|
|
|
/**
|
|
* @brief Show all the operation
|
|
* @param$sql is the sql stmt, normally created by build_search_sql
|
|
* @param$offset the offset
|
|
* @param$p_paid if we want to see info about payment
|
|
@code
|
|
// Example
|
|
// Build the sql
|
|
list($sql,$where)=$Ledger->build_search_sql($_GET);
|
|
// Count nb of line
|
|
$max_line=$this->db->count_sql($sql);
|
|
|
|
$step=$_SESSION['g_pagesize'];
|
|
$page=(isset($_GET['offset']))?$_GET['page']:1;
|
|
$offset=(isset($_GET['offset']))?$_GET['offset']:0;
|
|
// create the nav. bar
|
|
$bar=navigation_bar($offset,$max_line,$step,$page);
|
|
// show a part
|
|
list($count,$html)= $Ledger->list_operation($sql,$offset,0);
|
|
echo $html;
|
|
// show nav bar
|
|
echo $bar;
|
|
|
|
@endcode
|
|
* @see build_search_sql
|
|
* @see display_search_form
|
|
* @see search_form
|
|
|
|
* @return HTML string
|
|
*/
|
|
|
|
public function list_operation_to_reconcile($sql,$p_target)
|
|
{
|
|
global $g_parameter, $g_user;
|
|
$gDossier = dossier::id();
|
|
$limit = " LIMIT ".MAX_RECONCILE;
|
|
// Sort
|
|
// Count
|
|
$count = $this->db->count_sql($sql);
|
|
// Add the limit
|
|
$sql.=" order by jr_date asc " . $limit;
|
|
|
|
// Execute SQL stmt
|
|
$Res = $this->db->exec_sql($sql);
|
|
|
|
//starting from here we can refactor, so that instead of returning the generated HTML,
|
|
//this function returns a tree structure.
|
|
|
|
$r = "";
|
|
|
|
|
|
$Max = Database::num_row($Res);
|
|
|
|
if ($Max == 0)
|
|
return array(0, _("Aucun enregistrement trouvé"));
|
|
$r.=HtmlInput::hidden("target", $p_target);
|
|
$r.='<table class="result">';
|
|
|
|
|
|
$r.="<tr >";
|
|
$r.="<th>"._("Selection")."</th>";
|
|
$r.="<th>"._("Internal")."</th>";
|
|
|
|
if ($this->type == 'ALL')
|
|
{
|
|
$r.=th(_('Journal'));
|
|
}
|
|
|
|
$r.='<th>'._("Date").'</th>';
|
|
$r.='<th>'._("Pièce").'</td>';
|
|
$r.=th(_('tiers'));
|
|
$r.='<th>'._("Description").'</th>';
|
|
$r.=th(_('Notes'), ' ');
|
|
$r.='<th>'._("Montant").'</th>';
|
|
$r.="<th>" . _('Concerne') . "</th>";
|
|
$r.="</tr>";
|
|
// Total Amount
|
|
$tot = 0.0;
|
|
$gDossier = dossier::id();
|
|
$str_dossier = Dossier::id();
|
|
for ($i = 0; $i < $Max; $i++)
|
|
{
|
|
|
|
|
|
$row = Database::fetch_array($Res, $i);
|
|
|
|
if ($i % 2 == 0)
|
|
$tr = '<TR class="odd">';
|
|
else
|
|
$tr = '<TR class="even">';
|
|
$r.=$tr;
|
|
// Radiobox
|
|
//
|
|
|
|
$r.='<td><INPUT TYPE="CHECKBOX" name="jr_concerned' . $row['jr_id'] . '" ID="jr_concerned' . $row['jr_id'] . '" value="'.$row['quick_code'].'"> </td>';
|
|
//internal code
|
|
// button modify
|
|
$r.="<TD>";
|
|
// If url contains
|
|
//
|
|
|
|
$href = basename($_SERVER['PHP_SELF']);
|
|
|
|
|
|
$r.=sprintf('<A class="detail" style="text-decoration:underline" HREF="javascript:modifyOperation(\'%s\',\'%s\')" >%s </A>', $row['jr_id'], $gDossier, $row['jr_internal']);
|
|
$r.="</TD>";
|
|
if ($this->type == 'ALL')
|
|
$r.=td($row['jrn_def_name']);
|
|
// date
|
|
$r.="<TD>";
|
|
$r.=$row['str_jr_date'];
|
|
$r.="</TD>";
|
|
|
|
// pj
|
|
$r.="<TD>";
|
|
$r.=$row['jr_pj_number'];
|
|
$r.="</TD>";
|
|
|
|
// Tiers
|
|
$other = ($row['quick_code'] != '') ? '[' . $row['quick_code'] . '] ' . $row['name'] . ' ' . $row['first_name'] : '';
|
|
$r.=td($other);
|
|
// comment
|
|
$r.="<TD>";
|
|
$tmp_jr_comment = h($row['jr_comment']);
|
|
$r.=$tmp_jr_comment;
|
|
$r.="</TD>";
|
|
$r.=td(h($row['n_text']), ' style="font-size:0.87em"');
|
|
// Amount
|
|
// If the ledger is financial :
|
|
// the credit must be negative and written in red
|
|
$positive = 0;
|
|
|
|
// Check ledger type :
|
|
if ($row['jrn_def_type'] == 'FIN')
|
|
{
|
|
$positive = $this->db->get_value("select qf_amount from quant_fin where jr_id=$1", array($row['jr_id']));
|
|
if ($this->db->count() != 0)
|
|
$positive = ($positive < 0) ? 1 : 0;
|
|
}
|
|
$r.="<TD align=\"right\">";
|
|
|
|
$r.=( $positive != 0 ) ? "<font color=\"red\"> - " . nbm($row['jr_montant']) . "</font>" : nbm($row['jr_montant']);
|
|
$r.="</TD>";
|
|
|
|
|
|
|
|
// Rapprochement
|
|
$rec = new Acc_Reconciliation($this->db);
|
|
$rec->set_jr_id($row['jr_id']);
|
|
$a = $rec->get();
|
|
$r.="<TD>";
|
|
if ($a != null)
|
|
{
|
|
|
|
foreach ($a as $key => $element)
|
|
{
|
|
$operation = new Acc_Operation($this->db);
|
|
$operation->jr_id = $element;
|
|
$l_amount = $this->db->get_value("select jr_montant from jrn " .
|
|
" where jr_id=$element");
|
|
$r.= "<A class=\"detail\" HREF=\"javascript:modifyOperation('" . $element . "'," . $gDossier . ")\" > " . $operation->get_internal() . "[" . nbm($l_amount) . "]</A>";
|
|
}//for
|
|
}// if ( $a != null ) {
|
|
$r.="</TD>";
|
|
|
|
if ($row['jr_valid'] == 'f')
|
|
{
|
|
$r.="<TD>"._("Opération annulée")."</TD>";
|
|
}
|
|
// end row
|
|
$r.="</tr>";
|
|
}
|
|
$r.='</table>';
|
|
return array($count, $r);
|
|
}
|
|
|
|
/**
|
|
* @brief Show all the operation
|
|
* @param$sql is the sql stmt, normally created by build_search_sql
|
|
* @param$offset the offset
|
|
* @param$p_paid if we want to see info about payment
|
|
\code
|
|
// Example
|
|
// Build the sql
|
|
list($sql,$where)=$Ledger->build_search_sql($_GET);
|
|
// Count nb of line
|
|
$max_line=$cn->count_sql($sql);
|
|
|
|
$step=$_SESSION['g_pagesize'];
|
|
$page=(isset($_GET['offset']))?$_GET['page']:1;
|
|
$offset=(isset($_GET['offset']))?$_GET['offset']:0;
|
|
// create the nav. bar
|
|
$bar=navigation_bar($offset,$max_line,$step,$page);
|
|
// show a part
|
|
list($count,$html)= $Ledger->list_operation($sql,$offset,0);
|
|
echo $html;
|
|
// show nav bar
|
|
echo $bar;
|
|
|
|
\endcode
|
|
* \see build_search_sql
|
|
* \see display_search_form
|
|
* \see search_form
|
|
|
|
* \return HTML string
|
|
*/
|
|
|
|
public function list_operation($sql, $offset, $p_paid = 0)
|
|
{
|
|
global $g_parameter, $g_user;
|
|
bcscale(2);
|
|
$table = new Sort_Table();
|
|
$gDossier = dossier::id();
|
|
$amount_paid = 0.0;
|
|
$amount_unpaid = 0.0;
|
|
$limit = ($_SESSION['g_pagesize'] != -1) ? " LIMIT " . $_SESSION['g_pagesize'] : "";
|
|
$offset = ($_SESSION['g_pagesize'] != -1) ? " OFFSET " . Database::escape_string($offset) : "";
|
|
$order = " order by jr_date_order asc,jr_internal asc";
|
|
// Sort
|
|
$url = "?" . CleanUrl();
|
|
$str_dossier = dossier::get();
|
|
$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");
|
|
$table->add(_('Echeance'), $url, " order by jr_ech asc", " order by jr_ech desc", 'ea', 'ed');
|
|
$table->add(_('Paiement'), $url, " order by jr_date_paid asc", " order by jr_date_paid desc", 'eap', 'edp');
|
|
$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");
|
|
$table->add(_('Tiers'), $url, " order by name asc", " order by name desc", 'na', 'nd');
|
|
$table->add(_('Montant'), $url, " order by jr_montant asc", " order by jr_montant desc", "ma", "md");
|
|
$table->add(_("Description"), $url, "order by jr_comment asc", "order by jr_comment desc", "ca", "cd");
|
|
|
|
$ord = (!isset($_GET['ord'])) ? 'da' : $_GET['ord'];
|
|
$order = $table->get_sql_order($ord);
|
|
|
|
// Count
|
|
$count = $this->db->count_sql($sql);
|
|
// Add the limit
|
|
$sql.=$order . $limit . $offset;
|
|
// Execute SQL stmt
|
|
$Res = $this->db->exec_sql($sql);
|
|
|
|
//starting from here we can refactor, so that instead of returning the generated HTML,
|
|
//this function returns a tree structure.
|
|
|
|
$r = "";
|
|
|
|
|
|
$Max = Database::num_row($Res);
|
|
|
|
if ($Max == 0)
|
|
return array(0, _("Aucun enregistrement trouvé"));
|
|
|
|
$r.='<table class="result">';
|
|
|
|
|
|
$r.="<tr >";
|
|
$r.="<th>"._("n° interne")."</th>";
|
|
if ($this->type == 'ALL')
|
|
{
|
|
$r.=th('Journal');
|
|
}
|
|
$r.='<th>' . $table->get_header(0) . '</th>';
|
|
if ($p_paid != 0 ) $r.='<th>' . $table->get_header(1) . '</td>';
|
|
if ($p_paid != 0 ) $r.='<th>' . $table->get_header(2) . '</th>';
|
|
$r.='<th>' . $table->get_header(3) . '</th>';
|
|
$r.='<th>' . $table->get_header(4) . '</th>';
|
|
$r.='<th>' . $table->get_header(6) . '</th>';
|
|
$r.=th('Notes', ' style="width:15%"');
|
|
$r.='<th>' . $table->get_header(5) . '</th>';
|
|
// if $p_paid is not equal to 0 then we have a paid column
|
|
if ($p_paid != 0)
|
|
{
|
|
$r.="<th> " . _('Payé') . "</th>";
|
|
}
|
|
$r.="<th>" . _('Concerne') . "</th>";
|
|
$r.="<th>" . _('Document') . "</th>";
|
|
$r.="</tr>";
|
|
// Total Amount
|
|
$tot = 0.0;
|
|
$gDossier = dossier::id();
|
|
for ($i = 0; $i < $Max; $i++)
|
|
{
|
|
|
|
|
|
$row = Database::fetch_array($Res, $i);
|
|
|
|
if ($i % 2 == 0)
|
|
$tr = '<TR class="odd">';
|
|
else
|
|
$tr = '<TR class="even">';
|
|
$r.=$tr;
|
|
//internal code
|
|
// button modify
|
|
$r.="<TD>";
|
|
// If url contains
|
|
//
|
|
|
|
$href = basename($_SERVER['PHP_SELF']);
|
|
|
|
|
|
$r.=sprintf('<A class="detail" style="text-decoration:underline" HREF="javascript:modifyOperation(\'%s\',\'%s\')" >%s </A>', $row['jr_id'], $gDossier, $row['jr_internal']);
|
|
$r.="</TD>";
|
|
if ($this->type == 'ALL')
|
|
$r.=td($row['jrn_def_name']);
|
|
// date
|
|
$r.="<TD>";
|
|
$r.=$row['str_jr_date'];
|
|
$r.="</TD>";
|
|
// echeance
|
|
if ($p_paid != 0 )
|
|
{
|
|
$r.="<TD>";
|
|
$r.=$row['str_jr_ech'];
|
|
$r.="</TD>";
|
|
$r.="<TD>";
|
|
$r.=$row['str_jr_date_paid'];
|
|
$r.="</TD>";
|
|
}
|
|
|
|
// pj
|
|
$r.="<TD>";
|
|
$r.=$row['jr_pj_number'];
|
|
$r.="</TD>";
|
|
|
|
// Tiers
|
|
$other = ($row['quick_code'] != '') ? '[' . $row['quick_code'] . '] ' . $row['name'] . ' ' . $row['first_name'] : '';
|
|
$r.=td($other);
|
|
// comment
|
|
$r.="<TD>";
|
|
$tmp_jr_comment = h($row['jr_comment']);
|
|
$r.=$tmp_jr_comment;
|
|
$r.="</TD>";
|
|
$r.=td(h($row['n_text']), ' style="font-size:0.87em%"');
|
|
// Amount
|
|
// If the ledger is financial :
|
|
// the credit must be negative and written in red
|
|
$positive = 0;
|
|
|
|
// Check ledger type :
|
|
if ($row['jrn_def_type'] == 'FIN')
|
|
{
|
|
$positive = $this->db->get_value("select qf_amount from quant_fin where jr_id=$1", array($row['jr_id']));
|
|
if ($this->db->count() != 0)
|
|
$positive = ($positive < 0) ? 1 : 0;
|
|
}
|
|
$r.="<TD align=\"right\">";
|
|
$t_amount=$row['jr_montant'];
|
|
if ($row['total_invoice'] != null && $row['total_invoice'] != $row['jr_montant'])
|
|
$t_amount=$row['total_invoice'];
|
|
$tot = ($positive != 0) ? bcsub($tot , $t_amount ): bcadd($tot , $t_amount);
|
|
//STAN $positive always == 0
|
|
if ($row [ 'jrn_def_type']=='FIN')
|
|
{
|
|
$r.=( $positive != 0 ) ? "<font color=\"red\"> - " . nbm($t_amount) . "</font>" : nbm($t_amount);
|
|
}
|
|
else
|
|
{
|
|
$r.=( $t_amount < 0 ) ? "<font color=\"red\"> " . nbm($t_amount) . "</font>" : nbm($t_amount);
|
|
}
|
|
$r.="</TD>";
|
|
|
|
|
|
// Show the paid column if p_paid is not null
|
|
if ($p_paid != 0)
|
|
{
|
|
$w = new ICheckBox();
|
|
$w->name = "rd_paid" . $row['jr_id'];
|
|
$w->selected = ($row['jr_rapt'] == 'paid') ? true : false;
|
|
// if p_paid == 2 then readonly
|
|
$w->readonly = ( $p_paid == 2) ? true : false;
|
|
$h = new IHidden();
|
|
$h->name = "set_jr_id" . $row['jr_id'];
|
|
$r.='<TD>' . $w->input() . $h->input() . '</TD>';
|
|
if ($row['jr_rapt'] == 'paid')
|
|
$amount_paid=bcadd($amount_paid,$t_amount);
|
|
else
|
|
$amount_unpaid=bcadd($amount_unpaid,$t_amount);
|
|
}
|
|
|
|
// Rapprochement
|
|
$rec = new Acc_Reconciliation($this->db);
|
|
$rec->set_jr_id($row['jr_id']);
|
|
$a = $rec->get();
|
|
$r.="<TD>";
|
|
if ($a != null)
|
|
{
|
|
|
|
foreach ($a as $key => $element)
|
|
{
|
|
$operation = new Acc_Operation($this->db);
|
|
$operation->jr_id = $element;
|
|
$l_amount = $this->db->get_value("select jr_montant from jrn " .
|
|
" where jr_id=$element");
|
|
$r.= "<A class=\"detail\" HREF=\"javascript:modifyOperation('" . $element . "'," . $gDossier . ")\" > " . $operation->get_internal() . "[" . nbm($l_amount) . "]</A>";
|
|
}//for
|
|
}// if ( $a != null ) {
|
|
$r.="</TD>";
|
|
|
|
if ($row['jr_valid'] == 'f')
|
|
{
|
|
$r.="<TD>"._("Opération annulée")."</TD>";
|
|
}
|
|
else
|
|
{
|
|
|
|
} // else
|
|
//document
|
|
if ($row['jr_pj_name'] != "")
|
|
{
|
|
$r.='<td>'.HtmlInput::show_receipt_document($row['jr_id']).'</td>';
|
|
}
|
|
else
|
|
$r.="<TD></TD>";
|
|
|
|
// end row
|
|
$r.="</tr>";
|
|
}
|
|
$amount_paid = round($amount_paid, 4);
|
|
$amount_unpaid = round($amount_unpaid, 4);
|
|
$tot = round($tot, 4);
|
|
$r.="<TR>";
|
|
$r.='<TD COLSPAN="5">Total</TD>';
|
|
$r.='<TD ALIGN="RIGHT">' . nbm($tot) . "</TD>";
|
|
$r.="</tr>";
|
|
if ($p_paid != 0)
|
|
{
|
|
$r.="<TR>";
|
|
$r.='<TD COLSPAN="5">'._("Payé").'</TD>';
|
|
$r.='<TD ALIGN="RIGHT">' . nbm($amount_paid) . "</TD>";
|
|
$r.="</tr>";
|
|
$r.="<TR>";
|
|
$r.='<TD COLSPAN="5">'._("Non payé").'</TD>';
|
|
$r.='<TD ALIGN="RIGHT">' . nbm($amount_unpaid) . "</TD>";
|
|
$r.="</tr>";
|
|
}
|
|
$r.="</table>";
|
|
|
|
return array($count, $r);
|
|
}
|
|
|
|
/**
|
|
* @brief get_detail gives the detail of row
|
|
* this array must contains at least the field
|
|
* <ul>
|
|
* <li> montant</li>
|
|
* <li> grpt_id
|
|
* </ul>
|
|
* the following field will be added
|
|
* <ul>
|
|
* <li> HTVA
|
|
* <li> TVAC
|
|
* <li> TVA array with
|
|
* <ul>
|
|
* <li> field 0 idx
|
|
* <li> array containing tva_id,tva_label and tva_amount
|
|
* </ul>
|
|
* </ul>
|
|
*
|
|
* @paramp_array the structure is set in get_rowSimple, this array is
|
|
* modified,
|
|
* @param $trunc if the data must be truncated, usefull for pdf export
|
|
* @paramp_jrn_type is the type of the ledger (ACH or VEN)
|
|
* @param $a_TVA TVA Array (default null)
|
|
* @param $a_ParmCode Array (default null)
|
|
* \return p_array
|
|
*/
|
|
|
|
function get_detail(&$p_array, $p_jrn_type, $trunc = 0, $a_TVA = null, $a_ParmCode = null)
|
|
{
|
|
bcscale(2);
|
|
|
|
if ($a_TVA == null)
|
|
{
|
|
//Load TVA array
|
|
$a_TVA = $this->db->get_array('select tva_id,tva_label,tva_poste
|
|
from tva_rate where tva_rate != 0 order by tva_rate,tva_label,tva_id');
|
|
}
|
|
if ($a_ParmCode == null)
|
|
{
|
|
//Load Parm_code
|
|
$a_ParmCode = $this->db->get_array('select p_code,p_value from parm_code');
|
|
}
|
|
// init
|
|
$p_array['client'] = "";
|
|
$p_array['TVAC'] = 0;
|
|
$p_array['TVA'] = array();
|
|
$p_array['AMOUNT_TVA'] = 0.0;
|
|
$p_array['dep_priv'] = 0;
|
|
$p_array['dna'] = 0;
|
|
$p_array['tva_dna'] = 0;
|
|
$p_array['tva_np'] = 0;
|
|
$dep_priv = 0.0;
|
|
|
|
//
|
|
// Retrieve data from jrnx
|
|
$sql = "select j_id,j_poste,j_montant, j_debit,j_qcode from jrnx where " .
|
|
" j_grpt=" . $p_array['grpt_id'];
|
|
$Res2 = $this->db->exec_sql($sql);
|
|
$data_jrnx = Database::fetch_all($Res2);
|
|
$c = 0;
|
|
|
|
// Parse data from jrnx and fill diff. field
|
|
foreach ($data_jrnx as $code)
|
|
{
|
|
$idx_tva = 0;
|
|
$poste = new Acc_Account_Ledger($this->db, $code['j_poste']);
|
|
|
|
// if card retrieve name if the account is not a VAT account
|
|
if (strlen(trim($code['j_qcode'])) != 0 && $poste->isTva() == 0)
|
|
{
|
|
$fiche = new Fiche($this->db);
|
|
$fiche->get_by_qcode(trim($code['j_qcode']), false);
|
|
$fiche_def_id = $fiche->get_fiche_def_ref_id();
|
|
// Customer or supplier
|
|
if ($fiche_def_id == FICHE_TYPE_CLIENT ||
|
|
$fiche_def_id == FICHE_TYPE_FOURNISSEUR
|
|
||$fiche_def_id == FICHE_TYPE_ADM_TAX)
|
|
{
|
|
$p_array['TVAC'] = $code['j_montant'];
|
|
|
|
$p_array['client'] = ($trunc == 0) ? $fiche->getName() : mb_substr($fiche->getName(), 0, 20);
|
|
$p_array['reversed'] = false;
|
|
if ($fiche_def_id == FICHE_TYPE_CLIENT && $code['j_debit'] == 'f')
|
|
{
|
|
$p_array['reversed'] = true;
|
|
$p_array['TVAC']*=-1;
|
|
}
|
|
if ($fiche_def_id == FICHE_TYPE_ADM_TAX && $code['j_debit'] == 'f')
|
|
{
|
|
$p_array['reversed'] = true;
|
|
$p_array['TVAC']*=-1;
|
|
}
|
|
if ($fiche_def_id == FICHE_TYPE_FOURNISSEUR && $code['j_debit'] == 't')
|
|
{
|
|
$p_array['reversed'] = true;
|
|
$p_array['TVAC']*=-1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if we use the ledger ven / ach for others card than supplier and customer
|
|
if ($fiche_def_id != FICHE_TYPE_VENTE &&
|
|
$fiche_def_id != FICHE_TYPE_ACH_MAR &&
|
|
$fiche_def_id != FICHE_TYPE_ACH_SER &&
|
|
$fiche_def_id != FICHE_TYPE_ACH_MAT
|
|
)
|
|
{
|
|
$p_array['TVAC'] = $code['j_montant'];
|
|
|
|
$p_array['client'] = ($trunc == 0) ? $fiche->getName() : mb_substr($fiche->getName(), 0, 20);
|
|
$p_array['reversed'] = false;
|
|
if ($p_jrn_type == 'ACH' && $code['j_debit'] == 't')
|
|
{
|
|
$p_array['reversed'] = true;
|
|
$p_array['TVAC']*=-1;
|
|
}
|
|
if ($p_jrn_type == 'VEN' && $code['j_debit'] == 'f')
|
|
{
|
|
$p_array['reversed'] = true;
|
|
$p_array['TVAC']*=-1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// if TVA, load amount, tva id and rate in array
|
|
foreach ($a_TVA as $line_tva)
|
|
{
|
|
list($tva_deb, $tva_cred) = explode(',', $line_tva['tva_poste']);
|
|
if ($code['j_poste'] == $tva_deb ||
|
|
$code['j_poste'] == $tva_cred)
|
|
{
|
|
|
|
// For the reversed operation
|
|
if ($p_jrn_type == 'ACH' && $code['j_debit'] == 'f')
|
|
{
|
|
$code['j_montant'] = -1 * $code['j_montant'];
|
|
}
|
|
if ($p_jrn_type == 'VEN' && $code['j_debit'] == 't')
|
|
{
|
|
$code['j_montant'] = -1 * $code['j_montant'];
|
|
}
|
|
|
|
$p_array['AMOUNT_TVA']+=$code['j_montant'];
|
|
|
|
$p_array['TVA'][$c] = array($idx_tva, array($line_tva['tva_id'], $line_tva['tva_label'], $code['j_montant']));
|
|
$c++;
|
|
|
|
$idx_tva++;
|
|
}
|
|
}
|
|
|
|
// isDNA
|
|
// If operation is reversed then amount are negatif
|
|
/* if ND */
|
|
if ($p_array['jrn_def_type'] == 'ACH')
|
|
{
|
|
$purchase = new Gestion_Purchase($this->db);
|
|
$purchase->search_by_jid($code['j_id']);
|
|
$purchase->load();
|
|
$dep_priv+=$purchase->qp_dep_priv;
|
|
$p_array['dep_priv'] = $dep_priv;
|
|
$p_array['dna']=bcadd($p_array['dna'],$purchase->qp_nd_amount);
|
|
$p_array['tva_dna']=bcadd($p_array['tva_dna'],bcadd($purchase->qp_nd_tva,$purchase->qp_nd_tva_recup));
|
|
$p_array['tva_np']=bcadd($purchase->qp_vat_sided,$p_array['tva_np']);
|
|
}
|
|
if ($p_array['jrn_def_type'] == 'VEN') {
|
|
$sold=new gestion_sold($this->db);
|
|
$sold->search_by_jid($code['j_id']);
|
|
$sold->load();
|
|
$p_array['tva_np']=bcadd($sold->qs_vat_sided,$p_array['tva_np']);
|
|
}
|
|
|
|
|
|
}
|
|
$p_array['TVAC'] = sprintf('% 10.2f', $p_array['TVAC'] );
|
|
$p_array['HTVA'] = sprintf('% 10.2f', $p_array['TVAC'] - $p_array['AMOUNT_TVA']-$p_array['tva_dna']);
|
|
$r = "";
|
|
$a_tva_amount = array();
|
|
// inline TVA (used for the PDF)
|
|
foreach ($p_array['TVA'] as $linetva)
|
|
{
|
|
foreach ($a_TVA as $tva)
|
|
{
|
|
if ($tva['tva_id'] == $linetva[1][0])
|
|
{
|
|
$a = $tva['tva_id'];
|
|
$a_tva_amount[$a] = $linetva[1][2];
|
|
}
|
|
}
|
|
}
|
|
foreach ($a_TVA as $line_tva)
|
|
{
|
|
$a = $line_tva['tva_id'];
|
|
if (isset($a_tva_amount[$a]))
|
|
{
|
|
$tmp = sprintf("% 10.2f", $a_tva_amount[$a]);
|
|
$r.="$tmp";
|
|
}
|
|
else
|
|
$r.=sprintf("% 10.2f", 0);
|
|
}
|
|
$p_array['TVA_INLINE'] = $r;
|
|
|
|
return $p_array;
|
|
}
|
|
|
|
// retrieve data from jrnx
|
|
/**
|
|
* @brief Get the properties of a journal
|
|
*
|
|
* \return an array containing properties
|
|
*
|
|
*/
|
|
|
|
function get_propertie()
|
|
{
|
|
if ($this->id == 0)
|
|
return;
|
|
|
|
$Res = $this->db->exec_sql("select jrn_Def_id,jrn_def_name,jrn_def_class_deb,jrn_def_class_cred,jrn_def_type,
|
|
jrn_deb_max_line,jrn_cred_max_line,jrn_def_ech,jrn_def_ech_lib,jrn_def_code,
|
|
jrn_def_fiche_deb,jrn_def_fiche_cred,jrn_def_pj_pref
|
|
from jrn_Def
|
|
where jrn_def_id=$1", array($this->id));
|
|
$Count = Database::num_row($Res);
|
|
if ($Count == 0)
|
|
{
|
|
echo '<DIV="redcontent"><H2 class="error">' . _('Parametres journaux non trouves') . '</H2> </DIV>';
|
|
return null;
|
|
}
|
|
return Database::fetch_array($Res, 0);
|
|
}
|
|
|
|
/** \function GetDefLine
|
|
* @brief Get the number of lines of a journal
|
|
* @param$p_cred deb or cred
|
|
*
|
|
* \return an integer
|
|
*/
|
|
|
|
function GetDefLine()
|
|
{
|
|
$sql_cred = 'jrn_deb_max_line';
|
|
$sql = "select jrn_deb_max_line as value from jrn_def where jrn_def_id=$1";
|
|
$r = $this->db->exec_sql($sql, array($this->id));
|
|
$Res = Database::fetch_all($r);
|
|
if (sizeof($Res) == 0)
|
|
return 1;
|
|
return $Res[0]['value'];
|
|
}
|
|
|
|
/**
|
|
* @brief get the saldo of a ledger for a specific period
|
|
* @param$p_from start period
|
|
* @param$p_to end period
|
|
*/
|
|
|
|
function get_solde($p_from, $p_to)
|
|
{
|
|
$ledger = "";
|
|
if ($this->id != 0)
|
|
{
|
|
$ledger = " and j_jrn_def = " . $this->id;
|
|
}
|
|
|
|
$periode = sql_filter_per($this->db, $p_from, $p_to, 'p_id', 'j_tech_per');
|
|
$sql = 'select j_montant as montant,j_debit as deb from jrnx where '
|
|
. $periode . $ledger;
|
|
|
|
$ret = $this->db->exec_sql($sql);
|
|
$array = Database::fetch_all($ret);
|
|
$deb = 0.0;
|
|
$cred = 0.0;
|
|
foreach ($array as $line)
|
|
{
|
|
|
|
if ($line['deb'] == 't')
|
|
$deb+=$line['montant'];
|
|
else
|
|
$cred+=$line['montant'];
|
|
}
|
|
$response = array($deb, $cred);
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* @brief Show a select list of the ledgers you can access in
|
|
* writing, reading or simply accessing.
|
|
* @param$p_type = ALL or the type of the ledger (ACH,VEN,FIN,ODS)
|
|
* @param$p_access =3 for READ and WRITE, 2 for write and 1 for readonly
|
|
* \return object HtmlInput select
|
|
*/
|
|
|
|
function select_ledger($p_type = "ALL", $p_access = 3)
|
|
{
|
|
global $g_user;
|
|
$array = $g_user->get_ledger($p_type, $p_access);
|
|
|
|
if ($array == null)
|
|
return null;
|
|
$idx = 0;
|
|
$ret = array();
|
|
|
|
foreach ($array as $value)
|
|
{
|
|
$ret[$idx]['value'] = $value['jrn_def_id'];
|
|
$ret[$idx]['label'] = h($value['jrn_def_name']);
|
|
$idx++;
|
|
}
|
|
|
|
$select = new ISelect();
|
|
$select->name = 'p_jrn';
|
|
$select->value = $ret;
|
|
$select->selected = $this->id;
|
|
return $select;
|
|
}
|
|
|
|
/**
|
|
* @brief retrieve the jrn_def_fiche and return them into a array
|
|
* index deb, cred
|
|
* \param
|
|
* \param
|
|
* \param
|
|
*
|
|
*
|
|
* \return return an array ('deb'=> ,'cred'=>)
|
|
*/
|
|
|
|
function get_fiche_def()
|
|
{
|
|
$sql = "select jrn_def_fiche_deb as deb,jrn_def_fiche_cred as cred " .
|
|
" from jrn_def where " .
|
|
" jrn_def_id = $1 ";
|
|
|
|
$r = $this->db->exec_sql($sql, array($this->id));
|
|
|
|
$res = Database::fetch_all($r);
|
|
if (empty($res))
|
|
return null;
|
|
|
|
return $res[0];
|
|
}
|
|
|
|
/**
|
|
* @brief retrieve the jrn_def_class_deb and return it
|
|
*
|
|
*
|
|
* \return return an string
|
|
*/
|
|
|
|
function get_class_def()
|
|
{
|
|
$sql = "select jrn_def_class_deb " .
|
|
" from jrn_def where " .
|
|
" jrn_def_id = $1";
|
|
|
|
$r = $this->db->exec_sql($sql, array($this->id));
|
|
|
|
$res = Database::fetch_all($r);
|
|
|
|
if (empty($res))
|
|
return null;
|
|
|
|
return $res[0];
|
|
}
|
|
|
|
/**
|
|
* @brief show the result of the array to confirm
|
|
* before inserting
|
|
* @param$p_array array from the form
|
|
* \return string
|
|
*/
|
|
|
|
function confirm($p_array, $p_readonly = false)
|
|
{
|
|
global $g_parameter;
|
|
$msg = array();
|
|
if (!$p_readonly)
|
|
$msg = $this->verify($p_array);
|
|
$this->id = $p_array['p_jrn'];
|
|
if (empty($p_array))
|
|
return 'Aucun résultat';
|
|
$anc = null;
|
|
extract($p_array);
|
|
$lPeriode = new Periode($this->db);
|
|
if ($this->check_periode() == true)
|
|
{
|
|
$lPeriode->p_id = $period;
|
|
}
|
|
else
|
|
{
|
|
$lPeriode->find_periode($e_date);
|
|
}
|
|
$total_deb = 0;
|
|
$total_cred = 0;
|
|
bcscale(2);
|
|
|
|
$ret = "";
|
|
if (!empty($msg))
|
|
{
|
|
$ret.=$this->display_warning($msg, _("Attention : il vaut mieux utiliser les fiches que les postes comptables"));
|
|
}
|
|
$ret.="<table >";
|
|
$ret.="<tr><td>" . _('Date') . " : </td><td>$e_date</td></tr>";
|
|
/* display periode */
|
|
$date_limit = $lPeriode->get_date_limit();
|
|
$ret.='<tr> ' . td(_('Période Comptable')) . td($date_limit['p_start'] . '-' . $date_limit['p_end']) . '</tr>';
|
|
$ret.="<tr><td>" . _('Libellé') . " </td><td>" . h($desc) . "</td></tr>";
|
|
$ret.="<tr><td>" . _('PJ Num') . " </td><td>" . h($e_pj) . "</td></tr>";
|
|
$ret.='</table>';
|
|
$ret.="<table class=\"result\">";
|
|
$ret.="<tr>";
|
|
$ret.="<th>" . _('Quick Code ou ');
|
|
$ret.=_("Poste") . " </th>";
|
|
$ret.="<th style=\"text-align:left\"> " . _("Libellé") . " </th>";
|
|
$ret.="<th style=\"text-align:right\">" . _("Débit") . "</th>";
|
|
$ret.="<th style=\"text-align:right\">" . _("Crédit") . "</th>";
|
|
/* if we use the AC */
|
|
if ($g_parameter->MY_ANALYTIC != 'nu')
|
|
{
|
|
$anc = new Anc_Plan($this->db);
|
|
$a_anc = $anc->get_list();
|
|
$x = count($a_anc);
|
|
/* set the width of the col */
|
|
$ret.='<th colspan="' . $x . '" style="width:auto;text-align:center" >' . _('Compt. Analytique') . '</th>';
|
|
|
|
/* add hidden variables pa[] to hold the value of pa_id */
|
|
$ret.=Anc_Plan::hidden($a_anc);
|
|
}
|
|
$ret.="</tr>";
|
|
|
|
$ret.=HtmlInput::hidden('e_date', $e_date);
|
|
$ret.=HtmlInput::hidden('desc', $desc);
|
|
$ret.=HtmlInput::hidden('period', $lPeriode->p_id);
|
|
$ret.=HtmlInput::hidden('e_pj', $e_pj);
|
|
$ret.=HtmlInput::hidden('e_pj_suggest', $e_pj_suggest);
|
|
$mt = microtime(true);
|
|
$ret.=HtmlInput::hidden('mt', $mt);
|
|
// For predefined operation
|
|
$ret.=HtmlInput::hidden('e_comm', $desc);
|
|
$ret.=HtmlInput::hidden('jrn_type', $this->get_type());
|
|
$ret.=HtmlInput::hidden('p_jrn', $this->id);
|
|
$ret.=HtmlInput::hidden('nb_item', $nb_item);
|
|
if ($this->with_concerned == true)
|
|
{
|
|
$ret.=HtmlInput::hidden('jrn_concerned', $jrn_concerned);
|
|
}
|
|
$ret.=dossier::hidden();
|
|
$count = 0;
|
|
for ($i = 0; $i < $nb_item; $i++)
|
|
{
|
|
if ($p_readonly == true)
|
|
{
|
|
if (!isset(${'qc_' . $i}))
|
|
${'qc_' . $i} = '';
|
|
if (!isset(${'poste' . $i}))
|
|
${'poste' . $i} = '';
|
|
if (!isset(${'amount' . $i}))
|
|
${'amount' . $i} = '';
|
|
}
|
|
$class=($i%2==0)?' class="even" ':' class="odd" ';
|
|
$ret.="<tr $class> ";
|
|
if (trim(${'qc_' . $i}) != "")
|
|
{
|
|
$oqc = new Fiche($this->db);
|
|
$oqc->get_by_qcode(${'qc_' . $i}, false);
|
|
$strPoste = $oqc->strAttribut(ATTR_DEF_ACCOUNT);
|
|
$ret.="<td>" .
|
|
${'qc_' . $i} . ' - ' .
|
|
$oqc->strAttribut(ATTR_DEF_NAME) . HtmlInput::hidden('qc_' . $i, ${'qc_' . $i}) .
|
|
'</td>';
|
|
}
|
|
|
|
if (trim(${'qc_' . $i}) == "" && trim(${'poste' . $i}) != "")
|
|
{
|
|
$oposte = new Acc_Account_Ledger($this->db, ${'poste' . $i});
|
|
$strPoste = $oposte->id;
|
|
$ret.="<td>" . h(${"poste" . $i} . " - " .
|
|
$oposte->get_name()) . HtmlInput::hidden('poste' . $i, ${'poste' . $i}) .
|
|
'</td>';
|
|
}
|
|
|
|
if (trim(${'qc_' . $i}) == "" && trim(${'poste' . $i}) == "")
|
|
continue;
|
|
$ret.="<td>" . h(${"ld" . $i}) . HtmlInput::hidden('ld' . $i, ${'ld' . $i}) ;
|
|
$ret .=(isset(${"ck$i"})) ? HtmlInput::hidden('ck' . $i, ${'ck' . $i}) : "";
|
|
$ret .= "</td>";
|
|
if (isset(${"ck$i"}))
|
|
{
|
|
$ret.="<td class=\"num\">" . nbm(${"amount" . $i}) . HtmlInput::hidden('amount' . $i, ${'amount' . $i}) . "</td>" . td("");
|
|
$total_deb = bcadd($total_deb, ${'amount' . $i});
|
|
}
|
|
else
|
|
{
|
|
$ret.=td("") . "<td class=\"num\">" . nbm(${"amount" . $i}) . HtmlInput::hidden('amount' . $i, ${'amount' . $i}) . "</td>";
|
|
$total_cred = bcadd($total_cred, ${"amount" . $i});
|
|
}
|
|
/*$ret.="<td>";
|
|
$ret.=(isset(${"ck$i"})) ? HtmlInput::hidden('ck' . $i, ${'ck' . $i}) : "";
|
|
$ret.="</td>";*/
|
|
// CA
|
|
|
|
if ($g_parameter->MY_ANALYTIC != 'nu') // use of AA
|
|
{
|
|
if (preg_match("/^[6,7]+/", $strPoste) == 1)
|
|
{
|
|
// show form
|
|
$op = new Anc_Operation($this->db);
|
|
$null = ($g_parameter->MY_ANALYTIC == 'op') ? 1 : 0;
|
|
$p_array['pa_id'] = $a_anc;
|
|
/* op is the operation it contains either a sequence or a jrnx.j_id */
|
|
$ret.=HtmlInput::hidden('op[]=', $i);
|
|
|
|
$ret.='<td style="text-align:center">';
|
|
$read = ($p_readonly == true) ? 0 : 1;
|
|
$ret.=$op->display_form_plan($p_array, $null, $read, $count, round(${'amount' . $i}, 2));
|
|
$ret.='</td>';
|
|
$count++;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
$ret.="</tr>";
|
|
}
|
|
$ret.=tr(td('') . td(_('Totaux')) . td($total_deb, 'class="num"') . td($total_cred, 'class="num"'), 'class="highlight"');
|
|
$ret.="</table>";
|
|
if ($g_parameter->MY_ANALYTIC != 'nu' && $p_readonly == false)
|
|
$ret.='<input type="button" class="button" value="' . _('verifie Imputation Analytique') . '" onClick="verify_ca(\'\');">';
|
|
return $ret;
|
|
}
|
|
function get_min_row()
|
|
{
|
|
$row=$this->db->get_value("select jrn_deb_max_line from jrn_def where jrn_def_id=$1",array($this->id));
|
|
return $row;
|
|
}
|
|
/**
|
|
* @brief Show the form to encode your operation
|
|
* @param$p_array if you correct or use a predef operation (default = null)
|
|
* @param$p_readonly 1 for readonly 0 for writable (default 0)
|
|
*@exception if ledger not found
|
|
* \return a string containing the form
|
|
*/
|
|
|
|
function input($p_array = null, $p_readonly = 0)
|
|
{
|
|
global $g_parameter, $g_user;
|
|
$this->nb=$this->get_min_row();
|
|
if ($p_readonly == 1)
|
|
return $this->confirm($p_array);
|
|
|
|
if ($p_array != null)
|
|
extract($p_array);
|
|
$add_js = "";
|
|
if ($g_parameter->MY_PJ_SUGGEST == 'Y')
|
|
{
|
|
$add_js = "update_pj();";
|
|
}
|
|
if ($g_parameter->MY_DATE_SUGGEST=='Y')
|
|
{
|
|
$add_js.='get_last_date();';
|
|
}
|
|
$add_js.='update_row("quick_item");';
|
|
$ret = "";
|
|
if ($g_user->check_action(FICADD) == 1)
|
|
{
|
|
/* Add button */
|
|
$f_add_button = new IButton('add_card');
|
|
$f_add_button->label = _('Créer une nouvelle fiche');
|
|
$f_add_button->set_attribute('ipopup', 'ipop_newcard');
|
|
$f_add_button->set_attribute('jrn', $this->id);
|
|
$f_add_button->javascript = " this.jrn=\$('p_jrn').value;select_card_type(this);";
|
|
$f_add_button->input();
|
|
}
|
|
$wLedger = $this->select_ledger('ODS', 2);
|
|
if ($wLedger == null)
|
|
throw new Exception(_('Pas de journal disponible'));
|
|
$wLedger->javascript = "onChange='update_name();update_predef(\"ods\",\"t\",\"".$_REQUEST['ac']."\");$add_js'";
|
|
$label = " Journal " . HtmlInput::infobulle(2);
|
|
|
|
$ret.=$label . $wLedger->input();
|
|
|
|
|
|
// Load the javascript
|
|
//
|
|
$ret.="<table>";
|
|
$ret.= '<tr ><td colspan="2" style="width:auto">';
|
|
$wDate = new IDate('e_date');
|
|
$wDate->readonly = $p_readonly;
|
|
$e_date = (isset($e_date) && trim($e_date) != '') ? $e_date : '';
|
|
$wDate->value = $e_date;
|
|
|
|
$ret.=_("Date") . ' : ' . $wDate->input();
|
|
$ret.= '</td>';
|
|
/* insert periode if needed */
|
|
// Periode
|
|
//--
|
|
if ($this->check_periode() == true)
|
|
{
|
|
$l_user_per = $g_user->get_periode();
|
|
$def = (isset($periode)) ? $periode : $l_user_per;
|
|
|
|
$period = new IPeriod("period");
|
|
$period->user = $g_user;
|
|
$period->cn = $this->db;
|
|
$period->value = $def;
|
|
$period->type = OPEN;
|
|
try
|
|
{
|
|
$l_form_per = $period->input();
|
|
}
|
|
catch (Exception $e)
|
|
{
|
|
if ($e->getCode() == 1)
|
|
{
|
|
echo _("Aucune période ouverte");
|
|
exit();
|
|
}
|
|
}
|
|
$label = HtmlInput::infobulle(3);
|
|
$f_periode = _("Période comptable") . " $label " . $l_form_per;
|
|
$ret.=td($f_periode);
|
|
}
|
|
$wPJ = new IText('e_pj');
|
|
$wPJ->readonly = false;
|
|
$wPJ->size = 10;
|
|
|
|
/* suggest PJ ? */
|
|
$default_pj = '';
|
|
if ($g_parameter->MY_PJ_SUGGEST == 'Y')
|
|
{
|
|
$default_pj = $this->guess_pj();
|
|
}
|
|
$wPJ->value = (isset($e_pj)) ? $e_pj : $default_pj;
|
|
$ret.= '</tr>';
|
|
$ret.='<tr >';
|
|
$ret.='<td colspan="2" style="width:auto"> ' . _('Pièce') . ' : ' . $wPJ->input();
|
|
$ret.=HtmlInput::hidden('e_pj_suggest', $default_pj);
|
|
$ret.= '</tr>';
|
|
$ret.= '</td>';
|
|
|
|
$ret.= '<tr>';
|
|
$ret.='<td colspan="2" style="width:auto">';
|
|
$ret.=_('Libellé');
|
|
$wDescription = new IText('desc');
|
|
$wDescription->readonly = $p_readonly;
|
|
$wDescription->size = "50";
|
|
$wDescription->value = (isset($desc)) ? $desc : '';
|
|
|
|
$ret.=$wDescription->input();
|
|
$ret.= '</td>';
|
|
$ret.='</tr>';
|
|
|
|
$ret.= '</table>';
|
|
$nb_row = (isset($nb_item) ) ? $nb_item : $this->nb;
|
|
|
|
$ret.=HtmlInput::hidden('nb_item', $nb_row);
|
|
$ret.=dossier::hidden();
|
|
|
|
$ret.=dossier::hidden();
|
|
|
|
$ret.=HtmlInput::hidden('jrn_type', $this->get_type());
|
|
$info = HtmlInput::infobulle(0);
|
|
$info_poste = HtmlInput::infobulle(9);
|
|
if ($g_user->check_action(FICADD) == 1)
|
|
$ret.=$f_add_button->input();
|
|
$ret.='<table id="quick_item" style="position:float;width:100%">';
|
|
$ret.='<tr>' .
|
|
'<th style="text-align:left">Quickcode' . $info . '</th>' .
|
|
'<th style="text-align:left">' . _('Poste') . $info_poste . '</th>' .
|
|
'<th style="text-align:left">' . _('Libellé') . '</th>' .
|
|
'<th style="text-align:left">' . _('Montant') . '</th>' .
|
|
'<th style="text-align:left">' . _('Débit') . '</th>' .
|
|
'</tr>';
|
|
|
|
|
|
for ($i = 0; $i < $nb_row; $i++)
|
|
{
|
|
// Quick Code
|
|
$quick_code = new ICard('qc_' . $i);
|
|
$quick_code->set_dblclick("fill_ipopcard(this);");
|
|
$quick_code->set_attribute('ipopup', 'ipopcard');
|
|
|
|
// name of the field to update with the name of the card
|
|
$quick_code->set_attribute('label', "ld" . $i);
|
|
|
|
// name of the field to update with the name of the card
|
|
$quick_code->set_attribute('typecard', 'filter');
|
|
|
|
// Add the callback function to filter the card on the jrn
|
|
$quick_code->set_callback('filter_card');
|
|
$quick_code->set_function('fill_data');
|
|
$quick_code->javascript = sprintf(' onchange="fill_data_onchange(\'%s\');" ', $quick_code->name);
|
|
|
|
$quick_code->value = (isset(${'qc_' . $i})) ? ${'qc_' . $i} : "";
|
|
$quick_code->readonly = $p_readonly;
|
|
|
|
$label = '';
|
|
if ($quick_code->value != '')
|
|
{
|
|
$Fiche = new Fiche($this->db);
|
|
$Fiche->get_by_qcode($quick_code->value);
|
|
$label = $Fiche->strAttribut(ATTR_DEF_NAME);
|
|
}
|
|
|
|
|
|
// Account
|
|
$poste = new IPoste();
|
|
$poste->name = 'poste' . $i;
|
|
$poste->set_attribute('jrn', $this->id);
|
|
$poste->set_attribute('ipopup', 'ipop_account');
|
|
$poste->set_attribute('label', 'ld' . $i);
|
|
$poste->set_attribute('account', 'poste' . $i);
|
|
$poste->set_attribute('dossier', Dossier::id());
|
|
|
|
$poste->value = (isset(${'poste' . $i})) ? ${"poste" . $i} : ''
|
|
;
|
|
$poste->dbl_click_history();
|
|
|
|
$poste->readonly = $p_readonly;
|
|
|
|
if ($poste->value != '')
|
|
{
|
|
$Poste = new Acc_Account($this->db);
|
|
$Poste->set_parameter('value', $poste->value);
|
|
$label = $Poste->get_lib();
|
|
}
|
|
|
|
// Description of the line
|
|
$line_desc = new IText();
|
|
$line_desc->name = 'ld' . $i;
|
|
$line_desc->size = 30;
|
|
$line_desc->value = (isset(${"ld" . $i})) ? ${"ld" . $i} :
|
|
$label;
|
|
|
|
// Amount
|
|
$amount = new INum();
|
|
$amount->size = 10;
|
|
$amount->name = 'amount' . $i;
|
|
$amount->value = (isset(${'amount' . $i})) ? ${"amount" . $i} : ''
|
|
;
|
|
$amount->readonly = $p_readonly;
|
|
$amount->javascript = ' onChange="format_number(this);checkTotalDirect()"';
|
|
// D/C
|
|
$deb = new ICheckBox();
|
|
$deb->name = 'ck' . $i;
|
|
$deb->selected = (isset(${'ck' . $i})) ? true : false;
|
|
$deb->readonly = $p_readonly;
|
|
$deb->javascript = ' onChange="checkTotalDirect()"';
|
|
|
|
$ret.='<tr>';
|
|
$ret.='<td>' . $quick_code->input() . $quick_code->search() . '</td>';
|
|
$ret.='<td>' . $poste->input() .
|
|
'<script> document.getElementById(\'poste' . $i . '\').onblur=function(){ if (trim(this.value) !=\'\') {document.getElementById(\'qc_' . $i . '\').value="";}}</script>' .
|
|
'</td>';
|
|
$ret.='<td>' . $line_desc->input() . '</td>';
|
|
$ret.='<td>' . $amount->input() . '</td>';
|
|
$ret.='<td>' . $deb->input() . '</td>';
|
|
$ret.='</tr>';
|
|
// If readonly == 1 then show CA
|
|
}
|
|
$ret.='</table>';
|
|
if (isset($this->with_concerned) && $this->with_concerned == true)
|
|
{
|
|
$oRapt = new Acc_Reconciliation($this->db);
|
|
$w = $oRapt->widget();
|
|
$w->name = 'jrn_concerned';
|
|
$w->value = (isset($jrn_concerned)) ? $jrn_concerned : "";
|
|
$ret.="Réconciliation/rapprochements : " . $w->input();
|
|
}
|
|
$ret.= create_script("$('".$wDate->id."').focus()");
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* check if the current ledger is closed
|
|
* \return 1 for yes, otherwise 0
|
|
* \see Periode::is_closed
|
|
*/
|
|
|
|
function is_closed($p_periode)
|
|
{
|
|
$per = new Periode($this->db);
|
|
$per->set_jrn($this->id);
|
|
$per->set_periode($p_periode);
|
|
$ret = $per->is_closed();
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* @brief verify that the operation can be saved
|
|
* @param$p_array array of data same layout that the $_POST from show_form
|
|
*
|
|
*
|
|
* \throw the getcode value is 1 incorrect balance, 2 date
|
|
* invalid, 3 invalid amount, 4 the card is not in the range of
|
|
* permitted card, 5 not in the user's period, 6 closed period
|
|
*
|
|
*/
|
|
|
|
function verify($p_array)
|
|
{
|
|
if (is_array($p_array ) == false || empty($p_array))
|
|
throw new Exception ("Array empty");
|
|
/*
|
|
* Check needed value
|
|
*/
|
|
check_parameter($p_array,'p_jrn,e_date');
|
|
|
|
extract($p_array);
|
|
global $g_user;
|
|
$tot_cred = 0;
|
|
$tot_deb = 0;
|
|
$msg = array();
|
|
|
|
/* check if we can write into this ledger */
|
|
if ($g_user->check_jrn($p_jrn) != 'W')
|
|
throw new Exception(_('Accès interdit'), 20);
|
|
|
|
/* check for a double reload */
|
|
if (isset($mt) && $this->db->count_sql('select jr_mt from jrn where jr_mt=$1', array($mt)) != 0)
|
|
throw new Exception('Double Encodage', 5);
|
|
|
|
// Check the periode and the date
|
|
if (isDate($e_date) == null)
|
|
{
|
|
throw new Exception('Date invalide', 2);
|
|
}
|
|
$periode = new Periode($this->db);
|
|
/* find the periode if we have enabled the check_periode */
|
|
if ($this->check_periode() == false)
|
|
{
|
|
$periode->find_periode($e_date);
|
|
}
|
|
else
|
|
{
|
|
$periode->p_id = $period;
|
|
list ($min, $max) = $periode->get_date_limit();
|
|
if (cmpDate($e_date, $min) < 0 ||
|
|
cmpDate($e_date, $max) > 0)
|
|
throw new Exception(_('Date et periode ne correspondent pas'), 6);
|
|
}
|
|
|
|
|
|
|
|
// Periode ferme
|
|
if ($this->is_closed($periode->p_id) == 1)
|
|
{
|
|
throw new Exception('Periode fermee', 6);
|
|
}
|
|
/* check if we are using the strict mode */
|
|
if ($this->check_strict() == true)
|
|
{
|
|
/* if we use the strict mode, we get the date of the last
|
|
operation */
|
|
$last_date = $this->get_last_date();
|
|
if ($last_date != null && cmpDate($e_date, $last_date) < 0)
|
|
throw new Exception(_('Vous utilisez le mode strict la dernière operation est la date du ')
|
|
. $last_date . ' ' . _('vous ne pouvez pas encoder à une date antérieure'), 15);
|
|
}
|
|
|
|
for ($i = 0; $i < $nb_item; $i++)
|
|
{
|
|
$err = 0;
|
|
|
|
// Check the balance
|
|
if (!isset(${'amount' . $i}))
|
|
continue;
|
|
|
|
$amount = round(${'amount' . $i}, 2);
|
|
$tot_deb+=(isset(${'ck' . $i})) ? $amount : 0;
|
|
$tot_cred+=(!isset(${'ck' . $i})) ? $amount : 0;
|
|
|
|
// Check if the card is permitted
|
|
if (isset(${'qc_' . $i}) && trim(${'qc_' . $i}) != "")
|
|
{
|
|
$f = new Fiche($this->db);
|
|
$f->quick_code = ${'qc_' . $i};
|
|
if ($f->belong_ledger($p_jrn) < 0)
|
|
throw new Exception("La fiche quick_code = " .
|
|
$f->quick_code . " n'est pas dans ce journal", 4);
|
|
if (strlen(trim(${'qc_' . $i})) != 0 && isNumber(${'amount' . $i}) == 0)
|
|
throw new Exception('Montant invalide', 3);
|
|
|
|
$strPoste = $f->strAttribut(ATTR_DEF_ACCOUNT);
|
|
if ($strPoste == '')
|
|
throw new Exception(sprintf(_("La fiche %s n'a pas de poste comptable"), ${"qc_" . $i}));
|
|
|
|
$p = new Acc_Account_Ledger($this->db, $strPoste);
|
|
if ($p->do_exist() == 0)
|
|
throw new Exception(_('Poste Inexistant pour la fiche [' . ${'qc_' . $i} . ']'), 4);
|
|
}
|
|
|
|
// Check if the account is permitted
|
|
if (isset(${'poste' . $i}) && strlen(trim(${'poste' . $i})) != 0)
|
|
{
|
|
$p = new Acc_Account_Ledger($this->db, ${'poste' . $i});
|
|
if ($p->belong_ledger($p_jrn) < 0)
|
|
throw new Exception(_("Le poste") . " " . $p->id . " " . _("n'est pas dans ce journal"), 5);
|
|
if (strlen(trim(${'poste' . $i})) != 0 && isNumber(${'amount' . $i}) == 0)
|
|
throw new Exception(_('Poste invalide [' . ${'poste' . $i} . ']'), 3);
|
|
if ($p->do_exist() == 0)
|
|
throw new Exception(_('Poste Inexistant [' . ${'poste' . $i} . ']'), 4);
|
|
$card_id = $p->find_card();
|
|
if (!empty($card_id))
|
|
{
|
|
$str_msg = " Le poste " . $p->id . " appartient à " . count($card_id) . " fiche(s) dont :";
|
|
$max = (count($card_id) > MAX_COMPTE_CARD) ? MAX_COMPTE_CARD : count($card_id);
|
|
for ($x = 0; $x < $max; $x++)
|
|
{
|
|
$card = new Fiche($this->db, $card_id[$x]['f_id']);
|
|
$str_msg.=HtmlInput::card_detail($card->strAttribut(ATTR_DEF_QUICKCODE), $card->strAttribut(ATTR_DEF_NAME), 'style="color:red;display:inline;text-decoration:underline"');
|
|
$str_msg.=" ";
|
|
}
|
|
$msg[] = $str_msg;
|
|
}
|
|
}
|
|
}
|
|
$tot_deb = round($tot_deb, 4);
|
|
$tot_cred = round($tot_cred, 4);
|
|
if ($tot_deb != $tot_cred)
|
|
{
|
|
throw new Exception(_("Balance incorrecte ") . " debit = $tot_deb credit=$tot_cred ", 1);
|
|
}
|
|
|
|
return $msg;
|
|
}
|
|
|
|
/**
|
|
* @brief compute the internal code of the saved operation and set the $this->jr_internal to
|
|
* the computed value
|
|
*
|
|
* @param$p_grpt id in jr_grpt_
|
|
*
|
|
* \return string internal_code
|
|
* -
|
|
*
|
|
*/
|
|
|
|
function compute_internal_code($p_grpt)
|
|
{
|
|
if ($this->id == 0)
|
|
return;
|
|
$num = $this->db->get_next_seq('s_internal');
|
|
$atype = $this->get_propertie();
|
|
$type = substr($atype['jrn_def_code'], 0, 1);
|
|
$internal_code = sprintf("%s%06X", $type, $num);
|
|
$this->jr_internal = $internal_code;
|
|
return $internal_code;
|
|
}
|
|
|
|
/**
|
|
* @brief save the operation into the jrnx,jrn, ,
|
|
* CA and pre_def
|
|
* @param$p_array
|
|
*
|
|
* \return array with [0] = false if failed otherwise true, [1] error
|
|
* code
|
|
*/
|
|
|
|
function save($p_array = null)
|
|
{
|
|
if ($p_array == null)
|
|
throw new Exception('save cannot use a empty array');
|
|
global $g_parameter;
|
|
extract($p_array);
|
|
try
|
|
{
|
|
$msg = $this->verify($p_array);
|
|
if (!empty($msg))
|
|
{
|
|
echo $this->display_warning($msg, _("Attention : il vaut mieux utiliser les fiches que les postes comptables "));
|
|
}
|
|
$this->db->start();
|
|
|
|
$seq = $this->db->get_next_seq('s_grpt');
|
|
$internal = $this->compute_internal_code($seq);
|
|
|
|
$group = $this->db->get_next_seq("s_oa_group");
|
|
$tot_amount = 0;
|
|
$tot_deb = 0;
|
|
$tot_cred = 0;
|
|
$oPeriode = new Periode($this->db);
|
|
$check_periode = $this->check_periode();
|
|
if ($check_periode == false)
|
|
{
|
|
$oPeriode->find_periode($e_date);
|
|
}
|
|
else
|
|
{
|
|
$oPeriode->id = $period;
|
|
}
|
|
|
|
$count = 0;
|
|
for ($i = 0; $i < $nb_item; $i++)
|
|
{
|
|
if (!isset(${'qc_' . $i}) && !isset(${'poste' . $i}))
|
|
continue;
|
|
$acc_op = new Acc_Operation($this->db);
|
|
$quick_code = "";
|
|
// First we save the jrnx
|
|
if (isset(${'qc_' . $i}))
|
|
{
|
|
$qc = new Fiche($this->db);
|
|
$qc->get_by_qcode(${'qc_' . $i}, false);
|
|
$sposte = $qc->strAttribut(ATTR_DEF_ACCOUNT);
|
|
/* if there are 2 accounts take following the deb or cred */
|
|
if (strpos($sposte, ',') != 0)
|
|
{
|
|
$array = explode(",", $sposte);
|
|
$poste = (isset(${'ck' . $i})) ? $array[0] : $array[1];
|
|
}
|
|
else
|
|
{
|
|
$poste = $sposte;
|
|
if ($poste == '')
|
|
throw new Exception(sprintf(_("La fiche %s n'a pas de poste comptable"), ${"qc_" . $i}));
|
|
}
|
|
$quick_code = ${'qc_' . $i};
|
|
}
|
|
else
|
|
{
|
|
$poste = ${'poste' . $i};
|
|
}
|
|
|
|
$acc_op->date = $e_date;
|
|
// compute the periode is do not check it
|
|
if ($check_periode == false)
|
|
$acc_op->periode = $oPeriode->p_id;
|
|
$acc_op->desc = null;
|
|
if (strlen(trim(${'ld' . $i})) != 0)
|
|
$acc_op->desc = ${'ld' . $i};
|
|
$acc_op->amount = round(${'amount' . $i}, 2);
|
|
$acc_op->grpt = $seq;
|
|
$acc_op->poste = $poste;
|
|
$acc_op->jrn = $this->id;
|
|
$acc_op->type = (isset(${'ck' . $i})) ? 'd' : 'c';
|
|
$acc_op->qcode = $quick_code;
|
|
$j_id = $acc_op->insert_jrnx();
|
|
$tot_amount+=round($acc_op->amount, 2);
|
|
$tot_deb+=($acc_op->type == 'd') ? $acc_op->amount : 0;
|
|
$tot_cred+=($acc_op->type == 'c') ? $acc_op->amount : 0;
|
|
if ($g_parameter->MY_ANALYTIC != "nu")
|
|
{
|
|
if (preg_match("/^[6,7]+/", $poste) == 1)
|
|
{
|
|
|
|
// for each item, insert into operation_analytique */
|
|
$op = new Anc_Operation($this->db);
|
|
$op->oa_group = $group;
|
|
$op->j_id = $j_id;
|
|
$op->oa_date = $e_date;
|
|
$op->oa_debit = ($acc_op->type == 'd' ) ? 't' : 'f';
|
|
$op->oa_description = $desc;
|
|
$op->save_form_plan($p_array, $count, $j_id);
|
|
$count++;
|
|
}
|
|
}
|
|
}// loop for each item
|
|
$acc_end = new Acc_Operation($this->db);
|
|
$acc_end->amount = $tot_deb;
|
|
if ($check_periode == false)
|
|
$acc_end->periode = $oPeriode->p_id;
|
|
$acc_end->date = $e_date;
|
|
$acc_end->desc = $desc;
|
|
$acc_end->grpt = $seq;
|
|
$acc_end->jrn = $this->id;
|
|
$acc_end->mt = $mt;
|
|
$jr_id = $acc_end->insert_jrn();
|
|
$this->jr_id = $jr_id;
|
|
if ($jr_id == false)
|
|
throw new Exception(_('Balance incorrecte'));
|
|
$acc_end->pj = $e_pj;
|
|
|
|
/* if e_suggest != e_pj then do not increment sequence */
|
|
if (strcmp($e_pj, $e_pj_suggest) == 0 && strlen(trim($e_pj)) != 0)
|
|
{
|
|
$this->inc_seq_pj();
|
|
}
|
|
|
|
$this->pj = $acc_end->set_pj();
|
|
|
|
$this->db->exec_sql("update jrn set jr_internal='" . $internal . "' where " .
|
|
" jr_grpt_id = " . $seq);
|
|
$this->internal = $internal;
|
|
// Save now the predef op
|
|
//------------------------
|
|
if (isset ($opd_name) && trim($opd_name) != "" ){
|
|
$opd = new Pre_Op_Advanced($this->db);
|
|
$opd->get_post();
|
|
$opd->save();
|
|
}
|
|
|
|
if (isset($this->with_concerned) && $this->with_concerned == true)
|
|
{
|
|
$orap = new acc_reconciliation($this->db);
|
|
$orap->jr_id = $jr_id;
|
|
|
|
$orap->insert($jrn_concerned);
|
|
}
|
|
}
|
|
catch (Exception $a)
|
|
{
|
|
throw $a;
|
|
}
|
|
catch (Exception $e)
|
|
{
|
|
$this->db->rollback();
|
|
echo _('OPERATION ANNULEE ');
|
|
echo '<hr>';
|
|
echo __FILE__ . __LINE__ . $e->getMessage();
|
|
exit();
|
|
}
|
|
$this->db->commit();
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @brief get all the data from request and build the object
|
|
*/
|
|
|
|
function get_request()
|
|
{
|
|
$this->id = $_REQUEST['p_jrn'];
|
|
}
|
|
|
|
/**
|
|
* @brief retrieve the next number for this type of ledger
|
|
* @paramp_cn connx
|
|
* @paramp_type ledger type
|
|
*
|
|
* \return the number
|
|
*
|
|
*
|
|
*/
|
|
|
|
static function next_number($p_cn, $p_type)
|
|
{
|
|
|
|
$Ret = $p_cn->count_sql("select * from jrn_def where jrn_def_type='" . $p_type . "'");
|
|
return $Ret + 1;
|
|
}
|
|
|
|
/**
|
|
* @brief get the first ledger
|
|
* @paramthe type
|
|
* \return the j_id
|
|
*/
|
|
|
|
public function get_first($p_type, $p_access = 3)
|
|
{
|
|
global $g_user;
|
|
$all = $g_user->get_ledger($p_type, $p_access);
|
|
return $all[0];
|
|
}
|
|
|
|
/**
|
|
* @brief Update the paiment in the list of operation
|
|
* @param$p_array is normally $_GET
|
|
*/
|
|
|
|
function update_paid($p_array)
|
|
{
|
|
// reset all the paid flag because the checkbox is post only
|
|
// when checked
|
|
foreach ($p_array as $name => $paid)
|
|
{
|
|
list($ad) = sscanf($name, "set_jr_id%d");
|
|
if ($ad == null)
|
|
continue;
|
|
$sql = "update jrn set jr_rapt='' where jr_id=$ad";
|
|
$Res = $this->db->exec_sql($sql);
|
|
}
|
|
// set a paid flag for the checked box
|
|
foreach ($p_array as $name => $paid)
|
|
{
|
|
list ($id) = sscanf($name, "rd_paid%d");
|
|
if ($id == null)
|
|
continue;
|
|
|
|
$sql = "update jrn set jr_rapt='paid' where jr_id=$id";
|
|
$Res = $this->db->exec_sql($sql);
|
|
}
|
|
}
|
|
|
|
function update_internal_code($p_internal)
|
|
{
|
|
if (!isset($this->grpt_id))
|
|
throw new Exception(('ERREUR ' . __FILE__ . ":" . __LINE__));
|
|
$Res = $this->db->exec_sql("update jrn set jr_internal='" . $p_internal . "' where " .
|
|
" jr_grpt_id = " . $this->grpt_id);
|
|
}
|
|
/**
|
|
* Return an array of default card for the ledger type given
|
|
*
|
|
* @param $p_ledger_type VEN ACH ODS or FIN
|
|
* @param $p_side D for Debit or C for credit or NA No Applicable
|
|
*/
|
|
function get_default_card($p_ledger_type,$p_side)
|
|
{
|
|
$array=array();
|
|
$fiche_def_ref=new Fiche_Def_Ref($this->db);
|
|
// ----- for FINANCIAL ----
|
|
if ($p_ledger_type =='FIN')
|
|
{
|
|
$array=$fiche_def_ref->get_by_modele(FICHE_TYPE_CLIENT);
|
|
$array=array_merge ( $array , $fiche_def_ref->get_by_modele(FICHE_TYPE_FOURNISSEUR));
|
|
$array=array_merge ( $array , $fiche_def_ref->get_by_modele(FICHE_TYPE_FIN));
|
|
$array=array_merge ( $array , $fiche_def_ref->get_by_modele(FICHE_TYPE_ADM_TAX));
|
|
$array=array_merge ( $array , $fiche_def_ref->get_by_modele(FICHE_TYPE_EMPL));
|
|
|
|
}
|
|
// --- for miscellaneous ----
|
|
if ($p_ledger_type == 'ODS')
|
|
{
|
|
$result=$this->db->get_array('select fd_id from fiche_def');
|
|
for ($i = 0;$i<count($result);$i++ )
|
|
{
|
|
$array[$i]=$result[$i]['fd_id'];
|
|
}
|
|
}
|
|
if ($p_side == 'D')
|
|
{
|
|
switch($p_ledger_type)
|
|
{
|
|
case 'VEN':
|
|
$array=$fiche_def_ref->get_by_modele(FICHE_TYPE_CLIENT);
|
|
break;
|
|
case 'ACH':
|
|
$array=$fiche_def_ref->get_by_modele(FICHE_TYPE_ACH_SER);
|
|
$array=array_merge ($array, $fiche_def_ref->get_by_modele(FICHE_TYPE_ACH_MAR));
|
|
$array=array_merge ($array,$fiche_def_ref->get_by_modele(FICHE_TYPE_ACH_MAT));
|
|
break;
|
|
default :
|
|
throw new Exception(_('get_default_card p_ledger_side is invalide ['.$p_ledger_type.']'));
|
|
|
|
}
|
|
} elseif ($p_side == 'C')
|
|
{
|
|
switch($p_ledger_type)
|
|
{
|
|
case 'VEN':
|
|
$array=$fiche_def_ref->get_by_modele(FICHE_TYPE_VENTE);
|
|
break;
|
|
case 'ACH':
|
|
$array= array_merge($array, $fiche_def_ref->get_by_modele(FICHE_TYPE_ADM_TAX));
|
|
$array= array_merge($array, $fiche_def_ref->get_by_modele(FICHE_TYPE_FOURNISSEUR));
|
|
break;
|
|
default :
|
|
throw new Exception(_('get_default_card p_ledger_side is invalide ['.$p_ledger_type.']'));
|
|
|
|
}
|
|
}
|
|
return $array;
|
|
/*
|
|
$return=array();
|
|
$return = array_values($array);
|
|
for ($i = 0;$i<count($array);$i++ )
|
|
{
|
|
$return[$i]=$array[$i]['fd_id'];
|
|
}
|
|
return $return;
|
|
*
|
|
*/
|
|
}
|
|
/**
|
|
* @brief retrieve all the card for this type of ledger, make them
|
|
* into a string separated by comma
|
|
* @paramnone
|
|
* \return all the card or null is nothing is found
|
|
*/
|
|
|
|
function get_all_fiche_def()
|
|
{
|
|
$sql = "select jrn_def_fiche_deb as deb,jrn_def_fiche_cred as cred " .
|
|
" from jrn_def where " .
|
|
" jrn_def_id = $1 ";
|
|
|
|
$r = $this->db->exec_sql($sql, array($this->id));
|
|
|
|
$res = Database::fetch_all($r);
|
|
if (empty($res))
|
|
return null;
|
|
$card = "";
|
|
$comma = '';
|
|
foreach ($res as $item)
|
|
{
|
|
if (strlen(trim($item['deb'])) != 0)
|
|
{
|
|
$card.=$comma . $item['deb'];
|
|
$comma = ',';
|
|
}
|
|
if (strlen(trim($item['cred'])) != '')
|
|
{
|
|
$card.=$comma . $item['cred'];
|
|
$comma = ',';
|
|
}
|
|
}
|
|
|
|
return $card;
|
|
}
|
|
|
|
/**
|
|
* @brief get the saldo of an exercice, used for the opening of a folder
|
|
* @param$p_exercice is the exercice we want
|
|
* \return an array
|
|
* index =
|
|
* - solde (debit > 0 ; credit < 0)
|
|
* - j_poste
|
|
* - j_qcode
|
|
*/
|
|
|
|
function get_saldo_exercice($p_exercice)
|
|
{
|
|
$sql = "select sum(a.montant) as solde, j_poste, j_qcode
|
|
from
|
|
(select j_id, case when j_debit='t' then j_montant
|
|
else j_montant * (-1) end as montant
|
|
from jrnx) as a
|
|
join jrnx using (j_id)
|
|
join parm_periode on (j_tech_per = p_id )
|
|
where
|
|
p_exercice=$1
|
|
and j_poste::text not like '7%'
|
|
and j_poste::text not like '6%'
|
|
group by j_poste,j_qcode
|
|
having (sum(a.montant) != 0 )";
|
|
$res = $this->db->get_array($sql, array($p_exercice));
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* @brief Check if a Dossier is using the strict mode or not
|
|
* \return true if we are using the strict_mode
|
|
*/
|
|
|
|
function check_strict()
|
|
{
|
|
global $g_parameter;
|
|
if ($g_parameter->MY_STRICT == 'Y')
|
|
return true;
|
|
if ($g_parameter->MY_STRICT == 'N')
|
|
return false;
|
|
throw Exception("Valeur invalid " . __FILE__ . ':' . __LINE__);
|
|
}
|
|
|
|
/**
|
|
* @brief Check if a Dossier is using the check on the periode, if true than the user has to enter the date
|
|
* and the periode, it is a security check
|
|
* \return true if we are using the double encoding (date+periode)
|
|
*/
|
|
|
|
function check_periode()
|
|
{
|
|
global $g_parameter;
|
|
if ($g_parameter->MY_CHECK_PERIODE == 'Y')
|
|
return true;
|
|
if ($g_parameter->MY_CHECK_PERIODE == 'N')
|
|
return false;
|
|
throw Exception("Valeur invalid " . __FILE__ . ':' . __LINE__);
|
|
}
|
|
|
|
/**
|
|
* @brief get the date of the last operation
|
|
*/
|
|
|
|
function get_last_date()
|
|
{
|
|
if ($this->id == 0)
|
|
throw new Exception(__FILE__ . ":" . __LINE__ . "Journal incorrect ");
|
|
$sql = "select to_char(max(jr_date),'DD.MM.YYYY') from jrn where jr_def_id=$1";
|
|
$date = $this->db->get_value($sql, array($this->id));
|
|
return $date;
|
|
}
|
|
|
|
/**
|
|
* @brief retrieve the jr_id thanks the internal code, do not change
|
|
* anything to the current object
|
|
* @paramthe internal code
|
|
* \return the jr_id or 0 if not found
|
|
*/
|
|
|
|
function get_id($p_internal)
|
|
{
|
|
$sql = 'select jr_id from jrn where jr_internal=$1';
|
|
$value = $this->db->get_value($sql, array($p_internal));
|
|
if ($value == '')
|
|
$value = 0;
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* @brief create the invoice and saved it as attachment to the
|
|
* operation,
|
|
* @param$internal is the internal code
|
|
* @param$p_array is normally the $_POST
|
|
* \return a string
|
|
*/
|
|
|
|
function create_document($internal, $p_array)
|
|
{
|
|
extract($p_array);
|
|
$doc = new Document($this->db);
|
|
$doc->f_id = $e_client;
|
|
$doc->md_id = $gen_doc;
|
|
$doc->ag_id = 0;
|
|
$p_array['e_pj']=$this->pj;
|
|
$filename="";
|
|
$doc->Generate($p_array,$p_array['e_pj']);
|
|
// Move the document to the jrn
|
|
$doc->MoveDocumentPj($internal);
|
|
// Update the comment with invoice number, if the comment is empty
|
|
if (!isset($e_comm) || strlen(trim($e_comm)) == 0)
|
|
{
|
|
$sql = "update jrn set jr_comment=' document " . $doc->d_number . "' where jr_internal='$internal'";
|
|
$this->db->exec_sql($sql);
|
|
}
|
|
return h($doc->d_name . ' (' . $doc->d_filename . ')');
|
|
}
|
|
|
|
/**
|
|
* @brief check if the payment method is valid
|
|
* @param$e_mp is the value and $e_mp_qcode is the quickcode
|
|
* \return nothing throw an Exception
|
|
*/
|
|
|
|
public function check_payment($e_mp, $e_mp_qcode)
|
|
{
|
|
/* Check if the "paid by" is empty, */
|
|
if ($e_mp != 0)
|
|
{
|
|
/* the paid by is not empty then check if valid */
|
|
$empl = new Fiche($this->db);
|
|
$empl->get_by_qcode($e_mp_qcode);
|
|
if ($empl->empty_attribute(ATTR_DEF_ACCOUNT) == true)
|
|
{
|
|
throw new Exception(_("Celui qui paie n' a pas de poste comptable"), 20);
|
|
}
|
|
/* get the account and explode if necessary */
|
|
$sposte = $empl->strAttribut(ATTR_DEF_ACCOUNT);
|
|
// if 2 accounts, take only the debit one for customer
|
|
if (strpos($sposte, ',') != 0)
|
|
{
|
|
$array = explode(',', $sposte);
|
|
$poste_val = $array[0];
|
|
}
|
|
else
|
|
{
|
|
$poste_val = $sposte;
|
|
}
|
|
$poste = new Acc_Account_Ledger($this->db, $poste_val);
|
|
if ($poste->load() == false)
|
|
{
|
|
throw new Exception(sprintf(_("Pour la fiche %s le poste comptable [%s] n'existe pas"),$empl->quick_code,$poste->id ), 9);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief increment the sequence for the pj */
|
|
|
|
function inc_seq_pj()
|
|
{
|
|
$sql = "select nextval('s_jrn_pj" . $this->id . "')";
|
|
$this->db->exec_sql($sql);
|
|
}
|
|
|
|
/**
|
|
* @brief return a HTML string with the form for the search
|
|
* @param $p_type if the type of ledger possible values=ALL,VEN,ACH,ODS,FIN
|
|
* @param $all_type_ledger
|
|
* values :
|
|
* - 1 means all the ledger of this type
|
|
* - 0 No have the "Tous les journaux" availables
|
|
* @param $div is the div (for reconciliation)
|
|
* @return a HTML String without the tag FORM or DIV
|
|
*
|
|
* @see build_search_sql
|
|
* @see display_search_form
|
|
* @see list_operation
|
|
*/
|
|
|
|
function search_form($p_type, $all_type_ledger = 1, $div = "")
|
|
{
|
|
global $g_user;
|
|
$r="";
|
|
$bledger_param= json_encode(array(
|
|
'dossier'=>$_REQUEST['gDossier'],
|
|
'type'=>$p_type,
|
|
'all_type'=>$all_type_ledger,
|
|
'div'=>$div
|
|
));
|
|
|
|
$bledger_param= str_replace('"', "'", $bledger_param);
|
|
$bledger=new ISmallButton('l');
|
|
$bledger->label=_("choix des journaux");
|
|
$bledger->javascript=" show_ledger_choice($bledger_param)";
|
|
$f_ledger=$bledger->input();
|
|
$hid_jrn="";
|
|
if ( isset ($_REQUEST[$div.'nb_jrn']) ){
|
|
for ($i=0;$i < $_REQUEST[$div.'nb_jrn'];$i++) {
|
|
if ( isset ($_REQUEST[$div."r_jrn"][$i]))
|
|
$hid_jrn.=HtmlInput::hidden($div.'r_jrn['.$i.']',$_REQUEST[$div."r_jrn"][$i]);
|
|
}
|
|
$hid_jrn.=HtmlInput::hidden($div.'nb_jrn',$_REQUEST[$div.'nb_jrn']);
|
|
} else {
|
|
$hid_jrn=HtmlInput::hidden($div.'nb_jrn',0);
|
|
}
|
|
/* Compute date for exercice */
|
|
$period = $g_user->get_periode();
|
|
$per = new Periode($this->db, $period);
|
|
$exercice = $per->get_exercice();
|
|
list($per_start, $per_end) = $per->get_limit($exercice);
|
|
$date_end = $per_end->last_day();
|
|
$date_start=$per_start->first_day();
|
|
|
|
/* widget for date_start */
|
|
$f_date_start = new IDate('date_start');
|
|
/* all periode or only the selected one */
|
|
if (isset($_REQUEST['date_start']))
|
|
{
|
|
$f_date_start->value = $_REQUEST['date_start'];
|
|
}
|
|
else
|
|
{
|
|
$f_date_start->value=$date_start;
|
|
}
|
|
|
|
/* widget for date_end */
|
|
$f_date_end = new IDate('date_end');
|
|
/* all date or only the selected one */
|
|
if (isset($_REQUEST['date_end']))
|
|
{
|
|
$f_date_end->value = $_REQUEST['date_end'];
|
|
}
|
|
else
|
|
{
|
|
$f_date_end->value = $date_end;
|
|
}
|
|
/* widget for date term */
|
|
$f_date_paid_start=new IDate('date_paid_start');
|
|
$f_date_paid_end=new IDate('date_paid_end');
|
|
|
|
$f_date_paid_start->value=(isset($_REQUEST['date_paid_start']))?$_REQUEST['date_paid_start']:'';
|
|
$f_date_paid_end->value=(isset($_REQUEST['date_paid_end']))?$_REQUEST['date_paid_end']:'';
|
|
|
|
/* widget for desc */
|
|
$f_descript = new IText('desc');
|
|
$f_descript->size = 40;
|
|
if (isset($_REQUEST['desc']))
|
|
{
|
|
$f_descript->value = $_REQUEST['desc'];
|
|
}
|
|
|
|
/* widget for amount */
|
|
$f_amount_min = new INum('amount_min');
|
|
$f_amount_min->value = (isset($_REQUEST['amount_min'])) ? abs($_REQUEST['amount_min']) : 0;
|
|
$f_amount_max = new INum('amount_max');
|
|
$f_amount_max->value = (isset($_REQUEST['amount_max'])) ? abs($_REQUEST['amount_max']) : 0;
|
|
|
|
/* input quick code */
|
|
$f_qcode = new ICard('qcode' . $div);
|
|
|
|
$f_qcode->set_attribute('typecard', 'all');
|
|
/* $f_qcode->set_attribute('p_jrn','0');
|
|
|
|
$f_qcode->set_callback('filter_card');
|
|
*/
|
|
$f_qcode->set_dblclick("fill_ipopcard(this);");
|
|
// Add the callback function to filter the card on the jrn
|
|
//$f_qcode->set_callback('filter_card');
|
|
$f_qcode->set_function('fill_data');
|
|
$f_qcode->javascript = sprintf(' onchange="fill_data_onchange(%s);" ', $f_qcode->name);
|
|
$f_qcode->value = (isset($_REQUEST['qcode' . $div])) ? $_REQUEST['qcode' . $div] : '';
|
|
|
|
/* $f_txt_qcode=new IText('qcode');
|
|
$f_txt_qcode->value=(isset($_REQUEST['qcode']))?$_REQUEST['qcode']:'';
|
|
*/
|
|
|
|
/* input poste comptable */
|
|
$f_accounting = new IPoste('accounting');
|
|
$f_accounting->value = (isset($_REQUEST['accounting'])) ? $_REQUEST['accounting'] : '';
|
|
if ($this->id == -1)
|
|
$jrn = 0;
|
|
else
|
|
$jrn = $this->id;
|
|
$f_accounting->set_attribute('jrn', $jrn);
|
|
$f_accounting->set_attribute('ipopup', 'ipop_account');
|
|
$f_accounting->set_attribute('label', 'ld');
|
|
$f_accounting->set_attribute('account', 'accounting');
|
|
$info = HtmlInput::infobulle(13);
|
|
|
|
$f_paid = new ICheckbox('unpaid');
|
|
$f_paid->selected = (isset($_REQUEST['unpaid'])) ? true : false;
|
|
|
|
$r.=dossier::hidden();
|
|
$r.=HtmlInput::hidden('ledger_type', $this->type);
|
|
$r.=HtmlInput::hidden('ac', $_REQUEST['ac']);
|
|
ob_start();
|
|
require_once('template/ledger_search.php');
|
|
$r.=ob_get_contents();
|
|
ob_end_clean();
|
|
return $r;
|
|
}
|
|
|
|
/**
|
|
* @brief this function will create a sql stmt to use to create the list for
|
|
* the ledger,
|
|
* @param$p_array is usually the $_GET,
|
|
* @param$p_order the order of the row
|
|
* @param$p_where is the sql condition if not null then the $p_array will not be used
|
|
* \note the p_action will be used to filter the ledger but gl means ALL
|
|
* struct array $p_array
|
|
\verbatim
|
|
(
|
|
[gDossier] => 13
|
|
[p_jrn] => -1
|
|
[date_start] =>
|
|
[date_end] =>
|
|
[amount_min] => 0
|
|
[amount_max] => 0
|
|
[desc] =>
|
|
[search] => Rechercher
|
|
[p_action] => ven
|
|
[sa] => l
|
|
)
|
|
\endverbatim
|
|
* \return an array with a valid sql statement, an the where clause => array[sql] array[where]
|
|
* \see list_operation
|
|
* \see display_search_form
|
|
* \see search_form
|
|
*/
|
|
|
|
public function build_search_sql($p_array, $p_order = "", $p_where = "")
|
|
{
|
|
$sql = "select jr_id ,
|
|
jr_montant,
|
|
substr(jr_comment,1,60) as jr_comment,
|
|
to_char(jr_ech,'DD.MM.YY') as str_jr_ech,
|
|
to_char(jr_date,'DD.MM.YY') as str_jr_date,
|
|
jr_date as jr_date_order,
|
|
jr_grpt_id,
|
|
jr_rapt,
|
|
jr_internal,
|
|
jrn_def_id,
|
|
jrn_def_name,
|
|
jrn_def_ech,
|
|
jrn_def_type,
|
|
jr_valid,
|
|
jr_tech_per,
|
|
jr_pj_name,
|
|
p_closed,
|
|
jr_pj_number,
|
|
n_text,
|
|
case
|
|
when jrn_def_type='VEN' then
|
|
(select ad_value from fiche_detail where ad_id=1
|
|
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))
|
|
when jrn_def_type = 'ACH' then
|
|
(select ad_value from fiche_detail where ad_id=1
|
|
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))
|
|
when jrn_def_type = 'FIN' then
|
|
(select ad_value from fiche_detail where ad_id=1
|
|
and f_id=(select qf_other from quant_fin where quant_fin.jr_id=x.jr_id))
|
|
end as name,
|
|
case
|
|
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))
|
|
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))
|
|
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))
|
|
end as first_name,
|
|
case
|
|
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))
|
|
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))
|
|
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))
|
|
end as quick_code,
|
|
case
|
|
when jrn_def_type='VEN' then
|
|
(select sum(qs_price)+sum(vat) from
|
|
(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
|
|
)
|
|
when jrn_def_type = 'ACH' then
|
|
(
|
|
select sum(qp_price)+sum(vat)+sum(qp_nd_tva)+sum(qp_nd_tva_recup)
|
|
from
|
|
(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
|
|
)
|
|
else null
|
|
end as total_invoice,
|
|
jr_date_paid,
|
|
to_char(jr_date_paid,'DD.MM.YY') as str_jr_date_paid
|
|
from
|
|
jrn as X left join jrn_note using(jr_id)
|
|
join jrn_def on jrn_def_id=jr_def_id
|
|
join parm_periode on p_id=jr_tech_per";
|
|
|
|
if (!empty($p_array))
|
|
extract($p_array);
|
|
|
|
if (isset($op) )
|
|
$r_jrn = (isset(${$op."r_jrn"})) ? ${$op."r_jrn"} : -1;
|
|
else
|
|
{
|
|
$r_jrn = (isset($r_jrn)) ? $r_jrn : -1;
|
|
|
|
}
|
|
|
|
/* if no variable are set then give them a default
|
|
* value */
|
|
if ($p_array == null || empty($p_array) || !isset($amount_min))
|
|
{
|
|
$amount_min = 0;
|
|
$amount_max = 0;
|
|
|
|
$desc = '';
|
|
$qcode = (isset($qcode)) ? $qcode : "";
|
|
if (isset($qcodesearch_op))
|
|
$qcode = $qcodesearch_op;
|
|
$accounting = (isset($accounting)) ? $accounting : "";
|
|
$periode = new Periode($this->db);
|
|
$g_user = new User($this->db);
|
|
$p_id = $g_user->get_periode();
|
|
if ($p_id != null)
|
|
{
|
|
list($date_start, $date_end) = $periode->get_date_limit($p_id);
|
|
}
|
|
}
|
|
|
|
/* if p_jrn : 0 if means all ledgers, if -1 means all ledger of this
|
|
* type otherwise only one ledger */
|
|
$fil_ledger = '';
|
|
$fil_amount = '';
|
|
$fil_date = '';
|
|
$fil_desc = '';
|
|
$fil_sec = '';
|
|
$fil_qcode = '';
|
|
$fil_account = '';
|
|
$fil_paid = '';
|
|
$fil_date_paid='';
|
|
|
|
$and = '';
|
|
$g_user = new User($this->db);
|
|
$p_action = $ledger_type;
|
|
if ($p_action == '')
|
|
$p_action = 'ALL';
|
|
if ($r_jrn == -1)
|
|
{
|
|
|
|
/* from compta.php the p_action is quick_writing instead of ODS */
|
|
if ($p_action == 'quick_writing')
|
|
$p_action = 'ODS';
|
|
|
|
|
|
$fil_ledger = $g_user->get_ledger_sql($p_action, 3);
|
|
$and = ' and ';
|
|
}
|
|
else
|
|
{
|
|
|
|
if ($p_action == 'quick_writing')
|
|
$p_action = 'ODS';
|
|
|
|
$aLedger = $g_user->get_ledger($p_action, 3);
|
|
$fil_ledger = '';
|
|
$sp = '';
|
|
for ($i = 0; $i < count($r_jrn); $i++)
|
|
{
|
|
if (isset($r_jrn[$i]) )
|
|
{
|
|
$a=$r_jrn[$i];
|
|
$fil_ledger.=$sp . $a;
|
|
$sp = ',';
|
|
}
|
|
}
|
|
$fil_ledger = ' jrn_def_id in (' . $fil_ledger . ')';
|
|
$and = ' and ';
|
|
|
|
/* no ledger selected */
|
|
if ($sp == '')
|
|
{
|
|
$fil_ledger = '';
|
|
$and = '';
|
|
}
|
|
}
|
|
|
|
/* format the number */
|
|
$amount_min = abs(toNumber($amount_min));
|
|
$amount_max = abs(toNumber($amount_max));
|
|
if ($amount_min > 0 && isNumber($amount_min))
|
|
{
|
|
$fil_amount = $and . ' jr_montant >=' . $amount_min;
|
|
$and = ' and ';
|
|
}
|
|
if ($amount_max > 0 && isNumber($amount_max))
|
|
{
|
|
$fil_amount.=$and . ' jr_montant <=' . $amount_max;
|
|
$and = ' and ';
|
|
}
|
|
/* -------------------------------------------------------------------------- *
|
|
* if both amount are the same then we need to search into the detail
|
|
* and we reset the fil_amount
|
|
* -------------------------------------------------------------------------- */
|
|
if (isNumber($amount_min) &&
|
|
isNumber($amount_max) &&
|
|
$amount_min > 0 &&
|
|
bccomp($amount_min, $amount_max, 2) == 0)
|
|
{
|
|
$fil_amount = $and . ' ( ';
|
|
|
|
// Look in detail
|
|
$fil_amount .= 'jr_grpt_id in ( select distinct j_grpt from jrnx where j_montant = ' . $amount_min . ') ';
|
|
|
|
//and the total operation
|
|
$fil_amount .= ' or ';
|
|
$fil_amount .= ' jr_montant = '.$amount_min;
|
|
|
|
$fil_amount .= ')';
|
|
$and = " and ";
|
|
}
|
|
// date
|
|
if (isset($date_start) && isDate($date_start) != null)
|
|
{
|
|
$fil_date = $and . " jr_date >= to_date('" . $date_start . "','DD.MM.YYYY')";
|
|
$and = " and ";
|
|
}
|
|
if (isset($date_end) && isDate($date_end) != null)
|
|
{
|
|
$fil_date.=$and . " jr_date <= to_date('" . $date_end . "','DD.MM.YYYY')";
|
|
$and = " and ";
|
|
}
|
|
// date paiement
|
|
if (isset($date_paid_start) && isDate($date_paid_start) != null)
|
|
{
|
|
$fil_date_paid = $and . " jr_date_paid >= to_date('" . $date_paid_start . "','DD.MM.YYYY')";
|
|
$and = " and ";
|
|
}
|
|
if (isset($date_paid_end) && isDate($date_paid_end) != null)
|
|
{
|
|
$fil_date_paid.=$and . " jr_date_paid <= to_date('" . $date_paid_end . "','DD.MM.YYYY')";
|
|
$and = " and ";
|
|
}
|
|
// comment
|
|
if (isset($desc) && $desc != null)
|
|
{
|
|
$desc = sql_string($desc);
|
|
$fil_desc = $and . " ( upper(jr_comment) like upper('%" . $desc . "%') or upper(jr_pj_number) like upper('%" . $desc . "%') " .
|
|
" or upper(jr_internal) like upper('%" . $desc . "%')
|
|
or jr_grpt_id in (select j_grpt from jrnx where j_text ~* '" . $desc . "')
|
|
or jr_id in (select jr_id from jrn_info where ji_value is not null and ji_value ~* '$desc')
|
|
)";
|
|
$and = " and ";
|
|
}
|
|
// Poste
|
|
if (isset($accounting) && $accounting != null)
|
|
{
|
|
$fil_account = $and . " jr_grpt_id in (select j_grpt
|
|
from jrnx where j_poste::text like '" . sql_string($accounting) . "%' ) ";
|
|
$and = " and ";
|
|
}
|
|
// Quick Code
|
|
if (isset($qcodesearch_op))
|
|
$qcode = $qcodesearch_op;
|
|
if (isset($qcode) && $qcode != null)
|
|
{
|
|
$fil_qcode = $and . " jr_grpt_id in ( select j_grpt from
|
|
jrnx where trim(j_qcode) = upper(trim('" . sql_string($qcode) . "')))";
|
|
$and = " and ";
|
|
}
|
|
|
|
// Only the unpaid
|
|
if (isset($unpaid))
|
|
{
|
|
$fil_paid = $and . SQL_LIST_UNPAID_INVOICE;
|
|
$and = " and ";
|
|
}
|
|
|
|
$g_user = new User(new Database());
|
|
$g_user->Check();
|
|
$g_user->check_dossier(dossier::id());
|
|
|
|
if ($g_user->admin == 0 && $g_user->is_local_admin() == 0)
|
|
{
|
|
$fil_sec = $and . " jr_def_id in ( select uj_jrn_id " .
|
|
" from user_sec_jrn where " .
|
|
" uj_login='" . $_SESSION['g_user'] . "'" .
|
|
" and uj_priv in ('R','W'))";
|
|
}
|
|
$where = $fil_ledger . $fil_amount . $fil_date . $fil_desc . $fil_sec . $fil_amount . $fil_qcode . $fil_paid . $fil_account.$fil_date_paid;
|
|
$sql.=" where " . $where;
|
|
return array($sql, $where);
|
|
}
|
|
|
|
/**
|
|
* @brief return a html string with the search_form
|
|
* \return a HTML string with the FORM
|
|
* \see build_search_sql
|
|
* \see search_form
|
|
* \see list_operation
|
|
*/
|
|
|
|
function display_search_form()
|
|
{
|
|
$r = '';
|
|
$type = $this->type;
|
|
|
|
if ($type == "")
|
|
$type = 'ALL';
|
|
$r.='<div id="search_form" style="display:none">';
|
|
$r.=HtmlInput::anchor_hide('⨉', '$(\'search_form\').style.display=\'none\';');
|
|
$r.=h2('Recherche','class="title"');
|
|
$r.='<FORM METHOD="GET">';
|
|
$r.=$this->search_form($type);
|
|
$r.=HtmlInput::submit('search', _('Rechercher'));
|
|
$r.=HtmlInput::hidden('ac', $_REQUEST['ac']);
|
|
|
|
/* when called from commercial.php some hidden values are needed */
|
|
if (isset($_REQUEST['sa']))
|
|
$r.= HtmlInput::hidden("sa", $_REQUEST['sa']);
|
|
if (isset($_REQUEST['sb']))
|
|
$r.= HtmlInput::hidden("sb", $_REQUEST['sb']);
|
|
if (isset($_REQUEST['sc']))
|
|
$r.= HtmlInput::hidden("sc", $_REQUEST['sc']);
|
|
if (isset($_REQUEST['f_id']))
|
|
$r.=HtmlInput::hidden("f_id", $_REQUEST['f_id']);
|
|
|
|
$r.='</FORM>';
|
|
|
|
$r.='</div>';
|
|
$button = new IButton('tfs');
|
|
$button->label = _("Filtrer");
|
|
$button->javascript = "toggleHideShow('search_form','tfs');";
|
|
|
|
$r.=$button->input();
|
|
return $r;
|
|
}
|
|
|
|
/**
|
|
* @brief return the last p_limit operation into an array
|
|
* @param$p_limit is the max of operation to return
|
|
* \return $p_array of Follow_Up object
|
|
*/
|
|
|
|
function get_last($p_limit)
|
|
{
|
|
global $g_user;
|
|
$filter_ledger = $g_user->get_ledger_sql('ALL', 3);
|
|
$filter_ledger = str_replace('jrn_def_id', 'jr_def_id', $filter_ledger);
|
|
$sql = "
|
|
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
|
|
from jrn
|
|
join jrn_def on (jrn_def_id=jr_def_id)
|
|
where $filter_ledger
|
|
order by jr_date desc limit $p_limit";
|
|
$array = $this->db->get_array($sql);
|
|
return $array;
|
|
}
|
|
|
|
/**
|
|
* @brief retreive the jr_grpt_id from a ledger
|
|
* @param $p_what the column to seek
|
|
* possible values are
|
|
* - internal
|
|
* @param $p_value the value of the col.
|
|
*/
|
|
function search_group($p_what, $p_value)
|
|
{
|
|
switch ($p_what)
|
|
{
|
|
case 'internal':
|
|
return $this->db->get_value('select jr_grpt_id from jrn where jr_internal=$1', array($p_value));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief retrieve operation from jrn
|
|
* @param $p_from periode (id)
|
|
* @param $p_to periode (id)
|
|
* @return an array
|
|
*/
|
|
function get_operation($p_from, $p_to)
|
|
{
|
|
global $g_user;
|
|
$jrn = ($this->id == 0) ? 'and ' . $g_user->get_ledger_sql() : ' and jr_def_id = ' . $this->id;
|
|
$sql = "select jr_id as id ,jr_internal as internal, " .
|
|
"jr_pj_number as pj,jr_grpt_id," .
|
|
" to_char(jr_date,'DDMMYY') as date_fmt, " .
|
|
" jr_comment as comment, jr_montant as montant ," .
|
|
" jr_grpt_id,jr_def_id" .
|
|
" from jrn join jrn_def on (jr_def_id=jrn_def_id) where " .
|
|
" jr_date >= (select p_start from parm_periode where p_id = $1)
|
|
and jr_date <= (select p_end from parm_periode where p_id = $2)" .
|
|
' ' . $jrn . ' order by jr_date,substring(jr_pj_number,\'[0-9]+$\')::numeric asc';
|
|
$ret = $this->db->get_array($sql, array($p_from, $p_to));
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* @brief return the used VAT code with a rate > 0
|
|
* @return an array of tva_id,tva_label,tva_poste
|
|
*/
|
|
public function existing_vat()
|
|
{
|
|
if ($this->type == 'ACH')
|
|
{
|
|
$array = $this->db->get_array("select tva_id,tva_label,tva_poste from tva_rate where tva_rate != 0.0000 " .
|
|
" and exists (select qp_vat_code from quant_purchase
|
|
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));
|
|
}
|
|
if ($this->type == 'VEN')
|
|
{
|
|
$array = $this->db->get_array("select tva_id,tva_label,tva_poste from tva_rate where tva_rate != 0.0000 " .
|
|
" and exists (select qs_vat_code from quant_sold
|
|
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));
|
|
}
|
|
return $array;
|
|
}
|
|
|
|
/**
|
|
* @brief get the amount of vat for a given jr_grpt_id from the table
|
|
* quant_purchase
|
|
* @param the jr_grpt_id
|
|
* @return array price=htva, [1] = vat,
|
|
* @note
|
|
* @see
|
|
@code
|
|
array
|
|
'price' => string '91.3500' (length=7)
|
|
'vat' => string '0.0000' (length=6)
|
|
'priv' => string '0.0000' (length=6)
|
|
'tva_nd_recup' => string '0.0000' (length=6)
|
|
|
|
@endcode
|
|
*/
|
|
function get_other_amount($p_jr_id)
|
|
{
|
|
if ($this->type == 'ACH')
|
|
{
|
|
$array = $this->db->get_array('select sum(qp_price) as price,sum(qp_vat) as vat ' .
|
|
',sum(coalesce(qp_nd_amount,0)+coalesce(qp_dep_priv,0)) as priv' .
|
|
',sum(coalesce(qp_nd_tva_recup,0)+coalesce(qp_nd_tva,0)) as tva_nd' .
|
|
',sum(qp_vat_sided) as tva_np' .
|
|
' from quant_purchase join jrnx using(j_id)
|
|
where j_grpt=$1 ', array($p_jr_id));
|
|
$ret = $array[0];
|
|
}
|
|
if ($this->type == 'VEN')
|
|
{
|
|
$array = $this->db->get_array('select sum(qs_price) as price,sum(qs_vat) as vat ' .
|
|
',0 as priv' .
|
|
',0 as tva_nd' .
|
|
',sum(qs_vat_sided) as tva_np' .
|
|
' from quant_sold join jrnx using(j_id)
|
|
where j_grpt=$1 ', array($p_jr_id));
|
|
$ret = $array[0];
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* @brief get the amount of vat for a given jr_grpt_id from the table
|
|
* quant_purchase
|
|
* @param the jr_grpt_id
|
|
* @return array of sum_vat, tva_label
|
|
* @note
|
|
* @see
|
|
@code
|
|
|
|
@endcode
|
|
*/
|
|
function vat_operation($p_jr_id)
|
|
{
|
|
if ($this->type == 'ACH')
|
|
{
|
|
$array = $this->db->get_array('select coalesce(sum(qp_vat),0) as sum_vat,tva_id
|
|
from quant_purchase as p right join tva_rate on (qp_vat_code=tva_id) join jrnx using(j_id)
|
|
where tva_rate !=0.0 and j_grpt=$1 group by tva_id', array($p_jr_id));
|
|
}
|
|
if ($this->type == 'VEN')
|
|
{
|
|
$array = $this->db->get_array('select coalesce(sum(qs_vat),0) as sum_vat,tva_id
|
|
from quant_sold as p right join tva_rate on (qs_vat_code=tva_id) join jrnx using(j_id)
|
|
where tva_rate !=0.0 and j_grpt=$1 group by tva_id', array($p_jr_id));
|
|
}
|
|
return $array;
|
|
}
|
|
|
|
/**
|
|
* @brief retrieve amount of previous periode
|
|
* @param $p_to frmo the start of the exercise until $p_to
|
|
* @return $array with vat, price,other_amount
|
|
* @note
|
|
* @see
|
|
@code
|
|
array
|
|
'price' => string '446.1900' (length=8)
|
|
'vat' => string '21.7600' (length=7)
|
|
'priv' => string '0.0000' (length=6)
|
|
'tva_nd_recup' => string '0.0000' (length=6)
|
|
'tva' =>
|
|
array
|
|
0 =>
|
|
array
|
|
'sum_vat' => string '13.7200' (length=7)
|
|
'tva_id' => string '1' (length=1)
|
|
1 =>
|
|
array
|
|
'sum_vat' => string '8.0400' (length=6)
|
|
'tva_id' => string '3' (length=1)
|
|
2 =>
|
|
array
|
|
'sum_vat' => string '0.0000' (length=6)
|
|
'tva_id' => string '4' (length=1)
|
|
|
|
@endcode
|
|
*/
|
|
function previous_amount($p_to)
|
|
{
|
|
/* get the first periode of exercise */
|
|
$periode = new Periode($this->db, $p_to);
|
|
$exercise = $periode->get_exercice();
|
|
list ($min, $max) = $periode->get_limit($exercise);
|
|
// transform min into date
|
|
$min_date=$min->first_day();
|
|
// transform $p_to into date
|
|
$periode_max=new Periode($this->db,$p_to);
|
|
$max_date=$periode_max->first_day();
|
|
bcscale(2);
|
|
// min periode
|
|
if ($this->type == 'ACH')
|
|
{
|
|
/* get all amount exclude vat */
|
|
$sql = "select coalesce(sum(qp_price),0) as price" .
|
|
" ,coalesce(sum(qp_vat),0) as vat " .
|
|
',coalesce(sum(qp_dep_priv),0) as priv' .
|
|
',coalesce(sum(qp_vat_sided),0) as reversed' .
|
|
',coalesce(sum(qp_nd_tva_recup),0)+coalesce(sum(qp_nd_tva),0) as tva_nd' .
|
|
',coalesce(sum(qp_vat_sided),0) as tva_np' .
|
|
' from quant_purchase join jrnx using(j_id) ' .
|
|
" where j_date >= to_date($1,'DD.MM.YYYY') and j_date < to_date($2,'DD.MM.YYYY') ".
|
|
' and j_jrn_def = $3';
|
|
$array = $this->db->get_array($sql, array($min_date, $max_date,$this->id));
|
|
|
|
$ret = $array[0];
|
|
/* retrieve all vat code */
|
|
$array = $this->db->get_array("select coalesce(sum(qp_vat),0) as sum_vat,tva_id
|
|
from quant_purchase as p right join tva_rate on (qp_vat_code=tva_id) join jrnx using(j_id)
|
|
where tva_rate !=0 and j_date >= to_date($1,'DD.MM.YYYY') and j_date < to_date($2,'DD.MM.YYYY')
|
|
and j_jrn_def = $3
|
|
group by tva_id",
|
|
array($min_date, $max_date,$this->id));
|
|
$ret['tva'] = $array;
|
|
}
|
|
if ($this->type == 'VEN')
|
|
{
|
|
/* get all amount exclude vat */
|
|
$sql = "select coalesce(sum(qs_price),0) as price" .
|
|
" ,coalesce(sum(qs_vat),0) as vat " .
|
|
',0 as priv' .
|
|
',0 as tva_nd' .
|
|
',coalesce(sum(qs_vat_sided),0) as tva_np' .
|
|
' from quant_sold join jrnx using(j_id) ' .
|
|
" where j_date >= to_date($1,'DD.MM.YYYY') and j_date < to_date($2,'DD.MM.YYYY') ".
|
|
' and j_jrn_def = $3';
|
|
$array = $this->db->get_array($sql, array($min_date, $max_date,$this->id));
|
|
$ret = $array[0];
|
|
/* retrieve all vat code */
|
|
$array = $this->db->get_array("select coalesce(sum(qs_vat),0) as sum_vat,tva_id
|
|
from quant_sold as p right join tva_rate on (qs_vat_code=tva_id) join jrnx using(j_id)
|
|
where tva_rate !=0 and
|
|
j_date >= to_date($1,'DD.MM.YYYY') and j_date < to_date($2,'DD.MM.YYYY')
|
|
and j_jrn_def = $3
|
|
group by tva_id", array($min_date, $max_date,$this->id));
|
|
$ret['tva'] = $array;
|
|
}
|
|
if ($this->type=="FIN")
|
|
{
|
|
|
|
/* find the quick code of this ledger */
|
|
$ledger=new Acc_Ledger_Fin($this->db,$this->id);
|
|
$qcode=$ledger->get_bank();
|
|
$bank_card=new Fiche($this->db,$qcode);
|
|
|
|
/*add the amount from Opening Writing */
|
|
$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);
|
|
$saldo = $bank_card->get_bk_balance ($cond);
|
|
$ret['amount']=bcsub($saldo['debit'],$saldo['credit']);
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// TEST MODULE
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* @brief this function is intended to test this class
|
|
*/
|
|
static function test_me($pCase = '')
|
|
{
|
|
if ($pCase == '')
|
|
{
|
|
echo Acc_Reconciliation::$javascript;
|
|
html_page_start();
|
|
$cn = new Database(dossier::id());
|
|
$_SESSION['g_user'] = 'phpcompta';
|
|
$_SESSION['g_pass'] = 'phpcompta';
|
|
|
|
$id = (isset($_REQUEST['p_jrn'])) ? $_REQUEST['p_jrn'] : -1;
|
|
$a = new Acc_Ledger($cn, $id);
|
|
$a->with_concerned = true;
|
|
// Vide
|
|
echo '<FORM method="post">';
|
|
echo $a->select_ledger()->input();
|
|
echo HtmlInput::submit('go', 'Test it');
|
|
echo '</form>';
|
|
if (isset($_POST['go']))
|
|
{
|
|
echo "Ok ";
|
|
echo '<form method="post">';
|
|
echo $a->show_form();
|
|
echo HtmlInput::submit('post_id', 'Try me');
|
|
echo '</form>';
|
|
// Show the predef operation
|
|
// Don't forget the p_jrn
|
|
echo '<form>';
|
|
echo dossier::hidden();
|
|
echo '<input type="hidden" value="' . $id . '" name="p_jrn">';
|
|
$op = new Pre_operation($cn);
|
|
$op->p_jrn = $id;
|
|
$op->od_direct = 't';
|
|
if ($op->count() != 0)
|
|
{
|
|
echo HtmlInput::submit('use_opd', 'Utilisez une opération prédéfinie',"","smallbutton");
|
|
echo $op->show_button();
|
|
}
|
|
echo '</form>';
|
|
exit('test_me');
|
|
}
|
|
|
|
if (isset($_POST['post_id']))
|
|
{
|
|
|
|
echo '<form method="post">';
|
|
echo $a->show_form($_POST, 1);
|
|
echo HtmlInput::button('add', 'Ajout d\'une ligne', 'onClick="quick_writing_add_row()"');
|
|
echo HtmlInput::submit('save_it', "Sauver");
|
|
echo '</form>';
|
|
exit('test_me');
|
|
}
|
|
if (isset($_POST['save_it']))
|
|
{
|
|
print 'saving';
|
|
$array = $_POST;
|
|
$array['save_opd'] = 1;
|
|
try
|
|
{
|
|
$a->save($array);
|
|
}
|
|
catch (Exception $e)
|
|
{
|
|
alert($e->getMessage());
|
|
echo '<form method="post">';
|
|
|
|
echo $a->show_form($_POST);
|
|
echo HtmlInput::submit('post_id', 'Try me');
|
|
echo '</form>';
|
|
}
|
|
return;
|
|
}
|
|
// The GET at the end because automatically repost when you don't
|
|
// specify the url in the METHOD field
|
|
if (isset($_GET['use_opd']))
|
|
{
|
|
$op = new Pre_op_advanced($cn);
|
|
$op->set_od_id($_REQUEST['pre_def']);
|
|
//$op->p_jrn=$id;
|
|
|
|
$p_post = $op->compute_array();
|
|
|
|
echo '<FORM method="post">';
|
|
|
|
echo $a->show_form($p_post);
|
|
echo HtmlInput::submit('post_id', 'Use predefined operation');
|
|
echo '</form>';
|
|
return;
|
|
}
|
|
}// if case = ''
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// search
|
|
if ($pCase == 'search')
|
|
{
|
|
html_page_start();
|
|
$cn = new Database(dossier::id());
|
|
$ledger = new Acc_Ledger($cn, 0);
|
|
$_SESSION['g_user'] = 'phpcompta';
|
|
$_SESSION['g_pass'] = 'phpcompta';
|
|
echo $ledger->search_form('ALL');
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// reverse
|
|
// Give yourself the var and check in your tables
|
|
///////////////////////////////////////////////////////////////////////////
|
|
if ($pCase == 'reverse')
|
|
{
|
|
$cn = new Database(dossier::id());
|
|
$jr_internal = 'OD-01-272';
|
|
try
|
|
{
|
|
$cn->start();
|
|
$jrn_def_id = $cn->get_value('select jr_def_id from jrn where jr_internal=$1', array($jr_internal));
|
|
$ledger = new Acc_Ledger($cn, $jrn_def_id);
|
|
$ledger->jr_id = $cn->get_value('select jr_id from jrn where jr_internal=$1', array($jr_internal));
|
|
|
|
echo "Ouvrez le fichier " . __FILE__ . " à la ligne " . __LINE__ . " pour changer jr_internal et vérifier le résultat de l'extourne";
|
|
|
|
$ledger->reverse('01.07.2010');
|
|
}
|
|
catch (Exception $e)
|
|
{
|
|
$cn->rollback();
|
|
var_dump($e);
|
|
}
|
|
$cn->commit();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* create an array of the existing cat, to be used in a checkbox form
|
|
*
|
|
*/
|
|
static function array_cat()
|
|
{
|
|
$r = array(
|
|
array('cat' => 'VEN', 'name' => _("Journaux de vente")),
|
|
array('cat' => 'ACH', 'name' => _("'Journaux d'achat")),
|
|
array('cat' => 'FIN', 'name' => _("'Journaux Financier")),
|
|
array('cat' => 'ODS', 'name' => _("'Journaux d'Opérations diverses"))
|
|
);
|
|
return $r;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the third : supplier for purchase, customer for sale, bank for fin,
|
|
* @param $p_jrn_type type of the ledger FIN, VEN ACH or ODS
|
|
*/
|
|
function get_tiers($p_jrn_type, $jr_id)
|
|
{
|
|
if ($p_jrn_type == 'ODS')
|
|
return ' ';
|
|
$tiers = '';
|
|
switch ($p_jrn_type)
|
|
{
|
|
case 'VEN':
|
|
$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));
|
|
break;
|
|
case 'ACH':
|
|
$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));
|
|
|
|
break;
|
|
case 'FIN':
|
|
$tiers = $this->db->get_value('select qf_other from quant_fin where jr_id=$1', array($jr_id));
|
|
break;
|
|
}
|
|
if ($this->db->count() == 0)
|
|
return '';
|
|
$name = $this->db->get_value('select ad_value from fiche_detail where ad_id=1 and f_id=$1', array($tiers));
|
|
$first_name = $this->db->get_value('select ad_value from fiche_detail where ad_id=32 and f_id=$1', array($tiers));
|
|
return $name . ' ' . $first_name;
|
|
}
|
|
|
|
/**
|
|
* @brief listing of all ledgers
|
|
* @return HTML string
|
|
*/
|
|
function listing()
|
|
{
|
|
$str_dossier = dossier::get();
|
|
$base_url = "?" . dossier::get() . "&ac=" . $_REQUEST['ac'];
|
|
|
|
$r = "";
|
|
$r.=_('Filtre')." ".HtmlInput::filter_table("cfgledger_table_id", "0", "1");
|
|
$r.='<TABLE id="cfgledger_table_id" class="vert_mtitle">';
|
|
$r.='<TR><TD class="first"><A HREF="' . $base_url . '&sa=add">' . _('Ajout journal') . ' </A></TD></TR>';
|
|
$ret = $this->db->exec_sql("select distinct jrn_def_id,jrn_def_name,
|
|
jrn_def_class_deb,jrn_def_class_cred,jrn_def_type
|
|
from jrn_def order by jrn_def_name");
|
|
$Max = Database::num_row($ret);
|
|
|
|
|
|
for ($i = 0; $i < $Max; $i++)
|
|
{
|
|
$l_line = Database::fetch_array($ret, $i);
|
|
$url = $base_url . "&sa=detail&p_jrn=" . $l_line['jrn_def_id'];
|
|
$r.=sprintf('<TR><TD><A HREF="%s">%s</A></TD></TR>', $url, h($l_line['jrn_def_name']).' ('.$l_line['jrn_def_type'].')');
|
|
}
|
|
$r.= "</TABLE>";
|
|
return $r;
|
|
}
|
|
|
|
/**
|
|
* display detail of a ledger
|
|
*
|
|
*/
|
|
function display_ledger()
|
|
{
|
|
if ($this->load() == -1)
|
|
{
|
|
throw new Exception(_("Journal n'existe pas"), -1);
|
|
}
|
|
$type = $this->jrn_def_type;
|
|
$name = $this->jrn_def_name;
|
|
$code = $this->jrn_def_code;
|
|
$str_add_button="";
|
|
/* widget for searching an account */
|
|
$wSearch = new IPoste();
|
|
$wSearch->set_attribute('ipopup', 'ipop_account');
|
|
$wSearch->set_attribute('account', 'p_jrn_class_deb');
|
|
$wSearch->set_attribute('no_overwrite', '1');
|
|
$wSearch->set_attribute('noquery', '1');
|
|
$wSearch->table = 3;
|
|
$wSearch->name = "p_jrn_class_deb";
|
|
$wSearch->size = 20;
|
|
$wSearch->value = $this->jrn_def_class_deb;
|
|
$search = $wSearch->input();
|
|
|
|
$wPjPref = new IText();
|
|
$wPjPref->name = 'jrn_def_pj_pref';
|
|
$wPjPref->value = $this->jrn_def_pj_pref;
|
|
$pj_pref = $wPjPref->input();
|
|
|
|
$wPjSeq = new INum();
|
|
$wPjSeq->value = 0;
|
|
$wPjSeq->name = 'jrn_def_pj_seq';
|
|
$pj_seq = $wPjSeq->input();
|
|
$last_seq = $this->get_last_pj();
|
|
$name = $this->jrn_def_name;
|
|
|
|
$hidden = HtmlInput::hidden('p_jrn', $this->id);
|
|
$hidden.= HtmlInput::hidden('sa', 'detail');
|
|
$hidden.= dossier::hidden();
|
|
$hidden.=HtmlInput::hidden('p_jrn_deb_max_line', 10);
|
|
$hidden.=HtmlInput::hidden('p_ech_lib', 'echeance');
|
|
$hidden.=HtmlInput::hidden('p_jrn_type', $type);
|
|
|
|
$min_row = new INum("min_row",$this->jrn_deb_max_line);
|
|
$min_row->prec=0;
|
|
|
|
$description=new ITextarea('p_description');
|
|
$description->style='class="itextarea" style="margin:0px;"';
|
|
$description->value=$this->jrn_def_description;
|
|
$str_description=$description->input();
|
|
|
|
/* Load the card */
|
|
$card = $this->get_fiche_def();
|
|
$rdeb = explode(',', $card['deb']);
|
|
$rcred = explode(',', $card['cred']);
|
|
/* Numbering (only FIN) */
|
|
$num_op = new ICheckBox('numb_operation');
|
|
if ($this->jrn_def_num_op == 1)
|
|
$num_op->selected = true;
|
|
/* bank card */
|
|
$qcode_bank = '';
|
|
if ($type == 'FIN')
|
|
{
|
|
$f_id = $this->jrn_def_bank;
|
|
if (isNumber($f_id) == 1)
|
|
{
|
|
$fBank = new Fiche($this->db, $f_id);
|
|
$qcode_bank = $fBank->get_quick_code();
|
|
}
|
|
}
|
|
$new = 0;
|
|
$cn = $this->db;
|
|
echo $hidden;
|
|
require_once('template/param_jrn.php');
|
|
}
|
|
|
|
/**
|
|
* Verify before update
|
|
*
|
|
* @param type $array
|
|
* 'p_jrn' => string '3' (length=1)
|
|
'sa' => string 'detail' (length=6)
|
|
'gDossier' => string '82' (length=2)
|
|
'p_jrn_deb_max_line' => string '10' (length=2)
|
|
'p_ech_lib' => string 'echeance' (length=8)
|
|
'p_jrn_type' => string 'ACH' (length=3)
|
|
'p_jrn_name' => string 'Achat' (length=5)
|
|
'jrn_def_pj_pref' => string 'ACH' (length=3)
|
|
'jrn_def_pj_seq' => string '0' (length=1)
|
|
'FICHECRED' =>
|
|
array
|
|
0 => string '4' (length=1)
|
|
'FICHEDEB' =>
|
|
array
|
|
0 => string '7' (length=1)
|
|
1 => string '5' (length=1)
|
|
2 => string '13' (length=2)
|
|
'update' => string 'Sauve' (length=5
|
|
* @exception is throw is test are not valid
|
|
*/
|
|
function verify_ledger($array)
|
|
{
|
|
extract($array);
|
|
try
|
|
{
|
|
if (isNumber($p_jrn) == 0)
|
|
throw new Exception("Id invalide");
|
|
if (isNumber($p_jrn_deb_max_line) == 0)
|
|
throw new Exception(_("Nombre de ligne incorrect"));
|
|
if (trim($p_jrn_name) == "")
|
|
throw new Exception("Nom de journal invalide");
|
|
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)
|
|
throw new Exception(_("Un journal avec ce nom existe déjà"));
|
|
if ($p_jrn_type == 'FIN')
|
|
{
|
|
$a = new Fiche($this->db);
|
|
$result = $a->get_by_qcode(trim(strtoupper($_POST['bank'])), false);
|
|
if ($result == 1)
|
|
throw new Exception(_("Aucun compte en banque n'est donné"));
|
|
}
|
|
if ($p_jrn_type == "-1") {
|
|
throw new Exception(_('Choix du type de journal est obligatoire'));
|
|
}
|
|
}
|
|
catch (Exception $e)
|
|
{
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* update a ledger
|
|
* @param type $array normally post
|
|
* @see verify_ledger
|
|
*/
|
|
function update($array = '')
|
|
{
|
|
if ($array == null)
|
|
throw new Exception('save cannot use a empty array');
|
|
|
|
extract($array);
|
|
$this->jrn_def_id = $p_jrn;
|
|
$this->jrn_def_name = $p_jrn_name;
|
|
$this->jrn_def_ech_lib = $p_ech_lib;
|
|
$this->jrn_def_max_line_deb = ($p_jrn_deb_max_line<1)?1:$p_jrn_deb_max_line;
|
|
$this->jrn_def_type = $p_jrn_type;
|
|
$this->jrn_def_pj_pref = $jrn_def_pj_pref;
|
|
$this->jrn_def_fiche_deb = (isset($FICHEDEB)) ? join($FICHEDEB, ',') : "";
|
|
$this->jrn_deb_max_line=($min_row<1)?1:$min_row;
|
|
$this->jrn_def_description=$p_description;
|
|
switch ($this->jrn_def_type)
|
|
{
|
|
case 'ACH':
|
|
case 'VEN':
|
|
$this->jrn_def_fiche_cred = (isset($FICHECRED)) ? join($FICHECRED, ',') : '';
|
|
break;
|
|
case 'ODS':
|
|
$this->jrn_def_class_deb = $p_jrn_class_deb;
|
|
$this->jrn_def_fiche_cred=null;
|
|
break;
|
|
case 'FIN':
|
|
$a = new Fiche($this->db);
|
|
$result = $a->get_by_qcode(trim(strtoupper($_POST['bank'])), false);
|
|
$bank = $a->id;
|
|
$this->jrn_def_bank = $bank;
|
|
if ($result == -1)
|
|
throw new Exception(_("Aucun compte en banque n'est donné"));
|
|
$this->jrn_def_num_op = (isset($numb_operation)) ? 1 : 0;
|
|
break;
|
|
}
|
|
|
|
parent::update();
|
|
//Reset sequence if needed
|
|
if ($jrn_def_pj_seq != 0)
|
|
{
|
|
$Res = $this->db->alter_seq("s_jrn_pj" . $p_jrn, $jrn_def_pj_seq);
|
|
}
|
|
}
|
|
|
|
function input_paid()
|
|
{
|
|
$r = '';
|
|
$r.='<div id="payment"> ';
|
|
$r.='<h2> ' . _('Payé par') . ' </h2>';
|
|
$mp = new Acc_Payment($this->db);
|
|
$mp->set_parameter('ledger_source', $this->id);
|
|
$r.=$mp->select();
|
|
$r.='</div>';
|
|
return $r;
|
|
}
|
|
|
|
/**
|
|
* display screen to enter a new ledger
|
|
*/
|
|
function input_new()
|
|
{
|
|
$retry=HtmlInput::default_value_post("sa", "");
|
|
// if ( $retry == "add") {
|
|
$default_type=HtmlInput::default_value_post("p_jrn_type", -1);
|
|
$previous_jrn_def_pj_pref=HtmlInput::default_value_post("jrn_def_pj_pref","");
|
|
$previous_p_description=HtmlInput::default_value_post("p_description","");
|
|
$previous_p_jrn_name=HtmlInput::default_value_post('p_jrn_name','');
|
|
$previous_p_jrn_type = HtmlInput::default_value_post("p_jrn_type","");
|
|
// }
|
|
global $g_user;
|
|
$f_add_button=new ISmallButton('add_card');
|
|
$f_add_button->label=_('Créer une nouvelle fiche');
|
|
$f_add_button->tabindex=-1;
|
|
$f_add_button->set_attribute('jrn',-1);
|
|
$f_add_button->javascript=" this.jrn=-1;select_card_type({type_cat:4});";
|
|
|
|
$str_add_button="";
|
|
if ($g_user->check_action(FICADD)==1)
|
|
{
|
|
$str_add_button=$f_add_button->input();
|
|
}
|
|
$wSearch = new IPoste();
|
|
$wSearch->table = 3;
|
|
$wSearch->set_attribute('ipopup', 'ipop_account');
|
|
$wSearch->set_attribute('account', 'p_jrn_class_deb');
|
|
$wSearch->set_attribute('no_overwrite', '1');
|
|
$wSearch->set_attribute('noquery', '1');
|
|
|
|
$wSearch->name = "p_jrn_class_deb";
|
|
$wSearch->size = 20;
|
|
|
|
$search = $wSearch->input();
|
|
// default for ACH
|
|
$default_deb_purchase = $this->get_default_card('ACH', 'D');
|
|
$default_cred_purchase = $this->get_default_card('ACH', 'C');
|
|
|
|
// default for VEN
|
|
$default_deb_sale = $this->get_default_card('VEN', 'D');
|
|
$default_cred_sale = $this->get_default_card('VEN', 'C');
|
|
|
|
// default for FIN
|
|
$default_fin = $this->get_default_card("FIN", "");
|
|
|
|
//default ods
|
|
$default_ods = $this->get_default_card("ODS", "");
|
|
|
|
/* construct all the hidden */
|
|
$hidden = HtmlInput::hidden('p_jrn', -1);
|
|
$hidden.= HtmlInput::hidden('p_action', 'jrn');
|
|
$hidden.= HtmlInput::hidden('sa', 'add');
|
|
$hidden.= dossier::hidden();
|
|
$hidden.=HtmlInput::hidden('p_jrn_deb_max_line', 10);
|
|
$hidden.=HtmlInput::hidden('p_ech_lib', 'echeance');
|
|
|
|
/* properties of the ledger */
|
|
$name = $previous_p_jrn_name;
|
|
$code = "";
|
|
$wType = new ISelect();
|
|
$a_jrn= $this->db->make_array("select '-1',' -- "._("choix du type de journal")." -- ' union select jrn_type_id,jrn_desc from jrn_type");
|
|
$wType->selected='-1';
|
|
$wType->value =$a_jrn;
|
|
$wType->name = "p_jrn_type";
|
|
$wType->id= "p_jrn_type_select_id";
|
|
$wType->javascript=' onchange="show_ledger_div()"';
|
|
$wType->selected=$default_type;
|
|
$type = $wType->input();
|
|
$rcred = $rdeb = array();
|
|
$wPjPref = new IText();
|
|
$wPjPref->name = 'jrn_def_pj_pref';
|
|
$wPjPref->value=$previous_jrn_def_pj_pref;
|
|
$pj_pref = $wPjPref->input();
|
|
$pj_seq = '';
|
|
$last_seq = 0;
|
|
$new = 1;
|
|
$description=new ITextarea('p_description');
|
|
$description->style='class="itextarea" style="margin:0px;"';
|
|
$description->value=$previous_p_description;
|
|
$str_description=$description->input();
|
|
/* bank card */
|
|
$qcode_bank = '';
|
|
/* Numbering (only FIN) */
|
|
$num_op = new ICheckBox('numb_operation');
|
|
echo dossier::hidden();
|
|
echo HtmlInput::hidden('ac', $_REQUEST['ac']);
|
|
echo $hidden;
|
|
|
|
$cn = $this->db;
|
|
$min_row = new INum("min_row",MAX_ARTICLE);
|
|
$min_row->prec=0;
|
|
require_once('template/param_jrn.php');
|
|
}
|
|
|
|
/**
|
|
* Insert a new ledger
|
|
* @param type $array normally $_POST
|
|
* @see verify_ledger
|
|
*/
|
|
function save_new($array)
|
|
{
|
|
$this->load();
|
|
extract($array);
|
|
$this->jrn_def_id = -1;
|
|
$this->jrn_def_name = $p_jrn_name;
|
|
$this->jrn_def_ech_lib = $p_ech_lib;
|
|
$this->jrn_def_max_line_deb = $p_jrn_deb_max_line;
|
|
$this->jrn_def_type = $p_jrn_type;
|
|
$this->jrn_def_pj_pref = $jrn_def_pj_pref;
|
|
$this->jrn_def_fiche_deb = (isset($FICHEDEB)) ? join($FICHEDEB, ',') : "";
|
|
$this->jrn_deb_max_line=$min_row;
|
|
$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));
|
|
$this->jrn_def_description=$p_description;
|
|
switch ($this->jrn_def_type)
|
|
{
|
|
case 'ACH':
|
|
case 'VEN':
|
|
$this->jrn_def_fiche_cred = (isset($FICHECRED)) ? join($FICHECRED, ',') : '';
|
|
|
|
break;
|
|
case 'ODS':
|
|
$this->jrn_def_class_deb = $p_jrn_class_deb;
|
|
$this->jrn_def_fiche_cred = null;
|
|
break;
|
|
case 'FIN':
|
|
$a = new Fiche($this->db);
|
|
$result = $a->get_by_qcode(trim(strtoupper($_POST['bank'])), false);
|
|
$bank = $a->id;
|
|
$this->jrn_def_bank = $bank;
|
|
if ($result == -1)
|
|
throw new Exception(_("Aucun compte en banque n'est donné"));
|
|
$this->jrn_def_num_op = (isset($numb_operation)) ? 1 : 0;
|
|
break;
|
|
}
|
|
|
|
parent::insert();
|
|
}
|
|
|
|
/**
|
|
* delete a ledger IF is not already used
|
|
* @exeption : cannot delete
|
|
*/
|
|
function delete_ledger()
|
|
{
|
|
try
|
|
{
|
|
if ($this->db->get_value("select count(jr_id) from jrn where jr_def_id=$1", array($this->jrn_def_id)) > 0)
|
|
throw new Exception(_("Impossible d'effacer un journal qui contient des opérations"));
|
|
parent::delete();
|
|
}
|
|
catch (Exception $e)
|
|
{
|
|
throw $e;
|
|
}
|
|
}
|
|
/**
|
|
* Get operation from the ledger type before, after or with the
|
|
* given date . The array is filtered by the ledgers granted to the
|
|
* user
|
|
* @global type $g_user
|
|
* @param $p_date Date (d.m.Y)
|
|
* @param $p_ledger_type VEN ACH
|
|
* @param type $sql_op < > or =
|
|
* @return array from jrn (jr_id, jr_internal, jr_date, jr_comment,jr_pj_number,jr_montant)
|
|
* @throws Exception
|
|
*/
|
|
function get_operation_date($p_date,$p_ledger_type,$sql_op)
|
|
{
|
|
global $g_user;
|
|
switch ($p_ledger_type)
|
|
{
|
|
case 'ACH':
|
|
$filter=$g_user->get_ledger_sql('ACH',3);
|
|
break;
|
|
case 'VEN':
|
|
$filter=$g_user->get_ledger_sql('VEN',3);
|
|
break;
|
|
default:
|
|
throw new Exception ('Ledger_type invalid : '.$p_ledger_type);
|
|
}
|
|
|
|
|
|
$sql = "select jr_id, jr_internal, jr_date, jr_comment,jr_pj_number,jr_montant
|
|
from jrn
|
|
join jrn_def on (jrn_def_id=jr_def_id)
|
|
where
|
|
jr_ech is not null
|
|
and jr_ech $sql_op to_date($1,'DD.MM.YYYY')
|
|
and coalesce (jr_rapt,'xx') <> 'paid'
|
|
and $filter
|
|
";
|
|
$array=$this->db->get_array($sql,array($p_date));
|
|
return $array;
|
|
}
|
|
/**
|
|
* @brief get info from supplier to pay today
|
|
*/
|
|
function get_supplier_now()
|
|
{
|
|
$array=$this->get_operation_date(Date('d.m.Y'), 'ACH', '=');
|
|
return $array;
|
|
}
|
|
/**
|
|
* @brief get info from supplier not yet paid
|
|
*/
|
|
function get_supplier_late()
|
|
{
|
|
$array=$this->get_operation_date(Date('d.m.Y'), 'ACH', '<');
|
|
return $array;
|
|
}
|
|
/**
|
|
* @brief get info from customer to pay today
|
|
*/
|
|
function get_customer_now()
|
|
{
|
|
$array=$this->get_operation_date(Date('d.m.Y'), 'VEN', '=');
|
|
return $array;
|
|
}
|
|
/**
|
|
* @brief get info from customer not yet paid
|
|
*/
|
|
function get_customer_late()
|
|
{
|
|
$array=$this->get_operation_date(Date('d.m.Y'), 'VEN', '<');
|
|
return $array;
|
|
}
|
|
function convert_from_follow($p_ag_id)
|
|
{
|
|
global $g_user;
|
|
if (isNumber($p_ag_id)==0) return null;
|
|
if (! $g_user->can_read_action($p_ag_id)) die (_('Action non accessible'));
|
|
$array=array();
|
|
|
|
// retrieve info from action_gestion
|
|
$tiers_id=$this->db->get_value('select f_id_dest from action_gestion where ag_id=$1',array($p_ag_id));
|
|
if ( $this->db->size() !=0 )
|
|
$qcode=$this->db->get_value('select j_qcode from vw_poste_qcode where f_id=$1',array($tiers_id));
|
|
else
|
|
$qcode="";
|
|
|
|
$comment=$this->db->get_value('select ag_title from action_gestion where ag_id=$1',array($p_ag_id));
|
|
$array['e_client']=$qcode;
|
|
$array['e_comm']=$comment;
|
|
|
|
// retrieve info from action_detail
|
|
$a_item=$this->db->get_array('select f_id,ad_text,ad_pu,ad_quant,ad_tva_id,ad_tva_amount,j_qcode
|
|
from
|
|
action_detail
|
|
left join vw_poste_qcode using(f_id)
|
|
where
|
|
ag_id=$1',array($p_ag_id));
|
|
|
|
$array['nb_item']=($this->nb > count($a_item))?$this->nb:count($a_item);
|
|
for ($i=0;$i<count($a_item);$i++)
|
|
{
|
|
$array['e_march'.$i]=$a_item[$i]['j_qcode'];
|
|
$array['e_march'.$i.'_label']=$a_item[$i]['ad_text'];
|
|
$array['e_march'.$i.'_price']=$a_item[$i]['ad_pu'];
|
|
$array['e_march'.$i.'_tva_id']=$a_item[$i]['ad_tva_id'];
|
|
$array['e_march'.$i.'_tva_amount']=$a_item[$i]['ad_tva_amount'];
|
|
$array['e_quant'.$i]=$a_item[$i]['ad_quant'];
|
|
|
|
}
|
|
return $array;
|
|
|
|
}
|
|
/**
|
|
* Retrieve the label of an accounting
|
|
* @param $p_value tmp_pcmn.pcm_val
|
|
* @return string
|
|
*/
|
|
protected function find_label($p_value)
|
|
{
|
|
$lib=$this->db->get_value('select pcm_lib from tmp_pcmn where pcm_val=$1',array($p_value));
|
|
return $lib;
|
|
}
|
|
/**
|
|
* Let you select the repository before confirming a sale or a purchase.
|
|
* Returns an empty string if the company doesn't use stock
|
|
* @brief Let you select the repository before confirming a sale or a purchase.
|
|
* @global type $g_parameter check if company is using stock
|
|
* @param type $p_readonly
|
|
* @param type $p_repo
|
|
* @return string
|
|
*/
|
|
public function select_depot($p_readonly, $p_repo)
|
|
{
|
|
global $g_parameter;
|
|
$r=($p_readonly==false)?'<div id="repo_div_id" style="height:185px;height:10rem;">':'<div id="repo_div_id" >';
|
|
// Show the available repository
|
|
if ($g_parameter->MY_STOCK=='Y')
|
|
{
|
|
$sel=HtmlInput::select_stock($this->db, 'repo', 'W');
|
|
$sel->readOnly=$p_readonly;
|
|
if ($p_readonly==true)
|
|
$sel->selected=$p_repo;
|
|
$r.="<p class=\"decale\">"._('Dans le dépôt')." : ";
|
|
$r.=$sel->input();
|
|
$r.='</p>';
|
|
} else
|
|
{
|
|
$r.='<span class="notice">'.'Stock non utilisé'.'</span>';
|
|
}
|
|
$r.='</div>';
|
|
return $r;
|
|
|
|
}
|
|
/**
|
|
* Create a button to encode a new operation into the same ledger
|
|
* @return string
|
|
*/
|
|
function button_new_operation()
|
|
{
|
|
$url=http_build_query(array('ac'=>$_REQUEST['ac'],'gDossier'=>$_REQUEST['gDossier'],'p_jrn'=>$_REQUEST['p_jrn']));
|
|
$button = HtmlInput::button_anchor(_("Nouvelle opération"), 'do.php?'.$url);
|
|
return '<p>'.$button.'</p>';
|
|
}
|
|
|
|
}
|
|
?>
|