29 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
30 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobjectline.class.php';
44 public $element =
'multicurrency';
49 public $table_element =
'multicurrency';
54 public $table_element_line =
"multicurrency_rate";
59 public $rates = array();
118 global $conf, $langs;
120 dol_syslog(
'MultiCurrency::create', LOG_DEBUG);
124 if (self::checkCodeAlreadyExists($this->
code)) {
126 $this->errors[] = $langs->trans(
'multicurrency_code_already_added');
130 if (empty($this->entity) || $this->entity <= 0) {
131 $this->entity = $conf->entity;
136 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$this->table_element.
"(";
140 $sql .=
' date_create,';
142 $sql .=
') VALUES (';
143 $sql .=
" '".$this->db->escape($this->
code).
"',";
144 $sql .=
" '".$this->db->escape($this->
name).
"',";
145 $sql .=
" ".((int) $this->entity).
",";
146 $sql .=
" '".$this->db->idate($now).
"',";
147 $sql .=
" ".((int) $user->id);
153 $resql = $this->db->query(
$sql);
156 $this->errors[] =
'Error '.$this->db->lasterror();
157 dol_syslog(
'MultiCurrency::create '.join(
',', $this->errors), LOG_ERR);
161 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
162 $this->date_create = $now;
163 $this->fk_user = $user->id;
166 $result = $this->
call_trigger(
'CURRENCY_CREATE', $user);
174 $this->db->rollback();
191 public function fetch($id, $code =
null)
193 dol_syslog(
'MultiCurrency::fetch', LOG_DEBUG);
198 $sql .=
' c.rowid, c.name, c.code, c.entity, c.date_create, c.fk_user';
199 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' AS c';
201 $sql .=
' WHERE c.code = \''.$this->db->escape($code).
'\' AND c.entity =
'.$conf->entity;
203 $sql .= ' WHERE c.rowid =
'.((int) $id);
206 dol_syslog(__METHOD__, LOG_DEBUG);
207 $resql = $this->db->query($sql);
210 $numrows = $this->db->num_rows($resql);
212 $obj = $this->db->fetch_object($resql);
214 $this->id = $obj->rowid;
215 $this->name = $obj->name;
216 $this->code = $obj->code;
217 $this->entity = $obj->entity;
218 $this->date_create = $obj->date_create;
219 $this->fk_user = $obj->fk_user;
221 $this->fetchAllCurrencyRate();
224 $this->db->free($resql);
232 $this->errors[] = 'Error
'.$this->db->lasterror();
244 public function fetchAllCurrencyRate()
246 $sql = "SELECT cr.rowid";
247 $sql .= ' FROM
'.MAIN_DB_PREFIX.$this->table_element_line.' as cr
';
248 $sql .= ' WHERE cr.fk_multicurrency =
'.((int) $this->id);
249 $sql .= ' ORDER BY cr.date_sync DESC
';
251 $this->rates = array();
253 dol_syslog(__METHOD__, LOG_DEBUG);
254 $resql = $this->db->query($sql);
256 $num = $this->db->num_rows($resql);
258 while ($obj = $this->db->fetch_object($resql)) {
259 $rate = new CurrencyRate($this->db);
260 $rate->fetch($obj->rowid);
262 $this->rates[] = $rate;
264 $this->db->free($resql);
268 $this->errors[] = 'Error
'.$this->db->lasterror();
282 public function update(User $user, $trigger = true)
289 $this->name = trim($this->name);
290 $this->code = trim($this->code);
293 if (empty($this->code)) {
301 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET";
302 $sql .= " name = '".$this->db->escape($this->name)."',";
303 $sql .= " code = '".$this->db->escape($this->code)."'";
304 $sql .= " WHERE rowid = ".((int) $this->id);
308 $resql = $this->db->query($sql);
311 $this->errors[] = 'Error
'.$this->db->lasterror();
315 if (!$error && $trigger) {
316 $result = $this->call_trigger('CURRENCY_MODIFY
', $user);
322 // Commit or rollback
324 $this->db->rollback();
340 public function delete($trigger = true)
351 $result = $this->call_trigger('CURRENCY_DELETE
', $user);
358 // Delete all rates before
359 if (!$this->deleteRates()) {
361 $this->errors[] = 'Error
'.$this->db->lasterror();
362 dol_syslog('Currency::delete
'.join(',
', $this->errors), LOG_ERR);
365 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
366 $sql .= " WHERE rowid = ".((int) $this->id);
368 dol_syslog(__METHOD__, LOG_DEBUG);
369 $resql = $this->db->query($sql);
372 $this->errors[] = 'Error
'.$this->db->lasterror();
377 // Commit or rollback
379 $this->db->rollback();
394 public function deleteRates()
396 foreach ($this->rates as &$rate) {
397 if ($rate->delete() <= 0) {
411 public function addRate($rate)
413 $currencyRate = new CurrencyRate($this->db);
414 $currencyRate->rate = price2num($rate);
416 if ($currencyRate->create($this->id) > 0) {
417 $this->rate = $currencyRate;
421 $this->errors = $currencyRate->errors;
433 public function addRateFromDolibarr($code, $rate)
437 $currency = new MultiCurrency($this->db);
438 $currency->code = $code;
439 $currency->name = $code;
441 $sql = "SELECT label FROM ".MAIN_DB_PREFIX."c_currencies WHERE code_iso = '".$this->db->escape($code)."'";
443 dol_syslog(__METHOD__, LOG_DEBUG);
444 $resql = $this->db->query($sql);
445 if ($resql && ($line = $this->db->fetch_object($resql))) {
446 $currency->name = $line->label;
449 if ($currency->create($user) > 0) {
450 $currency->addRate($rate);
468 public function updateRate($rate)
470 return $this->addRate($rate);
478 public function getRate()
480 $sql = "SELECT cr.rowid";
481 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element_line." as cr";
482 $sql .= " WHERE cr.fk_multicurrency = ".((int) $this->id);
483 $sql .= " AND cr.date_sync = (SELECT MAX(cr2.date_sync) FROM ".MAIN_DB_PREFIX.$this->table_element_line." AS cr2 WHERE cr2.fk_multicurrency = ".((int) $this->id).")";
485 dol_syslog(__METHOD__, LOG_DEBUG);
486 $resql = $this->db->query($sql);
487 if ($resql && ($obj = $this->db->fetch_object($resql))) {
488 $this->rate = new CurrencyRate($this->db);
489 return $this->rate->fetch($obj->rowid);
503 public static function getIdFromCode($dbs, $code)
507 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."multicurrency WHERE code = '".$dbs->escape($code)."' AND entity = ".((int) $conf->entity);
509 dol_syslog(__METHOD__, LOG_DEBUG);
510 $resql = $dbs->query($sql);
511 if ($resql && $obj = $dbs->fetch_object($resql)) {
528 public static function getIdAndTxFromCode($dbs, $code, $date_document = '')
532 $sql1 = "SELECT m.rowid, mc.rate FROM ".MAIN_DB_PREFIX."multicurrency m";
534 $sql1 .= ' LEFT JOIN
'.MAIN_DB_PREFIX.'multicurrency_rate mc ON (m.rowid = mc.fk_multicurrency)
';
535 $sql1 .= " WHERE m.code = '".$dbs->escape($code)."'";
536 $sql1 .= " AND m.entity IN (".getEntity('multicurrency
').")";
538 if (!empty($conf->global->MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE) && !empty($date_document)) { // Use last known rate compared to document date
539 $tmparray = dol_getdate($date_document);
540 $sql2 .= " AND mc.date_sync <= '".$dbs->idate(dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year'], true))."'";
542 $sql3 = " ORDER BY mc.date_sync DESC LIMIT 1";
544 dol_syslog(__METHOD__, LOG_DEBUG);
545 $resql = $dbs->query($sql1.$sql2.$sql3);
547 if ($resql && $obj = $dbs->fetch_object($resql)) {
548 return array($obj->rowid, $obj->rate);
550 if (!empty($conf->global->MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE)) {
551 $resql = $dbs->query($sql1.$sql3);
552 if ($resql && $obj = $dbs->fetch_object($resql)) {
553 return array($obj->rowid, $obj->rate);
570 public static function getAmountConversionFromInvoiceRate($fk_facture, $amount, $way = 'dolibarr
', $table = 'facture
')
572 $multicurrency_tx = self::getInvoiceRate($fk_facture, $table);
574 if ($multicurrency_tx) {
575 if ($way == 'dolibarr
') {
576 return price2num($amount * $multicurrency_tx, 'MU
');
578 return price2num($amount / $multicurrency_tx, 'MU
');
592 public static function getInvoiceRate($fk_facture, $table = 'facture
')
596 $sql = "SELECT multicurrency_tx FROM ".MAIN_DB_PREFIX.$table." WHERE rowid = ".((int) $fk_facture);
598 dol_syslog(__METHOD__, LOG_DEBUG);
599 $resql = $db->query($sql);
600 if ($resql && ($line = $db->fetch_object($resql))) {
601 return $line->multicurrency_tx;
614 public function recalculRates(&$TRate)
618 if ($conf->currency != getDolGlobalString('MULTICURRENCY_APP_SOURCE
')) {
619 $alternate_source = 'USD
'.$conf->currency;
620 if (!empty($TRate->$alternate_source)) {
621 $coef = $TRate->USDUSD / $TRate->$alternate_source;
622 foreach ($TRate as $attr => &$rate) {
629 return -1; // Alternate souce not found
632 return 0; // Nothing to do
642 public function syncRates($key, $addifnotfound = 0)
644 global $conf, $db, $langs;
646 include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php
';
648 $urlendpoint = 'http:
649 $urlendpoint .=
'&source=' . (empty($conf->global->MULTICURRENCY_APP_SOURCE) ?
'USD' : $conf->global->MULTICURRENCY_APP_SOURCE);
651 dol_syslog(
"Call url endpoint ".$urlendpoint);
655 if ($resget[
'content']) {
656 $response = $resget[
'content'];
657 $response = json_decode($response);
659 if ($response->success) {
660 $TRate = $response->quotes;
664 foreach ($TRate as $currency_code => $rate) {
665 $code = substr($currency_code, 3, 3);
667 if ($obj->fetch(0, $code) > 0) {
668 $obj->updateRate($rate);
669 } elseif ($addifnotfound) {
677 dol_syslog(
"Failed to call endpoint ".$response->error->info, LOG_WARNING);
678 setEventMessages($langs->trans(
'multicurrency_syncronize_error', $response->error->info),
null,
'errors');
696 if ($currencytmp->fetch(
'', $code) > 0) {
713 public $element =
'multicurrency_rate';
718 public $table_element =
'multicurrency_rate';
738 public $fk_multicurrency;
765 public function create($fk_multicurrency, $trigger =
true)
769 dol_syslog(
'CurrencyRate::create', LOG_DEBUG);
773 if (empty($this->entity) || $this->entity <= 0) {
774 $this->entity = $conf->entity;
776 $now = empty($this->date_sync) ?
dol_now() : $this->date_sync;
779 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$this->table_element.
"(";
781 $sql .=
' date_sync,';
782 $sql .=
' fk_multicurrency,';
784 $sql .=
') VALUES (';
785 $sql .=
' '.((float) $this->rate).
',';
786 $sql .=
" '".$this->db->idate($now).
"',";
787 $sql .=
" ".((int) $fk_multicurrency).
",";
788 $sql .=
" ".((int) $this->entity);
794 $resql = $this->db->query(
$sql);
797 $this->errors[] =
'Error '.$this->db->lasterror();
798 dol_syslog(
'CurrencyRate::create '.join(
',', $this->errors), LOG_ERR);
802 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
803 $this->fk_multicurrency = $fk_multicurrency;
804 $this->date_sync = $now;
807 $result = $this->
call_trigger(
'CURRENCYRATE_CREATE', $user);
815 $this->db->rollback();
835 $sql =
"SELECT cr.rowid, cr.rate, cr.date_sync, cr.fk_multicurrency, cr.entity";
836 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" AS cr";
837 $sql .=
" WHERE cr.rowid = ".((int) $id);
840 $resql = $this->db->query(
$sql);
842 $numrows = $this->db->num_rows($resql);
844 $obj = $this->db->fetch_object($resql);
846 $this->
id = $obj->rowid;
847 $this->rate = $obj->rate;
848 $this->date_sync = $this->db->jdate($obj->date_sync);
849 $this->fk_multicurrency = $obj->fk_multicurrency;
850 $this->entity = $obj->entity;
852 $this->db->free($resql);
860 $this->errors[] =
'Error '.$this->db->lasterror();
861 dol_syslog(
'CurrencyRate::fetch '.join(
',', $this->errors), LOG_ERR);
879 dol_syslog(
'CurrencyRate::update', LOG_DEBUG);
884 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
885 $sql .=
"SET rate = ".((float) $this->rate);
886 if (!empty($this->date_sync)) {
887 $sql .=
", date_sync = '".$this->db->idate($this->date_sync).
"'";
889 if (!empty($this->fk_multicurrency)) {
890 $sql .=
', fk_multicurrency = '.((int) $this->fk_multicurrency);
892 $sql .=
" WHERE rowid =".((int) $this->
id);
897 $resql = $this->db->query(
$sql);
900 $this->errors[] =
'Error '.$this->db->lasterror();
901 dol_syslog(
'CurrencyRate::update '.join(
',', $this->errors), LOG_ERR);
904 if (!$error && $trigger) {
905 $result = $this->
call_trigger(
'CURRENCYRATE_MODIFY', $user);
913 $this->db->rollback();
929 public function delete($trigger =
true)
933 dol_syslog(
'CurrencyRate::delete', LOG_DEBUG);
940 $result = $this->
call_trigger(
'CURRENCYRATE_DELETE', $user);
947 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element;
948 $sql .=
' WHERE rowid='.((int) $this->
id);
951 $resql = $this->db->query(
$sql);
954 $this->errors[] =
'Error '.$this->db->lasterror();
955 dol_syslog(
'CurrencyRate::delete '.join(
',', $this->errors), LOG_ERR);
961 $this->db->rollback();