cn=$p_cn; $this->id=$p_id; $this->quick_code=''; } /*! get_by_qcode($p_qcode) * \brief Retrieve a card thx his quick_code * complete the object,, set the id member of the object or set it * to 0 if no card is found * \param $p_qcode quick_code (ad_id=23) * \param $p_all retrieve all the attribut of the card, possible value * are true, false retrieves only the f_id * \return 0 success 1 error not found */ function get_by_qcode($p_qcode=null,$p_all=true) { if ( $p_qcode == null ) $p_qcode=$this->quick_code; $p_qcode=trim($p_qcode); $sql="select f_id from jnt_fic_att_value join attr_value using (jft_id) where ad_id=23 and av_text=upper($1)"; $this->id=$this->cn->get_value($sql,array($p_qcode)); if ( $this->cn->count()==0) { $this->id=0; return 1; } echo_debug('class_fiche',__LINE__,'f_id = '.$this->id); if ( $p_all ) $this->getAttribut(); return 0; } /*! ************************************************** * \brief get all the attribute of a card, add missing ones * and sort the array ($this-\>attribut) by ad_id */ function getAttribut() { if ( $this->id == 0){ return; } $sql="select * from jnt_fic_att_value natural join fiche natural join attr_value join jnt_fic_attr on (jnt_fic_attr.fd_id=fiche.fd_id and jnt_fic_attr.ad_id=jnt_fic_att_value.ad_id) join attr_def on (attr_def.ad_id=jnt_fic_att_value.ad_id) where f_id=".$this->id. " order by jnt_order"; $Ret=$this->cn->exec_sql($sql); if ( ($Max=Database::num_row($Ret)) == 0 ) return ; for ($i=0;$i<$Max;$i++) { $row=Database::fetch_array($Ret,$i); $this->fiche_def=$row['fd_id']; $t=new Attribut ($row['ad_id']); $t->ad_text=$row['ad_text']; $t->av_text=$row['av_text']; $t->jnt_order=$row['jnt_order']; $this->attribut[$i]=$t; } $e=new Fiche_def($this->cn,$this->fiche_def); $e->GetAttribut(); if ( sizeof($this->attribut) != sizeof($e->attribut ) ) { // !!! Missing attribute foreach ($e->attribut as $f ) { $flag=0; foreach ($this->attribut as $g ) { if ( $g->ad_id == $f->ad_id ) $flag=1; } if ( $flag == 0 ) { // there's a missing one, we insert it $t=new Attribut ($f->ad_id); $t->av_text=""; $t->ad_text=$f->ad_text; $t->jnt_order=$f->jnt_order; $this->attribut[$Max]=$t; $Max++; } // if flag == 0 }// foreach $this->attribut=SortAttributeById($this->attribut); }//missing attribut } /** * @brief find the card with the p_attribut equal to p_value, it is not case sensitive * @param $p_attribut attribute to find see table attr_def * @param $p_value value in attr_value.av_text * @return return ARRAY OF jft_id,f_id,fd_id,ad_id,av_text */ function seek($p_attribut,$p_value){ $sql="select jft_id,f_id,fd_id,ad_id,av_text from fiche join jnt_fic_att_value using (f_id) join attr_value using (jft_id) where ad_id=$1 and upper(av_text)=upper($2)"; $res=$this->cn->get_array($sql,array($p_attribut,$p_value)); return $res; } /*! * \brief give the size of a card object * * \return size */ function size() { if ( isset ($this->ad_id)) return sizeof($this->ad_id); else return 0; } /*! ************************************************** * \brief Return array of card from the frd family * * \param $p_frd_id the fiche_def_ref.frd_id * \param $p_search p_search is a filter on the name * \param $p_sql extra sql condition * * \return array of fiche object */ function CountByDef($p_frd_id,$p_search="",$p_sql="") { $sql="select * from fiche join fiche_Def using (fd_id) where frd_id=".$p_frd_id; if ( $p_search != "" ) { $a=FormatString($p_search); $sql="select * from vw_fiche_attr where frd_id=".$p_frd_id. " and vw_name ~* '$p_search'"; } $Ret=$this->cn->exec_sql($sql.$p_sql); return Database::num_row($Ret) ; } /*! ************************************************** * \brief Return array of card from the frd family * * * \param $p_frd_id the fiche_def_ref.frd_id * \param $p_offset * \param $p_search is an optional filter * * \return array of fiche object */ function GetByDef($p_frd_id,$p_offset=-1,$p_search="") { if ( $p_offset == -1 ) { $sql="select * from fiche join fiche_Def using (fd_id) where frd_id=".$p_frd_id." $p_search order by f_id"; } else { $limit=($_SESSION['g_pagesize']!=-1)?"limit ".$_SESSION['g_pagesize']:""; $sql="select * from fiche join fiche_Def using (fd_id) where frd_id=".$p_frd_id." $p_search order by f_id " .$limit." offset ".$p_offset; } $Ret=$this->cn->exec_sql($sql); if ( ($Max=Database::num_row($Ret)) == 0 ) return ; $all[0]=new fiche($this->cn); for ($i=0;$i<$Max;$i++) { $row=Database::fetch_array($Ret,$i); $t=new fiche($this->cn,$row['f_id']); $t->getAttribut(); $all[$i]=$t; } echo_debug(__FILE__,__LINE__,$all); return $all; } function ShowTable() { echo " ". $this->id."". " ". $this->attribut_value."". " ". $this->attribut_def.""; } /*! ************************************************** * \brief return the string of the given attribute * (attr_def.ad_id) * \param $p_ad_id the AD_ID from attr_def.ad_id * \see constant.php * \return string */ function strAttribut($p_ad_id) { if ( sizeof ($this->attribut) == 0 ) { if ($this->id==0) return '- ERROR -'; // object is not in memory we need to look into the database $sql="select av_text from attr_value join jnt_fic_att_value using(jft_id) where f_id=".FormatString($this->id)." and ad_id=".$p_ad_id; $Res=$this->cn->exec_sql($sql); $row=Database::fetch_all($Res); // if not found return error if ( $row == false ) return ' - ERROR -'; return $row[0]['av_text']; } foreach ($this->attribut as $e) { if ( $e->ad_id == $p_ad_id ) return $e->av_text; } return '- ERROR -'; } /*!\brief make an array of attributes of the category of card (FICHE_DEF.FD_ID) *The array can be used with the function insert, it will return a struct like this : * in the first key (av_textX), X is the ATTR_DEF::AD_ID \verbatim Example Array ( [av_text1] => Nom [av_text12] => Personne de contact [av_text5] => Poste Comptable [av_text13] => numéro de tva [av_text14] => Adresse [av_text15] => code postal [av_text24] => Ville [av_text16] => pays [av_text17] => téléphone [av_text18] => email [av_text23] => Quick Code ) \endverbatim *\param $pfd_id FICHE_DEF::FD_ID *\return an array of attribute *\exception Exception if the cat of card doesn't exist, Exception.getCode()=1 *\see fiche::insert() */ function toArray($pfd_id) { $sql="select 'av_text'||to_char(ad_id,'9999') as key,". " ad_text ". " from fiche_def join jnt_fic_attr using (fd_id)". " join attr_def using (ad_id) ". " where fd_id=$1 order by jnt_order"; $ret=$this->cn->get_array($sql,array($pfd_id)); if ( empty($ret)) throw new Exception(_('Cette categorie de card n\'existe pas').' '.$pfd_id,1); $array=array(); foreach($ret as $idx=>$val) { $a=str_replace(' ','',$val['key']); $array[$a]=$val['ad_text']; } return $array; } /*! * \brief insert a new record * show a blank card to be filled * * \param $p_fiche_def is the fiche_def.fd_id * * \return HTML Code */ function blank($p_fiche_def) { // array = array of attribute object sorted on ad_id $f=new fiche_def($this->cn,$p_fiche_def); $f->Get(); $array=$f->getAttribut(); $r=''; foreach ($array as $attr) { $msg=""; if ( $attr->ad_id == ATTR_DEF_ACCOUNT) { $w=new IPoste("av_text".$attr->ad_id); $w->set_attribute('ipopup','ipop_account'); $w->set_attribute('account',"av_text".$attr->ad_id); // account created automatically $sql="select account_auto($p_fiche_def)"; echo_debug("class_fiche",__LINE__,$sql); $ret_sql=$this->cn->exec_sql($sql); $a=Database::fetch_array($ret_sql,0); $label=new ISpan(); $label->name="av_text".$attr->ad_id."_label"; if ( $a['account_auto'] == 't' ) $msg.=" "; else { // if there is a class base in fiche_def_ref, this account will be the // the default one if ( strlen(trim($f->class_base)) != 0 ) { $msg.=" "; $w->value=$f->class_base; } } $r.="".td("Poste Comptable",' class="input_text" ' ).td($w->input())."$msg "; continue; } elseif ( $attr->ad_id == ATTR_DEF_TVA) { $r.=JS_SHOW_TVA; $w=new ITva(); } elseif ( $attr->ad_id == ATTR_DEF_COMPANY ) { $r.=JS_LEDGER; $w=new ICard(); // filter on frd_id $sql=' select fd_id from fiche_def where frd_id in ('.FICHE_TYPE_CLIENT.','.FICHE_TYPE_FOURNISSEUR.','.FICHE_TYPE_ADM_TAX.')'; $filter=$this->cn->make_list($sql); $w->extra=$filter; $w->extra2=0; $label=new ISpan(); $label->name="av_text".$attr->ad_id."_label"; $msg=$label->input(); } else { $w=new IText(); } $w->table=1; $w->label=$attr->ad_text; $w->name="av_text".$attr->ad_id; $r.="".td($w->label,' class="input_text" ').$w->input()."$msg "; } $r.= '
".$label->input()."
"._("Rappel: Poste créé automatiquement à partir de ").$f->class_base."
".$label->input()."
"._("Rappel: Poste par défaut sera "). $f->class_base. " !
'; return $r; } /*! * \brief Display object instance, getAttribute * sort the attribute and add missing ones * \param $p_readonly true= if can not modify, otherwise false * * * \return string to display */ function Display($p_readonly) { $this->GetAttribut(); $attr=$this->attribut; $ret=""; if ( empty ($attr) ) { return "Fiche non trouvée"; } foreach ( $attr as $r) { $msg=""; $bulle=""; if ( $p_readonly) { $w=new IText(); $w->table=1; $w->readOnly=true; } if ($p_readonly==false) { if ( $r->ad_id == ATTR_DEF_ACCOUNT) { $w=new IPoste("av_text".$r->ad_id); $w->set_attribute('ipopup','ipop_account'); $w->set_attribute('account',"av_text".$r->ad_id); // account created automatically $w->table=1; // account created automatically $sql="select account_auto($this->fiche_def)"; echo_debug("class_fiche",__LINE__,$sql); $ret_sql=$this->cn->exec_sql($sql); $a=Database::fetch_array($ret_sql,0); $bulle=HtmlInput::infobulle(10); if ( $a['account_auto'] == 't' ) $bulle.=HtmlInput::warnbulle(11); } elseif ( $r->ad_id == ATTR_DEF_TVA) { $ret.=JS_SHOW_TVA; $w=new ITva(); $w->table=1; } elseif ( $r->ad_id == ATTR_DEF_COMPANY ) { $ret.=JS_LEDGER; $w=new ISearch(); // filter on frd_id $w->extra=FICHE_TYPE_CLIENT.','.FICHE_TYPE_FOURNISSEUR.','.FICHE_TYPE_ADM_TAX; $w->extra2=0; // jrn = 0 $w->table=1; $label=new ISpan(); $label->name="av_text".$r->ad_id."_label"; $msg=$label->input(); } else { $w=new IText(); $w->table=0; } } $w->value=$r->av_text; $w->name="av_text".$r->ad_id; $w->readonly=$p_readonly; $ret.="".td($r->ad_text.$bulle).td($w->input()).td($msg)." "; } $ret.="
"; return $ret; } /*! * \brief Save a card, call insert or update * * \param p_fiche_def (default 0) */ function Save($p_fiche_def=0) { // new card or only a update ? if ( $this->id == 0 ) $this->insert($p_fiche_def); else $this->update(); } /*! * \brief insert a new record * * \param p_fiche_def fiche_def.fd_id * \param p_array is the array containing the data */ function insert($p_fiche_def,$p_array=null) { if ( $p_array == null) $p_array=$_POST; $fiche_id=$this->cn->get_next_seq('s_fiche'); $this->id=$fiche_id; // first we create the card $this->cn->start(); try { $sql=sprintf("insert into fiche(f_id,fd_id)". " values (%d,%d)", $fiche_id,$p_fiche_def); $Ret=$this->cn->exec_sql($sql); // parse the $p_array array foreach ($p_array as $name=>$value ) { echo_debug ("class_fiche",__LINE__,"Name = $name value $value") ; /* avoid the button for searching an accounting item */ if ( $name=='av_text5_bt') continue; list ($id) = sscanf ($name,"av_text%d"); if ( $id == null ) continue; echo_debug("class_fiche",__LINE__,"add $id"); // Special traitement // quickcode if ( $id == ATTR_DEF_QUICKCODE) { echo_debug("Modify ATTR_DEF_QUICKCODE"); $sql=sprintf("select insert_quick_code(%d,'%s')", $fiche_id,FormatString($value)); $this->cn->exec_sql($sql); continue; } // name if ( $id == ATTR_DEF_NAME ) { echo_debug("Modify ATTR_DEF_NAME"); if ( strlen(trim($value)) == 0 ) $value="pas de nom"; } // account if ( $id == ATTR_DEF_ACCOUNT ) { echo_debug("insert ATTR_DEF_ACCOUNT"); $v=FormatString($value); try { if (isNumber($v) == 1 || strpos($v,',') != 0) { $parameter=array($this->id,$v); // $sql=sprintf("select account_insert(%d,'%s')",$this->id,$v); } else { $parameter=array($this->id,null); // $sql=sprintf("select account_insert(%d,null)", $this->id); } $this->cn->exec_sql("select account_insert($1,$2)",$parameter); echo_debug(__FILE__,__LINE__,$sql); } catch (Exception $e) { throw new Exception ("Erreur : ce compte [$v] n'a pas de compte parent.". "L'opération est annulée", 1); } continue; } // TVA if ( $id == ATTR_DEF_TVA ) { echo_debug("Modify ATTR_DEF_TVA"); // Verify if the rate exists, if not then do not update if ( strlen(trim($value)) != 0 ) { if ( isNumber($value) == 0 ) continue; if ( $this->cn->count_sql("select * from tva_rate where tva_id=".$value) == 0) { echo_debug("class_fiche",__LINE__,"Tva invalide $value"); continue; } } } // The contact has a company attribut if ( $id == ATTR_DEF_COMPANY ) { $exist=$this->cn->count_sql("select f_id from fiche join fiche_def using (fd_id) ". " join jnt_fic_att_value using (f_id) join attr_value using (jft_id) ". " where frd_id in (8,9,14) and ad_id=".ATTR_DEF_QUICKCODE. " and av_text='".FormatString($value)."'"); if ( $exist == 0 && FormatString($value) != null ) { $value=""; } } // Normal traitement $value2=FormatString($value); $sql=sprintf("select attribut_insert(%d,%d,'%s')", $fiche_id,$id,trim($value2)); $this->cn->exec_sql($sql); } } catch (Exception $e) { $this->cn->rollback(); throw ($e); return; } $this->cn->commit(); return; } /*!\brief update a card */ function update($p_array=null) { if ( $p_array == null) $p_array=$_POST; try { $this->cn->start(); // parse the $p_array array foreach ($p_array as $name=>$value ) { echo_debug ("class_fiche",__LINE__,"Name = $name value $value") ; list ($id) = sscanf ($name,"av_text%d"); if ( $id == null ) continue; echo_debug("class_fiche",__LINE__,"modify $id"); // retrieve jft_id to update table attr_value $sql=" select jft_id from jnt_fic_att_value where ad_id=$id and f_id=$this->id"; $Ret=$this->cn->exec_sql($sql); if ( Database::num_row($Ret) != 1 ) { // we need to insert this new attribut echo_debug ("class_fiche ".__LINE__." adding id !!! "); $jft_id=$this->cn->get_next_seq('s_jnt_fic_att_value'); $sql2=sprintf("insert into jnt_fic_att_value(jft_id,ad_id,f_id) values (%s,%s,%s)", $jft_id,$id,$this->id); $ret2=$this->cn->exec_sql($sql2); // insert a null value for this attribut $sql3=sprintf("insert into attr_value(jft_id,av_text) values (%s,null)", $jft_id); $ret3=$this->cn->exec_sql($sql3); } else { $tmp=Database::fetch_array($Ret,0); $jft_id=$tmp['jft_id']; } // Special traitement // quickcode if ( $id == ATTR_DEF_QUICKCODE) { echo_debug("Modify ATTR_DEF_QUICKCODE"); $sql=sprintf("select update_quick_code(%d,'%s')", $jft_id,FormatString($value)); $this->cn->exec_sql($sql); continue; } // name if ( $id == ATTR_DEF_NAME ) { echo_debug("Modify ATTR_DEF_NAME"); if ( strlen(trim($value)) == 0 ) continue; } if ( $id == ATTR_DEF_STOCK ) { $st=$this->cn->count_sql('select * from stock_goods where '. " f_id=".$this->id); if ( $st == 0 ) { $user=new User($this->cn); $exercice=$user->get_exercice(); if ( $exercice == 0 ) throw new Exception ('Annee invalide erreur'); $str_stock=sprintf('insert into stock_goods(f_id,sg_quantity,sg_comment,sg_code,sg_type,sg_exercice) '. ' values (%d,0,\'%s\',upper(\'%s\'),\'d\',\'%s\')', $this->id, 'initial', FormatString($value), $exercice); $this->cn->exec_sql($str_stock); }else { $str_stock=sprintf("update stock_goods set sg_code=upper('%s') where f_id=%d", FormatString($value), $this->id); $this->cn->exec_sql($str_stock); } } // account if ( $id == ATTR_DEF_ACCOUNT ) { echo_debug("Modify ATTR_DEF_ACCOUNT"); $v=FormatString($value); echo_debug("Value = $v"); if ( isNumber($v) == 1 || strpos($v,',') != 0 ) { $sql=sprintf("select account_update(%d,'%s')", $this->id,$v); try { $this->cn->exec_sql($sql); } catch (Exception $e) { throw new Exception(__LINE__."Erreur : ce compte [$v] n'a pas de compte parent.". "L'opération est annulée"); } continue; } if ( strlen (trim($v)) == 0 ) { $sql=sprintf("select account_update(%d,null)", $this->id); try { $Ret=$this->cn->exec_sql($sql); /* update also the jrnx */ /* The jrnx CANNOT BE UPDATED $sql='update jrnx set j_poste=$1 where j_qcode in (select quick_code from vw_fiche_attr where f_id=$2)'; $this->cn->exec_sql( $sql, array($v,$this->id)); */ } catch (Exception $e) { throw new Exception(__LINE__."Erreur : ce compte [$v] n'a pas de compte parent.". "L'opération est annulée"); } continue; } } // TVA if ( $id == ATTR_DEF_TVA ) { echo_debug("Modify ATTR_DEF_TVA"); // Verify if the rate exists, if not then do not update if ( strlen(trim($value)) != 0 ) { if ( $this->cn->count_sql("select * from tva_rate where tva_id=".$value) == 0) { echo_debug("class_fiche",__LINE__,"Tva invalide $value"); continue; } } } if ( $id == ATTR_DEF_COMPANY ) { $exist=$this->cn->count_sql("select f_id from fiche join fiche_def using (fd_id) ". " join jnt_fic_att_value using (f_id) join attr_value using (jft_id) ". " where frd_id in (8,9,14) and ad_id=".ATTR_DEF_QUICKCODE. " and av_text='".FormatString($value)."'"); if ( $exist == 0 && FormatString($value) != null ) { $value="Attention : pas de société "; } } // Normal traitement $value2=FormatString($value); $sql=sprintf("update attr_value set av_text='%s' where jft_id=%d", trim($value2),$jft_id); $this->cn->exec_sql($sql); } } catch (Exception $e ) { echo ''. $e->getMessage(). ''; $this->cn->rollback(); return; } $this->cn->commit(); return; } /*!\brief remove a card */ function remove() { if ( $this->id==0 ) return; // verify if that card has not been used is a ledger // if the card has its own account in PCMN // Get the fiche_def.fd_id from fiche.f_id $this->Get(); $fiche_def=new fiche_def($this->cn,$this->fiche_def); $fiche_def->Get(); // if the card is used do not removed it $qcode=$this->strAttribut(ATTR_DEF_QUICKCODE); if ( $this->cn->count_sql("select * from jrnx where j_qcode='".Database::escape_string($qcode)."'") != 0) { alert('Impossible cette fiche est utilisée dans un journal'); return; } $this->delete(); } /*!\brief return the name of a card * */ function getName() { $sql="select av_text from jnt_fic_att_value join attr_value using (jft_id) where ad_id=1 and f_id=".$this->id; $Res=$this->cn->exec_sql($sql); $r=Database::fetch_all($Res); if ( sizeof($r) == 0 ) return 1; return $r[0]['av_text']; } /*!\brief return the quick_code of a card * \return null if not quick_code is found */ function get_quick_code() { $sql="select av_text from jnt_fic_att_value join attr_value using (jft_id) where ad_id=23 and f_id=".$this->id; $Res=$this->cn->exec_sql($sql); $r=Database::fetch_all($Res); if ( sizeof($r) == 0 ) return null; return $r[0]['av_text']; } /*!\brief Synonum of fiche::getAttribut */ function Get() { echo_debug('class_client',__LINE__,'Get'); fiche::getAttribut(); } /*!\brief get all the card thanks the fiche_def_ref * \param $p_offset (default =-1) * \param $p_search sql condition * \return array of fiche object */ function GetAll($p_offset=-1,$p_search="") { return fiche::GetByDef($this->fiche_def_ref,$p_offset,$p_search); } /*!\brief retrieve the frd_id of the fiche it is the type of the * card (bank, purchase...) * (fiche_def_ref primary key) */ function get_fiche_def_ref_id() { $result=$this->cn->get_array("select frd_id from fiche join fiche_Def using (fd_id) where f_id=".$this->id); if ( $result == null ) return null; return $result[0]['frd_id']; } /** *@brief fetch and return and array *@see get_row get_row_date */ private function get_row_result($res) { $array=array(); $tot_cred=0.0; $tot_deb=0.0; $Max=Database::num_row($res); if ( $Max == 0 ) return null; for ($i=0;$i<$Max;$i++) { $array[]=Database::fetch_array($res,$i); if ($array[$i]['j_debit']=='t') { $tot_deb+=$array[$i]['deb_montant'] ; } else { $tot_cred+=$array[$i]['cred_montant'] ; } } $this->row=$array; return array($array,$tot_deb,$tot_cred); } /*! * \brief Get data for poste * * \param $p_from periode from * \param $p_to end periode * \return double array (j_date,deb_montant,cred_montant,description,jrn_name,j_debit,jr_internal) * (tot_deb,tot_credit * */ function get_row_date($p_from,$p_to) { if ( $this->id == 0 ) { echo_error("class_fiche",__LINE__,"id is 0"); return; } $qcode=$this->strAttribut(ATTR_DEF_QUICKCODE); $Res=$this->cn->exec_sql("select j_date,to_char(j_date,'DD.MM.YYYY') as j_date_fmt,j_qcode,". "case when j_debit='t' then j_montant else 0 end as deb_montant,". "case when j_debit='f' then j_montant else 0 end as cred_montant,". " jr_comment as description,jrn_def_name as jrn_name,". "j_debit, jr_internal,jr_id,coalesce(comptaproc.get_letter_jnt(j_id),-1) as letter ". " from jrnx left join jrn_def on jrn_def_id=j_jrn_def ". " left join jrn on jr_grpt_id=j_grpt". " where j_qcode=$1 and ". " ( to_date($2,'DD.MM.YYYY') <= j_date and ". " to_date($3,'DD.MM.YYYY') >= j_date )". " order by j_date",array($qcode,$p_from,$p_to)); return $this->get_row_result($Res); } /*! * \brief Get data for poste * * \param $p_from periode from * \param $p_to end periode * \return double array (j_date,deb_montant,cred_montant,description,jrn_name,j_debit,jr_internal) * (tot_deb,tot_credit * */ function get_row($p_from,$p_to) { if ( $this->id == 0 ) { echo_error("class_fiche",__LINE__,"id is 0"); return; } $qcode=$this->strAttribut(ATTR_DEF_QUICKCODE); $periode=sql_filter_per($this->cn,$p_from,$p_to,'p_id','jr_tech_per'); $Res=$this->cn->exec_sql("select j_date,to_char(j_date,'DD.MM.YYYY') as j_date_fmt,j_qcode,". "case when j_debit='t' then j_montant else 0 end as deb_montant,". "case when j_debit='f' then j_montant else 0 end as cred_montant,". " jr_comment as description,jrn_def_name as jrn_name,". "j_debit, jr_internal,jr_id ". " from jrnx left join jrn_def on jrn_def_id=j_jrn_def ". " left join jrn on jr_grpt_id=j_grpt". " where j_qcode='".$qcode."' and ".$periode. " order by j_date::date"); return $this->get_row_result($Res); } /*! * \brief HtmlTable, display a HTML of a card for the asked period * \return none */ function HtmlTableDetail($p_array=null) { if ( $p_array == null) $p_array=$_REQUEST; $name=$this->getName(); list($array,$tot_deb,$tot_cred)=$this->get_row_date( $p_array['from_periode'], $p_array['to_periode'] ); if ( count($this->row ) == 0 ) return; $rep=""; echo '

'.$this->id." ".$name.'

'; echo ""; echo "". "". "". "". "". "". ""; foreach ( $this->row as $op ) { echo "". "". "". "". "". "". ""; $ac=new Acc_Operation($this->cn); $ac->jr_id=$op['jr_id']; echo $ac->display_jrnx_detail(1); } $solde_type=($tot_deb>$tot_cred)?"solde débiteur":"solde créditeur"; $diff=round(abs($tot_deb-$tot_cred),2); echo "". "". "". "". "". ""; echo "
Code interne Date Description Montant Débit/Crédit
".$op['jr_internal']."".$op['j_date']."".h($op['description'])."".""."
$solde_type". "$diff$tot_deb$tot_cred
"; return; } /*! * \brief HtmlTable, display a HTML of a card for the asked period * \param $p_array default = null keys = from_periode, to_periode */ function HtmlTable($p_array=null) { if ( $p_array == null) $p_array=$_REQUEST; $name=h($this->getName()); list($array,$tot_deb,$tot_cred)=$this->get_row_date( $p_array['from_periode'], $p_array['to_periode'] ); if ( count($this->row ) == 0 ) return; $rep=""; echo '

'.$this->id." ".$name.'

'; echo ""; echo "". "". "". "". "". "". ""; foreach ( $this->row as $op ) { echo "". "". "". "". "". "". ""; } $solde_type=($tot_deb>$tot_cred)?"solde débiteur":"solde créditeur"; $diff=round(abs($tot_deb-$tot_cred),2); echo "". "". "". "". "". "". ""; echo "
"._('Code interne')." "._('Date').""._('Description')." "._('Débit')." "._('Crédit')."
".$op['jr_internal']."".$op['j_date_fmt']."".h($op['description'])."".$op['deb_montant']."".$op['cred_montant']."
$solde_type$diff$tot_deb$tot_cred
"; return; } /*! * \brief Display HTML Table Header (button) * * \return none */ function HtmlTableHeader($p_array=null) { if ( $p_array == null) $p_array=$_REQUEST; $hid=new IHidden(); echo '
'; echo ""; echo ''; echo '"; echo '"; echo '"; echo "
'. HtmlInput::submit('bt_other',"Autre poste"). dossier::hidden(). $hid->input("type","poste").$hid->input('p_action','impress')."
'. HtmlInput::submit('bt_pdf',"Export PDF"). dossier::hidden(). $hid->input("type","poste"). $hid->input('p_action','impress'). $hid->input("f_id",$this->id). dossier::hidden(). $hid->input("from_periode",$p_array['from_periode']). $hid->input("to_periode",$p_array['to_periode']); if (isset($p_array['oper_detail'])) echo $hid->input('oper_detail','on'); echo "
'. HtmlInput::submit('bt_csv',"Export CSV"). dossier::hidden(). $hid->input("type","poste"). $hid->input('p_action','impress'). $hid->input("f_id",$this->id). $hid->input("from_periode",$p_array['from_periode']). $hid->input("to_periode",$p_array['to_periode']); if (isset($p_array['oper_detail'])) echo $hid->input('oper_detail','on'); echo "
"; echo '
'; } /*! * \brief give the balance of an card * \return * balance of the card * */ function get_solde_detail($p_cond="") { if ( $this->id == 0 ) exit('fiche->id est nul'); $qcode=$this->strAttribut(ATTR_DEF_QUICKCODE); if ( $p_cond != "") $p_cond=" and ".$p_cond; $Res=$this->cn->exec_sql("select sum(deb) as sum_deb, sum(cred) as sum_cred from ( select j_poste, case when j_debit='t' then j_montant else 0 end as deb, case when j_debit='f' then j_montant else 0 end as cred from jrnx where j_qcode = ('$qcode'::text) $p_cond ) as m "); $Max=Database::num_row($Res); if ($Max==0) return 0; $r=Database::fetch_array($Res,0); return array('debit'=>$r['sum_deb'], 'credit'=>$r['sum_cred'], 'solde'=>abs($r['sum_deb']-$r['sum_cred'])); } /*!\brief check if an attribute is empty *\param $p_attr the id of the attribut to check (ad_id) *\return return true is the attribute is empty or missing */ function empty_attribute($p_attr) { $sql="select av_text from jnt_fic_att_value natural join fiche natural join attr_value left join attr_def using (ad_id) where f_id=".$this->id. " and ad_id = ".$p_attr. " order by ad_id"; $res=$this->cn->exec_sql($sql); if ( Database::num_row($res) == 0 ) return true; $text=Database::fetch_result($res,0,0); return (strlen(trim($text)) > 0)?false:true; } /*! Summary * \brief show the default screen * * \param $p_search (filter) * \param $p_action show the action column * \param $p_sql SQL to filter the number of card must start with AND * \return: string to display */ function Summary($p_search="",$p_action="",$p_sql="") { $str_dossier=dossier::get(); $p_search=FormatString($p_search); $script=$_SERVER['PHP_SELF']; // Creation of the nav bar // Get the max numberRow $all_tiers=$this->CountByDef($this->fiche_def_ref,$p_search,$p_sql); // Get offset and page variable $offset=( isset ($_REQUEST['offset'] )) ?$_REQUEST['offset']:0; $page=(isset($_REQUEST['page']))?$_REQUEST['page']:1; $bar=jrn_navigation_bar($offset,$all_tiers,$_SESSION['g_pagesize'],$page); // set a filter ? $search=$p_sql; $user=new User($this->cn); $exercice=$user->get_exercice(); $tPeriode=new Periode($this->cn); list($max,$min)=$tPeriode->get_limit($exercice); if ( trim($p_search) != "" ) { $search.=" and f_id in (select f_id from jnt_fic_att_value join fiche using (f_id) join attr_value using (jft_id) where ad_id=1 and av_text ~* '$p_search')"; } // Get The result Array $step_tiers=$this->GetAll($offset,$search); if ( $all_tiers == 0 ) return ""; $r=$bar; $r.=''; $r.=''; echo_debug(__FILE__,__LINE__,$step_tiers); if ( sizeof ($step_tiers ) == 0 ) return $r; foreach ($step_tiers as $tiers ) { $r.=""; $e=sprintf(' ', $script,$p_action,$tiers->id,$str_dossier); $r.=""; $r.=""; $r.=""; /* Filter on the default year */ $User=new User($this->cn); $filter_year=" j_tech_per in (select p_id from parm_periode ". "where p_exercice='".$User->get_exercice()."')"; $a=$tiers->get_solde_detail($filter_year); $r.=sprintf('',$a['debit']); $r.=sprintf('',$a['credit']); $r.=sprintf('',$a['solde']); $r.=""; } $r.="
'._('Quick Code').' '._('Nom').' '._('Adresse').' '._('Total débit').' '._('Total crédit').' '._('Solde').'
$e".$tiers->strAttribut(ATTR_DEF_QUICKCODE)."".h($tiers->strAttribut(ATTR_DEF_NAME))."".h($tiers->strAttribut(ATTR_DEF_ADRESS). " ".$tiers->strAttribut(ATTR_DEF_CP). " ".$tiers->strAttribut(ATTR_DEF_PAYS)). " %15.2f€ %15.2f€ %15.2f€
"; $r.=$bar; return $r; } /*! * \brief get the fd_id of the card : fd_id, it set the attribute fd_id */ function get_categorie() { if ( $this->id == 0 ) exit('class_fiche : f_id = 0 '); $sql='select fd_id from fiche where f_id='.$this->id; $R=$this->cn->get_value($sql); if ( $R == "" ) $this->fd_id=0; else $this->fd_id=$R; } /*! *************************************************** * \brief Check if a fiche is used by a jrn * return 1 if the fiche is in the range otherwise 0, the quick_code * or the id must be set * * * \param $p_jrn journal_id * \param $p_type : deb or cred default empty * * \return 1 if the fiche is in the range otherwise < 1 * -1 the card doesn't exist * -2 the ledger has no card to check * */ function belong_ledger($p_jrn,$p_type="") { // check if we have a quick_code or a f_id if (($this->quick_code==null || $this->quick_code == "" ) && $this->id == 0 ) { echo 'erreur ni quick_code ni f_id ne sont donnes'; exit(); } //retrieve the quick_code if ( $this->quick_code=="") $this->quick_code=$this->get_quick_code(); if ( $this->quick_code==null) return -1; if ( $this->id == 0 ) if ( $this->get_by_qcode(null,false) == 1) return -1; $get=""; if ( $p_type == 'deb' ) { $get='jrn_def_fiche_deb'; } if ( $p_type == 'cred' ) { $get='jrn_def_fiche_cred'; } if ( $get != "" ) { $Res=$this->cn->exec_sql("select $get as fiche from jrn_def where jrn_def_id=$p_jrn"); } else { // Get all the fiche type (deb and cred) $Res=$this->cn->exec_sql(" select jrn_def_fiche_cred as fiche from jrn_def where jrn_def_id=$p_jrn union select jrn_def_fiche_deb from jrn_def where jrn_def_id=$p_jrn" ); } $Max=Database::num_row($Res); if ( $Max==0) { return -2; } /* convert the array to a string */ $list=Database::fetch_all($Res); $str_list=""; $comma=''; foreach ($list as $row) { if ( $row['fiche'] != '' ) { $str_list.=$comma.$row['fiche']; $comma=','; } } // Normally Max must be == 1 if ( $str_list=="") { return -3; } $sql="select * from fiche where fd_id in (".$str_list.") and f_id= ".$this->id; $Res=$this->cn->exec_sql($sql); $Max=Database::num_row($Res); if ($Max==0 ) return 0; else return 1; } /*!\brief get all the card from a categorie *\param $p_cn database connx *\param $pFd_id is the category id *\return an array of card, but only the fiche->id is set */ static function get_fiche_def($p_cn,$pFd_id) { $sql='select f_id from fiche where fd_id=$1'; $array=$p_cn->get_array($sql,array($pFd_id)); if ( empty ($array) ) return null; foreach ($array as $ret ) { $r[]=new fiche($p_cn,$ret['f_id']); } return $r; } /*!\brief check if a card is used *\return return true is a card is used otherwise false */ function is_used() { /* retrieve first the quickcode */ $qcode=$this->strAttribut(ATTR_DEF_QUICKCODE); $sql='select count(*) as c from jrnx where j_qcode=$1'; $count=$this->cn->get_value($sql,array($qcode)); if ( $count == 0 ) return false; return true; } /*\brief remove a card without verification */ function delete() { // Remove from attr_value $Res=$this->cn->exec_sql("delete from attr_value where jft_id in (select jft_id from jnt_fic_att_value natural join fiche where f_id=".$this->id.")"); // Remove from jnt_fic_att_value $Res=$this->cn->exec_sql("delete from jnt_fic_att_value where f_id=".$this->id); // Remove from fiche $Res=$this->cn->exec_sql("delete from fiche where f_id=".$this->id); } /*!\brief create the sql statement for retrieving all * the card *\return string with sql statement *\param $array contains the condition \verbatim [jrn] => 2 [typecard] => cred / deb / filter or list [query] => string \endverbatim *\note the typecard cred, deb or filter must be used with jrn, the value of list means a list of fd_id *\see ajax_card.php cards.js */ function build_sql($array) { if ( ! empty($array) ) extract($array); $and=''; $filter_fd_id='true'; $filter_query=''; if ( isset($typecard)) { switch($typecard) { case 'cred': if ( ! isset($jrn)) throw ('Erreur pas de valeur pour jrn'); $filter_jrn=$this->cn->make_list("select jrn_def_fiche_cred from jrn_Def where jrn_def_id=$1",array($jrn)); $filter_fd_id=" fd_id in (".$filter_jrn.")"; $and=" and "; break; case 'deb': if ( ! isset($jrn)) throw ('Erreur pas de valeur pour jrn'); $filter_jrn=$this->cn->make_list("select jrn_def_fiche_deb from jrn_Def where jrn_def_id=$1",array($jrn)); $filter_fd_id=" fd_id in (".$filter_jrn.")"; $and=" and "; break; case 'filter': if ( ! isset($jrn)) throw ('Erreur pas de valeur pour jrn'); $filter_jrn=$this->cn->make_list("select jrn_def_fiche_deb from jrn_Def where jrn_def_id=$1",array($jrn)); $fp1=" fd_id in (".$filter_jrn.")"; $filter_jrn=$this->cn->make_list("select jrn_def_fiche_cred from jrn_Def where jrn_def_id=$1",array($jrn)); $fp2=" fd_id in (".$filter_jrn.")"; $filter_fd_id='('.$fp1.' or '.$fp2.')'; $and=" and "; break; case 'all': $filter_fd_id=' true'; break; default: $filter_fd_id=' fd_id in ('.$typecard.')'; } } $and=" and "; if (isset($query)){ $query=FormatString($query); $filter_query=$and."(vw_name ilike '%$query%' or quick_code ilike ('%$query%') or vw_description ilike '%$query%' or tva_num ilike '%$query%')"; } $sql="select * from vw_fiche_attr where ".$filter_fd_id.$filter_query; return $sql; } /** *@brief move a card to another cat. The properties will changed * and be removed *@param $p_fdid the fd_id of destination */ function move_to($p_fdid) { $this->cn->start(); $this->cn->exec_sql('update fiche set fd_id=$1 where f_id=$2',array($p_fdid,$this->id)); // add missing $this->cn->exec_sql('select fiche_attribut_synchro($1)',array($p_fdid)); // remove not valid $ajnt=$this->cn->get_array('select jft_id from jnt_fic_att_value where f_id=$1 and ad_id not in (select ad_id from jnt_fic_attr where fd_id=$2)', array($this->id,$p_fdid)); if ( count($ajnt) == 0 ) return; for ($i=0;$icn->exec_sql('delete from attr_value where jft_id=$1',array($ajnt[$i]['jft_id'])); $this->cn->exec_sql('delete from jnt_fic_att_value where jft_id=$1',array($ajnt[$i]['jft_id'])); } $this->cn->commit(); } static function test_me() { $cn=new Database(dossier::id()); $a=new Fiche($cn); $select_cat=new ISelect('fd_id'); $select_cat->value=$cn->make_array('select fd_id,fd_label from fiche_def where frd_id='. FICHE_TYPE_CLIENT); echo '
'; echo dossier::hidden(); echo HtmlInput::hidden('test_select',$_GET['test_select']); echo 'Choix de la catégorie'; echo $select_cat->input(); echo HtmlInput::submit('go_card','Afficher'); echo '
'; if ( isset ($_GET['go_card'])) { $empty=$a->toArray($_GET['fd_id']); print_r($empty); } } } ?>