diff --git a/html/ajax_misc.php b/html/ajax_misc.php index 5fa6fc560..bd9f124e8 100644 --- a/html/ajax_misc.php +++ b/html/ajax_misc.php @@ -257,6 +257,60 @@ if (array_key_exists($op, $path)) { } switch ($op) { + /* + * Get the currency rate + */ + case "CurrencyRate": + $a_answer=array(); + $a_answer['status']="NOK"; + $http=new HttpInput(); + try + { + $code=$http->get("p_code"); + if ( $code==-1) { + $a_answer['content']=1; + }else { + $a_answer['content']=$cn->get_value("select ch_value from v_currency_last_value where currency_id=$1", + [$code]); + } + $a_answer['status']="OK"; + } + catch (Exception $ex) + { + $a_answer['content']=$ex->getMessage(); + } + $jsson=json_encode($a_answer, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_NUMERIC_CHECK); + header('Content-Type: application/json;charset=utf-8'); + echo $jsson; + return; + + + break; + /* + * Get the currency code + */ + case "CurrencyCode": + $a_answer=array(); + $a_answer['status']="NOK"; + $http=new HttpInput(); + try + { + $code=$http->get("p_code"); + $a_answer['content']=$cn->get_value("select cr_code_iso||' ('||cr_name||')' from v_currency_last_value where currency_id=$1", + [$code]); + $a_answer['status']="OK"; + } + catch (Exception $ex) + { + $a_answer['content']=$ex->getMessage(); + } + $jsson=json_encode($a_answer, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_NUMERIC_CHECK); + header('Content-Type: application/json;charset=utf-8'); + echo $jsson; + return; + + + break; case "periode_change": $field=$http->get("field"); $type=$http->get("type"); diff --git a/html/js/acc_currency.js b/html/js/acc_currency.js index 356eef8df..51ff8ecc0 100644 --- a/html/js/acc_currency.js +++ b/html/js/acc_currency.js @@ -53,4 +53,93 @@ function CurrencyRateDelete(p_dossier, p_id) } }); +} +/** + * Update the field p_update with the rate from the currency + * @param DOMID p_code where the cr_code_iso will be selected + * @param DOMID p_update element to update + */ +function CurrencyUpdateValue(p_dossier,p_code,p_update) +{ + new Ajax.Request("ajax_misc.php",{ + method:"get", + asynchronous:false, + parameters:{p_code:$(p_code).value,gDossier:p_dossier,op:'CurrencyRate'}, + onSuccess:function (req) { + var answer=req.responseText.evalJSON(); + if ( answer.status == "OK") { + $(p_update).value=answer.content; + } else { + smoke.alert(answer.content); + } + } + }); +} +/** + * Update the field p_update with the code ISO from the currency + * @param DOMID p_code where the cr_code_iso will be selected + * @param DOMID p_update element to update + */ +function CurrencyUpdateCode(p_dossier,p_code,p_update) +{ + new Ajax.Request("ajax_misc.php",{ + method:"get", + parameters:{p_code:$(p_code).value,gDossier:p_dossier,op:'CurrencyCode'}, + onSuccess:function (req) { + var answer=req.responseText.evalJSON(); + if ( answer.status == "OK") { + $(p_update).innerHTML=answer.content; + } else { + smoke.alert(answer.content); + } + } + }); +} +/** + * Update the field Update with the amount in EUR + * @param DOMID p_rate where the rate is stored + * @param DOMID p_update element to update with the rate + */ +function CurrencyCompute(p_rate,p_update) +{ + var tvac=$('tvac').innerHTML; + + console.log("tvac= "+tvac); + if ( isNaN(tvac)) { + console.log("tva is nan" + tvac); + tvac=1; + } + var rate=$(p_rate).value; + console.log("rate = "+rate); + if ( isNaN(rate)) { + console.log("rate is nan" + rate); + rate=1; + } + var tot=tvac*rate; + tot=Math.round(tot*100)/100; + $(p_update).innerHTML=tot; + +} +/** + * + * @param {type} p_dossier + * @param {type} p_code + * @param {type} p_update + * @param {type} p_rate + * @param {type} p_eur_amount + * @returns {undefined} + */ +function LedgerCurrencyUpdate(p_dossier,p_code,p_update,p_rate,p_eur_amount) +{ + // Hide or show the row of the table with the amount in EUR + if ($(p_code).value != -1) { + $('row_currency').show(); + }else { + $('row_currency').hide(); + } + CurrencyUpdateValue(p_dossier,p_code,p_rate); + CurrencyUpdateCode(p_dossier,p_code,p_update); + // Compute all the fields + compute_all_ledger (); + } \ No newline at end of file diff --git a/html/js/acc_ledger.js b/html/js/acc_ledger.js index 3bbe15048..52aa5b7a0 100644 --- a/html/js/acc_ledger.js +++ b/html/js/acc_ledger.js @@ -488,6 +488,7 @@ function success_compute_ledger(request, json) g('htva_march' + ctl).value = rhtva; g('tvac_march' + ctl).value = rtvac; g('sum').show(); + CurrencyCompute('p_currency_rate','p_currency_euro'); refresh_ledger(); return; @@ -497,6 +498,7 @@ function success_compute_ledger(request, json) g('sum').show(); + CurrencyCompute('p_currency_rate','p_currency_euro'); if (g('e_march' + ctl + '_tva_amount').value == "" || g('e_march' + ctl + '_tva_amount').value == 0) { g('tva_march' + ctl).value = rtva; @@ -549,7 +551,7 @@ function compute_all_ledger() if (g('tvac')) g('tvac').innerHTML = Math.round(tvac * 100) / 100; - + } function clean_tva(p_ctl) diff --git a/include/class/acc_compute.class.php b/include/class/acc_compute.class.php index a2282a2a9..20c7ee7ca 100644 --- a/include/class/acc_compute.class.php +++ b/include/class/acc_compute.class.php @@ -65,7 +65,10 @@ class Acc_Compute 'amount_nd_rate'=>'amount_nd_rate', 'nd_vat_rate'=>'nd_vat_rate', 'amount_perso'=>'amount_perso', - 'amount_perso_rate'=>'amount_perso_rate' + 'amount_perso_rate'=>'amount_perso_rate', + 'amount_currency'=>'amount_currency', + 'amount_vat_currency'=>'amount_vat_currency', + 'currency_rate'=>'currency_rate' ); private $order; // check that the compute @@ -82,7 +85,19 @@ class Acc_Compute $this->order=0; $this->check=true; } - + + function convert_euro() + { + $local_amount=$this->amount; + $this->amount=bcmul($this->amount,$this->currency_rate); + $this->amount_currency=$local_amount; + } + function convert_euro_vat() + { + $local_amount=$this->amount_vat; + $this->amount_vat=bcmul($this->amount_vat,$this->currency_rate); + $this->amount_vat_currency=$local_amount; + } public function get_parameter($p_string) { if ( array_key_exists($p_string,self::$variable) ) @@ -109,12 +124,12 @@ class Acc_Compute { return var_export(self::$variable,true); } - function compute_vat() { if ( $this->check && $this->order != 0 ) throw new Exception ('ORDER NOT RESPECTED'); $this->amount_vat=bcmul($this->amount,$this->amount_vat_rate); $this->amount_vat=round($this->amount_vat,2); + $this->amount_currency=bcmul($this->amount_vat,$this->currency_rate); $this->order=1; } /*!\brief Compute the no deductible part of the amount, it reduce @@ -143,7 +158,7 @@ class Acc_Compute $this->nd_vat=bcdiv($this->nd_vat,100); $this->nd_vat=round($this->nd_vat,2); } - + function compute_ndded_vat() { if ( $this->check && $this->order > 4 ) throw new Exception ('ORDER NOT RESPECTED'); diff --git a/include/class/acc_currency.class.php b/include/class/acc_currency.class.php new file mode 100644 index 000000000..0e99cd958 --- /dev/null +++ b/include/class/acc_currency.class.php @@ -0,0 +1,120 @@ + + +require_once NOALYSS_INCLUDE."/database/v_currency_last_value_sql.class.php"; +/** + * @file + * @brief display currency , convert to euro , and save them if used + */ + +/** + * @class + * @brief display currency , convert to euro , and save them if used + */ +class Acc_Currency +{ + + private $cn; //!< database conx + private $currency; //!< v_currency_last_value_sql + + function __construct(Database $p_cn, $p_id=-1) + { + $this->cn=$p_cn; + $this->currency=new V_Currency_Last_Value_SQL($p_cn, $p_id); + } + + /** + * Retrieve a V_Currency_Last_Value_SQL thanks its iso_code + * @param string $p_iso + */ + function get_by_iso($p_iso) + { + $p_iso=trim(strtoupper($p_iso)); + $id=$this->cn->get_value("select currency_id from v_currency_last_value where cr_code_iso=$1", [$p_iso]); + if ($id!="") + { + $this->currency->setp("currency_id", $id); + $this->currency->load(); + } + } + + /** + * Retrieve a V_Currency_Last_Value_SQL thanks its id + * @param number $p_id + */ + function set_id($p_id) + { + $this->currency->setp("currency_id", $p_id); + $this->currency->load(); + } + /** + * Check if the record is found + * @return boolean + */ + function is_found() { + if ($this->currency->currency_id==-1) + { + return FALSE; + } + return TRUE; + } + /** + * return the rate of the currency + */ + function get_rate() + { + return $this->currency->getp("ch_value"); + + } + /** + * return the iso code of the currency + */ + function get_code() + { + return $this->currency->getp("cr_code_iso"); + + + } + /** + * return the id of the currency + */ + function get_id() + { + return $this->currency->getp("currency_id"); + + } + /** + * Create an object iselect to select the currency, + * @return \ISelect + */ + function select_currency() + { + $select=new ISelect('p_currency_code'); + $a_currency[0]=["value"=>-1,"label"=>"EUR"]; + $a_currency+=$this->cn->make_array("select currency_id,cr_code_iso from v_currency_last_value order by cr_code_iso"); + $select->value=$a_currency; + $select->selected=$this->currency->cr_code_iso; + + return $select; + } + + +} diff --git a/include/class/acc_ledger.class.php b/include/class/acc_ledger.class.php index f6254b13a..939b710a1 100644 --- a/include/class/acc_ledger.class.php +++ b/include/class/acc_ledger.class.php @@ -47,6 +47,8 @@ require_once NOALYSS_INCLUDE.'/class/acc_payment.class.php'; require_once NOALYSS_INCLUDE.'/class/acc_ledger_history.class.php'; //require_once NOALYSS_INCLUDE.'/class/print_ledger.class.php'; require_once NOALYSS_INCLUDE.'/lib/http_input.class.php'; +require_once NOALYSS_INCLUDE.'/class/acc_currency.class.php'; +require_once NOALYSS_INCLUDE.'/database/operation_currency_sql.class.php'; /** \file * @brief Class for jrn, class acc_ledger for manipulating the ledger @@ -2877,6 +2879,22 @@ class Acc_Ledger extends jrn_def_sql return FALSE; } + /** + * Create a select from value for currency and add javascript to update $p_currency_rate and + * $p_eur_amount + * @param string DOMID $p_currency_code + * @param string DOMID $p_currency_rate + * @param string DOMID $p_eur_amount + */ + function CurrencyInput($p_currency_code,$p_currency_rate,$p_eur_amount) + { + $currency = new Acc_Currency($this->db); + $select=$currency->select_currency(); + $select->javascript=sprintf('onchange="LedgerCurrencyUpdate(\'%s\',\'%s\',\'%s\',\'%s\',\'%s\');$(\'update_p_currency_rate\').innerHTML=$(\'p_currency_rate\').value;"', + Dossier::id(),$select->name,$p_currency_code,$p_currency_rate,$p_eur_amount); + return $select; + } + } ?> diff --git a/include/class/acc_ledger_purchase.class.php b/include/class/acc_ledger_purchase.class.php index b40122282..6e53be9c7 100644 --- a/include/class/acc_ledger_purchase.class.php +++ b/include/class/acc_ledger_purchase.class.php @@ -42,6 +42,7 @@ require_once NOALYSS_INCLUDE.'/class/acc_ledger_info.class.php'; require_once NOALYSS_INCLUDE.'/class/acc_ledger_fin.class.php'; require_once NOALYSS_INCLUDE.'/class/stock_goods.class.php'; + /*!\brief Handle the ledger of purchase, * * @@ -486,6 +487,8 @@ class Acc_Ledger_Purchase extends Acc_Ledger [bon_comm] => [other_info] => [record] =>Enregistrement + [p_currency_code]=> id currency + [p_currency_rate]=>rate used ) \endcode *\return string @@ -539,7 +542,11 @@ class Acc_Ledger_Purchase extends Acc_Ledger $tot_tva_nd=0; $tot_tva_ndded=0; $tot_tva_reversed=0; - $tva=array(); + $tva=array(); + + // find the currency from v_currency_last_value + $currency_rate_ref=new Acc_Currency($this->db, $p_currency_code); + /* Save all the items without vat and no deductible vat and expense*/ for ($i=0;$i< $nb_item;$i++) { @@ -568,12 +575,16 @@ class Acc_Ledger_Purchase extends Acc_Ledger $acc_operation->periode=$tperiode; $acc_operation->qcode=""; $amount_4=bcmul(${'e_march'.$i.'_price'},${'e_quant'.$i}); + /* We have to compute all the amount thanks Acc_Compute */ $amount=round($amount_4,2); $acc_amount=new Acc_Compute(); $acc_amount->check=false; $acc_amount->set_parameter('amount',$amount); + // Set the currency rate + $acc_amount->set_parameter("currency_rate", $p_currency_rate); + $acc_amount->convert_euro(); // Compute VAT or take the given one if ( $g_parameter->MY_TVA_USE=='Y') @@ -581,14 +592,18 @@ class Acc_Ledger_Purchase extends Acc_Ledger $acc_amount->set_parameter('amount_vat_rate',$oTva->get_parameter('rate')); if ( strlen(trim(${'e_march'.$i.'_tva_amount'})) ==0 || ${'e_march'.$i.'_tva_amount'} == 0) { + // vat is in euro $acc_amount->compute_vat(); } else { - $acc_amount->amount_vat= ${'e_march'.$i.'_tva_amount'}; + // we convert the vat in euro + $acc_amount->set_parameter("amount_vat", ${'e_march'.$i.'_tva_amount'}); + $acc_amount->convert_euro_vat(); } + // convert amount in eur $tot_tva=bcadd($tot_tva,$acc_amount->amount_vat); } @@ -603,7 +618,7 @@ class Acc_Ledger_Purchase extends Acc_Ledger - $tot_amount=round(bcadd($tot_amount,$amount),2); + $tot_amount=round(bcadd($tot_amount,$acc_amount->amount),2); /* get the account and explode if necessary */ $sposte=$fiche->strAttribut(ATTR_DEF_ACCOUNT); @@ -617,14 +632,21 @@ class Acc_Ledger_Purchase extends Acc_Ledger { $poste_val=$sposte; } - if ( $g_parameter->MY_UPDLAB=='Y') + if ($g_parameter->MY_UPDLAB=='Y') + { $acc_operation->desc=strip_tags(${"e_march".$i."_label"}); + } else + { $acc_operation->desc=null; + } $acc_operation->poste=$poste_val; $acc_operation->amount=$acc_amount->amount; $acc_operation->qcode=${"e_march".$i}; - if( $acc_amount->amount > 0 ) $tot_debit=bcadd($tot_debit,$acc_amount->amount); + if ($acc_amount->amount>0) + { + $tot_debit=bcadd($tot_debit, $acc_amount->amount); + } $j_id=$acc_operation->insert_jrnx(); /* insert ND */ @@ -636,11 +658,12 @@ class Acc_Ledger_Purchase extends Acc_Ledger { $tva_item=$acc_amount->amount_vat; - if (isset($tva[$idx_tva] ) ) - $tva[$idx_tva]=bcadd($tva[$idx_tva],$tva_item); + if (isset($tva[$idx_tva])) + { + $tva[$idx_tva]=bcadd($tva[$idx_tva], $tva_item); + } else $tva[$idx_tva]=$tva_item; - } /* Save the stock */ /* if the quantity is < 0 then the stock increase (return of @@ -660,6 +683,7 @@ class Acc_Ledger_Purchase extends Acc_Ledger { // for each item, insert into operation_analytique */ $op=new Anc_Operation($this->db); + $op->set_currency_rate($p_currency_rate); $op->oa_group=$group; $op->j_id=$j_id; $op->oa_date=$e_date; @@ -669,6 +693,7 @@ class Acc_Ledger_Purchase extends Acc_Ledger } // insert into quant_purchase //----- + $price_euro=bcmul(${'e_march'.$i.'_price'}, $p_currency_rate); if ( $g_parameter->MY_TVA_USE=='Y') { @@ -678,7 +703,7 @@ class Acc_Ledger_Purchase extends Acc_Ledger ,$j_id /* 2 */ ,${"e_march".$i} /* 3 */ ,${"e_quant".$i} /* 4 */ - ,round($amount,2) /* 5 */ + ,round($acc_amount->amount,2) /* 5 */ ,$acc_amount->amount_vat /* 6 */ ,$oTva->get_parameter('id') /* 7 */ ,$acc_amount->amount_nd /* 8 */ @@ -687,20 +712,21 @@ class Acc_Ledger_Purchase extends Acc_Ledger ,$acc_amount->amount_perso /* 11 */ ,$e_client /* 12 */ , $acc_amount->amount_unpaid /*13*/ - ,${'e_march'.$i.'_price'} /* 14 */ + ,$price_euro /* 14 */ )); } else { + $acc_amount->amount_vat=0; $r=$this->db->exec_sql("select insert_quant_purchase ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14)", array( null /*1*/ ,$j_id /* 2 */ ,${"e_march".$i} /* 3 */ ,${"e_quant".$i} /* 4 */ - ,round($amount,2) /* 5 */ + ,round($acc_amount->$amount,2) /* 5 */ ,0 /* 6 */ ,null/* 7 */ ,$acc_amount->amount_nd /* 8 */ @@ -709,10 +735,19 @@ class Acc_Ledger_Purchase extends Acc_Ledger ,$acc_amount->amount_perso /* 11 */ ,$e_client /* 12 */ , $acc_amount->amount_unpaid /*13*/ - ,${'e_march'.$i.'_price'} /* 14 */ + ,$price_euro /* 14 */ )); } - + /* + * Insert also in operation_currency + */ + $operation_currency=new Operation_currency_SQL($this->db); + $operation_currency->oc_amount=$acc_amount->amount_currency; + $operation_currency->oc_vat_amount=$acc_amount->amount_vat_currency; + $operation_currency->oc_price_unit=${'e_march'.$i.'_price'}; + $operation_currency->j_id=$j_id; + $operation_currency->insert(); + } // end loop : save all items /* save total customer */ $cust_amount=round(bcadd($tot_amount,$tot_tva),2); @@ -725,8 +760,10 @@ class Acc_Ledger_Purchase extends Acc_Ledger $acc_operation->type='c'; $acc_operation->periode=$tperiode; $acc_operation->qcode=${"e_client"}; - if ( $cust_amount < 0 ) - $tot_debit=bcadd($tot_debit,abs($cust_amount)); + if ($cust_amount<0) + { + $tot_debit=bcadd($tot_debit, abs($cust_amount)); + } $let_client=$acc_operation->insert_jrnx(); @@ -790,7 +827,13 @@ class Acc_Ledger_Purchase extends Acc_Ledger $acc_operation->periode=$tperiode; $acc_operation->pj=$e_pj; $acc_operation->mt=$mt; - $this->jr_id=$acc_operation->insert_jrn(); + $acc_operation->currency_id=$p_currency_code; + $acc_operation->currency_rate=$p_currency_rate; + $acc_operation->currency_rate_ref=$currency_rate_ref->get_rate(); + + if ( ! $this->jr_id=$acc_operation->insert_jrn() ) { + throw new Exception (_("Erreur de balance")); + } $this->pj=$acc_operation->set_pj(); // Set Internal code @@ -981,6 +1024,7 @@ class Acc_Ledger_Purchase extends Acc_Ledger public function input($p_array=null,$p_readonly=0) { global $g_parameter,$g_user; + $http=new HttpInput(); if ( $p_array != null ) extract($p_array, EXTR_SKIP); $flag_tva=$g_parameter->MY_TVA_USE; @@ -1301,6 +1345,18 @@ class Acc_Ledger_Purchase extends Acc_Ledger } $f_type=_('Fournisseur'); + + // Currency + $currency_select = $this->CurrencyInput("currency_code", "p_currency_rate" , "p_currency_euro"); + $currency_select->selected=$http->request('p_currency_code','string',-1); + + $currency_input=new INum("p_currency_rate"); + $currency_input->id="p_currency_rate"; + $currency_input->value=$http->request('p_currency_rate','string',1); + $currency_input->javascript='onchange="format_number(this,4);CurrencyCompute(\'p_currency_rate\',\'p_currency_euro\');"'; + + + // // Button for template operation // @@ -1341,19 +1397,18 @@ class Acc_Ledger_Purchase extends Acc_Ledger /*!@brief show the summary of the operation and propose to save it *@param array contains normally $_POST. It proposes also to save * the Analytic accountancy - * @param $p_summary true to confirm false, show only the result in RO + * @param $p_summary true to confirm false, show only the result in RO *@return string */ function confirm($p_array,$p_summary=false) { global $g_parameter; - extract ($p_array); + extract ($p_array,EXTR_SKIP); // we don't need to verify if we need only a feedback - if ( ! $p_summary ) - $this->verify($p_array) ; - - $anc=null; + if ( ! $p_summary ){$this->verify($p_array) ;} + + $anc=null; // to show a select list for the analytic // if analytic is op (optionnel) there is a blank line @@ -1583,33 +1638,59 @@ class Acc_Ledger_Purchase extends Acc_Ledger // Add the sum $decalage=($g_parameter->MY_TVA_USE == 'Y')?'':''; $tot = round(bcadd($tot_amount, $tot_tva), 2); + $str_tot=_('Totaux'); + $tot_eur=round(bcmul($tot, $p_currency_rate),2); + + // Get currency code + $str_code='EUR'; + if ( $p_currency_code != -1 ) { + $acc_currency=new Acc_Currency($this->db); + $acc_currency->set_id($p_currency_code); + $str_code=$acc_currency->get_code(); + } + // Format amount + $tot_amount=nbm($tot_amount); $tot_tva=nbm($tot_tva); $tot=nbm($tot); - $str_tot=_('Totaux'); - $tot_amount=nbm($tot_amount); if ( $g_parameter->MY_TVA_USE == 'Y') { $r.=<< {$decalage} - {$str_tot} + {$str_tot} {$str_code} - {$tot_tva} + {$tot_tva} {$tot_amount} - {$tot} + {$tot} {$str_code} + + + {$decalage} + + + + + + + + + + + {$tot_eur} EUR + + EOF; } else { $r.=<< {$decalage} - {$str_tot} + {$str_tot} {$str_code} {$tot_amount} @@ -1618,12 +1699,24 @@ EOF; - {$tot} + {$tot} {$str_code} + + + {$decalage} + + + + + + + + {$tot} {$str_code} + + EOF; } - $r.=''; $r.='

'; if ( $g_parameter->MY_ANALYTIC!='nu' && !$p_summary) // use of AA @@ -1662,6 +1755,7 @@ EOF; $r.=HtmlInput::hidden('jrn_type',$jrn_type); $r.=HtmlInput::hidden('e_pj',$e_pj); $r.=HtmlInput::hidden('e_pj_suggest',$e_pj_suggest); + $r.=HtmlInput::post_to_hidden(['p_currency_rate','p_currency_code']); $mt=microtime(true); $r.=HtmlInput::hidden('mt',$mt); @@ -1686,7 +1780,7 @@ EOF; } /** - * + * Payment method */ if ( $e_mp!=0 && strlen (trim (${'e_mp_qcode_'.$e_mp})) != 0 ) { diff --git a/include/class/acc_ledger_sold.class.php b/include/class/acc_ledger_sold.class.php index b94d0e8ce..b28e3abe3 100644 --- a/include/class/acc_ledger_sold.class.php +++ b/include/class/acc_ledger_sold.class.php @@ -282,6 +282,8 @@ class Acc_Ledger_Sold extends Acc_Ledger { $tot_debit = 0; $this->db->start(); $tva = array(); + // find the currency from v_currency_last_value + $currency_rate_ref=new Acc_Currency($this->db, $p_currency_code); /* Save all the items without vat */ for ($i = 0; $i < $nb_item; $i++) { $n_both = 0; @@ -291,8 +293,12 @@ class Acc_Ledger_Sold extends Acc_Ledger { /* First we save all the items without vat */ $fiche = new Fiche($this->db); $fiche->get_by_qcode(${"e_march" . $i}); - $amount = bcmul(${'e_march' . $i . '_price'}, ${'e_quant' . $i}); - $tot_amount = round(bcadd($tot_amount, $amount),2); + $amount_currency = bcmul(${'e_march' . $i . '_price'}, ${'e_quant' . $i}); + + // convert amount to currency + $amount=bcmul($amount_currency,$p_currency_rate); + + $tot_amount = bcadd($tot_amount, $amount); $acc_operation = new Acc_Operation($this->db); $acc_operation->date = $e_date; $sposte = $fiche->strAttribut(ATTR_DEF_ACCOUNT); @@ -311,14 +317,20 @@ class Acc_Ledger_Sold extends Acc_Ledger { $acc_operation->jrn = $p_jrn; $acc_operation->type = 'c'; $acc_operation->periode = $tperiode; - if ($g_parameter->MY_UPDLAB == 'Y') - $acc_operation->desc = strip_tags(${"e_march" . $i . "_label"}); + if ($g_parameter->MY_UPDLAB=='Y') + { + $acc_operation->desc=strip_tags(${"e_march".$i."_label"}); + } else - $acc_operation->desc = null; + { + $acc_operation->desc=null; + } $acc_operation->qcode = ${"e_march" . $i}; - if ($amount < 0) - $tot_debit = bcadd($tot_debit, abs($amount)); + if ($amount<0) + { + $tot_debit=bcadd($tot_debit, abs($amount)); + } $j_id = $acc_operation->insert_jrnx(); @@ -326,26 +338,34 @@ class Acc_Ledger_Sold extends Acc_Ledger { /* Compute sum vat */ $oTva = new Acc_Tva($this->db); $idx_tva = ${'e_march' . $i . '_tva_id'}; - $tva_item = ${'e_march' . $i . '_tva_amount'}; + $tva_item_currency = ${'e_march' . $i . '_tva_amount'}; $oTva->set_parameter("id", $idx_tva); $oTva->load(); /* if empty then we need to compute it */ - if (trim($tva_item) == '' || ${'e_march'.$i.'_tva_amount'} == 0) { + if (trim($tva_item_currency) == '' || ${'e_march'.$i.'_tva_amount'} == 0) { /* retrieve tva */ $l = new Acc_Tva($this->db, $idx_tva); $l->load(); - $tva_item = bcmul($amount, $l->get_parameter('rate')); + $tva_item_currency = bcmul($amount, $l->get_parameter('rate')); } + $tva_item=bcmul($tva_item_currency,$p_currency_rate); + if (isset($tva[$idx_tva])) - $tva[$idx_tva]+=$tva_item; + { + $tva[$idx_tva]=bcadd($tva_item,$tva[$idx_tva]); + } else - $tva[$idx_tva] = $tva_item; + { + $tva[$idx_tva]=$tva_item; + } if ($oTva->get_parameter("both_side") == 0) { $tot_tva = round(bcadd($tva_item, $tot_tva), 2); } else { $n_both = $tva_item; - if ($n_both < 0) - $tot_debit = bcadd($tot_debit, abs($n_both)); + if ($n_both<0) + { + $tot_debit=bcadd($tot_debit, abs($n_both)); + } } } @@ -367,6 +387,7 @@ class Acc_Ledger_Sold extends Acc_Ledger { if ($g_parameter->MY_ANALYTIC != "nu") { // for each item, insert into operation_analytique */ $op = new Anc_Operation($this->db); + $op->set_currency_rate($p_currency_rate); $op->oa_group = $group; $op->j_id = $j_id; $op->oa_date = $e_date; @@ -374,6 +395,8 @@ class Acc_Ledger_Sold extends Acc_Ledger { $op->oa_description = sql_string($e_comm); $op->save_form_plan($_POST, $i, $j_id); } + + $price_euro=bcmul(${'e_march'.$i.'_price'}, $p_currency_rate); if ($g_parameter->MY_TVA_USE == 'Y') { /* save into quant_sold */ $r = $this->db->exec_sql("select insert_quant_sold ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)", array(null, /* 1 */ @@ -385,7 +408,7 @@ class Acc_Ledger_Sold extends Acc_Ledger { $idx_tva, /* 7 */ $e_client, /* 8 */ $n_both, /* 9 */ - ${'e_march' . $i . '_price'} /* Price /unit */ + $price_euro/* Price /unit */ )); } else { $r = $this->db->exec_sql("select insert_quant_sold ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10) ", array(null, /* 1 */ @@ -397,9 +420,18 @@ class Acc_Ledger_Sold extends Acc_Ledger { null, $e_client, 0, /* 9 */ - ${'e_march' . $i . '_price'} /* Price /unit */ + $price_euro /* Price /unit */ )); } // if ( $g_parameter->MY_TVA_USE=='Y') { + /* + * Insert also in operation_currency + */ + $operation_currency=new Operation_currency_SQL($this->db); + $operation_currency->oc_amount=$amount_currency; + $operation_currency->oc_vat_amount=$tva_item_currency; + $operation_currency->oc_price_unit=${'e_march'.$i.'_price'}; + $operation_currency->j_id=$j_id; + $operation_currency->insert(); }// end loop : save all items /* save total customer */ @@ -413,8 +445,10 @@ class Acc_Ledger_Sold extends Acc_Ledger { $acc_operation->type = 'd'; $acc_operation->periode = $tperiode; $acc_operation->qcode = ${"e_client"}; - if ($cust_amount > 0) - $tot_debit = bcadd($tot_debit, $cust_amount); + if ($cust_amount>0) + { + $tot_debit=bcadd($tot_debit, $cust_amount); + } $let_tiers = $acc_operation->insert_jrnx(); @@ -439,8 +473,10 @@ class Acc_Ledger_Sold extends Acc_Ledger { $acc_operation->jrn = $p_jrn; $acc_operation->type = 'c'; $acc_operation->periode = $tperiode; - if ($value < 0) - $tot_debit = bcadd($tot_debit, abs($value)); + if ($value<0) + { + $tot_debit=bcadd($tot_debit, abs($value)); + } $acc_operation->insert_jrnx(); // if TVA is on both side, we deduce it immediately @@ -472,8 +508,13 @@ class Acc_Ledger_Sold extends Acc_Ledger { $acc_operation->periode = $tperiode; $acc_operation->pj = $e_pj; $acc_operation->mt = $mt; - - $this->jr_id = $acc_operation->insert_jrn(); + $acc_operation->currency_id=$p_currency_code; + $acc_operation->currency_rate=$p_currency_rate; + $acc_operation->currency_rate_ref=$currency_rate_ref->get_rate(); + + if ( ! $this->jr_id=$acc_operation->insert_jrn() ) { + throw new Exception (_("Erreur de balance")); + } $this->pj = $acc_operation->set_pj(); @@ -609,7 +650,7 @@ class Acc_Ledger_Sold extends Acc_Ledger { 'Erreur dans l\'enregistrement ' . __FILE__ . ':' . __LINE__ . ' ' . $e->getMessage(); - echo $e->getTrace(); + echo $e->getTraceAsString(); $this->db->rollback(); throw new Exception ($e); @@ -634,7 +675,9 @@ class Acc_Ledger_Sold extends Acc_Ledger { // don't need to verify for a summary if (!$p_summary) + { $this->verify($p_array); + } $anc = null; // to show a select list for the analytic & VAT USE // if analytic is op (optionnel) there is a blank line @@ -839,16 +882,29 @@ class Acc_Ledger_Sold extends Acc_Ledger { // Add the sum $decalage=($g_parameter->MY_TVA_USE == 'Y')?'':''; $tot = round(bcadd($tot_amount, $tot_tva), 2); + $tot_eur=round(bcmul($tot, $p_currency_rate),2); $tot_tva=nbm($tot_tva); $tot=nbm($tot); $str_tot=_('Totaux'); + + // Get currency code + $str_code='EUR'; + if ( $p_currency_code != -1 ) { + $acc_currency=new Acc_Currency($this->db); + $acc_currency->set_id($p_currency_code); + $str_code=$acc_currency->get_code(); + } + // Format amount $tot_amount=nbm($tot_amount); + $tot_tva=nbm($tot_tva); + $tot=nbm($tot); + if ( $g_parameter->MY_TVA_USE=="Y") { $r.=<< {$decalage} - {$str_tot} + {$str_tot} {$str_code} {$tot_tva} @@ -857,15 +913,31 @@ if ( $g_parameter->MY_TVA_USE=="Y") { {$tot_amount} - {$tot} + {$tot} {$str_code} + + + {$decalage} + + + + + + + + + + + {$tot_eur} EUR + + EOF; } else { $r.=<< {$decalage} - {$str_tot} + {$str_tot} {$str_code} @@ -876,6 +948,19 @@ EOF; {$tot} + + + {$decalage} + + + + + + + + {$tot} {$str_code} + + EOF; } $r.=''; @@ -910,9 +995,12 @@ EOF; $r.=HtmlInput::hidden('p_jrn', $p_jrn); $mt = microtime(true); $r.=HtmlInput::hidden('mt', $mt); - + $r.=HtmlInput::post_to_hidden(['p_currency_rate','p_currency_code']); + if (isset($period)) + { $r.=HtmlInput::hidden('period', $period); + } /* \todo comment les types hidden gérent ils des contenus avec des quotes, double quote ou < > ??? */ $r.=HtmlInput::hidden('e_comm', $e_comm); $r.=HtmlInput::hidden('e_date', $e_date); @@ -1047,6 +1135,7 @@ EOF; global $g_parameter, $g_user; if ($p_array != null) extract($p_array, EXTR_SKIP); + $http=new HttpInput(); $flag_tva = $g_parameter->MY_TVA_USE; /* Add button */ @@ -1328,6 +1417,18 @@ EOF; $array[$i]['quantity'] = $Quantity->input("e_quant" . $i, $quant); }// foreach article $f_type = _('Client'); + + // Currency + $currency_select = $this->CurrencyInput("currency_code", "p_currency_rate" , "p_currency_euro"); + $currency_select->selected=$http->request('p_currency_code','string',-1); + + $currency_input=new INum("p_currency_rate"); + $currency_input->id="p_currency_rate"; + $currency_input->value=$http->request('p_currency_rate','string',1); + $currency_input->javascript='onchange="format_number(this,4);CurrencyCompute(\'p_currency_rate\',\'p_currency_euro\');"'; + + + // // Button for template operation // diff --git a/include/class/acc_operation.class.php b/include/class/acc_operation.class.php index 8c2677166..cf9237636 100644 --- a/include/class/acc_operation.class.php +++ b/include/class/acc_operation.class.php @@ -46,7 +46,10 @@ class Acc_Operation var $amount; /*!< amount of the operatoin */ var $grpt; /*!< the group id */ var $date_paid; - var $jr_optype; /*!< type of operation :NOR,CLO,EXT,OPE + var $jr_optype; /*!< type of operation :NOR,CLO,EXT,OPE */ + var $currency_rate; /*< currency rate used */ + var $currency_id; /*< currency id */ + var $currency_rate_ref; /*< currency rate in the table currency*/ /*! * \brief constructor set automatically the attributes user and periode * \param $p_cn the databse connection @@ -60,6 +63,9 @@ class Acc_Operation $this->periode=$g_user->get_periode(); $this->jr_id=0; $this->jr_optype="NOR"; + $this->currency_rate=1; + $this->currency_rate_ref=1; + $this->currency_id=NULL; } /** *@brief retrieve the grpt_id from jrn for a jr_id @@ -181,7 +187,7 @@ class Acc_Operation $this->type=($this->type=='d')?'c':'d'; } if ( DEBUG ) { - echo "insert_jrn = {$this->amount}
"; + echo "insert_jrnx = {$this->amount} type {$this->type}
"; } $this->amount=abs($this->amount); $debit=($this->type=='c')?'false':'true'; @@ -199,7 +205,7 @@ class Acc_Operation $this->periode, //$8 $this->qcode, // $9 $this->desc)); //$10 - if ( $Res===false) return $Res; + if ( $Res===FALSE) return FALSE; $this->jrnx_id=$this->db->get_current_seq('s_jrn_op'); return $this->jrnx_id; @@ -293,13 +299,17 @@ class Acc_Operation // if amount == -1then the triggers will throw an error // $Res=$this->db->exec_sql("insert into jrn (jr_def_id,jr_montant,jr_comment,". - "jr_date,jr_ech,jr_grpt_id,jr_tech_per,jr_mt,jr_optype) values (". + "jr_date,jr_ech,jr_grpt_id,jr_tech_per,jr_mt,jr_optype,currency_id,currency_rate,currency_rate_ref) values (". "$1,$2,$3,". - "to_date($4,'DD.MM.YYYY'),to_date($5,'DD.MM.YYYY'),$6,$7,$8,$9)", + "to_date($4,'DD.MM.YYYY'),to_date($5,'DD.MM.YYYY'),$6,$7,$8,$9,$10,$11,$12)", array ($this->jrn, $this->amount,$p_comment, - $this->date,$echeance,$this->grpt,$this->periode,$this->mt,$this->jr_optype) + $this->date,$echeance,$this->grpt,$this->periode,$this->mt,$this->jr_optype, + $this->currency_id,$this->currency_rate,$this->currency_rate_ref) ); - if ( $Res == false) return false; + if ($Res==FALSE) + { + return FALSE; + } $this->jr_id=$this->db->get_current_seq('s_jrn'); return $this->jr_id; } diff --git a/include/class/anc_operation.class.php b/include/class/anc_operation.class.php index 6e1ecef98..1c57accab 100644 --- a/include/class/anc_operation.class.php +++ b/include/class/anc_operation.class.php @@ -50,12 +50,25 @@ class Anc_Operation var $oa_date; /*!< equal to j_date if j_id is not null */ var $pa_id; /*!< the plan analytique id */ var $card; /*!< Card linked to the operation */ + private $currency_rate; /*!< currency rate */ /** * In the case, the amount comes from a ND VAT, the variable * contents the jrnx.j_id of the source which was used to compute * the amount */ - var $oa_jrnx_id_source; + var $oa_jrnx_id_source; + + public function get_currency_rate() + { + return $this->currency_rate; + } + + public function set_currency_rate($currency_rate) + { + $this->currency_rate=$currency_rate; + return $this; + } + /** * @brief signed of the amount */ @@ -73,6 +86,7 @@ class Anc_Operation $this->has_data=0; $this->in_div=""; $this->card=""; + $this->currency_rate=1; } /*!\brief add a row to the table operation_analytique * \note if $this->oa_group == 0 then a sequence id will be computed for @@ -548,14 +562,18 @@ class Anc_Operation $table_id="t".$p_seq; $hidden=new IHidden(); - $readonly=($p_mode==1)?false:true; + $readonly=($p_mode==1)?false:true; - $result.=$hidden->input('amount_'.$table_id,$p_amount); - if ( $p_mode==1 ) + if ($p_mode==1) + { + $result.=$hidden->input('amount_'.$table_id,$p_amount); $result.=''; + } else + { $result.='
'; - $result.="".$plan->header().""; + } + $result.="".$plan->header().""; /* compute the number of rows */ $nb_row=(isset($val[$p_seq]))?count($val[$p_seq]):1; @@ -597,16 +615,20 @@ class Anc_Operation $select->readOnly=true; } if ($p_mode==1) + { $result.=''; + } else + { $result.=''; + } $count++; } $value=new INum(); $value->javascript='onchange="format_number(this);anc_refresh_remain(\''.$this->in_div.$table_id.'\',\''.$p_seq.'\')"'; - $value->name="val[".$p_seq."][]"; + $value->name=($readonly)?"ro"."val[".$p_seq."][]":"val[".$p_seq."][]"; $value->size=6; $value->value=(isset($val[$p_seq][$i]))?$val[$p_seq][$i]:abs($p_amount); $value->value=round($value->value,2); @@ -701,6 +723,8 @@ class Anc_Operation $op->j_id=$p_j_id; $ratio=bcdiv($val[$p_item][$row],${"amount_t".$p_item}); $amount= bcmul($p_nd, $ratio); + // convert to euro + $amount=bcmul($amount,$this->currency_rate); $op->oa_amount=round($amount,2); $op->oa_debit=$this->oa_debit; $op->oa_date=$this->oa_date; @@ -730,7 +754,7 @@ class Anc_Operation } } /*!\brief it called for each item, the data are taken from $p_array - * data and set before in this. + * data and set before in this. Amount will be transformed thanks the $this->currency_rate; * \param $p_item if the item nb for each item (purchase or selling * merchandise) * \param $p_array structure @@ -780,7 +804,8 @@ class Anc_Operation $op->po_id=$hplan[$p_item][$e]; $op->oa_group=$this->oa_group; $op->j_id=$p_j_id; - $op->oa_amount=$val[$p_item][$row]; + // convert oa_amount to EUR + $op->oa_amount=bcmul($val[$p_item][$row],$this->currency_rate); $op->oa_debit=$this->oa_debit; $op->oa_date=$this->oa_date; diff --git a/include/compta_ach.inc.php b/include/compta_ach.inc.php index 889137875..5ad7e6ea2 100644 --- a/include/compta_ach.inc.php +++ b/include/compta_ach.inc.php @@ -120,7 +120,7 @@ if (isset($_POST['view_invoice'])) '; diff --git a/include/compta_ven.inc.php b/include/compta_ven.inc.php index d5109ea7b..756466904 100644 --- a/include/compta_ven.inc.php +++ b/include/compta_ven.inc.php @@ -128,7 +128,7 @@ $p_msg=""; '; diff --git a/include/database/operation_currency_sql.class.php b/include/database/operation_currency_sql.class.php new file mode 100644 index 000000000..f624964f8 --- /dev/null +++ b/include/database/operation_currency_sql.class.php @@ -0,0 +1,67 @@ +table="public.operation_currency"; + $this->primary_key="id"; + /* + * List of columns + */ + $this->name=array( + "id"=>"id" + , "oc_amount"=>"oc_amount" + , "oc_vat_amount"=>"oc_vat_amount" + , "oc_price_unit"=>"oc_price_unit" + , "j_id"=>"j_id" + ); + /* + * Type of columns + */ + $this->type=array( + "id"=>"numeric" + , "oc_amount"=>"numeric" + , "oc_vat_amount"=>"numeric" + , "oc_price_unit"=>"numeric" + , "j_id"=>"numeric" + ); + + + $this->default=array( + "id"=>"auto" + ); + + $this->date_format="DD.MM.YYYY"; + parent::__construct($p_cn, $p_id); + } + +} diff --git a/include/template/form_ledger_detail.php b/include/template/form_ledger_detail.php index a6357d549..6c3543922 100644 --- a/include/template/form_ledger_detail.php +++ b/include/template/form_ledger_detail.php @@ -1,6 +1,7 @@

get_name()?>

@@ -60,7 +61,16 @@
+ + + +
montant
"._("montant")."
'.$select->input().''.$select->display().'
+ + + input()?> + change()?>EUR +
@@ -110,23 +120,50 @@ echo ''; ?> - - - - + + + + + + 0.0 - + 0.0 0.0 + + + + EUR + + + + + + + + + + + + + + - + + + diff --git a/sql/upgrade.sql b/sql/upgrade.sql index 54468f56d..29bfa60ef 100644 --- a/sql/upgrade.sql +++ b/sql/upgrade.sql @@ -17,6 +17,7 @@ CREATE TABLE public.currency ( CONSTRAINT currency_un UNIQUE (cr_code_iso) ); + -- Drop table -- DROP TABLE public.currency_history @@ -35,6 +36,8 @@ CREATE TABLE public.currency_history ( -- Ajouter commentaire sur colonne ALTER TABLE public.currency ADD cr_name varchar(80) NULL; +insert into currency (id,cr_code_iso,cr_name) values (-1,'EUR','EUR'); +insert into currency_history (ch_value,ch_from,currency_id) values (1,to_date('01.01.2000','DD.MM.YYYY'),-1); ALTER TABLE public.currency_history ADD CONSTRAINT currency_history_check CHECK (ch_value > 0) ; @@ -67,4 +70,31 @@ COMMENT ON COLUMN public.currency.cr_code_iso IS 'Code ISO' ; COMMENT ON COLUMN public.currency.cr_name IS 'Name of the currency' ; -insert into "parameter" values ('MY_CURRENCY','N'); \ No newline at end of file +insert into "parameter" values ('MY_CURRENCY','N'); + +-- Drop table + +-- DROP TABLE public.operation_currency + +CREATE TABLE public.operation_currency ( + id bigserial NOT NULL, + oc_amount numeric(6) NOT NULL, -- amount in currency + oc_vat_amount numeric(6) NULL DEFAULT 0, -- vat amount in currency + oc_price_unit numeric(6) NULL, -- unit price in currency + j_id int8 NOT NULL, -- fk to jrnx + CONSTRAINT operation_currency_pk PRIMARY KEY (id) +); + +ALTER TABLE public.operation_currency ADD CONSTRAINT operation_currency_jrnx_fk FOREIGN KEY (j_id) REFERENCES public.jrnx(j_id) ON DELETE CASCADE ON UPDATE CASCADE; + +-- Column comments + +COMMENT ON COLUMN public.operation_currency.oc_amount IS 'amount in currency' ; +COMMENT ON COLUMN public.operation_currency.oc_vat_amount IS 'vat amount in currency' ; +COMMENT ON COLUMN public.operation_currency.oc_price_unit IS 'unit price in currency' ; +COMMENT ON COLUMN public.operation_currency.j_id IS 'fk to jrnx' ; + +alter table jrn add currency_id bigint default -1; +alter table jrn add currency_rate numeric (20,6) default 1; +alter table jrn add currency_rate_ref numeric(20,6) default 1; +ALTER TABLE public.jrn ADD CONSTRAINT jrn_currency_fk FOREIGN KEY (currency_id) REFERENCES public.currency(id) ON DELETE RESTRICT ON UPDATE RESTRICT;