Plugins  LAST
 All Data Structures Files Functions Variables Pages
class_import_bank.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of NOALYSS.
5  *
6  * NOALYSS is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * NOALYSS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with NOALYSS; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 /* $Revision$ */
21 
22 // Copyright (c) 2002 Author Dany De Bontridder dany@alchimerys.be
23 
24 /* * \file
25  * \brief Manage import
26  */
27 require_once 'class_format_bank_sql.php';
28 require_once NOALYSS_INCLUDE.'/class/class_acc_ledger_fin.php';
29 require_once NOALYSS_INCLUDE.'/class/class_periode.php';
30 require_once 'class_temp_bank_sql.php';
31 
33 {
34 
35  /**
36  * @brief for the form we have here all the hidden variables
37  * @return html string with the hidden dossier, plugin_code,action(sa)
38  */
39  static function hidden()
40  {
41  $r=HtmlInput::extension().Dossier::hidden();
42  return $r;
43  }
44 
45  /**
46  * @brief check that there is no duplicate among header and we have at least the date
47  * and the amount
48  * @param array of header
49  * @return empty string if valid, otherwise error message
50  */
51  static function is_valid_header($array)
52  {
53  global $aheader;
55  $error='';
56  $amount=$date=false;
57  for ($i=0; $i<count($array); $i++)
58  {
59  $idx=$array[$i];
60 
61  if ($idx==-1)
62  continue;
63 
64  if ($idx==0)
65  $date=true;
66  if ($idx==1)
67  $amount=true;
68  if (isset($check[$idx+1]['count']))
69  {
70  $check[$idx+1]['count'] ++;
71  }
72  else
73  {
74  $check[$idx+1]['count']=1;
75  }
76  }
77  if (!$date)
78  $error.=_("Il manque la colonne pour les dates")." \n";
79  if (!$amount)
80  $error.=_("Il manque la colonne pour les montants")." \n";
81 
82  foreach ($check as $row)
83  {
84  if ($row['value']==-1)
85  continue;
86  if (isset($row['count'])&&$row['count']>1)
87  $error.=$row['label']." a été donné ".$row['count']." fois\n";
88  }
89  return $error;
90  }
91 
92  /**
93  * @brief show the different import
94  */
95  static function show_import()
96  {
97  global $cn;
98 
99  $ret=$cn->exec_sql('select a.id,to_char(i_date,\'DD.MM.YYYY HH24:MI\') as str_date,format_name,i_date
100  from importbank.import as a
101  left join importbank.format_bank as b on (format_bank_id=b.id)
102  order by i_date desc');
103  $link='?'.Dossier::get().'&plugin_code='.$_REQUEST['plugin_code'].
104  '&sb=list&sa='.$_REQUEST['sa']."&ac=".$_REQUEST['ac'];
105 
106  $status=$cn->prepare('status',
107  'select count(*) from importbank.temp_bank where import_id=$1 and status=$2');
108 
109  require_once('template/show_import.php');
110  }
111 
112  /**
113  * Delete all the selected import
114  */
115  static function delete($p_array)
116  {
117  global $cn;
118 
119  $a=$p_array['s_del'];
120  for ($i=0; $i<count($a); $i++)
121  {
122  $cn->exec_sql('delete from importbank.import where id=$1',
123  array($a[$i]));
124  }
125  }
126 
127  /**
128  * Show detail of a imported file
129  * @parameter $p_id is import.id
130  */
131  static function list_record($p_id)
132  {
133  global $cn;
134  $filter=new ISelect('fil_status');
135  $filter->value=array(
136  array('value'=>0, 'label'=>_('Tous')),
137  array('value'=>1, 'label'=>_('Nouveau')),
138  array('value'=>2, 'label'=>_('Transfèré')),
139  array('value'=>3, 'label'=>_('Attente')),
140  array('value'=>4, 'label'=>_('Erreur')),
141  array('value'=>5, 'label'=>_('Effacer'))
142  );
143  $filter->javascript=' onchange="submit(this)"';
144 
145  $filter->selected=HtmlInput::default_value('fil_status', 0, $_GET);
146  $sql_filter='';
147  $sql_filter=Import_Bank::convert_status_sql($filter->selected);
148  $array=$cn->get_array('select a.id as id,to_char(i_date,\'DD.MM.YYYY HH24:MI\') as i_date,format_name,jrn_def_id
149  from importbank.import as a
150  left join importbank.format_bank as b on (format_bank_id=b.id)
151  where a.id=$1', array($p_id));
152 
153  $ret=$cn->exec_sql(" SELECT id ,ref_operation,tp_date, amount,
154  case when status='N' then 'Nouveau'
155  when status='T' then 'Transfèré'
156  when status='W' then 'Attente'
157  when status='E' then 'ERREUR'
158  when status='D' then 'Effacer'
159  end as f_status,
160  f_id,
161  tp_rec,
162  status,
163  libelle,
164  tp_third, tp_extra,is_checked
165  FROM importbank.temp_bank
166  where import_id=$1 $sql_filter
167  order by tp_date,ref_operation,amount", array($p_id));
168  $remove=false;
169  if ( isset ($array[0]['jrn_def_id']) )
170  {
171  $jrn_name=$cn->get_value('select jrn_def_name from jrn_def where jrn_def_id=$1',
172  array($array[0]['jrn_def_id']));
173  $jrn_account=$cn->get_value("select ad_value from fiche_detail
174  where ad_id=1 and f_id=(select jrn_Def_bank from jrn_def where jrn_def_id=$1) "
175  , array($array[0]['jrn_def_id']));
176  } else {
177  $remove=true;
178  $jrn_name=_("Format effacé");
179  $jrn_account="";
180  }
181  require_once('template/show_list.php');
182  }
183 
184  /**
185  * return the HTML style for the status
186  * White : new
187  * green : transfered
188  * red : error
189  */
190  static function color_status($id)
191  {
192  $style="";
193  $id=strtoupper($id);
194  switch ($id)
195  {
196  case 'E':
197  $style="background-color:red;color:white";
198  break;
199  case 'W':
200  $style="background-color:orange;color:white";
201  break;
202  case 'T':
203  $style="background-color:darkgreen;color:white";
204  break;
205  case 'D':
206  $style="background-color:grey;color:red";
207  break;
208  case 'N':
209  $style="background-color:white;color:blue";
210  break;
211  default:
212  return "$id";
213  }
214  $style='style="'.$style.'"';
215  return $style;
216  }
217 
218  /**
219  * @brief delete the record marked as deleted
220  * @param $p_array is normally the request
221  */
222  static function delete_record($p_array)
223  {
224  global $cn;
225  $cn->exec_sql('delete from importbank.temp_bank where import_id=$1
226  and status=\'D\'', array($p_array['id']));
227  }
228 
229  /**
230  * @brief import row marked to transfer and from the specific import to
231  * the database
232  * @param $p_array
233  */
234  static function transfer_record($p_array)
235  {
236  global $cn;
237 
238  try
239  {
240  $cn->start();
241  /*
242  * retrieve banque account, ledger, bank quick code
243  */
244  $led_id=$cn->get_value('select jrn_def_id
245  from importbank.format_bank as fb
246  join importbank.import as imp on (format_bank_id = fb.id)
247  where imp.id=$1', array($p_array['id']));
248 
249  $fin_ledger=new Acc_Ledger_Fin($cn, $led_id);
250  $card_bank=$fin_ledger->get_bank();
251  $quickcode_bank=$cn->get_value('select ad_value from fiche_detail where f_id=$1 and ad_id=$2',
252  array($card_bank, ATTR_DEF_QUICKCODE));
253  $account_bank=$cn->get_value('select ad_value from fiche_detail where f_id=$1 and ad_id=$2',
254  array($card_bank, ATTR_DEF_ACCOUNT));
255  $bank_name=$fin_ledger->get_name();
256  /*
257  * record each row
258  */
259  $sql="select id from importbank.temp_bank where import_id=$1 and status='W'";
260 
261  $ResAll=$cn->exec_sql($sql, array($p_array['id']));
262  $Max=Database::num_row($ResAll);
263 
264  for ($i=0; $i<$Max; $i++)
265  {
266  $val=Database::fetch_array($ResAll, $i);
267 
268  $row=new Temp_Bank_Sql($cn, $val['id']);
269 
270  if ($row->f_id==null||$row->f_id=='')
271  {
272  // error
273  self::transfert_error($row->id, 'Aucune fiche donnée');
274  continue;
275  }
276 
277  // Retrieve the account thx the quick code
278  $f=new Fiche($cn, $row->f_id);
279  $poste_comptable=$f->strAttribut(ATTR_DEF_ACCOUNT);
280  $quick_code=$f->strAttribut(ATTR_DEF_QUICKCODE);
281 
282  // Vérification que le poste comptable trouvé existe
283  if ($poste_comptable==NOTFOUND||strlen(trim($poste_comptable))==0)
284  {
285  // error
286  self::transfert_error($row->id,
287  _('Poste comptable de la fiche est incorrecte'));
288  continue;
289  }
290  if (self::check_date($row->tp_date)==false)
291  {
292  // error
293  self::transfert_error($row->id, _('Date hors des limites'));
294  continue;
295  }
296  $err=self::is_closed($row->tp_date, $led_id);
297  if ($err!='')
298  {
299  self::transfert_error($row->id,
300  $err._(' - Date hors des journaux'));
301  continue;
302  }
303  // if double accounting
304  if ( strpos($poste_comptable,',') != 0 ) {
305  list($poste_debit,$poste_credit) =explode(',',$poste_comptable);
306  $poste_comptable=($row->amount > 0 ) ? $poste_debit: $poste_credit;
307  }
308  // Finances
309 
310  $seq=$cn->get_next_seq('s_grpt');
311  $p_user=$_SESSION['g_user'];
312 
313  $acc_op=new Acc_Operation($cn);
314  $acc_op->amount=$row->amount;
315  $acc_op->desc="";
316  $acc_op->type="d";
317  $acc_op->date=$row->tp_date;
318  $acc_op->user=$p_user;
319  $acc_op->poste=$account_bank;
320  $acc_op->grpt=$seq;
321  $acc_op->jrn=$led_id;
322  $acc_op->periode=0;
323  $acc_op->f_id=$card_bank;
324  $acc_op->qcode=$quickcode_bank;
325  $acc_op->mt=microtime(true);
326  $r=$acc_op->insert_jrnx();
327 
328 
329  $acc_op->type="c";
330  $acc_op->poste=$poste_comptable;
331  $acc_op->amount=$row->amount;
332  $acc_op->f_id=$row->f_id;
333  $acc_op->qcode=$quick_code;
334  $r=$acc_op->insert_jrnx();
335 
336  $acc_op->desc=$row->tp_third." ".$row->libelle." ".$row->tp_extra;
337  $jr_id=$acc_op->insert_jrn();
338 
339  $internal=$fin_ledger->compute_internal_code($seq);
340 
341  $Res=$cn->exec_sql("update jrn set jr_internal=$1 where jr_id = $2",
342  array($internal, $jr_id));
343 
344  $fin_ledger->insert_quant_fin($card_bank, $jr_id, $row->f_id,
345  $row->amount);
346 
347  // insert rapt
348  if (trim($row->tp_rec)!='')
349  {
350  $acc_reconc=new Acc_Reconciliation($cn);
351  $acc_reconc->set_jr_id($jr_id);
352  $acc_reconc->insert($row->tp_rec);
353  }
354 
355  $sql2="update importbank.temp_bank set status = 'T',tp_error_msg=null where id=$1";
356  $Res2=$cn->exec_sql($sql2, array($row->id));
357  }
358  }
359  catch (Exception $e)
360  {
361  $cn->rollback();
362  echo '<span class="error">'.
363  'Erreur dans '.__FILE__.':'.__LINE__.
364  ' Message = '.$e->getMessage().
365  '</span>';
366  }
367 
368  $cn->commit();
369  }
370 
371  /**
372  * Update the row with an error message, and change is status to E
373  */
374  static function transfert_error($id, $message)
375  {
376  global $cn;
377  $cn->exec_sql('update importbank.temp_bank set status=$1,tp_error_msg=$2 where id=$3',
378  array('E', $message, $id));
379  }
380 
381  /**
382  * check
383  * if the date is outside the defined periode
384  */
385  static function check_date($p_date)
386  {
387  global $cn;
388  $sql="select count(*) from parm_periode where p_start <= to_date($1,'DD.MM.YYYY') and p_end >= to_date($1,'DD.MM.YYYY') ";
389  $res=$cn->get_value($sql, array($p_date));
390  if ($res==0)
391  return false;
392  return true;
393  }
394 
395  /**
396  * Check if the date is in a periode and if the ledger
397  * is closed or not
398  */
399  static function is_closed($p_date, $ledger_id)
400  {
401  global $cn;
402  try
403  {
404  $periode=new Periode($cn);
405  $per=$periode->find_periode($p_date);
406  $periode->set_jrn($ledger_id);
407  $periode->set_periode($per);
408  if ($periode->is_closed()==1)
409  return "Période fermée";
410  return "";
411  }
412  catch (Exception $e)
413  {
414  $err=$e->getMessage();
415  return $err;
416  }
417  }
418  /**
419  * Check that the legder has an card for the bank and this card must also
420  * have a valid accounting
421  * @param integer $p_ledger the ledger id (jrn_def.jrn_def_id)
422  * @return 0 if success , otherwise 1
423  */
424  static function check_bank_account($p_ledger)
425  {
426  global $cn;
427  $ledger=new Acc_Ledger_Fin($cn, $p_ledger);
428  // does ledger exist ?
429  if ($ledger->id==-1||$ledger->type!='FIN')
430  {
431  alert(_('Journal financier mal configuré'));
432  return;
433  }
434 
435  // get card of ledger
436  $bank=$ledger->get_bank();
437  $bank_card=new Fiche($cn);
438  $bank_card->id=$bank;
439  $bank_card->load();
440 
441  // get accounting
442  $bank_accounting=$bank_card->strAttribut(ATTR_DEF_ACCOUNT);
443  $exist=$cn->get_value('
444  select count(*) from tmp_pcmn
445  where
446  pcm_val = $1
447  ', array($bank_accounting)
448  );
449  return $exist;
450  }
451  /**
452  * Do the same operation for all the selected records , the
453  * parameters are found in $_REQUEST
454  * @throws Exception
455  */
456  static function selected_action()
457  {
458 
459  $id=HtmlInput::default_value_request("id", 0);
460  $action=HtmlInput::default_value_request("select_action", 0);
461  $cn=Dossier::connect();
462  if ( $id == 0 || isNumber($id ) == 0 || $action == 0) {
463  throw new Exception(_("Donnée invalide"));
464  }
465  //-------------------
466  // Possible actions
467  //-------------------
468  $same_tiers = 1;
469  $remove_tiers = 2;
470  $suppress_reconcile = 3;
471  $accept_reconcile = 4;
472  $delete_tiers = 5;
473  $recup = 6;
474 
475  switch ($action)
476  {
477  case $same_tiers:
478  //-----------------------------------------------------------
479  // Same tiers
480  //-----------------------------------------------------------
481  echo "same tiers";
482  $fiche_code=HtmlInput::default_value_request("fiche1000", "");
483  $fiche_code=trim($fiche_code);
484  if ($fiche_code == "" ) {
485  throw new Exception(_("Donnée invalide"). "\$fiche_code");
486  }
487 
488  $fiche=new Fiche($cn);
489  $fiche->get_by_qcode($fiche_code,false);
490  if ( $fiche->id == 0 ) {
491  throw new Exception(_("Fiche non trouvée"));
492  }
493 
494  $cn->exec_sql("update importbank.temp_bank set f_id = $1 , "
495  . " status = 'W' , is_checked = 0"
496  . " where "
497  . " import_id = $2 and "
498  . " status in ('N','W','E','D') and"
499  . " is_checked = 1 "
500  , array($fiche->id,$id));
501 
502  break;
503 
504  case $remove_tiers :
505  //-----------------------------------------------------------
506  // Remove tiers from selected records
507  //-----------------------------------------------------------
508  echo "remove_tiers";
509  $cn->exec_sql("update importbank.temp_bank set "
510  . " status = 'N' , is_checked = 0 , f_id = null"
511  . " where "
512  . " import_id = $1 and "
513  . " status <> 'T' and"
514  . " is_checked = 1 "
515  , array($id));
516  break;
517  case $delete_tiers :
518  //-----------------------------------------------------------
519  // Mark for deletion selected records
520  //-----------------------------------------------------------
521  $cn->exec_sql("update importbank.temp_bank set "
522  . " status = 'D' , is_checked = 0"
523  . " where "
524  . " import_id = $1 and "
525  . " status <> 'T' and"
526  . " is_checked = 1 "
527  , array($id));
528  break;
529  case $recup:
530  //-----------------------------------------------------------
531  // Remove the flag for deletion selected records,
532  // reset the status to new
533  //-----------------------------------------------------------
534  $cn->exec_sql("update importbank.temp_bank set "
535  . " status = 'N' , is_checked = 0"
536  . " where "
537  . " import_id = $1 and "
538  . " status = 'D' and"
539  . " is_checked = 1 "
540  , array($id));
541  break;
542  case $suppress_reconcile:
543  //-----------------------------------------------------------
544  // Deleted auto reconcile for selected
545  //-----------------------------------------------------------
546  $sql = "
547  delete
548  from importbank.suggest_bank
549  where
550  temp_bank_id in (select id
551  from importbank.temp_bank
552  where
553  is_checked=1 and import_id=$1)";
554  $cn->exec_sql($sql,array($id));
555  $sql = "
556  update importbank.temp_bank set is_checked=0
557  where
558  is_checked=1 and import_id=$1";
559  $cn->exec_sql($sql,array($id));
560 
561  break;
562  case $accept_reconcile:
563  //-----------------------------------------------------------
564  // Accept automatic reconcile for selected
565  //-----------------------------------------------------------
566  $sql= "
567  update importbank.temp_bank set tp_rec = jr_id::text,
568  is_checked=0 ,
569  f_id=suggest_bank.f_id,
570  status='W'
571  from importbank.suggest_bank
572  where temp_bank_id=temp_bank.id
573  and temp_bank.import_id=$1
574  and temp_bank.is_checked=1
575  and temp_bank.id not in (select temp_bank_id from importbank.suggest_bank group by temp_bank_id having count(temp_bank_id) > 1)
576  ";
577  $cn->exec_sql($sql,array($id));
578  $sql = "
579  update importbank.temp_bank set is_checked=0
580  where
581  is_checked=1 and import_id=$1";
582  $cn->exec_sql($sql,array($id));
583  break;
584 
585  default:
586  throw new Exception(_("action impossible"));
587  break;
588  }
589  }
590  /**
591  * @brief Try to find the concerned operation, fill the table suggest_bank.
592  *
593  * @param type $p_id import.id
594  * @param type $all only checked or all
595  */
596  static function reconcile_auto($p_id,$all=true)
597  {
598  $cn=Dossier::connect();
599 
600  $sql="
601  insert into importbank.suggest_bank (temp_bank_id,jr_id,f_id)
602  select distinct tb.id, jrn.jr_id,jrnx.f_id
603  from
604  jrnx ,
605  jrn ,
606  importbank.temp_bank as tb ,
607  jrn_info
608  where
609  jrnx.j_grpt=jrn.jr_grpt_id
610  and j_date > tb.tp_date - interval '90 days'
611  and j_date < tb.tp_date + interval '90 days'
612  and jrn_info.jr_id = jrn.jr_id
613  and tb.status = 'N'
614  and tb.import_id=$1
615  and jrnx.f_id is not null
616  and ( (amount < 0 and j_debit = false ) or (amount > 0 and j_debit=true))
617  and tb.id not in (select temp_bank_id from importbank.suggest_bank)
618  and jrn_info.id_type in ('OTHER','BON_COMMANDE')
619  and coalesce(jrn_info.ji_value,'') != ''
620  and
621  ( position ( lower(jrn_info.ji_value) in lower(tb.libelle)) > 0
622  or position ( lower(jrn_info.ji_value) in lower(tb.tp_extra)) > 0
623  )
624  ";
625  $cn->exec_sql($sql,array($p_id));
626 
627  $sql="
628  insert into importbank.suggest_bank (temp_bank_id,jr_id,f_id)
629  select distinct tb.id, jr_id,jrnx.f_id
630  from
631  jrnx ,
632  jrn ,
633  importbank.temp_bank as tb
634  where
635  jrnx.j_grpt=jrn.jr_grpt_id
636  and j_date > tb.tp_date - interval '80 days'
637  and j_date < tb.tp_date + interval '80 days'
638  and tb.status = 'N'
639  and tb.import_id=$1
640  and abs(amount) = j_montant
641  and ( (amount < 0 and j_debit = false ) or (amount > 0 and j_debit=true))
642  and jrnx.f_id is not null
643  and tb.id not in (select temp_bank_id from importbank.suggest_bank)
644  and not exists (select jrn_rapt.jr_id from jrn_rapt
645  where jrn_rapt.jr_id = jrn.jr_id
646  or jrn_rapt.jra_concerned =jrn.jr_id)
647  and not exists (select lc.j_id from letter_cred as lc where
648  lc.j_id=jrnx.j_id or lc.jl_id = jrnx.j_id)
649  and not exists (select ld.j_id from letter_deb as ld where
650  ld.j_id=jrnx.j_id or ld.jl_id = jrnx.j_id);
651  ";
652  $cn->exec_sql($sql,array($p_id));
653 
654  }
655  /**
656  * Convert the status (0 to 5 to importbank.temp_bank.status which is
657  * a letter (N New T Transfered W waiting E error D deleted)
658  * @param type $p_param
659  * @return sql string
660  */
661  static function convert_status_sql($p_param) {
662  $sql_filter="";
663  switch ($p_param)
664  {
665  case 1:
666  // new
667  $sql_filter=" and status='N' ";
668  break;
669  case 2:
670  // transfered
671  $sql_filter=" and status='T'";
672  break;
673  case 3:
674  // waiting to be transfered
675  $sql_filter=" and status='W'";
676  break;
677  case 4:
678  // Error
679  $sql_filter=" and status='E'";
680  break;
681  case 5:
682  // deleted
683  $sql_filter=" and status='D'";
684  break;
685  }
686  return $sql_filter;
687  }
688 }
static transfer_record($p_array)
import row marked to transfer and from the specific import to the database
$f
Definition: show_field.php:4
$action
Definition: show_import.php:84
$ret
$periode
for($i=0;$i< Database::num_row($ret);$i++) $row
static list_record($p_id)
Show detail of a imported file $p_id is import.id.
static color_status($id)
return the HTML style for the status White : new green : transfered red : error
$r
static check_date($p_date)
check if the date is outside the defined periode
$style
Definition: detail_item.php:77
static check_bank_account($p_ledger)
Check that the legder has an card for the bank and this card must also have a valid accounting...
static hidden()
for the form we have here all the hidden variables
if(isset($_POST['remove'])) $array
static selected_action()
Do the same operation for all the selected records , the parameters are found in $_REQUEST.
static is_closed($p_date, $ledger_id)
Check if the date is in a periode and if the ledger is closed or not.
static delete_record($p_array)
delete the record marked as deleted
static show_import()
show the different import
static reconcile_auto($p_id, $all=true)
Try to find the concerned operation, fill the table suggest_bank.
$res
static is_valid_header($array)
check that there is no duplicate among header and we have at least the date and the amount ...
$_REQUEST['sb']
Definition: am_print.php:39
$error
$check
Definition: show_list.php:118
$sql
static transfert_error($id, $message)
Update the row with an error message, and change is status to E.
static convert_status_sql($p_param)
Convert the status (0 to 5 to importbank.temp_bank.status which is a letter (N New T Transfered W wai...
global $cn
global $aheader