diff --git a/htdocs/langs/en_US/multicurrency.lang b/htdocs/langs/en_US/multicurrency.lang index 4dc04ff2622..8e4f1c24502 100644 --- a/htdocs/langs/en_US/multicurrency.lang +++ b/htdocs/langs/en_US/multicurrency.lang @@ -18,3 +18,11 @@ MulticurrencyReceived=Received, original currency MulticurrencyRemainderToTake=Remaining amount, original currency MulticurrencyPaymentAmount=Payment amount, original currency AmountToOthercurrency=Amount To (in currency of receiving account) + +ErrorCallbackNotFound=Callback not found: %s +CurrencyRateSetup=Multi-currency exchange rates +MulticurrencyRateDeleted=Exchange rate deleted +MulticurrencyDateSync=Date +MulticurrencyRate=Exchange rate +MulticurrencyCode=Currency code +MulticurrencyEntity=Entity diff --git a/htdocs/langs/fr_FR/multicurrency.lang b/htdocs/langs/fr_FR/multicurrency.lang index 73dd1aa7cf6..b1418c780ee 100644 --- a/htdocs/langs/fr_FR/multicurrency.lang +++ b/htdocs/langs/fr_FR/multicurrency.lang @@ -18,3 +18,11 @@ MulticurrencyReceived=Reçu, devise originale MulticurrencyRemainderToTake=Montant restant, devise d'origine MulticurrencyPaymentAmount=Montant du règlement (devise d'origine) AmountToOthercurrency=Montant destination (en devise du compte de réception) + +ErrorCallbackNotFound=Callback introuvable : %s +CurrencyRateSetup=Taux de change multi-devise +MulticurrencyRateDeleted=Taux de change supprimé +MulticurrencyDateSync=Date +MulticurrencyRate=Taux de change +MulticurrencyCode=Code devise +MulticurrencyEntity=Entité diff --git a/htdocs/multicurrency/multicurrency_rates.php b/htdocs/multicurrency/multicurrency_rates.php index 6bf3d491c47..e41f6ddc48b 100644 --- a/htdocs/multicurrency/multicurrency_rates.php +++ b/htdocs/multicurrency/multicurrency_rates.php @@ -31,7 +31,13 @@ $res=@include("../main.inc.php"); // For root directory require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"); require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; -$langs->loadLangs(array("errors", "admin", "main", "companies", "resource", "holiday", "accountancy", "hrm", "orders", "contracts", "projects", "propal", "bills", "interventions")); +dol_include_once('/multicompany/class/actions_multicompany.class.php', 'ActionsMulticompany'); +/** @var Translate $langs */ +$langs->loadLangs(array( + "errors", + "admin", + "main", + "multicurrency")); @@ -41,7 +47,8 @@ if (!$user->admin) } // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$hookmanager->initHooks(array('admin')); +/** @var HookManager $hookmanager */ +$hookmanager->initHooks(array('multicurrency_rates')); // Load translation files required by the page @@ -69,67 +76,9 @@ if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, $offset = $listlimit * $page; $pageprev = $page - 1; $pagenext = $page + 1; +// TODO: sorting, filtering, paginating -// This page is a generic page to edit dictionaries -// Put here declaration of dictionaries properties - -// Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this. -$taborder = array(9, 0, 4, 3, 2, 0, 1, 8, 19, 16, 27, 38, 0, 5, 11, 0, 32, 33, 34, 0, 6, 0, 29, 0, 7, 24, 28, 17, 35, 36, 0, 10, 23, 12, 13, 0, 14, 0, 22, 20, 18, 21, 0, 15, 30, 0, 37, 0, 25, 0); - -// Name of SQL tables of dictionaries -$tabname = array(); -$tabname[1] = MAIN_DB_PREFIX."c_forme_juridique"; - -// Dictionary labels -$tablib = array(); -$tablib[1] = "DictionaryCompanyJuridicalType"; - -// Requests to extract data -$tabsql = array(); -$tabsql[1] = "SELECT f.rowid as rowid, f.code, f.libelle, c.code as country_code, c.label as country, f.active FROM ".MAIN_DB_PREFIX."c_forme_juridique as f, ".MAIN_DB_PREFIX."c_country as c WHERE f.fk_pays=c.rowid"; - -// Criteria to sort dictionaries -$tabsqlsort = array(); -$tabsqlsort[1] = "country ASC, code ASC"; - -// Field names in select result for dictionary display -$tabfield = array(); -$tabfield[1] = "code,libelle,country"; - -// Edit field names for editing a record -$tabfieldvalue = array(); -$tabfieldvalue[1] = "code,libelle,country"; - -// Field names in the table for inserting a record -$tabfieldinsert = array(); -$tabfieldinsert[1] = "code,libelle,fk_pays"; - -// Rowid name of field depending if field is autoincrement on or off.. -// Use "" if id field is "rowid" and has autoincrement on -// Use "nameoffield" if id field is not "rowid" or has not autoincrement on -$tabrowid = array(); -$tabrowid[1] = ""; - -// Condition to show dictionary in setup page -$tabcond = array(); -$tabcond[1] = (!empty($conf->societe->enabled)); - -// List of help for fields -$tabhelp = array(); -$tabhelp[1] = array('code'=>$langs->trans("EnterAnyCode")); -// List of check for fields (NOT USED YET) -$tabfieldcheck = array(); -$tabfieldcheck[1] = array(); - -// Defaut sortorder -if (empty($sortfield)) -{ - $tmp1 = explode(',', $tabsqlsort[$id]); - $tmp2 = explode(' ', $tmp1[0]); - $sortfield = preg_replace('/^.*\./', '', $tmp2[0]); -} - /* * Actions */ @@ -137,264 +86,6 @@ if (empty($sortfield)) _handleActions($db); exit; -/** - * Show fields in insert/edit mode - * - * @param array $fieldlist Array of fields - * @param Object $obj If we show a particular record, obj is filled with record fields - * @param string $tabname Name of SQL table - * @param string $context 'add'=Output field for the "add form", 'edit'=Output field for the "edit form", 'hide'=Output field for the "add form" but we dont want it to be rendered - * @return string '' or value of entity into table - */ -function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') -{ - global $conf, $langs, $db, $mysoc; - global $form; - global $region_id; - global $elementList, $sourceList, $localtax_typeList; - - $formadmin = new FormAdmin($db); - $formcompany = new FormCompany($db); - $formaccounting = new FormAccounting($db); - - $withentity = ''; - - foreach ($fieldlist as $field => $value) - { - if ($fieldlist[$field] == 'entity') { - $withentity = $obj->{$fieldlist[$field]}; - continue; - } - - if (in_array($fieldlist[$field], array('code', 'libelle', 'type')) && $tabname == MAIN_DB_PREFIX."c_actioncomm" && in_array($obj->type, array('system', 'systemauto'))) - { - $hidden = (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]}:''); - print ''; - print ''; - print $langs->trans($hidden); - print ''; - } - elseif ($fieldlist[$field] == 'country') - { - if (in_array('region_id', $fieldlist)) - { - print ''; - print ''; - continue; - } // For state page, we do not show the country input (we link to region, not country) - print ''; - $fieldname = 'country'; - print $form->select_country((!empty($obj->country_code) ? $obj->country_code : (!empty($obj->country) ? $obj->country : '')), $fieldname, '', 28, 'maxwidth150 maxwidthonsmartphone'); - print ''; - } - elseif ($fieldlist[$field] == 'country_id') - { - if (!in_array('country', $fieldlist)) // If there is already a field country, we don't show country_id (avoid duplicate) - { - $country_id = (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : 0); - print ''; - print ''; - print ''; - } - } - elseif ($fieldlist[$field] == 'region') - { - print ''; - $formcompany->select_region($region_id, 'region'); - print ''; - } - elseif ($fieldlist[$field] == 'region_id') - { - $region_id = (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]}:0); - print ''; - print ''; - print ''; - } - elseif ($fieldlist[$field] == 'lang') - { - print ''; - print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'lang'); - print ''; - } - // The type of the element (for contact types) - elseif ($fieldlist[$field] == 'element') - { - print ''; - print $form->selectarray('element', $elementList, (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]}:'')); - print ''; - } - // The source of the element (for contact types) - elseif ($fieldlist[$field] == 'source') - { - print ''; - print $form->selectarray('source', $sourceList, (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]}:'')); - print ''; - } - elseif ($fieldlist[$field] == 'private') - { - print ''; - print $form->selectyesno("private", (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]}:'')); - print ''; - } - elseif ($fieldlist[$field] == 'type' && $tabname == MAIN_DB_PREFIX."c_actioncomm") - { - $type = (!empty($obj->type) ? $obj->type : 'user'); // Check if type is different of 'user' (external module) - print ''; - print $type.''; - print ''; - } - elseif ($fieldlist[$field] == 'type' && $tabname == MAIN_DB_PREFIX.'c_paiement') - { - print ''; - $select_list = array(0=>$langs->trans('PaymentTypeCustomer'), 1=>$langs->trans('PaymentTypeSupplier'), 2=>$langs->trans('PaymentTypeBoth')); - print $form->selectarray($fieldlist[$field], $select_list, (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]}:'2')); - print ''; - } - elseif ($fieldlist[$field] == 'recuperableonly' || $fieldlist[$field] == 'type_cdr' || $fieldlist[$field] == 'deductible' || $fieldlist[$field] == 'category_type') { - if ($fieldlist[$field] == 'type_cdr') print ''; - else print ''; - if ($fieldlist[$field] == 'type_cdr') { - print $form->selectarray($fieldlist[$field], array(0=>$langs->trans('None'), 1=>$langs->trans('AtEndOfMonth'), 2=>$langs->trans('CurrentNext')), (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]}:'')); - } else { - print $form->selectyesno($fieldlist[$field], (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]}:''), 1); - } - print ''; - } - elseif (in_array($fieldlist[$field], array('nbjour', 'decalage', 'taux', 'localtax1', 'localtax2'))) { - $class = "left"; - if (in_array($fieldlist[$field], array('taux', 'localtax1', 'localtax2'))) $class = "center"; // Fields aligned on right - print ''; - print ''; - print ''; - } - elseif (in_array($fieldlist[$field], array('libelle_facture'))) { - print ''; - $transfound = 0; - $transkey = ''; - // Special case for labels - if ($tabname == MAIN_DB_PREFIX.'c_payment_term') - { - $langs->load("bills"); - $transkey = "PaymentCondition".strtoupper($obj->code); - if ($langs->trans($transkey) != $transkey) - { - $transfound = 1; - print $form->textwithpicto($langs->trans($transkey), $langs->trans("GoIntoTranslationMenuToChangeThis")); - } - } - if (!$transfound) - { - print ''; - } - else { - print ''; - } - print ''; - } - elseif ($fieldlist[$field] == 'price' || preg_match('/^amount/i', $fieldlist[$field])) { - print ''; - } - elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) { - print ''; - } - elseif ($fieldlist[$field] == 'unit') { - print ''; - $units = array( - 'mm' => $langs->trans('SizeUnitmm'), - 'cm' => $langs->trans('SizeUnitcm'), - 'point' => $langs->trans('SizeUnitpoint'), - 'inch' => $langs->trans('SizeUnitinch') - ); - print $form->selectarray('unit', $units, (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]}:''), 0, 0, 0); - print ''; - } - // Le type de taxe locale - elseif ($fieldlist[$field] == 'localtax1_type' || $fieldlist[$field] == 'localtax2_type') - { - print ''; - print $form->selectarray($fieldlist[$field], $localtax_typeList, (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]}:'')); - print ''; - } - elseif ($fieldlist[$field] == 'accountancy_code' || $fieldlist[$field] == 'accountancy_code_sell' || $fieldlist[$field] == 'accountancy_code_buy') - { - print ''; - if (!empty($conf->accounting->enabled)) - { - $fieldname = $fieldlist[$field]; - $accountancy_account = (!empty($obj->$fieldname) ? $obj->$fieldname : 0); - print $formaccounting->select_account($accountancy_account, '.'.$fieldlist[$field], 1, '', 1, 1, 'maxwidth200 maxwidthonsmartphone'); - } - else - { - $fieldname = $fieldlist[$field]; - print ''; - } - print ''; - } - elseif ($fieldlist[$field] == 'fk_tva') - { - print ''; - print $form->load_tva('fk_tva', $obj->taux, $mysoc, new Societe($db), 0, 0, '', false, -1); - print ''; - } - elseif ($fieldlist[$field] == 'fk_c_exp_tax_cat') - { - print ''; - print $form->selectExpenseCategories($obj->fk_c_exp_tax_cat); - print ''; - } - elseif ($fieldlist[$field] == 'fk_range') - { - print ''; - print $form->selectExpenseRanges($obj->fk_range); - print ''; - } - else - { - $fieldValue = isset($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]}:''; - - if ($fieldlist[$field] == 'sortorder') - { - $fieldlist[$field] = 'position'; - } - - $classtd = ''; $class = ''; - if ($fieldlist[$field] == 'code') $class = 'maxwidth100'; - if (in_array($fieldlist[$field], array('dayrule', 'day', 'month', 'year', 'pos', 'use_default', 'affect', 'delay', 'position', 'sortorder', 'sens', 'category_type'))) $class = 'maxwidth50'; - if (in_array($fieldlist[$field], array('libelle', 'label', 'tracking'))) $class = 'quatrevingtpercent'; - print ''; - $transfound = 0; - $transkey = ''; - if (in_array($fieldlist[$field], array('label', 'libelle'))) // For label - { - // Special case for labels - if ($tabname == MAIN_DB_PREFIX.'c_civility') { - $transkey = "Civility".strtoupper($obj->code); - } - if ($tabname == MAIN_DB_PREFIX.'c_payment_term') { - $langs->load("bills"); - $transkey = "PaymentConditionShort".strtoupper($obj->code); - } - if ($transkey && $langs->trans($transkey) != $transkey) - { - $transfound = 1; - print $form->textwithpicto($langs->trans($transkey), $langs->trans("GoIntoTranslationMenuToChangeThis")); - } - } - if (!$transfound) - { - print ''; - } - else { - print ''; - } - print ''; - } - } - - return $withentity; -} - function _handleActions($db) { $action = GETPOST('action', 'alpha'); if (empty($action)) $action = 'view'; @@ -408,88 +99,122 @@ function _handleActions($db) { call_user_func($callbackName, $db); } -function _actionAdd($db) { - -} - -function _actionModify($db) { - $id = GETPOST('id', 'int'); - _showDictionary($db, 'modify', $id); -} - -function _actionView($db) { - _showDictionary($db, 'view', intval(GETPOST('id', 'int')))); -} - -function _actionDelete($db) { +/** + * @param DoliDB $db + * @param string $mode + * @param int|null $targetId ID of the row targeted for edition, deletion, etc. + */ +function _mainView($db, $mode='view', $targetId=NULL) { global $langs; - global $delayedhtmlcontent; - $form = new Form($db); - $delayedhtmlcontent .= $form->formconfirm( - $_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').$paramwithsearch, - $langs->trans('DeleteLine'), - $langs->trans('ConfirmDeleteLine'), - 'confirm_delete', - '', - 0, - 1 - ); - _showDictionary($db, 'view', intval(GETPOST('id', 'int'))); -} - -function _actionConfirmDelete($db) { - $id = GETPOST('id', 'int'); - $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'multicurrency_rate' - .' WHERE rowid = ' . intval($id); - - _showDictionary($db, 'view'); -} - -function _showDictionary($db, $mode='view', $id=NULL) { - global $langs; - $form = new Form($db); - $formadmin = new FormAdmin($db); $title = $langs->trans('CurrencyRateSetup'); $limit = 123; + // column definition $TVisibleColumn = array( - 'rate.date_sync' => array('Date'), - 'rate.rate' => array('Number'), - 'currency.code' => array('CurrencyCode'), - 'rate.entity' => array(), + 'rate.date_sync' + => array('callback' => 'Date'), + 'rate.rate' + => array('callback' => 'Number'), + 'currency.code' + => array('callback' => 'CurrencyCode'), +// 'rate.entity' +// => array('callback' => 'Entity'), ); - foreach ($TVisibleColumn as $colSelect => &$colParam) { - $colParam['name'] = _columnAlias($colSelect); - } + foreach ($TVisibleColumn as $colSelect => &$colParam) { $colParam['name'] = _columnAlias($colSelect); } unset($colParam); - $sql = 'SELECT rate.rowid, ' . join(', ', array_keys($TVisibleColumn)) . ' FROM ' . MAIN_DB_PREFIX . 'multicurrency_rate rate' - . ' LEFT JOIN ' . MAIN_DB_PREFIX . 'multicurrency currency ON rate.fk_multicurrency = currency.rowid' - . ' WHERE 1 = 1' - . ' LIMIT ' . intval($limit); + $sql = /** @lang SQL */ + 'SELECT rate.rowid, ' . join(', ', array_keys($TVisibleColumn)) . ' FROM ' . MAIN_DB_PREFIX . 'multicurrency_rate rate' + . ' LEFT JOIN ' . MAIN_DB_PREFIX . 'multicurrency currency ON rate.fk_multicurrency = currency.rowid' + . ' WHERE rate.entity IN (' . getEntity('multicurrency') . ')' + . ' ORDER BY rate.date_sync DESC' + . ' LIMIT ' . intval($limit); $resql = $db->query($sql); if (!$resql) { - llxFooter(); - return; + setEventMessages($db->lasterror, array(), 'errors'); + $num_rows = 0; + } else { + $num_rows = $db->num_rows($resql); } - $num_rows = $db->num_rows($resql); llxHeader(); - echo load_fiche_titre($title, $linkback, $titlepicto); + echo load_fiche_titre($title); + + echo ''; echo ''; - echo ''; - echo ''; + echo '' + . '' + . '' + . ''; - // titres + + // En-têtes de colonnes + echo ''; + echo ''; foreach ($TVisibleColumn as $colSelect => $colParam) { - echo ''; } - echo ''; + echo ''; + echo ''; + + // Formulaire des filtres de recherche + echo ''; + foreach ($TVisibleColumn as $colSelect => $colParam) { + echo ''; + } + echo ''; echo ''; echo ''; + + // formulaire d'ajout ('new') + echo ''; + echo ''; + foreach ($TVisibleColumn as $colSelect => $colParam) { + echo ''; + } + // entire form is inside cell because HTML does not allow forms inside tables unless they are inside cells + echo ''; + echo ''; + echo ''; + + // lignes echo ''; if (!$num_rows) { echo ''; @@ -500,59 +225,296 @@ function _showDictionary($db, $mode='view', $id=NULL) { } for ($i = 0; $i < $num_rows; $i++) { $obj = $db->fetch_object($resql); + $objId = intval($obj->rowid); + $row_is_in_edit_mode = ($mode === 'modify' && $objId === $targetId); + $form_update_name = "form-update-" . $objId; if (!$obj) { break; } - echo ''; + echo ''; foreach ($TVisibleColumn as $colSelect => $colParam) { $rawValue = $obj->{$colParam['name']}; - - // default callback for how to display the raw value - $cellContentCallback = '_getCellDefault'; - - // possible override in column definition - if (isset($colParam['callback'])) { - $cbName = $colParam['callback']; - // mandatory function name prefix: '_getCell' (some day, the callback may come from untrusted input) - if (strpos($cbName, '_getCell') !== 0) $cbName = '_getCell' . $cbName; - if (function_exists($cbName)) { $cellContentCallback = $cbName; } - } - - if ($mode === 'modify' && $obj->rowid === $id) { - $cellContent = call_user_func($cellContentCallback, $rawValue, 'modify', $colParam['name']); - } else { - $cellContent = call_user_func($cellContentCallback, $rawValue, 'view', $colParam['name']); - } - echo ''; + $displayMode = 'view'; + if ($row_is_in_edit_mode) { $displayMode = 'modify'; } + $cellContent = _getCellContent($rawValue, $colParam, $displayMode, $form_update_name); + echo ''; } - echo ''; + echo ''; echo ''; } echo ''; echo '
'; - echo $langs->trans('multicurrencyColumn' . _camel(ucfirst($colParam['name']))); + echo ''; + echo $langs->trans('Multicurrency' . _camel(ucfirst($colParam['name']))); echo '
'; + echo _getCellContent( + GETPOST('search_' . $colParam['name']), + $colParam, + 'search', + 'form-filter' + ); + echo '' + . '
' + . '' + . '' + . '
' + . '
'; + // show an empty input + echo _getCellContent('', $colParam, 'new', 'form-add-new'); + echo '' + .'
' + .'' + .'' + .'
' + .'
' . $cellContent . '' . $cellContent . '' - . '' . img_picto('edit', 'edit') . '' - . '' . img_picto('delete', 'delete') . '' - . ''; + // save form (for the row in edit mode) + if ($row_is_in_edit_mode) { + echo '
' + . '' + . '' + . '' + . '
'; + } + + // edit + delete buttons (for rows not in edit mode) + else { + echo '
' + . '' + . '' + . '' + . '
'; + echo '
' + . '' + . '' + . '' + . '
'; + } + echo '
'; + // End of page llxFooter(); $db->close(); } +/** + * Calls a specialized callback depending on $colParam['callback'] (or a default one + * if not set or found) to return a representation of $rawValue depending on $mode: + * + * @param mixed $rawValue A raw value (as returned by the SQL handler) + * @param array $colParam Information about the kind of value (date, price, etc.) + * @param string $mode 'view', => returns the value for end user display + * 'modify', => returns a form to modify the value + * 'new', => returns a form to put the value in a new record + * 'raw', => does nothing (returns the raw value) + * 'text' => returns a text-only version of the value + * (for text-only exports etc.) + * @param string|null $formId HTML id of the form on which to attach the input in + * 'modify' and 'new' modes + * @return string + */ +function _getCellContent($rawValue, $colParam, $mode='view', $formId=NULL) { + if ($mode === 'raw') return $rawValue; + $callback = _cellContentCallbackName($colParam); + return call_user_func($callback, $rawValue, $mode, $colParam['name'], $formId); +} + +/** + * @param $rawValue + * @param string $mode + * @param string $inputName + * @return string + * @see _getCellContent() + */ +function _getCellDefault($rawValue, $mode='view', $inputName='', $formId=NULL) { + switch ($mode) { + case 'view': + return dol_escape_htmltag($rawValue); + case 'modify': case 'new': + $inputAttributes = array( + 'value' => $rawValue, + 'name' => $inputName, + ); + if ($formId !== NULL) { + $inputAttributes['form'] = $formId; + } + return _tagWithAttributes('input', $inputAttributes); + case 'raw': + return $rawValue; + case 'text': + return strip_tags($rawValue); + case 'search': + return ''; + } + return $rawValue; +} + +/** + * @param $rawValue + * @param string $mode + * @param string $inputName + * @return string + * @see _getCellContent() + */ +function _getCellDate($rawValue, $mode='view', $inputName='', $formId=NULL) { + global $db; + switch ($mode) { + case 'view': + $tms = $db->jdate($rawValue); + $dateFormat = '%d/%m/%Y %H:%M'; + $dateFormat = ''; + return dol_print_date($tms, $dateFormat); + case 'modify': case 'new': + $inputAttributes = array( + 'type' => 'date', + 'value' => preg_replace('/^(.*?) .*/', '$1', $rawValue), + 'name' => $inputName, + ); + if ($formId !== NULL) { + $inputAttributes['form'] = $formId; + } + return _tagWithAttributes('input', $inputAttributes); + case 'raw': + return $rawValue; + case 'text': + return strip_tags($rawValue); + case 'search': + return ''; + } + return $rawValue; +} + +/** + * @param $rawValue + * @param string $mode + * @param string $inputName + * @return string + * @see _getCellContent() + */ +function _getCellNumber($rawValue, $mode='view', $inputName='', $formId=NULL) { + switch ($mode) { + case 'view': + return price($rawValue); + case 'modify': case 'new': + $inputAttributes = array( + 'value' => $rawValue, + 'name' => $inputName, + 'placeholder' => '0,00', + 'pattern' => '\d+(?:[.,]\d+)?', + 'required' => 'required', + ); + if ($formId !== NULL) { + $inputAttributes['form'] = $formId; + } + return _tagWithAttributes('input', $inputAttributes); + case 'raw': + return $rawValue; + case 'text': + return strip_tags($rawValue); + case 'search': + return ''; + } + return $rawValue; +} + /** * @param $rawValue * @param string $mode * @param string $inputName * @return string */ -function _getcellDefault($rawValue, $mode='view', $inputName='') { - if ($mode === 'view') { - return dol_escape_htmltag($rawValue); - } elseif ($mode === 'modify') { - return ''; +function _getCellCurrencyCode($rawValue, $mode='view', $inputName='', $formId=NULL) { + global $db, $langs; + $form = new Form($db); + switch ($mode) { + case 'view': case 'modify': // 'modify' because the currency code is read-only + return $langs->cache_currencies[$rawValue]['label'] . ' (' . $langs->getCurrencySymbol($rawValue) . ')'; + case 'new': + $select = $form->selectMultiCurrency($rawValue, $inputName, 1); + if ($formId) { + // add form attribute to the output of selectCurrency + $select = preg_replace( + '/^trans('ErrorCallbackNotFound', $cbName), + 'warnings' + ); + } + } + return $cellContentCallback; +} + +/** + * Returns an opening (or self-closing) tag with the (escaped) requested attributes + * + * Example: _tagWithAttributes('input', ['name' => 'test', 'value' => '"hello"']) + * => '' + * + * + * @param string $tagName + * @param array $TAttribute [$attrName => $attrVal] + * @return string + */ +function _tagWithAttributes($tagName, $TAttribute) { + $selfClosing = in_array($tagName, array('area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr')); + $tag = '<' . $tagName; + foreach ($TAttribute as $attrName => $attrVal) { + $tag .= ' ' . $attrName . '="' . str_replace("\n", " ", htmlspecialchars($attrVal, ENT_QUOTES)) . '"'; + } + $tag .= $selfClosing ? ' />' : ' >'; + return $tag; } /** @@ -590,3 +552,137 @@ function _columnAlias($colSelect) { function _camel($str) { return preg_replace_callback('/_(.)?/', function($m) { return ucfirst($m[1]); }, $str); } + + +/** + * Default: view all currency rates + * @param DoliDB $db + */ +function _actionView($db) { + _mainView($db, 'view', intval(GETPOST('id', 'int'))); +} + +/** + * Add a new currency rate + * @param DoliDB $db + */ +function _actionAdd($db) { + global $langs, $conf; + $dateSync = GETPOST('date_sync', 'alpha'); + $rate = GETPOST('rate', 'int'); + $code = GETPOST('code', 'aZ09'); + $entity = intval($conf->entity); + $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'multicurrency_rate (`date_sync`, `rate`, `fk_multicurrency`, `entity`)' + . ' VALUES (' + . ' "' . $db->escape($dateSync) . '"' + . ' ,"' . $db->escape($rate) . '"' + . ' , (SELECT rowid FROM llx_multicurrency WHERE code = "'. $db->escape($code) . '" AND entity IN ('. getEntity('multicurrency') .') LIMIT 1)' + . ' ,"' . $db->escape($entity) . '"' + .')'; + $resql = $db->query($sql); + if (!$resql) { + setEventMessages($langs->trans('TODOSaveFailed'), array(), 'errors'); + } + _mainView($db, 'view'); +} + +/** + * Show a currency rate in edit mode + * @param DoliDB $db + */ +function _actionModify($db) { + $id = intval(GETPOST('id', 'int')); + _mainView($db, 'modify', $id); +} + +/** + * Saves a currency rate + * @param $db + */ +function _actionUpdate($db) { + global $langs; + $id = intval(GETPOST('id', 'int')); + $dateSync = GETPOST('date_sync', 'alpha'); + $rate = GETPOST('rate', 'int'); + $date = date_parse($dateSync); + $date = dol_mktime( + $date['hour'], + $date['minute'], + $date['second'], + $date['month'], + $date['day'], + $date['year'] + ); + $sql = /** @lang SQL */ + 'UPDATE ' . MAIN_DB_PREFIX . 'multicurrency_rate SET' + . ' date_sync = "' . $db->idate($date) . '",' + . ' rate = "' . price2num($rate) . '"' + . ' WHERE rowid = ' . $id; + $resql = $db->query($sql); + if (!$resql) { + setEventMessages($langs->trans($db->lasterror), array(), 'errors'); + } else { + setEventMessages($langs->trans('Saved'), array(), 'mesgs'); + } + _mainView($db); +} + +/** + * Show a confirm form prior to deleting a currency rate + * @param DoliDB $db + */ +function _actionDelete($db) { + global $langs; + global $delayedhtmlcontent; + $id = intval(GETPOST('id', 'int')); + $form = new Form($db); + $formParams = array( + 'id' => $id, + ); + if (isset($page)) $formParams['page'] = $page; + $formParams = http_build_query($formParams); + $delayedhtmlcontent .= $form->formconfirm( + $_SERVER["PHP_SELF"].'?'.$formParams, + $langs->trans('DeleteLine'), + $langs->trans('ConfirmDeleteLine'), + 'confirm_delete', + '', + 0, + 1 + ); + _mainView($db, 'view'); +} + +/** + * Delete a currency rate + * @param DoliDB $db + */ +function _actionConfirmDelete($db) { + global $langs; + $id = intval(GETPOST('id', 'int')); + if ($id === 0) { + setEventMessages($langs->trans('WrongID'), array(), 'errors'); + } else { + $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'multicurrency_rate' + . ' WHERE rowid = ' . $id; + $resql = $db->query($sql); + if (!$resql) { + setEventMessages($db->lasterror, array(), 'errors'); + } else { + setEventMessages($langs->trans('MulticurrencyRateDeleted'), array(), 'mesgs'); + } + } + _mainView($db, 'view'); +} + +/** + * Calls setEventMessages only if $message is not already stored for display + * + * @param string $message + * @param string $level 'errors', 'mesgs', 'warnings' + */ +function _setEventMessageOnce($message, $level='errors') { + if (!in_array($message, $_SESSION['dol_events'][$level])) { + setEventMessages($message, array(), $level); + } +}