29require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
30require_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();
116 global $conf, $langs;
118 dol_syslog(
'MultiCurrency::create', LOG_DEBUG);
122 if (self::checkCodeAlreadyExists($this->code)) {
124 $this->errors[] = $langs->trans(
'multicurrency_code_already_added');
128 if (empty($this->entity) || $this->entity <= 0) {
129 $this->entity = $conf->entity;
134 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$this->table_element.
"(";
138 $sql .=
' date_create,';
140 $sql .=
') VALUES (';
141 $sql .=
" '".$this->db->escape($this->code).
"',";
142 $sql .=
" '".$this->db->escape($this->
name).
"',";
143 $sql .=
" ".((int) $this->entity).
",";
144 $sql .=
" '".$this->db->idate($now).
"',";
145 $sql .=
" ".((int) $user->id);
151 $resql = $this->db->query($sql);
154 $this->errors[] =
'Error '.$this->db->lasterror();
155 dol_syslog(
'MultiCurrency::create '.join(
',', $this->errors), LOG_ERR);
159 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
160 $this->date_create = $now;
161 $this->fk_user = $user->id;
164 $result = $this->
call_trigger(
'CURRENCY_CREATE', $user);
172 $this->db->rollback();
189 public function fetch($id, $code =
null)
191 dol_syslog(
'MultiCurrency::fetch', LOG_DEBUG);
196 $sql .=
' c.rowid, c.name, c.code, c.entity, c.date_create, c.fk_user';
197 $sql .=
' FROM '.MAIN_DB_PREFIX.$this->table_element.
' AS c';
199 $sql .=
' WHERE c.code = \''.$this->db->escape($code).
'\' AND c.entity =
'.$conf->entity;
201 $sql .= ' WHERE c.rowid =
'.((int) $id);
204 dol_syslog(__METHOD__, LOG_DEBUG);
205 $resql = $this->db->query($sql);
208 $numrows = $this->db->num_rows($resql);
210 $obj = $this->db->fetch_object($resql);
212 $this->id = $obj->rowid;
213 $this->name = $obj->name;
214 $this->code = $obj->code;
215 $this->entity = $obj->entity;
216 $this->date_create = $obj->date_create;
217 $this->fk_user = $obj->fk_user;
219 $this->fetchAllCurrencyRate();
222 $this->db->free($resql);
230 $this->errors[] = 'Error
'.$this->db->lasterror();
242 public function fetchAllCurrencyRate()
244 $sql = "SELECT cr.rowid";
245 $sql .= ' FROM
'.MAIN_DB_PREFIX.$this->table_element_line.' as cr
';
246 $sql .= ' WHERE cr.fk_multicurrency =
'.((int) $this->id);
247 $sql .= ' ORDER BY cr.date_sync DESC
';
249 $this->rates = array();
251 dol_syslog(__METHOD__, LOG_DEBUG);
252 $resql = $this->db->query($sql);
254 $num = $this->db->num_rows($resql);
256 while ($obj = $this->db->fetch_object($resql)) {
257 $rate = new CurrencyRate($this->db);
258 $rate->fetch($obj->rowid);
260 $this->rates[] = $rate;
262 $this->db->free($resql);
266 $this->errors[] = 'Error
'.$this->db->lasterror();
280 public function update(User $user, $trigger = true)
287 $this->name = trim($this->name);
288 $this->code = trim($this->code);
291 if (empty($this->code)) {
299 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET";
300 $sql .= " name = '".$this->db->escape($this->name)."',";
301 $sql .= " code = '".$this->db->escape($this->code)."'";
302 $sql .= " WHERE rowid = ".((int) $this->id);
306 $resql = $this->db->query($sql);
309 $this->errors[] = 'Error
'.$this->db->lasterror();
313 if (!$error && $trigger) {
314 $result = $this->call_trigger('CURRENCY_MODIFY
', $user);
320 // Commit or rollback
322 $this->db->rollback();
339 public function delete($user, $trigger = true)
348 $result = $this->call_trigger('CURRENCY_DELETE
', $user);
355 // Delete all rates before
356 if (!$this->deleteRates()) {
358 $this->errors[] = 'Error
'.$this->db->lasterror();
359 dol_syslog('Currency::delete
'.join(',
', $this->errors), LOG_ERR);
362 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
363 $sql .= " WHERE rowid = ".((int) $this->id);
365 dol_syslog(__METHOD__, LOG_DEBUG);
366 $resql = $this->db->query($sql);
369 $this->errors[] = 'Error
'.$this->db->lasterror();
374 // Commit or rollback
376 $this->db->rollback();
391 public function deleteRates()
395 foreach ($this->rates as &$rate) {
396 if ($rate->delete($user) <= 0) {
410 public function addRate($rate)
412 $currencyRate = new CurrencyRate($this->db);
413 $currencyRate->rate = price2num($rate);
415 if ($currencyRate->create($this->id) > 0) {
416 $this->rate = $currencyRate;
420 $this->errors = $currencyRate->errors;
432 public function addRateFromDolibarr($code, $rate)
436 $currency = new MultiCurrency($this->db);
437 $currency->code = $code;
438 $currency->name = $code;
440 $sql = "SELECT label FROM ".MAIN_DB_PREFIX."c_currencies WHERE code_iso = '
".$this->db->escape($code)."'";
442 dol_syslog(__METHOD__, LOG_DEBUG);
443 $resql = $this->db->query($sql);
444 if ($resql && ($line = $this->db->fetch_object($resql))) {
445 $currency->name = $line->label;
448 if ($currency->create($user) > 0) {
449 $currency->addRate($rate);
467 public function updateRate($rate)
469 return $this->addRate($rate);
477 public function getRate()
479 $sql = "SELECT cr.rowid";
480 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element_line." as cr";
481 $sql .= " WHERE cr.fk_multicurrency = ".((int) $this->id);
482 $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).")";
484 dol_syslog(__METHOD__, LOG_DEBUG);
485 $resql = $this->db->query($sql);
486 if ($resql && ($obj = $this->db->fetch_object($resql))) {
487 $this->rate = new CurrencyRate($this->db);
488 return $this->rate->fetch($obj->rowid);
502 public static function getIdFromCode($dbs, $code)
506 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."multicurrency WHERE code = '
".$dbs->escape($code)."' AND entity = ".((int) $conf->entity);
508 dol_syslog(__METHOD__, LOG_DEBUG);
509 $resql = $dbs->query($sql);
510 if ($resql && $obj = $dbs->fetch_object($resql)) {
527 public static function getIdAndTxFromCode($dbs, $code, $date_document = '
')
531 $sql1 = "SELECT m.rowid, mc.rate FROM ".MAIN_DB_PREFIX."multicurrency m";
533 $sql1 .= ' LEFT JOIN
'.MAIN_DB_PREFIX.'multicurrency_rate mc ON (m.rowid = mc.fk_multicurrency)
';
534 $sql1 .= " WHERE m.code = '".$dbs->escape($code)."'";
535 $sql1 .= " AND m.entity IN (".getEntity('multicurrency
').")";
537 if (getDolGlobalString('MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE
') && !empty($date_document)) { // Use last known rate compared to document date
538 $tmparray = dol_getdate($date_document);
539 $sql2 .= " AND mc.date_sync <= '".$dbs->idate(dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year'], true))."'";
541 $sql3 = " ORDER BY mc.date_sync DESC LIMIT 1";
543 dol_syslog(__METHOD__, LOG_DEBUG);
544 $resql = $dbs->query($sql1.$sql2.$sql3);
546 if ($resql && $obj = $dbs->fetch_object($resql)) {
547 return array($obj->rowid, $obj->rate);
549 if (getDolGlobalString('MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE
')) {
550 $resql = $dbs->query($sql1.$sql3);
551 if ($resql && $obj = $dbs->fetch_object($resql)) {
552 return array($obj->rowid, $obj->rate);
570 public static function getAmountConversionFromInvoiceRate($fk_facture, $amount, $way = 'dolibarr
', $table = 'facture
', $invoice_rate = null)
572 if (!is_null($invoice_rate)) {
573 $multicurrency_tx = $invoice_rate;
575 $multicurrency_tx = self::getInvoiceRate($fk_facture, $table);
578 if ($multicurrency_tx) {
579 if ($way == 'dolibarr
') {
580 return price2num($amount * $multicurrency_tx, 'MU
');
582 return price2num($amount / $multicurrency_tx, 'MU
');
596 public static function getInvoiceRate($fk_facture, $table = 'facture
')
600 $sql = "SELECT multicurrency_tx FROM ".MAIN_DB_PREFIX.$table." WHERE rowid = ".((int) $fk_facture);
602 dol_syslog(__METHOD__, LOG_DEBUG);
603 $resql = $db->query($sql);
604 if ($resql && ($line = $db->fetch_object($resql))) {
605 return $line->multicurrency_tx;
618 public function recalculRates(&$TRate)
622 if ($conf->currency != getDolGlobalString('MULTICURRENCY_APP_SOURCE
')) {
623 $alternate_source = 'USD
'.$conf->currency;
624 if (!empty($TRate->$alternate_source)) {
625 $coef = 1 / $TRate->$alternate_source;
626 foreach ($TRate as $attr => &$rate) {
629 $TRate->USDUSD = $coef;
633 return -1; // Alternate souce not found
636 return 0; // Nothing to do
647 public function syncRates($key, $addifnotfound = 0, $mode = "")
649 global $conf, $db, $langs;
651 if (getDolGlobalString('MULTICURRENCY_DISABLE_SYNC_CURRENCYLAYER
')) {
652 if ($mode == "cron") {
653 $this->output = $langs->trans('Use of API
for currency
update is disabled by option MULTICURRENCY_DISABLE_SYNC_CURRENCYLAYER
');
655 setEventMessages($langs->trans('Use of API
for currency
update is disabled by option MULTICURRENCY_DISABLE_SYNC_CURRENCYLAYER
'), null, 'errors
');
661 $key = getDolGlobalString("MULTICURRENCY_APP_ID");
664 include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php
';
666 $urlendpoint = 'http:
667 $urlendpoint .=
'&source=' . (!
getDolGlobalString(
'MULTICURRENCY_APP_SOURCE') ?
'USD' : $conf->global->MULTICURRENCY_APP_SOURCE);
669 dol_syslog(
"Call url endpoint ".$urlendpoint);
673 if ($resget[
'content']) {
674 $response = $resget[
'content'];
675 $response = json_decode($response);
677 if ($response->success) {
678 $TRate = $response->quotes;
682 foreach ($TRate as $currency_code => $rate) {
683 $code = substr($currency_code, 3, 3);
685 if ($obj->fetch(0, $code) > 0) {
686 $obj->updateRate($rate);
687 } elseif ($addifnotfound) {
693 if ($mode ==
"cron") {
698 dol_syslog(
"Failed to call endpoint ".$response->error->info, LOG_WARNING);
699 if ($mode ==
"cron") {
700 $this->output = $langs->trans(
'multicurrency_syncronize_error', $response->error->info);
702 setEventMessages($langs->trans(
'multicurrency_syncronize_error', $response->error->info),
null,
'errors');
720 if ($currencytmp->fetch(
'', $code) > 0) {
737 public $element =
'multicurrency_rate';
742 public $table_element =
'multicurrency_rate';
757 public $rate_indirect;
767 public $fk_multicurrency;
792 public function create($fk_multicurrency, $trigger =
true)
796 dol_syslog(
'CurrencyRate::create', LOG_DEBUG);
800 if (empty($this->entity) || $this->entity <= 0) {
801 $this->entity = $conf->entity;
803 $now = empty($this->date_sync) ?
dol_now() : $this->date_sync;
806 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$this->table_element.
"(";
808 $sql .=
' rate_indirect,';
809 $sql .=
' date_sync,';
810 $sql .=
' fk_multicurrency,';
812 $sql .=
') VALUES (';
813 $sql .=
' '.((float) $this->rate).
',';
814 $sql .=
' '.((float) $this->rate_indirect).
',';
815 $sql .=
" '".$this->db->idate($now).
"',";
816 $sql .=
" ".((int) $fk_multicurrency).
",";
817 $sql .=
" ".((int) $this->entity);
823 $resql = $this->db->query($sql);
826 $this->errors[] =
'Error '.$this->db->lasterror();
827 dol_syslog(
'CurrencyRate::create '.join(
',', $this->errors), LOG_ERR);
831 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
832 $this->fk_multicurrency = $fk_multicurrency;
833 $this->date_sync = $now;
836 $result = $this->call_trigger(
'CURRENCYRATE_CREATE', $user);
844 $this->db->rollback();
864 $sql =
"SELECT cr.rowid, cr.rate, cr.rate_indirect, cr.date_sync, cr.fk_multicurrency, cr.entity";
865 $sql .=
" FROM ".MAIN_DB_PREFIX.$this->table_element.
" AS cr";
866 $sql .=
" WHERE cr.rowid = ".((int) $id);
869 $resql = $this->db->query($sql);
871 $numrows = $this->db->num_rows($resql);
873 $obj = $this->db->fetch_object($resql);
875 $this->
id = $obj->rowid;
876 $this->rate = $obj->rate;
877 $this->rate_indirect = $obj->rate_indirect;
878 $this->date_sync = $this->db->jdate($obj->date_sync);
879 $this->fk_multicurrency = $obj->fk_multicurrency;
880 $this->entity = $obj->entity;
882 $this->db->free($resql);
890 $this->errors[] =
'Error '.$this->db->lasterror();
891 dol_syslog(
'CurrencyRate::fetch '.join(
',', $this->errors), LOG_ERR);
909 dol_syslog(
'CurrencyRate::update', LOG_DEBUG);
914 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->table_element;
915 $sql .=
"SET rate = ".((float) $this->rate);
916 if (!empty($this->date_sync)) {
917 $sql .=
", date_sync = '".$this->db->idate($this->date_sync).
"'";
919 if (!empty($this->fk_multicurrency)) {
920 $sql .=
', fk_multicurrency = '.((int) $this->fk_multicurrency);
922 $sql .=
" WHERE rowid =".((int) $this->
id);
927 $resql = $this->db->query($sql);
930 $this->errors[] =
'Error '.$this->db->lasterror();
931 dol_syslog(
'CurrencyRate::update '.join(
',', $this->errors), LOG_ERR);
934 if (!$error && $trigger) {
935 $result = $this->call_trigger(
'CURRENCYRATE_MODIFY', $user);
943 $this->db->rollback();
960 public function delete($user, $trigger =
true)
962 dol_syslog(
'CurrencyRate::delete', LOG_DEBUG);
969 $result = $this->call_trigger(
'CURRENCYRATE_DELETE', $user);
976 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element;
977 $sql .=
' WHERE rowid='.((int) $this->
id);
980 $resql = $this->db->query($sql);
983 $this->errors[] =
'Error '.$this->db->lasterror();
984 dol_syslog(
'CurrencyRate::delete '.join(
',', $this->errors), LOG_ERR);
990 $this->db->rollback();
Parent class of all other business classes (invoices, contracts, proposals, orders,...
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
fetch($id)
Load object in memory from the database.
update($trigger=true)
Update object into database.
create($fk_multicurrency, $trigger=true)
Create object into database.
__construct(DoliDB $db)
Constructor.
Class to manage Dolibarr database access.
fetchAllCurrencyRate()
Load all rates in object from the database.
checkCodeAlreadyExists($code)
Check in database if the current code already exists.
__construct(DoliDB $db)
Constructor.
update(User $user, $trigger=true)
Update object into database.
delete($user, $trigger=true)
Delete object in database.
addRateFromDolibarr($code, $rate)
Try get label of code in llx_currency then add rate.
create(User $user, $trigger=true)
Create object into database.
recalculRates(&$TRate)
With free account we can't set source then recalcul all rates to force another source.
fetch($id, $code=null)
Load object in memory from the database.
Class to manage Dolibarr users.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_now($mode='auto')
Return date for now.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getURLContent($url, $postorget='GET', $param='', $followlocation=1, $addheaders=array(), $allowedschemes=array('http', 'https'), $localurl=0, $ssl_verifypeer=-1)
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.