noalyss  Version-6.9.1.8
 All Data Structures Namespaces Files Functions Variables Pages
class_follow_up.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 // Copyright Author Dany De Bontridder danydb@aevalys.eu
21 require_once NOALYSS_INCLUDE.'/lib/class_itextarea.php';
22 require_once NOALYSS_INCLUDE.'/lib/class_idate.php';
23 require_once NOALYSS_INCLUDE.'/lib/class_iselect.php';
24 require_once NOALYSS_INCLUDE.'/lib/class_ihidden.php';
25 require_once NOALYSS_INCLUDE.'/lib/class_itext.php';
26 require_once NOALYSS_INCLUDE.'/lib/class_ispan.php';
27 require_once NOALYSS_INCLUDE.'/lib/class_icard.php';
28 require_once NOALYSS_INCLUDE.'/lib/class_icheckbox.php';
29 require_once NOALYSS_INCLUDE.'/lib/class_ifile.php';
30 require_once NOALYSS_INCLUDE.'/class/class_fiche.php';
31 require_once NOALYSS_INCLUDE.'/class/class_document.php';
32 require_once NOALYSS_INCLUDE.'/class/class_document_type.php';
33 require_once NOALYSS_INCLUDE.'/class/class_document_modele.php';
34 require_once NOALYSS_INCLUDE.'/lib/user_common.php';
35 require_once NOALYSS_INCLUDE.'/class/class_follow_up_detail.php';
36 require_once NOALYSS_INCLUDE.'/lib/class_inum.php';
37 require_once NOALYSS_INCLUDE.'/lib/class_sort_table.php';
38 require_once NOALYSS_INCLUDE.'/lib/class_irelated_action.php';
39 require_once NOALYSS_INCLUDE.'/class/class_tag.php';
40 require_once NOALYSS_INCLUDE.'/class/class_default_menu.php';
41 /**
42  * \file
43  * \brief class_action for manipulating actions
44  * action can be :
45  * <ul>
46  * <li>an invoice
47  * <li>a meeting
48  * <li>an order
49  * <li>a letter
50  * </ul>
51  * The table document_type are the possible actions
52  */
53 
54 /**
55  * \brief class_action for manipulating actions
56  * action can be :
57  * <ul>
58  * <li> a meeting
59  * <li>an order
60  * <li>a letter
61  * </ul>
62  * The table document_type are the possible actions
63  */
64 class Follow_Up
65 {
66 
67  var $db; /*!< $db database connexion */
68  var $ag_timestamp; /*!< $ag_timestamp document date (ag_gestion.ag_timestamp) */
69  var $dt_id; /*!< $dt_id type of the document (document_type.dt_id) */
70  var $ag_state; /*!< $ag_state stage of the document (printed, send to client...) */
71  var $d_number; /*!< $d_number number of the document */
72  var $d_filename; /*!< $d_filename filename's document */
73  var $d_mimetype; /*!< $d_mimetype document's filename */
74  var $ag_title; /*!< $ag_title title document */
75  var $f_id; /*!< $f_id_dest fiche id (From field ) */
76  var $ag_ref; /*!< $ag_ref is the ref */
77  var $ag_hour; /*!< $ag_hour is the hour of the meeting, action */
78  var $ag_priority; /*!< $ag_priority is the priority 1 High, 2 medium, 3 low */
79  var $ag_dest; /*!< $ag_dest person who is in charged */
80  var $ag_contact; /*!< $ag_contact contact */
81  var $ag_remind_date; /*!< $ag_contact contact */
82 
83  /**
84  * @brief $operation string related operation
85  */
87 
88  /**
89  * @brief $action string related action
90  */
91  var $action;
92 
93  /**
94  * @brief constructor
95  * \brief constructor
96  * \param p_cn database connection
97  */
98  function __construct($p_cn, $p_id=0)
99  {
100  $this->db=$p_cn;
101  $this->ag_id=$p_id;
102  $this->f_id=0;
103  $this->aAction_detail=array();
104  $this->operation="";
105  $this->action="";
106  }
107  /**
108  * Create a filter based on the current user,
109  * @remark type $g_user Connected user
110  * @param type $cn Database connection
111  * @param type $p_mode Mode is R (for Read) or W (for write)
112  * @return string SQL where clause to include in the SQL
113  * example: (ag_dest in (select p_granted from user_sec_action_profile where p_id=x)
114  */
115  static function sql_security_filter($cn, $p_mode)
116  {
117  global $g_user;
118  $profile=$cn->get_value("select p_id from profile_user where user_name=$1", array($g_user->login));
119  if ($profile=='')
120  die("Security");
121  if ($p_mode=='R')
122  {
123  $sql=" (ag_dest in (select p_granted from user_sec_action_profile where p_id=$profile ) ) ";
124  } else if ($p_mode=='W')
125  {
126  $sql=" ( ag_dest in (select p_granted from user_sec_action_profile where p_id=$profile and ua_right='W' ) )";
127  } else {
128  error_log(_('Securité'));
129  throw new Exception(_('Securité'));
130  }
131  return $sql;
132  }
133 
134  //----------------------------------------------------------------------
135  /**
136  * \brief Display the object, the tags for the FORM
137  * are in the caller. It will be used for adding and updating
138  * action
139  * \note If ag_id is not equal to zero then it is an update otherwise
140  * it is a new document
141  *
142  * \param $p_view form will be in readonly mode (value: READ, UPD or NEW )
143  * \param $p_gen true we show the tag for generating a doc (value : true or false) and adding files
144  * \param $p_base is the ac parameter
145  * \param $retour is the html code for the return button
146  * \note update the reference number or the document type is not allowed
147  *
148  *
149  * \return string containing the html code
150  */
151  function Display($p_view, $p_gen, $p_base, $retour="")
152  {
153  global $g_user;
154  if ($p_view=='UPD')
155  {
156  $upd=true;
157  $readonly=false;
158  }
159  elseif ($p_view=="NEW")
160  {
161  $upd=false;
162  $readonly=false;
163  $this->ag_ref=_("Nouveau");
164  }
165  elseif ($p_view=='READ')
166  {
167  $upd=true;
168  $readonly=true;
169  }
170  else
171  {
172  throw new Exception('class_action'.__LINE__.'Follow_Up::Display error unknown parameter'.$p_view);
173  }
174  // Compute the widget
175  // Date
176  $date=new IDate();
177  $date->readOnly=$readonly;
178  $date->name="ag_timestamp";
179  $date->id="ag_timestamp";
180  $date->value=$this->ag_timestamp;
181 
182  $remind_date=new IDate();
183  $remind_date->readOnly=$readonly;
184  $remind_date->name="ag_remind_date";
185  $remind_date->id="ag_remind_date";
186  $remind_date->value=$this->ag_remind_date;
187 
188 
189  // Doc Type
190  $doc_type=new ISelect();
191  $doc_type->name="dt_id";
192  $doc_type->value=$this->db->make_array("select dt_id,dt_value from document_type order by dt_value", 1);
193  $doc_type->selected=$this->dt_id;
194  $doc_type->readOnly=$readonly;
195  $str_doc_type=$doc_type->input();
196 
197  // Description
198  $desc=new ITextArea();
199  $desc->style=' class="itextarea" style="width:80%;margin-left:0px"';
200  $desc->name="ag_comment";
201  $desc->readOnly=$readonly;
202  $acomment=$this->db->get_array("SELECT agc_id, ag_id, to_char(agc_date,'DD.MM.YYYY HH24:MI') as str_agc_date, agc_comment, tech_user
203  FROM action_gestion_comment where ag_id=$1 order by agc_id", array($this->ag_id)
204  );
205 
206  // List opération liées
207  $operation=$this->db->get_array("select ago_id,j.jr_id,j.jr_internal,j.jr_comment,to_char(j.jr_date,'DD.MM.YY') as str_date
208  from jrn as j join action_gestion_operation as ago on (j.jr_id=ago.jr_id)
209  where ag_id=$1 order by jr_date", array($this->ag_id));
210  $iconcerned=new IConcerned('operation');
211 
212  // List related action
213  $iaction=new IRelated_Action('action');
214  $iaction->value=(isset($this->action))?$this->action:"";
215 
216  // state
217  // Retrieve the value
218  $a=$this->db->make_array("select s_id,s_value from document_state ");
219  $state=new ISelect();
220  $state->readOnly=$readonly;
221  $state->name="ag_state";
222  $state->value=$a;
223  $state->selected=$this->ag_state;
224  $str_state=$state->input();
225 
226  // Retrieve the value if there is an attached doc
227  $doc_ref="";
228  // Document id
229 
230  $h2=new IHidden();
231  $h2->name="d_id";
232  $h2->value=$this->d_id;
233 
234  if ($this->d_id!=0&&$this->d_id!="")
235  {
236  $h2->readonly=($p_view=='NEW')?false:true;
237  $doc=new Document($this->db, $this->d_id);
238  $doc->get();
239  if (strlen(trim($doc->d_lob))!=0)
240  {
241  $d_id=new IHidden();
242  $doc_ref="<p> Document ".$doc->anchor().'</p>';
243  $doc_ref.=$h2->input().$d_id->input('d_id', $this->d_id);
244  }
245  }
246 
247 
248  // title
249  $title=new IText();
250  $title->readOnly=$readonly;
251  $title->name="ag_title";
252  $title->value=$this->ag_title;
253  $title->size=60;
254 
255 
256  // Priority of the ag_priority
257  $ag_priority=new ISelect();
258  $ag_priority->readOnly=$readonly;
259  $ag_priority->name="ag_priority";
261  $ag_priority->value=array(array('value'=>1, 'label'=>_('Haute')),
262  array('value'=>2, 'label'=>_('Moyenne')),
263  array('value'=>3, 'label'=>_('Basse'))
264  );
265  $str_ag_priority=$ag_priority->input();
266 
267  // hour of the action (meeting) ag_hour
268  $ag_hour=new IText();
269  $ag_hour->readOnly=$readonly;
270  $ag_hour->name="ag_hour";
271  $ag_hour->value=$this->ag_hour;
272  $ag_hour->size=6;
273  $ag_hour->javascript=" onblur=check_hour('ag_hour');";
274  $str_ag_hour=$ag_hour->input();
275 
276  // Profile in charged of the action
277  $ag_dest=new ISelect();
278  $ag_dest->readOnly=$readonly;
279  $ag_dest->name="ag_dest";
280  // select profile
281  $aAg_dest=$this->db->make_array("select p_id as value, ".
282  "p_name as label ".
283  " from profile where p_id in ".$g_user->get_writable_profile()."order by 2");
284 
285  $ag_dest->value=$aAg_dest;
286  $ag_dest->selected=$this->ag_dest;
287  $str_ag_dest=$ag_dest->input();
288 
289  // ag_ref
290  // Always false for update
291 
292  $client_label=new ISpan();
293 
294  /* Add button */
295  $f_add_button=new IButton('add_card');
296  $f_add_button->label=_('Créer une nouvelle fiche');
297  $f_add_button->set_attribute('ipopup', 'ipop_newcard');
298  $filter=$this->db->make_list('select fd_id from fiche_def ');
299  $f_add_button->set_attribute('filter', $filter);
300 
301  $f_add_button->javascript=" select_card_type(this);";
302  $str_add_button=$f_add_button->input();
303 
304  // f_id_dest sender
305  if ($this->qcode_dest!=NOTFOUND&&strlen(trim($this->qcode_dest))!=0)
306  {
307  $tiers=new Fiche($this->db);
308  $tiers->get_by_qcode($this->qcode_dest);
309  $qcode_dest_label=$tiers->strAttribut(1);
310  $this->f_id_dest=$tiers->id;
311  }
312  else
313  {
314  $qcode_dest_label=($this->f_id_dest==0||trim($this->qcode_dest)=="")?'Interne ':'Error';
315  }
316 
317  $h_ag_id=new IHidden();
318  // if concerns another action : show the link otherwise nothing
319  //
320  // sender
321  $w=new ICard();
322  $w->readOnly=$readonly;
323  $w->jrn=0;
324  $w->name='qcode_dest';
325  $w->value=($this->f_id_dest!=0)?$this->qcode_dest:"";
326  $w->label="";
327  $list_recipient=$this->db->make_list('select fd_id from fiche_def where frd_id in (14,25,8,9,16)');
328  $w->extra=$list_recipient;
329  $w->set_attribute('typecard', $list_recipient);
330  $w->set_dblclick("fill_ipopcard(this);");
331  $w->set_attribute('ipopup', 'ipopcard');
332 
333  // name of the field to update with the name of the card
334  $w->set_attribute('label', 'qcode_dest_label');
335  // name of the field to update with the name of the card
336  $w->set_attribute('typecard', $w->extra);
337  $w->set_function('fill_data');
338  $w->javascript=sprintf(' onchange="fill_data_onchange(\'%s\');" ', $w->name);
339 
340  $sp=new ISpan();
341  $sp->name='qcode_dest_label';
342  $sp->value=$qcode_dest_label;
343 
344  // autre - a refaire pour avoir plusieurs fiches
345  // Sur le modèle des tags
346  $ag_contact=new ICard();
347  $ag_contact->readOnly=$readonly;
348  $ag_contact->jrn=0;
349  $ag_contact->name='ag_contact';
350  $ag_contact->value='';
351  $ag_contact->set_attribute('ipopup', 'ipopcard');
352 
353  if ($this->ag_contact!=0)
354  {
355  $contact=new Fiche($this->db, $this->ag_contact);
356  $ag_contact->value=$contact->get_quick_code();
357  }
358 
359  $ag_contact->label="";
360 
361  $list_contact=$this->db->make_list('select fd_id from fiche_def where frd_id=16');
362  $ag_contact->extra=$list_contact;
363 
364  $ag_contact->set_dblclick("fill_ipopcard(this);");
365  // name of the field to update with the name of the card
366  $ag_contact->set_attribute('label', 'ag_contact_label');
367  // name of the field to update with the name of the card
368  $ag_contact->set_attribute('typecard', $list_contact);
369  $ag_contact->set_function('fill_data');
370  $ag_contact->javascript=sprintf(' onchange="fill_data_onchange(\'%s\');" ', $ag_contact->name);
371 
372  $spcontact=new ISpan();
373  $spcontact->name='ag_contact_label';
374  $spcontact->value='';
375  $fiche_contact=new Fiche($this->db);
376  $fiche_contact->get_by_qcode($this->ag_contact);
377  if ($fiche_contact->id!=0)
378  {
379  $spcontact->value=$fiche_contact->strAttribut(ATTR_DEF_NAME);
380  }
381 
382 
383  $h_agrefid=new IHidden();
384  $iag_ref=new IText("ag_ref");
385  $iag_ref->value=$this->ag_ref;
386  $iag_ref->readOnly=($p_view=="NEW"||$p_view=='READ')?true:false;
387  $str_ag_ref=$iag_ref->input();
388  // Preparing the return string
389  $r="";
390 
391  /* for new files */
392  $upload=new IFile();
393  $upload->name="file_upload[]";
394  $upload->readOnly=$readonly;
395  $upload->value="";
396  $aAttachedFile=$this->db->get_array('select d_id,d_filename,d_description,d_mimetype,'.
397  '\'export.php?act=RAW:document&'.
398  Dossier::get().'&d_id=\'||d_id as link'.
399  ' from document where ag_id=$1', array($this->ag_id));
400  /* create the select for document */
401  $aDocMod=new ISelect();
402  $aDocMod->name='doc_mod';
403  $aDocMod->value=$this->db->make_array('select md_id,dt_value||\' : \'||md_name as md_name'.
404  ' from document_modele join document_type on (md_type=dt_id)'.
405  ' order by md_name');
406  $str_select_doc=$aDocMod->input();
407  /* if no document then do not show the generate button */
408  if (empty($aDocMod->value))
409  $str_submit_generate="";
410  else
411  $str_submit_generate=HtmlInput::submit("generate", _("Génére le document"));
412 
414 
415  /* fid = Icard */
416  $icard=new ICard();
417  $icard->jrn=0;
418  $icard->table=0;
419  $icard->extra2='QuickCode';
420  $icard->noadd="no";
421  $icard->extra='all';
422 
423  /* Text desc */
424  $text=new IText();
425  $num=new INum();
426 
427  /* TVA */
428  $itva=new ITva_Popup($this->db);
429  $itva->in_table=true;
430  $aCard=array();
431  /* create aArticle for the detail section */
432  $article_count=(count($this->aAction_detail)==0)?MAX_ARTICLE:count($this->aAction_detail);
433  /* Compute total */
434  $tot_item=0;
435  $tot_vat=0;
436  for ($i=0; $i<$article_count; $i++)
437  {
438  /* fid = Icard */
439  $icard=new ICard();
440  $icard->jrn=0;
441  $icard->table=0;
442  $icard->noadd="no";
443  $icard->extra='all';
444  $icard->name="e_march".$i;
445  $tmp_ad=(isset($this->aAction_detail[$i]))?$this->aAction_detail[$i]:false;
446  $icard->readOnly=$readonly;
447  $icard->value='';
448  $aCard[$i]=0;
449  if ($tmp_ad)
450  {
451  $march=new Fiche($this->db);
452  $f=$tmp_ad->get_parameter('qcode');
453  if ($f!=0)
454  {
455  $march->id=$f;
456  $icard->value=$march->get_quick_code();
457  $aCard[$i]=$f;
458  }
459  }
460  $icard->set_dblclick("fill_ipopcard(this);");
461  // name of the field to update with the name of the card
462  $icard->set_attribute('label', "e_march".$i."_label");
463  // name of the field to update with the name of the card
464  $icard->set_attribute('typecard', $icard->extra);
465  $icard->set_attribute('ipopup', 'ipopcard');
466  $icard->set_function('fill_data');
467  $icard->javascript=sprintf(' onchange="fill_data_onchange(\'%s\');" ', $icard->name);
468 
469  $aArticle[$i]['fid']=$icard->search().$icard->input();
470 
471  $text->javascript=' onchange="clean_tva('.$i.');compute_ledger('.$i.')"';
472  $text->css_size="100%";
473  $text->name="e_march".$i."_label";
474  $text->id="e_march".$i."_label";
475  $text->size=40;
476  $text->value=($tmp_ad)?$tmp_ad->get_parameter('text'):"";
477  $text->readOnly=$readonly;
478  $aArticle[$i]['desc']=$text->input();
479 
480  $num->javascript=' onchange="format_number(this,4);clean_tva('.$i.');compute_ledger('.$i.')"';
481  $num->name="e_march".$i."_price";
482  $num->id="e_march".$i."_price";
483  $num->size=8;
484  $num->readOnly=$readonly;
485  $num->value=($tmp_ad)?$tmp_ad->get_parameter('price_unit'):0;
486  $aArticle[$i]['pu']=$num->input();
487 
488  $num->name="e_quant".$i;
489  $num->id="e_quant".$i;
490  $num->size=8;
491  $num->value=($tmp_ad)?$tmp_ad->get_parameter('quantity'):0;
492  $aArticle[$i]['quant']=$num->input();
493 
494  $itva->name='e_march'.$i.'_tva_id';
495  $itva->id='e_march'.$i.'_tva_id';
496  $itva->value=($tmp_ad)?$tmp_ad->get_parameter('tva_id'):0;
497  $itva->readOnly=$readonly;
498  $itva->js=' onchange="format_number(this);clean_tva('.$i.');compute_ledger('.$i.')"';
499  $itva->set_attribute('compute', $i);
500 
501  $aArticle[$i]['tvaid']=$itva->input();
502 
503  $num->name="e_march".$i."_tva_amount";
504  $num->id="e_march".$i."_tva_amount";
505  $num->value=($tmp_ad)?$tmp_ad->get_parameter('tva_amount'):0;
506  $num->javascript=" onchange=\"compute_ledger('".$i." ')\"";
507  $num->size=8;
508  $aArticle[$i]['tva']=$num->input();
509  $tot_vat=bcadd($tot_vat,$num->value);
510 
511  $num->name="tvac_march".$i;
512  $num->id="tvac_march".$i;
513  $num->value=($tmp_ad)?$tmp_ad->get_parameter('total'):0;
514  $num->size=8;
515  $aArticle[$i]['tvac']=$num->input();
516  $tot_item=bcadd($tot_item,$num->value);
517 
518  $aArticle[$i]['hidden_htva']=HtmlInput::hidden('htva_march'.$i, 0);
519  $aArticle[$i]['hidden_tva']=HtmlInput::hidden('tva_march'.$i, 0);
520  $aArticle[$i]['ad_id']=($tmp_ad)?HtmlInput::hidden('ad_id'.$i, $tmp_ad->get_parameter('id')):HtmlInput::hidden('ad_id'.$i, 0);
521  }
522 
523  /* Add the needed hidden values */
524  $r.=dossier::hidden();
525 
526  /* add the number of item */
527  $Hid=new IHidden();
528  $r.=$Hid->input("nb_item", $article_count);
529  $r.=HtmlInput::request_to_hidden(array("closed_action", "remind_date_end", "remind_date", "sag_ref", "only_internal", "state", "qcode", "ag_dest_query", "action_query", "tdoc", "date_start", "date_end", "hsstate", "searchtag"));
530  $a_tag=$this->tag_get();
531  $menu=new Default_Menu();
532  /* get template */
533  ob_start();
534  require NOALYSS_TEMPLATE.'/detail-action.php';
535  $content=ob_get_contents();
536  ob_end_clean();
537  $r.=$content;
538 
539  //hidden
540  $r.="<p>";
541  $r.=$h2->input();
542  $r.=$h_ag_id->input('ag_id', $this->ag_id);
543  $hidden2=new IHidden();
544  $r.=$hidden2->input('f_id_dest', $this->f_id_dest);
545  $r.="</p>";
546 
547  return $r;
548  }
549 
550  //----------------------------------------------------------------------
551  /**
552  * \brief This function shows the detail of an action thanks the ag_id
553  */
554  function get()
555  {
556  $sql="select ag_id,to_char (ag_timestamp,'DD.MM.YYYY') as ag_timestamp,".
557  " f_id_dest,ag_title,ag_ref,d_id,ag_type,ag_state, ag_owner, ".
558  " ag_dest, ag_hour, ag_priority, ag_contact,to_char (ag_remind_date,'DD.MM.YYYY') as ag_remind_date ".
559  " from action_gestion left join document using (ag_id) where ag_id=".$this->ag_id;
560  $r=$this->db->exec_sql($sql);
562  if ($row==false)
563  {
564  $this->ag_id=0;
565  return;
566  }
567  $this->ag_timestamp=$row[0]['ag_timestamp'];
568  $this->ag_contact=$row[0]['ag_contact'];
569  $this->f_id_dest=$row[0]['f_id_dest'];
570  $this->ag_title=$row[0]['ag_title'];
571  $this->ag_type=$row[0]['ag_type'];
572  $this->ag_ref=$row[0]['ag_ref'];
573  $this->ag_state=$row[0]['ag_state'];
574  $this->d_id=$row[0]['d_id'];
575  $this->ag_dest=$row[0]['ag_dest'];
576  $this->ag_hour=$row[0]['ag_hour'];
577  $this->ag_priority=$row[0]['ag_priority'];
578  $this->ag_remind_date=$row[0]['ag_remind_date'];
579  $this->ag_owner=$row[0]['ag_owner'];
580 
581  $action_detail=new Follow_Up_Detail($this->db);
582  $action_detail->set_parameter('ag_id', $this->ag_id);
583  $this->aAction_detail=$action_detail->load_all();
584 
585 
586  // if there is no document set 0 to d_id
587  if ($this->d_id=="")
588  $this->d_id=0;
589  // if there is a document fill the object
590  if ($this->d_id!=0)
591  {
592  $this->state=$row['0']['ag_state'];
593  $this->ag_state=$row[0]['ag_state'];
594  }
595  $this->dt_id=$this->ag_type;
596  $aexp=new Fiche($this->db, $this->f_id_dest);
597  $this->qcode_dest=$aexp->strAttribut(ATTR_DEF_QUICKCODE);
598  }
599 
600  /**
601  * \brief Save the document and propose to save the generated document or
602  * to upload one, the data are included except the file. Temporary the generated
603  * document is save.
604  * The files into $_FILES['file_upload'] will be saved
605  * @note the array $_POST['input_desc'] must be set, contains the description
606  * of the uploaded files
607  *
608  * \return
609  */
610  function save()
611  {
612 
613  // Get The sequence id,
614  $seq_name="seq_doc_type_".$this->dt_id;
615  $str_file="";
616  $add_file='';
617 
618  // f_id exp
619  $exp=new Fiche($this->db);
620  $exp->get_by_qcode($this->qcode_dest);
621  $exp->id=($exp->id==0)?null:$exp->id;
622 
623  $contact=new Fiche($this->db);
624  $contact->get_by_qcode($this->ag_contact);
625 
626  if (trim($this->ag_title)=="")
627  {
628  $doc_mod=new document_type($this->db);
629  $doc_mod->dt_id=$this->dt_id;
630  $doc_mod->get();
631  $this->ag_title=$doc_mod->dt_value;
632  }
633  $this->ag_id=$this->db->get_next_seq('action_gestion_ag_id_seq');
634 
635  // Create the reference
636  $ag_ref=$this->db->get_value('select dt_prefix from document_type where dt_id=$1', array($this->dt_id)).'-'.$this->db->get_next_seq($seq_name);
637  $this->ag_ref=$ag_ref;
638 
639  // save into the database
640  if ($this->ag_remind_date!=null||$this->ag_remind_date!='')
641  {
642  $sql="insert into action_gestion".
643  "(ag_id,ag_timestamp,ag_type,ag_title,f_id_dest,ag_ref, ag_dest, ".
644  " ag_hour, ag_priority,ag_owner,ag_contact,ag_state,ag_remind_date) ".
645  " values ($1,to_date($2,'DD.MM.YYYY'),$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,to_date($13,'DD.MM.YYYY'))";
646  }
647  else
648  {
649  $this->ag_remind_date=null;
650  $sql="insert into action_gestion".
651  "(ag_id,ag_timestamp,ag_type,ag_title,f_id_dest,ag_ref, ag_dest, ".
652  " ag_hour, ag_priority,ag_owner,ag_contact,ag_state,ag_remind_date) ".
653  " values ($1,to_date($2,'DD.MM.YYYY'),$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13)";
654  }
655  $this->db->exec_sql($sql, array($this->ag_id, /* 1 */
656  $this->ag_timestamp, /* 2 */
657  $this->dt_id, /* 3 */
658  $this->ag_title, /* 4 */
659  $exp->id, /* 5 */
660  $ag_ref, /* 6 */
661  $this->ag_dest, /* 7 */
662  $this->ag_hour, /* 8 */
663  $this->ag_priority, /* 9 */
664  $_SESSION['g_user'], /* 10 */
665  $contact->id, /* 11 */
666  $this->ag_state, /* 12 */
667  $this->ag_remind_date /* 13 */
668  )
669  );
670 
671  /* insert also the details */
672  for ($i=0; $i<$_POST['nb_item']; $i++)
673  {
674  $act=new Follow_Up_Detail($this->db);
675  $act->from_array($_POST, $i);
676  if ($act->f_id==0)
677  continue;
678  $act->ag_id=$this->ag_id;
679  $act->save();
680  }
681 
682  /* Upload the documents */
683  $doc=new Document($this->db);
684  $doc->Upload($this->ag_id);
685  if (trim($this->ag_comment)!='')
686  {
687  $this->db->exec_sql("insert into action_gestion_comment (ag_id,tech_user,agc_comment) values ($1,$2,$3)"
688  , array($this->ag_id, $_SESSION['g_user'], $this->ag_comment));
689  }
690  $this->insert_operation();
691  $this->insert_action();
692  }
693 
694  /**
695  * myList($p_base, $p_filter = "", $p_search = "")
696  * Show list of action by default if sorted on date
697  * @param $p_base base url with ac...
698  * @param $p_filter filters on the document_type
699  * @param $p_search must a valid sql command ( ex 'and ag_title like upper('%hjkh%'))
700  * @return string containing html code
701  */
702  function myList($p_base, $p_filter="", $p_search="")
703  {
704  // for the sort
705  $url=HtmlInput::get_to_string(array("closed_action", "remind_date_end", "remind_date", "sag_ref", "only_internal", "state", "qcode", "ag_dest_query", "action_query", "tdoc", "date_start", "date_end", "hsstate", "searchtag")).'&'.$p_base;
706 
707  $table=new Sort_Table();
708  $table->add('Date Doc.', $url, 'order by ag_timestamp asc', 'order by ag_timestamp desc', 'da', 'dd');
709  $table->add('Date Comm.', $url, 'order by last_comment', 'order by last_comment desc', 'dca', 'dcd');
710  $table->add('Date Limite', $url, 'order by ag_remind_date asc', 'order by ag_remind_date desc', 'ra', 'rd');
711  $table->add('Tag', $url, 'order by tags asc', 'order by tags desc', 'taa', 'tad');
712  $table->add('Réf.', $url, 'order by ag_ref asc', 'order by ag_ref desc', 'ra', 'rd');
713  $table->add('Groupe', $url, "order by coalesce((select p_name from profile where p_id=ag_dest),'Aucun groupe')", "order by coalesce((select p_name from profile where p_id=ag_dest),'Aucun groupe') desc", 'dea', 'ded');
714  $table->add('Dest/Exp', $url, 'order by name asc', 'order by name desc', 'ea', 'ed');
715  $table->add('Titre', $url, 'order by ag_title asc', 'order by ag_title desc', 'ta', 'td');
716 
717  $ord=(!isset($_GET['ord']))?"dcd":$_GET['ord'];
718  $sort=$table->get_sql_order($ord);
719 
720  if (strlen(trim($p_filter))!=0)
721  $p_filter_doc=" dt_id in ( $p_filter )";
722  else
723  $p_filter_doc=" 1=1 ";
724 
725  $sql="
726  select ag_id,to_char(ag_timestamp,'DD.MM.YYYY') as my_date,
727  to_char(ag_remind_date,'DD.MM.YYYY') as my_remind,
728  to_char(coalesce((select max(agc_date) from action_gestion_comment as agc where agc.ag_id=ag.ag_id),ag_timestamp),'DD.MM.YY') as str_last_comment,
729  coalesce((select max(agc_date) from action_gestion_comment as agc where agc.ag_id=ag.ag_id),ag_timestamp) as last_comment,
730  f_id_dest,
731  s_value,
732  ag_title,dt_value,ag_ref, ag_priority,ag_state,
733  coalesce((select p_name from profile where p_id=ag_dest),'Aucun groupe') as dest,
734  (select ad_value from fiche_Detail where f_id=ag.f_id_dest and ad_id=1) as name,
735  array_to_string((select array_agg(t1.t_tag) from action_tags as a1 join tags as t1 on (a1.t_id=t1.t_id) where a1.ag_id=ag.ag_id ),',') as tags
736  from action_gestion as ag
737  join document_type on (ag_type=dt_id)
738  join document_state on (ag_state=s_id)
739  where $p_filter_doc $p_search $sort";
740  $max_line=$this->db->count_sql($sql);
741  $step=$_SESSION['g_pagesize'];
742  $page=(isset($_GET['offset']))?$_GET['page']:1;
743  $offset=(isset($_GET['offset']))?Database::escape_string($_GET['offset']):0;
744  if ($step!=-1)
745  $limit=" LIMIT $step OFFSET $offset ";
746  else
747  $limit='';
749 
750  $Res=$this->db->exec_sql($sql.$limit);
751  $a_row=Database::fetch_all($Res);
752 
753  $r="";
754  $r.='<p>'.$bar.'</p>';
755  $r.='<table class="document">';
756  $r.="<tr>";
757  $r.='<th name="ag_id_td" style="display:none" >'.ICheckBox::toggle_checkbox('ag', 'list_ag_frm').'</th>';
758  $r.='<th>'.$table->get_header(0).'</th>';
759  $r.='<th>'.$table->get_header(1).'</th>';
760  $r.='<th>'.$table->get_header(2).'</th>';
761  $r.='<th>'.$table->get_header(3).'</th>';
762  $r.='<th>'.$table->get_header(4).'</th>';
763  $r.='<th>'.$table->get_header(5).'</th>';
764  $r.='<th>'.$table->get_header(6).'</th>';
765  $r.='<th>'.$table->get_header(7).'</th>';
766  $r.=th('Priorité');
767  $r.="</tr>";
768 
769 
770  // if there are no records return a message
771  if (sizeof($a_row)==0 or $a_row==false)
772  {
773  $r='<div style="clear:both">';
774  $r.='<hr>Aucun enregistrement trouvé';
775  $r.="</div>";
776  return $r;
777  }
778  $today=date('d.m.Y');
779  $i=0;
780  $checkbox=new ICheckBox("mag_id[]");
781  //show the sub_action
782  foreach ($a_row as $row)
783  {
784  $href='<A class="document" HREF="do.php?'.$p_base.HtmlInput::get_to_string(array("closed_action", "remind_date_end", "remind_date", "sag_ref", "only_internal", "state", "gDossier", "qcode", "ag_dest_query", "action_query", "tdoc", "date_start", "date_end", "hsstate", "searchtag", "ac"), "&").'&sa=detail&ag_id='.$row['ag_id'].'">';
785  $i++;
786  $tr=($i%2==0)?'even':'odd';
787  if ($row['ag_priority']<2)
788  $tr='priority1';
789  $st='';
790  if ($row['my_date']==$today)
791  $st=' style="font-weight:bold; border:2px solid orange;"';
792  $date_remind=format_date($row['my_remind'], 'DD.MM.YYYY', 'YYYYMMDD');
793  $date_today=date('Ymd');
794  if ($date_remind!=""&&$date_remind==$date_today&&$row['ag_state']!=1&&$row['ag_state']!=3)
795  $st=' style="font-weight:bold;background:orange"';
796  if ($date_remind!=""&&$date_remind<$date_today&&$row['ag_state']!=1&&$row['ag_state']!=3)
797  $st=' style="font-weight:bold;background:#FF0000;color:white;"';
798  $r.="<tr class=\"$tr\" $st>";
799  $checkbox->value=$row['ag_id'];
800  $r.='<td name="ag_id_td" style="display:none">'.$checkbox->input().'</td>';
801  $r.="<td>".$href.smaller_date($row['my_date']).'</a>'."</td>";
802  $r.="<td>".$href.$row['str_last_comment'].'</a>'."</td>";
803  $r.="<td>".$href.smaller_date($row['my_remind']).'</a>'."</td>";
804  $r.="<td>".$href.h($row['tags']).'</a>'."</td>";
805  $r.="<td>".$href.$row['ag_ref'].'</a>'."</td>";
806  $r.="<td>".$href.h($row['dest']).'</a>'."</td>";
807 
808  // Expediteur
809  $fexp=new Fiche($this->db);
810  $fexp->id=$row['f_id_dest'];
811  $qcode_dest=$fexp->strAttribut(ATTR_DEF_QUICKCODE);
812 
813  $qexp=($qcode_dest==NOTFOUND)?"Interne":$qcode_dest;
814  $jsexp=sprintf("javascript:showfiche('%s')", $qexp);
815  if ($qexp!='Interne')
816  {
817  $r.="<td>$href".$qexp." : ".$fexp->getName().'</a></td>';
818  }
819  else
820  $r.="<td>$href Interne </a></td>";
821 
822  $ref="";
823 
824 
825  $r.='<td>'.$href.
826  h($row['ag_title'])."</A></td>";
827 
828  /*
829  * State
830  */
831  switch ($row['ag_priority'])
832  {
833  case 1:
834  $priority='Haute';
835  break;
836  case 2:
837  $priority="Moyenne";
838  break;
839  case 3:
840  $priority="Important";
841  break;
842  }
843  $r.=td($priority);
844 
845  $r.="<td>".$ref."</td>";
846  $r.="</tr>";
847  }
848 
849  $r.="</table>";
850 
851  $r.='<p>'.$bar.'</p>';
852  return $r;
853  }
854 
855  //----------------------------------------------------------------------
856  /* * \brief Update the data into the database
857  *
858  * \return true on success otherwise false
859  */
860  function Update()
861  {
862 
863  // if ag_id == 0 nothing to do
864  if ($this->ag_id==0)
865  return;
866  // retrieve customer
867  // f_id
868 
869  if (trim($this->qcode_dest)=="")
870  {
871  // internal document
872  $this->f_id_dest=null; // internal document
873  }
874  else
875  {
876  $tiers=new Fiche($this->db);
877  if ($tiers->get_by_qcode($this->qcode_dest)==-1) // Error we cannot retrieve this qcode
878  return false;
879  else
880  $this->f_id_dest=$tiers->id;
881  }
882  $contact=new Fiche($this->db);
883  if ($contact->get_by_qcode($this->ag_contact)==-1)
884  $contact->id=0;
885 
886  // reload the old one
887  $old=new Follow_Up($this->db);
888  $old->ag_id=$this->ag_id;
889  $old->get();
890 
891  // If ag_ref changed then check if unique
892  if ($old->ag_ref!=$this->ag_ref)
893  {
894  $nAg_ref=$this->db->get_value("select count(*) from action_gestion where ag_ref=$1", array($this->ag_ref));
895  if ($nAg_ref!=0)
896  {
897  echo h2("Référence en double, référence non sauvée", 'class="error"');
898  $this->ag_ref=$old->ag_ref;
899  }
900  }
901 
902 
903  if ($this->ag_remind_date!=null)
904  {
905  $this->db->exec_sql("update action_gestion set ".
906  " ag_timestamp=to_date($1,'DD.MM.YYYY'),".
907  " ag_title=$2,".
908  " ag_type=$3, ".
909  " f_id_dest=$4, ".
910  "ag_state=$5,".
911  " ag_hour = $7 ,".
912  " ag_priority = $8 ,".
913  " ag_dest = $9 , ".
914  " ag_contact = $10, ".
915  " ag_ref = $11, ".
916  " ag_remind_date=to_date($12,'DD.MM.YYYY') ".
917  " where ag_id = $6", array(
918  $this->ag_timestamp, /* 1 */
919  $this->ag_title, /* 2 */
920  $this->dt_id, /* 3 */
921  $this->f_id_dest, /* 4 */
922  $this->ag_state, /* 5 */
923  $this->ag_id, /* 6 */
924  $this->ag_hour, /* 7 */
925  $this->ag_priority, /* 8 */
926  $this->ag_dest, /* 9 */
927  $contact->id, /* 10 */
928  $this->ag_ref, /* 11 */
929  $this->ag_remind_date /* 12 */
930  ));
931  }
932  else
933  {
934  $this->db->exec_sql("update action_gestion set ".
935  " ag_timestamp=to_date($1,'DD.MM.YYYY'),".
936  " ag_title=$2,".
937  " ag_type=$3, ".
938  " f_id_dest=$4, ".
939  "ag_state=$5,".
940  " ag_hour = $7 ,".
941  " ag_priority = $8 ,".
942  " ag_dest = $9 , ".
943  " ag_contact = $10, ".
944  " ag_ref = $11, ".
945  " ag_remind_date=null ".
946  " where ag_id = $6", array(
947  $this->ag_timestamp, /* 1 */
948  $this->ag_title, /* 2 */
949  $this->dt_id, /* 3 */
950  $this->f_id_dest, /* 4 */
951  $this->ag_state, /* 5 */
952  $this->ag_id, /* 6 */
953  $this->ag_hour, /* 7 */
954  $this->ag_priority, /* 8 */
955  $this->ag_dest, /* 9 */
956  $contact->id, /* 10 */
957  $this->ag_ref /* 11 */
958  ));
959  }
960  // Upload documents
961  $doc=new Document($this->db);
962  $doc->Upload($this->ag_id);
963 
964  /* save action details */
965  for ($i=0; $i<$_POST['nb_item']; $i++)
966  {
967  $act=new Follow_Up_Detail($this->db);
968  $act->from_array($_POST, $i);
969  if ($act->f_id==0&&$act->ad_id!=0)
970  $act->delete();
971  if ($act->f_id==0)
972  continue;
973  $act->save();
974  }
975  if (trim($this->ag_comment)!='')
976  {
977  $this->db->exec_sql("insert into action_gestion_comment (ag_id,tech_user,agc_comment) values ($1,$2,$3)"
978  , array($this->ag_id, $_SESSION['g_user'], $this->ag_comment));
979  }
980  $this->insert_operation();
981  $this->insert_action();
982  return true;
983  }
984 
985  /**
986  * \brief generate the document and add it to the action
987  * \param md_id is the id of the document_modele
988  * \param $p_array contains normally the $_POST
989  */
990  function generate_document($md_id, $p_array)
991  {
992  $doc=new Document($this->db);
993  $mod=new Document_Modele($this->db, $md_id);
994  $mod->load();
995  $doc->f_id=$this->f_id_dest;
996  $doc->md_id=$md_id;
997  $doc->ag_id=$this->ag_id;
998  $doc->Generate($p_array,$this->ag_id);
999  }
1000 
1001  /**
1002  * \brief put an array in the variable member, the indice
1003  * is the member name
1004  * \param $p_array to parse
1005  * - ag_id id of the Follow_up
1006  * - ag_ref reference of the action
1007  * - qcode_dest quick_code of the card of dest
1008  * - f_id_dest f_id of the card of dest
1009  * - dt_id Document_Modele::dt_id
1010  * - ag_state document_state::s_id (default:2)
1011  * - ag_title title of the action
1012  * - ag_hour
1013  * - ag_dest Profile, profile of the user
1014  * - ag_comment comment
1015  * - ag_remind_date Remind Date
1016  * - operation related operation
1017  * - action related action
1018  * - op deprecated
1019  * \return nothing
1020  */
1022  {
1023  global $g_user;
1024  $this->ag_id=(isset($p_array['ag_id']))?$p_array['ag_id']:0;
1025  $this->ag_ref=(isset($p_array['ag_ref']))?$p_array['ag_ref']:"";
1026  $this->qcode_dest=(isset($p_array['qcode_dest']))?$p_array['qcode_dest']:"";
1027  $this->f_id_dest=(isset($p_array['f_id_dest']))?$p_array['f_id_dest']:null;
1028  $this->ag_timestamp=(isset($p_array['ag_timestamp']))?$p_array['ag_timestamp']:date('d.m.Y');
1029  $this->qcode_dest=(isset($p_array['qcode_dest']))?$p_array['qcode_dest']:"";
1030  $this->dt_id=(isset($p_array['dt_id']))?$p_array['dt_id']:"";
1031  $this->ag_state=(isset($p_array['ag_state']))?$p_array['ag_state']:2;
1032  $this->ag_ref=(isset($p_array['ag_ref']))?$p_array['ag_ref']:"";
1033  $this->ag_title=(isset($p_array['ag_title']))?$p_array['ag_title']:"";
1034  $this->ag_hour=(isset($p_array['ag_hour']))?$p_array['ag_hour']:"";
1035  $this->ag_dest=(isset($p_array['ag_dest']))?$p_array['ag_dest']:$g_user->get_profile();
1036  $this->ag_priority=(isset($p_array['ag_priority']))?$p_array['ag_priority']:2;
1037  $this->ag_contact=(isset($p_array['ag_contact']))?$p_array['ag_contact']:"";
1038  $this->ag_comment=(isset($p_array['ag_comment']))?$p_array['ag_comment']:"";
1039  $this->ag_remind_date=(isset($p_array['ag_remind_date']))?$p_array['ag_remind_date']:null;
1040  $this->operation=(isset($p_array['operation']))?$p_array['operation']:null;
1041  /**
1042  * @todo
1043  * deprecated : to remove
1044  $this->op = (isset($p_array['op'])) ? $p_array['op'] : null;
1045  */
1046  $this->action=(isset($p_array['action']))?$p_array['action']:null;
1047  }
1048 
1049  /**
1050  * \brief remove the action
1051  *
1052  */
1053  function remove()
1054  {
1055  $this->get();
1056  // remove the key
1057  $sql="delete from action_gestion where ag_id=$1";
1058  $this->db->exec_sql($sql, array($this->ag_id));
1059 
1060  /* check the number of attached document */
1061  $doc=new Document($this->db);
1062  $aDoc=$doc->get_all($this->ag_id);
1063  if (!empty($aDoc))
1064  {
1065  // if there are documents
1066  for ($i=0; $i<sizeof($aDoc); $i++)
1067  {
1068  $aDoc[$i]->remove();
1069  }
1070  }
1071  }
1072 
1073  /**
1074  * \brief return the last p_limit operation into an array, there is a security
1075  * on user
1076  * \param $p_limit is the max of operation to return
1077  * \return $p_array of Follow_Up object
1078  */
1079  function get_last($p_limit)
1080  {
1081 
1082  $sql="select coalesce(vw_name,'Interne') as vw_name,ag_hour,quick_code,ag_id,ag_title,ag_ref, dt_value,to_char(ag_timestamp,'DD.MM.YYYY') as ag_timestamp_fmt,ag_timestamp ".
1083  " from action_gestion join document_type ".
1084  " on (ag_type=dt_id) "
1085  . "left join vw_fiche_attr on (f_id=f_id_dest) "
1086  . "where ag_state in (2,3) "
1087  . "and ".self::sql_security_filter($this->db,'R').
1088  "order by ag_timestamp desc limit $p_limit";
1089  $array=$this->db->get_array($sql);
1090  return $array;
1091  }
1092 
1093  /**
1094  * get the action where the remind day is today
1095  * @return array
1096  */
1097  function get_today()
1098  {
1099  $sql="select ag_ref,ag_hour,coalesce(vw_name,'Interne') as vw_name,ag_id,ag_title,ag_ref, dt_value,to_char(ag_remind_date,'DD.MM.YYYY') as ag_timestamp_fmt,ag_timestamp ".
1100  " from action_gestion join document_type ".
1101  " on (ag_type=dt_id)
1102  left join vw_fiche_attr on (f_id=f_id_dest)
1103  where
1104  ag_state not in (1,4)
1105  and to_char(ag_remind_date,'DDMMYYYY')=to_char(now(),'DDMMYYYY')
1106  and ". self::sql_security_filter($this->db,'R');
1107  $array=$this->db->get_array($sql);
1108  return $array;
1109  }
1110 
1111  /**
1112  * get the action where the remind day is today
1113  * @return array
1114  */
1115  function get_late()
1116  {
1117  $sql="select ag_ref,ag_hour,coalesce(vw_name,'Interne') as vw_name,ag_id,ag_title,ag_ref, dt_value,to_char(ag_remind_date,'DD.MM.YYYY') as ag_timestamp_fmt,ag_timestamp ".
1118  " from action_gestion join document_type ".
1119  " on (ag_type=dt_id) left join vw_fiche_attr on (f_id=f_id_dest) where ag_state not in (1,4)
1120  and ag_remind_date < now() and ".self::sql_security_filter($this->db,'R');
1121  $array=$this->db->get_array($sql);
1122  return $array;
1123  }
1124 
1125  /**
1126  * insert a related operation
1127  */
1128  function insert_operation()
1129  {
1130  if (trim($this->operation)=='')
1131  return;
1132  $array=explode(",", $this->operation);
1133  for ($i=0; $i<count($array); $i++)
1134  {
1135  if ($this->db->get_value("select count(*) from action_gestion_operation
1136  where ag_id=$1 and jr_id=$2", array($this->ag_id, $array[$i]))==0)
1137  {
1138  $this->db->exec_sql("insert into action_gestion_operation (ag_id,jr_id) values ($1,$2)", array($this->ag_id, $array[$i]));
1139  }
1140  }
1141  }
1142 
1143  /**
1144  * remove a related operation
1145  * @deprecated not used : dead_code
1146  * @todo to remove
1147  */
1149  {
1150  if ($this->op==null)
1151  return;
1152  $op=$this->op;
1153  for ($i=0; $i<count($op); $i++)
1154  {
1155  $this->db->exec_sql("delete from action_gestion_operation where ago_id=$1", array($op[$i]));
1156  }
1157  }
1158 
1159  /**
1160  * Display only a search box for searching an action
1161  * @param $cn database connx
1162  * @param $inner true if coming from an ajax (ajax_search_action)
1163  */
1164  static function display_search($cn, $inner=false)
1165  {
1166  global $g_user;
1167  $a=(isset($_GET['action_query']))?$_GET['action_query']:"";
1168  $qcode=(isset($_GET['qcode']))?$_GET['qcode']:"";
1169 
1170  $supl_hidden='';
1171  if (isset($_REQUEST['sc']))
1173  if (isset($_REQUEST['f_id']))
1174  {
1175  $supl_hidden.=HtmlInput::hidden('f_id', $_REQUEST['f_id']);
1176  $f=new Fiche($cn, $_REQUEST['f_id']);
1177  $supl_hidden.=HtmlInput::hidden('qcode_dest', $f->get_quick_code());
1178  }
1179  if (isset($_REQUEST['sb']))
1182 
1183  /**
1184  * Show the default button (add action, show search...)
1185  */
1186  if (!$inner)
1187  require_once NOALYSS_TEMPLATE.'/action_button.php';
1188 
1189  $w=new ICard();
1190  if ( $inner ) $w->autocomplete=0;
1191  $w->name='qcode';
1192  $w->id=$w->generate_id($w->name);
1193  $w->value=$qcode;
1194  $w->extra="all";
1195  $w->typecard='all';
1196  $w->jrn=0;
1197  $w->table=0;
1198  $list=$cn->make_list("select fd_id from fiche_def where frd_id in (4,8,9,14,15,16,25)");
1199  $w->extra=$list;
1200 
1201 
1202  /* type of documents */
1203  $type_doc=new ISelect('tdoc');
1204  $aTDoc=$cn->make_array('select dt_id,dt_value from document_type order by dt_value');
1205  $aTDoc[]=array('value'=>'-1', 'label'=>_('Tous les types'));
1206  $type_doc->value=$aTDoc;
1207  $type_doc->selected=(isset($_GET['tdoc']))?$_GET['tdoc']:-1;
1208 
1209  /* State of documents */
1210  $type_state=new ISelect('state');
1211  $aState=$cn->make_array('select s_id,s_value from document_state order by s_value');
1212  $aState[]=array('value'=>'-1', 'label'=>_('Tous les Etats'));
1213  $type_state->value=$aState;
1214  $type_state->selected=(isset($_GET['state']))?$_GET['state']:-1;
1215 
1216 
1217 
1218  /* Except State of documents */
1219  $hsExcptype_state=new ISelect('hsstate');
1220  $aExcpState=$cn->make_array('select s_id,s_value from document_state order by s_value');
1221  $aExcpState[]=array('value'=>'-1', 'label'=>_('Aucun'));
1222  $hsExcptype_state->value=$aExcpState;
1223  $hsExcptype_state->selected=(isset($_GET['hsstate']))?$_GET['hsstate']:-1;
1224 
1225 
1226  // date
1227  $start=new IDate('date_start');
1228  $start->value=(isset($_GET['date_start']))?$_GET['date_start']:"";
1229  $end=new IDate('date_end');
1230  $end->value=(isset($_GET['date_end']))?$_GET['date_end']:"";
1231 
1232  // Closed action
1233  $closed_action=new ICheckBox('closed_action');
1234  $closed_action->selected=(isset($_GET['closed_action']))?true:false;
1235 
1236  // Internal
1237  $only_internal=new ICheckBox('only_internal');
1238  $only_internal->selected=(isset($_GET['only_internal']))?true:false;
1239  // select profile
1240  $aAg_dest=$cn->make_array("select p_id as value, ".
1241  "p_name as label ".
1242  " from profile where p_id in ".
1243  $g_user->get_readable_profile().
1244  "order by 2");
1245  $aAg_dest[]=array('value'=>'-2', 'label'=>_('Tous les profiles'));
1246  $ag_dest=new ISelect();
1247  $ag_dest->name="ag_dest_query";
1248  $ag_dest->value=$aAg_dest;
1249  $ag_dest->selected=(isset($_GET["ag_dest_query"]))?$_GET["ag_dest_query"]:-2;
1250  $str_ag_dest=$ag_dest->input();
1251  $osag_ref=new IText("sag_ref");
1252  $osag_ref->value=(isset($_GET['sag_ref']))?$_GET['sag_ref']:"";
1253  $remind_date=new IDate('remind_date');
1254  $remind_date->value=(isset($_GET['remind_date']))?$_GET['remind_date']:"";
1255  $remind_date_end=new IDate('remind_date_end');
1256  $remind_date_end->value=(isset($_GET['remind_date_end']))?$_GET['remind_date_end']:"";
1257  $otag=new Tag($cn);
1258 
1259  // show the action in
1260  require_once NOALYSS_TEMPLATE.'/action_search.php';
1261  }
1262 
1263  /**
1264  * @brief show a list of documents
1265  * @param $cn database connextion
1266  * @param $p_base base URL
1267  */
1268  static function show_action_list($cn, $p_base)
1269  {
1270 
1272 
1273  $act=new Follow_Up($cn);
1274  /** \brief
1275  * \note The field 'recherche' is about a part of the title or a ref. number
1276  */
1278 
1279  echo '<form method="POST" id="list_ag_frm" style="display:inline">';
1280  echo HtmlInput::request_to_hidden(array("gDossier", "ac", "sb", "sc", "f_id"));
1281  require_once NOALYSS_TEMPLATE.'/action_other_action.php';
1282  echo $act->myList($p_base, "", $query);
1283  echo '</form>';
1284  }
1285 
1286  /**
1287  * Create a subquery to filter thanks the selected tag
1288  * @param $cn db connx
1289  * @param $p_array
1290  * @return SQL
1291  */
1292  static function filter_by_tag($cn, $p_array=null)
1293  {
1294  if ($p_array==null)
1295  $p_array=$_GET;
1296 
1297  extract($p_array, EXTR_SKIP);
1298  $query="";
1299  if (count($searchtag)==0)
1300  return "";
1301  for ($i=0; $i<count($searchtag); $i++)
1302  {
1303  if (isNumber($searchtag[$i])==1)
1304  $query .= ' and ag_id in (select ag_id from action_tags where t_id= '.sql_string($searchtag[$i]).')';
1305  }
1306  return $query;
1307  }
1308 
1309  /**
1310  * Get date from $_GET and create the sql stmt for the query
1311  * @note the query is taken in $_REQUEST
1312  * @see Follow_Up::ShowActionList
1313  * @return string SQL condition
1314  */
1315  static function create_query($cn, $p_array=null)
1316  {
1317  if ($p_array==null)
1318  $p_array=$_GET;
1319 
1320  extract($p_array, EXTR_SKIP);
1321  $action_query="";
1322 
1323 
1324  if (isset($_REQUEST['action_query']))
1325  {
1326  // if a query is request build the sql stmt
1327  $action_query="and (ag_title ~* '".sql_string($_REQUEST['action_query'])."' ".
1328  "or ag_ref ='".trim(sql_string($_REQUEST['action_query'])).
1329  "' or ag_id in (select ag_id from action_gestion_comment where agc_comment ~* '".trim(sql_string($_REQUEST['action_query']))."')".
1330  ")";
1331  }
1332 
1333  $str="";
1334  if (isset($qcode))
1335  {
1336  // verify that qcode is not empty
1337  if (strlen(trim($qcode))!=0)
1338  {
1339 
1340  $fiche=new Fiche($cn);
1341  $fiche->get_by_qcode($_REQUEST['qcode']);
1342  // if quick code not found then nothing
1343  if ($fiche->id==0)
1344  $str=' and false ';
1345  else
1346  $str=" and (f_id_dest= ".$fiche->id." or ag_id in (select ag_id from action_person as ap where ap.f_id=".$fiche->id.") )";
1347  }
1348  }
1349  if (isset($tdoc)&&$tdoc!=-1)
1350  {
1351  $action_query .= ' and dt_id = '.sql_string($tdoc);
1352  }
1353  if (isset($state)&&$state!=-1)
1354  {
1355  $action_query .= ' and ag_state= '.sql_string($state);
1356  }
1357  if (isset($hsstate)&&$hsstate!=-1)
1358  {
1359  $action_query .= ' and ag_state <> '.sql_string($hsstate);
1360  }
1361  if (isset($sag_ref)&&trim($sag_ref)!="")
1362  {
1363  $query .= ' and ag_ref= \''.sql_string($sag_ref)."'";
1364  }
1365 
1366  if (isset($_GET['only_internal']))
1367  $action_query .= ' and f_id_dest=0 ';
1368 
1369  if (isset($date_start)&&isDate($date_start)!=null)
1370  {
1371  $action_query.=" and ag_timestamp >= to_date('$date_start','DD.MM.YYYY')";
1372  }
1373  if (isset($date_end)&&isDate($date_end)!=null)
1374  {
1375  $action_query.=" and ag_timestamp <= to_date('$date_end','DD.MM.YYYY')";
1376  }
1377  if (isset($ag_dest_query)&&$ag_dest_query!=-2)
1378  {
1379  $action_query.= " and ((ag_dest = ".sql_string($ag_dest_query)." and ".self::sql_security_filter($cn, "R").") or ".
1380  "(ag_dest = ".sql_string($ag_dest_query)." and ".self::sql_security_filter($cn, "R")." and ".
1381  " ag_owner='".$_SESSION['g_user']."'))";
1382  }
1383  else
1384  {
1385  $action_query .=" and (ag_owner='".$_SESSION['g_user']."' or ".self::sql_security_filter($cn, "R")." or ag_dest=-1 )";
1386  }
1387 
1388 
1389  if (isNumber($ag_id)==1&&$ag_id!=0)
1390  {
1391  $action_query=" and ag_id= ".sql_string($ag_id);
1392  }
1393  if (isset($remind_date)&&$remind_date!=""&&isDate($remind_date)==$remind_date)
1394  {
1395  $action_query .= " and to_date('".sql_string($remind_date)."','DD.MM.YYYY')<= ag_remind_date";
1396  }
1397  if (isset($remind_date_end)&&$remind_date_end!=""&&isDate($remind_date_end)==$remind_date_end)
1398  {
1399  $action_query .= " and to_date('".sql_string($remind_date_end)."','DD.MM.YYYY')>= ag_remind_date";
1400  }
1401  if (!isset($closed_action))
1402  {
1403  $action_query.=" and s_status is null ";
1404  }
1405  if (isset($searchtag))
1406  {
1407  $action_query .= Follow_Up::filter_by_tag($cn, $p_array);
1408  }
1409  return $action_query.$str;
1410  }
1411 
1412  /**
1413  * Show the result of a search in an inner windows, the result is limited to 25
1414  * @param type $cn database connx
1415  * @param type $p_sql the query
1416  */
1417  static function short_list($cn, $p_sql)
1418  {
1419  $sql="
1420  select ag_id,to_char(ag_timestamp,'DD.MM.YY') as my_date,
1421  f_id_dest,
1422  substr(ag_title,1,40) as sub_ag_title,dt_value,ag_ref, ag_priority,ag_state,
1423  coalesce((select p_name from profile where p_id=ag_dest),'Aucun groupe') as dest,
1424  (select ad_value from fiche_Detail where f_id=action_gestion.f_id_dest and ad_id=1) as name
1425  from action_gestion
1426  join document_type on (ag_type=dt_id)
1427  join document_state on (s_id=ag_state)
1428  where $p_sql";
1429  $max_line=$cn->count_sql($sql);
1430 
1431  $limit=($max_line>25)?25:$max_line;
1432  $Res=$cn->exec_sql($sql."limit ".$limit);
1433  $a_row=Database::fetch_all($Res);
1434  require_once NOALYSS_TEMPLATE.'/action_search_result.php';
1435  }
1436 
1437  /**
1438  * Insert a related action into the table action_gestion_related
1439  */
1440  function insert_action()
1441  {
1442  if (trim($this->action)=='')
1443  return;
1444  $array=explode(",", $this->action);
1445  for ($i=0; $i<count($array); $i++)
1446  {
1447  // Do not insert an option child of himself
1448  if ( $this->ag_id == $array[$i]) {
1449  continue;
1450  }
1451 
1452  if ($this->db->get_value("select count(*) from action_gestion_related
1453  where (aga_least=$1 and aga_greatest=$2) or (aga_greatest=$1 and aga_least=$2)", array($array[$i], $this->ag_id))==0)
1454  {
1455  $this->db->exec_sql("insert into action_gestion_related(aga_least,aga_greatest) values ($1,$2)", array($this->ag_id, $array[$i]));
1456  }
1457  }
1458  }
1459 
1460  /**
1461  * export to CSV the query the p_array has
1462  * @param array $p_array
1463  */
1465  {
1466  extract($p_array, EXTR_SKIP);
1467 
1468 
1469  $p_search=self::create_query($this->db, $p_array);
1470  $sql="
1471  select ag_id,
1472  to_char(ag_timestamp,'DD.MM.YYYY') as my_date,
1473  to_char(ag_remind_date,'DD.MM.YYYY') as my_remind,
1474  to_char(coalesce((select max(agc_date) from action_gestion_comment as agc where agc.ag_id=ag_id),ag_timestamp),'DD.MM.YY') as last_comment,
1475  array_to_string((select array_agg(t1.t_tag) from action_tags as a1 join tags as t1 on (a1.t_id=t1.t_id) where a1.ag_id=ag.ag_id ),',') as tags,
1476  (select ad_value from fiche_Detail where f_id=ag.f_id_dest and ad_id=1) as name,
1477  ag_title,
1478  dt_value,
1479  ag_ref,
1480  ag_priority,
1481  ag_state,
1482 
1483  coalesce((select p_name from profile where p_id=ag_dest),'Aucun groupe') as dest
1484  from action_gestion as ag
1485  join document_type on (ag.ag_type=dt_id)
1486  join document_state on(ag.ag_state=s_id)
1487  where true $p_search order by ag.ag_timestamp,ag.ag_id";
1488  $ret=$this->db->exec_sql($sql);
1489 
1490  if (Database::num_row($ret)==0)
1491  return;
1492  $this->db->query_to_csv($ret, array(
1493  array("title"=>"doc id", "type"=>"string"),
1494  array("title"=>"date", "type"=>"date"),
1495  array("title"=>"rappel", "type"=>"date"),
1496  array("title"=>"date dernier commentaire", "type"=>"date"),
1497  array("title"=>"tags", "type"=>"string"),
1498  array("title"=>"nom", "type"=>"string"),
1499  array("title"=>"titre", "type"=>"string"),
1500  array("title"=>"type document", "type"=>"string"),
1501  array("title"=>"ref", "type"=>"string"),
1502  array("title"=>"priorite", "type"=>"string"),
1503  array("title"=>"etat", "type"=>"string"),
1504  array("title"=>"profil", "type"=>"string")
1505  )
1506  );
1507  }
1508 
1509  static function get_all_operation($p_jr_id)
1510  {
1511  global $cn;
1512  $array=$cn->get_array("
1513  select ag_id,ag_ref,ago_id,
1514  ag_title
1515  from action_gestion
1516  join action_gestion_operation using(ag_id)
1517  where
1518  jr_id=$1", array($p_jr_id));
1519  return $array;
1520  }
1521 
1522  /**
1523  * @brief get the tags of the current objet
1524  * @return an array idx [ag_id,t_id,at_id,t_tag]
1525  */
1526  function tag_get()
1527  {
1528  if ($this->ag_id==0)
1529  return;
1530  $sql='select b.ag_id,b.t_id,b.at_id,a.t_tag'
1531  .' from '
1532  .' tags as a join action_tags as b on (a.t_id=b.t_id)'
1533  .' where ag_id=$1 '
1534  .' order by a.t_tag';
1535  $array=$this->db->get_array($sql, array($this->ag_id));
1536  return $array;
1537  }
1538 
1539  /**
1540  * @brief show the tags of the current objet
1541  * normally used by ajax. The same tag cannot be added twice
1542  *
1543  */
1544  function tag_add($p_t_id)
1545  {
1546  if ($this->ag_id==0)
1547  return;
1548  $count=$this->db->get_value('select count(*) from action_tags'.
1549  ' where ag_id=$1 and t_id=$2', array($this->ag_id, $p_t_id));
1550  if ($count>0)
1551  return;
1552  $sql=' insert into action_tags (ag_id,t_id) values ($1,$2)';
1553  $this->db->exec_sql($sql, array($this->ag_id, $p_t_id));
1554  }
1555 
1556  /**
1557  * @brief remove the tags of the current objet
1558  * normally used by ajax
1559  */
1560  function tag_remove($p_t_id)
1561  {
1562  if ($this->ag_id==0)
1563  return;
1564  $sql=' delete from action_tags where ag_id=$1 and t_id=$2';
1565  $this->db->exec_sql($sql, array($this->ag_id, $p_t_id));
1566  }
1567 
1568  /**
1569  * @brief show the cell content in Display for the tags
1570  * called also by ajax
1571  */
1572  function tag_cell()
1573  {
1574  global $g_user;
1575  $a_tag=$this->tag_get();
1576  $c=count($a_tag);
1577  for ($e=0; $e<$c; $e++)
1578  {
1579  echo '<span style="border:1px solid black;margin-right:5px;">';
1580  echo $a_tag[$e]['t_tag'];
1581  if ($g_user->can_write_action($this->ag_id)==true)
1582  {
1583  $js_remove=sprintf("onclick=\"action_tag_remove('%s','%s','%s')\"", dossier::id(), $this->ag_id, $a_tag[$e]['t_id']);
1584  echo HtmlInput::anchor(SMALLX, "javascript:void(0)", $js_remove, ' class="smallbutton" style="padding:0px;display:inline" ');
1585  }
1586  echo '</span>';
1587  echo '&nbsp;';
1588  echo '&nbsp;';
1589  }
1590  $js=sprintf("onclick=\"action_tag_select('%s','%s')\"", dossier::id(), $this->ag_id);
1591  if ($g_user->can_write_action($this->ag_id)==true)
1592  {
1593  echo HtmlInput::button('tag_bt', 'Ajout tag', $js, 'smallbutton');
1594  }
1595  }
1596 
1597  static function action_tag_remove($cn, $p_array)
1598  {
1599  global $g_user;
1600  $mag_id=$p_array['mag_id'];
1601  $remtag=$p_array['remtag'];
1602  for ($i=0; $i<count($mag_id); $i++)
1603  {
1604  if ($g_user->can_write_action($mag_id[$i])==false)
1605  continue;
1606  for ($e=0; $e<count($remtag); $e++)
1607  {
1608  $a=new Follow_Up($cn, $mag_id[$i]);
1609  $a->tag_remove($remtag[$e]);
1610  }
1611  }
1612  }
1613 
1614  static function action_tag_add($cn, $p_array)
1615  {
1616  global $g_user;
1617  $mag_id=$p_array['mag_id'];
1618  $addtag=$p_array['addtag'];
1619  for ($i=0; $i<count($mag_id); $i++)
1620  {
1621  if ($g_user->can_write_action($mag_id[$i])==false)
1622  continue;
1623  for ($e=0; $e<count($addtag); $e++)
1624  {
1625  $a=new Follow_Up($cn, $mag_id[$i]);
1626  $a->tag_add($addtag[$e]);
1627  }
1628  }
1629  }
1630 
1631  static function action_tag_clear($cn, $p_array)
1632  {
1633  global $g_user;
1634  $mag_id=$p_array['mag_id'];
1635  for ($i=0; $i<count($mag_id); $i++)
1636  {
1637  if ($g_user->can_write_action($mag_id[$i])==false)
1638  continue;
1639  $a=new Follow_Up($cn, $mag_id[$i]);
1640  $a->tag_clear();
1641  }
1642  }
1643 
1644  static function action_print($cn, $p_array)
1645  {
1646  global $g_user;
1647  $mag_id=$p_array['mag_id'];
1648  for ($i=0; $i<count($mag_id); $i++)
1649  {
1650  if ($g_user->can_read_action($mag_id[$i])==false)
1651  continue;
1652  $a=new Follow_Up($cn, $mag_id[$i]);
1653  $a->get();
1654  echo '<div class="content">';
1655  echo $a->Display("READ", false, "");
1656  echo '</div>';
1657  echo '<P id="breakhere"> - - </p>';
1658  }
1659  }
1660 
1661  function tag_clear()
1662  {
1663  $this->db->exec_sql('delete from action_tags where ag_id=$1', array($this->ag_id));
1664  }
1665 
1666  static function action_set_state($cn, $p_array)
1667  {
1668 
1669  global $g_user;
1670  $mag_id=$p_array['mag_id'];
1671  $state=$p_array['ag_state'];
1672  for ($i=0; $i<count($mag_id); $i++)
1673  {
1674  if ($g_user->can_write_action($mag_id[$i])==false)
1675  continue;
1676  $cn->exec_sql('update action_gestion set ag_state=$1 where ag_id=$2', array($state, $mag_id[$i]));
1677  }
1678  }
1679 
1680  static function action_remove($cn, $p_array)
1681  {
1682  global $g_user;
1683 
1684  $mag_id=$p_array['mag_id'];
1685  for ($i=0; $i<count($mag_id); $i++)
1686  {
1687  if ($g_user->can_write_action($mag_id[$i])==false)
1688  continue;
1689  $cn->exec_sql('delete from action_gestion where ag_id=$1', array($mag_id[$i]));
1690  }
1691  }
1692 
1693  /**
1694  * Verify that data are correct
1695  * @throws Exception
1696  */
1697  function verify()
1698  {
1699  if ($this->dt_id==-1)
1700  {
1701  throw new Exception(_('Type action invalide'), 10);
1702  }
1703  if (isDate($this->ag_timestamp)!=$this->ag_timestamp)
1704  throw new Exception(_('Date invalide'), 20);
1705  if (isDate($this->ag_remind_date)!=$this->ag_remind_date)
1706  throw new Exception(_('Date invalide'), 30);
1707  if ($this->f_id_dest==0)
1708  $this->f_id_dest=null;
1709  }
1710 
1711  /**
1712  * Add another concerned (tiers, supplier...)
1713  * @remark type $g_user
1714  * @param type $p_fiche_id
1715  */
1716  function insert_linked_card($p_fiche_id)
1717  {
1718  global $g_user;
1719  if ($g_user->can_write_action($this->ag_id))
1720  {
1721  /**
1722  * insert into action_person
1723  */
1724  $count=$this->db->get_value('select count(*) from action_person where f_id=$1 and ag_id=$2', array($p_fiche_id, $this->ag_id));
1725  if ($count==0)
1726  {
1727  $this->db->exec_sql('insert into action_person (ag_id,f_id) values ($1,$2)', array($this->ag_id, $p_fiche_id));
1728  }
1729  }
1730  }
1731 
1732  /**
1733  * Remove another concerned (tiers, supplier...)
1734  * @remark type $g_user
1735  * @param type $p_fiche_id
1736  */
1737  function remove_linked_card($p_fiche_id)
1738  {
1739  global $g_user;
1740  if ($g_user->can_write_action($this->ag_id))
1741  {
1742  $this->db->exec_sql('delete from action_person where ag_id = $1 and f_id = $2', array($this->ag_id, $p_fiche_id));
1743  }
1744  }
1745 
1746  /**
1747  * Display the other concerned (tiers, supplier...)
1748  * @return string
1749  */
1750  function display_linked()
1751  {
1752  $a_linked=$this->db->get_array('select ap_id,f_id from action_person where ag_id=$1', array($this->ag_id));
1753  if (count($a_linked)==0)
1754  return "";
1755  for ($i=0; $i<count($a_linked); $i++)
1756  {
1757  $fiche=new Fiche($this->db, $a_linked[$i]['f_id']);
1758  $qc=$fiche->get_quick_code();
1759  $js_remove=sprintf("onclick=\"action_remove_concerned('%s','%s','%s')\"", dossier::id(), $a_linked[$i]['f_id'], $this->ag_id);
1760  echo '<span style="border:1px solid black;margin-right:5px;">';
1761  echo $qc;
1762  echo HtmlInput::anchor(SMALLX, "javascript:void(0)", $js_remove, ' class="smallbutton" style="padding:0px;display:inline" ');
1763  echo '</span>';
1764  echo '&nbsp;';
1765  echo '&nbsp;';
1766  }
1767  }
1768  /**
1769  * @brief display a small form to enter a new event
1770  *
1771  */
1772  function display_short()
1773  {
1774  $cn=$this->db;
1775  include NOALYSS_TEMPLATE.'/action_display_short.php';
1776  }
1777  /**
1778  * Add an event , with the minimum of informations,
1779  * used in Dashboard and Scheduler
1780  */
1781  function save_short()
1782  {
1783  global $g_user;
1784  // check if we can add
1785  if ($g_user->can_add_action($this->ag_dest) == FALSE )
1786  {
1787  throw new Exception(_('SECURITE : Ajout impossible'));
1788  }
1789 
1790 
1791 
1792  // Get The sequence id,
1793  $seq_name="seq_doc_type_".$this->dt_id;
1794  $str_file="";
1795  $add_file='';
1796 
1797 
1798  $this->ag_id=$this->db->get_next_seq('action_gestion_ag_id_seq');
1799 
1800  // Create the reference
1801  $ag_ref=$this->db->get_value('select dt_prefix from document_type '
1802  . 'where dt_id=$1', array($this->dt_id))
1803  .'-'.$this->db->get_next_seq($seq_name);
1804 
1805  $this->ag_ref=$ag_ref;
1806  /**
1807  * If ag_ref already exist then compute a new one
1808  */
1809 
1810  // save into the database
1811  $sql="insert into action_gestion".
1812  "(ag_id,ag_timestamp,ag_type,ag_title,f_id_dest,ag_ref, "
1813  . "ag_dest, ".
1814  " ag_priority,ag_owner,ag_state,ag_remind_date,ag_hour) ".
1815  " values "
1816  . "($1,to_date($2,'DD.MM.YYYY'),$3,$4,$5,$6,"
1817  . "$7,"
1818  . "$8,$9,$10,to_date($11,'DD.MM.YYYY'),$12)";
1819 
1820  $this->db->exec_sql($sql, array(
1821  $this->ag_id, /* 1 */
1822  $this->ag_timestamp, /* 2 */
1823  $this->dt_id, /* 3 */
1824  $this->ag_title, /* 4 */
1825  $this->f_id_dest, /* 5 */
1826  $ag_ref, /* 6 */
1827  $this->ag_dest, /* 7 */
1828  $this->ag_priority, /* 8 */
1829  $_SESSION['g_user'], /* 9 */
1830  $this->ag_state, /* 10 */
1831  $this->ag_remind_date, /* 11 */
1832  $this->ag_hour /* 12 */
1833  )
1834  );
1835 
1836  if (trim($this->ag_comment)!='')
1837  {
1838  $this->db->exec_sql("insert into action_gestion_comment (ag_id,tech_user,agc_comment) values ($1,$2,$3)"
1839  , array($this->ag_id, $_SESSION['g_user'], $this->ag_comment));
1840  }
1841  }
1842  /**
1843  * Return the first parent of the event tree, or -1 if not found
1844  * @return integer (ag_id)
1845  */
1846  function get_parent() {
1847  $value=$this->db->get_array('
1848  with recursive t (aga_least,aga_greatest,depth) as (
1849  select aga_least,aga_greatest , 1
1850  from
1851  action_gestion_related
1852  where aga_greatest=$1
1853  union all
1854  select p2.aga_least,p2.aga_greatest,depth + 1
1855  from
1856  t as p1, action_gestion_related as p2
1857  where
1858  p2.aga_greatest is not null and
1859  p2.aga_greatest = p1.aga_least
1860  ) select * from t order by depth desc limit 1
1861  ' , array($this->ag_id)
1862  );
1863  if ( ! empty($value ) )
1864  return $value[0]['aga_least'];
1865  else
1866  return -1;
1867  }
1868  /**
1869  * Compute an array of the complete tree depending of $p_id
1870  * @param $p_id ag_id
1871  * @return array
1872  * key index :
1873  * - uniq value , path
1874  * - aga_least
1875  * - aga_greatest
1876  * - depth
1877  */
1878  function get_children($p_id) {
1879  // retrieve parent
1880  // Get information
1881  $sql = "with recursive t (key_path, aga_least,aga_greatest,depth) as (
1882  select
1883  aga_least::text||'-'||aga_greatest::text as key_path ,
1884  aga_least,aga_greatest , 1
1885  from
1886  action_gestion_related
1887  where aga_least=$1
1888  union all
1889  select key_path||'-'||p2.aga_greatest::text,
1890  p2.aga_least,p2.aga_greatest,depth + 1
1891  from
1892  t as p1, action_gestion_related as p2
1893  where
1894  p1.aga_greatest is not null and
1895  p1.aga_greatest = p2.aga_least
1896  )
1897  select key_path,aga_greatest,ag_title as title,depth ,to_char(ag_timestamp,'DD/MM/YY') as str_date,ag_ref||' '||dt_value as action_ref
1898  from
1899  action_gestion join t on (ag_id=aga_greatest)
1900  join document_type on (ag_type=dt_id)
1901  order by key_path
1902 
1903 ";
1904  $ret_array=$this->db->get_array($sql,array($p_id));
1905  // Empty returns
1906  if ( empty($ret_array)) return array();
1907 
1908 
1909  return $ret_array;
1910  }
1911 
1912  /**
1913  * Display the tree of childrens of the current Action + related parents
1914  * @return return the tree of children in a unordered list , HTML string
1915  */
1916  function display_children($p_view, $p_base)
1917  {
1918  /**
1919  * First we retrieve the parent
1920  */
1921  $parent=$this->get_parent();
1922 
1923  $base=HtmlInput::request_to_string(array("gDossier", "ac", "sa", "sb", "sc",
1924  "f_id"));
1925  $parent=$this->get_parent();
1926  if ($parent==-1)
1927  {
1928  echo _('Principal');
1930  }
1931  else
1932  {
1933  $fu_parent=new Follow_Up($this->db, $parent);
1934  $fu_parent->get();
1935  echo'<span class="highlight">';
1936  $xaction=sprintf('view_action(%d,%d,%d)', $fu_parent->ag_id,
1937  Dossier::id(), 1);
1938  $showAction='<a class="line" href="javascript:'.$xaction.'">';
1939  echo $showAction.
1940  $fu_parent->ag_timestamp," ",
1941  h($fu_parent->ag_title),
1942  '('.h($fu_parent->ag_ref).')',
1943  '</a>';
1944 
1945  echo "</span>";
1946  }
1947  echo '<ul style="padding-left:10px;list-style-type: none;">';
1948  $action=$this->get_children($parent);
1949  for ($o=0; $o<count($action); $o++)
1950  {
1951  $class=($this->ag_id == $action[$o]['aga_greatest'])?' class="highlight" ':'';
1952 
1953  // Count the number of direct parents
1954  $count_parent =$this->db->get_value('select count(*) from action_gestion_related where aga_greatest = $1',array($action[$o]['aga_greatest']));
1955  $direct_parent=($count_parent > 1 ) ? _('direct parent ').$count_parent:"";
1956 
1957  $margin=($action[$o]['depth']>1 )?str_repeat("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",$action[$o]['depth']-1)."&#8680;":"";
1958  if ($p_view!='READ'&&$p_base!='ajax')
1959  {
1960  $rmAction=sprintf("return confirm_box(null,'"._('Voulez-vous effacer cette action ')."', function () {remove_action('%s','%s','%s');});",
1961  dossier::id(), $action[$o]['aga_greatest'],
1962  $_REQUEST['ag_id']);
1963  $showAction='<a class="line" href="'.$base."&ag_id=".$action[$o]['aga_greatest'].'">';
1964  $js='<a class="tinybutton" id="acact'.$action[$o]['aga_greatest'].'" href="javascript:void(0)" onclick="'.$rmAction.'">'.SMALLX.'</a>';
1965  echo '<li '.$class.' id="act'.$action[$o]['aga_greatest'].'">'.$margin.$showAction.$action[$o]['str_date'].
1966  h($action[$o]['title']).'('.h($action[$o]['action_ref']).')'.$direct_parent.'</a>'." "
1967  .$js.'</li>';
1968  }
1969  else
1970  /*
1971  * Display detail requested from Ajax Div
1972  */
1973  if ($p_base=='ajax')
1974  {
1975  $xaction=sprintf('view_action(%d,%d,%d)', $action[$o]['aga_greatest'],
1976  Dossier::id(), 1);
1977  $showAction='<a class="line" href="javascript:'.$xaction.'">';
1978  echo '<li '.$class.' >'.$margin.$showAction.$action[$o]['str_date']." ".
1979  h($action[$o]['title']).'('.h($action[$o]['action_ref']).')'.$direct_parent.'</a>'." "
1980  .'</li>';
1981  }
1982  /*
1983  * READ ONLY
1984  */
1985  else
1986  {
1987  $showAction='<a class="line" href="'.$base."&ag_id=".$action[$o]['aga_greatest'].'">';
1988  echo '<li '.$class.' >'.$margin.$showAction.$action[$o]['str_date']." ".
1989  h($action[$o]['sub_title']).'('.h($action[$o]['action_ref']).')'.$direct_parent.'</a>'." "
1990  .'</li>';
1991  }
1992  }
1993  echo '</ul>';
1994  }
1995  /**
1996  * Display the list of parent of the current Follow_Up
1997  * \param $p_view form will be in readonly mode (value: READ, UPD or NEW )
1998  * \param $p_base is the ac parameter
1999  * \see Follow_Up::Display
2000  * \return None display the HTML list
2001  */
2002  function display_parent($p_view,$p_base)
2003  {
2004  $a_parent=$this->db->get_array(
2005  "
2006  select ag_id,ag_title as title ,to_char(ag_timestamp,'DD/MM/YY') as str_date,ag_ref||' '||dt_value as action_ref
2007  from
2008  action_gestion
2009  join document_type on (ag_type=dt_id)
2010  where ag_id in (select aga_least from action_gestion_related where aga_greatest = $1)
2011  order by ag_id
2012  ", array($this->ag_id)
2013  );
2014  if ( empty($a_parent ) ) return;
2015  echo '<ul style="padding-left:10px;list-style-type: none;">';
2016  $base=HtmlInput::request_to_string(array("gDossier", "ac", "sa", "sb", "sc",
2017  "f_id"));
2018  for ($o=0; $o<count($a_parent); $o++)
2019  {
2020  $class=($this->ag_id == $a_parent[$o]['ag_id'])?' class="highlight" ':'';
2021 
2022  if ($p_view!='READ'&&$p_base!='ajax')
2023  {
2024  $rmAction=sprintf("return confirm_box(null,'"._('Voulez-vous effacer cette action ')."', function () {remove_action('%s','%s','%s');});",
2025  dossier::id(), $a_parent[$o]['ag_id'],
2026  $_REQUEST['ag_id']);
2027  $showAction='<a class="line" href="'.$base."&ag_id=".$a_parent[$o]['ag_id'].'">';
2028  $js='<a class="tinybutton" id="acact'.$a_parent[$o]['ag_id'].'" href="javascript:void(0)" onclick="'.$rmAction.'">'.SMALLX.'</a>';
2029  echo '<li '.$class.' id="act'.$a_parent[$o]['ag_id'].'">'.$showAction.$a_parent[$o]['str_date'].
2030  h($a_parent[$o]['title']).'('.h($a_parent[$o]['action_ref']).')'.'</a>'." "
2031  .$js.'</li>';
2032  }
2033  else
2034  /*
2035  * Display detail requested from Ajax Div
2036  */
2037  if ($p_base=='ajax')
2038  {
2039  $xaction=sprintf('view_action(%d,%d,%d)', $a_parent[$o]['ag_id'],
2040  Dossier::id(), 1);
2041  $showAction='<a class="line" href="javascript:'.$xaction.'">';
2042  echo '<li '.$class.' >'.$showAction.$a_parent[$o]['str_date']." ".
2043  h($a_parent[$o]['title']).'('.h($a_parent[$o]['action_ref']).')'.'</a>'." "
2044  .'</li>';
2045  }
2046  /*
2047  * READ ONLY
2048  */
2049  else
2050  {
2051  $showAction='<a class="line" href="'.$base."&ag_id=".$a_parent[$o]['ag_id'].'">';
2052  echo '<li '.$class.' >'.$showAction.$a_parent[$o]['str_date']." ".
2053  h($a_parent[$o]['sub_title']).'('.h($a_parent[$o]['action_ref']).')'.'</a>'." "
2054  .'</li>';
2055  }
2056  }
2057  echo '</ul>';
2058  }
2059 
2060 }
$base
Definition: action.inc.php:55
get_by_qcode($p_qcode=null, $p_all=true)
Retrieve a card thx his quick_code complete the object,, set the id member of the object or set it to...
$_GET['qcode']
$_POST['ac']
Definition: do.php:279
$str
Definition: fiche.inc.php:97
get_last($p_limit)
return the last p_limit operation into an array, there is a security on user
static fetch_all($ret)
wrapper for the function pg_fetch_all
if($g_user->check_dossier(dossier::id(), true)=='X') $op
Definition: ajax_ledger.php:89
static get_all_operation($p_jr_id)
tag_add($p_t_id)
show the tags of the current objet normally used by ajax.
static action_remove($cn, $p_array)
$supl_hidden
static anchor($p_text, $p_url="", $p_js="", $p_style='class="line" ')
Return a simple anchor with a url or a javascript if $p_js is not null then p_url will be javascript:...
sql_string($p_string)
Fix the problem with the quote char for the database.
Definition: ac_common.php:457
td($p_string='', $p_extra='')
surround the string with td
Definition: ac_common.php:83
static num_row($ret)
wrapper for the function pg_NumRows
Class Document corresponds to the table document.
get_today()
get the action where the remind day is today
static short_list($cn, $p_sql)
Show the result of a search in an inner windows, the result is limited to 25.
for($i=0;$i< count($aHeading);$i++) $sort
$class
const SMALLX
Definition: constant.php:87
h2($p_string, $p_class="", $raw="")
Definition: ac_common.php:68
$aAttachedFile[$i]['d_filename']
th($p_string, $p_extra='', $raw='')
Definition: ac_common.php:58
$operation
$operation string related operation
tag_remove($p_t_id)
remove the tags of the current objet normally used by ajax
Display($p_view, $p_gen, $p_base, $retour="")
Display the object, the tags for the FORM are in the caller.
insert_action()
Insert a related action into the table action_gestion_related.
static sql_security_filter($cn, $p_mode)
Create a filter based on the current user,.
display_children($p_view, $p_base)
Display the tree of childrens of the current Action + related parents.
format_date($p_date, $p_from_format= 'YYYY-MM-DD', $p_to_format='DD.MM.YYYY')
format the date, when taken from the database the format is MM-DD-YYYY
Definition: ac_common.php:767
let you choose a TVA in a popup
isNumber(&$p_int)
Definition: ac_common.php:202
static request_to_hidden($array)
transform $_REQUEST data to hidden
$value
static button($p_name, $p_value, $p_javascript="", $p_class="smallbutton")
insert_linked_card($p_fiche_id)
Add another concerned (tiers, supplier...)
static filter_by_tag($cn, $p_array=null)
Create a subquery to filter thanks the selected tag.
foreach($array as $idx=> $m) $w
get_late()
get the action where the remind day is today
static escape_string($p_string)
wrapper for the function pg_escape_string
Follow_Up Details are the details for an actions, it means the details of an order, delivery order, submit a quote... this class is linked to the table action_detail.
get_parent()
Return the first parent of the event tree, or -1 if not found.
static display_search($cn, $inner=false)
Display only a search box for searching an action.
save_short()
Add an event , with the minimum of informations, used in Dashboard and Scheduler. ...
switch($ss_action) $f
class_action for manipulating actions action can be :
$ag_id
Definition: action.inc.php:53
function document
Definition: smoke.js:7
navigation_bar($p_offset, $p_line, $p_size=0, $p_page=1, $p_javascript="")
Create a navigation_bar (pagesize)
Definition: user_common.php:81
Description of class_default_menu.
static create_query($cn, $p_array=null)
Get date from $_GET and create the sql stmt for the query.
$content
Definition: xml.php:17
define Class fiche and fiche def, those class are using class attribut. When adding or modifing new c...
Definition: class_fiche.php:44
static submit($p_name, $p_value, $p_javascript="", $p_class="smallbutton")
static action_set_state($cn, $p_array)
global $g_user
Find the default module or the first one.
Definition: action.inc.php:24
fromArray($p_array)
put an array in the variable member, the indice is the member name
tag_cell()
show the cell content in Display for the tags called also by ajax
get_children($p_id)
Compute an array of the complete tree depending of $p_id.
$date_start
generate_document($md_id, $p_array)
generate the document and add it to the action
$_REQUEST['ac']
function trim(s)
remove trailing and heading space
Definition: scripts.js:95
static action_tag_add($cn, $p_array)
if(!isset($_REQUEST['p_jrn'])) else $Ledger id
static id()
return the $_REQUEST['gDossier'] after a check
h($p_string)
to protect again bad characters which can lead to a cross scripting attack the string to be diplayed ...
Definition: ac_common.php:38
static get_to_string($array, $start="?")
transform $_GET data to string
tag_get()
get the tags of the current objet
$count
Definition: modele.inc.php:255
display_parent($p_view, $p_base)
Display the list of parent of the current Follow_Up.
isDate($p_date)
Definition: ac_common.php:223
insert_operation()
insert a related operation
static request_to_string($array, $start="?")
transform $_REQUEST data to string
Description of class_syn_sort_table.
static show_action_list($cn, $p_base)
show a list of documents
remove_linked_card($p_fiche_id)
Remove another concerned (tiers, supplier...)
$fl ag_id
$checkbox
Definition: pcmn_update.php:50
verify()
Verify that data are correct.
myList($p_base, $p_filter="", $p_search="")
myList($p_base, $p_filter = "", $p_search = "") Show list of action by default if sorted on date ...
const ATTR_DEF_QUICKCODE
Definition: constant.php:206
Input HTML for the card show buttons, in the file, you have to add card.js How to use : ...
$retour
Definition: action.inc.php:25
display_linked()
Display the other concerned (tiers, supplier...)
display_short()
display a small form to enter a new event
__construct($p_cn, $p_id=0)
constructor
$limit
Definition: dashboard.php:157
$action
$action string related action
const MAX_ARTICLE
Definition: constant.php:116
save()
Save the document and propose to save the generated document or to upload one, the data are included ...
$SecUser db
static action_tag_remove($cn, $p_array)
export_csv($p_array)
export to CSV the query the p_array has
const ATTR_DEF_NAME
Definition: constant.php:185
remove_operation_deprecated()
remove a related operation
static hidden($p_name, $p_value, $p_id="")
const NOTFOUND
Definition: constant.php:114
$url
static action_print($cn, $p_array)
$href
Definition: adm.inc.php:38
static action_tag_clear($cn, $p_array)
Html Input : Input a date format dd.mm.yyyy The property title should be set to indicate what it is e...
Definition: class_idate.php:31
This class handles only the numeric input, the input will call a javascript to change comma to period...
Definition: class_inum.php:40