30require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
31require_once DOL_DOCUMENT_ROOT.
'/multicurrency/class/currencyrate.class.php';
44 public $element =
'multicurrency';
49 public $table_element =
'multicurrency';
54 public $table_element_line =
"multicurrency_rate";
59 public $rates = array();
97 const MULTICURRENCY_APP_ENDPOINT_DEFAULT =
'https://api.currencylayer.com/live?access_key=__MULTICURRENCY_APP_KEY__&source=__MULTICURRENCY_APP_SOURCE__';
111 $urlendpoint =
getDolGlobalString(
"MULTICURRENCY_APP_ENDPOINT", self::MULTICURRENCY_APP_ENDPOINT_DEFAULT);
113 $this->urlendpoint = str_replace(array(
'__MULTICURRENCY_APP_KEY__',
'__MULTICURRENCY_APP_SOURCE__'), array($key, $source), $urlendpoint);
125 global $conf, $langs;
127 dol_syslog(
'MultiCurrency::create', LOG_DEBUG);
131 if (self::checkCodeAlreadyExists($this->code)) {
133 $this->errors[] = $langs->trans(
'multicurrency_code_already_added');
137 if (empty($this->entity) || $this->entity <= 0) {
138 $this->entity = $conf->entity;
143 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$this->table_element.
"(";
147 $sql .=
' date_create,';
149 $sql .=
') VALUES (';
150 $sql .=
" '".$this->db->escape($this->code).
"',";
151 $sql .=
" '".$this->db->escape($this->
name).
"',";
152 $sql .=
" ".((int) $this->entity).
",";
153 $sql .=
" '".$this->db->idate($now).
"',";
154 $sql .=
" ".((int) $user->id);
160 $resql = $this->db->query($sql);
163 $this->errors[] =
'Error '.$this->db->lasterror();
164 dol_syslog(
'MultiCurrency::create '.implode(
',', $this->errors), LOG_ERR);
168 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
169 $this->date_create = $now;
170 $this->fk_user = $user->id;
172 if (empty($notrigger)) {
173 $result = $this->call_trigger(
'CURRENCY_CREATE', $user);
181 $this->db->rollback();
198 public function fetch($id, $code =
null)
200 dol_syslog(
'MultiCurrency::fetch', LOG_DEBUG);
202 $sql =
"SELECT c.rowid, c.name, c.code, c.entity, c.date_create, c.fk_user";
203 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" AS c";
205 $sql .=
" WHERE c.code = '".$this->db->escape($code).
"'";
206 $sql .=
" AND c.entity IN (".getEntity($this->element).
")";
208 $sql .=
' WHERE c.rowid = '.((int) $id);
212 $resql = $this->db->query($sql);
215 $numrows = $this->db->num_rows($resql);
217 $obj = $this->db->fetch_object($resql);
219 $this->
id = $obj->rowid;
220 $this->
name = $obj->name;
221 $this->code = $obj->code;
222 $this->entity = $obj->entity;
223 $this->date_create = $obj->date_create;
224 $this->fk_user = $obj->fk_user;
229 $this->db->free($resql);
237 $this->errors[] =
'Error '.$this->db->lasterror();
238 dol_syslog(
'MultiCurrency::fetch '.implode(
',', $this->errors), LOG_ERR);
251 $sql =
"SELECT cr.rowid";
252 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element_line.
" as cr";
253 $sql .=
" WHERE cr.entity IN (".getEntity($this->element).
")";
254 $sql .=
" AND cr.fk_multicurrency = ".((int) $this->
id);
255 $sql .=
" ORDER BY cr.date_sync DESC";
257 $this->rates = array();
260 $resql = $this->db->query($sql);
262 $num = $this->db->num_rows($resql);
264 while ($obj = $this->db->fetch_object($resql)) {
266 $rate->fetch($obj->rowid);
268 $this->rates[] = $rate;
270 $this->db->free($resql);
274 $this->errors[] =
'Error '.$this->db->lasterror();
275 dol_syslog(
'MultiCurrency::fetchAllCurrencyRate '.implode(
',', $this->errors), LOG_ERR);
292 dol_syslog(
'MultiCurrency::update', LOG_DEBUG);
296 $this->code = trim($this->code);
299 if (empty($this->code)) {
301 dol_syslog(
'MultiCurrency::update $this->code can not be empty', LOG_ERR);
307 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element.
" SET";
308 $sql .=
" name = '".$this->db->escape($this->
name).
"',";
309 $sql .=
" code = '".$this->db->escape($this->code).
"'";
310 $sql .=
" WHERE rowid = ".((int) $this->
id);
314 $resql = $this->db->query($sql);
317 $this->errors[] =
'Error '.$this->db->lasterror();
318 dol_syslog(
'MultiCurrency::update '.implode(
',', $this->errors), LOG_ERR);
321 if (!$error && empty($notrigger)) {
322 $result = $this->call_trigger(
'CURRENCY_MODIFY', $user);
330 $this->db->rollback();
347 public function delete(
User $user, $notrigger = 0)
349 dol_syslog(
'MultiCurrency::delete', LOG_DEBUG);
355 if (empty($notrigger)) {
356 $result = $this->call_trigger(
'CURRENCY_DELETE', $user);
366 $this->errors[] =
'Error '.$this->db->lasterror();
367 dol_syslog(
'Currency::delete '.implode(
',', $this->errors), LOG_ERR);
370 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
371 $sql .=
" WHERE rowid = ".((int) $this->
id);
374 $resql = $this->db->query($sql);
377 $this->errors[] =
'Error '.$this->db->lasterror();
378 dol_syslog(
'MultiCurrency::delete '.implode(
',', $this->errors), LOG_ERR);
384 $this->db->rollback();
403 foreach ($this->rates as &$rate) {
404 if ($rate->delete($user) <= 0) {
423 $currencyRate->rate = (float)
price2num($rate);
425 if ($currencyRate->create($user, $this->id) > 0) {
426 $this->rate = $currencyRate;
430 $this->errors = $currencyRate->errors;
447 $currency->code = $code;
448 $currency->name = $code;
450 $sql =
"SELECT label FROM ".MAIN_DB_PREFIX.
"c_currencies WHERE code_iso = '".$this->db->escape($code).
"'";
453 $resql = $this->db->query($sql);
454 if ($resql && ($line = $this->db->fetch_object($resql))) {
455 $currency->name = $line->label;
458 if ($currency->create($user) > 0) {
459 $currency->addRate($rate);
489 $sql =
"SELECT cr.rowid";
490 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element_line.
" as cr";
491 $sql .=
" WHERE cr.entity IN (".getEntity($this->element).
")";
492 $sql .=
" AND cr.fk_multicurrency = ".((int) $this->
id);
493 $sql .=
" AND cr.date_sync = (SELECT MAX(cr2.date_sync) FROM ".MAIN_DB_PREFIX.$this->table_element_line.
" AS cr2";
494 $sql .=
" WHERE cr2.entity IN (".getEntity($this->element).
") AND cr2.fk_multicurrency = ".((int) $this->
id).
")";
498 $resql = $this->db->query($sql);
499 if ($resql && ($obj = $this->db->fetch_object($resql))) {
501 return $this->rate->fetch($obj->rowid);
519 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.
"multicurrency WHERE code = '".$dbs->escape($code).
"' AND entity = ".((int) $conf->entity);
522 $resql = $dbs->query($sql);
523 if ($resql && $obj = $dbs->fetch_object($resql)) {
542 $sql1 =
"SELECT m.rowid, mc.rate FROM ".MAIN_DB_PREFIX.
"multicurrency m";
543 $sql1 .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'multicurrency_rate mc ON (m.rowid = mc.fk_multicurrency)';
544 $sql1 .=
" WHERE m.code = '".$dbs->escape($code).
"'";
545 $sql1 .=
" AND m.entity IN (".getEntity(
'multicurrency').
")";
547 if (
getDolGlobalString(
'MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE') && !empty($date_document)) {
549 $sql2 .=
" AND mc.date_sync <= '".$dbs->idate(
dol_mktime(23, 59, 59, $tmparray[
'mon'], $tmparray[
'mday'], $tmparray[
'year'],
true)).
"'";
551 $sql3 =
" ORDER BY mc.date_sync DESC LIMIT 1";
554 $resql = $dbs->query($sql1.$sql2.$sql3);
556 if ($resql && $obj = $dbs->fetch_object($resql)) {
557 return array($obj->rowid, $obj->rate);
560 $resql = $dbs->query($sql1.$sql3);
561 if ($resql && $obj = $dbs->fetch_object($resql)) {
562 return array($obj->rowid, $obj->rate);
582 if (!is_null($invoice_rate)) {
583 $multicurrency_tx = $invoice_rate;
586 $multicurrency_tx = $tmparray[
'invoice_multicurrency_tx'];
589 if ($multicurrency_tx) {
590 if ($way ==
'dolibarr') {
591 return (
float)
price2num($amount * $multicurrency_tx,
'MU');
593 return (
float)
price2num($amount / $multicurrency_tx,
'MU');
611 $sql =
"SELECT multicurrency_tx, multicurrency_code";
612 $sql .=
" FROM ".MAIN_DB_PREFIX.$db->sanitize($table);
613 $sql .=
" WHERE rowid = ".((int) $fk_facture);
616 $resql = $db->query($sql);
617 if ($resql && ($line = $db->fetch_object($resql))) {
618 return array(
'invoice_multicurrency_tx' => $line->multicurrency_tx,
'invoice_multicurrency_code' => $line->multicurrency_code);
637 $alternate_source =
'USD'.getDolCurrency();
638 if (!empty($TRate->$alternate_source)) {
639 $coef = 1 / $TRate->$alternate_source;
640 foreach ($TRate as $attr => &$rate) {
643 $TRate->USDUSD = $coef;
662 public function syncRates($nu = 0, $addifnotfound = 0, $mode =
"")
667 if ($mode ==
"cron") {
668 $this->output = $langs->trans(
'Use of API for currency update is disabled by option MULTICURRENCY_DISABLE_SYNC_CURRENCYLAYER');
670 setEventMessages($langs->trans(
'Use of API for currency update is disabled by option MULTICURRENCY_DISABLE_SYNC_CURRENCYLAYER'),
null,
'errors');
675 include_once DOL_DOCUMENT_ROOT.
'/core/lib/geturl.lib.php';
677 $urlendpoint = $this->urlendpoint;
679 dol_syslog(
"Call url endpoint ".$urlendpoint);
683 $resget =
getURLContent($urlendpoint,
'GET',
'', 1, $addheaders);
690 if (!empty($resget[
'content'])) {
691 $response = $resget[
'content'];
692 $response = json_decode($response);
694 if ($response->success) {
695 $TRate = $response->quotes;
700 foreach ($TRate as $currency_code => $rate) {
701 $code = substr($currency_code, 3, 3);
703 if ($obj->fetch(0, $code) > 0) {
704 $obj->updateRate($rate);
705 } elseif ($addifnotfound) {
711 if ($mode ==
"cron") {
716 if (isset($response->error->info)) {
717 $error_info_syslog = $response->error->info;
718 $error_info = $error_info_syslog;
720 $error_info_syslog = json_encode($response);
721 if (empty($resget[
'content'])) {
722 $error_info =
"No error information found (see syslog)";
724 $error_info = $resget[
'content'];
728 dol_syslog(
"Failed to call endpoint ".$error_info_syslog, LOG_WARNING);
730 $this->output = $langs->trans(
'multicurrency_syncronize_error', $error_info);
735 $this->output = $resget[
'curl_error_msg'];
750 if ($currencytmp->fetch(0, $code) > 0) {
Parent class of all other business classes (invoices, contracts, proposals, orders,...
Class to manage Dolibarr database access.
static getInvoiceRate($fk_facture, $table='facture')
Get current invoite rate.
getRate()
Fetch CurrencyRate object in $this->rate.
static getIdAndTxFromCode($dbs, $code, $date_document=0)
Get id and rate of currency from code.
update(User $user, $notrigger=0)
Update object into database.
syncRates($nu=0, $addifnotfound=0, $mode="")
Sync rates from API.
fetchAllCurrencyRate()
Load all rates in object from the database.
static getAmountConversionFromInvoiceRate($fk_facture, $amount, $way='dolibarr', $table='facture', $invoice_rate=null)
Get the conversion of amount with invoice rate.
checkCodeAlreadyExists($code)
Check in database if the current code already exists.
updateRate($rate)
Add new entry into llx_multicurrency_rate.
static getIdFromCode($dbs, $code)
Get id of currency from code.
__construct(DoliDB $db)
Constructor.
deleteRates()
Delete rates in database.
create(User $user, $notrigger=0)
Create object into database.
addRateFromDolibarr($code, $rate)
Try get label of code in llx_currency then add rate.
recalculRates(&$TRate)
With free account we can't set source to something else than US, to we recalculate all rates to force...
fetch($id, $code=null)
Load object in memory from the database.
addRate($rate)
Add a Rate into database.
Class to manage Dolibarr users.
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
getDolCurrency()
Return the main currency ('EUR', 'USD', ...)
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
getURLContent($url, $postorget='GET', $param='', $followlocation=1, $addheaders=array(), $allowedschemes=array('http', 'https'), $localurl=0, $ssl_verifypeer=-1, $timeoutconnect=0, $timeoutresponse=0, $otherCurlOptions=array())
Function to get a content from an URL (use proxy if proxy defined).
$conf db name
Only used if Module[ID]Name translation string is not found.