';
diff --git a/htdocs/blockedlog/admin/blockedlog.php b/htdocs/blockedlog/admin/blockedlog.php
index 065dd4cda9e..1ef35942d1e 100644
--- a/htdocs/blockedlog/admin/blockedlog.php
+++ b/htdocs/blockedlog/admin/blockedlog.php
@@ -28,9 +28,9 @@ require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
// Load translation files required by the page
-$langs->loadLangs(array("admin","other","blockedlog"));
+$langs->loadLangs(array("admin", "other", "blockedlog"));
-if (! $user->admin || empty($conf->blockedlog->enabled)) accessforbidden();
+if (!$user->admin || empty($conf->blockedlog->enabled)) accessforbidden();
$action = GETPOST('action', 'alpha');
$backtopage = GETPOST('backtopage', 'alpha');
@@ -40,11 +40,12 @@ $backtopage = GETPOST('backtopage', 'alpha');
* Actions
*/
+$reg = array();
if (preg_match('/set_(.*)/', $action, $reg))
{
- $code=$reg[1];
+ $code = $reg[1];
$values = GETPOST($code);
- if(is_array($values))$values = implode(',', $values);
+ if (is_array($values)) $values = implode(',', $values);
if (dolibarr_set_const($db, $code, $values, 'chaine', 0, '', $conf->entity) > 0)
{
@@ -59,7 +60,7 @@ if (preg_match('/set_(.*)/', $action, $reg))
if (preg_match('/del_(.*)/', $action, $reg))
{
- $code=$reg[1];
+ $code = $reg[1];
if (dolibarr_del_const($db, $code, 0) > 0)
{
Header("Location: ".$_SERVER["PHP_SELF"]);
@@ -76,22 +77,22 @@ if (preg_match('/del_(.*)/', $action, $reg))
* View
*/
-$form=new Form($db);
+$form = new Form($db);
$block_static = new BlockedLog($db);
llxHeader('', $langs->trans("BlockedLogSetup"));
-$linkback='';
+$linkback = '';
if (GETPOST('withtab', 'alpha'))
{
- $linkback='
';
}
print load_fiche_titre($langs->trans("ModuleSetup").' '.$langs->trans('BlockedLog'), $linkback);
if (GETPOST('withtab', 'alpha'))
{
- $head=blockedlogadmin_prepare_head();
+ $head = blockedlogadmin_prepare_head();
dol_fiche_head($head, 'blockedlog', '', -1);
}
@@ -134,16 +135,16 @@ print '
';
$sql = "SELECT rowid, code as code_iso, code_iso as code_iso3, label, favorite";
-$sql.= " FROM ".MAIN_DB_PREFIX."c_country";
-$sql.= " WHERE active > 0";
+$sql .= " FROM ".MAIN_DB_PREFIX."c_country";
+$sql .= " WHERE active > 0";
-$countryArray=array();
-$resql=$db->query($sql);
+$countryArray = array();
+$resql = $db->query($sql);
if ($resql)
{
while ($obj = $db->fetch_object($resql))
{
- $countryArray[$obj->code_iso] = ($obj->code_iso && $langs->transnoentitiesnoconv("Country".$obj->code_iso)!="Country".$obj->code_iso?$langs->transnoentitiesnoconv("Country".$obj->code_iso):($obj->label!='-'?$obj->label:''));
+ $countryArray[$obj->code_iso] = ($obj->code_iso && $langs->transnoentitiesnoconv("Country".$obj->code_iso) != "Country".$obj->code_iso ? $langs->transnoentitiesnoconv("Country".$obj->code_iso) : ($obj->label != '-' ? $obj->label : ''));
}
}
@@ -159,8 +160,8 @@ print '';
print '
';
print '';
print $langs->trans("ListOfTrackedEvents").' ';
-$arrayoftrackedevents=$block_static->trackedevents;
-foreach($arrayoftrackedevents as $key => $val)
+$arrayoftrackedevents = $block_static->trackedevents;
+foreach ($arrayoftrackedevents as $key => $val)
{
print $key.' - '.$langs->trans($val).' ';
}
diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php
index becbbc3f151..3bd7f0097b9 100644
--- a/htdocs/blockedlog/admin/blockedlog_list.php
+++ b/htdocs/blockedlog/admin/blockedlog_list.php
@@ -58,7 +58,7 @@ if (($search_start == -1 || empty($search_start)) && ! GETPOSTISSET('search_star
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/bom/bom_agenda.php b/htdocs/bom/bom_agenda.php
index 37197d641dc..a5b66b9886f 100644
--- a/htdocs/bom/bom_agenda.php
+++ b/htdocs/bom/bom_agenda.php
@@ -60,7 +60,7 @@ $search_agenda_label = GETPOST('search_agenda_label');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php
index 3f1be6c7e4c..81b5f858c9b 100644
--- a/htdocs/bom/bom_card.php
+++ b/htdocs/bom/bom_card.php
@@ -520,7 +520,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
print ''."\n";
// Common attributes
- $keyforbreak = 'efficiency';
+ $keyforbreak = 'duration';
include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
// Other attributes
diff --git a/htdocs/bom/bom_document.php b/htdocs/bom/bom_document.php
index 6ac836fdcae..0fc68ed276e 100644
--- a/htdocs/bom/bom_document.php
+++ b/htdocs/bom/bom_document.php
@@ -48,7 +48,7 @@ $ref = GETPOST('ref', 'alpha');
// Get parameters
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/bom/bom_list.php b/htdocs/bom/bom_list.php
index 12602f9744a..e33394edcf7 100644
--- a/htdocs/bom/bom_list.php
+++ b/htdocs/bom/bom_list.php
@@ -47,7 +47,7 @@ $id = GETPOST('id', 'int');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php
index ddfb5e78d17..b53e2a7bc88 100644
--- a/htdocs/bom/class/bom.class.php
+++ b/htdocs/bom/class/bom.class.php
@@ -95,7 +95,7 @@ class BOM extends CommonObject
'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'notnull'=>-1,),
'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:1:(finished IS NULL or finished <> 0)', 'label'=>'Product', 'enabled'=>1, 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'help'=>'ProductBOMHelp'),
'qty' => array('type'=>'real', 'label'=>'Quantity', 'enabled'=>1, 'visible'=>1, 'default'=>1, 'position'=>55, 'notnull'=>1, 'isameasure'=>'1', 'css'=>'maxwidth75imp'),
- 'efficiency' => array('type'=>'real', 'label'=>'ManufacturingEfficiency', 'enabled'=>1, 'visible'=>-1, 'default'=>1, 'position'=>100, 'notnull'=>0, 'css'=>'maxwidth50imp', 'help'=>'ValueOfMeansLoss'),
+ //'efficiency' => array('type'=>'real', 'label'=>'ManufacturingEfficiency', 'enabled'=>1, 'visible'=>-1, 'default'=>1, 'position'=>100, 'notnull'=>0, 'css'=>'maxwidth50imp', 'help'=>'ValueOfMeansLossForProductProduced'),
'duration' => array('type'=>'duration', 'label'=>'EstimatedDuration', 'enabled'=>1, 'visible'=>-1, 'position'=>101, 'notnull'=>-1, 'css'=>'maxwidth50imp', 'help'=>'EstimatedDurationDesc'),
'fk_warehouse' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php:0', 'label'=>'WarehouseForProduction', 'enabled'=>1, 'visible'=>-1, 'position'=>102),
'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>-2, 'position'=>161, 'notnull'=>-1,),
@@ -561,7 +561,7 @@ class BOM extends CommonObject
{
$num = $this->ref;
}
- $this->newref = $num;
+ $this->newref = dol_sanitizeFileName($num);
// Validate
$sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
@@ -1056,7 +1056,7 @@ class BOMLine extends CommonObjectLine
'qty' => array('type'=>'double(24,8)', 'label'=>'Quantity', 'enabled'=>1, 'visible'=>1, 'position'=>100, 'notnull'=>1, 'isameasure'=>'1',),
'qty_frozen' => array('type'=>'smallint', 'label'=>'QuantityFrozen', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>105, 'css'=>'maxwidth50imp', 'help'=>'QuantityConsumedInvariable'),
'disable_stock_change' => array('type'=>'smallint', 'label'=>'DisableStockChange', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>108, 'css'=>'maxwidth50imp', 'help'=>'DisableStockChangeHelp'),
- //'efficiency' => array('type'=>'double(24,8)', 'label'=>'ManufacturingEfficiency', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'position'=>110, 'notnull'=>1, 'css'=>'maxwidth50imp', 'help'=>'ValueOfEfficiencyConsumedMeans'),
+ 'efficiency' => array('type'=>'double(24,8)', 'label'=>'ManufacturingEfficiency', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'position'=>110, 'notnull'=>1, 'css'=>'maxwidth50imp', 'help'=>'ValueOfEfficiencyConsumedMeans'),
'position' => array('type'=>'integer', 'label'=>'Rank', 'enabled'=>1, 'visible'=>0, 'default'=>0, 'position'=>200, 'notnull'=>1,),
'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>1000, 'notnull'=>-1,),
);
diff --git a/htdocs/bom/tpl/objectline_create.tpl.php b/htdocs/bom/tpl/objectline_create.tpl.php
index 7f3072d8051..445466a27a1 100644
--- a/htdocs/bom/tpl/objectline_create.tpl.php
+++ b/htdocs/bom/tpl/objectline_create.tpl.php
@@ -98,18 +98,18 @@ if (!empty($conf->product->enabled) || !empty($conf->service->enabled))
if (!empty($conf->global->ENTREPOT_EXTRA_STATUS))
{
// hide products in closed warehouse, but show products for internal transfer
- $form->select_produits(GETPOST('idprod'), 'idprod', $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, 'warehouseopen,warehouseinternal', GETPOST('combinations', 'array'));
+ $form->select_produits(GETPOST('idprod', 'int'), 'idprod', $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, 'warehouseopen,warehouseinternal', GETPOST('combinations', 'array'));
}
else
{
- $form->select_produits(GETPOST('idprod'), 'idprod', $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, '', GETPOST('combinations', 'array'));
+ $form->select_produits(GETPOST('idprod', 'int'), 'idprod', $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, '', GETPOST('combinations', 'array'));
}
echo '';
}
$coldisplay++;
-print ' ';
+print ' ';
print ' ';
if ($conf->global->PRODUCT_USE_UNITS)
@@ -128,11 +128,10 @@ $coldisplay++;
print ' ';
print ' ';
-//$coldisplay++;
-//print '';
-//print ' ';
-//print ' ';
-
+$coldisplay++;
+print '';
+print ' ';
+print ' ';
$coldisplay += $colspan;
print '';
@@ -141,7 +140,7 @@ print ' ';
print '';
if (is_object($objectline)) {
- print $objectline->showOptionals($extrafields, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1);
+ print $objectline->showOptionals($extrafields, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay), '', '', 1);
}
?>
diff --git a/htdocs/bom/tpl/objectline_edit.tpl.php b/htdocs/bom/tpl/objectline_edit.tpl.php
index 17d01e07fd9..04c84f9c1b0 100644
--- a/htdocs/bom/tpl/objectline_edit.tpl.php
+++ b/htdocs/bom/tpl/objectline_edit.tpl.php
@@ -124,9 +124,9 @@ $coldisplay++;
print ' disable_stock_change?' checked="checked"':'')).'">';
print ' ';
-//$coldisplay++;
-//print '';
-//print ' ';
+$coldisplay++;
+print '';
+print ' ';
$coldisplay+=$colspan;
print '';
@@ -138,7 +138,7 @@ print ' ';
print '';
if (is_object($objectline)) {
- print $objectline->showOptionals($extrafields, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1);
+ print $objectline->showOptionals($extrafields, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay), '', '', 1);
}
print "\n";
diff --git a/htdocs/bom/tpl/objectline_title.tpl.php b/htdocs/bom/tpl/objectline_title.tpl.php
index 706f71af7ec..138a0b9aa58 100644
--- a/htdocs/bom/tpl/objectline_title.tpl.php
+++ b/htdocs/bom/tpl/objectline_title.tpl.php
@@ -66,7 +66,7 @@ print ''.$form->textwithpicto($langs->trans('QtyFro
print ' '.$form->textwithpicto($langs->trans('DisableStockChange'), $langs->trans('DisableStockChangeHelp')).' ';
// Efficiency
-//print ''.$form->textwithpicto($langs->trans('ManufacturingEfficiency'), $langs->trans('XXX')).' ';
+print ''.$form->textwithpicto($langs->trans('ManufacturingEfficiency'), $langs->trans('ValueOfMeansLoss')).' ';
print ' '; // No width to allow autodim
diff --git a/htdocs/bom/tpl/objectline_view.tpl.php b/htdocs/bom/tpl/objectline_view.tpl.php
index 16d7d427c75..16aa5382f53 100644
--- a/htdocs/bom/tpl/objectline_view.tpl.php
+++ b/htdocs/bom/tpl/objectline_view.tpl.php
@@ -98,10 +98,10 @@ $coldisplay++;
echo $line->disable_stock_change ? yn($line->disable_stock_change) : ''; // Yes, it is a quantity, not a price, but we just want the formating role of function price
print '';
-//print '';
-//$coldisplay++;
-//echo $line->efficiency;
-//print ' ';
+print '';
+$coldisplay++;
+echo $line->efficiency;
+print ' ';
if ($this->status == 0 && ($object_rights->write) && $action != 'selectlines' ) {
print '';
@@ -156,7 +156,7 @@ print '';
//Line extrafield
if (!empty($extrafields))
{
- print $line->showOptionals($extrafields, 'view', array('style'=>'class="drag drop oddeven"', 'colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1);
+ print $line->showOptionals($extrafields, 'view', array('style'=>'class="drag drop oddeven"', 'colspan'=>$coldisplay), '', '', 1);
}
print "\n";
diff --git a/htdocs/bookmarks/bookmarks.lib.php b/htdocs/bookmarks/bookmarks.lib.php
index 8d772bf5b33..9e69eda2cd3 100644
--- a/htdocs/bookmarks/bookmarks.lib.php
+++ b/htdocs/bookmarks/bookmarks.lib.php
@@ -21,132 +21,6 @@
* \brief File with library for bookmark module
*/
-/**
- * Add area with bookmarks in menu
- *
- * @return string
- */
-function printBookmarksList()
-{
- global $conf, $user, $db, $langs;
-
- $ret = ''."\n";
-
- if (! empty($conf->use_javascript_ajax)) { // Bookmark autosubmit can't work when javascript is off.
- require_once DOL_DOCUMENT_ROOT.'/bookmarks/class/bookmark.class.php';
- if (! isset($conf->global->BOOKMARKS_SHOW_IN_MENU)) $conf->global->BOOKMARKS_SHOW_IN_MENU=5;
-
- $langs->load("bookmarks");
-
- $url= $_SERVER["PHP_SELF"];
-
- if (! empty($_SERVER["QUERY_STRING"]))
- {
- $url.=(dol_escape_htmltag($_SERVER["QUERY_STRING"])?'?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]):'');
- }
- else
- {
- global $sortfield,$sortorder;
- $tmpurl='';
- // No urlencode, all param $url will be urlencoded later
- if ($sortfield) $tmpurl.=($tmpurl?'&':'').'sortfield='.$sortfield;
- if ($sortorder) $tmpurl.=($tmpurl?'&':'').'sortorder='.$sortorder;
- if (is_array($_POST))
- {
- foreach($_POST as $key => $val)
- {
- if (preg_match('/^search_/', $key) && $val != '') $tmpurl.=($tmpurl?'&':'').$key.'='.$val;
- }
- }
- $url.=($tmpurl?'?'.$tmpurl:'');
- }
-
- // Menu bookmark
- $ret = ''."\n";
-
- $ret.= ''."\n";
- $ret.= '';
-
- $ret.=ajax_combobox('boxbookmark');
-
- $ret.='';
- }
-
- $ret.= ''."\n";
-
- return $ret;
-}
-
-
/**
* Add area with bookmarks in top menu
@@ -158,97 +32,91 @@ function printDropdownBookmarksList()
global $conf, $user, $db, $langs;
require_once DOL_DOCUMENT_ROOT.'/bookmarks/class/bookmark.class.php';
- if (! isset($conf->global->BOOKMARKS_SHOW_IN_MENU)) $conf->global->BOOKMARKS_SHOW_IN_MENU=5;
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
$langs->load("bookmarks");
- $url= $_SERVER["PHP_SELF"];
+ $url = $_SERVER["PHP_SELF"];
- if (! empty($_SERVER["QUERY_STRING"]))
+ if (!empty($_SERVER["QUERY_STRING"]))
{
- $url.=(dol_escape_htmltag($_SERVER["QUERY_STRING"])?'?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]):'');
+ $url .= (dol_escape_htmltag($_SERVER["QUERY_STRING"]) ? '?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]) : '');
}
else
{
- global $sortfield,$sortorder;
- $tmpurl='';
+ global $sortfield, $sortorder;
+ $tmpurl = '';
// No urlencode, all param $url will be urlencoded later
- if ($sortfield) $tmpurl.=($tmpurl?'&':'').'sortfield='.$sortfield;
- if ($sortorder) $tmpurl.=($tmpurl?'&':'').'sortorder='.$sortorder;
+ if ($sortfield) $tmpurl .= ($tmpurl ? '&' : '').'sortfield='.$sortfield;
+ if ($sortorder) $tmpurl .= ($tmpurl ? '&' : '').'sortorder='.$sortorder;
if (is_array($_POST))
{
- foreach($_POST as $key => $val)
+ foreach ($_POST as $key => $val)
{
- if (preg_match('/^search_/', $key) && $val != '') $tmpurl.=($tmpurl?'&':'').$key.'='.$val;
+ if (preg_match('/^search_/', $key) && $val != '') $tmpurl .= ($tmpurl ? '&' : '').$key.'='.$val;
}
}
- $url.=($tmpurl?'?'.$tmpurl:'');
+ $url .= ($tmpurl ? '?'.$tmpurl : '');
}
$searchForm = ''."\n";
- $searchForm.= '';
+ $searchForm .= '';
// Url to list bookmark
$listbtn = '';
+ $listbtn .= ' '.$langs->trans('Bookmarks').'';
// Url to go on create new bookmark page
$newbtn = '';
- if (! empty($user->rights->bookmark->creer))
+ if (!empty($user->rights->bookmark->creer))
{
//$urltoadd=DOL_URL_ROOT.'/bookmarks/card.php?action=create&urlsource='.urlencode($url).'&url='.urlencode($url);
- $urltoadd=DOL_URL_ROOT.'/bookmarks/card.php?action=create&url='.urlencode($url);
- $newbtn.= '';
+ $urltoadd = DOL_URL_ROOT.'/bookmarks/card.php?action=create&url='.urlencode($url);
+ $newbtn .= '';
}
-
- $bookmarkList='';
- // Menu with all bookmarks
- if (! empty($conf->global->BOOKMARKS_SHOW_IN_MENU))
+ $bookmarkList = '
';
+ else
+ {
+ dol_print_error($db);
+ }
+ $bookmarkList .= '
';
- $html= '';
- if (! empty($conf->global->BOOKMARKS_SHOW_IN_MENU)) {
- $html.= '
+ $html = '
';
- }
- $html.= '
+ $html .= '
'.$bookmarkList.'
';
- $html.= '
+ $html .= '
';
- if (! empty($conf->global->BOOKMARKS_SHOW_IN_MENU)) {
- $html .= '';
- }
return $html;
}
diff --git a/htdocs/bookmarks/list.php b/htdocs/bookmarks/list.php
index 4e9d6851399..067e2abeaa9 100644
--- a/htdocs/bookmarks/list.php
+++ b/htdocs/bookmarks/list.php
@@ -44,7 +44,7 @@ $optioncss = GETPOST('optioncss', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/cashdesk/tpl/facturation1.tpl.php b/htdocs/cashdesk/tpl/facturation1.tpl.php
index f3b76cbaed6..f1e19b4df20 100644
--- a/htdocs/cashdesk/tpl/facturation1.tpl.php
+++ b/htdocs/cashdesk/tpl/facturation1.tpl.php
@@ -21,14 +21,14 @@
*/
// Protection to avoid direct call of template
-if (empty($langs) || ! is_object($langs))
+if (empty($langs) || !is_object($langs))
{
print "Error, template page can't be called as URL";
exit;
}
// Load translation files required by the page
-$langs->loadLangs(array("main","bills","cashdesk"));
+$langs->loadLangs(array("main", "bills", "cashdesk"));
// Object $form must de defined
@@ -64,7 +64,7 @@ $id = $obj_facturation->id();
// Si trop d'articles ont ete trouves, on n'affiche que les X premiers (defini dans le fichier de configuration) ...
$nbtoshow = $nbr_enreg;
-if (! empty($conf_taille_listes) && $nbtoshow > $conf_taille_listes) $nbtoshow = $conf_taille_listes;
+if (!empty($conf_taille_listes) && $nbtoshow > $conf_taille_listes) $nbtoshow = $conf_taille_listes;
for ($i = 0; $i < $nbtoshow; $i++)
{
@@ -77,8 +77,8 @@ for ($i = 0; $i < $nbtoshow; $i++)
$label = $tab_designations[$i]['label'];
print ''.dol_trunc($tab_designations[$i]['ref'], 16).' - '.dol_trunc($label, 35, 'middle');
- if (! empty($conf->stock->enabled) && !empty($conf_fkentrepot) && $tab_designations[$i]['fk_product_type']==0) {
- print ' ('.$langs->trans("CashDeskStock").': '.(empty($tab_designations[$i]['reel'])?0:$tab_designations[$i]['reel']).')';
+ if (!empty($conf->stock->enabled) && !empty($conf_fkentrepot) && $tab_designations[$i]['fk_product_type'] == 0) {
+ print ' ('.$langs->trans("CashDeskStock").': '.(empty($tab_designations[$i]['reel']) ? 0 : $tab_designations[$i]['reel']).')';
}
print ' '."\n";
}
@@ -101,23 +101,23 @@ for ($i = 0; $i < $nbtoshow; $i++)
-
+
-
+
vatrate; // To get vat rate we just have selected
+ $vatrate = $obj_facturation->vatrate; // To get vat rate we just have selected
$buyer = new Societe($db);
if ($_SESSION["CASHDESK_ID_THIRDPARTY"] > 0) $buyer->fetch($_SESSION["CASHDESK_ID_THIRDPARTY"]);
- echo $form->load_tva('selTva', (isset($_POST["selTva"])?GETPOST("selTva", 'alpha', 2):$vatrate), $mysoc, $buyer, 0, 0, '', false, -1);
+ echo $form->load_tva('selTva', (GETPOSTISSET("selTva") ? GETPOST("selTva", 'alpha', 2) : $vatrate), $mysoc, $buyer, 0, 0, '', false, -1);
?>
@@ -152,7 +152,7 @@ for ($i = 0; $i < $nbtoshow; $i++)
-
+
diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php
index 39f94db02eb..e8296b96beb 100644
--- a/htdocs/categories/class/categorie.class.php
+++ b/htdocs/categories/class/categorie.class.php
@@ -167,8 +167,9 @@ class Categorie extends CommonObject
'member' => 'adherent',
'contact' => 'socpeople',
'user' => 'user',
- 'account' => 'bank_account',
- 'project' => 'projet',
+ 'account' => 'bank_account', // old for bank account
+ 'bank_account' => 'bank_account',
+ 'project' => 'projet',
'warehouse'=> 'entrepot',
'actioncomm' => 'actioncomm',
);
@@ -774,7 +775,7 @@ class Categorie extends CommonObject
/**
* Return list of fetched instance of elements having this category
*
- * @param string $type Type of category ('customer', 'supplier', 'contact', 'product', 'member')
+ * @param string $type Type of category ('customer', 'supplier', 'contact', 'product', 'member', ...)
* @param int $onlyids Return only ids of objects (consume less memory)
* @param int $limit Limit
* @param int $offset Offset
@@ -1911,8 +1912,8 @@ class Categorie extends CommonObject
/**
* Return label of contact status
*
- * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
- * @return string Label of contact status
+ * @param int $mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto, 6=Long label + Picto
+ * @return string Label of contact status
*/
public function getLibStatut($mode)
{
@@ -1957,4 +1958,59 @@ class Categorie extends CommonObject
return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables, 1);
}
+
+ /**
+ * Return the addtional SQL JOIN query for filtering a list by a category
+ *
+ * @param string $type The category type (e.g Categorie::TYPE_WAREHOUSE)
+ * @param string $rowIdName The name of the row id inside the whole sql query (e.g. "e.rowid")
+ * @return string A additional SQL JOIN query
+ */
+ public static function getFilterJoinQuery($type, $rowIdName)
+ {
+ if ($type == 'bank_account') $type = 'account';
+
+ return " LEFT JOIN ".MAIN_DB_PREFIX."categorie_".$type." as cp ON ".$rowIdName." = cp.fk_".$type;
+ }
+
+ /**
+ * Return the addtional SQL SELECT query for filtering a list by a category
+ *
+ * @param string $type The category type (e.g Categorie::TYPE_WAREHOUSE)
+ * @param string $rowIdName The name of the row id inside the whole sql query (e.g. "e.rowid")
+ * @param Array $searchList A list with the selected categories
+ * @return string A additional SQL SELECT query
+ */
+ public static function getFilterSelectQuery($type, $rowIdName, $searchList)
+ {
+ if ($type == 'bank_account') $type = 'account';
+
+ if (empty($searchList) && !is_array($searchList))
+ {
+ return "";
+ }
+
+ foreach ($searchList as $searchCategory)
+ {
+ if (intval($searchCategory) == -2)
+ {
+ $searchCategorySqlList[] = " cp.fk_categorie IS NULL";
+ }
+ elseif (intval($searchCategory) > 0)
+ {
+ $searchCategorySqlList[] = " ".$rowIdName
+ ." IN (SELECT fk_".$type." FROM ".MAIN_DB_PREFIX."categorie_".$type
+ ." WHERE fk_categorie = ".$searchCategory.")";
+ }
+ }
+
+ if (!empty($searchCategorySqlList))
+ {
+ return " AND (".implode(' AND ', $searchCategorySqlList).")";
+ }
+ else
+ {
+ return "";
+ }
+ }
}
diff --git a/htdocs/categories/index.php b/htdocs/categories/index.php
index c71be0cd919..d96fddca150 100644
--- a/htdocs/categories/index.php
+++ b/htdocs/categories/index.php
@@ -182,23 +182,13 @@ foreach ($fulltree as $key => $val)
$li = $categstatic->getNomUrl(1, '', 60);
$desc = dol_htmlcleanlastbr($val['description']);
+ $counter = '';
+
if($conf->global->CATEGORY_SHOW_COUNTS)
{
// we need only a count of the elements, so it is enough to consume only the id's from the database
- if ($type == Categorie::TYPE_PRODUCT) $elements = $categstatic->getObjectsInCateg("product", 1);
- if ($type == Categorie::TYPE_SUPPLIER) $elements = $categstatic->getObjectsInCateg("supplier", 1);
- if ($type == Categorie::TYPE_CUSTOMER) $elements = $categstatic->getObjectsInCateg("customer", 1);
- if ($type == Categorie::TYPE_MEMBER) $elements = $categstatic->getObjectsInCateg("member", 1);
- if ($type == Categorie::TYPE_CONTACT) $elements = $categstatic->getObjectsInCateg("contact", 1);
- if ($type == Categorie::TYPE_ACCOUNT) $elements = $categstatic->getObjectsInCateg("account", 1);
- if ($type == Categorie::TYPE_PROJECT) $elements = $categstatic->getObjectsInCateg("project", 1);
- if ($type == Categorie::TYPE_USER) $elements = $categstatic->getObjectsInCateg("user", 1);
-
- $counter = "".count($elements)." ";
- }
- else
- {
- $counter = "";
+ $elements = $categstatic->getObjectsInCateg($type, 1);
+ $counter = "".(is_countable($elements) ? count($elements) : '0')." ";
}
$data[] = array(
diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php
index 5d81ccd7d63..62538da0273 100644
--- a/htdocs/categories/viewcat.php
+++ b/htdocs/categories/viewcat.php
@@ -55,7 +55,7 @@ $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php
index c17f9cc9c1b..07cd885698e 100644
--- a/htdocs/comm/action/card.php
+++ b/htdocs/comm/action/card.php
@@ -840,7 +840,7 @@ if ($action == 'create')
print ' ';
print ' ';
print ' ';
- if ($backtopage) print ' ';
+ if ($backtopage) print ' ';
if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) print ' ';
if (GETPOST("actioncode", 'aZ09') == 'AC_RDV') print load_fiche_titre($langs->trans("AddActionRendezVous"), '', 'title_agenda');
@@ -1070,7 +1070,7 @@ if ($action == 'create')
$numproject = $formproject->select_projects((!empty($societe->id) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1);
print ' ';
- $urloption = '?action=create';
+ $urloption = '?action=create&donotclearsession=1';
$url = dol_buildpath('comm/action/card.php', 2).$urloption;
// update task list
@@ -1249,7 +1249,7 @@ if ($id > 0)
print ' ';
print ' ';
print ' ';
- if ($backtopage) print ' ';
+ if ($backtopage) print ' ';
if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) print ' ';
dol_fiche_head($head, 'card', $langs->trans("Action"), 0, 'action');
@@ -1479,10 +1479,10 @@ if ($id > 0)
$langs->load("projects");
print ' '.$langs->trans("Project").' ';
- $numprojet = $formproject->select_projects(($object->socid > 0 ? $object->socid : -1), $object->fk_project, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0);
+ $numprojet = $formproject->select_projects(($object->socid > 0 ? $object->socid : -1), $object->fk_project, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, 'maxwidth500');
if ($numprojet == 0)
{
- print ' id.'&action=edit').'">'.$langs->trans("AddProject").' ';
+ print ' id.'&action=edit').'"> ';
}
print ' ';
}
@@ -1503,7 +1503,7 @@ if ($id > 0)
{
print '';
- $urloption = '?action=create'; // we use create not edit for more flexibility
+ $urloption = '?action=create&donotclearsession=1'; // we use create not edit for more flexibility
$url = DOL_URL_ROOT.'/comm/action/card.php'.$urloption;
// update task list
@@ -1825,7 +1825,7 @@ if ($id > 0)
// Description
print ' '.$langs->trans("Description").' ';
- print dol_htmlentitiesbr($object->note);
+ print dol_string_onlythesehtmltags(dol_htmlentitiesbr($object->note_private));
print ' ';
// Other attributes
diff --git a/htdocs/comm/action/document.php b/htdocs/comm/action/document.php
index f01f49921e7..31f608a9ee0 100644
--- a/htdocs/comm/action/document.php
+++ b/htdocs/comm/action/document.php
@@ -64,7 +64,7 @@ if ($id > 0)
// Get parameters
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php
index 31808d35991..b480586bc6a 100644
--- a/htdocs/comm/action/index.php
+++ b/htdocs/comm/action/index.php
@@ -58,7 +58,7 @@ if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS))
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", "int");
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$offset = $limit * $page;
diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php
index 3ac82178810..e388bb25fb0 100644
--- a/htdocs/comm/action/list.php
+++ b/htdocs/comm/action/list.php
@@ -43,7 +43,7 @@ $action = GETPOST('action', 'alpha');
$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'actioncommlist'; // To manage different context of search
$resourceid = GETPOST("search_resourceid", "int") ?GETPOST("search_resourceid", "int") : GETPOST("resourceid", "int");
$pid = GETPOST("search_projectid", 'int', 3) ?GETPOST("search_projectid", 'int', 3) : GETPOST("projectid", 'int', 3);
-$status = (GETPOST("search_status", 'alpha') != '') ?GETPOST("search_status", 'alpha') : GETPOST("status", 'alpha');
+$search_status = (GETPOST("search_status", 'alpha') != '') ?GETPOST("search_status", 'alpha') : GETPOST("status", 'alpha');
$type = GETPOST('search_type', 'alphanohtml') ?GETPOST('search_type', 'alphanohtml') : GETPOST('type', 'alphanohtml');
$optioncss = GETPOST('optioncss', 'alpha');
$year = GETPOST("year", 'int');
@@ -67,8 +67,8 @@ $search_note = GETPOST('search_note', 'alpha');
$dateselect = dol_mktime(0, 0, 0, GETPOST('dateselectmonth', 'int'), GETPOST('dateselectday', 'int'), GETPOST('dateselectyear', 'int'));
$datestart = dol_mktime(0, 0, 0, GETPOST('datestartmonth', 'int'), GETPOST('datestartday', 'int'), GETPOST('datestartyear', 'int'));
$dateend = dol_mktime(0, 0, 0, GETPOST('dateendmonth', 'int'), GETPOST('dateendday', 'int'), GETPOST('dateendyear', 'int'));
-if ($status == '' && !isset($_GET['status']) && !isset($_POST['status'])) $status = (empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS);
-if (empty($action) && !isset($_GET['action']) && !isset($_POST['action'])) $action = (empty($conf->global->AGENDA_DEFAULT_VIEW) ? 'show_month' : $conf->global->AGENDA_DEFAULT_VIEW);
+if ($search_status == '' && !GETPOSTISSET('search_status')) $search_status = (empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS);
+if (empty($action) && !GETPOSTISSET('action')) $action = (empty($conf->global->AGENDA_DEFAULT_VIEW) ? 'show_month' : $conf->global->AGENDA_DEFAULT_VIEW);
$filter = GETPOST("search_filter", 'alpha', 3) ?GETPOST("search_filter", 'alpha', 3) : GETPOST("filter", 'alpha', 3);
$filtert = GETPOST("search_filtert", "int", 3) ?GETPOST("search_filtert", "int", 3) : GETPOST("filtert", "int", 3);
@@ -94,18 +94,18 @@ if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS))
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if ($page == -1 || $page == null) { $page = 0; }
$offset = $limit * $page;
if (!$sortorder)
{
$sortorder = "DESC,DESC";
- if ($status == 'todo') $sortorder = "DESC,DESC";
+ if ($search_status == 'todo') $sortorder = "DESC,DESC";
}
if (!$sortfield)
{
$sortfield = "a.datep,a.id";
- if ($status == 'todo') $sortfield = "a.datep,a.id";
+ if ($search_status == 'todo') $sortfield = "a.datep,a.id";
}
// Security check
@@ -184,7 +184,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
$search_note = '';
$datestart = '';
$dateend = '';
- $status = '';
+ $search_status = '';
$search_array_options = array();
}
@@ -218,7 +218,7 @@ if ($actioncode != '') {
} else $param .= "&search_actioncode=".urlencode($actioncode);
}
if ($resourceid > 0) $param .= "&search_resourceid=".urlencode($resourceid);
-if ($status != '' && $status > -1) $param .= "&search_status=".urlencode($status);
+if ($search_status != '' && $search_status > -1) $param .= "&search_status=".urlencode($search_status);
if ($filter) $param .= "&search_filter=".urlencode($filter);
if ($filtert) $param .= "&search_filtert=".urlencode($filtert);
if ($socid) $param .= "&search_socid=".urlencode($socid);
@@ -309,12 +309,12 @@ if ($socid > 0) $sql .= " AND s.rowid = ".$socid;
// We must filter on assignement table
if ($filtert > 0 || $usergroup > 0) $sql .= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'";
if ($type) $sql .= " AND c.id = ".(int) $type;
-if ($status == '0') { $sql .= " AND a.percent = 0"; }
-if ($status == '-1') { $sql .= " AND a.percent = -1"; } // Not applicable
-if ($status == '50') { $sql .= " AND (a.percent > 0 AND a.percent < 100)"; } // Running already started
-if ($status == '100') { $sql .= " AND a.percent = 100"; }
-if ($status == 'done') { $sql .= " AND (a.percent = 100)"; }
-if ($status == 'todo') { $sql .= " AND (a.percent >= 0 AND a.percent < 100)"; }
+if ($search_status == '0') { $sql .= " AND a.percent = 0"; }
+if ($search_status == '-1') { $sql .= " AND a.percent = -1"; } // Not applicable
+if ($search_status == '50') { $sql .= " AND (a.percent > 0 AND a.percent < 100)"; } // Running already started
+if ($search_status == '100') { $sql .= " AND a.percent = 100"; }
+if ($search_status == 'done') { $sql .= " AND (a.percent = 100)"; }
+if ($search_status == 'todo') { $sql .= " AND (a.percent >= 0 AND a.percent < 100)"; }
if ($search_id) $sql .= natural_search("a.id", $search_id, 1);
if ($search_title) $sql .= natural_search("a.label", $search_title);
if ($search_note) $sql .= natural_search('a.note', $search_note);
@@ -397,7 +397,7 @@ if ($resql)
print $nav;
dol_fiche_head($head, $tabactive, $langs->trans('Agenda'), 0, 'action');
- print_actions_filter($form, $canedit, $status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid);
+ print_actions_filter($form, $canedit, $search_status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid);
dol_fiche_end();
// Add link to show birthdays
@@ -488,8 +488,8 @@ if ($resql)
if (!empty($arrayfields['a.tms']['checked'])) print ' ';
if (!empty($arrayfields['a.percent']['checked'])) {
print '';
- $formactions->form_select_status_action('formaction', $status, 1, 'status', 1, 2, 'minwidth100imp maxwidth125');
- print ajax_combobox('selectstatus');
+ $formactions->form_select_status_action('formaction', $search_status, 1, 'search_status', 1, 2, 'minwidth100imp maxwidth125');
+ print ajax_combobox('selectsearch_status');
print ' ';
}
// Action column
diff --git a/htdocs/comm/action/pertype.php b/htdocs/comm/action/pertype.php
index 04f334a9551..b1d0ddc7ccc 100644
--- a/htdocs/comm/action/pertype.php
+++ b/htdocs/comm/action/pertype.php
@@ -56,7 +56,7 @@ if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS))
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", "int");
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$offset = $limit * $page;
diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php
index f906c4cab45..e8f7be097fa 100644
--- a/htdocs/comm/action/peruser.php
+++ b/htdocs/comm/action/peruser.php
@@ -56,7 +56,7 @@ $showbirthday = 0;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", "int");
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$offset = $limit * $page;
diff --git a/htdocs/comm/action/rapport/index.php b/htdocs/comm/action/rapport/index.php
index 92744da332c..b9ab38a734e 100644
--- a/htdocs/comm/action/rapport/index.php
+++ b/htdocs/comm/action/rapport/index.php
@@ -41,7 +41,7 @@ $year=GETPOST('year');
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if ($page == -1 || $page == null) { $page = 0 ; }
$offset = $limit * $page ;
if (! $sortorder) $sortorder="DESC";
diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php
index b5164d6078c..f1ea3c0923d 100644
--- a/htdocs/comm/card.php
+++ b/htdocs/comm/card.php
@@ -67,7 +67,7 @@ $mode = GETPOST("mode");
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
@@ -666,7 +666,7 @@ if ($object->id > 0)
$now = dol_now();
/*
- * Last proposals
+ * Latest proposals
*/
if (!empty($conf->propal->enabled) && $user->rights->propal->lire)
{
@@ -738,7 +738,7 @@ if ($object->id > 0)
}
/*
- * Last orders
+ * Latest orders
*/
if (!empty($conf->commande->enabled) && $user->rights->commande->lire)
{
@@ -751,7 +751,7 @@ if ($object->id > 0)
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as c";
$sql .= " WHERE c.fk_soc = s.rowid ";
$sql .= " AND s.rowid = ".$object->id;
- $sql .= " AND c.entity = ".$conf->entity;
+ $sql .= " AND c.entity IN (".getEntity('commande').')';
$sql .= " ORDER BY c.date_commande DESC";
$resql = $db->query($sql);
@@ -824,7 +824,7 @@ if ($object->id > 0)
}
/*
- * Last shipments
+ * Latest shipments
*/
if (!empty($conf->expedition->enabled) && $user->rights->expedition->lire)
{
@@ -897,7 +897,7 @@ if ($object->id > 0)
}
/*
- * Last linked contracts
+ * Latest linked contracts
*/
if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire)
{
@@ -905,7 +905,7 @@ if ($object->id > 0)
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as c";
$sql .= " WHERE c.fk_soc = s.rowid ";
$sql .= " AND s.rowid = ".$object->id;
- $sql .= " AND c.entity = ".$conf->entity;
+ $sql .= " AND c.entity IN (".getEntity('contract').")";
$sql .= " ORDER BY c.datec DESC";
$resql = $db->query($sql);
@@ -967,7 +967,7 @@ if ($object->id > 0)
}
/*
- * Last interventions
+ * Latest interventions
*/
if (!empty($conf->ficheinter->enabled) && $user->rights->ficheinter->lire)
{
@@ -975,7 +975,7 @@ if ($object->id > 0)
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as f";
$sql .= " WHERE f.fk_soc = s.rowid";
$sql .= " AND s.rowid = ".$object->id;
- $sql .= " AND f.entity = ".$conf->entity;
+ $sql .= " AND f.entity IN (".getEntity('intervention').")";
$sql .= " ORDER BY f.tms DESC";
$resql = $db->query($sql);
@@ -1028,7 +1028,7 @@ if ($object->id > 0)
}
/*
- * Last invoices templates
+ * Latest invoices templates
*/
if (!empty($conf->facture->enabled) && $user->rights->facture->lire)
{
@@ -1044,7 +1044,7 @@ if ($object->id > 0)
$sql .= ', s.nom, s.rowid as socid';
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture_rec as f";
$sql .= " WHERE f.fk_soc = s.rowid AND s.rowid = ".$object->id;
- $sql .= " AND f.entity = ".$conf->entity;
+ $sql .= " AND f.entity IN (".getEntity('invoice').")";
$sql .= ' GROUP BY f.rowid, f.titre, f.total, f.tva, f.total_ttc,';
$sql .= ' f.date_last_gen, f.datec, f.frequency, f.unit_frequency,';
$sql .= ' f.suspended, f.date_when,';
@@ -1063,7 +1063,7 @@ if ($object->id > 0)
print '';
print '';
- print ''.$langs->trans("LatestCustomerTemplateInvoices", ($num <= $MAXLIST ? "" : $MAXLIST)).' '.$langs->trans("AllCustomerTemplateInvoices").''.$num.' ';
+ print ' ';
print ' ';
}
diff --git a/htdocs/comm/contact.php b/htdocs/comm/contact.php
index 8b3f4cf4894..3121bc3f1b9 100644
--- a/htdocs/comm/contact.php
+++ b/htdocs/comm/contact.php
@@ -31,7 +31,7 @@ $langs->load("companies");
$sortfield=GETPOST('sortfield', 'alpha');
$sortorder=GETPOST('sortorder', 'alpha');
-$page=GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (! $sortorder) $sortorder="ASC";
if (! $sortfield) $sortfield="p.name";
if ($page < 0) { $page = 0; }
diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php
index f20197df4dd..0bb38aeaa38 100644
--- a/htdocs/comm/index.php
+++ b/htdocs/comm/index.php
@@ -4,6 +4,7 @@
* Copyright (C) 2005-2012 Regis Houssin
* Copyright (C) 2015 Jean-François Ferry
* Copyright (C) 2019 Nicolas ZABOURI
+ * Copyright (C) 2020 Pierre Ardoin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -149,6 +150,9 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire)
$sql = "SELECT p.rowid, p.ref, p.ref_client, p.total_ht, p.tva as total_tva, p.total as total_ttc, s.rowid as socid, s.nom as name, s.client, s.canvas";
$sql .= ", s.code_client";
+ $sql .= ", s.email";
+ $sql .= ", s.entity";
+ $sql .= ", s.code_compta";
$sql .= " FROM ".MAIN_DB_PREFIX."propal as p";
$sql .= ", ".MAIN_DB_PREFIX."societe as s";
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
@@ -193,6 +197,9 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire)
$companystatic->code_client = $obj->code_client;
$companystatic->code_fournisseur = $obj->code_fournisseur;
$companystatic->canvas = $obj->canvas;
+ $companystatic->entity = $obj->entity;
+ $companystatic->email = $obj->email;
+ $companystatic->code_compta = $obj->code_compta;
print $companystatic->getNomUrl(1, 'customer', 16);
print '';
print ''.price($obj->total_ht).' ';
@@ -233,6 +240,9 @@ if (!empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposa
$sql = "SELECT p.rowid, p.ref, p.total_ht, p.tva as total_tva, p.total as total_ttc, s.rowid as socid, s.nom as name, s.client, s.canvas";
$sql .= ", s.code_client";
+ $sql .= ", s.code_fournisseur";
+ $sql .= ", s.entity";
+ $sql .= ", s.email";
$sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal as p";
$sql .= ", ".MAIN_DB_PREFIX."societe as s";
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
@@ -276,6 +286,8 @@ if (!empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposa
$companystatic->code_client = $obj->code_client;
$companystatic->code_fournisseur = $obj->code_fournisseur;
$companystatic->canvas = $obj->canvas;
+ $companystatic->entity = $obj->entity;
+ $companystatic->email = $obj->email;
print $companystatic->getNomUrl(1, 'supplier', 16);
print '';
print ''.price($obj->total_ht).' ';
@@ -315,6 +327,9 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire)
$sql = "SELECT c.rowid, c.ref, c.ref_client, c.total_ht, c.tva as total_tva, c.total_ttc, s.rowid as socid, s.nom as name, s.client, s.canvas";
$sql .= ", s.code_client";
+ $sql .= ", s.email";
+ $sql .= ", s.entity";
+ $sql .= ", s.code_compta";
$sql .= " FROM ".MAIN_DB_PREFIX."commande as c";
$sql .= ", ".MAIN_DB_PREFIX."societe as s";
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
@@ -358,6 +373,8 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire)
$companystatic->code_client = $obj->code_client;
$companystatic->code_fournisseur = $obj->code_fournisseur;
$companystatic->canvas = $obj->canvas;
+ $companystatic->email = $obj->email;
+ $companystatic->entity = $obj->entity;
print $companystatic->getNomUrl(1, 'customer', 16);
print '';
if (!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT)) {
@@ -404,6 +421,8 @@ if (!empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande-
$sql = "SELECT cf.rowid, cf.ref, cf.ref_supplier, cf.total_ttc, s.rowid as socid, s.nom as name, s.client, s.canvas";
$sql .= ", s.code_client";
$sql .= ", s.code_fournisseur";
+ $sql .= ", s.entity";
+ $sql .= ", s.email";
$sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as cf";
$sql .= ", ".MAIN_DB_PREFIX."societe as s";
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
@@ -447,6 +466,8 @@ if (!empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande-
$companystatic->code_client = $obj->code_client;
$companystatic->code_fournisseur = $obj->code_fournisseur;
$companystatic->canvas = $obj->canvas;
+ $companystatic->entity = $obj->entity;
+ $companystatic->email = $obj->email;
print $companystatic->getNomUrl(1, 'supplier', 16);
print '';
if (!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT)) {
@@ -496,6 +517,9 @@ if (!empty($conf->societe->enabled) && $user->rights->societe->lire)
$sql = "SELECT s.rowid, s.nom as name, s.client, s.datec, s.tms, s.canvas";
$sql .= ", s.code_client";
+ $sql .= ", s.code_compta";
+ $sql .= ", s.entity";
+ $sql .= ", s.email";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql .= " WHERE s.client IN (1, 2, 3)";
@@ -532,6 +556,9 @@ if (!empty($conf->societe->enabled) && $user->rights->societe->lire)
$companystatic->code_client = $objp->code_client;
$companystatic->code_fournisseur = $objp->code_fournisseur;
$companystatic->canvas = $objp->canvas;
+ $companystatic->code_compta = $objp->code_compta;
+ $companystatic->entity = $objp->entity;
+ $companystatic->email = $objp->email;
print '';
print ''.$companystatic->getNomUrl(1, 'customer', 48).' ';
print '';
@@ -560,6 +587,8 @@ if (!empty($conf->fournisseur->enabled) && $user->rights->societe->lire)
$sql = "SELECT s.nom as name, s.rowid, s.datec as dc, s.canvas, s.tms as dm";
$sql .= ", s.code_fournisseur";
+ $sql .= ", s.entity";
+ $sql .= ", s.email";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql .= " WHERE s.fournisseur = 1";
@@ -591,6 +620,8 @@ if (!empty($conf->fournisseur->enabled) && $user->rights->societe->lire)
$companystatic->code_client = $objp->code_client;
$companystatic->code_fournisseur = $objp->code_fournisseur;
$companystatic->canvas = $objp->canvas;
+ $companystatic->entity = $objp->entity;
+ $companystatic->email = $objp->email;
print ' ';
print ''.$companystatic->getNomUrl(1, 'supplier', 44).' ';
print ''.dol_print_date($db->jdate($objp->dm), 'day').' ';
@@ -628,7 +659,7 @@ if ($user->rights->agenda->myactions->read)
/*
- * Last contracts
+ * Latest contracts
*/
if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire && 0) // TODO A REFAIRE DEPUIS NOUVEAU CONTRAT
{
@@ -636,7 +667,9 @@ if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire && 0) // TOD
$sql = "SELECT s.nom as name, s.rowid, s.canvas, ";
$sql .= ", s.code_client";
- $sql .= " c.statut, c.rowid as contratid, p.ref, c.fin_validite as datefin, c.date_cloture as dateclo";
+ $sql .= ", s.entity";
+ $sql .= ", s.email";
+ $sql .= ", c.statut, c.rowid as contratid, p.ref, c.fin_validite as datefin, c.date_cloture as dateclo";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
$sql .= ", ".MAIN_DB_PREFIX."contrat as c";
$sql .= ", ".MAIN_DB_PREFIX."product as p";
@@ -673,6 +706,8 @@ if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire && 0) // TOD
$companystatic->code_client = $objp->code_client;
$companystatic->code_fournisseur = $objp->code_fournisseur;
$companystatic->canvas = $objp->canvas;
+ $companystatic->entity = $objp->entity;
+ $companystatic->email = $objp->email;
print $companystatic->getNomUrl(1, 'customer', 44);
print ''."\n";
print "".$staticcontrat->LibStatut($obj->statut, 3)." \n";
@@ -697,6 +732,8 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire)
$langs->load("propal");
$sql = "SELECT s.nom as name, s.rowid, s.code_client";
+ $sql .= ", s.entity";
+ $sql .= ", s.email";
$sql .= ", p.rowid as propalid, p.entity, p.total as total_ttc, p.total_ht, p.tva as total_tva, p.ref, p.ref_client, p.fk_statut, p.datep as dp, p.fin_validite as dfv";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
$sql .= ", ".MAIN_DB_PREFIX."propal as p";
@@ -760,6 +797,8 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire)
$companystatic->code_client = $obj->code_client;
$companystatic->code_fournisseur = $obj->code_fournisseur;
$companystatic->canvas = $obj->canvas;
+ $companystatic->entity = $obj->entity;
+ $companystatic->email = $obj->email;
print $companystatic->getNomUrl(1, 'customer', 44);
print '';
print '';
@@ -802,6 +841,8 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire)
$sql = "SELECT s.nom as name, s.rowid, c.rowid as commandeid, c.total_ttc, c.total_ht, c.tva as total_tva, c.ref, c.ref_client, c.fk_statut, c.date_valid as dv, c.facture as billed";
$sql .= ", s.code_client";
+ $sql .= ", s.entity";
+ $sql .= ", s.email";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
$sql .= ", ".MAIN_DB_PREFIX."commande as c";
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
@@ -864,6 +905,8 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire)
$companystatic->code_client = $obj->code_client;
$companystatic->code_fournisseur = $obj->code_fournisseur;
$companystatic->canvas = $obj->canvas;
+ $companystatic->entity = $obj->entity;
+ $companystatic->email = $obj->email;
print $companystatic->getNomUrl(1, 'customer', 44);
print ' ';
print '';
diff --git a/htdocs/comm/mailing/advtargetemailing.php b/htdocs/comm/mailing/advtargetemailing.php
index b85826339e5..b716790aa8f 100644
--- a/htdocs/comm/mailing/advtargetemailing.php
+++ b/htdocs/comm/mailing/advtargetemailing.php
@@ -48,7 +48,7 @@ if (!$user->rights->mailing->lire || $user->socid > 0)
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php
index 3dcfdf9e451..9babe88fd0b 100644
--- a/htdocs/comm/mailing/cibles.php
+++ b/htdocs/comm/mailing/cibles.php
@@ -43,7 +43,7 @@ if (!$user->rights->mailing->lire || $user->socid > 0) accessforbidden();
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
@@ -673,7 +673,8 @@ if ($object->fetch($id) >= 0)
// Date sent
print ' ';
- print ''.$langs->trans("MailingStatusNotSent");
+ print ' ';
+ print $object::libStatutDest($obj->statut, 2, '');
print ' ';
}
else
diff --git a/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php b/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php
index f5acafcfb19..b9782515735 100644
--- a/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php
+++ b/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php
@@ -65,7 +65,7 @@ class FormAdvTargetEmailing extends Form
$sql .= " FROM ".MAIN_DB_PREFIX."c_prospectlevel";
$sql .= " WHERE active > 0";
$sql .= " ORDER BY sortorder";
- dol_syslog(get_class($this).'::multiselectProspectionStatus sql='.$sql, LOG_DEBUG);
+
$resql = $this->db->query($sql);
if ($resql) {
$num = $this->db->num_rows($resql);
@@ -111,7 +111,6 @@ class FormAdvTargetEmailing extends Form
$sql .= " WHERE active = 1 AND code<>''";
$sql .= " ORDER BY code ASC";
- dol_syslog(get_class($this)."::select_country sql=".$sql);
$resql = $this->db->query($sql);
if ($resql) {
$num = $this->db->num_rows($resql);
@@ -260,7 +259,6 @@ class FormAdvTargetEmailing extends Form
}
// $sql.= ' WHERE entity = '.$conf->entity;
- dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql) {
$num = $this->db->num_rows($resql);
@@ -297,7 +295,7 @@ class FormAdvTargetEmailing extends Form
$sql = "SELECT rowid, code, label as civilite, active FROM ".MAIN_DB_PREFIX."c_civility";
$sql .= " WHERE active = 1";
- dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql)
{
@@ -385,7 +383,7 @@ class FormAdvTargetEmailing extends Form
$sql = "SELECT rowid, label FROM ".MAIN_DB_PREFIX."categorie";
$sql .= " WHERE type=".$type;
- dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql)
{
@@ -432,10 +430,10 @@ class FormAdvTargetEmailing extends Form
$sql .= " WHERE type_element='$type_element'";
$sql .= " ORDER BY c.name";
- dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql) {
- $out .= '';
+ $out .= '';
if ($showempty)
$out .= ' ';
$num = $this->db->num_rows($resql);
diff --git a/htdocs/comm/mailing/class/mailing.class.php b/htdocs/comm/mailing/class/mailing.class.php
index 32637096910..553c5e79c15 100644
--- a/htdocs/comm/mailing/class/mailing.class.php
+++ b/htdocs/comm/mailing/class/mailing.class.php
@@ -662,10 +662,12 @@ class Mailing extends CommonObject
$labelStatusShort = array();
$labelStatus[-1] = $langs->trans('MailingStatusError');
+ $labelStatus[0] = $langs->trans('MailingStatusNotSent');
$labelStatus[1] = $langs->trans('MailingStatusSent');
$labelStatus[2] = $langs->trans('MailingStatusRead');
$labelStatus[3] = $langs->trans('MailingStatusNotContact');
$labelStatusShort[-1] = $langs->trans('MailingStatusError');
+ $labelStatusShort[0] = $langs->trans('MailingStatusNotSent');
$labelStatusShort[1] = $langs->trans('MailingStatusSent');
$labelStatusShort[2] = $langs->trans('MailingStatusRead');
$labelStatusShort[3] = $langs->trans('MailingStatusNotContact');
diff --git a/htdocs/comm/mailing/list.php b/htdocs/comm/mailing/list.php
index 7e2baa7274b..1eadb2d0da0 100644
--- a/htdocs/comm/mailing/list.php
+++ b/htdocs/comm/mailing/list.php
@@ -34,7 +34,7 @@ $result = restrictedArea($user, 'mailing');
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php
index f55861b00cc..9430fce4634 100644
--- a/htdocs/comm/propal/card.php
+++ b/htdocs/comm/propal/card.php
@@ -1893,7 +1893,7 @@ if ($action == 'create')
{
//Form to close proposal (signed or not)
$formquestion = array(
- array('type' => 'select', 'name' => 'statut', 'label' => $langs->trans("CloseAs"), 'values' => array(2=>$object->LibStatut(Propal::STATUS_SIGNED), 3=>$object->LibStatut(Propal::STATUS_NOTSIGNED))),
+ array('type' => 'select', 'name' => 'statut', 'label' => ''.$langs->trans("CloseAs").' ', 'values' => array(2=>$object->LibStatut(Propal::STATUS_SIGNED), 3=>$object->LibStatut(Propal::STATUS_NOTSIGNED))),
array('type' => 'text', 'name' => 'note_private', 'label' => $langs->trans("Note"), 'value' => '') // Field to complete private note (not replace)
);
diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php
index 1337c62da94..87c91d0f621 100644
--- a/htdocs/comm/propal/class/api_proposals.class.php
+++ b/htdocs/comm/propal/class/api_proposals.class.php
@@ -1,6 +1,7 @@
* Copyright (C) 2016 Laurent Destailleur
+ * Copyright (C) 2020 Thibault FOUCART
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -64,16 +65,70 @@ class Proposals extends DolibarrApi
*/
public function get($id, $contact_list = 1)
{
- if(! DolibarrApiAccess::$user->rights->propal->lire) {
+ return $this->_fetch($id, '', '', $contact_list);
+ }
+
+ /**
+ * Get properties of an proposal object by ref
+ *
+ * Return an array with proposal informations
+ *
+ * @param string $ref Ref of object
+ * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id
+ * @return array|mixed data without useless information
+ *
+ * @url GET ref/{ref}
+ *
+ * @throws RestException
+ */
+ public function getByRef($ref, $contact_list = 1)
+ {
+ return $this->_fetch('', $ref, '', $contact_list);
+ }
+
+ /**
+ * Get properties of an proposal object by ref_ext
+ *
+ * Return an array with proposal informations
+ *
+ * @param string $ref_ext External reference of object
+ * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id
+ * @return array|mixed data without useless information
+ *
+ * @url GET ref_ext/{ref_ext}
+ *
+ * @throws RestException
+ */
+ public function getByRefExt($ref_ext, $contact_list = 1)
+ {
+ return $this->_fetch('', '', $ref_ext, $contact_list);
+ }
+
+ /**
+ * Get properties of an proposal object
+ *
+ * Return an array with proposal informations
+ *
+ * @param int $id ID of order
+ * @param string $ref Ref of object
+ * @param string $ref_ext External reference of object
+ * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id
+ * @return array|mixed data without useless information
+ *
+ * @throws RestException
+ */
+ private function _fetch($id, $ref = '', $ref_ext = '', $contact_list = 1)
+ {
+ if (!DolibarrApiAccess::$user->rights->propal->lire) {
throw new RestException(401);
}
- $result = $this->propal->fetch($id);
- if( ! $result ) {
+ $result = $this->propal->fetch($id, $ref, $ref_ext);
+ if (!$result) {
throw new RestException(404, 'Commercial Proposal not found');
}
- if( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@@ -107,18 +162,18 @@ class Proposals extends DolibarrApi
// If the internal user must only see his customers, force searching by him
$search_sale = 0;
- if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id;
+ if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id;
$sql = "SELECT t.rowid";
if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
- $sql.= " FROM ".MAIN_DB_PREFIX."propal as t";
+ $sql .= " FROM ".MAIN_DB_PREFIX."propal as t";
- if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
+ if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
- $sql.= ' WHERE t.entity IN ('.getEntity('propal').')';
- if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc";
- if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")";
- if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
+ $sql .= ' WHERE t.entity IN ('.getEntity('propal').')';
+ if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= " AND t.fk_soc = sc.fk_soc";
+ if ($socids) $sql .= " AND t.fk_soc IN (".$socids.")";
+ if ($search_sale > 0) $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
// Insert sale filter
if ($search_sale > 0)
{
@@ -127,23 +182,23 @@ class Proposals extends DolibarrApi
// Add sql filters
if ($sqlfilters)
{
- if (! DolibarrApi::_checkFilters($sqlfilters))
+ if (!DolibarrApi::_checkFilters($sqlfilters))
{
throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
}
- $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
- $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
+ $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
+ $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
}
- $sql.= $db->order($sortfield, $sortorder);
- if ($limit) {
+ $sql .= $db->order($sortfield, $sortorder);
+ if ($limit) {
if ($page < 0)
{
$page = 0;
}
$offset = $limit * $page;
- $sql.= $db->plimit($limit + 1, $offset);
+ $sql .= $db->plimit($limit + 1, $offset);
}
dol_syslog("API Rest request");
@@ -158,7 +213,7 @@ class Proposals extends DolibarrApi
{
$obj = $db->fetch_object($result);
$proposal_static = new Propal($db);
- if($proposal_static->fetch($obj->rowid)) {
+ if ($proposal_static->fetch($obj->rowid)) {
// Add external contacts ids
$proposal_static->contacts_ids = $proposal_static->liste_contact(-1, 'external', 1);
$obj_ret[] = $this->_cleanObjectDatas($proposal_static);
@@ -169,7 +224,7 @@ class Proposals extends DolibarrApi
else {
throw new RestException(503, 'Error when retrieve propal list : '.$db->lasterror());
}
- if( ! count($obj_ret)) {
+ if (!count($obj_ret)) {
throw new RestException(404, 'No proposal found');
}
return $obj_ret;
@@ -183,13 +238,13 @@ class Proposals extends DolibarrApi
*/
public function post($request_data = null)
{
- if(! DolibarrApiAccess::$user->rights->propal->creer) {
+ if (!DolibarrApiAccess::$user->rights->propal->creer) {
throw new RestException(401, "Insuffisant rights");
}
// Check mandatory fields
$result = $this->_validate($request_data);
- foreach($request_data as $field => $value) {
+ foreach ($request_data as $field => $value) {
$this->propal->$field = $value;
}
/*if (isset($request_data["lines"])) {
@@ -217,16 +272,16 @@ class Proposals extends DolibarrApi
*/
public function getLines($id)
{
- if(! DolibarrApiAccess::$user->rights->propal->lire) {
+ if (!DolibarrApiAccess::$user->rights->propal->lire) {
throw new RestException(401);
}
$result = $this->propal->fetch($id);
- if( ! $result ) {
+ if (!$result) {
throw new RestException(404, 'Commercial Proposal not found');
}
- if( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
$this->propal->getLinesArray();
@@ -249,16 +304,16 @@ class Proposals extends DolibarrApi
*/
public function postLine($id, $request_data = null)
{
- if (! DolibarrApiAccess::$user->rights->propal->creer) {
+ if (!DolibarrApiAccess::$user->rights->propal->creer) {
throw new RestException(401);
}
$result = $this->propal->fetch($id);
- if (! $result) {
+ if (!$result) {
throw new RestException(404, 'Commercial Proposal not found');
}
- if (! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@@ -313,16 +368,16 @@ class Proposals extends DolibarrApi
*/
public function putLine($id, $lineid, $request_data = null)
{
- if(! DolibarrApiAccess::$user->rights->propal->creer) {
+ if (!DolibarrApiAccess::$user->rights->propal->creer) {
throw new RestException(401);
}
$result = $this->propal->fetch($id);
- if($result <= 0) {
+ if ($result <= 0) {
throw new RestException(404, 'Proposal not found');
}
- if( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@@ -336,27 +391,27 @@ class Proposals extends DolibarrApi
$updateRes = $this->propal->updateline(
$lineid,
- isset($request_data->subprice)?$request_data->subprice:$propalline->subprice,
- isset($request_data->qty)?$request_data->qty:$propalline->qty,
- isset($request_data->remise_percent)?$request_data->remise_percent:$propalline->remise_percent,
- isset($request_data->tva_tx)?$request_data->tva_tx:$propalline->tva_tx,
- isset($request_data->localtax1_tx)?$request_data->localtax1_tx:$propalline->localtax1_tx,
- isset($request_data->localtax2_tx)?$request_data->localtax2_tx:$propalline->localtax2_tx,
- isset($request_data->desc)?$request_data->desc:$propalline->desc,
+ isset($request_data->subprice) ? $request_data->subprice : $propalline->subprice,
+ isset($request_data->qty) ? $request_data->qty : $propalline->qty,
+ isset($request_data->remise_percent) ? $request_data->remise_percent : $propalline->remise_percent,
+ isset($request_data->tva_tx) ? $request_data->tva_tx : $propalline->tva_tx,
+ isset($request_data->localtax1_tx) ? $request_data->localtax1_tx : $propalline->localtax1_tx,
+ isset($request_data->localtax2_tx) ? $request_data->localtax2_tx : $propalline->localtax2_tx,
+ isset($request_data->desc) ? $request_data->desc : $propalline->desc,
'HT',
- isset($request_data->info_bits)?$request_data->info_bits:$propalline->info_bits,
- isset($request_data->special_code)?$request_data->special_code:$propalline->special_code,
- isset($request_data->fk_parent_line)?$request_data->fk_parent_line:$propalline->fk_parent_line,
+ isset($request_data->info_bits) ? $request_data->info_bits : $propalline->info_bits,
+ isset($request_data->special_code) ? $request_data->special_code : $propalline->special_code,
+ isset($request_data->fk_parent_line) ? $request_data->fk_parent_line : $propalline->fk_parent_line,
0,
- isset($request_data->fk_fournprice)?$request_data->fk_fournprice:$propalline->fk_fournprice,
- isset($request_data->pa_ht)?$request_data->pa_ht:$propalline->pa_ht,
- isset($request_data->label)?$request_data->label:$propalline->label,
- isset($request_data->product_type)?$request_data->product_type:$propalline->product_type,
- isset($request_data->date_start)?$request_data->date_start:$propalline->date_start,
- isset($request_data->date_end)?$request_data->date_end:$propalline->date_end,
- isset($request_data->array_options)?$request_data->array_options:$propalline->array_options,
- isset($request_data->fk_unit)?$request_data->fk_unit:$propalline->fk_unit,
- isset($request_data->multicurrency_subprice)?$request_data->multicurrency_subprice:$propalline->subprice
+ isset($request_data->fk_fournprice) ? $request_data->fk_fournprice : $propalline->fk_fournprice,
+ isset($request_data->pa_ht) ? $request_data->pa_ht : $propalline->pa_ht,
+ isset($request_data->label) ? $request_data->label : $propalline->label,
+ isset($request_data->product_type) ? $request_data->product_type : $propalline->product_type,
+ isset($request_data->date_start) ? $request_data->date_start : $propalline->date_start,
+ isset($request_data->date_end) ? $request_data->date_end : $propalline->date_end,
+ isset($request_data->array_options) ? $request_data->array_options : $propalline->array_options,
+ isset($request_data->fk_unit) ? $request_data->fk_unit : $propalline->fk_unit,
+ isset($request_data->multicurrency_subprice) ? $request_data->multicurrency_subprice : $propalline->subprice
);
if ($updateRes > 0) {
@@ -377,21 +432,22 @@ class Proposals extends DolibarrApi
* @url DELETE {id}/lines/{lineid}
*
* @return int
- * @throws 401
- * @throws 404
+ *
+ * @throws RestException 401
+ * @throws RestException 404
*/
public function deleteLine($id, $lineid)
{
- if(! DolibarrApiAccess::$user->rights->propal->creer) {
+ if (!DolibarrApiAccess::$user->rights->propal->creer) {
throw new RestException(401);
}
$result = $this->propal->fetch($id);
- if( ! $result ) {
+ if (!$result) {
throw new RestException(404, 'Proposal not found');
}
- if( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@@ -417,18 +473,19 @@ class Proposals extends DolibarrApi
* @url POST {id}/contact/{contactid}/{type}
*
* @return int
- * @throws 401
- * @throws 404
+ *
+ * @throws RestException 401
+ * @throws RestException 404
*/
public function postContact($id, $contactid, $type)
{
- if(!DolibarrApiAccess::$user->rights->propal->creer) {
+ if (!DolibarrApiAccess::$user->rights->propal->creer) {
throw new RestException(401);
}
$result = $this->propal->fetch($id);
- if(!$result) {
+ if (!$result) {
throw new RestException(404, 'Proposal not found');
}
@@ -436,7 +493,7 @@ class Proposals extends DolibarrApi
throw new RestException(500, 'Availables types: BILLING, SHIPPING OR CUSTOMER');
}
- if(!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@@ -458,23 +515,24 @@ class Proposals extends DolibarrApi
* @url DELETE {id}/contact/{rowid}
*
* @return int
- * @throws 401
- * @throws 404
- * @throws 500
+ *
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 500
*/
public function deleteContact($id, $rowid)
{
- if(!DolibarrApiAccess::$user->rights->propal->creer) {
+ if (!DolibarrApiAccess::$user->rights->propal->creer) {
throw new RestException(401);
}
$result = $this->propal->fetch($id);
- if(!$result) {
+ if (!$result) {
throw new RestException(404, 'Proposal not found');
}
- if(!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@@ -497,16 +555,16 @@ class Proposals extends DolibarrApi
*/
public function put($id, $request_data = null)
{
- if (! DolibarrApiAccess::$user->rights->propal->creer) {
+ if (!DolibarrApiAccess::$user->rights->propal->creer) {
throw new RestException(401);
}
$result = $this->propal->fetch($id);
- if ( ! $result ) {
+ if (!$result) {
throw new RestException(404, 'Proposal not found');
}
- if ( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
foreach ($request_data as $field => $value) {
@@ -521,7 +579,7 @@ class Proposals extends DolibarrApi
}
if (!empty($this->propal->fin_validite))
{
- if($this->propal->set_echeance(DolibarrApiAccess::$user, $this->propal->fin_validite)<0)
+ if ($this->propal->set_echeance(DolibarrApiAccess::$user, $this->propal->fin_validite) < 0)
{
throw new RestException(500, $this->propal->error);
}
@@ -546,19 +604,19 @@ class Proposals extends DolibarrApi
*/
public function delete($id)
{
- if(! DolibarrApiAccess::$user->rights->propal->supprimer) {
+ if (!DolibarrApiAccess::$user->rights->propal->supprimer) {
throw new RestException(401);
}
$result = $this->propal->fetch($id);
- if( ! $result ) {
+ if (!$result) {
throw new RestException(404, 'Commercial Proposal not found');
}
- if( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
- if( ! $this->propal->delete(DolibarrApiAccess::$user)) {
+ if (!$this->propal->delete(DolibarrApiAccess::$user)) {
throw new RestException(500, 'Error when delete Commercial Proposal : '.$this->propal->error);
}
@@ -581,15 +639,15 @@ class Proposals extends DolibarrApi
*/
public function settodraft($id)
{
- if(! DolibarrApiAccess::$user->rights->propal->creer) {
+ if (!DolibarrApiAccess::$user->rights->propal->creer) {
throw new RestException(401);
}
$result = $this->propal->fetch($id);
- if( ! $result ) {
+ if (!$result) {
throw new RestException(404, 'Proposal not found');
}
- if( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@@ -602,11 +660,11 @@ class Proposals extends DolibarrApi
}
$result = $this->propal->fetch($id);
- if( ! $result ) {
+ if (!$result) {
throw new RestException(404, 'Proposal not found');
}
- if( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@@ -629,24 +687,24 @@ class Proposals extends DolibarrApi
*
* @url POST {id}/validate
*
- * @throws 304
- * @throws 401
- * @throws 404
- * @throws 500
+ * @throws RestException 304
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 500
*
* @return array
*/
public function validate($id, $notrigger = 0)
{
- if(! DolibarrApiAccess::$user->rights->propal->creer) {
+ if (!DolibarrApiAccess::$user->rights->propal->creer) {
throw new RestException(401);
}
$result = $this->propal->fetch($id);
- if( ! $result ) {
+ if (!$result) {
throw new RestException(404, 'Commercial Proposal not found');
}
- if( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@@ -659,11 +717,11 @@ class Proposals extends DolibarrApi
}
$result = $this->propal->fetch($id);
- if( ! $result ) {
+ if (!$result) {
throw new RestException(404, 'Commercial Proposal not found');
}
- if( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@@ -686,15 +744,15 @@ class Proposals extends DolibarrApi
*/
public function close($id, $status, $note_private = '', $notrigger = 0)
{
- if(! DolibarrApiAccess::$user->rights->propal->creer) {
+ if (!DolibarrApiAccess::$user->rights->propal->creer) {
throw new RestException(401);
}
$result = $this->propal->fetch($id);
- if( ! $result ) {
+ if (!$result) {
throw new RestException(404, 'Commercial Proposal not found');
}
- if( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@@ -707,11 +765,11 @@ class Proposals extends DolibarrApi
}
$result = $this->propal->fetch($id);
- if( ! $result ) {
+ if (!$result) {
throw new RestException(404, 'Proposal not found');
}
- if( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@@ -731,15 +789,15 @@ class Proposals extends DolibarrApi
*/
public function setinvoiced($id)
{
- if (! DolibarrApiAccess::$user->rights->propal->creer) {
+ if (!DolibarrApiAccess::$user->rights->propal->creer) {
throw new RestException(401);
}
$result = $this->propal->fetch($id);
- if ( ! $result ) {
+ if (!$result) {
throw new RestException(404, 'Commercial Proposal not found');
}
- if ( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@@ -749,11 +807,11 @@ class Proposals extends DolibarrApi
}
$result = $this->propal->fetch($id);
- if ( ! $result ) {
+ if (!$result) {
throw new RestException(404, 'Proposal not found');
}
- if( ! DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
+ if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php
index 33e33301cfd..ff3038e85d1 100644
--- a/htdocs/comm/propal/class/propal.class.php
+++ b/htdocs/comm/propal/class/propal.class.php
@@ -223,6 +223,90 @@ class Propal extends CommonObject
public $oldcopy;
+
+ /**
+ * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password')
+ * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)"
+ * 'label' the translation key.
+ * 'enabled' is a condition when the field must be managed.
+ * 'position' is the sort order of field.
+ * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
+ * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing)
+ * 'noteditable' says if field is not editable (1 or 0)
+ * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created.
+ * 'index' if we want an index in database.
+ * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...).
+ * 'searchall' is 1 if we want to search in this field when making a search from the quick search button.
+ * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8).
+ * 'css' is the CSS style to use on field. For example: 'maxwidth200'
+ * 'help' is a string visible as a tooltip on field
+ * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record
+ * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code.
+ * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel")
+ * 'comment' is not used. You can store here any text of your choice. It is not used by application.
+ *
+ * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor.
+ */
+
+ // BEGIN MODULEBUILDER PROPERTIES
+ /**
+ * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
+ */
+ public $fields = array(
+ 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
+ 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>15, 'index'=>1),
+ 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>20),
+ 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'RefCustomer', 'enabled'=>1, 'visible'=>-1, 'position'=>22),
+ 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'RefExt', 'enabled'=>1, 'visible'=>0, 'position'=>40),
+ 'ref_int' =>array('type'=>'varchar(255)', 'label'=>'RefInt', 'enabled'=>1, 'visible'=>0, 'position'=>45), // deprecated
+ 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'position'=>23),
+ 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>24),
+ 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>25),
+ 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>55),
+ 'datep' =>array('type'=>'date', 'label'=>'Date', 'enabled'=>1, 'visible'=>-1, 'position'=>60),
+ 'fin_validite' =>array('type'=>'datetime', 'label'=>'DateEnd', 'enabled'=>1, 'visible'=>-1, 'position'=>65),
+ 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>70),
+ 'date_cloture' =>array('type'=>'datetime', 'label'=>'DateClosing', 'enabled'=>1, 'visible'=>-1, 'position'=>75),
+ 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>80),
+ 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>85),
+ 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
+ 'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user cloture', 'enabled'=>1, 'visible'=>-1, 'position'=>95),
+ 'price' =>array('type'=>'double', 'label'=>'Price', 'enabled'=>1, 'visible'=>-1, 'position'=>105),
+ 'remise_percent' =>array('type'=>'double', 'label'=>'RelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>110),
+ 'remise_absolue' =>array('type'=>'double', 'label'=>'CustomerRelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>115),
+ //'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>120),
+ 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>125, 'isameasure'=>1),
+ 'tva' =>array('type'=>'double(24,8)', 'label'=>'VAT', 'enabled'=>1, 'visible'=>-1, 'position'=>130, 'isameasure'=>1),
+ 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'LocalTax1', 'enabled'=>1, 'visible'=>-1, 'position'=>135, 'isameasure'=>1),
+ 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'LocalTax2', 'enabled'=>1, 'visible'=>-1, 'position'=>140, 'isameasure'=>1),
+ 'total' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>145, 'isameasure'=>1),
+ 'fk_account' =>array('type'=>'integer', 'label'=>'BankAccount', 'enabled'=>1, 'visible'=>-1, 'position'=>150),
+ 'fk_currency' =>array('type'=>'varchar(3)', 'label'=>'Currency', 'enabled'=>1, 'visible'=>-1, 'position'=>155),
+ 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'position'=>160),
+ 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>165),
+ 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>170),
+ 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>175),
+ 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'PDFTemplate', 'enabled'=>1, 'visible'=>0, 'position'=>180),
+ 'date_livraison' =>array('type'=>'date', 'label'=>'DateDeliveryPlanned', 'enabled'=>1, 'visible'=>-1, 'position'=>185),
+ 'fk_shipping_method' =>array('type'=>'integer', 'label'=>'ShippingMethod', 'enabled'=>1, 'visible'=>-1, 'position'=>190),
+ 'fk_availability' =>array('type'=>'integer', 'label'=>'Availability', 'enabled'=>1, 'visible'=>-1, 'position'=>195),
+ 'fk_delivery_address' =>array('type'=>'integer', 'label'=>'DeliveryAddress', 'enabled'=>1, 'visible'=>0, 'position'=>200), // deprecated
+ 'fk_input_reason' =>array('type'=>'integer', 'label'=>'InputReason', 'enabled'=>1, 'visible'=>-1, 'position'=>205),
+ 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>215),
+ 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>220),
+ 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLabel', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>225),
+ 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'MulticurrencyID', 'enabled'=>1, 'visible'=>-1, 'position'=>230),
+ 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCurrency', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>235),
+ 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>240, 'isameasure'=>1),
+ 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountHT', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>245, 'isameasure'=>1),
+ 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountVAT', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>250, 'isameasure'=>1),
+ 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountTTC', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>255, 'isameasure'=>1),
+ 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>-1, 'position'=>260),
+ 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500),
+ 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900),
+ );
+ // END MODULEBUILDER PROPERTIES
+
/**
* Draft status
*/
@@ -440,8 +524,8 @@ class Propal extends CommonObject
* @param int $date_end End date of the line
* @param array $array_options extrafields array
* @param string $fk_unit Code of the unit to use. Null to use the default one
- * @param string $origin 'order', ...
- * @param int $origin_id Id of origin object
+ * @param string $origin Depend on global conf MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION can be 'orderdet', 'propaldet'..., else 'order','propal,'....
+ * @param int $origin_id Depend on global conf MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION can be Id of origin object (aka line id), else object id
* @param double $pu_ht_devise Unit price in currency
* @param int $fk_remise_except Id discount if line is from a discount
* @return int >0 if OK, <0 if KO
@@ -1099,6 +1183,14 @@ class Propal extends CommonObject
$vatrate = $line->tva_tx;
if ($line->vat_src_code && !preg_match('/\(.*\)/', $vatrate)) $vatrate .= ' ('.$line->vat_src_code.')';
+ if(!empty($conf->global->MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION)) {
+ $originid=$line->origin_id;
+ $origintype=$line->origin;
+ } else {
+ $originid=$line->id;
+ $origintype=$this->element;
+ }
+
$result = $this->addline(
$line->desc,
$line->subprice,
@@ -1122,8 +1214,8 @@ class Propal extends CommonObject
$line->date_end,
$line->array_options,
$line->fk_unit,
- $this->element,
- $line->id
+ $origintype,
+ $originid
);
if ($result < 0)
@@ -1365,15 +1457,15 @@ class Propal extends CommonObject
}
/**
- * Load a proposal from database and its ligne array
+ * Load a proposal from database. Get also lines.
*
* @param int $rowid id of object to load
* @param string $ref Ref of proposal
+ * @param string $ref_ext Ref ext of proposal
* @return int >0 if OK, <0 if KO
*/
- public function fetch($rowid, $ref = '')
+ public function fetch($rowid, $ref = '', $ref_ext = '')
{
-
$sql = "SELECT p.rowid, p.ref, p.entity, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc";
$sql .= ", p.total, p.tva, p.localtax1, p.localtax2, p.total_ht";
$sql .= ", p.datec";
@@ -1437,8 +1529,13 @@ class Propal extends CommonObject
$this->total_localtax1 = $obj->localtax1;
$this->total_localtax2 = $obj->localtax2;
$this->total_ttc = $obj->total;
- $this->socid = $obj->fk_soc;
- $this->fk_project = $obj->fk_project;
+
+ $this->socid = $obj->fk_soc;
+ $this->thirdparty = null; // Clear if another value was already set by fetch_thirdparty
+
+ $this->fk_project = $obj->fk_project;
+ $this->project = null; // Clear if another value was already set by fetch_projet
+
$this->modelpdf = $obj->model_pdf;
$this->last_main_doc = $obj->last_main_doc;
$this->note = $obj->note_private; // TODO deprecated
@@ -1506,9 +1603,7 @@ class Propal extends CommonObject
$this->lines = array();
- /*
- * Lines
- */
+ // Lines
$result = $this->fetch_lines();
if ($result < 0)
{
@@ -1801,7 +1896,7 @@ class Propal extends CommonObject
{
$num = $this->ref;
}
- $this->newref = $num;
+ $this->newref = dol_sanitizeFileName($num);
$sql = "UPDATE ".MAIN_DB_PREFIX."propal";
$sql .= " SET ref = '".$this->db->escape($num)."',";
@@ -3247,8 +3342,8 @@ class Propal extends CommonObject
$statusType = '';
if ($status == self::STATUS_DRAFT) $statusType = 'status0';
elseif ($status == self::STATUS_VALIDATED) $statusType = 'status1';
- elseif ($status == self::STATUS_SIGNED) $statusType = 'status3';
- elseif ($status == self::STATUS_NOTSIGNED) $statusType = 'status5';
+ elseif ($status == self::STATUS_SIGNED) $statusType = 'status4';
+ elseif ($status == self::STATUS_NOTSIGNED) $statusType = 'status9';
elseif ($status == self::STATUS_BILLED) $statusType = 'status6';
return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
diff --git a/htdocs/comm/propal/class/propalestats.class.php b/htdocs/comm/propal/class/propalestats.class.php
index 0859bdb7974..d5c48006430 100644
--- a/htdocs/comm/propal/class/propalestats.class.php
+++ b/htdocs/comm/propal/class/propalestats.class.php
@@ -24,10 +24,10 @@
* \brief File of class to manage proposals statistics
*/
-include_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php';
-include_once DOL_DOCUMENT_ROOT . '/comm/propal/class/propal.class.php';
-include_once DOL_DOCUMENT_ROOT . '/supplier_proposal/class/supplier_proposal.class.php';
-include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
+include_once DOL_DOCUMENT_ROOT.'/core/class/stats.class.php';
+include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
+include_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
+include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
/**
@@ -66,36 +66,36 @@ class PropaleStats extends Stats
if ($mode == 'customer')
{
- $object=new Propal($this->db);
+ $object = new Propal($this->db);
$this->from = MAIN_DB_PREFIX.$object->table_element." as p";
$this->from_line = MAIN_DB_PREFIX.$object->table_element_line." as tl";
- $this->field_date='p.datep';
- $this->field='total_ht';
- $this->field_line='total_ht';
+ $this->field_date = 'p.datep';
+ $this->field = 'total_ht';
+ $this->field_line = 'total_ht';
- $this->where.= " p.fk_statut > 0";
+ $this->where .= " p.fk_statut > 0";
}
if ($mode == 'supplier')
{
- $object=new SupplierProposal($this->db);
+ $object = new SupplierProposal($this->db);
$this->from = MAIN_DB_PREFIX.$object->table_element." as p";
$this->from_line = MAIN_DB_PREFIX.$object->table_element_line." as tl";
- $this->field_date='p.date_valid';
- $this->field='total_ht';
- $this->field_line='total_ht';
+ $this->field_date = 'p.date_valid';
+ $this->field = 'total_ht';
+ $this->field_line = 'total_ht';
- $this->where.= " p.fk_statut > 0"; // Validated, accepted, refused and closed
+ $this->where .= " p.fk_statut > 0"; // Validated, accepted, refused and closed
}
//$this->where.= " AND p.fk_soc = s.rowid AND p.entity = ".$conf->entity;
- $this->where.= " AND p.entity IN (".getEntity('propal').")";
- if (!$user->rights->societe->client->voir && !$this->socid) $this->where .= " AND p.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id;
- if($this->socid)
+ $this->where .= " AND p.entity IN (".getEntity('propal').")";
+ if (!$user->rights->societe->client->voir && !$this->socid) $this->where .= " AND p.fk_soc = sc.fk_soc AND sc.fk_user = ".$user->id;
+ if ($this->socid)
{
- $this->where.=" AND p.fk_soc = ".$this->socid;
+ $this->where .= " AND p.fk_soc = ".$this->socid;
}
- if ($this->userid > 0) $this->where.=' AND fk_user_author = '.$this->userid;
+ if ($this->userid > 0) $this->where .= ' AND fk_user_author = '.$this->userid;
}
@@ -111,14 +111,14 @@ class PropaleStats extends Stats
global $user;
$sql = "SELECT date_format(".$this->field_date.",'%m') as dm, COUNT(*) as nb";
- $sql.= " FROM ".$this->from;
- if (!$user->rights->societe->client->voir && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'";
- $sql.= " AND ".$this->where;
- $sql.= " GROUP BY dm";
- $sql.= $this->db->order('dm', 'DESC');
+ $sql .= " FROM ".$this->from;
+ if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql .= " WHERE ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'";
+ $sql .= " AND ".$this->where;
+ $sql .= " GROUP BY dm";
+ $sql .= $this->db->order('dm', 'DESC');
- $res=$this->_getNbByMonth($year, $sql, $format);
+ $res = $this->_getNbByMonth($year, $sql, $format);
return $res;
}
@@ -133,11 +133,11 @@ class PropaleStats extends Stats
global $user;
$sql = "SELECT date_format(".$this->field_date.",'%Y') as dm, COUNT(*) as nb, SUM(c.".$this->field.")";
- $sql.= " FROM ".$this->from;
- if (!$user->rights->societe->client->voir && !$this->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE ".$this->where;
- $sql.= " GROUP BY dm";
- $sql.= $this->db->order('dm', 'DESC');
+ $sql .= " FROM ".$this->from;
+ if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql .= " WHERE ".$this->where;
+ $sql .= " GROUP BY dm";
+ $sql .= $this->db->order('dm', 'DESC');
return $this->_getNbByYear($sql);
}
@@ -154,14 +154,14 @@ class PropaleStats extends Stats
global $user;
$sql = "SELECT date_format(".$this->field_date.",'%m') as dm, SUM(p.".$this->field.")";
- $sql.= " FROM ".$this->from;
- if (!$user->rights->societe->client->voir && !$this->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'";
- $sql.= " AND ".$this->where;
- $sql.= " GROUP BY dm";
- $sql.= $this->db->order('dm', 'DESC');
+ $sql .= " FROM ".$this->from;
+ if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql .= " WHERE ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'";
+ $sql .= " AND ".$this->where;
+ $sql .= " GROUP BY dm";
+ $sql .= $this->db->order('dm', 'DESC');
- $res=$this->_getAmountByMonth($year, $sql, $format);
+ $res = $this->_getAmountByMonth($year, $sql, $format);
return $res;
}
@@ -176,12 +176,12 @@ class PropaleStats extends Stats
global $user;
$sql = "SELECT date_format(".$this->field_date.",'%m') as dm, AVG(p.".$this->field.")";
- $sql.= " FROM ".$this->from;
- if (!$user->rights->societe->client->voir && !$this->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'";
- $sql.= " AND ".$this->where;
- $sql.= " GROUP BY dm";
- $sql.= $this->db->order('dm', 'DESC');
+ $sql .= " FROM ".$this->from;
+ if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql .= " WHERE ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'";
+ $sql .= " AND ".$this->where;
+ $sql .= " GROUP BY dm";
+ $sql .= $this->db->order('dm', 'DESC');
return $this->_getAverageByMonth($year, $sql);
}
@@ -196,11 +196,11 @@ class PropaleStats extends Stats
global $user;
$sql = "SELECT date_format(".$this->field_date.",'%Y') as year, COUNT(*) as nb, SUM(".$this->field.") as total, AVG(".$this->field.") as avg";
- $sql.= " FROM ".$this->from;
- if (!$user->rights->societe->client->voir && !$this->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE ".$this->where;
- $sql.= " GROUP BY year";
- $sql.= $this->db->order('year', 'DESC');
+ $sql .= " FROM ".$this->from;
+ if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql .= " WHERE ".$this->where;
+ $sql .= " GROUP BY year";
+ $sql .= $this->db->order('year', 'DESC');
return $this->_getAllByYear($sql);
}
@@ -210,23 +210,24 @@ class PropaleStats extends Stats
/**
* Return nb, amount of predefined product for year
*
- * @param int $year Year to scan
- * @return array Array of values
+ * @param int $year Year to scan
+ * @param int $limit Limit
+ * @return array Array of values
*/
- public function getAllByProduct($year)
+ public function getAllByProduct($year, $limit = 10)
{
global $user;
$sql = "SELECT product.ref, COUNT(product.ref) as nb, SUM(tl.".$this->field_line.") as total, AVG(tl.".$this->field_line.") as avg";
- $sql.= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product";
- if (!$user->rights->societe->client->voir && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE ".$this->where;
- $sql.= " AND p.rowid = tl.fk_propal AND tl.fk_product = product.rowid";
- $sql.= " AND ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year, 1, false))."' AND '".$this->db->idate(dol_get_last_day($year, 12, false))."'";
- $sql.= " GROUP BY product.ref";
- $sql.= $this->db->order('nb', 'DESC');
+ $sql .= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product";
+ if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql .= " WHERE ".$this->where;
+ $sql .= " AND p.rowid = tl.fk_propal AND tl.fk_product = product.rowid";
+ $sql .= " AND ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year, 1, false))."' AND '".$this->db->idate(dol_get_last_day($year, 12, false))."'";
+ $sql .= " GROUP BY product.ref";
+ $sql .= $this->db->order('nb', 'DESC');
//$sql.= $this->db->plimit(20);
- return $this->_getAllByProduct($sql);
+ return $this->_getAllByProduct($sql, $limit);
}
}
diff --git a/htdocs/comm/propal/contact.php b/htdocs/comm/propal/contact.php
index c052c234eab..e396a5f8b92 100644
--- a/htdocs/comm/propal/contact.php
+++ b/htdocs/comm/propal/contact.php
@@ -21,7 +21,7 @@
/**
* \file htdocs/comm/propal/contact.php
* \ingroup propal
- * \brief Onglet de gestion des contacts de propal
+ * \brief Tab to manage contacts/adresses of proposal
*/
require '../../main.inc.php';
diff --git a/htdocs/comm/propal/document.php b/htdocs/comm/propal/document.php
index 9279da9b029..4ce7d10c9fd 100644
--- a/htdocs/comm/propal/document.php
+++ b/htdocs/comm/propal/document.php
@@ -55,7 +55,7 @@ $result = restrictedArea($user, 'propal', $id);
// Get parameters
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/comm/propal/index.php b/htdocs/comm/propal/index.php
index 11bb4292036..66f4aa94fd2 100644
--- a/htdocs/comm/propal/index.php
+++ b/htdocs/comm/propal/index.php
@@ -82,7 +82,7 @@ if (!empty($conf->global->MAIN_SEARCH_FORM_ON_HOME_AREAS)) // This is useles
* Statistics
*/
-$sql = "SELECT count(p.rowid), p.fk_statut";
+$sql = "SELECT count(p.rowid) as nb, p.fk_statut as status";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
$sql .= ", ".MAIN_DB_PREFIX."propal as p";
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
@@ -101,24 +101,26 @@ if ($resql)
$total = 0;
$totalinprocess = 0;
$dataseries = array();
+ $colorseries = array();
$vals = array();
+
// -1=Canceled, 0=Draft, 1=Validated, (2=Accepted/On process not managed for customer orders), 3=Closed (Sent/Received, billed or not)
while ($i < $num)
{
- $row = $db->fetch_row($resql);
- if ($row)
+ $obj = $db->fetch_object($resql);
+ if ($obj)
{
- //if ($row[1]!=-1 && ($row[1]!=3 || $row[2]!=1))
- {
- $vals[$row[1]] = $row[0];
- $totalinprocess += $row[0];
- }
- $total += $row[0];
+ $vals[$obj->status] = $obj->nb;
+ $totalinprocess += $obj->nb;
+
+ $total += $obj->nb;
}
$i++;
}
$db->free($resql);
+ include_once DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php';
+
print '';
print '
';
print ''.$langs->trans("Statistics").' - '.$langs->trans("Proposals").' '."\n";
@@ -126,7 +128,13 @@ if ($resql)
foreach ($listofstatus as $status)
{
$dataseries[] = array($propalstatic->LibStatut($status, 1), (isset($vals[$status]) ? (int) $vals[$status] : 0));
- if (!$conf->use_javascript_ajax)
+ if ($status == Propal::STATUS_DRAFT) $colorseries[$status] = '-'.$badgeStatus0;
+ if ($status == Propal::STATUS_VALIDATED) $colorseries[$status] = $badgeStatus1;
+ if ($status == Propal::STATUS_SIGNED) $colorseries[$status] = $badgeStatus4;
+ if ($status == Propal::STATUS_NOTSIGNED) $colorseries[$status] = $badgeStatus9;
+ if ($status == Propal::STATUS_BILLED) $colorseries[$status] = $badgeStatus6;
+
+ if (empty($conf->use_javascript_ajax))
{
print '';
print ''.$propalstatic->LibStatut($status, 0).' ';
@@ -141,10 +149,11 @@ if ($resql)
include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
$dolgraph = new DolGraph();
$dolgraph->SetData($dataseries);
- $dolgraph->setShowLegend(1);
+ $dolgraph->SetDataColor(array_values($colorseries));
+ $dolgraph->setShowLegend(2);
$dolgraph->setShowPercent(1);
$dolgraph->SetType(array('pie'));
- $dolgraph->setWidth('100%');
+ $dolgraph->setHeight('200');
$dolgraph->draw('idgraphthirdparties');
print $dolgraph->show($total ? 0 : 1);
diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php
index b9fefe3d78b..f41bdc4fc67 100644
--- a/htdocs/comm/propal/list.php
+++ b/htdocs/comm/propal/list.php
@@ -69,6 +69,11 @@ $search_societe = GETPOST('search_societe', 'alpha');
$search_montant_ht = GETPOST('search_montant_ht', 'alpha');
$search_montant_vat = GETPOST('search_montant_vat', 'alpha');
$search_montant_ttc = GETPOST('search_montant_ttc', 'alpha');
+$search_multicurrency_code = GETPOST('search_multicurrency_code', 'alpha');
+$search_multicurrency_tx = GETPOST('search_multicurrency_tx', 'alpha');
+$search_multicurrency_montant_ht = GETPOST('search_multicurrency_montant_ht', 'alpha');
+$search_multicurrency_montant_vat = GETPOST('search_multicurrency_montant_vat', 'alpha');
+$search_multicurrency_montant_ttc = GETPOST('search_multicurrency_montant_ttc', 'alpha');
$search_login = GETPOST('search_login', 'alpha');
$search_product_category = GETPOST('search_product_category', 'int');
$search_town = GETPOST('search_town', 'alpha');
@@ -98,7 +103,7 @@ $mesg = (GETPOST("msg") ? GETPOST("msg") : GETPOST("mesg"));
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn) || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
@@ -162,8 +167,15 @@ $arrayfields = array(
'p.total_ht'=>array('label'=>"AmountHT", 'checked'=>1),
'p.total_vat'=>array('label'=>"AmountVAT", 'checked'=>0),
'p.total_ttc'=>array('label'=>"AmountTTC", 'checked'=>0),
- 'p.total_ht_invoiced'=>array('label'=>$langs->trans("AmountInvoicedHT"), 'checked'=>0, 'enabled'=>$conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT),
- 'p.total_invoiced'=>array('label'=>$langs->trans("AmountInvoicedTTC"), 'checked'=>0, 'enabled'=>$conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT),
+ 'p.total_ht_invoiced'=>array('label'=>"AmountInvoicedHT", 'checked'=>0, 'enabled'=>!empty($conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT)),
+ 'p.total_invoiced'=>array('label'=>"AmountInvoicedTTC", 'checked'=>0, 'enabled'=>!empty($conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT)),
+ 'p.multicurrency_code'=>array('label'=>'Currency', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'p.multicurrency_tx'=>array('label'=>'CurrencyRate', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'p.multicurrency_total_ht'=>array('label'=>'MulticurrencyAmountHT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'p.multicurrency_total_vat'=>array('label'=>'MulticurrencyAmountVAT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'p.multicurrency_total_ttc'=>array('label'=>'MulticurrencyAmountTTC', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'p.multicurrency_total_ht_invoiced'=>array('label'=>'MulticurrencyAmountInvoicedHT', 'checked'=>0, 'enabled'=>!empty($conf->multicurrency->enabled) && !empty($conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT)),
+ 'p.multicurrency_total_invoiced'=>array('label'=>'MulticurrencyAmountInvoicedTTC', 'checked'=>0, 'enabled'=>!empty($conf->multicurrency->enabled) && !empty($conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT)),
'u.login'=>array('label'=>"Author", 'checked'=>1, 'position'=>10),
'sale_representative'=>array('label'=>"SaleRepresentativesOfThirdParty", 'checked'=>1),
'p.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500),
@@ -209,6 +221,11 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
$search_montant_ht = '';
$search_montant_vat = '';
$search_montant_ttc = '';
+ $search_multicurrency_code = '';
+ $search_multicurrency_tx = '';
+ $search_multicurrency_montant_ht = '';
+ $search_multicurrency_montant_vat = '';
+ $search_multicurrency_montant_ttc = '';
$search_login = '';
$search_product_category = '';
$search_town = '';
@@ -269,6 +286,7 @@ $sql .= " typent.code as typent_code,";
$sql .= " ava.rowid as availability,";
$sql .= " state.code_departement as state_code, state.nom as state_name,";
$sql .= ' p.rowid, p.entity, p.note_private, p.total_ht, p.tva as total_vat, p.total as total_ttc, p.localtax1, p.localtax2, p.ref, p.ref_client, p.fk_statut, p.fk_user_author, p.datep as dp, p.fin_validite as dfv,p.date_livraison as ddelivery,';
+$sql .= ' p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva as multicurrency_total_vat, p.multicurrency_total_ttc,';
$sql .= ' p.datec as date_creation, p.tms as date_update, p.date_cloture as date_cloture,';
$sql .= ' p.note_public, p.note_private,';
$sql .= " pr.rowid as project_id, pr.ref as project_ref, pr.title as project_label,";
@@ -326,6 +344,11 @@ if ($search_login) $sql .= natural_search("u.login", $search_login);
if ($search_montant_ht != '') $sql .= natural_search("p.total_ht", $search_montant_ht, 1);
if ($search_montant_vat != '') $sql .= natural_search("p.tva", $search_montant_vat, 1);
if ($search_montant_ttc != '') $sql .= natural_search("p.total", $search_montant_ttc, 1);
+if ($search_multicurrency_code != '') $sql .= ' AND p.multicurrency_code = "'.$db->escape($search_multicurrency_code).'"';
+if ($search_multicurrency_tx != '') $sql .= natural_search('p.multicurrency_tx', $search_multicurrency_tx, 1);
+if ($search_multicurrency_montant_ht != '') $sql .= natural_search('p.multicurrency_total_ht', $search_multicurrency_montant_ht, 1);
+if ($search_multicurrency_montant_vat != '') $sql .= natural_search('p.multicurrency_total_tva', $search_multicurrency_montant_vat, 1);
+if ($search_multicurrency_montant_ttc != '') $sql .= natural_search('p.multicurrency_total_ttc', $search_multicurrency_montant_ttc, 1);
if ($sall) {
$sql .= natural_search(array_keys($fieldstosearchall), $sall);
}
@@ -428,6 +451,11 @@ if ($resql)
if ($search_user > 0) $param .= '&search_user='.urlencode($search_user);
if ($search_sale > 0) $param .= '&search_sale='.urlencode($search_sale);
if ($search_montant_ht) $param .= '&search_montant_ht='.urlencode($search_montant_ht);
+ if ($search_multicurrency_code != '') $param .= '&search_multicurrency_code='.urlencode($search_multicurrency_code);
+ if ($search_multicurrency_tx != '') $param .= '&search_multicurrency_tx='.urlencode($search_multicurrency_tx);
+ if ($search_multicurrency_montant_ht != '') $param .= '&search_multicurrency_montant_ht='.urlencode($search_multicurrency_montant_ht);
+ if ($search_multicurrency_montant_vat != '') $param .= '&search_multicurrency_montant_vat='.urlencode($search_multicurrency_montant_vat);
+ if ($search_multicurrency_montant_ttc != '') $param .= '&search_multicurrency_montant_ttc='.urlencode($search_multicurrency_montant_ttc);
if ($search_login) $param .= '&search_login='.urlencode($search_login);
if ($search_town) $param .= '&search_town='.urlencode($search_town);
if ($search_zip) $param .= '&search_zip='.urlencode($search_zip);
@@ -677,6 +705,53 @@ if ($resql)
print '';
print ' ';
}
+ if (!empty($arrayfields['p.multicurrency_code']['checked']))
+ {
+ // Currency
+ print '';
+ print $form->selectMultiCurrency($search_multicurrency_code, 'search_multicurrency_code', 1);
+ print ' ';
+ }
+ if (!empty($arrayfields['p.multicurrency_tx']['checked']))
+ {
+ // Currency rate
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['p.multicurrency_total_ht']['checked']))
+ {
+ // Amount
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['p.multicurrency_total_vat']['checked']))
+ {
+ // Amount
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['p.multicurrency_total_ttc']['checked']))
+ {
+ // Amount
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['p.multicurrency_total_ht_invoiced']['checked']))
+ {
+ // Amount invoiced
+ print '';
+ print ' ';
+ }
+ if (!empty($arrayfields['p.multicurrency_total_invoiced']['checked']))
+ {
+ // Amount invoiced
+ print '';
+ print ' ';
+ }
if (!empty($arrayfields['u.login']['checked']))
{
// Author
@@ -750,6 +825,13 @@ if ($resql)
if (!empty($arrayfields['p.total_ttc']['checked'])) print_liste_field_titre($arrayfields['p.total_ttc']['label'], $_SERVER["PHP_SELF"], 'p.total', '', $param, 'class="right"', $sortfield, $sortorder);
if (!empty($arrayfields['p.total_ht_invoiced']['checked'])) print_liste_field_titre($arrayfields['p.total_ht_invoiced']['label'], $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder);
if (!empty($arrayfields['p.total_invoiced']['checked'])) print_liste_field_titre($arrayfields['p.total_invoiced']['label'], $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['p.multicurrency_code']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_code']['label'], $_SERVER['PHP_SELF'], 'p.multicurrency_code', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['p.multicurrency_tx']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_tx']['label'], $_SERVER['PHP_SELF'], 'p.multicurrency_tx', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['p.multicurrency_total_ht']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_total_ht']['label'], $_SERVER['PHP_SELF'], 'p.multicurrency_total_ht', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['p.multicurrency_total_vat']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_total_vat']['label'], $_SERVER['PHP_SELF'], 'p.multicurrency_total_tva', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['p.multicurrency_total_ttc']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_total_ttc']['label'], $_SERVER['PHP_SELF'], 'p.multicurrency_total_ttc', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['p.multicurrency_total_ht_invoiced']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_total_ht_invoiced']['label'], $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['p.multicurrency_total_invoiced']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_total_invoiced']['label'], $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder);
if (!empty($arrayfields['u.login']['checked'])) print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER["PHP_SELF"], 'u.login', '', $param, 'align="center"', $sortfield, $sortorder);
if (!empty($arrayfields['sale_representative']['checked'])) print_liste_field_titre($arrayfields['sale_representative']['label'], $_SERVER["PHP_SELF"], "", "", "$param", '', $sortfield, $sortorder);
// Extra fields
@@ -776,8 +858,9 @@ if ($resql)
$objectstatic->id = $obj->rowid;
$objectstatic->ref = $obj->ref;
- $objectstatic->note_private = $obj->note_private;
+ $objectstatic->ref_client = $obj->ref_client;
$objectstatic->note_public = $obj->note_public;
+ $objectstatic->note_private = $obj->note_private;
$companystatic->id = $obj->socid;
$companystatic->name = $obj->name;
@@ -789,6 +872,29 @@ if ($resql)
$projectstatic->ref = $obj->project_ref;
$projectstatic->title = $obj->project_label;
+ $totalInvoicedHT = 0;
+ $totalInvoicedTTC = 0;
+ $multicurrency_totalInvoicedHT = 0;
+ $multicurrency_totalInvoicedTTC = 0;
+
+ $TInvoiceData = $objectstatic->InvoiceArrayList($obj->rowid);
+
+ if (!empty($TInvoiceData))
+ {
+ foreach ($TInvoiceData as $invoiceData)
+ {
+ $invoice = new Facture($db);
+ $invoice->fetch($invoiceData->facid);
+
+ if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS) && $invoice->type == Facture::TYPE_DEPOSIT) continue;
+
+ $totalInvoicedHT += $invoice->total_ht;
+ $totalInvoicedTTC += $invoice->total_ttc;
+ $multicurrency_totalInvoicedHT += $invoice->multicurrency_total_ht;
+ $multicurrency_totalInvoicedTTC += $invoice->multicurrency_total_ttc;
+ }
+ }
+
print ' ';
if (!empty($arrayfields['p.ref']['checked']))
@@ -824,7 +930,7 @@ if ($resql)
if (!empty($arrayfields['p.ref_client']['checked']))
{
// Customer ref
- print '';
+ print ' ';
print $obj->ref_client;
print ' ';
if (!$i) $totalarray['nbfield']++;
@@ -974,46 +1080,66 @@ if ($resql)
$totalarray['val']['p.total_ttc'] += $obj->total_ttc;
}
// Amount invoiced
- if (!empty($arrayfields['p.total_ht_invoiced']['checked'])) {
- $totalInvoiced = 0;
- $p = new Propal($db);
- $TInvoiceData = $p->InvoiceArrayList($obj->rowid);
-
- if (!empty($TInvoiceData)) {
- foreach ($TInvoiceData as $invoiceData) {
- $invoice = new Facture($db);
- $invoice->fetch($invoiceData->facid);
-
- if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS) && $invoice->type == Facture::TYPE_DEPOSIT) continue;
- $totalInvoiced += $invoice->total_ht;
- }
- }
-
- print ''.price($totalInvoiced)." \n";
+ if (!empty($arrayfields['p.total_ht_invoiced']['checked']))
+ {
+ print ''.price($totalInvoicedHT)." \n";
if (!$i) $totalarray['nbfield']++;
if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'p.total_ht_invoiced';
- $totalarray['val']['p.total_ht_invoiced'] += $obj->total_ht_invoiced;
+ $totalarray['val']['p.total_ht_invoiced'] += $totalInvoicedHT;
}
// Amount invoiced
- if (!empty($arrayfields['p.total_invoiced']['checked'])) {
- $totalInvoiced = 0;
- $p = new Propal($db);
- $TInvoiceData = $p->InvoiceArrayList($obj->rowid);
-
- if (!empty($TInvoiceData)) {
- foreach ($TInvoiceData as $invoiceData) {
- $invoice = new Facture($db);
- $invoice->fetch($invoiceData->facid);
-
- if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS) && $invoice->type == Facture::TYPE_DEPOSIT) continue;
- $totalInvoiced += $invoice->total_ttc;
- }
- }
-
- print ''.price($totalInvoiced)." \n";
+ if (!empty($arrayfields['p.total_invoiced']['checked']))
+ {
+ print ''.price($totalInvoicedTTC)." \n";
if (!$i) $totalarray['nbfield']++;
if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'p.total_invoiced';
- $totalarray['val']['p.total_invoiced'] += $obj->total_invoiced;
+ $totalarray['val']['p.total_invoiced'] += $totalInvoicedTTC;
+ }
+
+ // Currency
+ if (!empty($arrayfields['p.multicurrency_code']['checked']))
+ {
+ print ''.$obj->multicurrency_code.' - '.$langs->trans('Currency'.$obj->multicurrency_code)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+
+ // Currency rate
+ if (!empty($arrayfields['p.multicurrency_tx']['checked']))
+ {
+ print '';
+ $form->form_multicurrency_rate($_SERVER['PHP_SELF'].'?id='.$obj->rowid, $obj->multicurrency_tx, 'none', $obj->multicurrency_code);
+ print " \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount HT
+ if (!empty($arrayfields['p.multicurrency_total_ht']['checked']))
+ {
+ print ''.price($obj->multicurrency_total_ht)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount VAT
+ if (!empty($arrayfields['p.multicurrency_total_vat']['checked']))
+ {
+ print ''.price($obj->multicurrency_total_vat)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount TTC
+ if (!empty($arrayfields['p.multicurrency_total_ttc']['checked']))
+ {
+ print ''.price($obj->multicurrency_total_ttc)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount invoiced
+ if (!empty($arrayfields['p.multicurrency_total_ht_invoiced']['checked']))
+ {
+ print ''.price($multicurrency_totalInvoicedHT)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount invoiced
+ if (!empty($arrayfields['p.multicurrency_total_invoiced']['checked']))
+ {
+ print ''.price($multicurrency_totalInvoicedTTC)." \n";
+ if (!$i) $totalarray['nbfield']++;
}
$userstatic->id = $obj->fk_user_author;
@@ -1039,9 +1165,7 @@ if ($resql)
$nbofsalesrepresentative = count($listsalesrepresentatives);
if ($nbofsalesrepresentative > 3) // We print only number
{
- print '';
print $nbofsalesrepresentative;
- print ' ';
}
elseif ($nbofsalesrepresentative > 0)
{
diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php
index 902b773735a..651fa556e8a 100644
--- a/htdocs/comm/remx.php
+++ b/htdocs/comm/remx.php
@@ -111,6 +111,7 @@ if ($action == 'confirm_split' && GETPOST("confirm") == 'yes')
$newdiscount1->description = $discount->description.' (1)';
$newdiscount2->description = $discount->description.' (2)';
}
+
$newdiscount1->fk_user = $discount->fk_user;
$newdiscount2->fk_user = $discount->fk_user;
$newdiscount1->fk_soc = $discount->fk_soc;
@@ -121,7 +122,7 @@ if ($action == 'confirm_split' && GETPOST("confirm") == 'yes')
$newdiscount2->datec = $discount->datec;
$newdiscount1->tva_tx = $discount->tva_tx;
$newdiscount2->tva_tx = $discount->tva_tx;
- $newdiscount1->amount_ttc = $_POST["amount_ttc_1"];
+ $newdiscount1->amount_ttc = $amount_ttc_1;
$newdiscount2->amount_ttc = price2num($discount->amount_ttc - $newdiscount1->amount_ttc);
$newdiscount1->amount_ht = price2num($newdiscount1->amount_ttc / (1 + $newdiscount1->tva_tx / 100), 'MT');
$newdiscount2->amount_ht = price2num($newdiscount2->amount_ttc / (1 + $newdiscount2->tva_tx / 100), 'MT');
diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php
index 3c1bf672c0f..7db4d3c9767 100644
--- a/htdocs/commande/card.php
+++ b/htdocs/commande/card.php
@@ -93,25 +93,29 @@ $extrafields = new ExtraFields($db);
$extrafields->fetch_name_optionals_label($object->table_element);
// Load object
-include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once
+include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
-$hookmanager->initHooks(array('ordercard','globalcard'));
+$hookmanager->initHooks(array('ordercard', 'globalcard'));
$usercanread = $user->rights->commande->lire;
$usercancreate = $user->rights->commande->creer;
$usercanclose = $user->rights->commande->cloturer;
$usercandelete = $user->rights->commande->supprimer;
-$usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->order_advance->validate)));
-$usercancancel = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->order_advance->annuler)));
+$usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->commande->order_advance->validate)));
+$usercancancel = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->commande->order_advance->annuler)));
$usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->commande->order_advance->send);
$usercancreatepurchaseorder = $user->rights->fournisseur->commande->creer;
-$permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php
-$permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php
-$permissiontoadd = $usercancreate; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
+$permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php
+$permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php
+$permissiontoadd = $usercancreate; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
+if (!empty($conf->expedition->enabled) && $conf->global->WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER = 1){
+ if (empty($object->warehouse_id) && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE)) $object->warehouse_id = $conf->global->MAIN_DEFAULT_WAREHOUSE;
+ if (empty($object->warehouse_id) && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE_USER)) $object->warehouse_id = $user->fk_warehouse;
+}
/*
* Actions
@@ -1594,25 +1598,25 @@ if ($action == 'create' && $usercancreate)
$note_public = $object->getDefaultCreateValueFor('note_public');
}
- print '
';
// End of page
llxFooter();
diff --git a/htdocs/compta/bank/list.php b/htdocs/compta/bank/list.php
index 329ac25ef79..82728fc693d 100644
--- a/htdocs/compta/bank/list.php
+++ b/htdocs/compta/bank/list.php
@@ -4,6 +4,7 @@
* Copyright (C) 2005-2012 Regis Houssin
* Copyright (C) 2015 Jean-François Ferry
* Copyright (C) 2018 Ferran Marcet
+ * Copyright (C) 2020 Tobias Sekan
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,36 +31,43 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
require_once DOL_DOCUMENT_ROOT.'/compta/tva/class/tva.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
-if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php';
-if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php';
+if (!empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
+if (!empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
+if (!empty($conf->categorie->enabled)) require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
// Load translation files required by the page
$langs->loadLangs(array('banks', 'categories', 'accountancy', 'compta'));
-$action=GETPOST('action', 'alpha');
-$massaction=GETPOST('massaction', 'alpha');
-$show_files=GETPOST('show_files', 'int');
-$confirm=GETPOST('confirm', 'alpha');
+$action = GETPOST('action', 'alpha');
+$massaction = GETPOST('massaction', 'alpha');
+$show_files = GETPOST('show_files', 'int');
+$confirm = GETPOST('confirm', 'alpha');
$toselect = GETPOST('toselect', 'array');
-$contextpage= GETPOST('contextpage', 'aZ')?GETPOST('contextpage', 'aZ'):'bankaccountlist'; // To manage different context of search
+$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'bankaccountlist'; // To manage different context of search
-$search_ref=GETPOST('search_ref', 'alpha');
-$search_label=GETPOST('search_label', 'alpha');
-$search_number=GETPOST('search_number', 'alpha');
-$search_status=GETPOST('search_status')?GETPOST('search_status', 'alpha'):'opened'; // 'all' or ''='opened'
+$search_ref = GETPOST('search_ref', 'alpha');
+$search_label = GETPOST('search_label', 'alpha');
+$search_number = GETPOST('search_number', 'alpha');
+$search_status = GETPOST('search_status') ?GETPOST('search_status', 'alpha') : 'opened'; // 'all' or ''='opened'
$optioncss = GETPOST('optioncss', 'alpha');
+if (!empty($conf->categorie->enabled))
+{
+ $search_category_list = GETPOST("search_category_".Categorie::TYPE_ACCOUNT."_list", "array");
+}
+
// Security check
-if ($user->socid) $socid=$user->socid;
-if (! empty($user->rights->accounting->chartofaccount)) $allowed=1; // Dictionary with list of banks accounting account allowed to manager of chart account
-if (! $allowed) $result=restrictedArea($user, 'banque');
+if ($user->socid) $socid = $user->socid;
+if (!empty($user->rights->accounting->chartofaccount)) $allowed = 1; // Dictionary with list of banks accounting account allowed to manager of chart account
+if (!$allowed) $result = restrictedArea($user, 'banque');
-$diroutputmassaction=$conf->bank->dir_output . '/temp/massgeneration/'.$user->id;
+$diroutputmassaction = $conf->bank->dir_output.'/temp/massgeneration/'.$user->id;
-$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
+$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
@@ -74,7 +82,7 @@ $extrafields = new ExtraFields($db);
// fetch optionals attributes and labels
$extrafields->fetch_name_optionals_label($object->table_element);
-$search_array_options=$extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
+$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
// List of fields to search into when doing a "search in all"
$fieldstosearchall = array(
@@ -100,10 +108,10 @@ $arrayfields = array(
// Extra fields
if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0)
{
- foreach($extrafields->attributes[$object->table_element]['label'] as $key => $val)
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val)
{
- if (! empty($extrafields->attributes[$object->table_element]['list'][$key]))
- $arrayfields["ef.".$key]=array('label'=>$extrafields->attributes[$object->table_element]['label'][$key], 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key]<0)?0:1), 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key])!=3 && $extrafields->attributes[$object->table_element]['perms'][$key]));
+ if (!empty($extrafields->attributes[$object->table_element]['list'][$key]))
+ $arrayfields["ef.".$key] = array('label'=>$extrafields->attributes[$object->table_element]['label'][$key], 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1), 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key]));
}
}
$object->fields = dol_sort_array($object->fields, 'position');
@@ -138,38 +146,50 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
* View
*/
-$form=new Form($db);
+$form = new FormCategory($db);
-$title=$langs->trans('BankAccounts');
+$title = $langs->trans('BankAccounts');
// Load array of financial accounts (opened by default)
$accounts = array();
$sql = "SELECT b.rowid, b.label, b.courant, b.rappro, b.account_number, b.fk_accountancy_journal, b.currency_code, b.datec as date_creation, b.tms as date_update";
// Add fields from extrafields
-if (! empty($extrafields->attributes[$object->table_element]['label'])) {
- foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql.=($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key.' as options_'.$key : '');
+if (!empty($extrafields->attributes[$object->table_element]['label'])) {
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key.' as options_'.$key : '');
}
// Add fields from hooks
-$parameters=array();
-$reshook=$hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
-$sql.=$hookmanager->resPrint;
-$sql.= " FROM ".MAIN_DB_PREFIX."bank_account as b";
-if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (b.rowid = ef.fk_object)";
-$sql.= " WHERE b.entity IN (".getEntity('bank_account').")";
-if ($search_status == 'opened') $sql.= " AND clos = 0";
-if ($search_status == 'closed') $sql.= " AND clos = 1";
-if ($search_ref != '') $sql.=natural_search('b.ref', $search_ref);
-if ($search_label != '') $sql.=natural_search('b.label', $search_label);
-if ($search_number != '') $sql.=natural_search('b.number', $search_number);
+$parameters = array();
+$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
+$sql .= $hookmanager->resPrint;
+$sql .= " FROM ".MAIN_DB_PREFIX."bank_account as b";
+if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (b.rowid = ef.fk_object)";
+
+if (!empty($conf->categorie->enabled))
+{
+ $sql .= Categorie::getFilterJoinQuery(Categorie::TYPE_ACCOUNT, "b.rowid");
+}
+
+$sql .= " WHERE b.entity IN (".getEntity('bank_account').")";
+if ($search_status == 'opened') $sql .= " AND clos = 0";
+if ($search_status == 'closed') $sql .= " AND clos = 1";
+
+if (!empty($conf->categorie->enabled))
+{
+ $sql .= Categorie::getFilterSelectQuery(Categorie::TYPE_ACCOUNT, "b.rowid", $search_category_list);
+}
+
+if ($search_ref != '') $sql .= natural_search('b.ref', $search_ref);
+if ($search_label != '') $sql .= natural_search('b.label', $search_label);
+if ($search_number != '') $sql .= natural_search('b.number', $search_number);
// Add where from extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
// Add where from hooks
-$parameters=array();
-$reshook=$hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
-$sql.=$hookmanager->resPrint;
+$parameters = array();
+$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
+$sql .= $hookmanager->resPrint;
-$sql.= $db->order($sortfield, $sortorder);
+$sql .= $db->order($sortfield, $sortorder);
// Count total nb of records
$nbtotalofrecords = '';
@@ -263,6 +283,10 @@ if ($sall)
$moreforfilter = '';
+if (!empty($conf->categorie->enabled))
+{
+ $moreforfilter .= $form->getFilterBox(Categorie::TYPE_ACCOUNT, $search_category_list);
+}
// Bank accounts
$parameters = array();
@@ -414,52 +438,52 @@ foreach ($accounts as $key=>$type)
$solde = $objecttmp->solde(1);
- if (! empty($lastcurrencycode) && $lastcurrencycode != $objecttmp->currency_code)
+ if (!empty($lastcurrencycode) && $lastcurrencycode != $objecttmp->currency_code)
{
- $lastcurrencycode='various'; // We found several different currencies
+ $lastcurrencycode = 'various'; // We found several different currencies
}
if ($lastcurrencycode != 'various')
{
- $lastcurrencycode=$objecttmp->currency_code;
+ $lastcurrencycode = $objecttmp->currency_code;
}
print '';
// Ref
- if (! empty($arrayfields['b.ref']['checked']))
+ if (!empty($arrayfields['b.ref']['checked']))
{
print ''.$objecttmp->getNomUrl(1).' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Label
- if (! empty($arrayfields['b.label']['checked']))
+ if (!empty($arrayfields['b.label']['checked']))
{
print ''.$objecttmp->label.' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Account type
- if (! empty($arrayfields['accountype']['checked']))
+ if (!empty($arrayfields['accountype']['checked']))
{
print '';
print $objecttmp->type_lib[$objecttmp->type];
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Number
- if (! empty($arrayfields['b.number']['checked']))
+ if (!empty($arrayfields['b.number']['checked']))
{
print ''.$objecttmp->number.' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Account number
- if (! empty($arrayfields['b.account_number']['checked']))
+ if (!empty($arrayfields['b.account_number']['checked']))
{
print '';
- if (! empty($conf->accounting->enabled) && ! empty($objecttmp->account_number))
+ if (!empty($conf->accounting->enabled) && !empty($objecttmp->account_number))
{
$accountingaccount = new AccountingAccount($db);
$accountingaccount->fetch('', $objecttmp->account_number, 1);
@@ -470,14 +494,14 @@ foreach ($accounts as $key=>$type)
print $objecttmp->account_number;
}
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Accountancy journal
- if (! empty($arrayfields['b.fk_accountancy_journal']['checked']))
+ if (!empty($arrayfields['b.fk_accountancy_journal']['checked']))
{
print '';
- if (! empty($conf->accounting->enabled) && ! empty($objecttmp->fk_accountancy_journal))
+ if (!empty($conf->accounting->enabled) && !empty($objecttmp->fk_accountancy_journal))
{
$accountingjournal = new AccountingJournal($db);
$accountingjournal->fetch($objecttmp->fk_accountancy_journal);
@@ -523,47 +547,47 @@ foreach ($accounts as $key=>$type)
print ''.$langs->trans("FeatureDisabled").' ';
}
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
// Fields from hook
- $parameters=array('arrayfields'=>$arrayfields);
- $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters, $objecttmp); // Note that $action and $objecttmpect may have been modified by hook
+ $parameters = array('arrayfields'=>$arrayfields);
+ $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $objecttmp); // Note that $action and $objecttmpect may have been modified by hook
print $hookmanager->resPrint;
// Date creation
- if (! empty($arrayfields['b.datec']['checked']))
+ if (!empty($arrayfields['b.datec']['checked']))
{
print '';
print dol_print_date($objecttmp->date_creation, 'dayhour');
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Date modification
- if (! empty($arrayfields['b.tms']['checked']))
+ if (!empty($arrayfields['b.tms']['checked']))
{
print '';
print dol_print_date($objecttmp->date_update, 'dayhour');
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Status
- if (! empty($arrayfields['b.clos']['checked']))
+ if (!empty($arrayfields['b.clos']['checked']))
{
print ''.$objecttmp->getLibStatut(5).' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Balance
- if (! empty($arrayfields['balance']['checked']))
+ if (!empty($arrayfields['balance']['checked']))
{
print '';
print ''.price($solde, 0, $langs, 0, -1, -1, $objecttmp->currency_code).' ';
print ' ';
- if (! $i) $totalarray['nbfield']++;
- if (! $i) $totalarray['pos'][$totalarray['nbfield']]='balance';
+ if (!$i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'balance';
$totalarray['val']['balance'] += $solde;
}
diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php
index 9ae1d5d7d83..0350895ca0d 100644
--- a/htdocs/compta/bank/releve.php
+++ b/htdocs/compta/bank/releve.php
@@ -49,7 +49,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
$langs->loadLangs(array("banks", "categories", "companies", "bills", "trips", "donations", "loan"));
$action = GETPOST('action', 'alpha');
-$id = GETPOST('account', 'int');
+$id = GETPOST('account', 'int') ? GETPOST('account', 'int') : GETPOST('id', 'int');
$ref = GETPOST('ref', 'alpha');
$dvid = GETPOST('dvid', 'alpha');
$numref = GETPOST('num', 'alpha');
@@ -80,7 +80,7 @@ if ($user->rights->banque->consolidate && $action == 'dvprev' && !empty($dvid))
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
$pageplusone = GETPOST("pageplusone", 'int');
if ($pageplusone) $page = $pageplusone - 1;
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php
index 7ca62b67ab8..b8d259cdc8d 100644
--- a/htdocs/compta/bank/treso.php
+++ b/htdocs/compta/bank/treso.php
@@ -39,18 +39,18 @@ $langs->loadLangs(array('banks', 'categories', 'bills', 'companies'));
// Security check
if (isset($_GET["account"]) || isset($_GET["ref"]))
{
- $id = isset($_GET["account"])?$_GET["account"]:(isset($_GET["ref"])?$_GET["ref"]:'');
+ $id = isset($_GET["account"]) ? $_GET["account"] : (isset($_GET["ref"]) ? $_GET["ref"] : '');
}
-$fieldid = isset($_GET["ref"])?'ref':'rowid';
-if ($user->socid) $socid=$user->socid;
-$result=restrictedArea($user, 'banque', $id, 'bank_account&bank_account', '', '', $fieldid);
+$fieldid = isset($_GET["ref"]) ? 'ref' : 'rowid';
+if ($user->socid) $socid = $user->socid;
+$result = restrictedArea($user, 'banque', $id, 'bank_account&bank_account', '', '', $fieldid);
-$vline=isset($_GET["vline"])?$_GET["vline"]:$_POST["vline"];
-$page=isset($_GET["page"])?$_GET["page"]:0;
+$vline = isset($_GET["vline"]) ? $_GET["vline"] : $_POST["vline"];
+$page = isset($_GET["page"]) ? $_GET["page"] : 0;
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
-$hookmanager->initHooks(array('banktreso','globalcard'));
+$hookmanager->initHooks(array('banktreso', 'globalcard'));
/*
* View
@@ -61,9 +61,9 @@ $helpurl = "";
llxHeader('', $title, $helpurl);
$societestatic = new Societe($db);
-$facturestatic=new Facture($db);
-$facturefournstatic=new FactureFournisseur($db);
-$socialcontribstatic=new ChargeSociales($db);
+$facturestatic = new Facture($db);
+$facturefournstatic = new FactureFournisseur($db);
+$socialcontribstatic = new ChargeSociales($db);
$form = new Form($db);
@@ -81,17 +81,17 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
$object = new Account($db);
if ($_GET["account"])
{
- $result=$object->fetch($_GET["account"]);
+ $result = $object->fetch($_GET["account"]);
}
if ($_GET["ref"])
{
- $result=$object->fetch(0, $_GET["ref"]);
- $_GET["account"]=$object->id;
+ $result = $object->fetch(0, $_GET["ref"]);
+ $_GET["account"] = $object->id;
}
// Onglets
- $head=bank_prepare_head($object);
+ $head = bank_prepare_head($object);
dol_fiche_head($head, 'cash', $langs->trans("FinancialAccount"), 0, 'account');
$linkback = ''.$langs->trans("BackToList").' ';
@@ -103,7 +103,7 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
print ' ';
$solde = $object->solde(0);
- if($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED)$colspan = 6;
+ if ($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED)$colspan = 6;
else $colspan = 5;
// Show next coming entries
@@ -114,7 +114,7 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
print ' ';
print ''.$langs->trans("DateDue").' ';
print ''.$langs->trans("Description").' ';
- if($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED )print ''.$langs->trans("Entity").' ';
+ if ($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED)print ''.$langs->trans("Entity").' ';
print ''.$langs->trans("ThirdParty").' ';
print ''.$langs->trans("Debit").' ';
print ''.$langs->trans("Credit").' ';
@@ -139,54 +139,54 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
// Customer invoices
$sql = "SELECT 'invoice' as family, f.rowid as objid, f.ref as ref, f.total_ttc, f.type, f.date_lim_reglement as dlr,";
- $sql.= " s.rowid as socid, s.nom as name, s.fournisseur";
- $sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
- $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid";
- $sql.= " WHERE f.entity IN (".getEntity('invoice').")";
- $sql.= " AND f.paye = 0 AND f.fk_statut = 1"; // Not paid
- $sql.= " AND (f.fk_account IN (0, ".$object->id.") OR f.fk_account IS NULL)"; // Id bank account of invoice
- $sql.= " ORDER BY dlr ASC";
+ $sql .= " s.rowid as socid, s.nom as name, s.fournisseur";
+ $sql .= " FROM ".MAIN_DB_PREFIX."facture as f";
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid";
+ $sql .= " WHERE f.entity IN (".getEntity('invoice').")";
+ $sql .= " AND f.paye = 0 AND f.fk_statut = 1"; // Not paid
+ $sql .= " AND (f.fk_account IN (0, ".$object->id.") OR f.fk_account IS NULL)"; // Id bank account of invoice
+ $sql .= " ORDER BY dlr ASC";
$sqls[] = $sql;
// Supplier invoices
$sql = " SELECT 'invoice_supplier' as family, ff.rowid as objid, ff.ref as ref, ff.ref_supplier as ref_supplier, (-1*ff.total_ttc) as total_ttc, ff.type, ff.date_lim_reglement as dlr,";
- $sql.= " s.rowid as socid, s.nom as name, s.fournisseur";
- $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as ff";
- $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON ff.fk_soc = s.rowid";
- $sql.= " WHERE ff.entity = ".$conf->entity;
- $sql.= " AND ff.paye = 0 AND fk_statut = 1"; // Not paid
- $sql.= " AND (ff.fk_account IN (0, ".$object->id.") OR ff.fk_account IS NULL)"; // Id bank account of supplier invoice
- $sql.= " ORDER BY dlr ASC";
+ $sql .= " s.rowid as socid, s.nom as name, s.fournisseur";
+ $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as ff";
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON ff.fk_soc = s.rowid";
+ $sql .= " WHERE ff.entity = ".$conf->entity;
+ $sql .= " AND ff.paye = 0 AND fk_statut = 1"; // Not paid
+ $sql .= " AND (ff.fk_account IN (0, ".$object->id.") OR ff.fk_account IS NULL)"; // Id bank account of supplier invoice
+ $sql .= " ORDER BY dlr ASC";
$sqls[] = $sql;
// Social contributions
$sql = " SELECT 'social_contribution' as family, cs.rowid as objid, cs.libelle as ref, (-1*cs.amount) as total_ttc, ccs.libelle as type, cs.date_ech as dlr";
- $sql.= ", cs.fk_account";
- $sql.= " FROM ".MAIN_DB_PREFIX."chargesociales as cs";
- $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_chargesociales as ccs ON cs.fk_type = ccs.id";
- $sql.= " WHERE cs.entity = ".$conf->entity;
- $sql.= " AND cs.paye = 0"; // Not paid
- $sql.= " AND (cs.fk_account IN (0, ".$object->id.") OR cs.fk_account IS NULL)"; // Id bank account of social contribution
- $sql.= " ORDER BY dlr ASC";
+ $sql .= ", cs.fk_account";
+ $sql .= " FROM ".MAIN_DB_PREFIX."chargesociales as cs";
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_chargesociales as ccs ON cs.fk_type = ccs.id";
+ $sql .= " WHERE cs.entity = ".$conf->entity;
+ $sql .= " AND cs.paye = 0"; // Not paid
+ $sql .= " AND (cs.fk_account IN (0, ".$object->id.") OR cs.fk_account IS NULL)"; // Id bank account of social contribution
+ $sql .= " ORDER BY dlr ASC";
$sqls[] = $sql;
// others sql
$parameters = array();
$reshook = $hookmanager->executeHooks('addMoreSQL', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
- if(empty($reshook) and isset($hookmanager->resArray['sql'])){
+ if (empty($reshook) and isset($hookmanager->resArray['sql'])) {
$sqls[] = $hookmanager->resArray['sql'];
}
- $error=0;
- $tab_sqlobjOrder=array();
- $tab_sqlobj=array();
+ $error = 0;
+ $tab_sqlobjOrder = array();
+ $tab_sqlobj = array();
- foreach($sqls as $sql){
+ foreach ($sqls as $sql) {
$resql = $db->query($sql);
if ($resql) {
while ($sqlobj = $db->fetch_object($resql)) {
$tab_sqlobj[] = $sqlobj;
- $tab_sqlobjOrder[]= $db->jdate($sqlobj->dlr);
+ $tab_sqlobjOrder[] = $db->jdate($sqlobj->dlr);
}
$db->free($resql);
} else {
@@ -195,13 +195,13 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
}
// Sort array
- if (! $error)
+ if (!$error)
{
array_multisort($tab_sqlobjOrder, $tab_sqlobj);
// Apply distinct filter
foreach ($tab_sqlobj as $key=>$value) {
- $tab_sqlobj[$key] = "'" . serialize($value) . "'";
+ $tab_sqlobj[$key] = "'".serialize($value)."'";
}
$tab_sqlobj = array_unique($tab_sqlobj);
foreach ($tab_sqlobj as $key=>$value) {
@@ -221,52 +221,52 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
if ($obj->family == 'invoice_supplier')
{
- $showline=1;
+ $showline = 1;
// Uncomment this line to avoid to count suppliers credit note (ff.type = 2)
//$showline=(($obj->total_ttc < 0 && $obj->type != 2) || ($obj->total_ttc > 0 && $obj->type == 2))
if ($showline)
{
- $ref=$obj->ref;
- $facturefournstatic->ref=$ref;
- $facturefournstatic->id=$obj->objid;
- $facturefournstatic->type=$obj->type;
+ $ref = $obj->ref;
+ $facturefournstatic->ref = $ref;
+ $facturefournstatic->id = $obj->objid;
+ $facturefournstatic->type = $obj->type;
$ref = $facturefournstatic->getNomUrl(1, '');
$societestatic->id = $obj->socid;
$societestatic->name = $obj->name;
- $refcomp=$societestatic->getNomUrl(1, '', 24);
+ $refcomp = $societestatic->getNomUrl(1, '', 24);
- $totalpayment = -1*$facturefournstatic->getSommePaiement(); // Payment already done
+ $totalpayment = -1 * $facturefournstatic->getSommePaiement(); // Payment already done
}
}
if ($obj->family == 'invoice')
{
- $facturestatic->ref=$obj->ref;
- $facturestatic->id=$obj->objid;
- $facturestatic->type=$obj->type;
+ $facturestatic->ref = $obj->ref;
+ $facturestatic->id = $obj->objid;
+ $facturestatic->type = $obj->type;
$ref = $facturestatic->getNomUrl(1, '');
$societestatic->id = $obj->socid;
$societestatic->name = $obj->name;
- $refcomp=$societestatic->getNomUrl(1, '', 24);
+ $refcomp = $societestatic->getNomUrl(1, '', 24);
- $totalpayment = $facturestatic->getSommePaiement(); // Payment already done
- $totalpayment+= $facturestatic->getSumDepositsUsed();
- $totalpayment+= $facturestatic->getSumCreditNotesUsed();
+ $totalpayment = $facturestatic->getSommePaiement(); // Payment already done
+ $totalpayment += $facturestatic->getSumDepositsUsed();
+ $totalpayment += $facturestatic->getSumCreditNotesUsed();
}
if ($obj->family == 'social_contribution')
{
- $socialcontribstatic->ref=$obj->ref;
- $socialcontribstatic->id=$obj->objid;
- $socialcontribstatic->label=$obj->type;
+ $socialcontribstatic->ref = $obj->ref;
+ $socialcontribstatic->id = $obj->objid;
+ $socialcontribstatic->label = $obj->type;
$ref = $socialcontribstatic->getNomUrl(1, 24);
- $totalpayment = -1*$socialcontribstatic->getSommePaiement(); // Payment already done
+ $totalpayment = -1 * $socialcontribstatic->getSommePaiement(); // Payment already done
}
$parameters = array('obj' => $obj, 'ref' => $ref, 'refcomp' => $refcomp, 'totalpayment' => $totalpayment);
$reshook = $hookmanager->executeHooks('moreFamily', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
- if(empty($reshook)){
+ if (empty($reshook)) {
$ref = isset($hookmanager->resArray['ref']) ? $hookmanager->resArray['ref'] : $ref;
$refcomp = isset($hookmanager->resArray['refcomp']) ? $hookmanager->resArray['refcomp'] : $refcomp;
$totalpayment = isset($hookmanager->resArray['totalpayment']) ? $hookmanager->resArray['totalpayment'] : $totalpayment;
@@ -286,11 +286,14 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
else print $langs->trans("NotDefined");
print "";
print "".$ref." ";
- if($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED ){
- if($obj->family == 'invoice'){
+ if ($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) {
+ if ($obj->family == 'invoice') {
$mc->getInfo($obj->entity);
print "".$mc->label." ";
- }else print " ";
+ }
+ else {
+ print " ";
+ }
}
print "".$refcomp." ";
if ($obj->total_ttc < 0) { print ''.price(abs($total_ttc))." "; };
@@ -310,7 +313,7 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
// Other lines
$parameters = array('solde' => $solde);
$reshook = $hookmanager->executeHooks('printObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
- if(empty($reshook)){
+ if (empty($reshook)) {
print $hookmanager->resPrint;
$solde = isset($hookmanager->resArray['solde']) ? $hookmanager->resArray['solde'] : $solde;
}
diff --git a/htdocs/compta/bank/various_payment/document.php b/htdocs/compta/bank/various_payment/document.php
index 37ff26b0b4b..618cc6006a5 100644
--- a/htdocs/compta/bank/various_payment/document.php
+++ b/htdocs/compta/bank/various_payment/document.php
@@ -45,7 +45,7 @@ $result = restrictedArea($user, 'banque', '', '', '');
// Get parameters
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/bank/various_payment/list.php b/htdocs/compta/bank/various_payment/list.php
index b6cee9a29d0..e2aa6517417 100644
--- a/htdocs/compta/bank/various_payment/list.php
+++ b/htdocs/compta/bank/various_payment/list.php
@@ -56,7 +56,7 @@ if ($search_accountancy_subledger == - 1) $search_accountancy_subledger = '';
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php
index 8e83e6a33a4..57d81c625fe 100644
--- a/htdocs/compta/cashcontrol/cashcontrol_card.php
+++ b/htdocs/compta/cashcontrol/cashcontrol_card.php
@@ -47,7 +47,7 @@ $sday = (GETPOSTISSET('closeday') ?GETPOST('closeday', 'int') : dol_print_date($
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
@@ -77,6 +77,9 @@ $extrafields->fetch_name_optionals_label($object->table_element);
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('cashcontrolcard', 'globalcard'));
+// Load object
+include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
+
/*
* Actions
@@ -96,7 +99,22 @@ if (empty($conf->global->CASHDESK_ID_BANKACCOUNT_CASH) && empty($conf->global->C
if (GETPOST('cancel', 'alpha'))
{
- $action = 'create';
+ if ($action == 'valid') {
+ $action = 'view';
+ }
+ else {
+ $action = 'create';
+ }
+}
+
+if ($action == "reopen")
+{
+ $result = $object->setStatut($object::STATUS_DRAFT, null, '', 'CASHFENCE_REOPEN');
+ if ($result < 0) {
+ dol_print_error($db, $object->error, $object->error);
+ }
+
+ $action = 'view';
}
if ($action == "start")
@@ -162,18 +180,35 @@ elseif ($action == "add")
}
}
-if ($action == "close")
+if ($action == "valid") // validate = close
{
$object->fetch($id);
- $result = $object->valid($user);
+ $db->begin();
+
+ /*
+ $object->day_close = GETPOST('closeday', 'int');
+ $object->month_close = GETPOST('closemonth', 'int');
+ $object->year_close = GETPOST('closeyear', 'int');
+ */
+
+ $object->cash = price2num(GETPOST('cash_amount', 'alpha'));
+ $object->card = price2num(GETPOST('card_amount', 'alpha'));
+ $object->cheque = price2num(GETPOST('cheque_amount', 'alpha'));
+
+ $result = $object->update($user);
+
+ $result = $object->valid($user);
+
if ($result <= 0)
{
setEventMessages($object->error, $object->errors, 'errors');
+ $db->rollback();
}
else
{
setEventMessages($langs->trans("CashFenceDone"), null);
+ $db->commit();
}
$action = "view";
@@ -213,15 +248,22 @@ if ($action == 'confirm_delete' && !empty($permissiontodelete))
$form = new Form($db);
-if ($action == "create" || $action == "start")
+$initialbalanceforterminal = array();
+$theoricalamountforterminal = array();
+$theoricalnbofinvoiceforterminal = array();
+
+if ($action == "create" || $action == "start" || $action == 'close')
{
- llxHeader();
+ if ($action == 'close') {
+ $posmodule = $object->posmodule;
+ $terminalid = $object->posnumber;
+ $terminaltouse = $terminalid;
- $initialbalanceforterminal = array();
- $theoricalamountforterminal = array();
- $theoricalnbofinvoiceforterminal = array();
-
- if (GETPOST('posnumber', 'alpha') != '' && GETPOST('posnumber', 'alpha') != '' && GETPOST('posnumber', 'alpha') != '-1')
+ $syear = $object->year_close;
+ $smonth = $object->month_close;
+ $sday = $object->day_close;
+ }
+ elseif (GETPOST('posnumber', 'alpha') != '' && GETPOST('posnumber', 'alpha') != '' && GETPOST('posnumber', 'alpha') != '-1')
{
$posmodule = GETPOST('posmodule', 'alpha');
$terminalid = GETPOST('posnumber', 'alpha');
@@ -234,7 +276,10 @@ if ($action == "create" || $action == "start")
setEventMessages($langs->trans("OnlyTerminal1IsAvailableForCashDeskModule"), null, 'errors');
$error++;
}
+ }
+ if ($terminalid != '')
+ {
// Calculate $initialbalanceforterminal for terminal 0
foreach ($arrayofpaymentmode as $key => $val)
{
@@ -246,9 +291,7 @@ if ($action == "create" || $action == "start")
// Get the bank account dedicated to this point of sale module/terminal
$vartouse = 'CASHDESK_ID_BANKACCOUNT_CASH'.$terminaltouse;
- $bankid = $conf->global->$vartouse; // This value is ok for 'Terminal 0' for module 'CashDesk' and 'TakePos' (they manage only 1 terminal)
- // Hook to get the good bank id according to posmodule and posnumber.
- // @todo add hook here
+ $bankid = $conf->global->$vartouse;
if ($bankid > 0)
{
@@ -274,11 +317,9 @@ if ($action == "create" || $action == "start")
}
}
- // Calculate $theoricalamountforterminal for terminal 0
+ // Calculate $theoricalamountforterminal
foreach ($arrayofpaymentmode as $key => $val)
{
- /*$sql = "SELECT SUM(amount) as total FROM ".MAIN_DB_PREFIX."bank";
- $sql.= " WHERE fk_account = ".$bankid;*/
$sql = "SELECT SUM(pf.amount) as total, COUNT(*) as nb";
$sql .= " FROM ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."facture as f, ".MAIN_DB_PREFIX."paiement as p, ".MAIN_DB_PREFIX."c_paiement as cp";
$sql .= " WHERE pf.fk_facture = f.rowid AND p.rowid = pf.fk_paiement AND cp.id = p.fk_paiement";
@@ -315,197 +356,230 @@ if ($action == "create" || $action == "start")
}
}
- print load_fiche_titre($langs->trans("CashControl")." - ".$langs->trans("New"), '', 'cash-register');
+ //var_dump($theoricalamountforterminal); var_dump($theoricalnbofinvoiceforterminal);
+ if ($action != 'close') {
+ llxHeader();
- print '';
- print ' ';
- if ($action == 'start' && GETPOST('posnumber', 'int') != '' && GETPOST('posnumber', 'int') != '' && GETPOST('posnumber', 'int') != '-1')
- {
- print ' ';
- }
- else
- {
- print ' ';
- }
- print '';
- print '';
- print ''.$langs->trans("Module").' ';
- print ''.$langs->trans("Terminal").' ';
- print ''.$langs->trans("Year").' ';
- print ''.$langs->trans("Month").' ';
- print ''.$langs->trans("Day").' ';
- print ' ';
- print " \n";
+ print load_fiche_titre($langs->trans("CashControl")." - ".$langs->trans("New"), '', 'cash-register');
- $disabled = 0;
- $prefix = 'close';
+ print '';
+ print ' ';
+ if ($action == 'start' && GETPOST('posnumber', 'int') != '' && GETPOST('posnumber', 'int') != '' && GETPOST('posnumber', 'int') != '-1')
+ {
+ print ' ';
+ }
+ elseif ($action == 'close')
+ {
+ print ' ';
+ print ' ';
+ }
+ else
+ {
+ print ' ';
+ }
- print '';
- print ''.$form->selectarray('posmodule', $arrayofposavailable, GETPOST('posmodule', 'alpha'), (count($arrayofposavailable) > 1 ? 1 : 0)).' ';
- print '';
+ print '';
+ print '
';
+ print '';
+ print ''.$langs->trans("Module").' ';
+ print ''.$langs->trans("Terminal").' ';
+ print ''.$langs->trans("Year").' ';
+ print ''.$langs->trans("Month").' ';
+ print ''.$langs->trans("Day").' ';
+ print ' ';
+ print " \n";
- $array = array();
- $numterminals = max(1, $conf->global->TAKEPOS_NUM_TERMINALS);
- for($i = 1; $i <= $numterminals; $i++) {
- $array[$i] = $i;
- }
- $selectedposnumber = 0; $showempty = 1;
- if ($conf->global->TAKEPOS_NUM_TERMINALS == '1')
- {
- $selectedposnumber = 1; $showempty = 0;
- }
- print $form->selectarray('posnumber', $array, GETPOSTISSET('posnumber') ?GETPOST('posnumber', 'int') : $selectedposnumber, $showempty);
- //print ' ';
- print '';
- // Year
- print '';
- $retstring = '';
- for ($year = $syear - 10; $year < $syear + 10; $year++)
- {
- $retstring .= ''.$year.' ';
- }
- $retstring .= " \n";
- print $retstring;
- print ' ';
- // Month
- print '';
- $retstring = '';
- $retstring .= ' ';
- for ($month = 1; $month <= 12; $month++)
- {
- $retstring .= '';
- $retstring .= dol_print_date(mktime(12, 0, 0, $month, 1, 2000), "%b");
- $retstring .= " ";
- }
- $retstring .= " ";
- print $retstring;
- print ' ';
- // Day
- print '';
- $retstring = '';
- $retstring .= ' ';
- for ($day = 1; $day <= 31; $day++)
- {
- $retstring .= ''.$day.' ';
- }
- $retstring .= " ";
- print $retstring;
- print ' ';
- // Button Start
- print '';
- if ($action == 'start' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '-1')
- {
- print '';
- }
- else
- {
- print ' ';
- }
- print ' ';
- print '
';
+ $disabled = 0;
+ $prefix = 'close';
- // Table to see/enter balance
- if ($action == 'start' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '-1')
- {
- $posmodule = GETPOST('posmodule', 'alpha');
- $terminalid = GETPOST('posnumber', 'alpha');
+ print '
';
+ print ''.$form->selectarray('posmodule', $arrayofposavailable, GETPOST('posmodule', 'alpha'), (count($arrayofposavailable) > 1 ? 1 : 0)).' ';
+ print '';
- print ' ';
-
- print '';
-
- print '';
- print ' ';
- print ''.$langs->trans("InitialBankBalance");
- //print ' '.$langs->trans("TheoricalAmount").' '.$langs->trans("RealAmount");
- print ' ';
- print '';
- print $langs->trans("AmountAtEndOfPeriod");
- print ' ';
- print ' ';
- print ' ';
-
- print '';
- print ' ';
- print ''.$langs->trans("Cash");
- //print ' '.$langs->trans("TheoricalAmount").' '.$langs->trans("RealAmount");
- print ' ';
- $i = 0;
- foreach ($arrayofpaymentmode as $key => $val)
+ $array = array();
+ $numterminals = max(1, $conf->global->TAKEPOS_NUM_TERMINALS);
+ for($i = 1; $i <= $numterminals; $i++) {
+ $array[$i] = $i;
+ }
+ $selectedposnumber = 0; $showempty = 1;
+ if ($conf->global->TAKEPOS_NUM_TERMINALS == '1')
+ {
+ $selectedposnumber = 1; $showempty = 0;
+ }
+ print $form->selectarray('posnumber', $array, GETPOSTISSET('posnumber') ?GETPOST('posnumber', 'int') : $selectedposnumber, $showempty);
+ //print ' ';
+ print '';
+ // Year
+ print '';
+ $retstring = '';
+ for ($year = $syear - 10; $year < $syear + 10; $year++)
{
- print ''.$langs->trans($val);
+ $retstring .= ''.$year.' ';
+ }
+ $retstring .= "\n";
+ print $retstring;
+ print ' ';
+ // Month
+ print '';
+ $retstring = '';
+ $retstring .= ' ';
+ for ($month = 1; $month <= 12; $month++)
+ {
+ $retstring .= '';
+ $retstring .= dol_print_date(mktime(12, 0, 0, $month, 1, 2000), "%b");
+ $retstring .= " ";
+ }
+ $retstring .= " ";
+ print $retstring;
+ print ' ';
+ // Day
+ print '';
+ $retstring = '';
+ $retstring .= ' ';
+ for ($day = 1; $day <= 31; $day++)
+ {
+ $retstring .= ''.$day.' ';
+ }
+ $retstring .= " ";
+ print $retstring;
+ print ' ';
+ // Button Start
+ print '';
+ if ($action == 'start' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '-1')
+ {
+ print '';
+ }
+ else
+ {
+ print ' ';
+ }
+ print ' ';
+ print '
';
+ print '';
+
+ // Table to see/enter balance
+ if (($action == 'start' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '-1') || $action == 'close')
+ {
+ $posmodule = GETPOST('posmodule', 'alpha');
+ $terminalid = GETPOST('posnumber', 'alpha');
+
+ print ' ';
+
+ print '';
+ }
+
+ print '';
}
- print '';
}
-if (empty($action) || $action == "view")
+if (empty($action) || $action == "view" || $action == "close")
{
$result = $object->fetch($id);
@@ -520,7 +594,7 @@ if (empty($action) || $action == "view")
$head[0][1] = $langs->trans("Card");
$head[0][2] = 'cashcontrol';
- dol_fiche_head($head, 'cashcontrol', $langs->trans("CashControl"), -1, 'cashcontrol');
+ dol_fiche_head($head, 'cashcontrol', $langs->trans("CashControl"), -1, 'account');
$linkback = ''.$langs->trans("BackToList").' ';
@@ -533,7 +607,7 @@ if (empty($action) || $action == "view")
print '';
print '
';
print '
';
- print '
';
+ print '';
print '';
print $langs->trans("Ref");
@@ -587,17 +661,212 @@ if (empty($action) || $action == "view")
dol_fiche_end();
- print '';
- print '
';
- if ($object->status == CashControl::STATUS_DRAFT)
- {
- print '
';
+ if ($action != 'close') {
+ print '
';
- print '
';
- }
- print '
';
+ print '
';
- print '
';
+ if ($object->status == CashControl::STATUS_DRAFT)
+ {
+ print '
';
+
+ print '
';
+ } else {
+ print '
';
+ }
+
+ print '
';
+
+ print ' ';
+ } else {
+ print '';
+ print ' ';
+ if ($action == 'start' && GETPOST('posnumber', 'int') != '' && GETPOST('posnumber', 'int') != '' && GETPOST('posnumber', 'int') != '-1')
+ {
+ print ' ';
+ }
+ elseif ($action == 'close')
+ {
+ print ' ';
+ print ' ';
+ }
+ else
+ {
+ print ' ';
+ }
+
+ /*
+ print '';
+ print '
';
+ print '';
+ print ''.$langs->trans("Module").' ';
+ print ''.$langs->trans("Terminal").' ';
+ print ''.$langs->trans("Year").' ';
+ print ''.$langs->trans("Month").' ';
+ print ''.$langs->trans("Day").' ';
+ print ' ';
+ print " \n";
+
+ $disabled = 1;
+ $prefix = 'close';
+
+ print '';
+ print ''.$form->selectarray('posmodulebis', $arrayofposavailable, $object->posmodule, (count($arrayofposavailable) > 1 ? 1 : 0), 0, 0, '', 0, 0, $disabled).' ';
+ print ' ';
+ print '';
+
+ $array = array();
+ $numterminals = max(1, $conf->global->TAKEPOS_NUM_TERMINALS);
+ for($i = 1; $i <= $numterminals; $i++) {
+ $array[$i] = $i;
+ }
+ $selectedposnumber = $object->posnumber; $showempty = 1;
+ //print $form->selectarray('posnumber', $array, GETPOSTISSET('posnumber') ?GETPOST('posnumber', 'int') : $selectedposnumber, $showempty, 0, 0, '', 0, 0, $disabled);
+ print ' ';
+ print ' ';
+ print ' ';
+ // Year
+ print '';
+ print ' ';
+ print ' ';
+ print ' ';
+ // Month
+ print '';
+ print ' ';
+ print ' ';
+ print ' ';
+ // Day
+ print '';
+ print ' ';
+ print ' ';
+ print ' ';
+
+ print ' ';
+ print '
';
+ print '
';
+ */
+
+ // Table to see/enter balance
+ if (($action == 'start' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '' && GETPOST('posnumber') != '-1') || $action == 'close')
+ {
+ $posmodule = $object->posmodule;
+ $terminalid = $object->posnumber;
+
+ print ' ';
+
+ print '';
+ }
+
+ print ' ';
+ }
}
}
diff --git a/htdocs/compta/cashcontrol/cashcontrol_list.php b/htdocs/compta/cashcontrol/cashcontrol_list.php
index 6c59276d600..d559fad2b30 100644
--- a/htdocs/compta/cashcontrol/cashcontrol_list.php
+++ b/htdocs/compta/cashcontrol/cashcontrol_list.php
@@ -65,7 +65,7 @@ $id = GETPOST('id', 'int');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/cashcontrol/class/cashcontrol.class.php b/htdocs/compta/cashcontrol/class/cashcontrol.class.php
index 32f7533b6c3..f30410d187f 100644
--- a/htdocs/compta/cashcontrol/class/cashcontrol.class.php
+++ b/htdocs/compta/cashcontrol/class/cashcontrol.class.php
@@ -104,6 +104,7 @@ class CashControl extends CommonObject
const STATUS_DRAFT = 0;
const STATUS_VALIDATED = 1;
+ const STATUS_CLOSED = 1; // For the moment CLOSED = VALIDATED
/**
@@ -288,6 +289,18 @@ class CashControl extends CommonObject
return $result;
}
+ /**
+ * Update object into database
+ *
+ * @param User $user User that modifies
+ * @param bool $notrigger false=launch triggers after, true=disable triggers
+ * @return int <0 if KO, >0 if OK
+ */
+ public function update(User $user, $notrigger = false)
+ {
+ return $this->updateCommon($user, $notrigger);
+ }
+
/**
* Delete object in database
*
diff --git a/htdocs/compta/cashcontrol/report.php b/htdocs/compta/cashcontrol/report.php
index 8cd74f1cccf..1ea06eba9e9 100644
--- a/htdocs/compta/cashcontrol/report.php
+++ b/htdocs/compta/cashcontrol/report.php
@@ -40,6 +40,7 @@ $langs->load("bills");
$id = GETPOST('id', 'int');
$_GET['optioncss'] = "print";
+
$cashcontrol = new CashControl($db);
$cashcontrol->fetch($id);
@@ -69,6 +70,8 @@ $terminalid = $cashcontrol->posnumber;
* View
*/
+$param = '';
+
llxHeader('', $langs->trans("CashControl"), '', '', 0, 0, array(), array(), $param);
/*$sql = "SELECT b.rowid, b.dateo as do, b.datev as dv, b.amount, b.label, b.rappro as conciliated, b.num_releve, b.num_chq,";
@@ -268,21 +271,21 @@ if ($resql)
print "
";
print $langs->trans("Cash").": ".price($cash);
- if ($cash != $cashcontrol->cash) {
+ if ($cashcontrol->status == $cashcontrol::STATUS_VALIDATED && $cash != $cashcontrol->cash) {
print ' <> '.$langs->trans("Declared").': '.price($cashcontrol->cash).' ';
}
print " ";
//print ' ';
print $langs->trans("PaymentTypeCHQ").": ".price($cheque);
- if ($cheque != $cashcontrol->cheque) {
+ if ($cashcontrol->status == $cashcontrol::STATUS_VALIDATED && $cheque != $cashcontrol->cheque) {
print ' <> '.$langs->trans("Declared").': '.price($cashcontrol->cheque).' ';
}
print " ";
//print ' ';
print $langs->trans("PaymentTypeCB").": ".price($bank);
- if ($bank != $cashcontrol->card) {
+ if ($cashcontrol->status == $cashcontrol::STATUS_VALIDATED && $bank != $cashcontrol->card) {
print ' <> '.$langs->trans("Declared").': '.price($cashcontrol->card).' ';
}
print " ";
diff --git a/htdocs/compta/charges/index.php b/htdocs/compta/charges/index.php
index 653a13f01a1..e9aa35d80b3 100644
--- a/htdocs/compta/charges/index.php
+++ b/htdocs/compta/charges/index.php
@@ -58,7 +58,7 @@ $search_account = GETPOST('search_account', 'int');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/clients.php b/htdocs/compta/clients.php
index 8cfeeda613e..b9db96a78bc 100644
--- a/htdocs/compta/clients.php
+++ b/htdocs/compta/clients.php
@@ -46,7 +46,7 @@ $mode=GETPOST("mode");
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/deplacement/document.php b/htdocs/compta/deplacement/document.php
index 2829e257b3b..d85f4239d02 100644
--- a/htdocs/compta/deplacement/document.php
+++ b/htdocs/compta/deplacement/document.php
@@ -50,7 +50,7 @@ $result = restrictedArea($user, 'deplacement', $id, '');
// Get parameters
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/deplacement/index.php b/htdocs/compta/deplacement/index.php
index fde600aff8f..e95d7f95732 100644
--- a/htdocs/compta/deplacement/index.php
+++ b/htdocs/compta/deplacement/index.php
@@ -32,43 +32,43 @@ $langs->loadLangs(array('companies', 'users', 'trips'));
// Security check
$socid = GETPOST('socid', 'int');
-if ($user->socid) $socid=$user->socid;
+if ($user->socid) $socid = $user->socid;
$result = restrictedArea($user, 'deplacement', '', '');
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
-if (! $sortorder) $sortorder="DESC";
-if (! $sortfield) $sortfield="d.dated";
-$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
+if (!$sortorder) $sortorder = "DESC";
+if (!$sortfield) $sortfield = "d.dated";
+$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
/*
* View
*/
-$tripandexpense_static=new Deplacement($db);
+$tripandexpense_static = new Deplacement($db);
$childids = $user->getAllChildIds();
-$childids[]=$user->id;
+$childids[] = $user->id;
//$help_url='EN:Module_Donations|FR:Module_Dons|ES:Módulo_Donaciones';
-$help_url='';
+$help_url = '';
llxHeader('', $langs->trans("ListOfFees"), $help_url);
-$totalnb=0;
+$totalnb = 0;
$sql = "SELECT count(d.rowid) as nb, sum(d.km) as km, d.type";
-$sql.= " FROM ".MAIN_DB_PREFIX."deplacement as d";
-$sql.= " WHERE d.entity = ".$conf->entity;
-if (empty($user->rights->deplacement->readall) && empty($user->rights->deplacement->lire_tous)) $sql.=' AND d.fk_user IN ('.join(',', $childids).')';
-$sql.= " GROUP BY d.type";
-$sql.= " ORDER BY d.type";
+$sql .= " FROM ".MAIN_DB_PREFIX."deplacement as d";
+$sql .= " WHERE d.entity = ".$conf->entity;
+if (empty($user->rights->deplacement->readall) && empty($user->rights->deplacement->lire_tous)) $sql .= ' AND d.fk_user IN ('.join(',', $childids).')';
+$sql .= " GROUP BY d.type";
+$sql .= " ORDER BY d.type";
$result = $db->query($sql);
if ($result)
@@ -102,10 +102,10 @@ print '';
print ''.$langs->trans("Statistics").' ';
print " \n";
-$listoftype=$tripandexpense_static->listOfTypes();
+$listoftype = $tripandexpense_static->listOfTypes();
foreach ($listoftype as $code => $label)
{
- $dataseries[]=array($label, (isset($nb[$code])?(int) $nb[$code]:0));
+ $dataseries[] = array($label, (isset($nb[$code]) ? (int) $nb[$code] : 0));
}
if ($conf->use_javascript_ajax)
@@ -115,12 +115,12 @@ if ($conf->use_javascript_ajax)
include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
$dolgraph = new DolGraph();
$dolgraph->SetData($dataseries);
- $dolgraph->setShowLegend(1);
+ $dolgraph->setShowLegend(2);
$dolgraph->setShowPercent(1);
$dolgraph->SetType(array('pie'));
- $dolgraph->setWidth('100%');
+ $dolgraph->setHeight('200');
$dolgraph->draw('idgraphstatus');
- print $dolgraph->show($totalnb?0:1);
+ print $dolgraph->show($totalnb ? 0 : 1);
print ' ';
}
@@ -137,25 +137,25 @@ print '
';
print '';
-$max=10;
+$max = 10;
$langs->load("boxes");
$sql = "SELECT u.rowid as uid, u.lastname, u.firstname, d.rowid, d.dated as date, d.tms as dm, d.km, d.fk_statut";
-$sql.= " FROM ".MAIN_DB_PREFIX."deplacement as d, ".MAIN_DB_PREFIX."user as u";
-if (!$user->rights->societe->client->voir && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."societe_commerciaux as sc";
-$sql.= " WHERE u.rowid = d.fk_user";
-$sql.= " AND d.entity = ".$conf->entity;
-if (empty($user->rights->deplacement->readall) && empty($user->rights->deplacement->lire_tous)) $sql.=' AND d.fk_user IN ('.join(',', $childids).')';
-if (!$user->rights->societe->client->voir && !$user->socid) $sql.= " AND d.fk_soc = s. rowid AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
-if ($socid) $sql.= " AND d.fk_soc = ".$socid;
-$sql.= $db->order("d.tms", "DESC");
-$sql.= $db->plimit($max, 0);
+$sql .= " FROM ".MAIN_DB_PREFIX."deplacement as d, ".MAIN_DB_PREFIX."user as u";
+if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+$sql .= " WHERE u.rowid = d.fk_user";
+$sql .= " AND d.entity = ".$conf->entity;
+if (empty($user->rights->deplacement->readall) && empty($user->rights->deplacement->lire_tous)) $sql .= ' AND d.fk_user IN ('.join(',', $childids).')';
+if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND d.fk_soc = s. rowid AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
+if ($socid) $sql .= " AND d.fk_soc = ".$socid;
+$sql .= $db->order("d.tms", "DESC");
+$sql .= $db->plimit($max, 0);
$result = $db->query($sql);
if ($result)
{
- $var=false;
+ $var = false;
$num = $db->num_rows($result);
$i = 0;
@@ -171,16 +171,16 @@ if ($result)
{
$total_ttc = $totalam = $total = 0;
- $deplacementstatic=new Deplacement($db);
- $userstatic=new User($db);
+ $deplacementstatic = new Deplacement($db);
+ $userstatic = new User($db);
while ($i < $num && $i < $max)
{
$obj = $db->fetch_object($result);
- $deplacementstatic->ref=$obj->rowid;
- $deplacementstatic->id=$obj->rowid;
- $userstatic->id=$obj->uid;
- $userstatic->lastname=$obj->lastname;
- $userstatic->firstname=$obj->firstname;
+ $deplacementstatic->ref = $obj->rowid;
+ $deplacementstatic->id = $obj->rowid;
+ $userstatic->id = $obj->uid;
+ $userstatic->lastname = $obj->lastname;
+ $userstatic->firstname = $obj->firstname;
print '
';
print ''.$deplacementstatic->getNomUrl(1).' ';
print ''.$userstatic->getNomUrl(1).' ';
diff --git a/htdocs/compta/deplacement/list.php b/htdocs/compta/deplacement/list.php
index e8e806bbbcd..ea2d68cc126 100644
--- a/htdocs/compta/deplacement/list.php
+++ b/htdocs/compta/deplacement/list.php
@@ -45,7 +45,7 @@ $search_company=GETPOST('search_company', 'alpha');
// $search_amount=GETPOST('search_amount','alpha');
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
diff --git a/htdocs/compta/facture/card-rec.php b/htdocs/compta/facture/card-rec.php
index 7d1f529bf82..dd295fa3112 100644
--- a/htdocs/compta/facture/card-rec.php
+++ b/htdocs/compta/facture/card-rec.php
@@ -70,7 +70,7 @@ $month_date_when = GETPOST('month_date_when');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
if (!$sortorder) $sortorder = 'DESC';
diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index 3e59b92a146..8d2de29ca21 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -101,6 +101,9 @@ $usehm = (!empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE) ? $conf->global-
$object = new Facture($db);
$extrafields = new ExtraFields($db);
+// Fetch optionals attributes and labels
+$extrafields->fetch_name_optionals_label($object->table_element);
+
// Load object
if ($id > 0 || !empty($ref)) {
if ($action != 'add') {
@@ -293,31 +296,32 @@ if (empty($reshook))
// Also negative lines should not be allowed on 'non Credit notes' invoices. A test is done when adding or updating lines but we must
// do it again in validation to avoid cases where invoice is created from another object that allow negative lines.
- // Note that we can accept the negative line if sum with other lines with same vat is positivie: Because all the lines will be merged together
+ // Note that we can accept the negative line if sum with other lines with same vat makes total positive: Because all the lines will be merged together
// when converted into 'available credit' and we will get a positive available credit line.
// Note: Other solution if you want to add a negative line on invoice, is to create a discount for customer and consumme it (but this is possible on standard invoice only).
- $array_of_pu_ht_per_vat_rate = array();
- $array_of_pu_ht_devise_per_vat_rate = array();
+ $array_of_total_ht_per_vat_rate = array();
+ $array_of_total_ht_devise_per_vat_rate = array();
foreach ($object->lines as $line) {
- if (empty($array_of_pu_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code])) $array_of_pu_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] = 0;
- if (empty($array_of_pu_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code])) $array_of_pu_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] = 0;
- $array_of_pu_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] += $line->subprice;
- $array_of_pu_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] += $line->multicurrency_subprice;
+ if (empty($array_of_total_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code])) $array_of_total_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] = 0;
+ if (empty($array_of_total_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code])) $array_of_total_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] = 0;
+ $array_of_total_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] += $line->total_ht;
+ $array_of_total_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] += $line->multicurrency_total_ht;
}
- //var_dump($array_of_pu_ht_per_vat_rate);exit;
- foreach ($array_of_pu_ht_per_vat_rate as $vatrate => $tmpvalue)
- {
- $pu_ht = $array_of_pu_ht_per_vat_rate[$vatrate];
- $pu_ht_devise = $array_of_pu_ht_devise_per_vat_rate[$vatrate];
- if (($pu_ht < 0 || $pu_ht_devise < 0) && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES))
+ //var_dump($array_of_total_ht_per_vat_rate);exit;
+ foreach ($array_of_total_ht_per_vat_rate as $vatrate => $tmpvalue)
+ {
+ $tmp_total_ht = $array_of_total_ht_per_vat_rate[$vatrate];
+ $tmp_total_ht_devise = $array_of_total_ht_devise_per_vat_rate[$vatrate];
+
+ if (($tmp_total_ht < 0 || $tmp_total_ht_devise < 0) && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES))
{
$langs->load("errors");
if ($object->type == $object::TYPE_DEPOSIT) {
// Using negative lines on deposit lead to headach and blocking problems when you want to consume them.
setEventMessages($langs->trans("ErrorLinesCantBeNegativeOnDeposits"), null, 'errors');
} else {
- setEventMessages($langs->trans("ErrorFieldCantBeNegativeOnInvoice", $langs->transnoentitiesnoconv("UnitPriceHT"), $langs->transnoentitiesnoconv("CustomerAbsoluteDiscountShort")), null, 'errors');
+ setEventMessages($langs->trans("ErrorLinesCantBeNegativeForOneVATRate"), null, 'errors');
}
$error++;
$action = '';
@@ -793,7 +797,7 @@ if (empty($reshook))
$canconvert = 0;
if ($object->type == Facture::TYPE_DEPOSIT && empty($discountcheck->id)) $canconvert = 1; // we can convert deposit into discount if deposit is payed (completely, partially or not at all) and not already converted (see real condition into condition used to show button converttoreduc)
- if (($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_STANDARD) && $object->paye == 0 && empty($discountcheck->id)) $canconvert = 1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc)
+ if (($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_SITUATION) && $object->paye == 0 && empty($discountcheck->id)) $canconvert = 1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc)
if ($canconvert)
{
$db->begin();
@@ -1519,7 +1523,7 @@ if (empty($reshook))
// If we create a deposit with all lines and a percent, we change amount
if ($_POST['type'] == Facture::TYPE_DEPOSIT && $typeamount == 'variablealllines') {
if (is_array($lines)) {
- foreach($lines as $line) {
+ foreach ($lines as $line) {
// We keep ->subprice and ->pa_ht, but we change the qty
$line->qty = price2num($line->qty * $valuedeposit / 100, 'MS');
}
@@ -3351,8 +3355,8 @@ if ($action == 'create')
print ' ';
// Bank Account
- if (isset($_POST['fk_account'])) {
- $fk_account = $_POST['fk_account'];
+ if (GETPOSTISSET('fk_account')) {
+ $fk_account = GETPOST('fk_account');
}
print '
'.$langs->trans('BankAccount').' ';
@@ -3640,7 +3644,7 @@ elseif ($id > 0 || !empty($ref))
// Confirmation de la conversion de l'avoir en reduc
if ($action == 'converttoreduc') {
- if ($object->type == Facture::TYPE_STANDARD) $type_fac = 'ExcessReceived';
+ if ($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_SITUATION) $type_fac = 'ExcessReceived';
elseif ($object->type == Facture::TYPE_CREDIT_NOTE) $type_fac = 'CreditNote';
elseif ($object->type == Facture::TYPE_DEPOSIT) $type_fac = 'Deposit';
$text = $langs->trans('ConfirmConvertToReduc', strtolower($langs->transnoentities($type_fac)));
@@ -4517,7 +4521,7 @@ elseif ($id > 0 || !empty($ref))
$current_situation_counter = array();
foreach ($object->tab_previous_situation_invoice as $prev_invoice) {
- $totalpaye = $prev_invoice->getSommePaiement();
+ $totalpaye_prev = $prev_invoice->getSommePaiement();
$total_prev_ht += $prev_invoice->total_ht;
$total_prev_ttc += $prev_invoice->total_ttc;
$current_situation_counter[] = (($prev_invoice->type == Facture::TYPE_CREDIT_NOTE) ?-1 : 1) * $prev_invoice->situation_counter;
@@ -4528,7 +4532,7 @@ elseif ($id > 0 || !empty($ref))
if (!empty($conf->banque->enabled)) print ' ';
print ''.price($prev_invoice->total_ht).' ';
print ''.price($prev_invoice->total_ttc).' ';
- print ''.$prev_invoice->getLibStatut(3, $totalpaye).' ';
+ print ''.$prev_invoice->getLibStatut(3, $totalpaye_prev).' ';
print '';
}
}
@@ -5093,9 +5097,9 @@ elseif ($id > 0 || !empty($ref))
}
// Reverse back money or convert to reduction
- if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_STANDARD) {
+ if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_SITUATION) {
// For credit note only
- if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercanissuepayment)
+ if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $usercanissuepayment)
{
if ($resteapayer == 0)
{
@@ -5108,12 +5112,12 @@ elseif ($id > 0 || !empty($ref))
}
// For standard invoice with excess received
- if ($object->type == Facture::TYPE_STANDARD && empty($object->paye) && ($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits) < 0 && $usercancreate && empty($discount->id))
+ if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_SITUATION) && $object->statut == Facture::STATUS_VALIDATED && empty($object->paye) && $resteapayer < 0 && $usercancreate && empty($discount->id))
{
print '
id.'&action=converttoreduc">'.$langs->trans('ConvertExcessReceivedToReduc').' ';
}
// For credit note
- if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercancreate
+ if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $usercancreate
&& (!empty($conf->global->INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED) || $object->getSommePaiement() == 0)
) {
print '
id.'&action=converttoreduc" title="'.dol_escape_htmltag($langs->trans("ConfirmConvertToReduc2")).'">'.$langs->trans('ConvertToReduc').' ';
@@ -5126,7 +5130,7 @@ elseif ($id > 0 || !empty($ref))
}
// Classify paid
- if (($object->statut == 1 && $object->paye == 0 && $usercanissuepayment && (($object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT && $resteapayer <= 0) || ($object->type == Facture::TYPE_CREDIT_NOTE && $resteapayer >= 0)))
+ if (($object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $usercanissuepayment && (($object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT && $resteapayer <= 0) || ($object->type == Facture::TYPE_CREDIT_NOTE && $resteapayer >= 0)))
|| ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 0 && $object->total_ttc > 0 && $resteapayer == 0 && $usercanissuepayment && empty($discount->id))
)
{
@@ -5135,7 +5139,7 @@ elseif ($id > 0 || !empty($ref))
// Classify 'closed not completely paid' (possible si validee et pas encore classee payee)
- if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0 && $usercanissuepayment)
+ if ($object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $resteapayer > 0 && $usercanissuepayment)
{
if ($totalpaye > 0 || $totalcreditnotes > 0)
{
diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php
index 7c7437bfb8e..969d351d1bb 100644
--- a/htdocs/compta/facture/class/api_invoices.class.php
+++ b/htdocs/compta/facture/class/api_invoices.class.php
@@ -1,5 +1,6 @@
+/* Copyright (C) 2020 Thibault FOUCART
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -63,11 +64,65 @@ class Invoices extends DolibarrApi
*/
public function get($id, $contact_list = 1)
{
+ return $this->_fetch($id, '', '', $contact_list);
+ }
+
+ /**
+ * Get properties of an invoice object by ref
+ *
+ * Return an array with invoice informations
+ *
+ * @param string $ref Ref of object
+ * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id
+ * @return array|mixed data without useless information
+ *
+ * @url GET ref/{ref}
+ *
+ * @throws RestException
+ */
+ public function getByRef($ref, $contact_list = 1)
+ {
+ return $this->_fetch('', $ref, '', $contact_list);
+ }
+
+ /**
+ * Get properties of an invoice object by ref_ext
+ *
+ * Return an array with invoice informations
+ *
+ * @param string $ref_ext External reference of object
+ * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id
+ * @return array|mixed data without useless information
+ *
+ * @url GET ref_ext/{ref_ext}
+ *
+ * @throws RestException
+ */
+ public function getByRefExt($ref_ext, $contact_list = 1)
+ {
+ return $this->_fetch('', '', $ref_ext, $contact_list);
+ }
+
+ /**
+ * Get properties of an invoice object
+ *
+ * Return an array with invoice informations
+ *
+ * @param int $id ID of order
+ * @param string $ref Ref of object
+ * @param string $ref_ext External reference of object
+ * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id
+ * @return array|mixed data without useless information
+ *
+ * @throws RestException
+ */
+ private function _fetch($id, $ref = '', $ref_ext = '', $contact_list = 1)
+ {
if (!DolibarrApiAccess::$user->rights->facture->lire) {
throw new RestException(401);
}
- $result = $this->invoice->fetch($id);
+ $result = $this->invoice->fetch($id, $ref, $ref_ext);
if (!$result) {
throw new RestException(404, 'Invoice not found');
}
@@ -87,7 +142,7 @@ class Invoices extends DolibarrApi
$this->invoice->fetchObjectLinked();
return $this->_cleanObjectDatas($this->invoice);
- }
+ }
/**
* List invoices
@@ -242,10 +297,10 @@ class Invoices extends DolibarrApi
* @url POST /createfromorder/{orderid}
*
* @return int
- * @throws 400
- * @throws 401
- * @throws 404
- * @throws 405
+ * @throws RestException 400
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 405
*/
public function createInvoiceFromOrder($orderid)
{
@@ -318,10 +373,9 @@ class Invoices extends DolibarrApi
*
* @return array
*
- * @throws 200
- * @throws 304
- * @throws 401
- * @throws 404
+ * @throws RestException 304
+ * @throws RestException 401
+ * @throws RestException 404 Invoice not found
*/
public function putLine($id, $lineid, $request_data = null)
{
@@ -383,8 +437,9 @@ class Invoices extends DolibarrApi
* @url POST {id}/contact/{contactid}/{type}
*
* @return int
- * @throws 401
- * @throws 404
+ *
+ * @throws RestException 401
+ * @throws RestException 404
*/
public function postContact($id, $contactid, $type)
{
@@ -424,9 +479,10 @@ class Invoices extends DolibarrApi
* @url DELETE {id}/contact/{rowid}
*
* @return array
- * @throws 401
- * @throws 404
- * @throws 500
+ *
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 500
*/
public function deleteContact($id, $rowid)
{
@@ -463,10 +519,10 @@ class Invoices extends DolibarrApi
*
* @return array
*
- * @throws 400
- * @throws 401
- * @throws 404
- * @throws 405
+ * @throws RestException 400
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 405
*/
public function deleteLine($id, $lineid)
{
@@ -591,10 +647,10 @@ class Invoices extends DolibarrApi
*
* @return int
*
- * @throws 200
- * @throws 401
- * @throws 404
- * @throws 400
+ * @throws RestException 304
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 400
*/
public function postLine($id, $request_data = null)
{
@@ -673,11 +729,10 @@ class Invoices extends DolibarrApi
*
* @return array
*
- * @throws 200
- * @throws 304
- * @throws 401
- * @throws 404
- * @throws 500
+ * @throws RestException 304
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 500
*
*/
public function addContact($id, $fk_socpeople, $type_contact, $source, $notrigger = 0)
@@ -723,11 +778,10 @@ class Invoices extends DolibarrApi
*
* @return array
*
- * @throws 200
- * @throws 304
- * @throws 401
- * @throws 404
- * @throws 500
+ * @throws RestException 304
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 500
*
*/
public function settodraft($id, $idwarehouse = -1)
@@ -827,11 +881,10 @@ class Invoices extends DolibarrApi
*
* @return array An invoice object
*
- * @throws 200
- * @throws 304
- * @throws 401
- * @throws 404
- * @throws 500
+ * @throws RestException 304
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 500
*/
public function settopaid($id, $close_code = '', $close_note = '')
{
@@ -878,11 +931,10 @@ class Invoices extends DolibarrApi
*
* @return array An invoice object
*
- * @throws 200
- * @throws 304
- * @throws 401
- * @throws 404
- * @throws 500
+ * @throws RestException 304
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 500
*/
public function settounpaid($id)
{
@@ -927,11 +979,10 @@ class Invoices extends DolibarrApi
*
* @return array An invoice object
*
- * @throws 200
- * @throws 304
- * @throws 401
- * @throws 404
- * @throws 500
+ * @throws RestException 304
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 500
*/
public function markAsCreditAvailable($id)
{
@@ -1103,10 +1154,11 @@ class Invoices extends DolibarrApi
* @url POST {id}/usediscount/{discountid}
*
* @return int
- * @throws 400
- * @throws 401
- * @throws 404
- * @throws 405
+ *
+ * @throws RestException 400
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 405
*/
public function useDiscount($id, $discountid)
{
@@ -1149,10 +1201,11 @@ class Invoices extends DolibarrApi
* @url POST {id}/usecreditnote/{discountid}
*
* @return int
- * @throws 400
- * @throws 401
- * @throws 404
- * @throws 405
+ *
+ * @throws RestException 400
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 405
*/
public function useCreditNote($id, $discountid)
{
@@ -1194,10 +1247,11 @@ class Invoices extends DolibarrApi
* @url GET {id}/payments
*
* @return array
- * @throws 400
- * @throws 401
- * @throws 404
- * @throws 405
+ *
+ * @throws RestException 400
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 405
*/
public function getPayments($id)
{
@@ -1243,9 +1297,10 @@ class Invoices extends DolibarrApi
* @url POST {id}/payments
*
* @return int Payment ID
- * @throws 400
- * @throws 401
- * @throws 404
+ *
+ * @throws RestException 400
+ * @throws RestException 401
+ * @throws RestException 404
*/
public function addPayment($id, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement = '', $comment = '', $chqemetteur = '', $chqbank = '')
{
@@ -1362,10 +1417,11 @@ class Invoices extends DolibarrApi
* @url POST /paymentsdistributed
*
* @return int Payment ID
- * @throws 400
- * @throws 401
- * @throws 403
- * @throws 404
+ *
+ * @throws RestException 400
+ * @throws RestException 401
+ * @throws RestException 403
+ * @throws RestException 404
*/
public function addPaymentDistributed($arrayofamounts, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement = '', $comment = '', $chqemetteur = '', $chqbank = '')
{
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index 294493ed081..b0b78b3bf03 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -112,7 +112,13 @@ class Facture extends CommonInvoice
public $date; // Date invoice
public $datem;
public $ref_client;
- public $ref_int;
+
+ /**
+ * @var int Ref Int
+ * @deprecated
+ */
+ public $ref_int; // deprecated
+
//Check constants for types
public $type = self::TYPE_STANDARD;
@@ -250,15 +256,15 @@ class Facture extends CommonInvoice
/**
* @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
*/
- public $fields=array(
+ public $fields = array(
'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>15),
'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>20, 'index'=>1),
'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>25),
- 'ref_int' =>array('type'=>'varchar(255)', 'label'=>'Ref int', 'enabled'=>1, 'visible'=>0, 'position'=>30),
+ 'ref_int' =>array('type'=>'varchar(255)', 'label'=>'Ref int', 'enabled'=>1, 'visible'=>0, 'position'=>30), // deprecated
'type' =>array('type'=>'smallint(6)', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35),
'ref_client' =>array('type'=>'varchar(255)', 'label'=>'Ref client', 'enabled'=>1, 'visible'=>-1, 'position'=>40),
- 'increment' =>array('type'=>'varchar(10)', 'label'=>'Increment', 'enabled'=>1, 'visible'=>-1, 'position'=>45),
+ //'increment' =>array('type'=>'varchar(10)', 'label'=>'Increment', 'enabled'=>1, 'visible'=>-1, 'position'=>45),
'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>50),
'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>55),
'datef' =>array('type'=>'date', 'label'=>'DateInvoice', 'enabled'=>1, 'visible'=>-1, 'position'=>60),
@@ -267,18 +273,17 @@ class Facture extends CommonInvoice
'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>75),
'paye' =>array('type'=>'smallint(6)', 'label'=>'InvoicePaidCompletely', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>80),
//'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>85),
- 'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
- 'remise_absolue' =>array('type'=>'double', 'label'=>'Remise absolue', 'enabled'=>1, 'visible'=>-1, 'position'=>95),
- 'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
+ 'remise_percent' =>array('type'=>'double', 'label'=>'RelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
+ 'remise_absolue' =>array('type'=>'double', 'label'=>'CustomerRelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>95),
+ //'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
'close_code' =>array('type'=>'varchar(16)', 'label'=>'EarlyClosingReason', 'enabled'=>1, 'visible'=>-1, 'position'=>105),
'close_note' =>array('type'=>'varchar(128)', 'label'=>'EarlyClosingComment', 'enabled'=>1, 'visible'=>-1, 'position'=>110),
'tva' =>array('type'=>'double(24,8)', 'label'=>'TotalVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>115, 'isameasure'=>1),
- 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>120, 'isameasure'=>1),
- 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>125, 'isameasure'=>1),
+ 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'LocalTax1', 'enabled'=>1, 'visible'=>-1, 'position'=>120, 'isameasure'=>1),
+ 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'LocalTax2', 'enabled'=>1, 'visible'=>-1, 'position'=>125, 'isameasure'=>1),
'revenuestamp' =>array('type'=>'double(24,8)', 'label'=>'RevenueStamp', 'enabled'=>1, 'visible'=>-1, 'position'=>130, 'isameasure'=>1),
'total' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>135, 'isameasure'=>1),
'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>140, 'isameasure'=>1),
- 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Paid', 3=>'Abandonned')),
'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>150),
'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>155),
'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>160),
@@ -300,20 +305,21 @@ class Facture extends CommonInvoice
'retained_warranty' =>array('type'=>'double', 'label'=>'Retained warranty', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY', 'visible'=>-1, 'position'=>245),
'retained_warranty_date_limit' =>array('type'=>'date', 'label'=>'Retained warranty date limit', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY', 'visible'=>-1, 'position'=>250),
'retained_warranty_fk_cond_reglement' =>array('type'=>'integer', 'label'=>'Retained warranty fk cond reglement', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY', 'visible'=>-1, 'position'=>255),
- 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermsCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>260),
- 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermsLocation', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>265),
+ 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>260),
+ 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLabel', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>265),
'date_pointoftax' =>array('type'=>'date', 'label'=>'DatePointOfTax', 'enabled'=>'$conf->global->INVOICE_POINTOFTAX_DATE', 'visible'=>-1, 'position'=>270),
'fk_multicurrency' =>array('type'=>'integer', 'label'=>'MulticurrencyID', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>275),
- 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCode', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>280),
- 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>285),
- 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ht', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>290),
- 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total tva', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>295),
- 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ttc', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>300),
+ 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCurrency', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>280),
+ 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>285, 'isameasure'=>1),
+ 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountHT', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>290, 'isameasure'=>1),
+ 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountVAT', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>295, 'isameasure'=>1),
+ 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountTTC', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>300, 'isameasure'=>1),
'fk_fac_rec_source' =>array('type'=>'integer', 'label'=>'RecurringInvoiceSource', 'enabled'=>1, 'visible'=>-1, 'position'=>305),
- 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>310),
+ 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>-1, 'position'=>310),
'module_source' =>array('type'=>'varchar(32)', 'label'=>'POSModule', 'enabled'=>1, 'visible'=>-1, 'position'=>315),
'pos_source' =>array('type'=>'varchar(32)', 'label'=>'POSTerminal', 'enabled'=>1, 'visible'=>-1, 'position'=>320),
- 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>220),
+ 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Paid', 3=>'Abandonned')),
+ 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900),
);
// END MODULEBUILDER PROPERTIES
@@ -477,7 +483,7 @@ class Facture extends CommonInvoice
$this->fk_project = GETPOST('projectid', 'int') > 0 ? ((int) GETPOST('projectid', 'int')) : $_facrec->fk_project;
$this->note_public = GETPOST('note_public', 'none') ? GETPOST('note_public', 'none') : $_facrec->note_public;
$this->note_private = GETPOST('note_private', 'none') ? GETPOST('note_private', 'none') : $_facrec->note_private;
- $this->modelpdf = GETPOST('model', 'alpha') ? GETPOST('model', 'apha') : $_facrec->modelpdf;
+ $this->modelpdf = GETPOST('model', 'alpha') ? GETPOST('model', 'alpha') : $_facrec->modelpdf;
$this->cond_reglement_id = GETPOST('cond_reglement_id', 'int') > 0 ? ((int) GETPOST('cond_reglement_id', 'int')) : $_facrec->cond_reglement_id;
$this->mode_reglement_id = GETPOST('mode_reglement_id', 'int') > 0 ? ((int) GETPOST('mode_reglement_id', 'int')) : $_facrec->mode_reglement_id;
$this->fk_account = GETPOST('fk_account') > 0 ? ((int) GETPOST('fk_account')) : $_facrec->fk_account;
@@ -807,6 +813,14 @@ class Facture extends CommonInvoice
$vatrate = $line->tva_tx;
if ($line->vat_src_code && !preg_match('/\(.*\)/', $vatrate)) $vatrate .= ' ('.$line->vat_src_code.')';
+ if(!empty($conf->global->MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION)) {
+ $originid=$line->origin_id;
+ $origintype=$line->origin;
+ } else {
+ $originid=$line->id;
+ $origintype=$this->element;
+ }
+
$result = $this->addline(
$line->desc,
$line->subprice,
@@ -826,8 +840,8 @@ class Facture extends CommonInvoice
$line->product_type,
$line->rang,
$line->special_code,
- $this->element,
- $line->id,
+ $origintype,
+ $originid,
$fk_parent_line,
$line->fk_fournprice,
$line->pa_ht,
@@ -1253,6 +1267,14 @@ class Facture extends CommonInvoice
$line->date_start = $object->lines[$i]->date_start;
$line->date_end = $object->lines[$i]->date_end;
+ // Multicurrency
+ $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency;
+ $line->multicurrency_code = $object->lines[$i]->multicurrency_code;
+ $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice;
+ $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht;
+ $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva;
+ $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc;
+
$line->fk_fournprice = $object->lines[$i]->fk_fournprice;
$marginInfos = getMarginInfos($object->lines[$i]->subprice, $object->lines[$i]->remise_percent, $object->lines[$i]->tva_tx, $object->lines[$i]->localtax1_tx, $object->lines[$i]->localtax2_tx, $object->lines[$i]->fk_fournprice, $object->lines[$i]->pa_ht);
$line->pa_ht = $marginInfos[0];
@@ -1267,6 +1289,7 @@ class Facture extends CommonInvoice
$this->socid = $object->socid;
$this->fk_project = $object->fk_project;
+ $this->fk_account = $object->fk_account;
$this->cond_reglement_id = $object->cond_reglement_id;
$this->mode_reglement_id = $object->mode_reglement_id;
$this->availability_id = $object->availability_id;
@@ -1388,6 +1411,9 @@ class Facture extends CommonInvoice
if (!empty($this->total_ttc))
$label .= ''.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
if ($moretitle) $label .= ' - '.$moretitle;
+ if (isset($this->statut) && isset($this->alreadypaid)) {
+ $label .= ''.$langs->trans("Status").": ".$this->getLibStatut(5, $this->alreadypaid);
+ }
}
$linkclose = ($target ? ' target="'.$target.'"' : '');
@@ -1436,20 +1462,20 @@ class Facture extends CommonInvoice
}
/**
- * Get object and lines from database
+ * Get object from database. Get also lines.
*
- * @param int $rowid Id of object to load
- * @param string $ref Reference of invoice
- * @param string $ref_ext External reference of invoice
- * @param int $ref_int Internal reference of other object
+ * @param int $rowid Id of object to load
+ * @param string $ref Reference of invoice
+ * @param string $ref_ext External reference of invoice
+ * @param int $notused Not used
* @param bool $fetch_situation Fetch the previous and next situation in $tab_previous_situation_invoice and $tab_next_situation_invoice
- * @return int >0 if OK, <0 if KO, 0 if not found
+ * @return int >0 if OK, <0 if KO, 0 if not found
*/
- public function fetch($rowid, $ref = '', $ref_ext = '', $ref_int = '', $fetch_situation = false)
+ public function fetch($rowid, $ref = '', $ref_ext = '', $notused = '', $fetch_situation = false)
{
global $conf;
- if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1;
+ if (empty($rowid) && empty($ref) && empty($ref_ext)) return -1;
$sql = 'SELECT f.rowid,f.entity,f.ref,f.ref_client,f.ref_ext,f.ref_int,f.type,f.fk_soc';
$sql .= ', f.tva, f.localtax1, f.localtax2, f.total, f.total_ttc, f.revenuestamp';
@@ -1481,7 +1507,7 @@ class Facture extends CommonInvoice
$sql .= ' WHERE f.entity IN ('.getEntity('invoice').')'; // Dont't use entity if you use rowid
if ($ref) $sql .= " AND f.ref='".$this->db->escape($ref)."'";
if ($ref_ext) $sql .= " AND f.ref_ext='".$this->db->escape($ref_ext)."'";
- if ($ref_int) $sql .= " AND f.ref_int='".$this->db->escape($ref_int)."'";
+ if ($notused) $sql .= " AND f.ref_int='".$this->db->escape($notused)."'"; // deprecated
}
dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
@@ -1514,10 +1540,16 @@ class Facture extends CommonInvoice
$this->total_localtax2 = $obj->localtax2;
$this->total_ttc = $obj->total_ttc;
$this->revenuestamp = $obj->revenuestamp;
- $this->paye = $obj->paye;
+ $this->paye = $obj->paye;
$this->close_code = $obj->close_code;
$this->close_note = $obj->close_note;
- $this->socid = $obj->fk_soc;
+
+ $this->socid = $obj->fk_soc;
+ $this->thirdparty = null; // Clear if another value was already set by fetch_thirdparty
+
+ $this->fk_project = $obj->fk_project;
+ $this->project = null; // Clear if another value was already set by fetch_projet
+
$this->statut = $obj->fk_statut;
$this->date_lim_reglement = $this->db->jdate($obj->dlr);
$this->mode_reglement_id = $obj->fk_mode_reglement;
@@ -1528,7 +1560,6 @@ class Facture extends CommonInvoice
$this->cond_reglement = $obj->cond_reglement_libelle;
$this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
$this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account : null;
- $this->fk_project = $obj->fk_project;
$this->fk_facture_source = $obj->fk_facture_source;
$this->fk_fac_rec_source = $obj->fk_fac_rec_source;
$this->note = $obj->note_private; // deprecated
@@ -1574,10 +1605,7 @@ class Facture extends CommonInvoice
// fetch optionals attributes and labels
$this->fetch_optionals();
- /*
- * Lines
- */
-
+ // Lines
$this->lines = array();
$result = $this->fetch_lines();
@@ -2408,12 +2436,23 @@ class Facture extends CommonInvoice
* @param string $force_number Reference to force on invoice
* @param int $idwarehouse Id of warehouse to use for stock decrease if option to decreasenon stock is on (0=no decrease)
* @param int $notrigger 1=Does not execute triggers, 0= execute triggers
+ * @param int $batch_rule [=0] 0 not decrement batch, else batch rule to use
+ * 1=take in batches ordered by sellby and eatby dates
* @return int <0 if KO, 0=Nothing done because invoice is not a draft, >0 if OK
*/
- public function validate($user, $force_number = '', $idwarehouse = 0, $notrigger = 0)
+ public function validate($user, $force_number = '', $idwarehouse = 0, $notrigger = 0, $batch_rule = 0)
{
global $conf, $langs;
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+ $productStatic = null;
+ $warehouseStatic = null;
+ if ($batch_rule > 0) {
+ require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
+ require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
+ require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
+ $productStatic = new Product($this->db);
+ $warehouseStatic = new Entrepot($this->db);
+ }
$now = dol_now();
@@ -2505,7 +2544,7 @@ class Facture extends CommonInvoice
{
$num = $this->ref;
}
- $this->newref = $num;
+ $this->newref = dol_sanitizeFileName($num);
if ($num)
{
@@ -2555,11 +2594,94 @@ class Facture extends CommonInvoice
$mouvP = new MouvementStock($this->db);
$mouvP->origin = &$this;
// We decrease stock for product
- if ($this->type == self::TYPE_CREDIT_NOTE) $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceValidatedInDolibarr", $num));
- else $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr", $num));
- if ($result < 0) {
- $error++;
- $this->error = $mouvP->error;
+ if ($this->type == self::TYPE_CREDIT_NOTE) {
+ $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceValidatedInDolibarr", $num));
+ if ($result < 0) {
+ $error++;
+ $this->error = $mouvP->error;
+ }
+ } else {
+ $is_batch_line = false;
+ if ($batch_rule > 0) {
+ $productStatic->fetch($this->lines[$i]->fk_product);
+ if ($productStatic->hasbatch()) {
+ $is_batch_line = true;
+ $product_qty_remain = $this->lines[$i]->qty;
+
+ $sortfield = null;
+ $sortorder = null;
+ // find all batch order by sellby (DLC) and eatby dates (DLUO) first
+ if ($batch_rule == Productbatch::BATCH_RULE_SELLBY_EATBY_DATES_FIRST) {
+ $sortfield = 'pl.sellby,pl.eatby,pb.qty,pl.rowid';
+ $sortorder = 'ASC,ASC,ASC,ASC';
+ }
+
+ $resBatchList = Productbatch::findAllForProduct($this->db, $productStatic->id, $idwarehouse, (!empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER) ? null : 0), $sortfield, $sortorder);
+ if (!is_array($resBatchList)) {
+ $error++;
+ $this->error = $this->db->lasterror();
+ }
+
+ if (!$error) {
+ $batchList = $resBatchList;
+ if (empty($batchList)) {
+ $error++;
+ $langs->load('errors');
+ $warehouseStatic->fetch($idwarehouse);
+ $this->error = $langs->trans('ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref);
+ dol_syslog(__METHOD__.' Error: '.$langs->transnoentitiesnoconv('ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR);
+ }
+
+ foreach ($batchList as $batch) {
+ if ($batch->qty <= 0) continue; // try to decrement only batches have positive quantity first
+
+ // enough quantity in this batch
+ if ($batch->qty >= $product_qty_remain) {
+ $product_batch_qty = $product_qty_remain;
+ } // not enough (take all in batch)
+ else {
+ $product_batch_qty = $batch->qty;
+ }
+ $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_batch_qty, $this->lines[$i]->subprice, $langs->trans('InvoiceValidatedInDolibarr', $num), '', '', '', $batch->batch);
+ if ($result < 0) {
+ $error++;
+ $this->error = $mouvP->error;
+ break;
+ }
+
+ $product_qty_remain -= $product_batch_qty;
+ // all product quantity was decremented
+ if ($product_qty_remain <= 0) break;
+ }
+
+ if (!$error && $product_qty_remain > 0) {
+ if ($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER) {
+ // take in the first batch
+ $batch = $batchList[0];
+ $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_qty_remain, $this->lines[$i]->subprice, $langs->trans('InvoiceValidatedInDolibarr', $num), '', '', '', $batch->batch);
+ if ($result < 0) {
+ $error++;
+ $this->error = $mouvP->error;
+ }
+ } else {
+ $error++;
+ $langs->load('errors');
+ $warehouseStatic->fetch($idwarehouse);
+ $this->error = $langs->trans('ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref);
+ dol_syslog(__METHOD__.' Error: '.$langs->transnoentitiesnoconv('ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR);
+ }
+ }
+ }
+ }
+ }
+
+ if (!$is_batch_line) {
+ $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr", $num));
+ if ($result < 0) {
+ $error++;
+ $this->error = $mouvP->error;
+ }
+ }
}
}
}
@@ -2828,8 +2950,8 @@ class Facture extends CommonInvoice
* @param int $type Type of line (0=product, 1=service). Not used if fk_product is defined, the type of product is used.
* @param int $rang Position of line
* @param int $special_code Special code (also used by externals modules!)
- * @param string $origin 'order', ...
- * @param int $origin_id Id of origin object
+ * @param string $origin Depend on global conf MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION can be 'orderdet', 'propaldet'..., else 'order','propal,'....
+ * @param int $origin_id Depend on global conf MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION can be Id of origin object (aka line id), else object id
* @param int $fk_parent_line Id of parent line
* @param int $fk_fournprice Supplier price id (to calculate margin) or ''
* @param int $pa_ht Buying price of line (to calculate margin) or ''
@@ -3577,63 +3699,76 @@ class Facture extends CommonInvoice
public function getNextNumRef($soc, $mode = 'next')
{
global $conf, $langs;
- $langs->load("bills");
- // Clean parameters (if not defined or using deprecated value)
- if (empty($conf->global->FACTURE_ADDON)) $conf->global->FACTURE_ADDON = 'mod_facture_terre';
- elseif ($conf->global->FACTURE_ADDON == 'terre') $conf->global->FACTURE_ADDON = 'mod_facture_terre';
- elseif ($conf->global->FACTURE_ADDON == 'mercure') $conf->global->FACTURE_ADDON = 'mod_facture_mercure';
+ if ($this->module_source == 'takepos') {
+ $langs->load('cashdesk@cashdesk');
- if (!empty($conf->global->FACTURE_ADDON))
- {
- dol_syslog("Call getNextNumRef with FACTURE_ADDON = ".$conf->global->FACTURE_ADDON.", thirdparty=".$soc->nom.", type=".$soc->typent_code, LOG_DEBUG);
+ $moduleName = 'takepos';
+ $moduleSourceName = 'Takepos';
+ $addonConstName = 'TAKEPOS_REF_ADDON';
+
+ // Clean parameters (if not defined or using deprecated value)
+ if (empty($conf->global->TAKEPOS_REF_ADDON)) $conf->global->TAKEPOS_REF_ADDON = 'mod_takepos_ref_simple';
+
+ $addon = $conf->global->TAKEPOS_REF_ADDON;
+ } else {
+ $langs->load('bills');
+
+ $moduleName = 'facture';
+ $moduleSourceName = 'Invoice';
+ $addonConstName = 'FACTURE_ADDON';
+
+ // Clean parameters (if not defined or using deprecated value)
+ if (empty($conf->global->FACTURE_ADDON)) $conf->global->FACTURE_ADDON = 'mod_facture_terre';
+ elseif ($conf->global->FACTURE_ADDON == 'terre') $conf->global->FACTURE_ADDON = 'mod_facture_terre';
+ elseif ($conf->global->FACTURE_ADDON == 'mercure') $conf->global->FACTURE_ADDON = 'mod_facture_mercure';
+
+ $addon = $conf->global->FACTURE_ADDON;
+ }
+
+ if (!empty($addon)) {
+ dol_syslog("Call getNextNumRef with " . $addonConstName . " = " . $conf->global->FACTURE_ADDON . ", thirdparty=" . $soc->nom . ", type=" . $soc->typent_code, LOG_DEBUG);
$mybool = false;
- $file = $conf->global->FACTURE_ADDON.".php";
- $classname = $conf->global->FACTURE_ADDON;
+ $file = $addon . '.php';
+ $classname = $addon;
// Include file with class
$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
-
foreach ($dirmodels as $reldir) {
- $dir = dol_buildpath($reldir."core/modules/facture/");
+ $dir = dol_buildpath($reldir . 'core/modules/' . $moduleName . '/');
// Load file with numbering class (if found)
- if (is_file($dir.$file) && is_readable($dir.$file))
- {
- $mybool |= include_once $dir.$file;
- }
- }
-
- // For compatibility
- if (!$mybool)
- {
- $file = $conf->global->FACTURE_ADDON."/".$conf->global->FACTURE_ADDON.".modules.php";
- $classname = "mod_facture_".$conf->global->FACTURE_ADDON;
- $classname = preg_replace('/\-.*$/', '', $classname);
- // Include file with class
- foreach ($conf->file->dol_document_root as $dirroot)
- {
- $dir = $dirroot."/core/modules/facture/";
-
- // Load file with numbering class (if found)
- if (is_file($dir.$file) && is_readable($dir.$file)) {
- $mybool |= include_once $dir.$file;
- }
+ if (is_file($dir . $file) && is_readable($dir . $file)) {
+ $mybool |= include_once $dir . $file;
}
}
- if (!$mybool)
- {
- dol_print_error('', "Failed to include file ".$file);
+ // For compatibility
+ if (!$mybool) {
+ $file = $addon . '/' . $addon . '.modules.php';
+ $classname = 'mod_' . $moduleName . '_' . $addon;
+ $classname = preg_replace('/\-.*$/', '', $classname);
+ // Include file with class
+ foreach ($conf->file->dol_document_root as $dirroot) {
+ $dir = $dirroot . '/core/modules/' . $moduleName . '/';
+
+ // Load file with numbering class (if found)
+ if (is_file($dir . $file) && is_readable($dir . $file)) {
+ $mybool |= include_once $dir . $file;
+ }
+ }
+ }
+
+ if (!$mybool) {
+ dol_print_error('', 'Failed to include file ' . $file);
return '';
}
$obj = new $classname();
- $numref = "";
$numref = $obj->getNextValue($soc, $this, $mode);
/**
@@ -3642,17 +3777,14 @@ class Facture extends CommonInvoice
*/
if ($mode != 'last' && !$numref) {
$this->error = $obj->error;
- //dol_print_error($this->db,"Facture::getNextNumRef ".$obj->error);
- return "";
+ return '';
}
return $numref;
- }
- else
- {
- $langs->load("errors");
- print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("Invoice"));
- return "";
+ } else {
+ $langs->load('errors');
+ print $langs->trans('Error') . ' ' . $langs->trans('ErrorModuleSetupNotComplete', $langs->transnoentitiesnoconv($moduleSourceName));
+ return '';
}
}
@@ -4102,7 +4234,7 @@ class Facture extends CommonInvoice
if ($generic_facture->hasDelay()) {
$response->nbtodolate++;
- $response->url_late=DOL_URL_ROOT.'/compta/facture/list.php?search_option=late&mainmenu=billing&leftmenu=customers_bills';
+ $response->url_late = DOL_URL_ROOT.'/compta/facture/list.php?search_option=late&mainmenu=billing&leftmenu=customers_bills';
}
}
@@ -4578,15 +4710,40 @@ class Facture extends CommonInvoice
// Paid invoices have status STATUS_CLOSED
if ($this->statut != Facture::STATUS_VALIDATED) return false;
- return $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay);
+ $hasDelay = $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay);
+ if ($hasDelay && !empty($this->retained_warranty) && !empty($this->retained_warranty_date_limit))
+ {
+ $totalpaye = $this->getSommePaiement();
+ $totalpaye = floatval($totalpaye);
+ $RetainedWarrantyAmount = $this->getRetainedWarrantyAmount();
+ if ($totalpaye >= 0 && $RetainedWarrantyAmount >= 0)
+ {
+ if (($totalpaye < $this->total_ttc - $RetainedWarrantyAmount) && $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay))
+ {
+ $hasDelay = 1;
+ }
+ elseif ($totalpaye < $this->total_ttc && $this->retained_warranty_date_limit < ($now - $conf->facture->client->warning_delay))
+ {
+ $hasDelay = 1;
+ }
+ else
+ {
+ $hasDelay = 0;
+ }
+ }
+ }
+
+ return $hasDelay;
}
/**
+ * @param int $rounding Minimum number of decimal to show. If 0, no change, if -1, we use min($conf->global->MAIN_MAX_DECIMALS_UNIT,$conf->global->MAIN_MAX_DECIMALS_TOT)
* @return number or -1 if not available
*/
- public function getRetainedWarrantyAmount()
+ public function getRetainedWarrantyAmount($rounding = -1)
{
+ global $conf;
if (empty($this->retained_warranty)) {
return -1;
}
@@ -4630,6 +4787,11 @@ class Facture extends CommonInvoice
$retainedWarrantyAmount = $this->total_ttc * $this->retained_warranty / 100;
}
+ if ($rounding < 0) {
+ $rounding = min($conf->global->MAIN_MAX_DECIMALS_UNIT, $conf->global->MAIN_MAX_DECIMALS_TOT);
+ return round($retainedWarrantyAmount, 2);
+ }
+
return $retainedWarrantyAmount;
}
diff --git a/htdocs/compta/facture/class/facturestats.class.php b/htdocs/compta/facture/class/facturestats.class.php
index f24f31bbc9a..ea0b17bc59a 100644
--- a/htdocs/compta/facture/class/facturestats.class.php
+++ b/htdocs/compta/facture/class/facturestats.class.php
@@ -22,10 +22,10 @@
* \ingroup factures
* \brief Fichier de la classe de gestion des stats des factures
*/
-include_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php';
-include_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
-include_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.facture.class.php';
-include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
+include_once DOL_DOCUMENT_ROOT.'/core/class/stats.class.php';
+include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
+include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
+include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
/**
* Class to manage stats for invoices (customer and supplier)
@@ -64,32 +64,32 @@ class FactureStats extends Stats
if ($mode == 'customer')
{
- $object=new Facture($this->db);
+ $object = new Facture($this->db);
$this->from = MAIN_DB_PREFIX.$object->table_element." as f";
$this->from_line = MAIN_DB_PREFIX.$object->table_element_line." as tl";
- $this->field='total';
- $this->field_line='total_ht';
+ $this->field = 'total';
+ $this->field_line = 'total_ht';
}
if ($mode == 'supplier')
{
- $object=new FactureFournisseur($this->db);
+ $object = new FactureFournisseur($this->db);
$this->from = MAIN_DB_PREFIX.$object->table_element." as f";
$this->from_line = MAIN_DB_PREFIX.$object->table_element_line." as tl";
- $this->field='total_ht';
- $this->field_line='total_ht';
+ $this->field = 'total_ht';
+ $this->field_line = 'total_ht';
}
$this->where = " f.fk_statut >= 0";
- $this->where.= " AND f.entity IN (".getEntity('invoice').")";
- if (!$user->rights->societe->client->voir && !$this->socid) $this->where .= " AND f.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id;
- if ($mode == 'customer') $this->where.=" AND (f.fk_statut <> 3 OR f.close_code <> 'replaced')"; // Exclude replaced invoices as they are duplicated (we count closed invoices for other reasons)
+ $this->where .= " AND f.entity IN (".getEntity('invoice').")";
+ if (!$user->rights->societe->client->voir && !$this->socid) $this->where .= " AND f.fk_soc = sc.fk_soc AND sc.fk_user = ".$user->id;
+ if ($mode == 'customer') $this->where .= " AND (f.fk_statut <> 3 OR f.close_code <> 'replaced')"; // Exclude replaced invoices as they are duplicated (we count closed invoices for other reasons)
if ($this->socid)
{
- $this->where.=" AND f.fk_soc = ".$this->socid;
+ $this->where .= " AND f.fk_soc = ".$this->socid;
}
- if ($this->userid > 0) $this->where.=' AND f.fk_user_author = '.$this->userid;
- if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $this->where.= " AND f.type IN (0,1,2,5)";
- else $this->where.= " AND f.type IN (0,1,2,3,5)";
+ if ($this->userid > 0) $this->where .= ' AND f.fk_user_author = '.$this->userid;
+ if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $this->where .= " AND f.type IN (0,1,2,5)";
+ else $this->where .= " AND f.type IN (0,1,2,3,5)";
}
@@ -105,14 +105,14 @@ class FactureStats extends Stats
global $user;
$sql = "SELECT date_format(f.datef,'%m') as dm, COUNT(*) as nb";
- $sql.= " FROM ".$this->from;
+ $sql .= " FROM ".$this->from;
if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE f.datef BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'";
- $sql.= " AND ".$this->where;
- $sql.= " GROUP BY dm";
- $sql.= $this->db->order('dm', 'DESC');
+ $sql .= " WHERE f.datef BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'";
+ $sql .= " AND ".$this->where;
+ $sql .= " GROUP BY dm";
+ $sql .= $this->db->order('dm', 'DESC');
- $res=$this->_getNbByMonth($year, $sql, $format);
+ $res = $this->_getNbByMonth($year, $sql, $format);
//var_dump($res);print ' ';
return $res;
}
@@ -128,11 +128,11 @@ class FactureStats extends Stats
global $user;
$sql = "SELECT date_format(f.datef,'%Y') as dm, COUNT(*), SUM(c.".$this->field.")";
- $sql.= " FROM ".$this->from;
+ $sql .= " FROM ".$this->from;
if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE ".$this->where;
- $sql.= " GROUP BY dm";
- $sql.= $this->db->order('dm', 'DESC');
+ $sql .= " WHERE ".$this->where;
+ $sql .= " GROUP BY dm";
+ $sql .= $this->db->order('dm', 'DESC');
return $this->_getNbByYear($sql);
}
@@ -150,14 +150,14 @@ class FactureStats extends Stats
global $user;
$sql = "SELECT date_format(datef,'%m') as dm, SUM(f.".$this->field.")";
- $sql.= " FROM ".$this->from;
- if (!$user->rights->societe->client->voir && !$this->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE f.datef BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'";
- $sql.= " AND ".$this->where;
- $sql.= " GROUP BY dm";
- $sql.= $this->db->order('dm', 'DESC');
+ $sql .= " FROM ".$this->from;
+ if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql .= " WHERE f.datef BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'";
+ $sql .= " AND ".$this->where;
+ $sql .= " GROUP BY dm";
+ $sql .= $this->db->order('dm', 'DESC');
- $res=$this->_getAmountByMonth($year, $sql, $format);
+ $res = $this->_getAmountByMonth($year, $sql, $format);
//var_dump($res);print ' ';
return $res;
}
@@ -173,12 +173,12 @@ class FactureStats extends Stats
global $user;
$sql = "SELECT date_format(datef,'%m') as dm, AVG(f.".$this->field.")";
- $sql.= " FROM ".$this->from;
- if (!$user->rights->societe->client->voir && !$this->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE f.datef BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'";
- $sql.= " AND ".$this->where;
- $sql.= " GROUP BY dm";
- $sql.= $this->db->order('dm', 'DESC');
+ $sql .= " FROM ".$this->from;
+ if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql .= " WHERE f.datef BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'";
+ $sql .= " AND ".$this->where;
+ $sql .= " GROUP BY dm";
+ $sql .= $this->db->order('dm', 'DESC');
return $this->_getAverageByMonth($year, $sql);
}
@@ -193,11 +193,11 @@ class FactureStats extends Stats
global $user;
$sql = "SELECT date_format(datef,'%Y') as year, COUNT(*) as nb, SUM(f.".$this->field.") as total, AVG(f.".$this->field.") as avg";
- $sql.= " FROM ".$this->from;
- if (!$user->rights->societe->client->voir && !$this->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE ".$this->where;
- $sql.= " GROUP BY year";
- $sql.= $this->db->order('year', 'DESC');
+ $sql .= " FROM ".$this->from;
+ if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql .= " WHERE ".$this->where;
+ $sql .= " GROUP BY year";
+ $sql .= $this->db->order('year', 'DESC');
return $this->_getAllByYear($sql);
}
@@ -205,23 +205,24 @@ class FactureStats extends Stats
/**
* Return nb, amount of predefined product for year
*
- * @param int $year Year to scan
- * @return array Array of values
+ * @param int $year Year to scan
+ * @param int $limit Limit
+ * @return array Array of values
*/
- public function getAllByProduct($year)
+ public function getAllByProduct($year, $limit = 10)
{
global $user;
$sql = "SELECT product.ref, COUNT(product.ref) as nb, SUM(tl.".$this->field_line.") as total, AVG(tl.".$this->field_line.") as avg";
- $sql.= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product";
- if (!$user->rights->societe->client->voir && !$this->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE ".$this->where;
- $sql.= " AND f.rowid = tl.fk_facture AND tl.fk_product = product.rowid";
- $sql.= " AND f.datef BETWEEN '".$this->db->idate(dol_get_first_day($year, 1, false))."' AND '".$this->db->idate(dol_get_last_day($year, 12, false))."'";
- $sql.= " GROUP BY product.ref";
- $sql.= $this->db->order('nb', 'DESC');
+ $sql .= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product";
+ if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql .= " WHERE ".$this->where;
+ $sql .= " AND f.rowid = tl.fk_facture AND tl.fk_product = product.rowid";
+ $sql .= " AND f.datef BETWEEN '".$this->db->idate(dol_get_first_day($year, 1, false))."' AND '".$this->db->idate(dol_get_last_day($year, 12, false))."'";
+ $sql .= " GROUP BY product.ref";
+ $sql .= $this->db->order('nb', 'DESC');
//$sql.= $this->db->plimit(20);
- return $this->_getAllByProduct($sql);
+ return $this->_getAllByProduct($sql, $limit);
}
}
diff --git a/htdocs/compta/facture/document.php b/htdocs/compta/facture/document.php
index e880d77db74..cccae974893 100644
--- a/htdocs/compta/facture/document.php
+++ b/htdocs/compta/facture/document.php
@@ -58,7 +58,7 @@ $result=restrictedArea($user, 'facture', $id, '');
// Get parameters
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/facture/invoicetemplate_list.php b/htdocs/compta/facture/invoicetemplate_list.php
index 370bfe9a8b9..c04e9072339 100644
--- a/htdocs/compta/facture/invoicetemplate_list.php
+++ b/htdocs/compta/facture/invoicetemplate_list.php
@@ -33,10 +33,7 @@ require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
-if (!empty($conf->projet->enabled)) {
- require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
- //require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
-}
+require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php';
@@ -54,6 +51,8 @@ $cancel = GETPOST('cancel', 'alpha');
$toselect = GETPOST('toselect', 'array');
$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'invoicetemplatelist'; // To manage different context of search
+$socid = GETPOST('socid', 'int');
+
// Security check
$id = (GETPOST('facid', 'int') ?GETPOST('facid', 'int') : GETPOST('id', 'int'));
$lineid = GETPOST('lineid', 'int');
@@ -62,7 +61,6 @@ if ($user->socid) $socid = $user->socid;
$objecttype = 'facture_rec';
if ($action == "create" || $action == "add") $objecttype = '';
$result = restrictedArea($user, 'facture', $id, $objecttype);
-$projectid = GETPOST('projectid', 'int');
$search_ref = GETPOST('search_ref');
$search_societe = GETPOST('search_societe');
@@ -85,7 +83,7 @@ $search_status = GETPOST('search_status', 'int');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
if (!$sortorder) $sortorder = 'DESC';
@@ -146,6 +144,13 @@ if (is_array($extrafields->attributes[$object->table_element]['label']) && count
$object->fields = dol_sort_array($object->fields, 'position');
$arrayfields = dol_sort_array($arrayfields, 'position');
+if ($socid > 0) {
+ $tmpthirdparty = new Societe($db);
+ $res = $tmpthirdparty->fetch($socid);
+ if ($res > 0) $search_societe = $tmpthirdparty->name;
+}
+
+
/*
* Actions
@@ -218,6 +223,7 @@ $today = dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['
/*
* List mode
*/
+
$sql = "SELECT s.nom as name, s.rowid as socid, f.rowid as facid, f.titre as title, f.total, f.tva as total_vat, f.total_ttc, f.frequency, f.unit_frequency,";
$sql .= " f.nb_gen_done, f.nb_gen_max, f.date_last_gen, f.date_when, f.suspended,";
$sql .= " f.datec, f.tms,";
@@ -243,6 +249,7 @@ if (!$user->rights->societe->client->voir && !$socid) {
$sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
}
if ($search_ref) $sql .= natural_search('f.titre', $search_ref);
+if ($socid) $sql .= ' AND s.rowid = '.(int) $socid;
if ($search_societe) $sql .= natural_search('s.nom', $search_societe);
if ($search_montant_ht != '') $sql .= natural_search('f.total', $search_montant_ht, 1);
if ($search_montant_vat != '') $sql .= natural_search('f.tva', $search_montant_vat, 1);
@@ -286,7 +293,7 @@ if ($resql)
$param = '';
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage);
if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit);
- if ($socid) $param .= '&socid='.urlencode($socid);
+ if ($socid > 0) $param .= '&socid='.urlencode($socid);
if ($search_day) $param .= '&search_day='.urlencode($search_day);
if ($search_month) $param .= '&search_month='.urlencode($search_month);
if ($search_year) $param .= '&search_year='.urlencode($search_year);
@@ -299,12 +306,11 @@ if ($resql)
if ($search_montant_vat != '') $param .= '&search_montant_vat='.urlencode($search_montant_vat);
if ($search_montant_ttc != '') $param .= '&search_montant_ttc='.urlencode($search_montant_ttc);
if ($search_payment_mode != '') $param .= '&search_payment_mode='.urlencode($search_payment_mode);
- if ($search_payment_type != '') $param .= '&search_payment_type='.urlencode($search_payment_type);
+ if ($search_payment_term != '') $param .= '&search_payment_term='.urlencode($search_payment_term);
if ($search_recurring != '' && $search_recurrning != '-1') $param .= '&search_recurring='.urlencode($search_recurring);
if ($search_frequency > 0) $param .= '&search_frequency='.urlencode($search_frequency);
if ($search_unit_frequency != '') $param .= '&search_unit_frequency='.urlencode($search_unit_frequency);
if ($search_status != '') $param .= '&search_status='.urlencode($search_status);
- if ($option) $param .= "&option=".urlencode($option);
if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss);
// Add $param from extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
@@ -326,12 +332,16 @@ if ($resql)
print ' ';
print ' ';
- print_barre_liste($langs->trans("RepeatableInvoices"), $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'invoicing', 0, '', '', $limit);
+ $title = $langs->trans("RepeatableInvoices");
+
+ print_barre_liste($title, $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'invoicing', 0, '', '', $limit);
print ''.$langs->trans("ToCreateAPredefinedInvoice", $langs->transnoentitiesnoconv("ChangeIntoRepeatableInvoice")).' ';
$i = 0;
+ $moreforfilter = '';
+
print '';
print '
'."\n";
@@ -467,7 +477,6 @@ if ($resql)
print '';
print "\n";
-
print '';
if (!empty($arrayfields['f.titre']['checked'])) print_liste_field_titre($arrayfields['f.titre']['label'], $_SERVER['PHP_SELF'], "f.titre", "", $param, "", $sortfield, $sortorder);
if (!empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER['PHP_SELF'], "s.nom", "", $param, "", $sortfield, $sortorder);
@@ -527,21 +536,21 @@ if ($resql)
}
if (!empty($arrayfields['f.total']['checked']))
{
- print ''.price($objp->total).' '."\n";
+ print ''.price($objp->total).' '."\n";
if (!$i) $totalarray['nbfield']++;
if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'f.total';
$totalarray['val']['f.total'] += $objp->total;
}
if (!empty($arrayfields['f.tva']['checked']))
{
- print ''.price($objp->total_vat).' '."\n";
+ print ''.price($objp->total_vat).' '."\n";
if (!$i) $totalarray['nbfield']++;
if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'f.tva';
$totalarray['val']['f.tva'] += $objp->total_vat;
}
if (!empty($arrayfields['f.total_ttc']['checked']))
{
- print ''.price($objp->total_ttc).' '."\n";
+ print ''.price($objp->total_ttc).' '."\n";
if (!$i) $totalarray['nbfield']++;
if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'f.total_ttc';
$totalarray['val']['f.total_ttc'] += $objp->total_ttc;
diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php
index 32cd30ea207..cecbacdc209 100644
--- a/htdocs/compta/facture/list.php
+++ b/htdocs/compta/facture/list.php
@@ -87,6 +87,11 @@ $search_montant_vat = GETPOST('search_montant_vat', 'alpha');
$search_montant_localtax1 = GETPOST('search_montant_localtax1', 'alpha');
$search_montant_localtax2 = GETPOST('search_montant_localtax2', 'alpha');
$search_montant_ttc = GETPOST('search_montant_ttc', 'alpha');
+$search_multicurrency_code = GETPOST('search_multicurrency_code', 'alpha');
+$search_multicurrency_tx = GETPOST('search_multicurrency_tx', 'alpha');
+$search_multicurrency_montant_ht = GETPOST('search_multicurrency_montant_ht', 'alpha');
+$search_multicurrency_montant_vat = GETPOST('search_multicurrency_montant_vat', 'alpha');
+$search_multicurrency_montant_ttc = GETPOST('search_multicurrency_montant_ttc', 'alpha');
$search_status = GETPOST('search_status', 'intcomma');
$search_paymentmode = GETPOST('search_paymentmode', 'int');
$search_paymentterms = GETPOST('search_paymentterms', 'int');
@@ -116,7 +121,7 @@ $filtre = GETPOST('filtre', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn) || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
if (!$sortorder && !empty($conf->global->INVOICE_DEFAULT_UNPAYED_SORT_ORDER) && $search_status == '1') $sortorder = $conf->global->INVOICE_DEFAULT_UNPAYED_SORT_ORDER;
@@ -183,6 +188,13 @@ $arrayfields = array(
'f.total_ttc'=>array('label'=>"AmountTTC", 'checked'=>0, 'position'=>130),
'dynamount_payed'=>array('label'=>"Received", 'checked'=>0, 'position'=>140),
'rtp'=>array('label'=>"Rest", 'checked'=>0, 'position'=>150), // Not enabled by default because slow
+ 'f.multicurrency_code'=>array('label'=>'Currency', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>160),
+ 'f.multicurrency_tx'=>array('label'=>'CurrencyRate', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>170),
+ 'f.multicurrency_total_ht'=>array('label'=>'MulticurrencyAmountHT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>180),
+ 'f.multicurrency_total_vat'=>array('label'=>'MulticurrencyAmountVAT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>190),
+ 'f.multicurrency_total_ttc'=>array('label'=>'MulticurrencyAmountTTC', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>200),
+ 'multicurrency_dynamount_payed'=>array('label'=>'MulticurrencyAlreadyPaid', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>210),
+ 'multicurrency_rtp'=>array('label'=>'MulticurrencyRemainderToPay', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>220), // Not enabled by default because slow
'f.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500),
'f.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500),
'f.fk_statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000),
@@ -236,6 +248,11 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter',
$search_montant_localtax1 = '';
$search_montant_localtax2 = '';
$search_montant_ttc = '';
+ $search_multicurrency_code = '';
+ $search_multicurrency_tx = '';
+ $search_multicurrency_montant_ht = '';
+ $search_multicurrency_montant_vat = '';
+ $search_multicurrency_montant_ttc = '';
$search_status = '';
$search_paymentmode = '';
$search_paymentterms = '';
@@ -383,6 +400,7 @@ $sql = 'SELECT';
if ($sall || $search_product_category > 0) $sql = 'SELECT DISTINCT';
$sql .= ' f.rowid as id, f.ref, f.ref_client, f.type, f.note_private, f.note_public, f.increment, f.fk_mode_reglement, f.fk_cond_reglement, f.total as total_ht, f.tva as total_vat, f.total_ttc,';
$sql .= ' f.localtax1 as total_localtax1, f.localtax2 as total_localtax2,';
+$sql .= ' f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva as multicurrency_total_vat, f.multicurrency_total_ttc,';
$sql .= ' f.datef as df, f.date_lim_reglement as datelimite, f.module_source, f.pos_source,';
$sql .= ' f.paye as paye, f.fk_statut, f.close_code,';
$sql .= ' f.datec as date_creation, f.tms as date_update, f.date_closing as date_closing,';
@@ -394,7 +412,7 @@ $sql .= " country.code as country_code,";
$sql .= " p.rowid as project_id, p.ref as project_ref, p.title as project_label";
// We need dynamount_payed to be able to sort on status (value is surely wrong because we can count several lines several times due to other left join or link with contacts. But what we need is just 0 or > 0)
// TODO Better solution to be able to sort on already payed or remain to pay is to store amount_payed in a denormalized field.
-if (!$sall) $sql .= ', SUM(pf.amount) as dynamount_payed';
+if (!$sall) $sql .= ', SUM(pf.amount) as dynamount_payed, SUM(pf.multicurrency_amount) as multicurrency_dynamount_payed';
if ($search_categ_cus) $sql .= ", cc.fk_categorie, cc.fk_soc";
// Add fields from extrafields
if (!empty($extrafields->attributes[$object->table_element]['label'])) {
@@ -459,6 +477,11 @@ if ($search_montant_vat != '') $sql .= natural_search('f.tva', $search_montant_v
if ($search_montant_localtax1 != '') $sql .= natural_search('f.localtax1', $search_montant_localtax1, 1);
if ($search_montant_localtax2 != '') $sql .= natural_search('f.localtax2', $search_montant_localtax2, 1);
if ($search_montant_ttc != '') $sql .= natural_search('f.total_ttc', $search_montant_ttc, 1);
+if ($search_multicurrency_code != '') $sql .= ' AND f.multicurrency_code = "'.$db->escape($search_multicurrency_code).'"';
+if ($search_multicurrency_tx != '') $sql .= natural_search('f.multicurrency_tx', $search_multicurrency_tx, 1);
+if ($search_multicurrency_montant_ht != '') $sql .= natural_search('f.multicurrency_total_ht', $search_multicurrency_montant_ht, 1);
+if ($search_multicurrency_montant_vat != '') $sql .= natural_search('f.multicurrency_total_tva', $search_multicurrency_montant_vat, 1);
+if ($search_multicurrency_montant_ttc != '') $sql .= natural_search('f.multicurrency_total_ttc', $search_multicurrency_montant_ttc, 1);
if ($search_categ_cus > 0) $sql .= " AND cc.fk_categorie = ".$db->escape($search_categ_cus);
if ($search_categ_cus == -2) $sql .= " AND cc.fk_categorie IS NULL";
if ($search_status != '-1' && $search_status != '')
@@ -591,6 +614,11 @@ if ($resql)
if ($search_montant_localtax1 != '') $param .= '&search_montant_localtax1='.urlencode($search_montant_localtax1);
if ($search_montant_localtax2 != '') $param .= '&search_montant_localtax2='.urlencode($search_montant_localtax2);
if ($search_montant_ttc != '') $param .= '&search_montant_ttc='.urlencode($search_montant_ttc);
+ if ($search_multicurrency_code != '') $param .= '&search_multicurrency_code='.urlencode($search_multicurrency_code);
+ if ($search_multicurrency_tx != '') $param .= '&search_multicurrency_tx='.urlencode($search_multicurrency_tx);
+ if ($search_multicurrency_montant_ht != '') $param .= '&search_multicurrency_montant_ht='.urlencode($search_multicurrency_montant_ht);
+ if ($search_multicurrency_montant_vat != '') $param .= '&search_multicurrency_montant_vat='.urlencode($search_multicurrency_montant_vat);
+ if ($search_multicurrency_montant_ttc != '') $param .= '&search_multicurrency_montant_ttc='.urlencode($search_multicurrency_montant_ttc);
if ($search_status != '') $param .= '&search_status='.urlencode($search_status);
if ($search_paymentmode > 0) $param .= '&search_paymentmode='.urlencode($search_paymentmode);
if ($search_paymentterms > 0) $param .= '&search_paymentterms='.urlencode($search_paymentterms);
@@ -878,13 +906,11 @@ if ($resql)
print ' ';
print '';
}
-
if (!empty($arrayfields['f.retained_warranty']['checked']))
{
print '';
print ' ';
}
-
if (!empty($arrayfields['dynamount_payed']['checked']))
{
print '';
@@ -895,6 +921,51 @@ if ($resql)
print ' ';
print ' ';
}
+ if (!empty($arrayfields['f.multicurrency_code']['checked']))
+ {
+ // Currency
+ print '';
+ print $form->selectMultiCurrency($search_multicurrency_code, 'search_multicurrency_code', 1);
+ print ' ';
+ }
+ if (!empty($arrayfields['f.multicurrency_tx']['checked']))
+ {
+ // Currency rate
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['f.multicurrency_total_ht']['checked']))
+ {
+ // Amount
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['f.multicurrency_total_vat']['checked']))
+ {
+ // Amount
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['f.multicurrency_total_ttc']['checked']))
+ {
+ // Amount
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['multicurrency_dynamount_payed']['checked']))
+ {
+ print '';
+ print ' ';
+ }
+ if (!empty($arrayfields['multicurrency_rtp']['checked']))
+ {
+ print '';
+ print ' ';
+ }
if (!empty($arrayfields['f.date_closing']['checked']))
{
print '';
@@ -936,31 +1007,38 @@ if ($resql)
print " \n";
print '';
- if (!empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($arrayfields['f.ref']['label'], $_SERVER['PHP_SELF'], 'f.ref', '', $param, '', $sortfield, $sortorder);
- if (!empty($arrayfields['f.ref_client']['checked'])) print_liste_field_titre($arrayfields['f.ref_client']['label'], $_SERVER["PHP_SELF"], 'f.ref_client', '', $param, '', $sortfield, $sortorder);
- if (!empty($arrayfields['f.type']['checked'])) print_liste_field_titre($arrayfields['f.type']['label'], $_SERVER["PHP_SELF"], 'f.type', '', $param, '', $sortfield, $sortorder);
- if (!empty($arrayfields['f.date']['checked'])) print_liste_field_titre($arrayfields['f.date']['label'], $_SERVER['PHP_SELF'], 'f.datef', '', $param, 'align="center"', $sortfield, $sortorder);
- if (!empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'], $_SERVER['PHP_SELF'], "f.date_lim_reglement", '', $param, 'align="center"', $sortfield, $sortorder);
- if (!empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER['PHP_SELF'], "p.ref", '', $param, '', $sortfield, $sortorder);
- if (!empty($arrayfields['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'], $_SERVER['PHP_SELF'], "p.title", '', $param, '', $sortfield, $sortorder);
- if (!empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER['PHP_SELF'], 's.nom', '', $param, '', $sortfield, $sortorder);
- if (!empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'], $_SERVER["PHP_SELF"], 's.town', '', $param, '', $sortfield, $sortorder);
- if (!empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'], $_SERVER["PHP_SELF"], 's.zip', '', $param, '', $sortfield, $sortorder);
- if (!empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'], $_SERVER["PHP_SELF"], "state.nom", "", $param, '', $sortfield, $sortorder);
- if (!empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'], $_SERVER["PHP_SELF"], "country.code_iso", "", $param, 'align="center"', $sortfield, $sortorder);
- if (!empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'], $_SERVER["PHP_SELF"], "typent.code", "", $param, 'align="center"', $sortfield, $sortorder);
- if (!empty($arrayfields['f.fk_mode_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_mode_reglement']['label'], $_SERVER["PHP_SELF"], "f.fk_mode_reglement", "", $param, "", $sortfield, $sortorder);
- if (!empty($arrayfields['f.fk_cond_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_cond_reglement']['label'], $_SERVER["PHP_SELF"], "f.fk_cond_reglement", "", $param, "", $sortfield, $sortorder);
- if (!empty($arrayfields['f.module_source']['checked'])) print_liste_field_titre($arrayfields['f.module_source']['label'], $_SERVER["PHP_SELF"], "f.module_source", "", $param, "", $sortfield, $sortorder);
- if (!empty($arrayfields['f.pos_source']['checked'])) print_liste_field_titre($arrayfields['f.pos_source']['label'], $_SERVER["PHP_SELF"], "f.pos_source", "", $param, "", $sortfield, $sortorder);
- if (!empty($arrayfields['f.total_ht']['checked'])) print_liste_field_titre($arrayfields['f.total_ht']['label'], $_SERVER['PHP_SELF'], 'f.total', '', $param, 'class="right"', $sortfield, $sortorder);
- if (!empty($arrayfields['f.total_vat']['checked'])) print_liste_field_titre($arrayfields['f.total_vat']['label'], $_SERVER['PHP_SELF'], 'f.tva', '', $param, 'class="right"', $sortfield, $sortorder);
- if (!empty($arrayfields['f.total_localtax1']['checked'])) print_liste_field_titre($arrayfields['f.total_localtax1']['label'], $_SERVER['PHP_SELF'], 'f.localtax1', '', $param, 'class="right"', $sortfield, $sortorder);
- if (!empty($arrayfields['f.total_localtax2']['checked'])) print_liste_field_titre($arrayfields['f.total_localtax2']['label'], $_SERVER['PHP_SELF'], 'f.localtax2', '', $param, 'class="right"', $sortfield, $sortorder);
- if (!empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'], $_SERVER['PHP_SELF'], 'f.total_ttc', '', $param, 'class="right"', $sortfield, $sortorder);
- if (!empty($arrayfields['f.retained_warranty']['checked'])) print_liste_field_titre($arrayfields['f.retained_warranty']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'align="right"', $sortfield, $sortorder);
- if (!empty($arrayfields['dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['dynamount_payed']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder);
- if (!empty($arrayfields['rtp']['checked'])) print_liste_field_titre($arrayfields['rtp']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($arrayfields['f.ref']['label'], $_SERVER['PHP_SELF'], 'f.ref', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.ref_client']['checked'])) print_liste_field_titre($arrayfields['f.ref_client']['label'], $_SERVER["PHP_SELF"], 'f.ref_client', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.type']['checked'])) print_liste_field_titre($arrayfields['f.type']['label'], $_SERVER["PHP_SELF"], 'f.type', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.date']['checked'])) print_liste_field_titre($arrayfields['f.date']['label'], $_SERVER['PHP_SELF'], 'f.datef', '', $param, 'align="center"', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'], $_SERVER['PHP_SELF'], "f.date_lim_reglement", '', $param, 'align="center"', $sortfield, $sortorder);
+ if (!empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER['PHP_SELF'], "p.ref", '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'], $_SERVER['PHP_SELF'], "p.title", '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER['PHP_SELF'], 's.nom', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'], $_SERVER["PHP_SELF"], 's.town', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'], $_SERVER["PHP_SELF"], 's.zip', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'], $_SERVER["PHP_SELF"], "state.nom", "", $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'], $_SERVER["PHP_SELF"], "country.code_iso", "", $param, 'align="center"', $sortfield, $sortorder);
+ if (!empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'], $_SERVER["PHP_SELF"], "typent.code", "", $param, 'align="center"', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.fk_mode_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_mode_reglement']['label'], $_SERVER["PHP_SELF"], "f.fk_mode_reglement", "", $param, "", $sortfield, $sortorder);
+ if (!empty($arrayfields['f.fk_cond_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_cond_reglement']['label'], $_SERVER["PHP_SELF"], "f.fk_cond_reglement", "", $param, "", $sortfield, $sortorder);
+ if (!empty($arrayfields['f.module_source']['checked'])) print_liste_field_titre($arrayfields['f.module_source']['label'], $_SERVER["PHP_SELF"], "f.module_source", "", $param, "", $sortfield, $sortorder);
+ if (!empty($arrayfields['f.pos_source']['checked'])) print_liste_field_titre($arrayfields['f.pos_source']['label'], $_SERVER["PHP_SELF"], "f.pos_source", "", $param, "", $sortfield, $sortorder);
+ if (!empty($arrayfields['f.total_ht']['checked'])) print_liste_field_titre($arrayfields['f.total_ht']['label'], $_SERVER['PHP_SELF'], 'f.total', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.total_vat']['checked'])) print_liste_field_titre($arrayfields['f.total_vat']['label'], $_SERVER['PHP_SELF'], 'f.tva', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.total_localtax1']['checked'])) print_liste_field_titre($arrayfields['f.total_localtax1']['label'], $_SERVER['PHP_SELF'], 'f.localtax1', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.total_localtax2']['checked'])) print_liste_field_titre($arrayfields['f.total_localtax2']['label'], $_SERVER['PHP_SELF'], 'f.localtax2', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'], $_SERVER['PHP_SELF'], 'f.total_ttc', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.retained_warranty']['checked'])) print_liste_field_titre($arrayfields['f.retained_warranty']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'align="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['dynamount_payed']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['rtp']['checked'])) print_liste_field_titre($arrayfields['rtp']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.multicurrency_code']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_code']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_code', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.multicurrency_tx']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_tx']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_tx', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.multicurrency_total_ht']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_total_ht']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_total_ht', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.multicurrency_total_vat']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_total_vat']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_total_tva', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.multicurrency_total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_total_ttc']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_total_ttc', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['multicurrency_dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['multicurrency_dynamount_payed']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['multicurrency_rtp']['checked'])) print_liste_field_titre($arrayfields['multicurrency_rtp']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder);
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
// Hook fields
@@ -989,10 +1067,16 @@ if ($resql)
$facturestatic->id = $obj->id;
$facturestatic->ref = $obj->ref;
+ $facturestatic->ref_client = $obj->ref_client;
$facturestatic->type = $obj->type;
$facturestatic->total_ht = $obj->total_ht;
$facturestatic->total_tva = $obj->total_vat;
$facturestatic->total_ttc = $obj->total_ttc;
+ $facturestatic->multicurrency_code = $obj->multicurrency_code;
+ $facturestatic->multicurrency_tx = $obj->multicurrency_tx;
+ $facturestatic->multicurrency_total_ht = $obj->multicurrency_total_ht;
+ $facturestatic->multicurrency_total_tva = $obj->multicurrency_total_vat;
+ $facturestatic->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
$facturestatic->statut = $obj->fk_statut;
$facturestatic->close_code = $obj->close_code;
$facturestatic->total_ttc = $obj->total_ttc;
@@ -1030,16 +1114,27 @@ if ($resql)
$totaldeposits = $facturestatic->getSumDepositsUsed();
$totalpay = $paiement + $totalcreditnotes + $totaldeposits;
$remaintopay = price2num($facturestatic->total_ttc - $totalpay);
+ $multicurrency_paiement = $facturestatic->getSommePaiement(1);
+ $multicurrency_totalcreditnotes = $facturestatic->getSumCreditNotesUsed(1);
+ $multicurrency_totaldeposits = $facturestatic->getSumDepositsUsed(1);
+ $multicurrency_totalpay = $multicurrency_paiement + $multicurrency_totalcreditnotes + $multicurrency_totaldeposits;
+ $multicurrency_remaintopay = price2num($facturestatic->multicurrency_total_ttc - $multicurrency_totalpay);
if ($facturestatic->statut == Facture::STATUS_CLOSED && $facturestatic->close_code == 'discount_vat') { // If invoice closed with discount for anticipated payment
$remaintopay = 0;
+ $multicurrency_remaintopay = 0;
}
if ($facturestatic->type == Facture::TYPE_CREDIT_NOTE && $obj->paye == 1) { // If credit note closed, we take into account the amount not yet consummed
- $remaincreditnote = $discount->getAvailableDiscounts($obj->fk_soc, '', 'rc.fk_facture_source='.$facturestatic->id);
+ $remaincreditnote = $discount->getAvailableDiscounts($thirdpartystatic, '', 'rc.fk_facture_source='.$facturestatic->id);
$remaintopay = -$remaincreditnote;
$totalpay = price2num($facturestatic->total_ttc - $remaintopay);
+ $multicurrency_remaincreditnote = $discount->getAvailableDiscounts($thirdpartystatic, '', 'rc.fk_facture_source='.$facturestatic->id, 0, 0, 1);
+ $multicurrency_remaintopay = -$multicurrency_remaincreditnote;
+ $multicurrency_totalpay = price2num($facturestatic->multicurrency_total_ttc - $multicurrency_remaintopay);
}
+ $facturestatic->alreadypaid = $paiement;
+
print ' ';
+ print '';
print $obj->ref_client;
print ' ';
if (!$i) $totalarray['nbfield']++;
@@ -1303,6 +1398,55 @@ if ($resql)
$totalarray['val']['rtp'] += $remaintopay;
}
+
+ // Currency
+ if (!empty($arrayfields['f.multicurrency_code']['checked']))
+ {
+ print ''.$obj->multicurrency_code.' - '.$langs->trans('Currency'.$obj->multicurrency_code)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+
+ // Currency rate
+ if (!empty($arrayfields['f.multicurrency_tx']['checked']))
+ {
+ print '';
+ $form->form_multicurrency_rate($_SERVER['PHP_SELF'].'?id='.$obj->rowid, $obj->multicurrency_tx, 'none', $obj->multicurrency_code);
+ print " \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount HT
+ if (!empty($arrayfields['f.multicurrency_total_ht']['checked']))
+ {
+ print ''.price($obj->multicurrency_total_ht)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount VAT
+ if (!empty($arrayfields['f.multicurrency_total_vat']['checked']))
+ {
+ print ''.price($obj->multicurrency_total_vat)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount TTC
+ if (!empty($arrayfields['f.multicurrency_total_ttc']['checked']))
+ {
+ print ''.price($obj->multicurrency_total_ttc)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ if (!empty($arrayfields['multicurrency_dynamount_payed']['checked']))
+ {
+ print ''.(!empty($multicurrency_totalpay) ?price($multicurrency_totalpay, 0, $langs) : ' ').' '; // TODO Use a denormalized field
+ if (!$i) $totalarray['nbfield']++;
+ }
+
+ // Pending amount
+ if (!empty($arrayfields['multicurrency_rtp']['checked']))
+ {
+ print '';
+ print (!empty($multicurrency_remaintopay) ? price($multicurrency_remaintopay, 0, $langs) : ' ');
+ print ' '; // TODO Use a denormalized field
+ if (!$i) $totalarray['nbfield']++;
+ }
+
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
// Fields from hook
diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php
index 447f5f47ecc..c9a77e5cc26 100644
--- a/htdocs/compta/index.php
+++ b/htdocs/compta/index.php
@@ -455,7 +455,7 @@ if (!empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->
$sql = "SELECT ff.rowid, ff.ref, ff.fk_statut, ff.libelle, ff.total_ht, ff.total_tva, ff.total_ttc, ff.tms, ff.paye";
$sql .= ", s.nom as name";
$sql .= ", s.rowid as socid";
- $sql .= ", s.code_fournisseur, s.code_compta_fournisseur";
+ $sql .= ", s.code_fournisseur, s.code_compta_fournisseur, s.email";
$sql .= ", SUM(pf.amount) as am";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as ff";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf on ff.rowid=pf.fk_facturefourn";
@@ -503,10 +503,14 @@ if (!empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->
$thirdpartystatic->id = $obj->socid;
$thirdpartystatic->name = $obj->name;
+ $thirdpartystatic->email = $obj->email;
+ $thirdpartystatic->country_id = 0;
+ $thirdpartystatic->country_code = '';
+ $thirdpartystatic->client = 0;
$thirdpartystatic->fournisseur = 1;
- //$thirdpartystatic->code_client = $obj->code_client;
+ $thirdpartystatic->code_client = '';
$thirdpartystatic->code_fournisseur = $obj->code_fournisseur;
- //$thirdpartystatic->code_compta = $obj->code_compta;
+ $thirdpartystatic->code_compta = '';
$thirdpartystatic->code_compta_fournisseur = $obj->code_compta_fournisseur;
print ' ';
diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php
index fb2a3edfd9c..b4da848ea5a 100644
--- a/htdocs/compta/paiement.php
+++ b/htdocs/compta/paiement.php
@@ -49,7 +49,7 @@ $socid = GETPOST('socid', 'int');
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
$amounts = array();
$amountsresttopay = array();
@@ -97,6 +97,8 @@ if (empty($reshook))
$totalpayment = 0;
$multicurrency_totalpayment = 0;
$atleastonepaymentnotnull = 0;
+ $formquestion = array();
+ $i = 0;
// Generate payment array and check if there is payment higher than invoice and payment date before invoice date
$tmpinvoice = new Facture($db);
@@ -216,7 +218,7 @@ if (empty($reshook))
{
$error = 0;
- $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
+ $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
$db->begin();
@@ -262,8 +264,10 @@ if (empty($reshook))
$paiement->amounts = $amounts; // Array with all payments dispatching with invoice id
$paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching
$paiement->paiementid = dol_getIdFromCode($db, GETPOST('paiementcode'), 'c_paiement', 'code', 'id', 1);
- $paiement->num_paiement = GETPOST('num_paiement', 'alpha');
- $paiement->note = GETPOST('comment', 'alpha');
+ $paiement->num_payment = GETPOST('num_paiement', 'alpha');
+ $paiement->note_private = GETPOST('comment', 'alpha');
+ $paiement->num_paiement = $paiement->num_payment; // For bacward compatibility
+ $paiement->note = $paiement->note_private; // For bacward compatibility
if (!$error)
{
diff --git a/htdocs/compta/paiement/cheque/card.php b/htdocs/compta/paiement/cheque/card.php
index 526905e2ee9..89445e1ec74 100644
--- a/htdocs/compta/paiement/cheque/card.php
+++ b/htdocs/compta/paiement/cheque/card.php
@@ -48,7 +48,7 @@ $result = restrictedArea($user, 'cheque', $id, 'bordereau_cheque', '', 'fk_user_
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (!$sortorder) $sortorder = "ASC";
if (!$sortfield) $sortfield = "b.dateo,b.rowid";
if (empty($page) || $page == -1) { $page = 0; }
diff --git a/htdocs/compta/paiement/cheque/list.php b/htdocs/compta/paiement/cheque/list.php
index 823ae87d420..4534f08dbb1 100644
--- a/htdocs/compta/paiement/cheque/list.php
+++ b/htdocs/compta/paiement/cheque/list.php
@@ -45,7 +45,7 @@ $search_amount = GETPOST('search_amount', 'alpha');
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
index 75dcb837df9..9b0ee645fc7 100644
--- a/htdocs/compta/paiement/class/paiement.class.php
+++ b/htdocs/compta/paiement/class/paiement.class.php
@@ -29,8 +29,8 @@
* \ingroup facture
* \brief File of class to manage payments of customers invoices
*/
-require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
-require_once DOL_DOCUMENT_ROOT .'/multicurrency/class/multicurrency.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
+require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
/**
@@ -41,12 +41,12 @@ class Paiement extends CommonObject
/**
* @var string ID to identify managed object
*/
- public $element='payment';
+ public $element = 'payment';
/**
* @var string Name of table without prefix where object is stored
*/
- public $table_element='paiement';
+ public $table_element = 'paiement';
/**
* @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
@@ -68,12 +68,12 @@ class Paiement extends CommonObject
*/
public $montant;
- public $amount; // Total amount of payment
- public $amounts=array(); // Array of amounts
- public $multicurrency_amounts=array(); // Array of amounts
+ public $amount; // Total amount of payment
+ public $amounts = array(); // Array of amounts
+ public $multicurrency_amounts = array(); // Array of amounts
public $author;
- public $paiementid; // Type of payment. Id saved into fields fk_paiement on llx_paiement
- public $paiementcode; // Code of payment.
+ public $paiementid; // Type of payment. Id saved into fields fk_paiement on llx_paiement
+ public $paiementcode; // Code of payment.
/**
* @var string type libelle
@@ -136,7 +136,7 @@ class Paiement extends CommonObject
/**
* @var int payment id
*/
- public $fk_paiement; // Type of payment
+ public $fk_paiement; // Type of payment
/**
@@ -160,18 +160,18 @@ class Paiement extends CommonObject
public function fetch($id, $ref = '', $fk_bank = '')
{
$sql = 'SELECT p.rowid, p.ref, p.datep as dp, p.amount, p.statut, p.ext_payment_id, p.ext_payment_site, p.fk_bank,';
- $sql.= ' c.code as type_code, c.libelle as type_label,';
- $sql.= ' p.num_paiement as num_payment, p.note,';
- $sql.= ' b.fk_account';
- $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement as p LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id';
- $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
- $sql.= ' WHERE p.entity IN (' . getEntity('invoice').')';
+ $sql .= ' c.code as type_code, c.libelle as type_label,';
+ $sql .= ' p.num_paiement as num_payment, p.note,';
+ $sql .= ' b.fk_account';
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement as p LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id';
+ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
+ $sql .= ' WHERE p.entity IN ('.getEntity('invoice').')';
if ($id > 0)
- $sql.= ' AND p.rowid = '.$id;
+ $sql .= ' AND p.rowid = '.$id;
elseif ($ref)
- $sql.= " AND p.ref = '".$ref."'";
+ $sql .= " AND p.ref = '".$ref."'";
elseif ($fk_bank)
- $sql.= ' AND p.fk_bank = '.$fk_bank;
+ $sql .= ' AND p.fk_bank = '.$fk_bank;
$resql = $this->db->query($sql);
if ($resql)
@@ -180,15 +180,15 @@ class Paiement extends CommonObject
{
$obj = $this->db->fetch_object($resql);
$this->id = $obj->rowid;
- $this->ref = $obj->ref?$obj->ref:$obj->rowid;
+ $this->ref = $obj->ref ? $obj->ref : $obj->rowid;
$this->date = $this->db->jdate($obj->dp);
$this->datepaye = $this->db->jdate($obj->dp);
- $this->num_paiement = $obj->num_payment; // deprecated
+ $this->num_paiement = $obj->num_payment; // deprecated
$this->num_payment = $obj->num_payment;
- $this->montant = $obj->amount; // deprecated
+ $this->montant = $obj->amount; // deprecated
$this->amount = $obj->amount;
$this->note = $obj->note;
- $this->type_label = $obj->type_label;
+ $this->type_label = $obj->type_label;
$this->type_code = $obj->type_code;
$this->statut = $obj->statut;
$this->ext_payment_id = $obj->ext_payment_id;
@@ -231,7 +231,7 @@ class Paiement extends CommonObject
$error = 0;
$way = $this->getWay();
- $now=dol_now();
+ $now = dol_now();
// Clean parameters
$totalamount = 0;
@@ -258,7 +258,7 @@ class Paiement extends CommonObject
$newvalue = price2num($value, 'MT');
$amounts[$key] = $newvalue;
$totalamount += $newvalue;
- if (! empty($newvalue)) $atleastonepaymentnotnull++;
+ if (!empty($newvalue)) $atleastonepaymentnotnull++;
}
$totalamount = price2num($totalamount);
@@ -267,14 +267,16 @@ class Paiement extends CommonObject
// Check parameters
if (empty($totalamount) && empty($atleastonepaymentnotnull)) // We accept negative amounts for withdraw reject but not empty arrays
{
- $this->errors[]='TotalAmountEmpty';
- $this->error='TotalAmountEmpty';
+ $this->errors[] = 'TotalAmountEmpty';
+ $this->error = 'TotalAmountEmpty';
return -1;
}
- $this->db->begin();
+ dol_syslog(get_class($this)."::create insert paiement", LOG_DEBUG);
- $this->ref = $this->getNextNumRef(is_object($thirdparty)?$thirdparty:'');
+ $this->db->begin();
+
+ $this->ref = $this->getNextNumRef(is_object($thirdparty) ? $thirdparty : '');
if ($way == 'dolibarr')
{
@@ -287,13 +289,12 @@ class Paiement extends CommonObject
$mtotal = $totalamount;
}
- $num_payment = ($this->num_payment?$this->num_payment:$this->num_paiement);
- $note = ($this->note_public?$this->note_public:$this->note);
+ $num_payment = ($this->num_payment ? $this->num_payment : $this->num_paiement);
+ $note = ($this->note_public ? $this->note_public : $this->note);
$sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, ext_payment_id, ext_payment_site, fk_user_creat)";
- $sql.= " VALUES (".$conf->entity.", '".$this->db->escape($this->ref)."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', ".$total.", ".$mtotal.", ".$this->paiementid.", '".$this->db->escape($num_payment)."', '".$this->db->escape($note)."', ".($this->ext_payment_id?"'".$this->db->escape($this->ext_payment_id)."'":"null").", ".($this->ext_payment_site?"'".$this->db->escape($this->ext_payment_site)."'":"null").", ".$user->id.")";
+ $sql .= " VALUES (".$conf->entity.", '".$this->db->escape($this->ref)."', '".$this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', ".$total.", ".$mtotal.", ".$this->paiementid.", '".$this->db->escape($num_payment)."', '".$this->db->escape($note)."', ".($this->ext_payment_id ? "'".$this->db->escape($this->ext_payment_id)."'" : "null").", ".($this->ext_payment_site ? "'".$this->db->escape($this->ext_payment_site)."'" : "null").", ".$user->id.")";
- dol_syslog(get_class($this)."::Create insert paiement", LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql)
{
@@ -307,23 +308,23 @@ class Paiement extends CommonObject
{
$amount = price2num($amount);
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'paiement_facture (fk_facture, fk_paiement, amount, multicurrency_amount)';
- $sql .= ' VALUES ('.$facid.', '. $this->id.', \''.$amount.'\', \''.$this->multicurrency_amounts[$key].'\')';
+ $sql .= ' VALUES ('.$facid.', '.$this->id.', \''.$amount.'\', \''.$this->multicurrency_amounts[$key].'\')';
- dol_syslog(get_class($this).'::Create Amount line '.$key.' insert paiement_facture', LOG_DEBUG);
- $resql=$this->db->query($sql);
+ dol_syslog(get_class($this).'::create Amount line '.$key.' insert paiement_facture', LOG_DEBUG);
+ $resql = $this->db->query($sql);
if ($resql)
{
- $invoice=new Facture($this->db);
+ $invoice = new Facture($this->db);
$invoice->fetch($facid);
// If we want to closed payed invoices
if ($closepaidinvoices)
{
$paiement = $invoice->getSommePaiement();
- $creditnotes=$invoice->getSumCreditNotesUsed();
- $deposits=$invoice->getSumDepositsUsed();
- $alreadypayed=price2num($paiement + $creditnotes + $deposits, 'MT');
- $remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits, 'MT');
+ $creditnotes = $invoice->getSumCreditNotesUsed();
+ $deposits = $invoice->getSumDepositsUsed();
+ $alreadypayed = price2num($paiement + $creditnotes + $deposits, 'MT');
+ $remaintopay = price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits, 'MT');
//var_dump($invoice->total_ttc.' - '.$paiement.' -'.$creditnotes.' - '.$deposits.' - '.$remaintopay);exit;
@@ -394,12 +395,12 @@ class Paiement extends CommonObject
}
// Set invoice to paid
- if (! $error)
+ if (!$error)
{
- $result=$invoice->set_paid($user, '', '');
- if ($result<0)
+ $result = $invoice->set_paid($user, '', '');
+ if ($result < 0)
{
- $this->error=$invoice->error;
+ $this->error = $invoice->error;
$error++;
}
}
@@ -409,10 +410,15 @@ class Paiement extends CommonObject
// Regenerate documents of invoices
if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
{
- $newlang='';
+ dol_syslog(get_class($this).'::create Regenerate the document after inserting payment for thirdparty default_lang='.(is_object($invoice->thirdparty) ? $invoice->thirdparty->default_lang : 'null'), LOG_DEBUG);
+
+ $newlang = '';
$outputlangs = $langs;
- if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $invoice->thirdparty->default_lang;
- if (! empty($newlang)) {
+ if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
+ $invoice->fetch_thirdparty();
+ $newlang = $invoice->thirdparty->default_lang;
+ }
+ if (!empty($newlang)) {
$outputlangs = new Translate("", $conf);
$outputlangs->setDefaultLang($newlang);
}
@@ -426,7 +432,7 @@ class Paiement extends CommonObject
}
else
{
- $this->error=$this->db->lasterror();
+ $this->error = $this->db->lasterror();
$error++;
}
}
@@ -436,25 +442,25 @@ class Paiement extends CommonObject
}
}
- if (! $error) // All payments into $this->amounts were recorded without errors
+ if (!$error) // All payments into $this->amounts were recorded without errors
{
// Appel des triggers
- $result=$this->call_trigger('PAYMENT_CUSTOMER_CREATE', $user);
+ $result = $this->call_trigger('PAYMENT_CUSTOMER_CREATE', $user);
if ($result < 0) { $error++; }
// Fin appel triggers
}
}
else
{
- $this->error=$this->db->lasterror();
+ $this->error = $this->db->lasterror();
$error++;
}
- if (! $error)
+ if (!$error)
{
- $this->amount=$total;
- $this->total=$total; // deprecated
- $this->multicurrency_amount=$mtotal;
+ $this->amount = $total;
+ $this->total = $total; // deprecated
+ $this->multicurrency_amount = $mtotal;
$this->db->commit();
return $this->id;
}
@@ -478,7 +484,7 @@ class Paiement extends CommonObject
{
global $conf, $user, $langs;
- $error=0;
+ $error = 0;
$bank_line_id = $this->bank_line;
@@ -486,12 +492,12 @@ class Paiement extends CommonObject
// Verifier si paiement porte pas sur une facture classee
// Si c'est le cas, on refuse la suppression
- $billsarray=$this->getBillsArray('fk_statut > 1');
+ $billsarray = $this->getBillsArray('fk_statut > 1');
if (is_array($billsarray))
{
if (count($billsarray))
{
- $this->error="ErrorDeletePaymentLinkedToAClosedInvoiceNotPossible";
+ $this->error = "ErrorDeletePaymentLinkedToAClosedInvoiceNotPossible";
$this->db->rollback();
return -1;
}
@@ -507,32 +513,32 @@ class Paiement extends CommonObject
{
$accline = new AccountLine($this->db);
- $result=$accline->fetch($bank_line_id);
- if ($result == 0) $accline->rowid=$bank_line_id; // If not found, we set artificially rowid to allow delete of llx_bank_url
+ $result = $accline->fetch($bank_line_id);
+ if ($result == 0) $accline->rowid = $bank_line_id; // If not found, we set artificially rowid to allow delete of llx_bank_url
// Delete bank account url lines linked to payment
- $result=$accline->delete_urls($user);
+ $result = $accline->delete_urls($user);
if ($result < 0)
{
- $this->error=$accline->error;
+ $this->error = $accline->error;
$this->db->rollback();
return -3;
}
// Delete bank account lines linked to payment
- $result=$accline->delete($user);
+ $result = $accline->delete($user);
if ($result < 0)
{
- $this->error=$accline->error;
+ $this->error = $accline->error;
$this->db->rollback();
return -4;
}
}
- if (! $notrigger)
+ if (!$notrigger)
{
// Call triggers
- $result=$this->call_trigger('PAYMENT_CUSTOMER_DELETE', $user);
+ $result = $this->call_trigger('PAYMENT_CUSTOMER_DELETE', $user);
if ($result < 0)
{
$this->db->rollback();
@@ -543,18 +549,18 @@ class Paiement extends CommonObject
// Delete payment (into paiement_facture and paiement)
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'paiement_facture';
- $sql.= ' WHERE fk_paiement = '.$this->id;
+ $sql .= ' WHERE fk_paiement = '.$this->id;
dol_syslog($sql);
$result = $this->db->query($sql);
if ($result)
{
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'paiement';
- $sql.= ' WHERE rowid = '.$this->id;
+ $sql .= ' WHERE rowid = '.$this->id;
dol_syslog($sql);
$result = $this->db->query($sql);
- if (! $result)
+ if (!$result)
{
- $this->error=$this->db->lasterror();
+ $this->error = $this->db->lasterror();
$this->db->rollback();
return -3;
}
@@ -564,7 +570,7 @@ class Paiement extends CommonObject
}
else
{
- $this->error=$this->db->error;
+ $this->error = $this->db->error;
$this->db->rollback();
return -5;
}
@@ -586,46 +592,46 @@ class Paiement extends CommonObject
*/
public function addPaymentToBank($user, $mode, $label, $accountid, $emetteur_nom, $emetteur_banque, $notrigger = 0)
{
- global $conf,$langs,$user;
+ global $conf, $langs, $user;
- $error=0;
- $bank_line_id=0;
+ $error = 0;
+ $bank_line_id = 0;
- if (! empty($conf->banque->enabled))
+ if (!empty($conf->banque->enabled))
{
if ($accountid <= 0)
{
- $this->error='Bad value for parameter accountid='.$accountid;
+ $this->error = 'Bad value for parameter accountid='.$accountid;
dol_syslog(get_class($this).'::addPaymentToBank '.$this->error, LOG_ERR);
return -1;
}
$this->db->begin();
- $this->fk_account=$accountid;
+ $this->fk_account = $accountid;
include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
- dol_syslog("$user->id,$mode,$label,$this->fk_account,$emetteur_nom,$emetteur_banque");
+ dol_syslog("$user->id, $mode, $label, $this->fk_account, $emetteur_nom, $emetteur_banque");
$acc = new Account($this->db);
- $result=$acc->fetch($this->fk_account);
+ $result = $acc->fetch($this->fk_account);
- $totalamount=$this->amount;
- if (empty($totalamount)) $totalamount=$this->total; // For backward compatibility
+ $totalamount = $this->amount;
+ if (empty($totalamount)) $totalamount = $this->total; // For backward compatibility
// if dolibarr currency != bank currency then we received an amount in customer currency (currently I don't manage the case : my currency is USD, the customer currency is EUR and he paid me in GBP. Seems no sense for me)
- if (!empty($conf->multicurrency->enabled) && $conf->currency != $acc->currency_code) $totalamount=$this->multicurrency_amount;
+ if (!empty($conf->multicurrency->enabled) && $conf->currency != $acc->currency_code) $totalamount = $this->multicurrency_amount;
- if ($mode == 'payment_supplier') $totalamount=-$totalamount;
+ if ($mode == 'payment_supplier') $totalamount = -$totalamount;
// Insert payment into llx_bank
$bank_line_id = $acc->addline(
$this->datepaye,
- $this->paiementid, // Payment mode id or code ("CHQ or VIR for example")
+ $this->paiementid, // Payment mode id or code ("CHQ or VIR for example")
$label,
- $totalamount, // Sign must be positive when we receive money (customer payment), negative when you give money (supplier invoice or credit note)
- $this->num_paiement,
+ $totalamount, // Sign must be positive when we receive money (customer payment), negative when you give money (supplier invoice or credit note)
+ $this->num_payment,
'',
$user,
$emetteur_nom,
@@ -636,7 +642,7 @@ class Paiement extends CommonObject
// On connait ainsi le paiement qui a genere l'ecriture bancaire
if ($bank_line_id > 0)
{
- $result=$this->update_fk_bank($bank_line_id);
+ $result = $this->update_fk_bank($bank_line_id);
if ($result <= 0)
{
$error++;
@@ -644,14 +650,14 @@ class Paiement extends CommonObject
}
// Add link 'payment', 'payment_supplier' in bank_url between payment and bank transaction
- if ( ! $error)
+ if (!$error)
{
- $url='';
- if ($mode == 'payment') $url=DOL_URL_ROOT.'/compta/paiement/card.php?id=';
- if ($mode == 'payment_supplier') $url=DOL_URL_ROOT.'/fourn/paiement/card.php?id=';
+ $url = '';
+ if ($mode == 'payment') $url = DOL_URL_ROOT.'/compta/paiement/card.php?id=';
+ if ($mode == 'payment_supplier') $url = DOL_URL_ROOT.'/fourn/paiement/card.php?id=';
if ($url)
{
- $result=$acc->add_url_line($bank_line_id, $this->id, $url, '(paiement)', $mode);
+ $result = $acc->add_url_line($bank_line_id, $this->id, $url, '(paiement)', $mode);
if ($result <= 0)
{
$error++;
@@ -662,9 +668,9 @@ class Paiement extends CommonObject
// Add link 'company' in bank_url between invoice and bank transaction (for each invoice concerned by payment)
//if (! $error && $label != '(WithdrawalPayment)')
- if (! $error)
+ if (!$error)
{
- $linkaddedforthirdparty=array();
+ $linkaddedforthirdparty = array();
foreach ($this->amounts as $key => $value) // We should have invoices always for same third party but we loop in case of.
{
if ($mode == 'payment')
@@ -672,9 +678,9 @@ class Paiement extends CommonObject
$fac = new Facture($this->db);
$fac->fetch($key);
$fac->fetch_thirdparty();
- if (! in_array($fac->thirdparty->id, $linkaddedforthirdparty)) // Not yet done for this thirdparty
+ if (!in_array($fac->thirdparty->id, $linkaddedforthirdparty)) // Not yet done for this thirdparty
{
- $result=$acc->add_url_line(
+ $result = $acc->add_url_line(
$bank_line_id,
$fac->thirdparty->id,
DOL_URL_ROOT.'/comm/card.php?socid=',
@@ -682,7 +688,7 @@ class Paiement extends CommonObject
'company'
);
if ($result <= 0) dol_syslog(get_class($this).'::addPaymentToBank '.$this->db->lasterror());
- $linkaddedforthirdparty[$fac->thirdparty->id]=$fac->thirdparty->id; // Mark as done for this thirdparty
+ $linkaddedforthirdparty[$fac->thirdparty->id] = $fac->thirdparty->id; // Mark as done for this thirdparty
}
}
if ($mode == 'payment_supplier')
@@ -690,9 +696,9 @@ class Paiement extends CommonObject
$fac = new FactureFournisseur($this->db);
$fac->fetch($key);
$fac->fetch_thirdparty();
- if (! in_array($fac->thirdparty->id, $linkaddedforthirdparty)) // Not yet done for this thirdparty
+ if (!in_array($fac->thirdparty->id, $linkaddedforthirdparty)) // Not yet done for this thirdparty
{
- $result=$acc->add_url_line(
+ $result = $acc->add_url_line(
$bank_line_id,
$fac->thirdparty->id,
DOL_URL_ROOT.'/fourn/card.php?socid=',
@@ -700,15 +706,15 @@ class Paiement extends CommonObject
'company'
);
if ($result <= 0) dol_syslog(get_class($this).'::addPaymentToBank '.$this->db->lasterror());
- $linkaddedforthirdparty[$fac->thirdparty->id]=$fac->thirdparty->id; // Mark as done for this thirdparty
+ $linkaddedforthirdparty[$fac->thirdparty->id] = $fac->thirdparty->id; // Mark as done for this thirdparty
}
}
}
}
// Add link 'WithdrawalPayment' in bank_url
- if (! $error && $label == '(WithdrawalPayment)') {
- $result=$acc->add_url_line(
+ if (!$error && $label == '(WithdrawalPayment)') {
+ $result = $acc->add_url_line(
$bank_line_id,
$this->id_prelevement,
DOL_URL_ROOT.'/compta/prelevement/card.php?id=',
@@ -717,21 +723,21 @@ class Paiement extends CommonObject
);
}
- if (! $error && ! $notrigger)
+ if (!$error && !$notrigger)
{
// Appel des triggers
- $result=$this->call_trigger('PAYMENT_ADD_TO_BANK', $user);
+ $result = $this->call_trigger('PAYMENT_ADD_TO_BANK', $user);
if ($result < 0) { $error++; }
// Fin appel triggers
}
}
else
{
- $this->error=$acc->error;
+ $this->error = $acc->error;
$error++;
}
- if (! $error)
+ if (!$error)
{
$this->db->commit();
}
@@ -741,7 +747,7 @@ class Paiement extends CommonObject
}
}
- if (! $error)
+ if (!$error)
{
return $bank_line_id;
}
@@ -763,7 +769,7 @@ class Paiement extends CommonObject
{
// phpcs:enable
$sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' set fk_bank = '.$id_bank;
- $sql.= ' WHERE rowid = '.$this->id;
+ $sql .= ' WHERE rowid = '.$this->id;
dol_syslog(get_class($this).'::update_fk_bank', LOG_DEBUG);
$result = $this->db->query($sql);
@@ -773,7 +779,7 @@ class Paiement extends CommonObject
}
else
{
- $this->error=$this->db->lasterror();
+ $this->error = $this->db->lasterror();
dol_syslog(get_class($this).'::update_fk_bank '.$this->error);
return -1;
}
@@ -789,7 +795,7 @@ class Paiement extends CommonObject
public function update_date($date)
{
// phpcs:enable
- $error=0;
+ $error = 0;
if (!empty($date) && $this->statut != 1)
{
@@ -798,35 +804,35 @@ class Paiement extends CommonObject
dol_syslog(get_class($this)."::update_date with date = ".$date, LOG_DEBUG);
$sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
- $sql.= " SET datep = '".$this->db->idate($date)."'";
- $sql.= " WHERE rowid = ".$this->id;
+ $sql .= " SET datep = '".$this->db->idate($date)."'";
+ $sql .= " WHERE rowid = ".$this->id;
$result = $this->db->query($sql);
- if (! $result)
+ if (!$result)
{
$error++;
- $this->error='Error -1 '.$this->db->error();
+ $this->error = 'Error -1 '.$this->db->error();
}
$type = $this->element;
$sql = "UPDATE ".MAIN_DB_PREFIX.'bank';
- $sql.= " SET dateo = '".$this->db->idate($date)."', datev = '".$this->db->idate($date)."'";
- $sql.= " WHERE rowid IN (SELECT fk_bank FROM ".MAIN_DB_PREFIX."bank_url WHERE type = '".$type."' AND url_id = ".$this->id.")";
- $sql.= " AND rappro = 0";
+ $sql .= " SET dateo = '".$this->db->idate($date)."', datev = '".$this->db->idate($date)."'";
+ $sql .= " WHERE rowid IN (SELECT fk_bank FROM ".MAIN_DB_PREFIX."bank_url WHERE type = '".$type."' AND url_id = ".$this->id.")";
+ $sql .= " AND rappro = 0";
$result = $this->db->query($sql);
- if (! $result)
+ if (!$result)
{
$error++;
- $this->error='Error -1 '.$this->db->error();
+ $this->error = 'Error -1 '.$this->db->error();
}
- if (! $error)
+ if (!$error)
{
}
- if (! $error)
+ if (!$error)
{
$this->datepaye = $date;
$this->date = $date;
@@ -853,10 +859,10 @@ class Paiement extends CommonObject
public function update_num($num)
{
// phpcs:enable
- if(!empty($num) && $this->statut!=1) {
+ if (!empty($num) && $this->statut != 1) {
$sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
- $sql.= " SET num_paiement = '".$this->db->escape($num)."'";
- $sql.= " WHERE rowid = ".$this->id;
+ $sql .= " SET num_paiement = '".$this->db->escape($num)."'";
+ $sql .= " WHERE rowid = ".$this->id;
dol_syslog(get_class($this)."::update_num", LOG_DEBUG);
$result = $this->db->query($sql);
@@ -867,7 +873,7 @@ class Paiement extends CommonObject
}
else
{
- $this->error='Error -1 '.$this->db->error();
+ $this->error = 'Error -1 '.$this->db->error();
return -2;
}
}
@@ -892,7 +898,7 @@ class Paiement extends CommonObject
}
else
{
- $this->error=$this->db->lasterror();
+ $this->error = $this->db->lasterror();
dol_syslog(get_class($this).'::valide '.$this->error);
return -1;
}
@@ -916,7 +922,7 @@ class Paiement extends CommonObject
}
else
{
- $this->error=$this->db->lasterror();
+ $this->error = $this->db->lasterror();
dol_syslog(get_class($this).'::reject '.$this->error);
return -1;
}
@@ -931,8 +937,8 @@ class Paiement extends CommonObject
public function info($id)
{
$sql = 'SELECT p.rowid, p.datec, p.fk_user_creat, p.fk_user_modif, p.tms';
- $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement as p';
- $sql.= ' WHERE p.rowid = '.$id;
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement as p';
+ $sql .= ' WHERE p.rowid = '.$id;
dol_syslog(get_class($this).'::info', LOG_DEBUG);
$result = $this->db->query($sql);
@@ -947,7 +953,7 @@ class Paiement extends CommonObject
{
$cuser = new User($this->db);
$cuser->fetch($obj->fk_user_creat);
- $this->user_creation = $cuser;
+ $this->user_creation = $cuser;
}
if ($obj->fk_user_modif)
{
@@ -975,20 +981,20 @@ class Paiement extends CommonObject
public function getBillsArray($filter = '')
{
$sql = 'SELECT pf.fk_facture';
- $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'facture as f'; // We keep link on invoice to allow use of some filters on invoice
- $sql.= ' WHERE pf.fk_facture = f.rowid AND pf.fk_paiement = '.$this->id;
- if ($filter) $sql.= ' AND '.$filter;
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'facture as f'; // We keep link on invoice to allow use of some filters on invoice
+ $sql .= ' WHERE pf.fk_facture = f.rowid AND pf.fk_paiement = '.$this->id;
+ if ($filter) $sql .= ' AND '.$filter;
$resql = $this->db->query($sql);
if ($resql)
{
- $i=0;
- $num=$this->db->num_rows($resql);
- $billsarray=array();
+ $i = 0;
+ $num = $this->db->num_rows($resql);
+ $billsarray = array();
while ($i < $num)
{
$obj = $this->db->fetch_object($resql);
- $billsarray[$i]=$obj->fk_facture;
+ $billsarray[$i] = $obj->fk_facture;
$i++;
}
@@ -996,7 +1002,7 @@ class Paiement extends CommonObject
}
else
{
- $this->error=$this->db->error();
+ $this->error = $this->db->error();
dol_syslog(get_class($this).'::getBillsArray Error '.$this->error.' -', LOG_DEBUG);
return -1;
}
@@ -1010,19 +1016,19 @@ class Paiement extends CommonObject
public function getAmountsArray()
{
$sql = 'SELECT pf.fk_facture, pf.amount';
- $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf';
- $sql.= ' WHERE pf.fk_paiement = '.$this->id;
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf';
+ $sql .= ' WHERE pf.fk_paiement = '.$this->id;
$resql = $this->db->query($sql);
if ($resql)
{
- $i=0;
- $num=$this->db->num_rows($resql);
+ $i = 0;
+ $num = $this->db->num_rows($resql);
$amounts = array();
while ($i < $num)
{
$obj = $this->db->fetch_object($resql);
- $amounts[$obj->fk_facture]=$obj->amount;
+ $amounts[$obj->fk_facture] = $obj->amount;
$i++;
}
@@ -1030,7 +1036,7 @@ class Paiement extends CommonObject
}
else
{
- $this->error=$this->db->error();
+ $this->error = $this->db->error();
dol_syslog(get_class($this).'::getAmountsArray Error '.$this->error.' -', LOG_DEBUG);
return -1;
}
@@ -1050,13 +1056,13 @@ class Paiement extends CommonObject
$langs->load("bills");
// Clean parameters (if not defined or using deprecated value)
- if (empty($conf->global->PAYMENT_ADDON)) $conf->global->PAYMENT_ADDON='mod_payment_cicada';
- elseif ($conf->global->PAYMENT_ADDON=='ant') $conf->global->PAYMENT_ADDON='mod_payment_ant';
- elseif ($conf->global->PAYMENT_ADDON=='cicada') $conf->global->PAYMENT_ADDON='mod_payment_cicada';
+ if (empty($conf->global->PAYMENT_ADDON)) $conf->global->PAYMENT_ADDON = 'mod_payment_cicada';
+ elseif ($conf->global->PAYMENT_ADDON == 'ant') $conf->global->PAYMENT_ADDON = 'mod_payment_ant';
+ elseif ($conf->global->PAYMENT_ADDON == 'cicada') $conf->global->PAYMENT_ADDON = 'mod_payment_cicada';
- if (! empty($conf->global->PAYMENT_ADDON))
+ if (!empty($conf->global->PAYMENT_ADDON))
{
- $mybool=false;
+ $mybool = false;
$file = $conf->global->PAYMENT_ADDON.".php";
$classname = $conf->global->PAYMENT_ADDON;
@@ -1070,12 +1076,12 @@ class Paiement extends CommonObject
// Load file with numbering class (if found)
if (is_file($dir.$file) && is_readable($dir.$file))
{
- $mybool |= include_once $dir . $file;
+ $mybool |= include_once $dir.$file;
}
}
// For compatibility
- if (! $mybool)
+ if (!$mybool)
{
$file = $conf->global->PAYMENT_ADDON.".php";
$classname = "mod_payment_".$conf->global->PAYMENT_ADDON;
@@ -1087,12 +1093,12 @@ class Paiement extends CommonObject
// Load file with numbering class (if found)
if (is_file($dir.$file) && is_readable($dir.$file)) {
- $mybool |= include_once $dir . $file;
+ $mybool |= include_once $dir.$file;
}
}
}
- if (! $mybool)
+ if (!$mybool)
{
dol_print_error('', "Failed to include file ".$file);
return '';
@@ -1156,16 +1162,16 @@ class Paiement extends CommonObject
*/
public function initAsSpecimen($option = '')
{
- global $user,$langs,$conf;
+ global $user, $langs, $conf;
- $now=dol_now();
- $arraynow=dol_getdate($now);
- $nownotime=dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
+ $now = dol_now();
+ $arraynow = dol_getdate($now);
+ $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
// Initialize parameters
- $this->id=0;
+ $this->id = 0;
$this->ref = 'SPECIMEN';
- $this->specimen=1;
+ $this->specimen = 1;
$this->facid = 1;
$this->datepaye = $nownotime;
}
@@ -1184,49 +1190,49 @@ class Paiement extends CommonObject
{
global $conf, $langs;
- if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips
+ if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
- $result='';
+ $result = '';
$label = ''.$langs->trans("ShowPayment").' ';
- $label.= ''.$langs->trans("Ref").': '.$this->ref;
- if ($this->datepaye ? $this->datepaye : $this->date) $label.= ''.$langs->trans("Date").': '.dol_print_date($this->datepaye ? $this->datepaye : $this->date, 'dayhour');
+ $label .= ''.$langs->trans("Ref").': '.$this->ref;
+ if ($this->datepaye ? $this->datepaye : $this->date) $label .= ''.$langs->trans("Date").': '.dol_print_date($this->datepaye ? $this->datepaye : $this->date, 'dayhour');
if ($mode == 'withlistofinvoices')
{
$arraybill = $this->getBillsArray();
if (is_array($arraybill) && count($arraybill) > 0)
{
include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
- $facturestatic=new Facture($this->db);
+ $facturestatic = new Facture($this->db);
foreach ($arraybill as $billid)
{
$facturestatic->fetch($billid);
- $label .=' '.$facturestatic->getNomUrl(1).' '.$facturestatic->getLibStatut(2, 1);
+ $label .= ' '.$facturestatic->getNomUrl(1).' '.$facturestatic->getLibStatut(2, 1);
}
}
}
- $linkclose='';
+ $linkclose = '';
if (empty($notooltip))
{
- if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
+ if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
{
- $label=$langs->trans("ShowMyObject");
- $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
+ $label = $langs->trans("ShowMyObject");
+ $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
}
- $linkclose.=' title="'.dol_escape_htmltag($label, 1).'"';
- $linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"';
+ $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
+ $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
}
- else $linkclose = ($morecss?' class="'.$morecss.'"':'');
+ else $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
$url = DOL_URL_ROOT.'/compta/paiement/card.php?id='.$this->id;
$linkstart = '';
- $linkend=' ';
+ $linkstart .= $linkclose.'>';
+ $linkend = '';
$result .= $linkstart;
- if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'generic'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
- if ($withpicto && $withpicto != 2) $result.= ($this->ref?$this->ref:$this->id);
+ if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
+ if ($withpicto && $withpicto != 2) $result .= ($this->ref ? $this->ref : $this->id);
$result .= $linkend;
return $result;
@@ -1254,7 +1260,7 @@ class Paiement extends CommonObject
public function LibStatut($status, $mode = 0)
{
// phpcs:enable
- global $langs; // TODO Renvoyer le libelle anglais et faire traduction a affichage
+ global $langs; // TODO Renvoyer le libelle anglais et faire traduction a affichage
$langs->load('compta');
/*if ($mode == 0)
@@ -1305,7 +1311,7 @@ class Paiement extends CommonObject
public function fetch_thirdparty($force_thirdparty_id = 0)
{
// phpcs:enable
- include_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
+ include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
if (empty($force_thirdparty_id))
{
diff --git a/htdocs/compta/paiement/list.php b/htdocs/compta/paiement/list.php
index b1de388f7ba..926c0bfc87e 100644
--- a/htdocs/compta/paiement/list.php
+++ b/htdocs/compta/paiement/list.php
@@ -68,7 +68,7 @@ $search_payment_num=GETPOST('search_payment_num', 'alpha');
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/paiement/tovalidate.php b/htdocs/compta/paiement/tovalidate.php
index 1c5e4be20c2..7539d6165ea 100644
--- a/htdocs/compta/paiement/tovalidate.php
+++ b/htdocs/compta/paiement/tovalidate.php
@@ -42,7 +42,7 @@ if ($user->socid > 0)
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/prelevement/bons.php b/htdocs/compta/prelevement/bons.php
index c623d660aaa..b42e6a4fe62 100644
--- a/htdocs/compta/prelevement/bons.php
+++ b/htdocs/compta/prelevement/bons.php
@@ -39,7 +39,7 @@ $result = restrictedArea($user, 'prelevement', '', '', 'bons');
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/prelevement/card.php b/htdocs/compta/prelevement/card.php
index d998554b533..68f40999aa7 100644
--- a/htdocs/compta/prelevement/card.php
+++ b/htdocs/compta/prelevement/card.php
@@ -49,7 +49,7 @@ $socid = GETPOST('socid', 'int');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php
index d1b6361cc34..45c413efb76 100644
--- a/htdocs/compta/prelevement/create.php
+++ b/htdocs/compta/prelevement/create.php
@@ -48,7 +48,7 @@ $action = GETPOST('action', 'alpha');
$mode = GETPOST('mode', 'alpha') ?GETPOST('mode', 'alpha') : 'real';
$format = GETPOST('format', 'aZ09');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
diff --git a/htdocs/compta/prelevement/demandes.php b/htdocs/compta/prelevement/demandes.php
index 61c457c9b17..181f71a678c 100644
--- a/htdocs/compta/prelevement/demandes.php
+++ b/htdocs/compta/prelevement/demandes.php
@@ -50,7 +50,7 @@ $search_societe = trim(GETPOST('search_societe', 'alpha'));
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php
index 63db9aea363..3297042407f 100644
--- a/htdocs/compta/prelevement/factures.php
+++ b/htdocs/compta/prelevement/factures.php
@@ -45,7 +45,7 @@ $ref = GETPOST('ref', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php
index 4320a0c6094..44be3d1cd01 100644
--- a/htdocs/compta/prelevement/fiche-rejet.php
+++ b/htdocs/compta/prelevement/fiche-rejet.php
@@ -45,7 +45,7 @@ $ref = GETPOST('ref', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/prelevement/fiche-stat.php b/htdocs/compta/prelevement/fiche-stat.php
index 70441ff19c2..6e8e8390ae8 100644
--- a/htdocs/compta/prelevement/fiche-stat.php
+++ b/htdocs/compta/prelevement/fiche-stat.php
@@ -43,7 +43,7 @@ $ref = GETPOST('ref', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/prelevement/line.php b/htdocs/compta/prelevement/line.php
index 5d0734cae22..3615809d21a 100644
--- a/htdocs/compta/prelevement/line.php
+++ b/htdocs/compta/prelevement/line.php
@@ -43,7 +43,7 @@ $action = GETPOST('action', 'alpha');
$id = GETPOST('id', 'int');
$socid = GETPOST('socid', 'int');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
$sortorder = GETPOST('sortorder', 'alpha');
$sortfield = GETPOST('sortfield', 'alpha');
diff --git a/htdocs/compta/prelevement/list.php b/htdocs/compta/prelevement/list.php
index e5ba1daffa8..bbac6c6232e 100644
--- a/htdocs/compta/prelevement/list.php
+++ b/htdocs/compta/prelevement/list.php
@@ -41,7 +41,7 @@ $result = restrictedArea($user, 'prelevement', '', '', 'bons');
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/prelevement/rejets.php b/htdocs/compta/prelevement/rejets.php
index 4235f5d7fc3..cc4f3fe5e79 100644
--- a/htdocs/compta/prelevement/rejets.php
+++ b/htdocs/compta/prelevement/rejets.php
@@ -39,7 +39,7 @@ if ($user->socid) $socid=$user->socid;
$result = restrictedArea($user, 'prelevement', '', '', 'bons');
// Get supervariables
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
$sortorder = GETPOST('sortorder', 'alpha');
$sortfield = GETPOST('sortfield', 'alpha');
diff --git a/htdocs/compta/recap-compta.php b/htdocs/compta/recap-compta.php
index 60ea008a834..37bf3d36d70 100644
--- a/htdocs/compta/recap-compta.php
+++ b/htdocs/compta/recap-compta.php
@@ -48,7 +48,7 @@ $hookmanager->initHooks(array('recapcomptacard', 'globalcard'));
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/resultat/clientfourn.php b/htdocs/compta/resultat/clientfourn.php
index ee76a29d282..17d2becfc19 100644
--- a/htdocs/compta/resultat/clientfourn.php
+++ b/htdocs/compta/resultat/clientfourn.php
@@ -57,7 +57,7 @@ if (!empty($conf->accounting->enabled)) $result = restrictedArea($user, 'account
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
@@ -67,8 +67,7 @@ if (!$sortorder) $sortorder = 'ASC';
// Date range
$year = GETPOST('year', 'int');
-if (empty($year))
-{
+if (empty($year)) {
$year_current = strftime("%Y", dol_now());
$month_current = strftime("%m", dol_now());
$year_start = $year_current;
@@ -114,7 +113,7 @@ $tmps = dol_getdate($date_start);
$year_start = $tmps['year'];
$tmpe = dol_getdate($date_end);
$year_end = $tmpe['year'];
-$nbofyear = ($year_end - $start_year) + 1;
+$nbofyear = ($year_end - $year_start) + 1;
//var_dump("year_start=".$year_start." year_end=".$year_end." nbofyear=".$nbofyear." date_start=".dol_print_date($date_start, 'dayhour')." date_end=".dol_print_date($date_end, 'dayhour'));
// Define modecompta ('CREANCES-DETTES' or 'RECETTES-DEPENSES' or 'BOOKKEEPING')
@@ -193,17 +192,21 @@ if (!empty($conf->accounting->enabled) && $modecompta != 'BOOKKEEPING')
}
// Show report array
-$param = '&modecompta='.$modecompta;
+$param = '&modecompta='.urlencode($modecompta).'&showaccountdetail='.urlencode($showaccountdetail);
if ($date_startday) $param .= '&date_startday='.$date_startday;
if ($date_startmonth) $param .= '&date_startmonth='.$date_startmonth;
if ($date_startyear) $param .= '&date_startyear='.$date_startyear;
if ($date_endday) $param .= '&date_endday='.$date_endday;
if ($date_endmonth) $param .= '&date_endmonth='.$date_endmonth;
-if ($date_endyear) $param .= '&date_endyear='.$date_startyear;
+if ($date_endyear) $param .= '&date_endyear='.$date_endyear;
print '';
print '';
-print_liste_field_titre("PredefinedGroups", $_SERVER["PHP_SELF"], 'f.thirdparty_code,f.rowid', '', $param, '', $sortfield, $sortorder, 'width200 ');
+if ($modecompta == 'BOOKKEEPING') {
+ print_liste_field_titre("PredefinedGroups", $_SERVER["PHP_SELF"], 'f.thirdparty_code,f.rowid', '', $param, '', $sortfield, $sortorder, 'width200 ');
+} else {
+ print_liste_field_titre("", $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'width200 ');
+}
print_liste_field_titre('');
if ($modecompta == 'BOOKKEEPING')
{
@@ -243,7 +246,7 @@ if ($modecompta == 'BOOKKEEPING')
$sql .= " AND f.entity = ".$conf->entity;
if (!empty($date_start) && !empty($date_end))
$sql .= " AND f.doc_date >= '".$db->idate($date_start)."' AND f.doc_date <= '".$db->idate($date_end)."'";
- $sql .= " GROUP BY pcg_type, pcg_subtype, name, socid";
+ $sql .= " GROUP BY pcg_type, name, socid";
$sql .= $db->order($sortfield, $sortorder);
$oldpcgtype = '';
diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php
index c5e142ca7ca..69ad435c64c 100644
--- a/htdocs/compta/sociales/card.php
+++ b/htdocs/compta/sociales/card.php
@@ -47,6 +47,11 @@ $action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm');
$projectid = (GETPOST('projectid') ? GETPOST('projectid', 'int') : 0);
+$dateech = dol_mktime(GETPOST('echhour'), GETPOST('echmin'), GETPOST('echsec'), GETPOST('echmonth'), GETPOST('echday'), GETPOST('echyear'));
+$dateperiod = dol_mktime(GETPOST('periodhour'), GETPOST('periodmin'), GETPOST('periodsec'), GETPOST('periodmonth'), GETPOST('periodday'), GETPOST('periodyear'));
+$label = GETPOST('label', 'alpha');
+$actioncode = GETPOST('actioncode');
+
// Security check
$socid = GETPOST('socid', 'int');
if ($user->socid) $socid = $user->socid;
@@ -134,10 +139,7 @@ if ($action == 'confirm_delete' && $confirm == 'yes')
// Add social contribution
if ($action == 'add' && $user->rights->tax->charges->creer)
{
- $dateech = dol_mktime(GETPOST('echhour'), GETPOST('echmin'), GETPOST('echsec'), GETPOST('echmonth'), GETPOST('echday'), GETPOST('echyear'));
- $dateperiod = dol_mktime(GETPOST('periodhour'), GETPOST('periodmin'), GETPOST('periodsec'), GETPOST('periodmonth'), GETPOST('periodday'), GETPOST('periodyear'));
$amount = price2num(GETPOST('amount'));
- $actioncode = GETPOST('actioncode');
if (!$dateech)
{
@@ -187,8 +189,6 @@ if ($action == 'add' && $user->rights->tax->charges->creer)
if ($action == 'update' && !$_POST["cancel"] && $user->rights->tax->charges->creer)
{
- $dateech = dol_mktime(GETPOST('echhour'), GETPOST('echmin'), GETPOST('echsec'), GETPOST('echmonth'), GETPOST('echday'), GETPOST('echyear'));
- $dateperiod = dol_mktime(GETPOST('periodhour'), GETPOST('periodmin'), GETPOST('periodsec'), GETPOST('periodmonth'), GETPOST('periodday'), GETPOST('periodyear'));
$amount = price2num(GETPOST('amount'));
if (!$dateech)
diff --git a/htdocs/compta/sociales/class/paymentsocialcontribution.class.php b/htdocs/compta/sociales/class/paymentsocialcontribution.class.php
index a5279ecbeae..629a73578b2 100644
--- a/htdocs/compta/sociales/class/paymentsocialcontribution.class.php
+++ b/htdocs/compta/sociales/class/paymentsocialcontribution.class.php
@@ -57,7 +57,7 @@ class PaymentSocialContribution extends CommonObject
/**
* @deprecated
- * @see amount
+ * @see $amount
*/
public $total;
diff --git a/htdocs/compta/sociales/document.php b/htdocs/compta/sociales/document.php
index 4a714df8bae..2d5d3c48899 100644
--- a/htdocs/compta/sociales/document.php
+++ b/htdocs/compta/sociales/document.php
@@ -54,7 +54,7 @@ $result = restrictedArea($user, 'tax', $id, 'chargesociales', 'charges');
// Get parameters
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) {
$page = 0;
}
diff --git a/htdocs/compta/sociales/list.php b/htdocs/compta/sociales/list.php
index d259fb362fd..ca58830a7bb 100644
--- a/htdocs/compta/sociales/list.php
+++ b/htdocs/compta/sociales/list.php
@@ -3,6 +3,7 @@
* Copyright (C) 2004-2017 Laurent Destailleur
* Copyright (C) 2005-2009 Regis Houssin
* Copyright (C) 2016 Frédéric France
+ * Copyright (C) 2020 Pierre Ardoin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,6 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php'
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formsocialcontrib.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+if (!empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
// Load translation files required by the page
$langs->loadLangs(array('compta', 'banks', 'bills'));
@@ -52,11 +54,13 @@ $search_status = GETPOST('search_status', 'int');
$search_day_lim = GETPOST('search_day_lim', 'int');
$search_month_lim = GETPOST('search_month_lim', 'int');
$search_year_lim = GETPOST('search_year_lim', 'int');
+$search_project_ref = GETPOST('search_project_ref', 'alpha');
+$search_project = GETPOST('search_project', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
@@ -88,11 +92,13 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
$search_label = "";
$search_amount = "";
$search_status = '';
- $search_typeid = "";
+ $search_typeid = "";
$year = "";
$search_day_lim = '';
$search_year_lim = '';
$search_month_lim = '';
+ $search_project_ref = '';
+ $search_project = '';
$toselect = '';
$search_array_options = array();
}
@@ -106,21 +112,25 @@ $form = new Form($db);
$formother = new FormOther($db);
$formsocialcontrib = new FormSocialContrib($db);
$chargesociale_static = new ChargeSociales($db);
+if (!empty($conf->projet->enabled)) $projectstatic = new Project($db);
llxHeader('', $langs->trans("SocialContributions"));
$sql = "SELECT cs.rowid as id, cs.fk_type as type, ";
$sql .= " cs.amount, cs.date_ech, cs.libelle as label, cs.paye, cs.periode,";
+if (!empty($conf->projet->enabled)) $sql .= " p.rowid as project_id, p.ref as project_ref, p.title as project_label,";
$sql .= " c.libelle as type_label,";
$sql .= " SUM(pc.amount) as alreadypayed";
$sql .= " FROM ".MAIN_DB_PREFIX."c_chargesociales as c,";
$sql .= " ".MAIN_DB_PREFIX."chargesociales as cs";
+if (!empty($conf->projet->enabled)) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet as p ON p.rowid = cs.fk_projet";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiementcharge as pc ON pc.fk_charge = cs.rowid";
$sql .= " WHERE cs.fk_type = c.id";
$sql .= " AND cs.entity = ".$conf->entity;
// Search criteria
if ($search_ref) $sql .= " AND cs.rowid=".$db->escape($search_ref);
if ($search_label) $sql .= natural_search("cs.libelle", $search_label);
+if (!empty($conf->projet->enabled)) if ($search_project_ref != '') $sql .= natural_search("p.ref", $search_project_ref);
if ($search_amount) $sql .= natural_search("cs.amount", $search_amount, 1);
if ($search_status != '' && $search_status >= 0) $sql .= " AND cs.paye = ".$db->escape($search_status);
$sql .= dolSqlDateFilter("cs.periode", $search_day_lim, $search_month_lim, $search_year_lim);
@@ -163,6 +173,7 @@ if ($resql)
if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit);
if ($search_ref) $param .= '&search_ref='.urlencode($search_ref);
if ($search_label) $param .= '&search_label='.urlencode($search_label);
+ if ($search_project_ref >= 0) $param .= "&search_project_ref=".urlencode($search_project_ref);
if ($search_amount) $param .= '&search_amount='.urlencode($search_amount);
if ($search_typeid) $param .= '&search_typeid='.urlencode($search_typeid);
if ($search_status != '' && $search_status != '-1') $param .= '&search_status='.urlencode($search_status);
@@ -217,6 +228,8 @@ if ($resql)
print '';
$formsocialcontrib->select_type_socialcontrib($search_typeid, 'search_typeid', 1, 0, 0, 'maxwidth100onsmartphone');
print ' ';
+ // Ref Project
+ if (!empty($conf->projet->enabled)) print ' ';
// Date
print ' ';
// Period end date
@@ -245,6 +258,7 @@ if ($resql)
print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "id", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Label", $_SERVER["PHP_SELF"], "cs.libelle", "", $param, 'class="left"', $sortfield, $sortorder);
print_liste_field_titre("Type", $_SERVER["PHP_SELF"], "type", "", $param, 'class="left"', $sortfield, $sortorder);
+ if (!empty($conf->projet->enabled)) print_liste_field_titre('ProjectRef', $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder);
print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "cs.date_ech", "", $param, 'align="center"', $sortfield, $sortorder);
print_liste_field_titre("PeriodEndDate", $_SERVER["PHP_SELF"], "periode", "", $param, 'align="center"', $sortfield, $sortorder);
print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "cs.amount", "", $param, 'class="right"', $sortfield, $sortorder);
@@ -262,6 +276,11 @@ if ($resql)
$chargesociale_static->ref = $obj->id;
$chargesociale_static->label = $obj->label;
$chargesociale_static->type_label = $obj->type_label;
+ if (!empty($conf->projet->enabled)) {
+ $projectstatic->id = $obj->project_id;
+ $projectstatic->ref = $obj->project_ref;
+ $projectstatic->title = $obj->project_label;
+ }
print '';
@@ -277,6 +296,17 @@ if ($resql)
print "".$obj->type_label." \n";
if (!$i) $totalarray['nbfield']++;
+ // Project Ref
+ if (!empty($conf->projet->enabled)) {
+ print '';
+ if ($obj->project_id > 0)
+ {
+ print $projectstatic->getNomUrl(1);
+ }
+ print ' ';
+ if (!$i) $totalarray['nbfield']++;
+ }
+
// Date
print ''.dol_print_date($db->jdate($obj->date_ech), 'day').' ';
if (!$i) $totalarray['nbfield']++;
diff --git a/htdocs/compta/sociales/payments.php b/htdocs/compta/sociales/payments.php
index f89171a082d..5cfa5df06ed 100644
--- a/htdocs/compta/sociales/payments.php
+++ b/htdocs/compta/sociales/payments.php
@@ -48,7 +48,7 @@ if (!$year && $mode != 'sconly') { $year = date("Y", time()); }
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/compta/stats/cabyprodserv.php b/htdocs/compta/stats/cabyprodserv.php
index 138bff4a525..a1bdfb6678d 100644
--- a/htdocs/compta/stats/cabyprodserv.php
+++ b/htdocs/compta/stats/cabyprodserv.php
@@ -31,23 +31,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
// Load translation files required by the page
-$langs->loadLangs(array("products","categories","errors",'accountancy'));
+$langs->loadLangs(array("products", "categories", "errors", 'accountancy'));
// Security pack (data & check)
$socid = GETPOST('socid', 'int');
if ($user->socid > 0) $socid = $user->socid;
-if (! empty($conf->comptabilite->enabled)) $result=restrictedArea($user, 'compta', '', '', 'resultat');
-if (! empty($conf->accounting->enabled)) $result=restrictedArea($user, 'accounting', '', '', 'comptarapport');
+if (!empty($conf->comptabilite->enabled)) $result = restrictedArea($user, 'compta', '', '', 'resultat');
+if (!empty($conf->accounting->enabled)) $result = restrictedArea($user, 'accounting', '', '', 'comptarapport');
// Define modecompta ('CREANCES-DETTES' or 'RECETTES-DEPENSES')
$modecompta = $conf->global->ACCOUNTING_MODE;
-if (GETPOST("modecompta")) $modecompta=GETPOST("modecompta");
+if (GETPOST("modecompta")) $modecompta = GETPOST("modecompta");
-$sortorder=isset($_GET["sortorder"])?$_GET["sortorder"]:$_POST["sortorder"];
-$sortfield=isset($_GET["sortfield"])?$_GET["sortfield"]:$_POST["sortfield"];
-if (! $sortorder) $sortorder="asc";
-if (! $sortfield) $sortfield="ref";
+$sortorder = isset($_GET["sortorder"]) ? $_GET["sortorder"] : $_POST["sortorder"];
+$sortfield = isset($_GET["sortfield"]) ? $_GET["sortfield"] : $_POST["sortfield"];
+if (!$sortorder) $sortorder = "asc";
+if (!$sortfield) $sortfield = "ref";
// Category
$selected_cat = (int) GETPOST('search_categ', 'int');
@@ -58,11 +58,11 @@ if (GETPOST('subcat', 'alpha') === 'yes') {
}
// product/service
$selected_type = GETPOST('search_type', 'int');
-if ($selected_type =='') $selected_type = -1;
+if ($selected_type == '') $selected_type = -1;
// Date range
-$year=GETPOST("year");
-$month=GETPOST("month");
+$year = GETPOST("year");
+$month = GETPOST("month");
$date_startyear = GETPOST("date_startyear");
$date_startmonth = GETPOST("date_startmonth");
$date_startday = GETPOST("date_startday");
@@ -79,76 +79,78 @@ if (empty($year))
$month_current = strftime("%m", dol_now());
$year_start = $year;
}
-$date_start=dol_mktime(0, 0, 0, GETPOST("date_startmonth"), GETPOST("date_startday"), GETPOST("date_startyear"));
-$date_end=dol_mktime(23, 59, 59, GETPOST("date_endmonth"), GETPOST("date_endday"), GETPOST("date_endyear"));
+$date_start = dol_mktime(0, 0, 0, GETPOST("date_startmonth"), GETPOST("date_startday"), GETPOST("date_startyear"));
+$date_end = dol_mktime(23, 59, 59, GETPOST("date_endmonth"), GETPOST("date_endday"), GETPOST("date_endyear"));
// Quarter
if (empty($date_start) || empty($date_end)) // We define date_start and date_end
{
- $q=GETPOST("q", "int");
+ $q = GETPOST("q", "int");
if (empty($q))
{
// We define date_start and date_end
- $month_start=GETPOST("month")?GETPOST("month"):($conf->global->SOCIETE_FISCAL_MONTH_START?($conf->global->SOCIETE_FISCAL_MONTH_START):1);
- $year_end=$year_start;
- $month_end=$month_start;
- if (! GETPOST("month")) // If month not forced
+ $month_start = GETPOST("month") ?GETPOST("month") : ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1);
+ $year_end = $year_start;
+ $month_end = $month_start;
+ if (!GETPOST("month")) // If month not forced
{
- if (! GETPOST('year') && $month_start > $month_current)
+ if (!GETPOST('year') && $month_start > $month_current)
{
$year_start--;
$year_end--;
}
- $month_end=$month_start-1;
- if ($month_end < 1) $month_end=12;
+ $month_end = $month_start - 1;
+ if ($month_end < 1) $month_end = 12;
else $year_end++;
}
- $date_start=dol_get_first_day($year_start, $month_start, false); $date_end=dol_get_last_day($year_end, $month_end, false);
+ $date_start = dol_get_first_day($year_start, $month_start, false); $date_end = dol_get_last_day($year_end, $month_end, false);
}
else
{
- if ($q==1) { $date_start=dol_get_first_day($year_start, 1, false); $date_end=dol_get_last_day($year_start, 3, false); }
- if ($q==2) { $date_start=dol_get_first_day($year_start, 4, false); $date_end=dol_get_last_day($year_start, 6, false); }
- if ($q==3) { $date_start=dol_get_first_day($year_start, 7, false); $date_end=dol_get_last_day($year_start, 9, false); }
- if ($q==4) { $date_start=dol_get_first_day($year_start, 10, false); $date_end=dol_get_last_day($year_start, 12, false); }
+ if ($q == 1) { $date_start = dol_get_first_day($year_start, 1, false); $date_end = dol_get_last_day($year_start, 3, false); }
+ if ($q == 2) { $date_start = dol_get_first_day($year_start, 4, false); $date_end = dol_get_last_day($year_start, 6, false); }
+ if ($q == 3) { $date_start = dol_get_first_day($year_start, 7, false); $date_end = dol_get_last_day($year_start, 9, false); }
+ if ($q == 4) { $date_start = dol_get_first_day($year_start, 10, false); $date_end = dol_get_last_day($year_start, 12, false); }
}
} else {
// TODO We define q
}
// $date_start and $date_end are defined. We force $year_start and $nbofyear
-$tmps=dol_getdate($date_start);
+$tmps = dol_getdate($date_start);
$year_start = $tmps['year'];
-$tmpe=dol_getdate($date_end);
+$tmpe = dol_getdate($date_end);
$year_end = $tmpe['year'];
$nbofyear = ($year_end - $year_start) + 1;
-$commonparams=array();
-$commonparams['modecompta']=$modecompta;
-$commonparams['sortorder'] = $sortorder;
-$commonparams['sortfield'] = $sortfield;
+$commonparams = array();
+if (!empty($modecompta)) $commonparams['modecompta'] = $modecompta;
+if (!empty($sortorder)) $commonparams['sortorder'] = $sortorder;
+if (!empty($sortfield)) $commonparams['sortfield'] = $sortfield;
$headerparams = array();
-$headerparams['date_startyear'] = $date_startyear;
-$headerparams['date_startmonth'] = $date_startmonth;
-$headerparams['date_startday'] = $date_startday;
-$headerparams['date_endyear'] = $date_endyear;
-$headerparams['date_endmonth'] = $date_endmonth;
-$headerparams['date_endday'] = $date_endday;
+if (!empty($date_startyear)) $headerparams['date_startyear'] = $date_startyear;
+if (!empty($date_startmonth)) $headerparams['date_startmonth'] = $date_startmonth;
+if (!empty($date_startday)) $headerparams['date_startday'] = $date_startday;
+if (!empty($date_endyear)) $headerparams['date_endyear'] = $date_endyear;
+if (!empty($date_endmonth)) $headerparams['date_endmonth'] = $date_endmonth;
+if (!empty($date_endday)) $headerparams['date_endday'] = $date_endday;
+if (!empty($year)) $headerparams['year'] = $year;
+if (!empty($month)) $headerparams['month'] = $month;
$headerparams['q'] = $q;
$tableparams = array();
-$tableparams['search_categ'] = $selected_cat;
-$tableparams['search_soc'] = $selected_soc;
-$tableparams['search_type'] = $selected_type;
-$tableparams['subcat'] = ($subcat === true)?'yes':'';
+if (!empty($selected_cat)) $tableparams['search_categ'] = $selected_cat;
+if (!empty($selected_soc)) $tableparams['search_soc'] = $selected_soc;
+if (!empty($selected_type)) $tableparams['search_type'] = $selected_type;
+$tableparams['subcat'] = ($subcat === true) ? 'yes' : '';
// Adding common parameters
$allparams = array_merge($commonparams, $headerparams, $tableparams);
$headerparams = array_merge($commonparams, $headerparams);
$tableparams = array_merge($commonparams, $tableparams);
-foreach($allparams as $key => $value) {
- $paramslink .= '&' . $key . '=' . $value;
+foreach ($allparams as $key => $value) {
+ $paramslink .= '&'.$key.'='.$value;
}
@@ -158,127 +160,127 @@ foreach($allparams as $key => $value) {
llxHeader();
-$form=new Form($db);
+$form = new Form($db);
$formother = new FormOther($db);
// TODO Report from bookkeeping not yet available, so we switch on report on business events
-if ($modecompta=="BOOKKEEPING") $modecompta="CREANCES-DETTES";
-if ($modecompta=="BOOKKEEPINGCOLLECTED") $modecompta="RECETTES-DEPENSES";
+if ($modecompta == "BOOKKEEPING") $modecompta = "CREANCES-DETTES";
+if ($modecompta == "BOOKKEEPINGCOLLECTED") $modecompta = "RECETTES-DEPENSES";
// Show report header
-if ($modecompta=="CREANCES-DETTES") {
- $name=$langs->trans("Turnover").', '.$langs->trans("ByProductsAndServices");
- $calcmode=$langs->trans("CalcModeDebt");
+if ($modecompta == "CREANCES-DETTES") {
+ $name = $langs->trans("Turnover").', '.$langs->trans("ByProductsAndServices");
+ $calcmode = $langs->trans("CalcModeDebt");
//$calcmode.=' ('.$langs->trans("SeeReportInInputOutputMode",'',' ').')';
- $description=$langs->trans("RulesCADue");
- if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
- $description.= $langs->trans("DepositsAreNotIncluded");
+ $description = $langs->trans("RulesCADue");
+ if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
+ $description .= $langs->trans("DepositsAreNotIncluded");
} else {
- $description.= $langs->trans("DepositsAreIncluded");
+ $description .= $langs->trans("DepositsAreIncluded");
}
- $builddate=dol_now();
+ $builddate = dol_now();
}
-elseif ($modecompta=="RECETTES-DEPENSES")
+elseif ($modecompta == "RECETTES-DEPENSES")
{
- $name=$langs->trans("TurnoverCollected").', '.$langs->trans("ByProductsAndServices");
- $calcmode=$langs->trans("CalcModeEngagement");
+ $name = $langs->trans("TurnoverCollected").', '.$langs->trans("ByProductsAndServices");
+ $calcmode = $langs->trans("CalcModeEngagement");
//$calcmode.=' ('.$langs->trans("SeeReportInDueDebtMode",'',' ').')';
- $description=$langs->trans("RulesCAIn");
- $description.= $langs->trans("DepositsAreIncluded");
+ $description = $langs->trans("RulesCAIn");
+ $description .= $langs->trans("DepositsAreIncluded");
- $builddate=dol_now();
+ $builddate = dol_now();
}
-elseif ($modecompta=="BOOKKEEPING")
+elseif ($modecompta == "BOOKKEEPING")
{
}
-elseif ($modecompta=="BOOKKEEPINGCOLLECTED")
+elseif ($modecompta == "BOOKKEEPINGCOLLECTED")
{
}
-$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
-if ($date_end == dol_time_plus_duree($date_start, 1, 'y') - 1) $periodlink=''.img_previous().' '.img_next().' ';
+$period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
+if ($date_end == dol_time_plus_duree($date_start, 1, 'y') - 1) $periodlink = ''.img_previous().' '.img_next().' ';
else $periodlink = '';
report_header($name, $namelink, $period, $periodlink, $description, $builddate, $exportlink, $tableparams, $calcmode);
-if (! empty($conf->accounting->enabled) && $modecompta != 'BOOKKEEPING')
+if (!empty($conf->accounting->enabled) && $modecompta != 'BOOKKEEPING')
{
print info_admin($langs->trans("WarningReportNotReliable"), 0, 0, 1);
}
-$name=array();
+$name = array();
// SQL request
-$catotal=0;
-$catotal_ht=0;
-$qtytotal=0;
+$catotal = 0;
+$catotal_ht = 0;
+$qtytotal = 0;
if ($modecompta == 'CREANCES-DETTES')
{
$sql = "SELECT DISTINCT p.rowid as rowid, p.ref as ref, p.label as label, p.fk_product_type as product_type,";
- $sql.= " SUM(l.total_ht) as amount, SUM(l.total_ttc) as amount_ttc,";
- $sql.= " SUM(CASE WHEN f.type = 2 THEN -l.qty ELSE l.qty END) as qty";
- $sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
- if($selected_soc > 0) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as soc ON (soc.rowid = f.fk_soc)";
- $sql.= ",".MAIN_DB_PREFIX."facturedet as l";
- $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON l.fk_product = p.rowid";
+ $sql .= " SUM(l.total_ht) as amount, SUM(l.total_ttc) as amount_ttc,";
+ $sql .= " SUM(CASE WHEN f.type = 2 THEN -l.qty ELSE l.qty END) as qty";
+ $sql .= " FROM ".MAIN_DB_PREFIX."facture as f";
+ if ($selected_soc > 0) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as soc ON (soc.rowid = f.fk_soc)";
+ $sql .= ",".MAIN_DB_PREFIX."facturedet as l";
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON l.fk_product = p.rowid";
if ($selected_cat === -2) // Without any category
{
- $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product";
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product";
}
elseif ($selected_cat) // Into a specific category
{
- $sql.= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_product as cp";
+ $sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_product as cp";
}
- $sql.= " WHERE l.fk_facture = f.rowid";
- $sql.= " AND f.fk_statut in (1,2)";
- if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
- $sql.= " AND f.type IN (0,1,2,5)";
+ $sql .= " WHERE l.fk_facture = f.rowid";
+ $sql .= " AND f.fk_statut in (1,2)";
+ if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
+ $sql .= " AND f.type IN (0,1,2,5)";
} else {
- $sql.= " AND f.type IN (0,1,2,3,5)";
+ $sql .= " AND f.type IN (0,1,2,3,5)";
}
if ($date_start && $date_end) {
- $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
+ $sql .= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
}
- if ($selected_type >=0)
+ if ($selected_type >= 0)
{
- $sql.= " AND l.product_type = ".$selected_type;
+ $sql .= " AND l.product_type = ".$selected_type;
}
if ($selected_cat === -2) // Without any category
{
- $sql.=" AND cp.fk_product is null";
+ $sql .= " AND cp.fk_product is null";
}
elseif ($selected_cat) { // Into a specific category
- $sql.= " AND (c.rowid = ".$selected_cat;
- if ($subcat) $sql.=" OR c.fk_parent = " . $selected_cat;
- $sql.= ")";
- $sql.= " AND cp.fk_categorie = c.rowid AND cp.fk_product = p.rowid";
+ $sql .= " AND (c.rowid = ".$selected_cat;
+ if ($subcat) $sql .= " OR c.fk_parent = ".$selected_cat;
+ $sql .= ")";
+ $sql .= " AND cp.fk_categorie = c.rowid AND cp.fk_product = p.rowid";
}
- if($selected_soc > 0) $sql .= " AND soc.rowid=".$selected_soc;
- $sql.= " AND f.entity IN (".getEntity('invoice').")";
- $sql.= " GROUP BY p.rowid, p.ref, p.label, p.fk_product_type";
- $sql.= $db->order($sortfield, $sortorder);
+ if ($selected_soc > 0) $sql .= " AND soc.rowid=".$selected_soc;
+ $sql .= " AND f.entity IN (".getEntity('invoice').")";
+ $sql .= " GROUP BY p.rowid, p.ref, p.label, p.fk_product_type";
+ $sql .= $db->order($sortfield, $sortorder);
dol_syslog("cabyprodserv", LOG_DEBUG);
$result = $db->query($sql);
if ($result) {
$num = $db->num_rows($result);
- $i=0;
+ $i = 0;
while ($i < $num) {
$obj = $db->fetch_object($result);
$amount_ht[$obj->rowid] = $obj->amount;
$amount[$obj->rowid] = $obj->amount_ttc;
$qty[$obj->rowid] = $obj->qty;
- $name[$obj->rowid] = $obj->ref . ' - ' . $obj->label;
+ $name[$obj->rowid] = $obj->ref.' - '.$obj->label;
$type[$obj->rowid] = $obj->product_type;
- $catotal_ht+=$obj->amount;
- $catotal+=$obj->amount_ttc;
- $qtytotal+=$obj->qty;
+ $catotal_ht += $obj->amount;
+ $catotal += $obj->amount_ttc;
+ $qtytotal += $obj->qty;
$i++;
}
} else {
@@ -286,25 +288,25 @@ if ($modecompta == 'CREANCES-DETTES')
}
// Show Array
- $i=0;
+ $i = 0;
print '';
// Extra parameters management
- foreach($headerparams as $key => $value)
+ foreach ($headerparams as $key => $value)
{
print ' ';
}
- $moreforfilter='';
+ $moreforfilter = '';
print '';
- print '
'."\n";
+ print ''."\n";
// Category filter
print '';
print '';
- print $langs->trans("Category") . ': ' . $formother->select_categories(Categorie::TYPE_PRODUCT, $selected_cat, 'search_categ', true);
+ print $langs->trans("Category").': '.$formother->select_categories(Categorie::TYPE_PRODUCT, $selected_cat, 'search_categ', true);
print ' ';
- print $langs->trans("SubCats") . '? ';
+ print $langs->trans("SubCats").'? ';
print ' ';
// type filter (produit/service)
print ' ';
- print $langs->trans("Type"). ': ';
- $form->select_type_of_lines(isset($selected_type)?$selected_type:-1, 'search_type', 1, 1, 1);
+ print $langs->trans("Type").': ';
+ $form->select_type_of_lines(isset($selected_type) ? $selected_type : -1, 'search_type', 1, 1, 1);
//select thirdparty
print '';
- print $langs->trans("ThirdParty") . ': ' . $form->select_thirdparty_list($selected_soc, 'search_soc', '', 1);
+ print $langs->trans("ThirdParty").': '.$form->select_thirdparty_list($selected_soc, 'search_soc', '', 1);
print ' ';
print '';
@@ -389,16 +391,16 @@ if ($modecompta == 'CREANCES-DETTES')
print " \n";
if (count($name)) {
- foreach($name as $key=>$value) {
+ foreach ($name as $key=>$value) {
print '';
// Product
print "";
- $fullname=$name[$key];
+ $fullname = $name[$key];
if ($key > 0) {
- $linkname=''.img_object($langs->trans("ShowProduct"), $type[$key]==0?'product':'service').' '.$fullname.' ';
+ $linkname = ''.img_object($langs->trans("ShowProduct"), $type[$key] == 0 ? 'product' : 'service').' '.$fullname.' ';
} else {
- $linkname=$langs->trans("PaymentsNotLinkedToProduct");
+ $linkname = $langs->trans("PaymentsNotLinkedToProduct");
}
print $linkname;
print " \n";
@@ -463,7 +465,7 @@ if ($modecompta == 'CREANCES-DETTES')
// "Calculation of part of each product for accountancy in this mode is not possible. When a partial payment (for example 5 euros) is done on an
// invoice with 2 product (product A for 10 euros and product B for 20 euros), what is part of paiment for product A and part of paiment for product B ?
// Because there is no way to know this, this report is not relevant.
- print ' '.$langs->trans("TurnoverPerProductInCommitmentAccountingNotRelevant") . ' ';
+ print ' '.$langs->trans("TurnoverPerProductInCommitmentAccountingNotRelevant").' ';
}
// End of page
diff --git a/htdocs/compta/stats/index.php b/htdocs/compta/stats/index.php
index 684ef337fcd..9be5607b62d 100644
--- a/htdocs/compta/stats/index.php
+++ b/htdocs/compta/stats/index.php
@@ -407,7 +407,7 @@ for ($mois = 1 + $nb_mois_decalage; $mois <= 12 + $nb_mois_decalage; $mois++)
print "".dol_print_date(dol_mktime(12,0,0,$mois,1,2000),"%B")." ";
for ($annee = $year_start ; $annee <= $year_end ; $annee++)
{
- $casenow = dol_print_date(mktime(),"%Y-%m");
+ $casenow = dol_print_date(dol_now(),"%Y-%m");
$case = dol_print_date(dol_mktime(1,1,1,$mois,1,$annee),"%Y-%m");
$caseprev = dol_print_date(dol_mktime(1,1,1,$mois,1,$annee-1),"%Y-%m");
diff --git a/htdocs/compta/tva/card.php b/htdocs/compta/tva/card.php
index 5a64728029a..86fb598fb8b 100644
--- a/htdocs/compta/tva/card.php
+++ b/htdocs/compta/tva/card.php
@@ -279,7 +279,7 @@ if ($action == 'create')
if (! empty($conf->banque->enabled))
{
print ' '.$langs->trans("BankAccount").' ';
- $form->select_comptes($_POST["accountid"], "accountid", 0, "courant=1", 1); // Affiche liste des comptes courant
+ $form->select_comptes(GETPOST("accountid", 'int'), "accountid", 0, "courant=1", 2); // List of bank account available
print ' ';
}
diff --git a/htdocs/compta/tva/document.php b/htdocs/compta/tva/document.php
index 7f860491a8d..037e6baa5c3 100644
--- a/htdocs/compta/tva/document.php
+++ b/htdocs/compta/tva/document.php
@@ -55,7 +55,7 @@ $result = restrictedArea($user, 'tax', '', 'vat', 'charges');
// Get parameters
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) {
$page = 0;
}
@@ -70,8 +70,8 @@ if (!$sortfield) $sortfield = "name";
$object = new Tva($db);
if ($id > 0) $object->fetch($id);
-$upload_dir = $conf->tax->dir_output.'/'.dol_sanitizeFileName($object->ref);
-$modulepart = 'tax';
+$upload_dir = $conf->tax->dir_output.'/vat/'.dol_sanitizeFileName($object->ref);
+$modulepart = 'tax-vat';
/*
@@ -144,7 +144,6 @@ if ($object->id)
dol_fiche_end();
- $modulepart = 'tax';
$permission = $user->rights->tax->charges->creer;
$permtoedit = $user->rights->fournisseur->facture->creer;
$param = '&id='.$object->id;
diff --git a/htdocs/compta/tva/list.php b/htdocs/compta/tva/list.php
index 35492d19821..35c5dc2c052 100644
--- a/htdocs/compta/tva/list.php
+++ b/htdocs/compta/tva/list.php
@@ -53,7 +53,7 @@ $year = GETPOST("year", "int");
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/contact/agenda.php b/htdocs/contact/agenda.php
index 24d49040c13..d07b84e1e36 100644
--- a/htdocs/contact/agenda.php
+++ b/htdocs/contact/agenda.php
@@ -90,7 +90,7 @@ $result = restrictedArea($user, 'contact', $id, 'socpeople&societe', '', '', 'ro
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php
index f1491d73bf4..73862b65b2e 100644
--- a/htdocs/contact/card.php
+++ b/htdocs/contact/card.php
@@ -218,6 +218,8 @@ if (empty($reshook))
$object->priv = GETPOST("priv", 'int');
$object->note_public = GETPOST("note_public", 'none');
$object->note_private = GETPOST("note_private", 'none');
+ $object->roles = GETPOST("roles", 'array');
+
$object->statut = 1; //Defult status to Actif
// Note: Correct date should be completed with location to have exact GM time of birth.
@@ -552,6 +554,8 @@ else
setEventMessages($object->error, $object->errors, 'errors');
}
+ $object->fetchRoles();
+
// Show tabs
$head = contact_prepare_head($object);
@@ -578,7 +582,7 @@ else
$object->country = $tmparray['label'];
}
- $title = $addcontact = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("AddContact") : $langs->trans("AddContactAddress"));
+ $title = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("AddContact") : $langs->trans("AddContactAddress"));
$linkback = '';
print load_fiche_titre($title, $linkback, 'address');
@@ -652,7 +656,7 @@ else
// Civility
print ''.$langs->trans("UserTitle").' ';
- print $formcompany->select_civility(GETPOSTISSET("civility_code") ?GETPOST("civility_code", 'alpha') : $object->civility_code, 'civility_code');
+ print $formcompany->select_civility(GETPOSTISSET("civility_code") ? GETPOST("civility_code", 'alpha') : $object->civility_code, 'civility_code');
print ' ';
print ''.$langs->trans("PostOrFunction").' ';
@@ -681,13 +685,13 @@ else
if (($objsoc->typent_code == 'TE_PRIVATE' || !empty($conf->global->CONTACT_USE_COMPANY_ADDRESS)) && dol_strlen(trim($object->zip)) == 0) $object->zip = $objsoc->zip; // Predefined with third party
if (($objsoc->typent_code == 'TE_PRIVATE' || !empty($conf->global->CONTACT_USE_COMPANY_ADDRESS)) && dol_strlen(trim($object->town)) == 0) $object->town = $objsoc->town; // Predefined with third party
print ''.$langs->trans("Zip").' / '.$langs->trans("Town").' ';
- print $formcompany->select_ziptown((GETPOST("zipcode", 'alpha') ?GETPOST("zipcode", 'alpha') : $object->zip), 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6).' ';
- print $formcompany->select_ziptown((GETPOST("town", 'alpha') ?GETPOST("town", 'alpha') : $object->town), 'town', array('zipcode', 'selectcountry_id', 'state_id'));
+ print $formcompany->select_ziptown((GETPOST("zipcode", 'alpha') ? GETPOST("zipcode", 'alpha') : $object->zip), 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6).' ';
+ print $formcompany->select_ziptown((GETPOST("town", 'alpha') ? GETPOST("town", 'alpha') : $object->town), 'town', array('zipcode', 'selectcountry_id', 'state_id'));
print ' ';
// Country
print ''.$langs->trans("Country").' ';
- print $form->select_country((GETPOST("country_id", 'alpha') ?GETPOST("country_id", 'alpha') : $object->country_id), 'country_id');
+ print $form->select_country((GETPOST("country_id", 'alpha') ? GETPOST("country_id", 'alpha') : $object->country_id), 'country_id');
if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
print ' ';
@@ -705,7 +709,7 @@ else
if ($object->country_id)
{
- print $formcompany->select_state(GETPOST("state_id", 'alpha') ?GETPOST("state_id", 'alpha') : $object->state_id, $object->country_code, 'state_id');
+ print $formcompany->select_state(GETPOST("state_id", 'alpha') ? GETPOST("state_id", 'alpha') : $object->state_id, $object->country_code, 'state_id');
}
else
{
@@ -719,23 +723,23 @@ else
// Phone / Fax
print ''.img_picto('', 'object_phoning').' '.$form->editfieldkey('PhonePro', 'phone_pro', '', $object, 0).' ';
- print ' ';
+ print ' ';
if ($conf->browser->layout == 'phone') print '';
print ''.img_picto('', 'object_phoning').' '.$form->editfieldkey('PhonePerso', 'phone_perso', '', $object, 0).' ';
- print ' ';
+ print ' ';
print ''.img_picto('', 'object_phoning_mobile').' '.$form->editfieldkey('PhoneMobile', 'phone_mobile', '', $object, 0).' ';
- print ' ';
+ print ' ';
if ($conf->browser->layout == 'phone') print '';
print ''.img_picto('', 'object_phoning_fax').' '.$form->editfieldkey('Fax', 'fax', '', $object, 0).' ';
- print ' ';
+ print ' ';
print ' ';
if (($objsoc->typent_code == 'TE_PRIVATE' || !empty($conf->global->CONTACT_USE_COMPANY_ADDRESS)) && dol_strlen(trim($object->email)) == 0) $object->email = $objsoc->email; // Predefined with third party
// Email
print ''.img_picto('', 'object_email').' '.$form->editfieldkey('EMail', 'email', '', $object, 0, 'string', '').' ';
- print ' ';
+ print ' ';
print ' ';
if (!empty($conf->mailing->enabled))
@@ -755,7 +759,7 @@ else
print '';
print ''.$langs->trans("No_Email").' ';
- print ''.$form->selectyesno('no_email', (GETPOSTISSET("no_email") ?GETPOST("no_email", 'alpha') : $noemail), 1).' ';
+ print ''.$form->selectyesno('no_email', (GETPOSTISSET("no_email") ? GETPOST("no_email", 'alpha') : $noemail), 1).' ';
print ' ';
}
print '';
diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php
index b1eb83eebdb..8d880226ff4 100644
--- a/htdocs/contact/class/contact.class.php
+++ b/htdocs/contact/class/contact.class.php
@@ -64,7 +64,7 @@ class Contact extends CommonObject
/**
* @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
*/
- public $fields=array(
+ public $fields = array(
'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>15),
'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20),
@@ -314,9 +314,9 @@ class Contact extends CommonObject
// Clean parameters
$this->lastname = $this->lastname ?trim($this->lastname) : trim($this->name);
$this->firstname = trim($this->firstname);
- if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname = ucwords($this->lastname);
+ if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname = ucwords(strtolower($this->lastname));
if (!empty($conf->global->MAIN_ALL_TO_UPPER)) $this->lastname = strtoupper($this->lastname);
- if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname = ucwords($this->firstname);
+ if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname = ucwords(strtolower($this->firstname));
if (empty($this->socid)) $this->socid = 0;
if (empty($this->priv)) $this->priv = 0;
if (empty($this->statut)) $this->statut = 0; // This is to convert '' into '0' to avoid bad sql request
@@ -358,7 +358,7 @@ class Contact extends CommonObject
if (!$error)
{
- $result = $this->update($this->id, $user, 1, 'add');
+ $result = $this->update($this->id, $user, 1, 'add'); // This include updateRoles(), ...
if ($result < 0)
{
$error++;
@@ -427,9 +427,9 @@ class Contact extends CommonObject
$this->entity = ((isset($this->entity) && is_numeric($this->entity)) ? $this->entity : $conf->entity);
// Clean parameters
- if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname = ucwords($this->lastname);
+ if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname = ucwords(strtolower($this->lastname));
if (!empty($conf->global->MAIN_ALL_TO_UPPER)) $this->lastname = strtoupper($this->lastname);
- if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname = ucwords($this->firstname);
+ if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname = ucwords(strtolower($this->firstname));
$this->lastname = trim($this->lastname) ?trim($this->lastname) : trim($this->lastname);
$this->firstname = trim($this->firstname);
@@ -802,20 +802,19 @@ class Contact extends CommonObject
/**
- * Load object contact
+ * Load object contact.
*
- * @param int $id id du contact
- * @param User $user Utilisateur (abonnes aux alertes) qui veut les alertes de ce contact
- * @param string $ref_ext External reference, not given by Dolibarr
- * @param string $email Email
- * @return int -1 if KO, 0 if OK but not found, 1 if OK
+ * @param int $id Id of contact
+ * @param User $user Load also alerts of this user (subscribing to alerts) that want alerts about this contact
+ * @param string $ref_ext External reference, not given by Dolibarr
+ * @param string $email Email
+ * @param int $loadalsoroles Load also roles
+ * @return int >0 if OK, <0 if KO or if two records found for same ref or idprof, 0 if not found.
*/
- public function fetch($id, $user = null, $ref_ext = '', $email = '')
+ public function fetch($id, $user = null, $ref_ext = '', $email = '', $loadalsoroles = 0)
{
global $langs;
- $langs->load("dict");
-
dol_syslog(get_class($this)."::fetch id=".$id." ref_ext=".$ref_ext." email=".$email, LOG_DEBUG);
if (empty($id) && empty($ref_ext) && empty($email))
@@ -824,7 +823,7 @@ class Contact extends CommonObject
return -1;
}
- $langs->load("companies");
+ $langs->loadLangs(array("dict", "companies"));
$sql = "SELECT c.rowid, c.entity, c.fk_soc, c.ref_ext, c.civility as civility_code, c.lastname, c.firstname,";
$sql .= " c.address, c.statut, c.zip, c.town,";
@@ -861,7 +860,15 @@ class Contact extends CommonObject
$resql = $this->db->query($sql);
if ($resql)
{
- if ($this->db->num_rows($resql))
+ $num = $this->db->num_rows($resql);
+ if ($num > 1)
+ {
+ $this->error = 'Fetch found several records. Rename one of contact to avoid duplicate.';
+ dol_syslog($this->error, LOG_ERR);
+
+ return 2;
+ }
+ elseif ($num) // $num = 1
{
$obj = $this->db->fetch_object($resql);
@@ -942,7 +949,11 @@ class Contact extends CommonObject
return -1;
}
- // Charge alertes du user
+ // Retreive all extrafield
+ // fetch optionals attributes and labels
+ $this->fetch_optionals();
+
+ // Load also alerts of this user
if ($user)
{
$sql = "SELECT fk_user";
@@ -967,13 +978,12 @@ class Contact extends CommonObject
}
}
- // Retreive all extrafield
- // fetch optionals attributes and labels
- $this->fetch_optionals();
-
- $resultRole = $this->fetchRoles();
- if ($resultRole < 0) {
- return $resultRole;
+ // Load also roles of this address
+ if ($loadalsoroles) {
+ $resultRole = $this->fetchRoles();
+ if ($resultRole < 0) {
+ return $resultRole;
+ }
}
return 1;
@@ -1007,7 +1017,7 @@ class Contact extends CommonObject
{
$this->gender = 'man';
}
- elseif(in_array($this->civility_id, array('MME','MLE')) || in_array($this->civility_code, array('MME','MLE')))
+ elseif (in_array($this->civility_id, array('MME', 'MLE')) || in_array($this->civility_code, array('MME', 'MLE')))
{
$this->gender = 'woman';
}
@@ -1276,9 +1286,16 @@ class Contact extends CommonObject
{
global $conf, $langs, $hookmanager;
- $result = '';
+ $result = ''; $label = '';
- $label = ''.$langs->trans("ShowContact").' ';
+ if (!empty($this->photo) && class_exists('Form'))
+ {
+ $label .= '';
+ $label .= Form::showphoto('contact', $this, 0, 40, 0, '', 'mini', 0); // Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip.
+ $label .= '
';
+ }
+
+ $label .= ''.$langs->trans("ShowContact").' ';
$label .= ''.$langs->trans("Name").': '.$this->getFullName($langs);
//if ($this->civility_id) $label.= '' . $langs->trans("Civility") . ': '.$this->civility_id; // TODO Translate cibilty_id code
if (!empty($this->poste)) $label .= ''.$langs->trans("Poste").': '.$this->poste;
@@ -1580,7 +1597,7 @@ class Contact extends CommonObject
}
/**
- * Fetch Role for a contact
+ * Fetch Roles for a contact
*
* @return float|int
* @throws Exception
@@ -1592,14 +1609,14 @@ class Contact extends CommonObject
$num = 0;
$sql = "SELECT tc.rowid, tc.element, tc.source, tc.code, tc.libelle, sc.rowid as contactroleid";
- $sql .= " FROM ".MAIN_DB_PREFIX."societe_contacts as sc ";
+ $sql .= " FROM ".MAIN_DB_PREFIX."societe_contacts as sc";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."c_type_contact as tc";
$sql .= " ON tc.rowid = sc.fk_c_type_contact";
$sql .= " AND sc.fk_socpeople = ".$this->id;
$sql .= " AND tc.source = 'external' AND tc.active=1";
$sql .= " AND sc.entity IN (".getEntity('societe').')';
- dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$this->roles = array();
$resql = $this->db->query($sql);
@@ -1636,6 +1653,10 @@ class Contact extends CommonObject
{
$tab = array();
+ if ($element == 'action') {
+ $element = 'agenda';
+ }
+
$sql = "SELECT sc.fk_socpeople as id, sc.fk_c_type_contact";
$sql .= " FROM ".MAIN_DB_PREFIX."c_type_contact tc";
$sql .= ", ".MAIN_DB_PREFIX."societe_contacts sc";
@@ -1644,7 +1665,7 @@ class Contact extends CommonObject
$sql .= " AND tc.element='".$element."'";
$sql .= " AND tc.active=1";
- dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql)
{
@@ -1684,7 +1705,7 @@ class Contact extends CommonObject
$sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_contacts WHERE fk_soc=".$this->socid." AND fk_socpeople=".$this->id; ;
- dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$result = $this->db->query($sql);
if (!$result) {
$this->errors[] = $this->db->lasterror().' sql='.$sql;
@@ -1704,7 +1725,7 @@ class Contact extends CommonObject
$sql .= $valRoles." , ";
$sql .= $this->id;
$sql .= ")";
- dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$result = $this->db->query($sql);
if (!$result)
diff --git a/htdocs/contact/consumption.php b/htdocs/contact/consumption.php
index 458fdae07b1..f27903f559e 100644
--- a/htdocs/contact/consumption.php
+++ b/htdocs/contact/consumption.php
@@ -45,7 +45,7 @@ $socid = $object->thirdparty->id;
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/contact/document.php b/htdocs/contact/document.php
index 8533cb13feb..0825c77a61f 100644
--- a/htdocs/contact/document.php
+++ b/htdocs/contact/document.php
@@ -57,7 +57,7 @@ $result = restrictedArea($user, 'contact', $id, 'socpeople&societe', '', '', 'ro
// Get parameters
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php
index 1d0c3839f4f..0335e203049 100644
--- a/htdocs/contact/list.php
+++ b/htdocs/contact/list.php
@@ -103,7 +103,7 @@ $view = GETPOST("view", 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
$userid = GETPOST('userid', 'int');
$begin = GETPOST('begin');
if (!$sortorder) $sortorder = "ASC";
@@ -290,7 +290,7 @@ $title = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("C
$sql = "SELECT s.rowid as socid, s.nom as name,";
$sql .= " p.rowid, p.lastname as lastname, p.statut, p.firstname, p.zip, p.town, p.poste, p.email, p.no_email,";
-$sql .= " p.socialnetworks,";
+$sql .= " p.socialnetworks, p.photo,";
$sql .= " p.phone as phone_pro, p.phone_mobile, p.phone_perso, p.fax, p.fk_pays, p.priv, p.datec as date_creation, p.tms as date_update,";
$sql .= " co.label as country, co.code as country_code";
// Add fields from extrafields
@@ -786,7 +786,6 @@ while ($i < min($num, $limit))
{
$obj = $db->fetch_object($result);
- print '';
$arraysocialnetworks = (array) json_decode($obj->socialnetworks, true);
$contactstatic->lastname = $obj->lastname;
$contactstatic->firstname = '';
@@ -802,6 +801,9 @@ while ($i < min($num, $limit))
$contactstatic->socialnetworks = $arraysocialnetworks;
$contactstatic->country = $obj->country;
$contactstatic->country_code = $obj->country_code;
+ $contactstatic->photo = $obj->photo;
+
+ print ' ';
// ID
if (!empty($arrayfields['p.rowid']['checked']))
diff --git a/htdocs/contrat/agenda.php b/htdocs/contrat/agenda.php
index 6b754dc9551..1fb3f572078 100644
--- a/htdocs/contrat/agenda.php
+++ b/htdocs/contrat/agenda.php
@@ -58,7 +58,7 @@ $result = restrictedArea($user, 'contrat', $id, '');
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php
index 1fc63769af3..4e0e5cb5865 100644
--- a/htdocs/contrat/card.php
+++ b/htdocs/contrat/card.php
@@ -1704,7 +1704,7 @@ else
if (is_array($extralabelslines) && count($extralabelslines) > 0) {
$line = new ContratLigne($db);
$line->fetch_optionals($objp->rowid);
- print $line->showOptionals($extrafields, 'view', array('style'=>'class="oddeven"', 'colspan'=>$colspan), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1);
+ print $line->showOptionals($extrafields, 'view', array('style'=>'class="oddeven"', 'colspan'=>$colspan), '', '', 1);
}
}
// Line in mode update
@@ -1794,7 +1794,7 @@ else
if (is_array($extralabelslines) && count($extralabelslines) > 0) {
$line = new ContratLigne($db);
$line->fetch_optionals($objp->rowid);
- print $line->showOptionals($extrafields, 'edit', array('style'=>'class="oddeven"', 'colspan'=>$colspan), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1);
+ print $line->showOptionals($extrafields, 'edit', array('style'=>'class="oddeven"', 'colspan'=>$colspan), '', '', 1);
}
}
diff --git a/htdocs/contrat/class/api_contracts.class.php b/htdocs/contrat/class/api_contracts.class.php
index 9d201d6fef1..71458e76050 100644
--- a/htdocs/contrat/class/api_contracts.class.php
+++ b/htdocs/contrat/class/api_contracts.class.php
@@ -439,8 +439,9 @@ class Contracts extends DolibarrApi
* @url DELETE {id}/lines/{lineid}
*
* @return int
- * @throws 401
- * @throws 404
+ *
+ * @throws RestException 401
+ * @throws RestException 404
*/
public function deleteLine($id, $lineid)
{
diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php
index 1f77e1905cf..0aee2ed876d 100644
--- a/htdocs/contrat/class/contrat.class.php
+++ b/htdocs/contrat/class/contrat.class.php
@@ -225,7 +225,6 @@ class Contrat extends CommonObject
'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35),
'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>40),
'date_contrat' =>array('type'=>'datetime', 'label'=>'Date contrat', 'enabled'=>1, 'visible'=>-1, 'position'=>45),
- 'statut' =>array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Closed')),
'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>70),
'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>75),
'fk_commercial_signature' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk commercial signature', 'enabled'=>1, 'visible'=>-1, 'position'=>80),
@@ -239,6 +238,7 @@ class Contrat extends CommonObject
'ref_customer' =>array('type'=>'varchar(50)', 'label'=>'Ref customer', 'enabled'=>1, 'visible'=>-1, 'position'=>130),
'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135),
'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>140),
+ 'statut' =>array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Closed'))
);
// END MODULEBUILDER PROPERTIES
@@ -517,7 +517,7 @@ class Contrat extends CommonObject
{
$num = $this->ref;
}
- $this->newref = $num;
+ $this->newref = dol_sanitizeFileName($num);
if ($num)
{
@@ -2754,8 +2754,8 @@ class ContratLigne extends CommonObjectLine
/**
* Return label of this contract line status
*
- * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
- * @return string Libelle
+ * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
+ * @return string Label of status
*/
public function getLibStatut($mode)
{
@@ -2767,10 +2767,10 @@ class ContratLigne extends CommonObjectLine
* Return label of a contract line status
*
* @param int $status Id status
- * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
+ * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
* @param int $expired 0=Not expired, 1=Expired, -1=Both or unknown
* @param string $moreatt More attribute
- * @return string Libelle
+ * @return string Label of status
*/
public static function LibStatut($status, $mode, $expired = -1, $moreatt = '')
{
diff --git a/htdocs/contrat/document.php b/htdocs/contrat/document.php
index aae50630eb7..cb350c61b51 100644
--- a/htdocs/contrat/document.php
+++ b/htdocs/contrat/document.php
@@ -57,7 +57,7 @@ $result = restrictedArea($user, 'contrat', $id);
// Get parameters
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/contrat/index.php b/htdocs/contrat/index.php
index 6dd6fc56e17..1061d47a888 100644
--- a/htdocs/contrat/index.php
+++ b/htdocs/contrat/index.php
@@ -39,7 +39,7 @@ $langs->loadLangs(array('products', 'companies', 'contracts'));
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
$statut = GETPOST('statut') ?GETPOST('statut') : 1;
@@ -209,10 +209,10 @@ if (!empty($conf->use_javascript_ajax))
include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
$dolgraph = new DolGraph();
$dolgraph->SetData($dataseries);
- $dolgraph->setShowLegend(1);
+ $dolgraph->setShowLegend(2);
$dolgraph->setShowPercent(1);
$dolgraph->SetType(array('pie'));
- $dolgraph->setWidth('100%');
+ $dolgraph->setHeight('200');
$dolgraph->draw('idgraphstatus');
print $dolgraph->show($total ? 0 : 1);
@@ -363,10 +363,10 @@ if ($result)
print '';
print ''.dol_print_date($db->jdate($obj->tms), 'dayhour').' ';
//print ''.$staticcontrat->LibStatut($obj->statut,2).' ';
- print ''.($obj->nb_initial > 0 ? $obj->nb_initial.$staticcontratligne->LibStatut(0, 3) : '').' ';
- print ''.($obj->nb_running > 0 ? $obj->nb_running.$staticcontratligne->LibStatut(4, 3, 0) : '').' ';
- print ''.($obj->nb_expired > 0 ? $obj->nb_expired.$staticcontratligne->LibStatut(4, 3, 1) : '').' ';
- print ''.($obj->nb_closed > 0 ? $obj->nb_closed.$staticcontratligne->LibStatut(5, 3) : '').' ';
+ print ''.($obj->nb_initial > 0 ? ''.$obj->nb_initial.' '.$staticcontratligne->LibStatut(0, 3, -1, 'class="paddingleft"') : '').' ';
+ print ''.($obj->nb_running > 0 ? ''.$obj->nb_running.' '.$staticcontratligne->LibStatut(4, 3, 0, 'class="marginleft"') : '').' ';
+ print ''.($obj->nb_expired > 0 ? ''.$obj->nb_expired.' '.$staticcontratligne->LibStatut(4, 3, 1, 'class="paddingleft"') : '').' ';
+ print ''.($obj->nb_closed > 0 ? ''.$obj->nb_closed.' '.$staticcontratligne->LibStatut(5, 3, -1, 'class="paddingleft"') : '').' ';
print " \n";
$i++;
}
diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php
index 328507f6722..09dfe2692b8 100644
--- a/htdocs/contrat/list.php
+++ b/htdocs/contrat/list.php
@@ -74,7 +74,7 @@ $optioncss = GETPOST('optioncss', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
@@ -705,9 +705,7 @@ while ($i < min($num, $limit))
$nbofsalesrepresentative = count($listsalesrepresentatives);
if ($nbofsalesrepresentative > 3) {
// We print only number
- print '';
print $nbofsalesrepresentative;
- print ' ';
}
elseif ($nbofsalesrepresentative > 0)
{
@@ -741,7 +739,7 @@ while ($i < min($num, $limit))
// Date
if (!empty($arrayfields['c.date_contrat']['checked']))
{
- print ''.dol_print_date($db->jdate($obj->date_contrat), 'day', 'tzuser').' ';
+ print ''.dol_print_date($db->jdate($obj->date_contrat), 'day', 'tzserver').' ';
}
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php
index 952a286d773..c8a6c321b6e 100644
--- a/htdocs/contrat/services_list.php
+++ b/htdocs/contrat/services_list.php
@@ -38,7 +38,7 @@ $langs->loadLangs(array('products', 'contracts', 'companies'));
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/contrat/tpl/linkedobjectblock.tpl.php b/htdocs/contrat/tpl/linkedobjectblock.tpl.php
index b7ec9574ccb..b200baef726 100644
--- a/htdocs/contrat/tpl/linkedobjectblock.tpl.php
+++ b/htdocs/contrat/tpl/linkedobjectblock.tpl.php
@@ -63,7 +63,7 @@ foreach($linkedObjectBlock as $key => $objectlink)
echo price($totalcontrat);
} ?>
getLibStatut(7); ?>
- id.'&action=dellink&dellinkid='.$key.'">'.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink'); ?>
+ id.'&action=dellink&dellinkid='.$key; ?>">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?>
fields[$key]['type'])) {
$value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup
} else {
- $value = GETPOST($key, 'alpha');
+ $value = GETPOST($key, 'alphanohtml');
}
if (preg_match('/^integer:/i', $object->fields[$key]['type']) && $value == '-1') $value = ''; // This is an implicit foreign key field
if (!empty($object->fields[$key]['foreignkey']) && $value == '-1') $value = ''; // This is an explicit foreign key field
@@ -128,6 +128,13 @@ if ($action == 'update' && !empty($permissiontoadd))
if ($object->fields[$key]['type'] == 'duration') {
if (!GETPOSTISSET($key.'hour') || !GETPOSTISSET($key.'min')) continue; // The field was not submited to be edited
}
+ elseif ($object->fields[$key]['type'] == 'boolean') {
+ if (!GETPOSTISSET($key)) {
+ $object->$key = 0; // use 0 instead null if the field is defined as not null
+ continue;
+ }
+ }
+
else {
if (!GETPOSTISSET($key)) continue; // The field was not submited to be edited
}
diff --git a/htdocs/core/actions_extrafields.inc.php b/htdocs/core/actions_extrafields.inc.php
index ca2499ab145..bb5a7516fb2 100644
--- a/htdocs/core/actions_extrafields.inc.php
+++ b/htdocs/core/actions_extrafields.inc.php
@@ -23,18 +23,18 @@
* \brief Code for actions on extrafields admin pages
*/
-$maxsizestring=255;
-$maxsizeint=10;
-$mesg=array();
+$maxsizestring = 255;
+$maxsizeint = 10;
+$mesg = array();
-$extrasize=GETPOST('size', 'intcomma');
-$type=GETPOST('type', 'alpha');
-$param=GETPOST('param', 'alpha');
+$extrasize = GETPOST('size', 'intcomma');
+$type = GETPOST('type', 'alpha');
+$param = GETPOST('param', 'alpha');
-if ($type=='double' && strpos($extrasize, ',')===false) $extrasize='24,8';
-if ($type=='date') $extrasize='';
-if ($type=='datetime') $extrasize='';
-if ($type=='select') $extrasize='';
+if ($type == 'double' && strpos($extrasize, ',') === false) $extrasize = '24,8';
+if ($type == 'date') $extrasize = '';
+if ($type == 'datetime') $extrasize = '';
+if ($type == 'select') $extrasize = '';
// Add attribute
@@ -43,83 +43,83 @@ if ($action == 'add')
if ($_POST["button"] != $langs->trans("Cancel"))
{
// Check values
- if (! $type)
+ if (!$type)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type"));
+ $mesg[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type"));
$action = 'create';
}
- if ($type=='varchar' && $extrasize <= 0)
+ if ($type == 'varchar' && $extrasize <= 0)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Size"));
+ $mesg[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Size"));
$action = 'edit';
}
- if ($type=='varchar' && $extrasize > $maxsizestring)
+ if ($type == 'varchar' && $extrasize > $maxsizestring)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorSizeTooLongForVarcharType", $maxsizestring);
+ $mesg[] = $langs->trans("ErrorSizeTooLongForVarcharType", $maxsizestring);
$action = 'create';
}
- if ($type=='int' && $extrasize > $maxsizeint)
+ if ($type == 'int' && $extrasize > $maxsizeint)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorSizeTooLongForIntType", $maxsizeint);
+ $mesg[] = $langs->trans("ErrorSizeTooLongForIntType", $maxsizeint);
$action = 'create';
}
- if ($type=='select' && !$param)
+ if ($type == 'select' && !$param)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorNoValueForSelectType");
+ $mesg[] = $langs->trans("ErrorNoValueForSelectType");
$action = 'create';
}
- if ($type=='sellist' && !$param)
+ if ($type == 'sellist' && !$param)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorNoValueForSelectListType");
+ $mesg[] = $langs->trans("ErrorNoValueForSelectListType");
$action = 'create';
}
- if ($type=='checkbox' && !$param)
+ if ($type == 'checkbox' && !$param)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorNoValueForCheckBoxType");
+ $mesg[] = $langs->trans("ErrorNoValueForCheckBoxType");
$action = 'create';
}
- if ($type=='link' && !$param)
+ if ($type == 'link' && !$param)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorNoValueForLinkType");
+ $mesg[] = $langs->trans("ErrorNoValueForLinkType");
$action = 'create';
}
- if ($type=='radio' && !$param)
+ if ($type == 'radio' && !$param)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorNoValueForRadioType");
+ $mesg[] = $langs->trans("ErrorNoValueForRadioType");
$action = 'create';
}
- if ((($type=='radio') || ($type=='checkbox')) && $param)
+ if ((($type == 'radio') || ($type == 'checkbox')) && $param)
{
// Construct array for parameter (value of select list)
$parameters = $param;
$parameters_array = explode("\r\n", $parameters);
- foreach($parameters_array as $param_ligne)
+ foreach ($parameters_array as $param_ligne)
{
if (!empty($param_ligne)) {
if (preg_match_all('/,/', $param_ligne, $matches))
{
- if (count($matches[0])>1) {
+ if (count($matches[0]) > 1) {
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorBadFormatValueList", $param_ligne);
+ $mesg[] = $langs->trans("ErrorBadFormatValueList", $param_ligne);
$action = 'create';
}
}
@@ -127,14 +127,14 @@ if ($action == 'add')
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorBadFormatValueList", $param_ligne);
+ $mesg[] = $langs->trans("ErrorBadFormatValueList", $param_ligne);
$action = 'create';
}
}
}
}
- if (! $error)
+ if (!$error)
{
// attrname must be alphabetical and lower case only
if (isset($_POST["attrname"]) && preg_match("/^[a-z0-9-_]+$/", $_POST['attrname']) && !is_numeric($_POST["attrname"]))
@@ -144,8 +144,8 @@ if ($action == 'add')
$parameters = $param;
$parameters_array = explode("\r\n", $parameters);
//In sellist we have only one line and it can have come to do SQL expression
- if ($type=='sellist') {
- foreach($parameters_array as $param_ligne)
+ if ($type == 'sellist') {
+ foreach ($parameters_array as $param_ligne)
{
$params['options'] = array($parameters=>null);
}
@@ -153,37 +153,38 @@ if ($action == 'add')
else
{
//Esle it's separated key/value and coma list
- foreach($parameters_array as $param_ligne)
+ foreach ($parameters_array as $param_ligne)
{
- list($key,$value) = explode(',', $param_ligne);
+ list($key, $value) = explode(',', $param_ligne);
$params['options'][$key] = $value;
}
}
// Visibility: -1=not visible by default in list, 1=visible, 0=hidden
$visibility = GETPOST('list', 'alpha');
- if ($type == 'separate') $visibility=3;
+ if ($type == 'separate') $visibility = 3;
- $result=$extrafields->addExtraField(
+ $result = $extrafields->addExtraField(
GETPOST('attrname', 'alpha'),
GETPOST('label', 'alpha'),
$type,
GETPOST('pos', 'int'),
$extrasize,
$elementtype,
- (GETPOST('unique', 'alpha')?1:0),
- (GETPOST('required', 'alpha')?1:0),
+ (GETPOST('unique', 'alpha') ? 1 : 0),
+ (GETPOST('required', 'alpha') ? 1 : 0),
$default_value,
$params,
- (GETPOST('alwayseditable', 'alpha')?1:0),
- (GETPOST('perms', 'alpha')?GETPOST('perms', 'alpha'):''),
+ (GETPOST('alwayseditable', 'alpha') ? 1 : 0),
+ (GETPOST('perms', 'alpha') ?GETPOST('perms', 'alpha') : ''),
$visibility,
GETPOST('help', 'alpha'),
GETPOST('computed_value', 'alpha'),
- (GETPOST('entitycurrentorall', 'alpha')?0:''),
+ (GETPOST('entitycurrentorall', 'alpha') ? 0 : ''),
GETPOST('langfile', 'alpha'),
1,
- (GETPOST('totalizable', 'alpha')?1:0)
+ (GETPOST('totalizable', 'alpha') ? 1 : 0),
+ GETPOST('printable', 'alpha')
);
if ($result > 0)
{
@@ -194,7 +195,7 @@ if ($action == 'add')
else
{
$error++;
- $mesg=$extrafields->error;
+ $mesg = $extrafields->error;
setEventMessages($mesg, null, 'errors');
}
}
@@ -202,7 +203,7 @@ if ($action == 'add')
{
$error++;
$langs->load("errors");
- $mesg=$langs->trans("ErrorFieldCanNotContainSpecialNorUpperCharacters", $langs->transnoentities("AttributeCode"));
+ $mesg = $langs->trans("ErrorFieldCanNotContainSpecialNorUpperCharacters", $langs->transnoentities("AttributeCode"));
setEventMessages($mesg, null, 'errors');
$action = 'create';
}
@@ -220,76 +221,76 @@ if ($action == 'update')
if ($_POST["button"] != $langs->trans("Cancel"))
{
// Check values
- if (! $type)
+ if (!$type)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type"));
+ $mesg[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type"));
$action = 'edit';
}
- if ($type=='varchar' && $extrasize <= 0)
+ if ($type == 'varchar' && $extrasize <= 0)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Size"));
+ $mesg[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Size"));
$action = 'edit';
}
- if ($type=='varchar' && $extrasize > $maxsizestring)
+ if ($type == 'varchar' && $extrasize > $maxsizestring)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorSizeTooLongForVarcharType", $maxsizestring);
+ $mesg[] = $langs->trans("ErrorSizeTooLongForVarcharType", $maxsizestring);
$action = 'edit';
}
- if ($type=='int' && $extrasize > $maxsizeint)
+ if ($type == 'int' && $extrasize > $maxsizeint)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorSizeTooLongForIntType", $maxsizeint);
+ $mesg[] = $langs->trans("ErrorSizeTooLongForIntType", $maxsizeint);
$action = 'edit';
}
- if ($type=='select' && !$param)
+ if ($type == 'select' && !$param)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorNoValueForSelectType");
+ $mesg[] = $langs->trans("ErrorNoValueForSelectType");
$action = 'edit';
}
- if ($type=='sellist' && !$param)
+ if ($type == 'sellist' && !$param)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorNoValueForSelectListType");
+ $mesg[] = $langs->trans("ErrorNoValueForSelectListType");
$action = 'edit';
}
- if ($type=='checkbox' && !$param)
+ if ($type == 'checkbox' && !$param)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorNoValueForCheckBoxType");
+ $mesg[] = $langs->trans("ErrorNoValueForCheckBoxType");
$action = 'edit';
}
- if ($type=='radio' && !$param)
+ if ($type == 'radio' && !$param)
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorNoValueForRadioType");
+ $mesg[] = $langs->trans("ErrorNoValueForRadioType");
$action = 'edit';
}
- if ((($type=='radio') || ($type=='checkbox')) && $param)
+ if ((($type == 'radio') || ($type == 'checkbox')) && $param)
{
// Construct array for parameter (value of select list)
$parameters = $param;
$parameters_array = explode("\r\n", $parameters);
- foreach($parameters_array as $param_ligne)
+ foreach ($parameters_array as $param_ligne)
{
if (!empty($param_ligne)) {
if (preg_match_all('/,/', $param_ligne, $matches))
{
- if (count($matches[0])>1) {
+ if (count($matches[0]) > 1) {
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorBadFormatValueList", $param_ligne);
+ $mesg[] = $langs->trans("ErrorBadFormatValueList", $param_ligne);
$action = 'edit';
}
}
@@ -297,14 +298,14 @@ if ($action == 'update')
{
$error++;
$langs->load("errors");
- $mesg[]=$langs->trans("ErrorBadFormatValueList", $param_ligne);
+ $mesg[] = $langs->trans("ErrorBadFormatValueList", $param_ligne);
$action = 'edit';
}
}
}
}
- if (! $error)
+ if (!$error)
{
if (isset($_POST["attrname"]) && preg_match("/^\w[a-zA-Z0-9-_]*$/", $_POST['attrname']))
{
@@ -313,8 +314,8 @@ if ($action == 'update')
$parameters = $param;
$parameters_array = explode("\r\n", $parameters);
//In sellist we have only one line and it can have come to do SQL expression
- if ($type=='sellist') {
- foreach($parameters_array as $param_ligne)
+ if ($type == 'sellist') {
+ foreach ($parameters_array as $param_ligne)
{
$params['options'] = array($parameters=>null);
}
@@ -322,37 +323,38 @@ if ($action == 'update')
else
{
//Esle it's separated key/value and coma list
- foreach($parameters_array as $param_ligne)
+ foreach ($parameters_array as $param_ligne)
{
- list($key,$value) = explode(',', $param_ligne);
+ list($key, $value) = explode(',', $param_ligne);
$params['options'][$key] = $value;
}
}
// Visibility: -1=not visible by default in list, 1=visible, 0=hidden
$visibility = GETPOST('list', 'alpha');
- if ($type == 'separate') $visibility=3;
+ if ($type == 'separate') $visibility = 3;
- $result=$extrafields->update(
+ $result = $extrafields->update(
GETPOST('attrname', 'alpha'),
GETPOST('label', 'alpha'),
$type,
$extrasize,
$elementtype,
- (GETPOST('unique', 'alpha')?1:0),
- (GETPOST('required', 'alpha')?1:0),
+ (GETPOST('unique', 'alpha') ? 1 : 0),
+ (GETPOST('required', 'alpha') ? 1 : 0),
$pos,
$params,
- (GETPOST('alwayseditable', 'alpha')?1:0),
- (GETPOST('perms', 'alpha')?GETPOST('perms', 'alpha'):''),
+ (GETPOST('alwayseditable', 'alpha') ? 1 : 0),
+ (GETPOST('perms', 'alpha') ?GETPOST('perms', 'alpha') : ''),
$visibility,
GETPOST('help', 'alpha'),
GETPOST('default_value', 'alpha'),
GETPOST('computed_value', 'alpha'),
- (GETPOST('entitycurrentorall', 'alpha')?0:''),
+ (GETPOST('entitycurrentorall', 'alpha') ? 0 : ''),
GETPOST('langfile'),
1,
- (GETPOST('totalizable', 'alpha')?1:0)
+ (GETPOST('totalizable', 'alpha') ? 1 : 0),
+ GETPOST('printable', 'alpha')
);
if ($result > 0)
{
@@ -363,7 +365,7 @@ if ($action == 'update')
else
{
$error++;
- $mesg=$extrafields->error;
+ $mesg = $extrafields->error;
setEventMessages($mesg, null, 'errors');
}
}
@@ -371,7 +373,7 @@ if ($action == 'update')
{
$error++;
$langs->load("errors");
- $mesg=$langs->trans("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities("AttributeCode"));
+ $mesg = $langs->trans("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities("AttributeCode"));
setEventMessages($mesg, null, 'errors');
}
}
@@ -385,20 +387,20 @@ if ($action == 'update')
// Delete attribute
if ($action == 'delete')
{
- if(isset($_GET["attrname"]) && preg_match("/^\w[a-zA-Z0-9-_]*$/", $_GET["attrname"]))
+ if (isset($_GET["attrname"]) && preg_match("/^\w[a-zA-Z0-9-_]*$/", $_GET["attrname"]))
{
- $result=$extrafields->delete($_GET["attrname"], $elementtype);
+ $result = $extrafields->delete($_GET["attrname"], $elementtype);
if ($result >= 0)
{
header("Location: ".$_SERVER["PHP_SELF"]);
exit;
}
- else $mesg=$extrafields->error;
+ else $mesg = $extrafields->error;
}
else
{
$error++;
$langs->load("errors");
- $mesg=$langs->trans("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities("AttributeCode"));
+ $mesg = $langs->trans("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities("AttributeCode"));
}
}
diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
index 4a00412f800..c3f046431b0 100644
--- a/htdocs/core/actions_massactions.inc.php
+++ b/htdocs/core/actions_massactions.inc.php
@@ -691,11 +691,11 @@ if ($massaction == 'confirm_createbills') // Create bills from orders
for ($i = 0; $i < $num; $i++)
{
- $desc = ($lines[$i]->desc ? $lines[$i]->desc : $lines[$i]->libelle);
+ $desc = ($lines[$i]->desc ? $lines[$i]->desc : '');
// If we build one invoice for several order, we must put the invoice of order on the line
if (!empty($createbills_onebythird))
{
- $desc = dol_concatdesc($desc, $langs->trans("Order").' '.$cmd->ref.' - '.dol_print_date($cmd->date, 'day', $langs));
+ $desc = dol_concatdesc($desc, $langs->trans("Order").' '.$cmd->ref.' - '.dol_print_date($cmd->date, 'day'));
}
if ($lines[$i]->subprice < 0)
diff --git a/htdocs/core/actions_setmoduleoptions.inc.php b/htdocs/core/actions_setmoduleoptions.inc.php
index 9ade3c148a4..313375d1aa1 100644
--- a/htdocs/core/actions_setmoduleoptions.inc.php
+++ b/htdocs/core/actions_setmoduleoptions.inc.php
@@ -68,6 +68,7 @@ if ($action == 'setModuleOptions')
{
foreach ($_POST as $key => $val)
{
+ $reg = array();
if (preg_match('/^param(\d*)$/', $key, $reg)) // Works for POST['param'], POST['param1'], POST['param2'], ...
{
$param = GETPOST("param".$reg[1], 'alpha');
diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php
index e5aa9cbe4bb..a9a7df300c3 100644
--- a/htdocs/core/ajax/ajaxdirpreview.php
+++ b/htdocs/core/ajax/ajaxdirpreview.php
@@ -48,7 +48,7 @@ if (!isset($mode) || $mode != 'noajax') // For ajax call
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
- $page = GETPOST("page", 'int');
+ $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/core/boxes/box_boms.php b/htdocs/core/boxes/box_boms.php
index 8f27ff739e0..44102f0aab1 100644
--- a/htdocs/core/boxes/box_boms.php
+++ b/htdocs/core/boxes/box_boms.php
@@ -86,7 +86,7 @@ class box_boms extends ModeleBoxes
if ($user->rights->bom->read)
{
- $sql = "SELECT p.ref as product_ref";
+ $sql = "SELECT p.ref as product_ref, p.tobuy, p.tosell";
$sql.= ", c.rowid";
$sql.= ", c.date_creation";
$sql.= ", c.tms";
@@ -109,11 +109,15 @@ class box_boms extends ModeleBoxes
while ($line < $num) {
$objp = $this->db->fetch_object($result);
$datem=$this->db->jdate($objp->tms);
+
$bomstatic->id = $objp->rowid;
$bomstatic->ref = $objp->ref;
$bomstatic->id = $objp->socid;
$bomstatic->status = $objp->status;
+
$productstatic->ref = $objp->product_ref;
+ $productstatic->status = $objp->tobuy;
+ $productstatic->status_buy = $objp->tosell;
$this->info_box_contents[$line][] = array(
'td' => 'class="nowraponall"',
diff --git a/htdocs/core/boxes/box_clients.php b/htdocs/core/boxes/box_clients.php
index feb7564cdaf..d82a4aee71e 100644
--- a/htdocs/core/boxes/box_clients.php
+++ b/htdocs/core/boxes/box_clients.php
@@ -32,9 +32,9 @@ include_once DOL_DOCUMENT_ROOT.'/core/boxes/modules_boxes.php';
*/
class box_clients extends ModeleBoxes
{
- public $boxcode="lastcustomers";
- public $boximg="object_company";
- public $boxlabel="BoxLastCustomers";
+ public $boxcode = "lastcustomers";
+ public $boximg = "object_company";
+ public $boxlabel = "BoxLastCustomers";
public $depends = array("societe");
/**
@@ -61,9 +61,9 @@ class box_clients extends ModeleBoxes
$this->db = $db;
// disable box for such cases
- if (! empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) $this->enabled=0; // disabled by this option
+ if (!empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) $this->enabled = 0; // disabled by this option
- $this->hidden = ! ($user->rights->societe->lire && empty($user->socid));
+ $this->hidden = !($user->rights->societe->lire && empty($user->socid));
}
/**
@@ -77,33 +77,33 @@ class box_clients extends ModeleBoxes
global $user, $langs, $conf;
$langs->load("boxes");
- $this->max=$max;
+ $this->max = $max;
include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
- $thirdpartystatic=new Societe($this->db);
+ $thirdpartystatic = new Societe($this->db);
$this->info_box_head = array('text' => $langs->trans("BoxTitleLastModifiedCustomers", $max));
if ($user->rights->societe->lire)
{
$sql = "SELECT s.nom as name, s.rowid as socid";
- $sql.= ", s.code_client";
- $sql.= ", s.client";
- $sql.= ", s.code_fournisseur";
- $sql.= ", s.fournisseur";
- $sql.= ", s.code_compta";
- $sql.= ", s.code_compta_fournisseur";
- $sql.= ", s.logo";
- $sql.= ", s.email";
- $sql.= ", s.datec, s.tms, s.status";
- $sql.= " FROM ".MAIN_DB_PREFIX."societe as s";
- if (!$user->rights->societe->client->voir && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE s.client IN (1, 3)";
- $sql.= " AND s.entity IN (".getEntity('societe').")";
- if (!$user->rights->societe->client->voir && !$user->socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
- if ($user->socid) $sql.= " AND s.rowid = $user->socid";
- $sql.= " ORDER BY s.tms DESC";
- $sql.= $this->db->plimit($max, 0);
+ $sql .= ", s.code_client";
+ $sql .= ", s.client";
+ $sql .= ", s.code_fournisseur";
+ $sql .= ", s.fournisseur";
+ $sql .= ", s.code_compta";
+ $sql .= ", s.code_compta_fournisseur";
+ $sql .= ", s.logo";
+ $sql .= ", s.email";
+ $sql .= ", s.datec, s.tms, s.status, s.entity";
+ $sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
+ if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql .= " WHERE s.client IN (1, 3)";
+ $sql .= " AND s.entity IN (".getEntity('societe').")";
+ if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
+ if ($user->socid) $sql .= " AND s.rowid = $user->socid";
+ $sql .= " ORDER BY s.tms DESC";
+ $sql .= $this->db->plimit($max, 0);
dol_syslog(get_class($this)."::loadBox", LOG_DEBUG);
$result = $this->db->query($sql);
@@ -115,8 +115,8 @@ class box_clients extends ModeleBoxes
while ($line < $num)
{
$objp = $this->db->fetch_object($result);
- $datec=$this->db->jdate($objp->datec);
- $datem=$this->db->jdate($objp->tms);
+ $datec = $this->db->jdate($objp->datec);
+ $datem = $this->db->jdate($objp->tms);
$thirdpartystatic->id = $objp->socid;
$thirdpartystatic->name = $objp->name;
$thirdpartystatic->code_client = $objp->code_client;
@@ -127,6 +127,7 @@ class box_clients extends ModeleBoxes
$thirdpartystatic->fournisseur = $objp->fournisseur;
$thirdpartystatic->logo = $objp->logo;
$thirdpartystatic->email = $objp->email;
+ $thirdpartystatic->entity = $objp->entity;
$this->info_box_contents[$line][] = array(
'td' => '',
@@ -147,7 +148,7 @@ class box_clients extends ModeleBoxes
$line++;
}
- if ($num==0) $this->info_box_contents[$line][0] = array('td' => 'class="center"','text'=>$langs->trans("NoRecordedCustomers"));
+ if ($num == 0) $this->info_box_contents[$line][0] = array('td' => 'class="center"', 'text'=>$langs->trans("NoRecordedCustomers"));
$this->db->free($result);
}
diff --git a/htdocs/core/boxes/box_commandes.php b/htdocs/core/boxes/box_commandes.php
index c8a050ea1d4..10b9c52acb0 100644
--- a/htdocs/core/boxes/box_commandes.php
+++ b/htdocs/core/boxes/box_commandes.php
@@ -72,6 +72,7 @@ class box_commandes extends ModeleBoxes
public function loadBox($max = 5)
{
global $user, $langs, $conf;
+ $langs->load('orders');
$this->max = $max;
diff --git a/htdocs/core/boxes/box_contacts.php b/htdocs/core/boxes/box_contacts.php
index 91c6ab23910..caea252c571 100644
--- a/htdocs/core/boxes/box_contacts.php
+++ b/htdocs/core/boxes/box_contacts.php
@@ -4,6 +4,7 @@
* Copyright (C) 2005-2009 Regis Houssin
* Copyright (C) 2015 Frederic France
* Copyright (C) 2018 Josep Lluís Amador
+ * Copyright (C) 2020 Ferran Marcet
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -83,6 +84,7 @@ class box_contacts extends ModeleBoxes
if ($user->rights->societe->lire && $user->rights->societe->contact->lire)
{
$sql = "SELECT sp.rowid as id, sp.lastname, sp.firstname, sp.civility as civility_id, sp.datec, sp.tms, sp.fk_soc, sp.statut as status";
+
$sql .= ", sp.address, sp.zip, sp.town, sp.phone, sp.phone_perso, sp.phone_mobile, sp.email as spemail";
$sql .= ", s.nom as socname, s.name_alias, s.email as semail";
$sql .= ", s.client, s.fournisseur, s.code_client, s.code_fournisseur";
diff --git a/htdocs/core/boxes/box_fournisseurs.php b/htdocs/core/boxes/box_fournisseurs.php
index 5f26351affe..2f55a379362 100644
--- a/htdocs/core/boxes/box_fournisseurs.php
+++ b/htdocs/core/boxes/box_fournisseurs.php
@@ -2,6 +2,7 @@
/* Copyright (C) 2004-2006 Destailleur Laurent
* Copyright (C) 2005-2009 Regis Houssin
* Copyright (C) 2015-2019 Frederic France
+ * Copyright (C) 2020 Pierre Ardoin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,9 +32,9 @@ include_once DOL_DOCUMENT_ROOT.'/core/boxes/modules_boxes.php';
*/
class box_fournisseurs extends ModeleBoxes
{
- public $boxcode="lastsuppliers";
- public $boximg="object_company";
- public $boxlabel="BoxLastSuppliers";
+ public $boxcode = "lastsuppliers";
+ public $boximg = "object_company";
+ public $boxlabel = "BoxLastSuppliers";
public $depends = array("fournisseur");
/**
@@ -59,7 +60,7 @@ class box_fournisseurs extends ModeleBoxes
$this->db = $db;
- $this->hidden = ! ($user->rights->societe->lire && empty($user->socid));
+ $this->hidden = !($user->rights->societe->lire && empty($user->socid));
}
/**
@@ -73,28 +74,28 @@ class box_fournisseurs extends ModeleBoxes
global $conf, $user, $langs;
$langs->load("boxes");
- $this->max=$max;
+ $this->max = $max;
include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
- $thirdpartystatic=new Societe($this->db);
+ $thirdpartystatic = new Societe($this->db);
include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
- $thirdpartytmp=new Fournisseur($this->db);
+ $thirdpartytmp = new Fournisseur($this->db);
$this->info_box_head = array('text' => $langs->trans("BoxTitleLastModifiedSuppliers", $max));
if ($user->rights->societe->lire)
{
$sql = "SELECT s.nom as name, s.rowid as socid, s.datec, s.tms, s.status,";
- $sql.= " s.code_fournisseur, s.email as semail,";
- $sql.= " s.logo";
+ $sql .= " s.code_fournisseur, s.email as semail,";
+ $sql .= " s.logo, s.code_compta_fournisseur, s.entity";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
- if (!$user->rights->societe->client->voir && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE s.fournisseur = 1";
- $sql.= " AND s.entity IN (".getEntity('societe').")";
- if (!$user->rights->societe->client->voir && !$user->socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
- if ($user->socid) $sql.= " AND s.rowid = ".$user->socid;
- $sql.= " ORDER BY s.tms DESC ";
- $sql.= $this->db->plimit($max, 0);
+ if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql .= " WHERE s.fournisseur = 1";
+ $sql .= " AND s.entity IN (".getEntity('societe').")";
+ if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
+ if ($user->socid) $sql .= " AND s.rowid = ".$user->socid;
+ $sql .= " ORDER BY s.tms DESC ";
+ $sql .= $this->db->plimit($max, 0);
$result = $this->db->query($sql);
if ($result)
@@ -105,13 +106,15 @@ class box_fournisseurs extends ModeleBoxes
while ($line < $num)
{
$objp = $this->db->fetch_object($result);
- $datec=$this->db->jdate($objp->datec);
- $datem=$this->db->jdate($objp->tms);
+ $datec = $this->db->jdate($objp->datec);
+ $datem = $this->db->jdate($objp->tms);
$thirdpartytmp->id = $objp->socid;
$thirdpartytmp->name = $objp->name;
$thirdpartytmp->email = $objp->semail;
$thirdpartytmp->code_client = $objp->code_client;
$thirdpartytmp->logo = $objp->logo;
+ $thirdpartytmp->code_compta_fournisseur = $objp->code_compta_fournisseur;
+ $thirdpartytmp->entity = $objp->entity;
$this->info_box_contents[$line][] = array(
'td' => '',
@@ -132,7 +135,7 @@ class box_fournisseurs extends ModeleBoxes
$line++;
}
- if ($num==0) $this->info_box_contents[$line][0] = array(
+ if ($num == 0) $this->info_box_contents[$line][0] = array(
'td' => 'class="center"',
'text'=>$langs->trans("NoRecordedSuppliers"),
);
diff --git a/htdocs/core/boxes/box_graph_invoices_permonth.php b/htdocs/core/boxes/box_graph_invoices_permonth.php
index 6c0a20bc6db..e78b6e235b1 100644
--- a/htdocs/core/boxes/box_graph_invoices_permonth.php
+++ b/htdocs/core/boxes/box_graph_invoices_permonth.php
@@ -160,6 +160,7 @@ class box_graph_invoices_permonth extends ModeleBoxes
}
$i++;
}
+
$px1->SetLegend($legend);
$px1->SetMaxValue($px1->GetCeilMaxValue());
$px1->SetWidth($WIDTH);
diff --git a/htdocs/core/boxes/box_graph_product_distribution.php b/htdocs/core/boxes/box_graph_product_distribution.php
index c61bc2569be..e8337d74303 100644
--- a/htdocs/core/boxes/box_graph_product_distribution.php
+++ b/htdocs/core/boxes/box_graph_product_distribution.php
@@ -75,6 +75,7 @@ class box_graph_product_distribution extends ModeleBoxes
global $conf, $user, $langs;
$this->max = $max;
+ $dir = $conf->user->dir_temp;
$refreshaction = 'refresh_'.$this->boxcode;
@@ -145,7 +146,8 @@ class box_graph_product_distribution extends ModeleBoxes
$showpointvalue = 1; $nocolor = 0;
$mode = 'customer';
$stats_invoice = new FactureStats($this->db, $socid, $mode, ($userid > 0 ? $userid : 0));
- $data1 = $stats_invoice->getAllByProductEntry($year, (GETPOST('action', 'aZ09') == $refreshaction ?-1 : (3600 * 24)));
+ $data1 = $stats_invoice->getAllByProductEntry($year, (GETPOST('action', 'aZ09') == $refreshaction ?-1 : (3600 * 24)), 5);
+
if (empty($data1))
{
$showpointvalue = 0;
@@ -159,11 +161,12 @@ class box_graph_product_distribution extends ModeleBoxes
$mesg = $px1->isGraphKo();
if (!$mesg)
{
- $i = 0; $tot = count($data1); $legend = array();
- while ($i <= $tot)
+ $i = 0; $legend = array();
+
+ foreach ($data1 as $key => $val)
{
- $data1[$i][0] = dol_trunc($data1[$i][0], 5); // Required to avoid error "Could not draw pie with labels contained inside canvas"
- $legend[] = $data1[$i][0];
+ $data1[$key][0] = dol_trunc($data1[$key][0], 32);
+ $legend[] = $data1[$key][0];
$i++;
}
@@ -172,11 +175,11 @@ class box_graph_product_distribution extends ModeleBoxes
if ($nocolor) $px1->SetDataColor(array(array(220, 220, 220)));
$px1->SetLegend($legend);
- $px1->setShowLegend(0);
+ $px1->setShowLegend(2);
$px1->setShowPointValue($showpointvalue);
$px1->setShowPercent(0);
$px1->SetMaxValue($px1->GetCeilMaxValue());
- $px1->SetWidth($WIDTH);
+ //$px1->SetWidth($WIDTH);
$px1->SetHeight($HEIGHT);
//$px1->SetYLabel($langs->trans("NumberOfBills"));
$px1->SetShading(3);
@@ -202,7 +205,7 @@ class box_graph_product_distribution extends ModeleBoxes
$showpointvalue = 1; $nocolor = 0;
$stats_proposal = new PropaleStats($this->db, $socid, ($userid > 0 ? $userid : 0));
- $data2 = $stats_proposal->getAllByProductEntry($year, (GETPOST('action', 'aZ09') == $refreshaction ?-1 : (3600 * 24)));
+ $data2 = $stats_proposal->getAllByProductEntry($year, (GETPOST('action', 'aZ09') == $refreshaction ?-1 : (3600 * 24)), 5);
if (empty($data2))
{
$showpointvalue = 0;
@@ -217,11 +220,12 @@ class box_graph_product_distribution extends ModeleBoxes
$mesg = $px2->isGraphKo();
if (!$mesg)
{
- $i = 0; $tot = count($data2); $legend = array();
- while ($i <= $tot)
+ $i = 0; $legend = array();
+
+ foreach ($data2 as $key => $val)
{
- $data2[$i][0] = dol_trunc($data2[$i][0], 5); // Required to avoid error "Could not draw pie with labels contained inside canvas"
- $legend[] = $data2[$i][0];
+ $data2[$key][0] = dol_trunc($data2[$key][0], 32);
+ $legend[] = $data2[$key][0];
$i++;
}
@@ -230,11 +234,11 @@ class box_graph_product_distribution extends ModeleBoxes
if ($nocolor) $px2->SetDataColor(array(array(220, 220, 220)));
$px2->SetLegend($legend);
- $px2->setShowLegend(0);
+ $px2->setShowLegend(2);
$px2->setShowPointValue($showpointvalue);
$px2->setShowPercent(0);
$px2->SetMaxValue($px2->GetCeilMaxValue());
- $px2->SetWidth($WIDTH);
+ //$px2->SetWidth($WIDTH);
$px2->SetHeight($HEIGHT);
//$px2->SetYLabel($langs->trans("AmountOfBillsHT"));
$px2->SetShading(3);
@@ -261,7 +265,7 @@ class box_graph_product_distribution extends ModeleBoxes
$showpointvalue = 1; $nocolor = 0;
$mode = 'customer';
$stats_order = new CommandeStats($this->db, $socid, $mode, ($userid > 0 ? $userid : 0));
- $data3 = $stats_order->getAllByProductEntry($year, (GETPOST('action', 'aZ09') == $refreshaction ?-1 : (3600 * 24)));
+ $data3 = $stats_order->getAllByProductEntry($year, (GETPOST('action', 'aZ09') == $refreshaction ?-1 : (3600 * 24)), 5);
if (empty($data3))
{
$showpointvalue = 0;
@@ -276,11 +280,12 @@ class box_graph_product_distribution extends ModeleBoxes
$mesg = $px3->isGraphKo();
if (!$mesg)
{
- $i = 0; $tot = count($data3); $legend = array();
- while ($i <= $tot)
+ $i = 0; $legend = array();
+
+ foreach ($data3 as $key => $val)
{
- $data3[$i][0] = dol_trunc($data3[$i][0], 5); // Required to avoid error "Could not draw pie with labels contained inside canvas"
- $legend[] = $data3[$i][0];
+ $data3[$key][0] = dol_trunc($data3[$key][0], 32);
+ $legend[] = $data3[$key][0];
$i++;
}
@@ -289,11 +294,11 @@ class box_graph_product_distribution extends ModeleBoxes
if ($nocolor) $px3->SetDataColor(array(array(220, 220, 220)));
$px3->SetLegend($legend);
- $px3->setShowLegend(0);
+ $px3->setShowLegend(2);
$px3->setShowPointValue($showpointvalue);
$px3->setShowPercent(0);
$px3->SetMaxValue($px3->GetCeilMaxValue());
- $px3->SetWidth($WIDTH);
+ //$px3->SetWidth($WIDTH);
$px3->SetHeight($HEIGHT);
//$px3->SetYLabel($langs->trans("AmountOfBillsHT"));
$px3->SetShading(3);
diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php
index 0bc6d801e41..9fffc92963f 100644
--- a/htdocs/core/boxes/box_project.php
+++ b/htdocs/core/boxes/box_project.php
@@ -96,7 +96,7 @@ class box_project extends ModeleBoxes
$projectsListId='';
if (! $user->rights->projet->all->lire) $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, $socid);
- $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut, p.public";
+ $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut as status, p.public";
$sql.= " FROM ".MAIN_DB_PREFIX."projet as p";
$sql.= " WHERE p.entity IN (".getEntity('project').")"; // Only current entity or severals if permission ok
$sql.= " AND p.fk_statut = 1"; // Only open projects
@@ -117,6 +117,7 @@ class box_project extends ModeleBoxes
$projectstatic->ref = $objp->ref;
$projectstatic->title = $objp->title;
$projectstatic->public = $objp->public;
+ $projectstatic->statut = $objp->status;
$this->info_box_contents[$i][] = array(
'td' => 'class="nowraponall"',
@@ -152,6 +153,7 @@ class box_project extends ModeleBoxes
$this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => round(0));
$this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => "N/A ");
}
+ $this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => $projectstatic->getLibStatut(3));
$i++;
}
@@ -166,22 +168,26 @@ class box_project extends ModeleBoxes
// Add the sum à the bottom of the boxes
$this->info_box_contents[$i][] = array(
- 'td' => '',
+ 'td' => 'class="liste_total"',
'text' => $langs->trans("Total")." ".$textHead,
'text' => " ",
);
$this->info_box_contents[$i][] = array(
- 'td' => 'class="right" ',
+ 'td' => 'class="right liste_total" ',
'text' => round($num, 0)." ".$langs->trans("Projects"),
);
$this->info_box_contents[$i][] = array(
- 'td' => 'class="right" ',
+ 'td' => 'class="right liste_total" ',
'text' => (($max < $num) ? '' : (round($totalnbTask, 0)." ".$langs->trans("Tasks"))),
);
$this->info_box_contents[$i][] = array(
- 'td' => '',
+ 'td' => 'class="liste_total"',
'text' => " ",
);
+ $this->info_box_contents[$i][] = array(
+ 'td' => 'class="liste_total"',
+ 'text' => " ",
+ );
}
/**
diff --git a/htdocs/core/boxes/box_propales.php b/htdocs/core/boxes/box_propales.php
index 3cbd9f45514..979723753a0 100644
--- a/htdocs/core/boxes/box_propales.php
+++ b/htdocs/core/boxes/box_propales.php
@@ -3,6 +3,7 @@
* Copyright (C) 2004-2007 Laurent Destailleur
* Copyright (C) 2005-2009 Regis Houssin
* Copyright (C) 2015-2019 Frederic France
+ * Copyright (C) 2020 Pierre Ardoin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,10 +33,10 @@ include_once DOL_DOCUMENT_ROOT.'/core/boxes/modules_boxes.php';
*/
class box_propales extends ModeleBoxes
{
- public $boxcode="lastpropals";
- public $boximg="object_propal";
- public $boxlabel="BoxLastProposals";
- public $depends = array("propal"); // conf->propal->enabled
+ public $boxcode = "lastpropals";
+ public $boximg = "object_propal";
+ public $boxlabel = "BoxLastProposals";
+ public $depends = array("propal"); // conf->propal->enabled
/**
* @var DoliDB Database handler.
@@ -60,7 +61,7 @@ class box_propales extends ModeleBoxes
$this->db = $db;
- $this->hidden = ! ($user->rights->propale->lire);
+ $this->hidden = !($user->rights->propale->lire);
}
/**
@@ -73,45 +74,45 @@ class box_propales extends ModeleBoxes
{
global $user, $langs, $conf;
- $this->max=$max;
+ $this->max = $max;
include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
- $propalstatic=new Propal($this->db);
+ $propalstatic = new Propal($this->db);
$societestatic = new Societe($this->db);
- $this->info_box_head = array('text' => $langs->trans("BoxTitleLast".($conf->global->MAIN_LASTBOX_ON_OBJECT_DATE?"":"Modified")."Propals", $max));
+ $this->info_box_head = array('text' => $langs->trans("BoxTitleLast".($conf->global->MAIN_LASTBOX_ON_OBJECT_DATE ? "" : "Modified")."Propals", $max));
if ($user->rights->propale->lire)
{
- $sql = "SELECT s.nom as name, s.rowid as socid, s.code_client, s.logo, s.email,";
- $sql.= " p.rowid, p.ref, p.fk_statut, p.datep as dp, p.datec, p.fin_validite, p.date_cloture, p.total_ht, p.tva as total_tva, p.total as total_ttc, p.tms";
- $sql.= " FROM ".MAIN_DB_PREFIX."societe as s";
- $sql.= ", ".MAIN_DB_PREFIX."propal as p";
- if (!$user->rights->societe->client->voir && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- $sql.= " WHERE p.fk_soc = s.rowid";
- $sql.= " AND p.entity = ".$conf->entity;
- if (!$user->rights->societe->client->voir && !$user->socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
- if($user->socid) $sql.= " AND s.rowid = ".$user->socid;
- if ($conf->global->MAIN_LASTBOX_ON_OBJECT_DATE) $sql.= " ORDER BY p.datep DESC, p.ref DESC ";
- else $sql.= " ORDER BY p.tms DESC, p.ref DESC ";
- $sql.= $this->db->plimit($max, 0);
+ $sql = "SELECT s.nom as name, s.rowid as socid, s.code_client, s.logo, s.entity, s.email,";
+ $sql .= " p.rowid, p.ref, p.fk_statut, p.datep as dp, p.datec, p.fin_validite, p.date_cloture, p.total_ht, p.tva as total_tva, p.total as total_ttc, p.tms";
+ $sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
+ $sql .= ", ".MAIN_DB_PREFIX."propal as p";
+ if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql .= " WHERE p.fk_soc = s.rowid";
+ $sql .= " AND p.entity = ".$conf->entity;
+ if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
+ if ($user->socid) $sql .= " AND s.rowid = ".$user->socid;
+ if ($conf->global->MAIN_LASTBOX_ON_OBJECT_DATE) $sql .= " ORDER BY p.datep DESC, p.ref DESC ";
+ else $sql .= " ORDER BY p.tms DESC, p.ref DESC ";
+ $sql .= $this->db->plimit($max, 0);
$result = $this->db->query($sql);
if ($result)
{
$num = $this->db->num_rows($result);
- $now=dol_now();
+ $now = dol_now();
$line = 0;
while ($line < $num) {
$objp = $this->db->fetch_object($result);
- $date=$this->db->jdate($objp->dp);
- $datec=$this->db->jdate($objp->datec);
- $datem=$this->db->jdate($objp->tms);
- $dateterm=$this->db->jdate($objp->fin_validite);
- $dateclose=$this->db->jdate($objp->date_cloture);
+ $date = $this->db->jdate($objp->dp);
+ $datec = $this->db->jdate($objp->datec);
+ $datem = $this->db->jdate($objp->tms);
+ $dateterm = $this->db->jdate($objp->fin_validite);
+ $dateclose = $this->db->jdate($objp->date_cloture);
$propalstatic->id = $objp->rowid;
$propalstatic->ref = $objp->ref;
$propalstatic->total_ht = $objp->total_ht;
@@ -122,6 +123,7 @@ class box_propales extends ModeleBoxes
$societestatic->code_client = $objp->code_client;
$societestatic->logo = $objp->logo;
$societestatic->email = $objp->email;
+ $societestatic->entity = $objp->entity;
$late = '';
if ($objp->fk_statut == 1 && $dateterm < ($now - $conf->propal->cloture->warning_delay)) {
@@ -159,7 +161,7 @@ class box_propales extends ModeleBoxes
$line++;
}
- if ($num==0)
+ if ($num == 0)
$this->info_box_contents[$line][0] = array(
'td' => 'class="center"',
'text'=>$langs->trans("NoRecordedProposals"),
diff --git a/htdocs/core/boxes/box_services_contracts.php b/htdocs/core/boxes/box_services_contracts.php
index dbb26408b6f..5b40fc61436 100644
--- a/htdocs/core/boxes/box_services_contracts.php
+++ b/htdocs/core/boxes/box_services_contracts.php
@@ -91,7 +91,7 @@ class box_services_contracts extends ModeleBoxes
$sql = "SELECT s.nom as name, s.rowid as socid, s.email, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,";
$sql.= " c.rowid, c.ref, c.statut as contract_status, c.ref_customer, c.ref_supplier,";
$sql.= " cd.rowid as cdid, cd.label, cd.description, cd.tms as datem, cd.statut, cd.product_type as type,";
- $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as plabel, p.fk_product_type as ptype, p.entity";
+ $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as plabel, p.fk_product_type as ptype, p.entity, p.tobuy, p.tosell";
$sql.= " FROM (".MAIN_DB_PREFIX."societe as s";
$sql.= " INNER JOIN ".MAIN_DB_PREFIX."contrat as c ON s.rowid = c.fk_soc";
$sql.= " INNER JOIN ".MAIN_DB_PREFIX."contratdet as cd ON c.rowid = cd.fk_contrat";
@@ -165,6 +165,9 @@ class box_services_contracts extends ModeleBoxes
$productstatic->ref=$objp->product_ref;
$productstatic->entity=$objp->pentity;
$productstatic->label=$objp->plabel;
+ $productstatic->status = $objp->tosell;
+ $productstatic->status_buy = $objp->tobuy;
+
$text = $productstatic->getNomUrl(1, '', 20);
if ($objp->plabel)
{
diff --git a/htdocs/core/boxes/box_shipments.php b/htdocs/core/boxes/box_shipments.php
index 3b07b5bbd68..26f45bc08db 100644
--- a/htdocs/core/boxes/box_shipments.php
+++ b/htdocs/core/boxes/box_shipments.php
@@ -77,6 +77,7 @@ class box_shipments extends ModeleBoxes
$this->max = $max;
include_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
+ include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
$shipmentstatic = new Expedition($this->db);
diff --git a/htdocs/core/boxes/box_task.php b/htdocs/core/boxes/box_task.php
index 2ae0ede3c21..94983ef6bff 100644
--- a/htdocs/core/boxes/box_task.php
+++ b/htdocs/core/boxes/box_task.php
@@ -86,6 +86,7 @@ class box_task extends ModeleBoxes
$form = new Form($this->db);
$cookie_name = 'boxfilter_task';
$boxcontent = '';
+ $socid = $user->socid;
$textHead = $langs->trans("CurentlyOpenedTasks");
@@ -97,7 +98,6 @@ class box_task extends ModeleBoxes
$filterValue = $_COOKIE[$cookie_name];
}
-
if ($filterValue == 'im_task_contact') {
$textHead .= ' : '.$langs->trans("WhichIamLinkedTo");
}
@@ -127,15 +127,17 @@ class box_task extends ModeleBoxes
$boxcontent .= ''.$langs->trans("Refresh").' ';
$boxcontent .= ''."\n";
$boxcontent .= ''."\n";
- $boxcontent .= '';
- // set cookie by js
- $boxcontent .= '';
+ ';
+ // set cookie by js
+ $boxcontent .= '';
+ }
$this->info_box_contents[0][] = array(
'tr'=>'class="nohover showiffilter'.$this->boxcode.' hideobject"',
'td' => 'class="nohover"',
@@ -143,6 +145,10 @@ class box_task extends ModeleBoxes
);
+ // Get list of project id allowed to user (in a string list separated by coma)
+ $projectsListId = '';
+ if (!$user->rights->projet->all->lire) $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, $socid);
+
$sql = "SELECT pt.rowid, pt.ref, pt.fk_projet, pt.fk_task_parent, pt.datec, pt.dateo, pt.datee, pt.datev, pt.label, pt.description, pt.duration_effective, pt.planned_workload, pt.progress";
$sql .= ", p.rowid project_id, p.ref project_ref, p.title project_title";
@@ -163,7 +169,7 @@ class box_task extends ModeleBoxes
$sql .= " AND p.fk_statut = ".Project::STATUS_VALIDATED;
$sql .= " AND (pt.progress < 100 OR pt.progress IS NULL ) "; // 100% is done and not displayed
$sql .= " AND p.usage_task = 1 ";
-
+ if (!$user->rights->projet->all->lire) $sql .= " AND p.rowid IN (".$projectsListId.")"; // public and assigned to, or restricted to company for external users
$sql .= " ORDER BY pt.datee ASC, pt.dateo ASC";
$sql .= $this->db->plimit($max, 0);
diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php
index dc2b00c586c..bba38bddb30 100644
--- a/htdocs/core/class/CMailFile.class.php
+++ b/htdocs/core/class/CMailFile.class.php
@@ -144,7 +144,10 @@ class CMailFile
}
}
- $this->subject = $subject;
+ // Add autocopy to (Note: Adding bcc for specific modules are also done from pages)
+ if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) $addr_bcc .= ($addr_bcc ? ', ' : '').$conf->global->MAIN_MAIL_AUTOCOPY_TO;
+
+ $this->subject = $subject;
$this->addr_to = $to;
$this->addr_from = $from;
$this->msg = $msg;
@@ -204,7 +207,7 @@ class CMailFile
if (empty($msg))
{
dol_syslog("CMailFile::CMailfile: Try to send an email with empty body");
- $msg = '.'; // Avoid empty message (with empty message conten show a multipart structure)
+ $msg = '.'; // Avoid empty message (with empty message content, you will see a multipart structure)
}
// Detect if message is HTML (use fast method)
@@ -226,7 +229,7 @@ class CMailFile
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
// Replace relative /viewimage to absolute path
- $msg = preg_replace('/src="'.preg_quote(DOL_URL_ROOT, '/').'\/viewimage\.php/ims', 'src="'.$urlwithroot.'/viewimage.php', $msg, -1, $nbrep);
+ $msg = preg_replace('/src="'.preg_quote(DOL_URL_ROOT, '/').'\/viewimage\.php/ims', 'src="'.$urlwithroot.'/viewimage.php', $msg, -1);
if (!empty($conf->global->MAIN_MAIL_FORCE_CONTENT_TYPE_TO_HTML)) $this->msgishtml = 1; // To force to send everything with content type html.
@@ -267,9 +270,6 @@ class CMailFile
}
}
- // Add autocopy to (Note: Adding bcc for specific modules are also done from pages)
- if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) $addr_bcc .= ($addr_bcc ? ', ' : '').$conf->global->MAIN_MAIL_AUTOCOPY_TO;
-
// We set all data according to choosed sending method.
// We also set a value for ->msgid
if ($this->sendmode == 'mail')
@@ -354,6 +354,9 @@ class CMailFile
$msg = $this->checkIfHTML($msg);
}
+ // Replace . alone on a new line with .. to avoid to have SMTP interpret this as end of message
+ $msg = preg_replace('/(\r|\n)\.(\r|\n)/ims', '\1..\2', $msg);
+
if ($this->msgishtml) $smtps->setBodyContent($msg, 'html');
else $smtps->setBodyContent($msg, 'plain');
diff --git a/htdocs/core/class/canvas.class.php b/htdocs/core/class/canvas.class.php
index cfdb09c527e..80c6ff1b7a6 100644
--- a/htdocs/core/class/canvas.class.php
+++ b/htdocs/core/class/canvas.class.php
@@ -36,7 +36,7 @@ class Canvas
/**
* @var string Error code (or message)
*/
- public $error='';
+ public $error = '';
/**
* @var string[] Error codes (or messages)
@@ -45,13 +45,13 @@ class Canvas
public $actiontype;
- public $dirmodule; // Module directory
- public $targetmodule; // Module concerned by canvas (ex: thirdparty, contact, ...)
- public $canvas; // Name of canvas (ex: company, individual, product, service, ...)
- public $card; // Tab (sub-canvas)
+ public $dirmodule; // Module directory
+ public $targetmodule; // Module concerned by canvas (ex: thirdparty, contact, ...)
+ public $canvas; // Name of canvas (ex: company, individual, product, service, ...)
+ public $card; // Tab (sub-canvas)
- public $template_dir; // Initialized by getCanvas with templates directory
- public $control; // Initialized by getCanvas with controller instance
+ public $template_dir; // Initialized by getCanvas with templates directory
+ public $control; // Initialized by getCanvas with controller instance
/**
@@ -76,9 +76,9 @@ class Canvas
private function _cleanaction($action)
{
$newaction = $action;
- if ($newaction == 'add') $newaction='create';
- if ($newaction == 'update') $newaction='edit';
- if (empty($newaction) || $newaction == 'delete' || $newaction == 'create_user' || $newaction == 'presend' || $newaction == 'send') $newaction='view';
+ if ($newaction == 'add') $newaction = 'create';
+ if ($newaction == 'update') $newaction = 'edit';
+ if (empty($newaction) || $newaction == 'delete' || $newaction == 'create_user' || $newaction == 'presend' || $newaction == 'send') $newaction = 'view';
return $newaction;
}
@@ -114,7 +114,7 @@ class Canvas
if (file_exists($controlclassfile))
{
// Include actions class (controller)
- $this->control_file=$controlclassfile;
+ $this->control_file = $controlclassfile;
require_once $controlclassfile;
// Instantiate actions class (controller)
@@ -124,9 +124,9 @@ class Canvas
// Template dir
$this->template_dir = dol_buildpath('/'.$this->dirmodule.'/canvas/'.$this->canvas.'/tpl/');
- if (! is_dir($this->template_dir))
+ if (!is_dir($this->template_dir))
{
- $this->template_dir='';
+ $this->template_dir = '';
}
//print 'dimodule='.$dirmodule.' canvas='.$this->canvas.' ';
@@ -158,7 +158,7 @@ class Canvas
{
if (empty($this->template_dir)) return 0;
- if (file_exists($this->template_dir.(!empty($this->card)?$this->card.'_':'').$this->_cleanaction($action).'.tpl.php')) return 1;
+ if (file_exists($this->template_dir.(!empty($this->card) ? $this->card.'_' : '').$this->_cleanaction($action).'.tpl.php')) return 1;
else return 0;
}
@@ -176,7 +176,8 @@ class Canvas
global $db, $conf, $langs, $user, $canvas;
global $form, $formfile;
- include $this->template_dir.(!empty($this->card)?$this->card.'_':'').$this->_cleanaction($action).'.tpl.php'; // Include native PHP template
+ //var_dump($this->card.'-'.$action);
+ include $this->template_dir.(!empty($this->card) ? $this->card.'_' : '').$this->_cleanaction($action).'.tpl.php'; // Include native PHP template
}
diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php
index dc4cbeff1ac..279eb1f7a6b 100644
--- a/htdocs/core/class/commondocgenerator.class.php
+++ b/htdocs/core/class/commondocgenerator.class.php
@@ -49,6 +49,10 @@ abstract class CommonDocGenerator
*/
protected $db;
+ /**
+ * @var Extrafields object
+ */
+ public $extrafieldsCache;
/**
* Constructor
@@ -217,24 +221,24 @@ abstract class CommonDocGenerator
);
// Retrieve extrafields
- if(is_array($object->array_options) && count($object->array_options))
+ if (is_array($object->array_options) && count($object->array_options))
{
require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
$extrafields = new ExtraFields($this->db);
$extrafields->fetch_name_optionals_label($object->table_element, true);
$object->fetch_optionals();
- foreach($extrafields->attributes[$object->table_element]['label'] as $key=>$label)
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key=>$label)
{
- if($extrafields->attributes[$object->table_element]['type'][$key] == 'price')
+ if ($extrafields->attributes[$object->table_element]['type'][$key] == 'price')
{
$object->array_options['options_'.$key] = price($object->array_options['options_'.$key], 0, $outputlangs, 0, 0, -1, $conf->currency);
}
- elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'select' || $extrafields->attributes[$object->table_element]['type'][$key] == 'checkbox')
+ elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'select' || $extrafields->attributes[$object->table_element]['type'][$key] == 'checkbox')
{
$object->array_options['options_'.$key] = $extrafields->attributes[$object->table_element]['param'][$key]['options'][$object->array_options['options_'.$key]];
}
- $array_thirdparty = array_merge($array_thirdparty, array ('company_options_'.$key => $object->array_options ['options_' . $key]));
+ $array_thirdparty = array_merge($array_thirdparty, array('company_options_'.$key => $object->array_options ['options_'.$key]));
}
}
return $array_thirdparty;
@@ -254,61 +258,61 @@ abstract class CommonDocGenerator
// phpcs:enable
global $conf;
- if(empty($object->country) && ! empty($object->country_code))
+ if (empty($object->country) && !empty($object->country_code))
{
- $object->country = $outputlangs->transnoentitiesnoconv("Country" . $object->country_code);
+ $object->country = $outputlangs->transnoentitiesnoconv("Country".$object->country_code);
}
- if(empty($object->state) && ! empty($object->state_code))
+ if (empty($object->state) && !empty($object->state_code))
{
$object->state = getState($object->state_code, 0);
}
- $array_contact = array (
- $array_key . '_fullname' => $object->getFullName($outputlangs, 1),
- $array_key . '_lastname' => $object->lastname,
- $array_key . '_firstname' => $object->firstname,
- $array_key . '_address' => $object->address,
- $array_key . '_zip' => $object->zip,
- $array_key . '_town' => $object->town,
- $array_key . '_state_id' => $object->state_id,
- $array_key . '_state_code' => $object->state_code,
- $array_key . '_state' => $object->state,
- $array_key . '_country_id' => $object->country_id,
- $array_key . '_country_code' => $object->country_code,
- $array_key . '_country' => $object->country,
- $array_key . '_poste' => $object->poste,
- $array_key . '_socid' => $object->socid,
- $array_key . '_statut' => $object->statut,
- $array_key . '_code' => $object->code,
- $array_key . '_email' => $object->email,
- $array_key . '_jabberid' => $object->jabberid,
- $array_key . '_phone_pro' => $object->phone_pro,
- $array_key . '_phone_perso' => $object->phone_perso,
- $array_key . '_phone_mobile' => $object->phone_mobile,
- $array_key . '_fax' => $object->fax,
- $array_key . '_birthday' => $object->birthday,
- $array_key . '_default_lang' => $object->default_lang,
- $array_key . '_note_public' => $object->note_public,
- $array_key . '_note_private' => $object->note_private
+ $array_contact = array(
+ $array_key.'_fullname' => $object->getFullName($outputlangs, 1),
+ $array_key.'_lastname' => $object->lastname,
+ $array_key.'_firstname' => $object->firstname,
+ $array_key.'_address' => $object->address,
+ $array_key.'_zip' => $object->zip,
+ $array_key.'_town' => $object->town,
+ $array_key.'_state_id' => $object->state_id,
+ $array_key.'_state_code' => $object->state_code,
+ $array_key.'_state' => $object->state,
+ $array_key.'_country_id' => $object->country_id,
+ $array_key.'_country_code' => $object->country_code,
+ $array_key.'_country' => $object->country,
+ $array_key.'_poste' => $object->poste,
+ $array_key.'_socid' => $object->socid,
+ $array_key.'_statut' => $object->statut,
+ $array_key.'_code' => $object->code,
+ $array_key.'_email' => $object->email,
+ $array_key.'_jabberid' => $object->jabberid,
+ $array_key.'_phone_pro' => $object->phone_pro,
+ $array_key.'_phone_perso' => $object->phone_perso,
+ $array_key.'_phone_mobile' => $object->phone_mobile,
+ $array_key.'_fax' => $object->fax,
+ $array_key.'_birthday' => $object->birthday,
+ $array_key.'_default_lang' => $object->default_lang,
+ $array_key.'_note_public' => $object->note_public,
+ $array_key.'_note_private' => $object->note_private
);
// Retrieve extrafields
- require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
+ require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
$extrafields = new ExtraFields($this->db);
$extrafields->fetch_name_optionals_label($object->table_element, true);
$object->fetch_optionals();
- foreach($extrafields->attributes[$object->table_element]['label'] as $key => $label)
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label)
{
if ($extrafields->attributes[$object->table_element]['type'][$key] == 'price')
{
- $object->array_options['options_' . $key] = price($object->array_options ['options_' . $key], 0, $outputlangs, 0, 0, - 1, $conf->currency);
+ $object->array_options['options_'.$key] = price($object->array_options ['options_'.$key], 0, $outputlangs, 0, 0, - 1, $conf->currency);
}
- elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'select' || $extrafields->attributes[$object->table_element]['type'][$key] == 'checkbox')
+ elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'select' || $extrafields->attributes[$object->table_element]['type'][$key] == 'checkbox')
{
- $object->array_options['options_' . $key] = $extrafields->attributes[$object->table_element]['param'][$key]['options'][$object->array_options['options_' . $key]];
+ $object->array_options['options_'.$key] = $extrafields->attributes[$object->table_element]['param'][$key]['options'][$object->array_options['options_'.$key]];
}
- $array_contact = array_merge($array_contact, array($array_key.'_options_' . $key => $object->array_options['options_'. $key]));
+ $array_contact = array_merge($array_contact, array($array_key.'_options_'.$key => $object->array_options['options_'.$key]));
}
return $array_contact;
}
@@ -474,20 +478,20 @@ abstract class CommonDocGenerator
}
// Add vat by rates
- if (is_array($object->lines) && count($object->lines)>0)
+ if (is_array($object->lines) && count($object->lines) > 0)
{
$totalUp = 0;
foreach ($object->lines as $line)
{
// $line->tva_tx format depends on database field accuraty, no reliable. This is kept for backward compatibility
- if (empty($resarray[$array_key.'_total_vat_'.$line->tva_tx])) $resarray[$array_key.'_total_vat_'.$line->tva_tx]=0;
- $resarray[$array_key.'_total_vat_'.$line->tva_tx]+=$line->total_tva;
- $resarray[$array_key.'_total_vat_locale_'.$line->tva_tx]=price($resarray[$array_key.'_total_vat_'.$line->tva_tx]);
+ if (empty($resarray[$array_key.'_total_vat_'.$line->tva_tx])) $resarray[$array_key.'_total_vat_'.$line->tva_tx] = 0;
+ $resarray[$array_key.'_total_vat_'.$line->tva_tx] += $line->total_tva;
+ $resarray[$array_key.'_total_vat_locale_'.$line->tva_tx] = price($resarray[$array_key.'_total_vat_'.$line->tva_tx]);
// $vatformated is vat without not expected chars (so 20, or 8.5 or 5.99 for example)
- $vatformated=vatrate($line->tva_tx);
- if (empty($resarray[$array_key.'_total_vat_'.$vatformated])) $resarray[$array_key.'_total_vat_'.$vatformated]=0;
- $resarray[$array_key.'_total_vat_'.$vatformated]+=$line->total_tva;
- $resarray[$array_key.'_total_vat_locale_'.$vatformated]=price($resarray[$array_key.'_total_vat_'.$vatformated]);
+ $vatformated = vatrate($line->tva_tx);
+ if (empty($resarray[$array_key.'_total_vat_'.$vatformated])) $resarray[$array_key.'_total_vat_'.$vatformated] = 0;
+ $resarray[$array_key.'_total_vat_'.$vatformated] += $line->total_tva;
+ $resarray[$array_key.'_total_vat_locale_'.$vatformated] = price($resarray[$array_key.'_total_vat_'.$vatformated]);
$totalUp += $line->subprice * $line->qty;
}
@@ -532,14 +536,16 @@ abstract class CommonDocGenerator
*
* @param Object $line Object line
* @param Translate $outputlangs Lang object to use for output
+ * @param int $linenumber The number of the line for the substitution of "object_line_pos"
* @return array Return a substitution array
*/
- public function get_substitutionarray_lines($line, $outputlangs)
+ public function get_substitutionarray_lines($line, $outputlangs, $linenumber = 0)
{
// phpcs:enable
global $conf;
$resarray = array(
+ 'line_pos' => $linenumber,
'line_fulldesc'=>doc_getlinedesc($line, $outputlangs),
'line_product_ref'=>$line->product_ref,
'line_product_ref_fourn'=>$line->ref_fourn, // for supplier doc lines
@@ -562,12 +568,12 @@ abstract class CommonDocGenerator
'line_price_ttc_locale'=>price($line->total_ttc, 0, $outputlangs),
'line_price_vat_locale'=>price($line->total_tva, 0, $outputlangs),
// Dates
- 'line_date_start'=>dol_print_date($line->date_start, 'day', 'tzuser'),
- 'line_date_start_locale'=>dol_print_date($line->date_start, 'day', 'tzuser', $outputlangs),
- 'line_date_start_rfc'=>dol_print_date($line->date_start, 'dayrfc', 'tzuser'),
- 'line_date_end'=>dol_print_date($line->date_end, 'day', 'tzuser'),
- 'line_date_end_locale'=>dol_print_date($line->date_end, 'day', 'tzuser', $outputlangs),
- 'line_date_end_rfc'=>dol_print_date($line->date_end, 'dayrfc', 'tzuser'),
+ 'line_date_start'=>dol_print_date($line->date_start, 'day'),
+ 'line_date_start_locale'=>dol_print_date($line->date_start, 'day', 'tzserver', $outputlangs),
+ 'line_date_start_rfc'=>dol_print_date($line->date_start, 'dayrfc'),
+ 'line_date_end'=>dol_print_date($line->date_end, 'day'),
+ 'line_date_end_locale'=>dol_print_date($line->date_end, 'day', 'tzserver', $outputlangs),
+ 'line_date_end_rfc'=>dol_print_date($line->date_end, 'dayrfc'),
'line_multicurrency_code' => price2num($line->multicurrency_code),
'line_multicurrency_subprice' => price2num($line->multicurrency_subprice),
@@ -583,13 +589,13 @@ abstract class CommonDocGenerator
// Units
if ($conf->global->PRODUCT_USE_UNITS)
{
- $resarray['line_unit']=$outputlangs->trans($line->getLabelOfUnit('long'));
- $resarray['line_unit_short']=$outputlangs->trans($line->getLabelOfUnit('short'));
+ $resarray['line_unit'] = $outputlangs->trans($line->getLabelOfUnit('long'));
+ $resarray['line_unit_short'] = $outputlangs->trans($line->getLabelOfUnit('short'));
}
// Retrieve extrafields
- $extrafieldkey=$line->element;
- $array_key="line";
+ $extrafieldkey = $line->element;
+ $array_key = "line";
require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
$extrafields = new ExtraFields($this->db);
$extrafields->fetch_name_optionals_label($extrafieldkey, true);
@@ -602,22 +608,33 @@ abstract class CommonDocGenerator
{
// Add the product supplier extrafields to the substitutions
$extrafields->fetch_name_optionals_label("product_fournisseur_price");
- $extralabels=$extrafields->attributes["product_fournisseur_price"]['label'];
- $columns = "";
- foreach ($extralabels as $key => $value)
- $columns .= "$key, ";
+ $extralabels = $extrafields->attributes["product_fournisseur_price"]['label'];
- if ($columns != "")
- {
- $columns = substr($columns, 0, strlen($columns) - 2);
- $resql = $this->db->query("SELECT $columns FROM " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields AS ex INNER JOIN " . MAIN_DB_PREFIX . "product_fournisseur_price AS f ON ex.fk_object = f.rowid WHERE f.ref_fourn = '" . $line->ref_supplier . "'");
- if ($this->db->num_rows($resql) > 0) {
- $resql = $this->db->fetch_object($resql);
+ if (!empty($extralabels) && is_array($extralabels))
+ {
+ $columns = "";
- foreach ($extralabels as $key => $value)
- $resarray['line_product_supplier_'.$key] = $resql->{$key};
- }
- }
+ foreach ($extralabels as $key)
+ {
+ $columns .= "$key, ";
+ }
+
+ if ($columns != "")
+ {
+ $columns = substr($columns, 0, strlen($columns) - 2);
+ $resql = $this->db->query("SELECT $columns FROM ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields AS ex INNER JOIN ".MAIN_DB_PREFIX."product_fournisseur_price AS f ON ex.fk_object = f.rowid WHERE f.ref_fourn = '".$line->ref_supplier."'");
+
+ if ($this->db->num_rows($resql) > 0)
+ {
+ $resql = $this->db->fetch_object($resql);
+
+ foreach ($extralabels as $key)
+ {
+ $resarray['line_product_supplier_'.$key] = $resql->{$key};
+ }
+ }
+ }
+ }
}
// Load product data optional fields to the line -> enables to use "line_options_{extrafield}"
@@ -720,14 +737,14 @@ abstract class CommonDocGenerator
'line_qty'=>$line->qty,
'line_qty_shipped'=>$line->qty_shipped,
'line_qty_asked'=>$line->qty_asked,
- 'line_discount_percent'=>($line->remise_percent?$line->remise_percent.'%':''),
+ 'line_discount_percent'=>($line->remise_percent ? $line->remise_percent.'%' : ''),
'line_price_ht'=>price($line->total_ht),
'line_price_ttc'=>price($line->total_ttc),
'line_price_vat'=>price($line->total_tva),
- 'line_weight'=>empty($line->weight) ? '' : $line->weight*$line->qty_shipped.' '.measuringUnitString(0, 'weight', $line->weight_units),
- 'line_length'=>empty($line->length) ? '' : $line->length*$line->qty_shipped.' '.measuringUnitString(0, 'size', $line->length_units),
- 'line_surface'=>empty($line->surface) ? '' : $line->surface*$line->qty_shipped.' '.measuringUnitString(0, 'surface', $line->surface_units),
- 'line_volume'=>empty($line->volume) ? '' : $line->volume*$line->qty_shipped.' '.measuringUnitString(0, 'volume', $line->volume_units),
+ 'line_weight'=>empty($line->weight) ? '' : $line->weight * $line->qty_shipped.' '.measuringUnitString(0, 'weight', $line->weight_units),
+ 'line_length'=>empty($line->length) ? '' : $line->length * $line->qty_shipped.' '.measuringUnitString(0, 'size', $line->length_units),
+ 'line_surface'=>empty($line->surface) ? '' : $line->surface * $line->qty_shipped.' '.measuringUnitString(0, 'surface', $line->surface_units),
+ 'line_volume'=>empty($line->volume) ? '' : $line->volume * $line->qty_shipped.' '.measuringUnitString(0, 'volume', $line->volume_units),
);
// Retrieve extrafields
@@ -788,81 +805,84 @@ abstract class CommonDocGenerator
{
// phpcs:enable
global $conf;
- foreach($extrafields->attributes[$object->table_element]['label'] as $key=>$label)
- {
- if($extrafields->attributes[$object->table_element]['type'][$key] == 'price')
+
+ if (is_array($extrafields->attributes[$object->table_element]['label'])) {
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key=>$label)
{
- $object->array_options['options_'.$key] = price2num($object->array_options['options_'.$key]);
- $object->array_options['options_'.$key.'_currency'] = price($object->array_options['options_'.$key], 0, $outputlangs, 0, 0, -1, $conf->currency);
- //Add value to store price with currency
- $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_currency' => $object->array_options['options_'.$key.'_currency']));
- }
- elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'select')
- {
- $object->array_options['options_'.$key] = $extrafields->attributes[$object->table_element]['param'][$key]['options'][$object->array_options['options_'.$key]];
- }
- elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'checkbox') {
- $valArray=explode(',', $object->array_options['options_'.$key]);
- $output=array();
- foreach($extrafields->attributes[$object->table_element]['param'][$key]['options'] as $keyopt=>$valopt) {
- if (in_array($keyopt, $valArray)) {
- $output[]=$valopt;
+ if ($extrafields->attributes[$object->table_element]['type'][$key] == 'price')
+ {
+ $object->array_options['options_'.$key] = price2num($object->array_options['options_'.$key]);
+ $object->array_options['options_'.$key.'_currency'] = price($object->array_options['options_'.$key], 0, $outputlangs, 0, 0, -1, $conf->currency);
+ //Add value to store price with currency
+ $array_to_fill = array_merge($array_to_fill, array($array_key.'_options_'.$key.'_currency' => $object->array_options['options_'.$key.'_currency']));
+ }
+ elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'select')
+ {
+ $object->array_options['options_'.$key] = $extrafields->attributes[$object->table_element]['param'][$key]['options'][$object->array_options['options_'.$key]];
+ }
+ elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'checkbox') {
+ $valArray = explode(',', $object->array_options['options_'.$key]);
+ $output = array();
+ foreach ($extrafields->attributes[$object->table_element]['param'][$key]['options'] as $keyopt=>$valopt) {
+ if (in_array($keyopt, $valArray)) {
+ $output[] = $valopt;
+ }
}
+ $object->array_options['options_'.$key] = implode(', ', $output);
}
- $object->array_options['options_'.$key] = implode(', ', $output);
- }
- elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'date')
- {
- if (strlen($object->array_options['options_'.$key])>0)
+ elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'date')
{
- $date = $object->array_options['options_'.$key];
- $object->array_options['options_'.$key] = dol_print_date($date, 'day'); // using company output language
- $object->array_options['options_'.$key.'_locale'] = dol_print_date($date, 'day', 'tzserver', $outputlangs); // using output language format
- $object->array_options['options_'.$key.'_rfc'] = dol_print_date($date, 'dayrfc'); // international format
- }
- else
- {
- $object->array_options['options_'.$key] = '';
- $object->array_options['options_'.$key.'_locale'] = '';
- $object->array_options['options_'.$key.'_rfc'] = '';
- }
- $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale']));
- $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc']));
- }
- elseif($extrafields->attributes[$object->table_element]['label'][$key] == 'datetime')
- {
- $datetime = $object->array_options['options_'.$key];
- $object->array_options['options_'.$key] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhour'):''); // using company output language
- $object->array_options['options_'.$key.'_locale'] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhour', 'tzserver', $outputlangs):''); // using output language format
- $object->array_options['options_'.$key.'_rfc'] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhourrfc'):''); // international format
- $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale']));
- $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc']));
- }
- elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'link')
- {
- $id = $object->array_options['options_'.$key];
- if ($id != "")
- {
- $param = $extrafields->attributes[$object->table_element]['param'][$key];
- $param_list=array_keys($param['options']); // $param_list='ObjectName:classPath'
- $InfoFieldList = explode(":", $param_list[0]);
- $classname=$InfoFieldList[0];
- $classpath=$InfoFieldList[1];
- if (! empty($classpath))
+ if (strlen($object->array_options['options_'.$key]) > 0)
{
- dol_include_once($InfoFieldList[1]);
- if ($classname && class_exists($classname))
+ $date = $object->array_options['options_'.$key];
+ $object->array_options['options_'.$key] = dol_print_date($date, 'day'); // using company output language
+ $object->array_options['options_'.$key.'_locale'] = dol_print_date($date, 'day', 'tzserver', $outputlangs); // using output language format
+ $object->array_options['options_'.$key.'_rfc'] = dol_print_date($date, 'dayrfc'); // international format
+ }
+ else
+ {
+ $object->array_options['options_'.$key] = '';
+ $object->array_options['options_'.$key.'_locale'] = '';
+ $object->array_options['options_'.$key.'_rfc'] = '';
+ }
+ $array_to_fill = array_merge($array_to_fill, array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale']));
+ $array_to_fill = array_merge($array_to_fill, array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc']));
+ }
+ elseif ($extrafields->attributes[$object->table_element]['label'][$key] == 'datetime')
+ {
+ $datetime = $object->array_options['options_'.$key];
+ $object->array_options['options_'.$key] = ($datetime != "0000-00-00 00:00:00" ?dol_print_date($object->array_options['options_'.$key], 'dayhour') : ''); // using company output language
+ $object->array_options['options_'.$key.'_locale'] = ($datetime != "0000-00-00 00:00:00" ?dol_print_date($object->array_options['options_'.$key], 'dayhour', 'tzserver', $outputlangs) : ''); // using output language format
+ $object->array_options['options_'.$key.'_rfc'] = ($datetime != "0000-00-00 00:00:00" ?dol_print_date($object->array_options['options_'.$key], 'dayhourrfc') : ''); // international format
+ $array_to_fill = array_merge($array_to_fill, array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale']));
+ $array_to_fill = array_merge($array_to_fill, array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc']));
+ }
+ elseif ($extrafields->attributes[$object->table_element]['type'][$key] == 'link')
+ {
+ $id = $object->array_options['options_'.$key];
+ if ($id != "")
+ {
+ $param = $extrafields->attributes[$object->table_element]['param'][$key];
+ $param_list = array_keys($param['options']); // $param_list='ObjectName:classPath'
+ $InfoFieldList = explode(":", $param_list[0]);
+ $classname = $InfoFieldList[0];
+ $classpath = $InfoFieldList[1];
+ if (!empty($classpath))
{
- $tmpobject = new $classname($this->db);
- $tmpobject->fetch($id);
- // completely replace the id with the linked object name
- $object->array_options['options_'.$key] = $tmpobject->name;
+ dol_include_once($InfoFieldList[1]);
+ if ($classname && class_exists($classname))
+ {
+ $tmpobject = new $classname($this->db);
+ $tmpobject->fetch($id);
+ // completely replace the id with the linked object name
+ $object->array_options['options_'.$key] = $tmpobject->name;
+ }
}
}
}
- }
- $array_to_fill = array_merge($array_to_fill, array($array_key.'_options_'.$key => $object->array_options['options_'.$key]));
+ $array_to_fill = array_merge($array_to_fill, array($array_key.'_options_'.$key => $object->array_options['options_'.$key]));
+ }
}
return $array_to_fill;
@@ -928,27 +948,27 @@ abstract class CommonDocGenerator
uasort($this->cols, array($this, 'columnSort'));
// Positionning
- $curX = $this->page_largeur-$this->marge_droite; // start from right
+ $curX = $this->page_largeur - $this->marge_droite; // start from right
// Array width
- $arrayWidth = $this->page_largeur-$this->marge_droite-$this->marge_gauche;
+ $arrayWidth = $this->page_largeur - $this->marge_droite - $this->marge_gauche;
// Count flexible column
$totalDefinedColWidth = 0;
$countFlexCol = 0;
foreach ($this->cols as $colKey =>& $colDef)
{
- if(!$this->getColumnStatus($colKey)) continue; // continue if disabled
+ if (!$this->getColumnStatus($colKey)) continue; // continue if disabled
- if(!empty($colDef['scale'])){
+ if (!empty($colDef['scale'])) {
// In case of column width is defined by percentage
$colDef['width'] = abs($arrayWidth * $colDef['scale'] / 100);
}
- if(empty($colDef['width'])){
+ if (empty($colDef['width'])) {
$countFlexCol++;
}
- else{
+ else {
$totalDefinedColWidth += $colDef['width'];
}
}
@@ -1070,11 +1090,11 @@ abstract class CommonDocGenerator
/**
* print standard column content
*
- * @param PDF $pdf pdf object
+ * @param TCPDF $pdf pdf object
* @param float $curY curent Y position
* @param string $colKey the column key
* @param string $columnText column text
- * @return int new rank on success and -1 on error
+ * @return null
*/
public function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '')
{
@@ -1090,13 +1110,295 @@ abstract class CommonDocGenerator
if (!$reshook)
{
if (empty($columnText)) return;
- $pdf->SetXY($this->getColumnContentXStart($colKey) - 1, $curY); // Set curent position
+ $pdf->SetXY($this->getColumnContentXStart($colKey), $curY); // Set curent position
$colDef = $this->cols[$colKey];
- $pdf->writeHTMLCell($this->getColumnContentWidth($colKey) + 2, 2, $this->getColumnContentXStart($colKey) - 1, $curY, $columnText, 0, 0, 0, true, $colDef['content']['align']);
+ // save curent cell padding
+ $curentCellPaddinds = $pdf->getCellPaddings();
+ // set cell padding with column content definition
+ $pdf->setCellPaddings($colDef['content']['padding'][3], $colDef['content']['padding'][0], $colDef['content']['padding'][1], $colDef['content']['padding'][2]);
+ $pdf->writeHTMLCell($colDef['width'], 2, $colDef['xStartPos'], $curY, $columnText, 0, 1, 0, true, $colDef['content']['align']);
+
+ // restore cell padding
+ $pdf->setCellPaddings($curentCellPaddinds['L'], $curentCellPaddinds['T'], $curentCellPaddinds['R'], $curentCellPaddinds['B']);
}
}
+ /**
+ * print description column content
+ *
+ * @param TCPDF $pdf pdf object
+ * @param float $curY curent Y position
+ * @param string $colKey the column key
+ * @param object $object CommonObject
+ * @param int $i the $object->lines array key
+ * @param Translate $outputlangs Output language
+ * @param int $hideref hide ref
+ * @param int $hidedesc hide desc
+ * @param int $issupplierline if object need supplier product
+ * @return null
+ */
+ public function printColDescContent($pdf, &$curY, $colKey, $object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $issupplierline = 0)
+ {
+ // load desc col params
+ $colDef = $this->cols[$colKey];
+ // save curent cell padding
+ $curentCellPaddinds = $pdf->getCellPaddings();
+ // set cell padding with column content definition
+ $pdf->setCellPaddings($colDef['content']['padding'][3], $colDef['content']['padding'][0], $colDef['content']['padding'][1], $colDef['content']['padding'][2]);
+
+ // line description
+ pdf_writelinedesc($pdf, $object, $i, $outputlangs, $colDef['width'], 3, $colDef['xStartPos'], $curY, $hideref, $hidedesc, $issupplierline);
+ $posYAfterDescription = $pdf->GetY() - $colDef['content']['padding'][0];
+
+ // restore cell padding
+ $pdf->setCellPaddings($curentCellPaddinds['L'], $curentCellPaddinds['T'], $curentCellPaddinds['R'], $curentCellPaddinds['B']);
+
+ // Display extrafield if needed
+ $params = array(
+ 'display' => 'list',
+ 'printableEnable' => array(3),
+ 'printableEnableNotEmpty' => array(4)
+ );
+ $extrafieldDesc = $this->getExtrafieldsInHtml($object->lines[$i], $outputlangs, $params);
+ if (!empty($extrafieldDesc)) {
+ $this->printStdColumnContent($pdf, $posYAfterDescription, $colKey, $extrafieldDesc);
+ }
+ }
+
+ /**
+ * get extrafield content for pdf writeHtmlCell compatibility
+ * usage for PDF line columns and object note block
+ *
+ * @param object $object common object
+ * @param string $extrafieldKey the extrafield key
+ * @return string
+ */
+ public function getExtrafieldContent($object, $extrafieldKey)
+ {
+ global $hookmanager;
+
+ if (empty($object->table_element)) { return; }
+
+ $extrafieldsKeyPrefix = "options_";
+
+ // Cleanup extrafield key to remove prefix if present
+ $pos = strpos($extrafieldKey, $extrafieldsKeyPrefix);
+ if ($pos === 0) {
+ $extrafieldKey = substr($extrafieldKey, strlen($extrafieldsKeyPrefix));
+ }
+
+ $extrafieldOptionsKey = $extrafieldsKeyPrefix.$extrafieldKey;
+
+
+ // Load extrafiels if not allready does
+ if (empty($this->extrafieldsCache)) { $this->extrafieldsCache = new ExtraFields($this->db); }
+ if (empty($this->extrafieldsCache->attributes[$object->table_element])) { $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); }
+ $extrafields = $this->extrafieldsCache;
+
+ $extrafieldOutputContent = $extrafields->showOutputField($extrafieldKey, $object->array_options[$extrafieldOptionsKey], '', $object->table_element);
+
+ // TODO : allow showOutputField to be pdf public friendly, ex: in a link to object, clean getNomUrl to remove link and images... like a getName methode ...
+ if ($extrafields->attributes[$object->table_element]['type'][$extrafieldKey] == 'link') {
+ // for lack of anything better we cleanup all html tags
+ $extrafieldOutputContent = dol_string_nohtmltag($extrafieldOutputContent);
+ }
+
+ $parameters = array(
+ 'object' => $object,
+ 'extrafields' => $extrafields,
+ 'extrafieldKey' => $extrafieldKey,
+ 'extrafieldOutputContent' =>& $extrafieldOutputContent
+ );
+ $reshook = $hookmanager->executeHooks('getPDFExtrafieldContent', $parameters, $this); // Note that $action and $object may have been modified by hook
+ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+ if ($reshook)
+ {
+ $extrafieldOutputContent = $hookmanager->resPrint;
+ }
+
+ return $extrafieldOutputContent;
+ }
+
+
+ /**
+ * display extrafields columns content
+ *
+ * @param object $object line of common object
+ * @param Translate $outputlangs Output language
+ * @param array $params array of additionals parameters
+ * @return double max y value
+ */
+ public function getExtrafieldsInHtml($object, $outputlangs, $params = array())
+ {
+ global $hookmanager;
+
+ if (empty($object->table_element)) {
+ return;
+ }
+
+ // Load extrafiels if not allready does
+ if (empty($this->extrafieldsCache)) { $this->extrafieldsCache = new ExtraFields($this->db); }
+ if (empty($this->extrafieldsCache->attributes[$object->table_element])) { $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); }
+ $extrafields = $this->extrafieldsCache;
+
+ $defaultParams = array(
+ 'style' => '',
+ 'display' => 'auto', // auto, table, list
+ 'printableEnable' => array(1),
+ 'printableEnableNotEmpty' => array(2),
+
+ 'table' => array(
+ 'maxItemsInRow' => 2,
+ 'cellspacing' => 0,
+ 'cellpadding' => 0,
+ 'border' => 0,
+ 'labelcolwidth' => '25%',
+ 'arrayOfLineBreakType' => array('text', 'html')
+ ),
+
+ 'list' => array(
+ 'separator' => ' '
+ ),
+
+ 'auto' => array(
+ 'list' => 0, // 0 for default
+ 'table' => 4 // if there more than x extrafield to display
+ ),
+ );
+
+ $params = $params + $defaultParams;
+
+
+ /**
+ * @var $extrafields ExtraFields
+ */
+
+ $html = '';
+ $fields = array();
+
+ if (is_array($extrafields->attributes[$object->table_element]['label'])) {
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label)
+ {
+ // Enable extrafield ?
+ $enabled = 0;
+ $disableOnEmpty = 0;
+ if (!empty($extrafields->attributes[$object->table_element]['printable'][$key])) {
+ $printable = intval($extrafields->attributes[$object->table_element]['printable'][$key]);
+ if (in_array($printable, $params['printableEnable']) || in_array($printable, $params['printableEnableNotEmpty'])) {
+ $enabled = 1;
+ }
+
+ if (in_array($printable, $params['printableEnableNotEmpty'])) {
+ $disableOnEmpty = 1;
+ }
+ }
+
+ if (empty($enabled)) {
+ continue;
+ }
+
+ $field = new stdClass();
+ $field->rank = intval($extrafields->attributes[$object->table_element]['pos'][$key]);
+ $field->content = $this->getExtrafieldContent($object, $key);
+ $field->label = $outputlangs->transnoentities($label);
+ $field->type = $extrafields->attributes[$object->table_element]['type'][$key];
+
+ // dont display if empty
+ if ($disableOnEmpty && empty($field->content)) {
+ continue;
+ }
+
+ $fields[] = $field;
+ }
+ }
+
+ if (!empty($fields))
+ {
+ // Sort extrafields by rank
+ uasort($fields, function ($a, $b) {
+ return ($a->rank > $b->rank) ? -1 : 1;
+ });
+
+ // define some HTML content with style
+ $html .= !empty($params['style']) ? '' : '';
+
+ // auto select display format
+ if ($params['display'] == 'auto') {
+ $lastNnumbItems = 0;
+ foreach ($params['auto'] as $display => $numbItems) {
+ if ($lastNnumbItems <= $numbItems && count($fields) > $numbItems) {
+ $lastNnumbItems = $numbItems;
+ $params['display'] = $display;
+ }
+ }
+ }
+
+ if ($params['display'] == 'list') {
+ // Display in list format
+ $i = 0;
+ foreach ($fields as $field) {
+ $html .= !empty($i) ? $params['list']['separator'] : '';
+ $html .= ''.$field->label.' : ';
+ $html .= $field->content;
+ $i++;
+ }
+ }
+ elseif ($params['display'] == 'table') {
+ // Display in table format
+ $html .= '';
+ }
+ }
+
+ return $html;
+ }
+
+
/**
* get column status from column key
*
@@ -1114,7 +1416,7 @@ abstract class CommonDocGenerator
/**
* Print standard column content
*
- * @param PDF $pdf Pdf object
+ * @param TCPDI $pdf Pdf object
* @param float $tab_top Tab top position
* @param float $tab_height Default tab height
* @param Translate $outputlangs Output language
@@ -1150,21 +1452,123 @@ abstract class CommonDocGenerator
}
if (empty($hidetop)) {
- $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0]);
- $textWidth = $colDef['width'] - $colDef['title']['padding'][3] - $colDef['title']['padding'][1];
- $pdf->MultiCell($textWidth, 2, $colDef['title']['label'], '', $colDef['title']['align']);
+ // save curent cell padding
+ $curentCellPaddinds = $pdf->getCellPaddings();
global $outputlangsbis;
if (is_object($outputlangsbis)) {
- $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] + 4);
+ // set cell padding with column title definition
+ $pdf->setCellPaddings($colDef['title']['padding'][3], $colDef['title']['padding'][0], $colDef['title']['padding'][1], 0.5);
+ }
+ else {
+ // set cell padding with column title definition
+ $pdf->setCellPaddings($colDef['title']['padding'][3], $colDef['title']['padding'][0], $colDef['title']['padding'][1], $colDef['title']['padding'][2]);
+ }
+
+ $pdf->SetXY($colDef['xStartPos'], $tab_top);
+ $textWidth = $colDef['width'];
+ $pdf->MultiCell($textWidth, 2, $colDef['title']['label'], '', $colDef['title']['align']);
+
+
+ if (is_object($outputlangsbis)) {
+ $pdf->setCellPaddings($colDef['title']['padding'][3], 0, $colDef['title']['padding'][1], $colDef['title']['padding'][2]);
+ $pdf->SetXY($colDef['xStartPos'], $pdf->GetY());
$textbis = $outputlangsbis->transnoentities($colDef['title']['textkey']);
$pdf->MultiCell($textWidth, 2, $textbis, '', $colDef['title']['align']);
}
- $this->tabTitleHeight = max($pdf->GetY() - $tab_top + $colDef['title']['padding'][2], $this->tabTitleHeight);
+ $this->tabTitleHeight = max($pdf->GetY() - $tab_top, $this->tabTitleHeight);
+
+ // restore cell padding
+ $pdf->setCellPaddings($curentCellPaddinds['L'], $curentCellPaddinds['T'], $curentCellPaddinds['R'], $curentCellPaddinds['B']);
}
}
}
return $this->tabTitleHeight;
}
+
+
+
+ /**
+ * Define Array Column Field for extrafields
+ *
+ * @param object $object common object det
+ * @param Translate $outputlangs langs
+ * @param int $hidedetails Do not show line details
+ * @return null
+ */
+ public function defineColumnExtrafield($object, $outputlangs, $hidedetails = 0)
+ {
+ global $conf;
+
+ if (!empty($hidedetails)) {
+ return;
+ }
+
+ if (empty($object->table_element)) {
+ return;
+ }
+
+ // Load extrafiels if not allready does
+ if (empty($this->extrafieldsCache)) { $this->extrafieldsCache = new ExtraFields($this->db); }
+ if (empty($this->extrafieldsCache->attributes[$object->table_element])) { $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); }
+ $extrafields = $this->extrafieldsCache;
+
+
+ if (!empty($extrafields->attributes[$object->table_element]) && is_array($extrafields->attributes[$object->table_element]['label'])) {
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label)
+ {
+ // Dont display separator yet even is set to be displayed (not compatible yet)
+ if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate')
+ {
+ continue;
+ }
+
+ // Enable extrafield ?
+ $enabled = 0;
+ if (!empty($extrafields->attributes[$object->table_element]['printable'][$key])) {
+ $printable = intval($extrafields->attributes[$object->table_element]['printable'][$key]);
+ if ($printable === 1 || $printable === 2) {
+ $enabled = 1;
+ }
+ // Note : if $printable === 3 or 4 so, it's displayed after line description not in cols
+ }
+
+ if (!$enabled) { continue; } // don't wast resourses if we don't need them...
+
+ // Load language if required
+ if (!empty($extrafields->attributes[$object->table_element]['langfile'][$key])) $outputlangs->load($extrafields->attributes[$object->table_element]['langfile'][$key]);
+
+ // TODO : add more extrafield customisation capacities for PDF like width, rank...
+
+ // set column definition
+ $def = array(
+ 'rank' => intval($extrafields->attributes[$object->table_element]['pos'][$key]),
+ 'width' => 25, // in mm
+ 'status' => boolval($enabled),
+ 'title' => array(
+ 'label' => $outputlangs->transnoentities($label)
+ ),
+ 'content' => array(
+ 'align' => 'C'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+ $alignTypeRight = array('double', 'int', 'price');
+ if (in_array($extrafields->attributes[$object->table_element]['type'][$key], $alignTypeRight)) {
+ $def['content']['align'] = 'R';
+ }
+
+ $alignTypeLeft = array('text', 'html');
+ if (in_array($extrafields->attributes[$object->table_element]['type'][$key], $alignTypeLeft)) {
+ $def['content']['align'] = 'L';
+ }
+
+
+ // for extrafields we use rank of extrafield to place it on PDF
+ $this->insertNewColumnDef("options_".$key, $def);
+ }
+ }
+ }
}
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index c7dbab57b31..04d7fc1f4a4 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -337,7 +337,7 @@ abstract class CommonObject
/**
* @deprecated
- * @see $note_public
+ * @see $note_private
*/
public $note;
@@ -491,6 +491,7 @@ abstract class CommonObject
return $this->error.(is_array($this->errors) ? (($this->error != '' ? ', ' : '').join(', ', $this->errors)) : '');
}
+
/**
* Return customer ref for screen output.
*
@@ -559,6 +560,28 @@ abstract class CommonObject
return dol_trunc($ret, $maxlen);
}
+ /**
+ * Return clicable link of object (with eventually picto)
+ *
+ * @param string $option Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
+ * @return string HTML Code for Kanban thumb.
+ */
+ public function getKanbanView($option = '')
+ {
+ $return = '';
+ $return .= '
';
+ $return .= '
';
+ $return .= ' '; // Can be image
+ $return .= ' ';
+ $return .= '
';
+ $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).' ';
+ $return .= '
';
+ $return .= '
';
+ $return .= '
';
+
+ return $return;
+ }
+
/**
* Return full address of contact
*
@@ -1080,7 +1103,7 @@ abstract class CommonObject
* Get array of all contacts for an object
*
* @param int $status Status of links to get (-1=all)
- * @param string $source Source of contact: external or thirdparty (llx_socpeople) or internal (llx_user)
+ * @param string $source Source of contact: 'external' or 'thirdparty' (llx_socpeople) or 'internal' (llx_user)
* @param int $list 0:Return array contains all properties, 1:Return array contains just id
* @param string $code Filter on this code of contact type ('SHIPPING', 'BILLING', ...)
* @return array|int Array of contacts, -1 if error
@@ -1242,14 +1265,15 @@ abstract class CommonObject
/**
* Return array with list of possible values for type of contacts
*
- * @param string $source 'internal', 'external' or 'all'
- * @param int $option 0=Return array id->label, 1=Return array code->label
- * @param int $activeonly 0=all status of contact, 1=only the active
- * @param string $code Type of contact (Example: 'CUSTOMER', 'SERVICE')
- * @param string $element Filter Element Type
- * @return array Array list of type of contacts (id->label if option=0, code->label if option=1)
+ * @param string $source 'internal', 'external' or 'all'
+ * @param int $option 0=Return array id->label, 1=Return array code->label
+ * @param int $activeonly 0=all status of contact, 1=only the active
+ * @param string $code Type of contact (Example: 'CUSTOMER', 'SERVICE')
+ * @param string $element Filter on 1 element type
+ * @param string $excludeelement Exclude 1 element type. Example: 'agenda'
+ * @return array Array list of type of contacts (id->label if option=0, code->label if option=1)
*/
- public function listeTypeContacts($source = 'internal', $option = 0, $activeonly = 0, $code = '', $element = '')
+ public function listeTypeContacts($source = 'internal', $option = 0, $activeonly = 0, $code = '', $element = '', $excludeelement = '')
{
// phpcs:enable
global $langs, $conf;
@@ -1260,8 +1284,12 @@ abstract class CommonObject
$sql .= " FROM ".MAIN_DB_PREFIX."c_type_contact as tc";
$sqlWhere = array();
- if (!empty($element))
+ if (!empty($element)) {
$sqlWhere[] = " tc.element='".$this->db->escape($element)."'";
+ }
+ if (!empty($excludeelement)) {
+ $sqlWhere[] = " tc.element <> '".$this->db->escape($excludeelement)."'";
+ }
if ($activeonly == 1)
$sqlWhere[] = " tc.active=1"; // only the active types
@@ -1278,24 +1306,25 @@ abstract class CommonObject
$sql .= $this->db->order('tc.element, tc.position', 'ASC');
- dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql) {
$num = $this->db->num_rows($resql);
if ($num > 0) {
while ($obj = $this->db->fetch_object($resql)) {
+ $modulename = $obj->element;
if (strpos($obj->element, 'project') !== false) {
- $element = 'projet';
+ $modulename = 'projet';
} elseif ($obj->element == 'contrat') {
$element = 'contract';
+ } elseif ($obj->element == 'action') {
+ $modulename = 'agenda';
} elseif (strpos($obj->element, 'supplier') !== false && $obj->element != 'supplier_proposal') {
- $element = 'fournisseur';
+ $modulename = 'fournisseur';
} elseif (strpos($obj->element, 'supplier') !== false && $obj->element != 'supplier_proposal') {
- $element = 'fournisseur';
- } else {
- $element = $obj->element;
+ $modulename = 'fournisseur';
}
- if ($conf->{$element}->enabled) {
+ if ($conf->{$modulename}->enabled) {
$libelle_element = $langs->trans('ContactDefault_'.$obj->element);
$transkey = "TypeContact_".$this->element."_".$source."_".$obj->code;
$libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->libelle);
@@ -1701,7 +1730,7 @@ abstract class CommonObject
$sql .= " WHERE ".$id_field." = ".$id;
- dol_syslog(get_class($this)."::".__FUNCTION__."", LOG_DEBUG);
+ dol_syslog(__METHOD__."", LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql)
{
@@ -1768,14 +1797,14 @@ abstract class CommonObject
// this->ismultientitymanaged contains
// 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table
$aliastablesociete = 's';
- if ($this->element == 'societe') $aliastablesociete = 'te'; // te as table_element
+ if ($this->element == 'societe') $aliastablesociete = 'te'; // te as table_element
$sql = "SELECT MAX(te.".$fieldid.")";
$sql .= " FROM ".(empty($nodbprefix) ?MAIN_DB_PREFIX:'').$this->table_element." as te";
if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
$sql .= ",".MAIN_DB_PREFIX."usergroup_user as ug";
}
- if (isset($this->ismultientitymanaged) && ! is_numeric($this->ismultientitymanaged)) {
+ if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) {
$tmparray = explode('@', $this->ismultientitymanaged);
$sql .= ", ".MAIN_DB_PREFIX.$tmparray[1]." as ".($tmparray[1] == 'societe' ? 's' : 'parenttable'); // If we need to link to this table to limit select to entity
}
@@ -1790,7 +1819,7 @@ abstract class CommonObject
if (!preg_match('/^\s*AND/i', $filter)) $sql .= " AND "; // For backward compatibility
$sql .= $filter;
}
- if (isset($this->ismultientitymanaged) && ! is_numeric($this->ismultientitymanaged)) {
+ if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) {
$tmparray = explode('@', $this->ismultientitymanaged);
$sql .= ' AND te.'.$tmparray[0].' = '.($tmparray[1] == 'societe' ? 's' : 'parenttable').'.rowid'; // If we need to link to this table to limit select to entity
}
@@ -1807,7 +1836,7 @@ abstract class CommonObject
$sql .= ' AND te.entity IN ('.getEntity($this->element).')';
}
}
- if (isset($this->ismultientitymanaged) && ! is_numeric($this->ismultientitymanaged) && $this->element != 'societe') {
+ if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged) && $this->element != 'societe') {
$tmparray = explode('@', $this->ismultientitymanaged);
$sql .= ' AND parenttable.entity IN ('.getEntity($tmparray[1]).')';
}
@@ -2920,7 +2949,7 @@ abstract class CommonObject
$MODULE = "MODULE_DISALLOW_UPDATE_PRICE_ORDER";
elseif ($this->element == 'facture' || $this->element == 'invoice')
$MODULE = "MODULE_DISALLOW_UPDATE_PRICE_INVOICE";
- elseif ($this->element == 'facture_fourn' || $this->element == 'supplier_invoice')
+ elseif ($this->element == 'facture_fourn' || $this->element == 'supplier_invoice' || $this->element == 'invoice_supplier')
$MODULE = "MODULE_DISALLOW_UPDATE_PRICE_SUPPLIER_INVOICE";
elseif ($this->element == 'order_supplier' || $this->element == 'supplier_order')
$MODULE = "MODULE_DISALLOW_UPDATE_PRICE_SUPPLIER_ORDER";
@@ -3340,6 +3369,9 @@ abstract class CommonObject
elseif ($objecttype == 'subscription') {
$classpath = 'adherents/class'; $module = 'adherent';
}
+ elseif ($objecttype == 'contact') {
+ $module = 'societe';
+ }
// Set classfile
$classfile = strtolower($subelement); $classname = ucfirst($subelement);
@@ -3362,6 +3394,9 @@ abstract class CommonObject
elseif ($objecttype == 'subscription') {
$classfile = 'subscription'; $classname = 'Subscription';
}
+ elseif ($objecttype == 'project' || $objecttype == 'projet') {
+ $classpath = 'projet/class'; $classfile = 'project'; $classname = 'Project';
+ }
// Here $module, $classfile and $classname are set
if ($conf->$module->enabled && (($element != $this->element) || $alsosametype))
@@ -4744,6 +4779,7 @@ abstract class CommonObject
{
if (!dol_is_file($srctemplatepath))
{
+ dol_syslog("Failed to locate template file ".$srctemplatepath, LOG_WARNING);
$this->error = 'ErrorGenerationAskedForOdtTemplateWithSrcFileNotFound';
return -1;
}
@@ -4944,7 +4980,7 @@ abstract class CommonObject
global $conf, $_POST;
// If param here has been posted, we use this value first.
- if (isset($_POST[$fieldname])) return GETPOST($fieldname, 2);
+ if (GETPOSTISSET($fieldname)) return GETPOST($fieldname, 'alphanohtml', 3);
if (isset($alternatevalue)) return $alternatevalue;
@@ -5384,7 +5420,7 @@ abstract class CommonObject
// Add field of attribute
if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] != 'separate') // Only for other type than separator)
{
- if ($new_array_options[$key] != '')
+ if ($new_array_options[$key] != '' || $new_array_options[$key] == '0')
{
$sql .= ",'".$this->db->escape($new_array_options[$key])."'";
}
@@ -5486,7 +5522,7 @@ abstract class CommonObject
$this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel);
return -1;
}
- elseif ($value == '')
+ elseif ($value === '')
{
$this->array_options["options_".$key] = null;
}
@@ -5499,7 +5535,7 @@ abstract class CommonObject
$this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel);
return -1;
}
- elseif ($value == '')
+ elseif ($value === '')
{
$this->array_options["options_".$key] = null;
}
@@ -5557,7 +5593,7 @@ abstract class CommonObject
if ($error)
{
- dol_syslog(get_class($this)."::".__METHOD__.$this->error, LOG_ERR);
+ dol_syslog(__METHOD__.$this->error, LOG_ERR);
$this->db->rollback();
return -1;
}
@@ -5595,7 +5631,7 @@ abstract class CommonObject
$form = new Form($this->db);
}
- if (! empty($this->fields)) {
+ if (!empty($this->fields)) {
$val = $this->fields[$key];
}
@@ -6624,7 +6660,12 @@ abstract class CommonObject
if (is_array($params) && array_key_exists('onlykey', $params) && $key != $params['onlykey']) continue;
// @todo Add test also on 'enabled' (different than 'list' that is 'visibility')
- //$enabled = 1;
+ $enabled = 1;
+ if ($enabled && isset($extrafields->attributes[$this->table_element]['enabled'][$key]))
+ {
+ $enabled = dol_eval($extrafields->attributes[$this->table_element]['enabled'][$key], 1);
+ }
+ if (empty($enabled)) continue;
$visibility = 1;
if ($visibility && isset($extrafields->attributes[$this->table_element]['list'][$key]))
@@ -6757,7 +6798,8 @@ abstract class CommonObject
if ($mode != 'view' && !empty($extrafields->attributes[$this->table_element]['required'][$key])) $out .= ' * ';
} else {
if ($mode != 'view' && !empty($extrafields->attributes[$this->table_element]['required'][$key])) $out .= ' fieldrequired';
- $out .= '">';
+ $out .= '"';
+ $out .= '>';
if (!empty($extrafields->attributes[$this->table_element]['help'][$key])) $out .= $form->textwithpicto($labeltoshow, $extrafields->attributes[$this->table_element]['help'][$key]);
else $out .= $labeltoshow;
}
diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php
index 4f5602fc5ef..9a804256dac 100644
--- a/htdocs/core/class/conf.class.php
+++ b/htdocs/core/class/conf.class.php
@@ -293,30 +293,30 @@ class Conf
$rootfortemp = empty($this->global->MAIN_TEMP_DIR) ? $rootfordata : $this->global->MAIN_TEMP_DIR;
// Define default dir_output and dir_temp for directories of modules
- foreach($this->modules as $module)
+ foreach ($this->modules as $module)
{
//var_dump($module);
// For multicompany sharings
- $this->$module->multidir_output = array($this->entity => $rootfordata."/".$module);
- $this->$module->multidir_temp = array($this->entity => $rootfortemp."/".$module."/temp");
+ $this->$module->multidir_output = array($this->entity => $rootfordata."/".$module);
+ $this->$module->multidir_temp = array($this->entity => $rootfortemp."/".$module."/temp");
// For backward compatibility
- $this->$module->dir_output = $rootfordata."/".$module;
- $this->$module->dir_temp = $rootfortemp."/".$module."/temp";
+ $this->$module->dir_output = $rootfordata."/".$module;
+ $this->$module->dir_temp = $rootfortemp."/".$module."/temp";
}
// External modules storage
- if (! empty($this->modules_parts['dir']))
+ if (!empty($this->modules_parts['dir']))
{
- foreach($this->modules_parts['dir'] as $module => $dirs)
+ foreach ($this->modules_parts['dir'] as $module => $dirs)
{
- if (! empty($this->$module->enabled))
+ if (!empty($this->$module->enabled))
{
- foreach($dirs as $type => $name) // $type is 'output' or 'temp'
+ foreach ($dirs as $type => $name) // $type is 'output' or 'temp'
{
- $multidirname = 'multidir_'.$type;
- $dirname = 'dir_'.$type;
+ $multidirname = 'multidir_'.$type;
+ $dirname = 'dir_'.$type;
- if($type != 'temp')
+ if ($type != 'temp')
{
// For multicompany sharings
$this->$module->$multidirname = array($this->entity => $rootfordata."/".$name);
@@ -338,90 +338,90 @@ class Conf
}
// For mycompany storage
- $this->mycompany->dir_output = $rootfordata."/mycompany";
- $this->mycompany->dir_temp = $rootfortemp."/mycompany/temp";
+ $this->mycompany->dir_output = $rootfordata."/mycompany";
+ $this->mycompany->dir_temp = $rootfortemp."/mycompany/temp";
// For admin storage
- $this->admin->dir_output = $rootfordata.'/admin';
- $this->admin->dir_temp = $rootfortemp.'/admin/temp';
+ $this->admin->dir_output = $rootfordata.'/admin';
+ $this->admin->dir_temp = $rootfortemp.'/admin/temp';
// For user storage
- $this->user->multidir_output = array($this->entity => $rootfordata."/users");
- $this->user->multidir_temp = array($this->entity => $rootfortemp."/users/temp");
+ $this->user->multidir_output = array($this->entity => $rootfordata."/users");
+ $this->user->multidir_temp = array($this->entity => $rootfortemp."/users/temp");
// For backward compatibility
- $this->user->dir_output = $rootforuser."/users";
- $this->user->dir_temp = $rootfortemp."/users/temp";
+ $this->user->dir_output = $rootforuser."/users";
+ $this->user->dir_temp = $rootfortemp."/users/temp";
// For usergroup storage
- $this->usergroup->dir_output = $rootforuser."/usergroups";
- $this->usergroup->dir_temp = $rootfortemp."/usergroups/temp";
+ $this->usergroup->dir_output = $rootforuser."/usergroups";
+ $this->usergroup->dir_temp = $rootfortemp."/usergroups/temp";
// For proposal storage
- $this->propal->multidir_output = array($this->entity => $rootfordata."/propale");
- $this->propal->multidir_temp = array($this->entity => $rootfortemp."/propale/temp");
+ $this->propal->multidir_output = array($this->entity => $rootfordata."/propale");
+ $this->propal->multidir_temp = array($this->entity => $rootfortemp."/propale/temp");
// For backward compatibility
- $this->propal->dir_output = $rootfordata."/propale";
- $this->propal->dir_temp = $rootfortemp."/propale/temp";
+ $this->propal->dir_output = $rootfordata."/propale";
+ $this->propal->dir_temp = $rootfortemp."/propale/temp";
// For medias storage
- $this->medias->multidir_output = array($this->entity => $rootfordata."/medias");
- $this->medias->multidir_temp = array($this->entity => $rootfortemp."/medias/temp");
+ $this->medias->multidir_output = array($this->entity => $rootfordata."/medias");
+ $this->medias->multidir_temp = array($this->entity => $rootfortemp."/medias/temp");
// Exception: Some dir are not the name of module. So we keep exception here for backward compatibility.
// Sous module bons d'expedition
- $this->expedition_bon->enabled=(! empty($this->global->MAIN_SUBMODULE_EXPEDITION)?$this->global->MAIN_SUBMODULE_EXPEDITION:0);
+ $this->expedition_bon->enabled = (!empty($this->global->MAIN_SUBMODULE_EXPEDITION) ? $this->global->MAIN_SUBMODULE_EXPEDITION : 0);
// Sous module bons de livraison
- $this->livraison_bon->enabled=(! empty($this->global->MAIN_SUBMODULE_LIVRAISON)?$this->global->MAIN_SUBMODULE_LIVRAISON:0);
+ $this->livraison_bon->enabled = (!empty($this->global->MAIN_SUBMODULE_LIVRAISON) ? $this->global->MAIN_SUBMODULE_LIVRAISON : 0);
// Module fournisseur
- if (! empty($this->fournisseur))
+ if (!empty($this->fournisseur))
{
- $this->fournisseur->commande=new stdClass();
- $this->fournisseur->commande->multidir_output = array($this->entity => $rootfordata."/fournisseur/commande");
- $this->fournisseur->commande->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/commande/temp");
- $this->fournisseur->commande->dir_output = $rootfordata."/fournisseur/commande"; // For backward compatibility
- $this->fournisseur->commande->dir_temp = $rootfortemp."/fournisseur/commande/temp"; // For backward compatibility
+ $this->fournisseur->commande = new stdClass();
+ $this->fournisseur->commande->multidir_output = array($this->entity => $rootfordata."/fournisseur/commande");
+ $this->fournisseur->commande->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/commande/temp");
+ $this->fournisseur->commande->dir_output = $rootfordata."/fournisseur/commande"; // For backward compatibility
+ $this->fournisseur->commande->dir_temp = $rootfortemp."/fournisseur/commande/temp"; // For backward compatibility
- $this->fournisseur->facture=new stdClass();
- $this->fournisseur->facture->multidir_output = array($this->entity => $rootfordata."/fournisseur/facture");
- $this->fournisseur->facture->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/facture/temp");
- $this->fournisseur->facture->dir_output = $rootfordata."/fournisseur/facture"; // For backward compatibility
- $this->fournisseur->facture->dir_temp = $rootfortemp."/fournisseur/facture/temp"; // For backward compatibility
+ $this->fournisseur->facture = new stdClass();
+ $this->fournisseur->facture->multidir_output = array($this->entity => $rootfordata."/fournisseur/facture");
+ $this->fournisseur->facture->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/facture/temp");
+ $this->fournisseur->facture->dir_output = $rootfordata."/fournisseur/facture"; // For backward compatibility
+ $this->fournisseur->facture->dir_temp = $rootfortemp."/fournisseur/facture/temp"; // For backward compatibility
- $this->supplierproposal=new stdClass();
- $this->supplierproposal->multidir_output = array($this->entity => $rootfordata."/supplier_proposal");
- $this->supplierproposal->multidir_temp = array($this->entity => $rootfortemp."/supplier_proposal/temp");
- $this->supplierproposal->dir_output = $rootfordata."/supplier_proposal"; // For backward compatibility
- $this->supplierproposal->dir_temp = $rootfortemp."/supplier_proposal/temp"; // For backward compatibility
+ $this->supplierproposal = new stdClass();
+ $this->supplierproposal->multidir_output = array($this->entity => $rootfordata."/supplier_proposal");
+ $this->supplierproposal->multidir_temp = array($this->entity => $rootfortemp."/supplier_proposal/temp");
+ $this->supplierproposal->dir_output = $rootfordata."/supplier_proposal"; // For backward compatibility
+ $this->supplierproposal->dir_temp = $rootfortemp."/supplier_proposal/temp"; // For backward compatibility
- $this->fournisseur->payment=new stdClass();
- $this->fournisseur->payment->multidir_output = array($this->entity => $rootfordata."/fournisseur/payment");
- $this->fournisseur->payment->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/payment/temp");
- $this->fournisseur->payment->dir_output = $rootfordata."/fournisseur/payment"; // For backward compatibility
- $this->fournisseur->payment->dir_temp = $rootfortemp."/fournisseur/payment/temp"; // For backward compatibility
+ $this->fournisseur->payment = new stdClass();
+ $this->fournisseur->payment->multidir_output = array($this->entity => $rootfordata."/fournisseur/payment");
+ $this->fournisseur->payment->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/payment/temp");
+ $this->fournisseur->payment->dir_output = $rootfordata."/fournisseur/payment"; // For backward compatibility
+ $this->fournisseur->payment->dir_temp = $rootfortemp."/fournisseur/payment/temp"; // For backward compatibility
// To prepare split of module fournisseur into fournisseur + supplier_order + supplier_invoice
- if (! empty($this->fournisseur->enabled) && empty($this->global->MAIN_USE_NEW_SUPPLIERMOD)) // By default, if module supplier is on, we set new properties
+ if (!empty($this->fournisseur->enabled) && empty($this->global->MAIN_USE_NEW_SUPPLIERMOD)) // By default, if module supplier is on, we set new properties
{
if (empty($this->global->MAIN_USE_NEW_SUPPLIERMOD)) // This can be set to 1 once modules purchase order and supplier invoice exists
{
- $this->supplier_order=new stdClass();
- $this->supplier_order->enabled = 1;
- $this->supplier_order->multidir_output = array($this->entity => $rootfordata."/fournisseur/commande");
- $this->supplier_order->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/commande/temp");
- $this->supplier_order->dir_output = $rootfordata."/fournisseur/commande"; // For backward compatibility
- $this->supplier_order->dir_temp = $rootfortemp."/fournisseur/commande/temp"; // For backward compatibility
+ $this->supplier_order = new stdClass();
+ $this->supplier_order->enabled = 1;
+ $this->supplier_order->multidir_output = array($this->entity => $rootfordata."/fournisseur/commande");
+ $this->supplier_order->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/commande/temp");
+ $this->supplier_order->dir_output = $rootfordata."/fournisseur/commande"; // For backward compatibility
+ $this->supplier_order->dir_temp = $rootfortemp."/fournisseur/commande/temp"; // For backward compatibility
}
if (empty($this->global->MAIN_USE_NEW_SUPPLIERMOD)) // This can be set to 1 once modules purchase order and supplier invoice exists
{
- $this->supplier_invoice=new stdClass();
- $this->supplier_invoice->enabled = 1;
- $this->supplier_invoice->multidir_output = array($this->entity => $rootfordata."/fournisseur/facture");
- $this->supplier_invoice->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/facture/temp");
- $this->supplier_invoice->dir_output = $rootfordata."/fournisseur/facture"; // For backward compatibility
- $this->supplier_invoice->dir_temp = $rootfortemp."/fournisseur/facture/temp"; // For backward compatibility
+ $this->supplier_invoice = new stdClass();
+ $this->supplier_invoice->enabled = 1;
+ $this->supplier_invoice->multidir_output = array($this->entity => $rootfordata."/fournisseur/facture");
+ $this->supplier_invoice->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/facture/temp");
+ $this->supplier_invoice->dir_output = $rootfordata."/fournisseur/facture"; // For backward compatibility
+ $this->supplier_invoice->dir_temp = $rootfortemp."/fournisseur/facture/temp"; // For backward compatibility
}
}
}
@@ -438,22 +438,22 @@ class Conf
$this->service->dir_temp = $rootfortemp."/produit/temp";
// Module productbatch
- $this->productbatch->multidir_output = array($this->entity => $rootfordata."/produitlot");
- $this->productbatch->multidir_temp = array($this->entity => $rootfortemp."/produitlot/temp");
+ $this->productbatch->multidir_output = array($this->entity => $rootfordata."/produitlot");
+ $this->productbatch->multidir_temp = array($this->entity => $rootfortemp."/produitlot/temp");
// Module contrat
- $this->contrat->multidir_output = array($this->entity => $rootfordata."/contract");
- $this->contrat->multidir_temp = array($this->entity => $rootfortemp."/contract/temp");
+ $this->contrat->multidir_output = array($this->entity => $rootfordata."/contract");
+ $this->contrat->multidir_temp = array($this->entity => $rootfortemp."/contract/temp");
// For backward compatibility
- $this->contrat->dir_output = $rootfordata."/contract";
- $this->contrat->dir_temp = $rootfortemp."/contract/temp";
+ $this->contrat->dir_output = $rootfordata."/contract";
+ $this->contrat->dir_temp = $rootfortemp."/contract/temp";
// Module bank
$this->bank->multidir_output = array($this->entity => $rootfordata."/bank");
$this->bank->multidir_temp = array($this->entity => $rootfortemp."/bank/temp");
// For backward compatibility
- $this->bank->dir_output = $rootfordata."/bank";
- $this->bank->dir_temp = $rootfortemp."/bank/temp";
+ $this->bank->dir_output = $rootfordata."/bank";
+ $this->bank->dir_temp = $rootfortemp."/bank/temp";
// Set some default values
//$this->global->MAIN_LIST_FILTER_ON_DAY=1; // On filter that show date, we must show input field for day before or after month
@@ -527,7 +527,7 @@ class Conf
if (empty($this->global->MAIN_THEME)) $this->global->MAIN_THEME = "eldy";
if (!empty($this->global->MAIN_FORCETHEME)) $this->global->MAIN_THEME = $this->global->MAIN_FORCETHEME;
$this->theme = $this->global->MAIN_THEME;
- $this->css = "/theme/".$this->theme."/style.css.php";
+ $this->css = "/theme/".$this->theme."/style.css.php";
// conf->email_from = email pour envoi par dolibarr des mails automatiques
$this->email_from = "robot@example.com";
@@ -681,10 +681,10 @@ class Conf
$this->global->AGENDA_DEFAULT_FILTER_TYPE = '0'; // 'AC_NON_AUTO' does not exists when AGENDA_DEFAULT_FILTER_TYPE is not on.
}
- if (!isset($this->global->MAIN_EXTRAFIELDS_IN_ONE_TD)) $this->global->MAIN_EXTRAFIELDS_IN_ONE_TD = 1;
-
if (!isset($this->global->MAIN_USE_OLD_TITLE_BUTTON)) $this->global->MAIN_USE_OLD_TITLE_BUTTON = 0;
+ if (!isset($this->global->MAIN_JS_GRAPH)) $this->global->MAIN_JS_GRAPH = 'chart'; // Use chart.js library
+
if (empty($this->global->MAIN_MODULE_DOLISTORE_API_SRV)) $this->global->MAIN_MODULE_DOLISTORE_API_SRV = 'https://www.dolistore.com';
if (empty($this->global->MAIN_MODULE_DOLISTORE_API_KEY)) $this->global->MAIN_MODULE_DOLISTORE_API_KEY = 'dolistorecatalogpublickey1234567';
diff --git a/htdocs/core/class/coreobject.class.php b/htdocs/core/class/coreobject.class.php
index 672697cd0a3..999b01341f0 100644
--- a/htdocs/core/class/coreobject.class.php
+++ b/htdocs/core/class/coreobject.class.php
@@ -36,7 +36,7 @@ class CoreObject extends CommonObject
/**
* @var Array $_fields Fields to synchronize with Database
*/
- protected $fields=array();
+ protected $fields = array();
/**
* Constructor
@@ -70,8 +70,8 @@ class CoreObject extends CommonObject
else $this->{$field} = '';
}
- $this->to_delete=false;
- $this->is_clone=false;
+ $this->to_delete = false;
+ $this->is_clone = false;
return true;
}
@@ -110,7 +110,7 @@ class CoreObject extends CommonObject
public function fetch($id, $loadChild = true)
{
$res = $this->fetchCommon($id);
- if($res>0) {
+ if ($res > 0) {
if ($loadChild) $this->fetchChild();
}
@@ -129,11 +129,11 @@ class CoreObject extends CommonObject
*/
public function addChild($tabName, $id = 0, $key = 'id', $try_to_load = false)
{
- if(!empty($id))
+ if (!empty($id))
{
- foreach($this->{$tabName} as $k=>&$object)
+ foreach ($this->{$tabName} as $k=>&$object)
{
- if($object->{$key} === $id) return $k;
+ if ($object->{$key} === $id) return $k;
}
}
@@ -141,7 +141,7 @@ class CoreObject extends CommonObject
$className = ucfirst($tabName);
$this->{$tabName}[$k] = new $className($this->db);
- if($id>0 && $key==='id' && $try_to_load)
+ if ($id > 0 && $key === 'id' && $try_to_load)
{
$this->{$tabName}[$k]->fetch($id);
}
@@ -181,20 +181,20 @@ class CoreObject extends CommonObject
{
if ($this->withChild && !empty($this->childtables) && !empty($this->fk_element))
{
- foreach($this->childtables as &$childTable)
+ foreach ($this->childtables as &$childTable)
{
$className = ucfirst($childTable);
- $this->{$className}=array();
+ $this->{$className} = array();
$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$childTable.' WHERE '.$this->fk_element.' = '.$this->id;
$res = $this->db->query($sql);
- if($res)
+ if ($res)
{
- while($obj = $this->db->fetch_object($res))
+ while ($obj = $this->db->fetch_object($res))
{
- $o=new $className($this->db);
+ $o = new $className($this->db);
$o->fetch($obj->rowid);
$this->{$className}[] = $o;
@@ -216,19 +216,19 @@ class CoreObject extends CommonObject
*/
public function saveChild(User &$user)
{
- if($this->withChild && !empty($this->childtables) && !empty($this->fk_element))
+ if ($this->withChild && !empty($this->childtables) && !empty($this->fk_element))
{
- foreach($this->childtables as &$childTable)
+ foreach ($this->childtables as &$childTable)
{
$className = ucfirst($childTable);
- if(!empty($this->{$className}))
+ if (!empty($this->{$className}))
{
- foreach($this->{$className} as $i => &$object)
+ foreach ($this->{$className} as $i => &$object)
{
$object->{$this->fk_element} = $this->id;
$object->update($user);
- if($this->unsetChildDeleted && isset($object->to_delete) && $object->to_delete==true) unset($this->{$className}[$i]);
+ if ($this->unsetChildDeleted && isset($object->to_delete) && $object->to_delete == true) unset($this->{$className}[$i]);
}
}
}
@@ -245,7 +245,7 @@ class CoreObject extends CommonObject
public function update(User &$user)
{
if (empty($this->id)) return $this->create($user); // To test, with that, no need to test on high level object, the core decide it, update just needed
- elseif (isset($this->to_delete) && $this->to_delete==true) return $this->delete($user);
+ elseif (isset($this->to_delete) && $this->to_delete == true) return $this->delete($user);
$error = 0;
$this->db->begin();
@@ -253,7 +253,7 @@ class CoreObject extends CommonObject
$res = $this->updateCommon($user);
if ($res)
{
- $result = $this->call_trigger(strtoupper($this->element). '_UPDATE', $user);
+ $result = $this->call_trigger(strtoupper($this->element).'_UPDATE', $user);
if ($result < 0) $error++;
else $this->saveChild($user);
}
@@ -284,17 +284,17 @@ class CoreObject extends CommonObject
*/
public function create(User &$user)
{
- if($this->id > 0) return $this->update($user);
+ if ($this->id > 0) return $this->update($user);
$error = 0;
$this->db->begin();
$res = $this->createCommon($user);
- if($res)
+ if ($res)
{
$this->id = $this->db->last_insert_id($this->table_element);
- $result = $this->call_trigger(strtoupper($this->element). '_CREATE', $user);
+ $result = $this->call_trigger(strtoupper($this->element).'_CREATE', $user);
if ($result < 0) $error++;
else $this->saveChild($user);
}
@@ -330,20 +330,20 @@ class CoreObject extends CommonObject
$error = 0;
$this->db->begin();
- $result = $this->call_trigger(strtoupper($this->element). '_DELETE', $user);
+ $result = $this->call_trigger(strtoupper($this->element).'_DELETE', $user);
if ($result < 0) $error++;
if (!$error)
{
$this->deleteCommon($user);
- if($this->withChild && !empty($this->childtables))
+ if ($this->withChild && !empty($this->childtables))
{
- foreach($this->childtables as &$childTable)
+ foreach ($this->childtables as &$childTable)
{
$className = ucfirst($childTable);
if (!empty($this->{$className}))
{
- foreach($this->{$className} as &$object)
+ foreach ($this->{$className} as &$object)
{
$object->delete($user);
}
@@ -376,7 +376,7 @@ class CoreObject extends CommonObject
*/
public function getDate($field, $format = '')
{
- if(empty($this->{$field})) return '';
+ if (empty($this->{$field})) return '';
else
{
return dol_print_date($this->{$field}, $format);
@@ -416,24 +416,20 @@ class CoreObject extends CommonObject
{
foreach ($Tab as $key => $value)
{
- if($this->checkFieldType($key, 'date'))
+ if ($this->checkFieldType($key, 'date'))
{
$this->setDate($key, $value);
}
- elseif( $this->checkFieldType($key, 'array'))
- {
- $this->{$key} = $value;
- }
- elseif( $this->checkFieldType($key, 'float') )
+ elseif ($this->checkFieldType($key, 'float'))
{
$this->{$key} = (double) price2num($value);
}
- elseif( $this->checkFieldType($key, 'int') ) {
+ elseif ($this->checkFieldType($key, 'int')) {
$this->{$key} = (int) price2num($value);
}
else
{
- $this->{$key} = $value;
+ $this->{$key} = dol_string_nohtmltag($value);
}
}
diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php
index ca40910aacd..c3707b18972 100644
--- a/htdocs/core/class/discount.class.php
+++ b/htdocs/core/class/discount.class.php
@@ -504,15 +504,16 @@ class DiscountAbsolute
* @param string $filter Filtre autre
* @param int $maxvalue Filter on max value for discount
* @param int $discount_type 0 => customer discount, 1 => supplier discount
+ * @param int $multicurrency Return multicurrency_amount instead of amount
* @return int <0 if KO, amount otherwise
*/
- public function getAvailableDiscounts($company = '', $user = '', $filter = '', $maxvalue = 0, $discount_type = 0)
+ public function getAvailableDiscounts($company = '', $user = '', $filter = '', $maxvalue = 0, $discount_type = 0, $multicurrency = 0)
{
global $conf;
dol_syslog(get_class($this)."::getAvailableDiscounts discount_type=".$discount_type, LOG_DEBUG);
- $sql = "SELECT SUM(rc.amount_ttc) as amount";
+ $sql = "SELECT SUM(rc.amount_ttc) as amount, SUM(rc.multicurrency_amount_ttc) as multicurrency_amount";
$sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as rc";
$sql .= " WHERE rc.entity = ".$conf->entity;
$sql .= " AND rc.discount_type=".intval($discount_type);
@@ -535,6 +536,11 @@ class DiscountAbsolute
//print 'zz'.$obj->amount;
//$obj = $this->db->fetch_object($resql);
//}
+ if ($multicurrency)
+ {
+ return $obj->amount_multicurrency;
+ }
+
return $obj->amount;
}
return -1;
@@ -604,14 +610,14 @@ class DiscountAbsolute
$sql = 'SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount';
$sql .= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc, '.MAIN_DB_PREFIX.'facture as f';
$sql .= ' WHERE rc.fk_facture_source=f.rowid AND rc.fk_facture = '.$invoice->id;
- $sql .= ' AND (f.type = 2 OR f.type = 0)'; // Find discount coming from credit note or excess received
+ $sql .= ' AND f.type IN (' . $invoice::TYPE_STANDARD . ', ' . $invoice::TYPE_CREDIT_NOTE . ', ' . $invoice::TYPE_SITUATION . ')'; // Find discount coming from credit note or excess received
}
elseif ($invoice->element == 'invoice_supplier')
{
$sql = 'SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount';
$sql .= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc, '.MAIN_DB_PREFIX.'facture_fourn as f';
$sql .= ' WHERE rc.fk_invoice_supplier_source=f.rowid AND rc.fk_invoice_supplier = '.$invoice->id;
- $sql .= ' AND (f.type = 2 OR f.type = 0)'; // Find discount coming from credit note or excess paid
+ $sql .= ' AND f.type IN (' . $invoice::TYPE_STANDARD . ', ' . $invoice::TYPE_CREDIT_NOTE . ')'; // Find discount coming from credit note or excess paid
}
else
{
diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php
index 06b6ec2d949..de5ef1f2e9f 100644
--- a/htdocs/core/class/doleditor.class.php
+++ b/htdocs/core/class/doleditor.class.php
@@ -85,44 +85,6 @@ class DolEditor
if ($okforextendededitor === 'ace') $this->tool = 'ace';
//if ($conf->dol_use_jmobile) $this->tool = 'textarea'; // ckeditor and ace seems ok with mobile
- // Define content and some properties
- if ($this->tool == 'ckeditor')
- {
- $content = dol_htmlentitiesbr($content); // If content is not HTML, we convert to HTML.
- }
- if ($this->tool == 'fckeditor')
- {
- require_once DOL_DOCUMENT_ROOT.'/includes/fckeditor/fckeditor.php';
-
- $content = dol_htmlentitiesbr($content); // If content is not HTML, we convert to HTML.
-
- $this->editor = new FCKeditor($htmlname);
- $this->editor->BasePath = DOL_URL_ROOT.'/includes/fckeditor/';
- $this->editor->Value = $content;
- $this->editor->Height = $height;
- if (!empty($width)) $this->editor->Width = $width;
- $this->editor->ToolbarSet = $shorttoolbarname; // Profile of this toolbar set is deinfed into theme/mytheme/ckeditor/config.js
- $this->editor->Config['AutoDetectLanguage'] = 'true'; // Language of user (browser)
- $this->editor->Config['ToolbarLocation'] = $toolbarlocation ? $toolbarlocation : 'In';
- $this->editor->Config['ToolbarStartExpanded'] = $toolbarstartexpanded;
-
- // Rem: Le forcage de ces 2 parametres ne semble pas fonctionner.
- // Dolibarr utilise toujours liens avec modulepart='fckeditor' quelque soit modulepart.
- // Ou se trouve donc cette valeur /viewimage.php?modulepart=fckeditor&file=' ?
- $modulepart = 'fckeditor';
- $this->editor->Config['UserFilesPath'] = '/viewimage.php?modulepart='.$modulepart.'&entity='.$conf->entity.'&file=';
- $this->editor->Config['UserFilesAbsolutePath'] = DOL_DATA_ROOT.'/'.$modulepart.'/';
-
- $this->editor->Config['LinkBrowser'] = ($uselocalbrowser ? 'true' : 'false');
- $this->editor->Config['ImageBrowser'] = ($uselocalbrowser ? 'true' : 'false');
-
- if (file_exists(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/fckeditor/fckconfig.js'))
- {
- $this->editor->Config['CustomConfigurationsPath'] = DOL_URL_ROOT.'/theme/'.$conf->theme.'/fckeditor/fckconfig.js';
- $this->editor->Config['SkinPath'] = DOL_URL_ROOT.'/theme/'.$conf->theme.'/fckeditor/';
- }
- }
-
// Define some properties
if (in_array($this->tool, array('textarea', 'ckeditor', 'ace')))
{
@@ -172,7 +134,8 @@ class DolEditor
{
$found = 1;
//$out.= 'readonly?' disabled':'').' rows="'.$this->rows.'"'.(preg_match('/%/',$this->cols)?' style="margin-top: 5px; width: '.$this->cols.'"':' cols="'.$this->cols.'"').' class="flat">';
- // TODO We do not put the disabled tag because on a read form, it change style with grey.
+ // TODO We do not put the 'disabled' tag because on a read form, it change style with grey.
+ //print $this->content;
$out .= 'cols) ? ' style="margin-top: 5px; width: '.$this->cols.'"' : ' cols="'.$this->cols.'"').' class="flat">';
$out .= htmlspecialchars($this->content);
$out .= ' ';
diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php
index 9aa54498edc..d59ab8ce6bc 100644
--- a/htdocs/core/class/dolgraph.class.php
+++ b/htdocs/core/class/dolgraph.class.php
@@ -30,10 +30,10 @@
* $dolgraph->SetTitle($langs->transnoentities('MyTitle').' '.$langs->transnoentities('MyTitlePercent').'%');
* $dolgraph->SetMaxValue(50);
* $dolgraph->SetData($data);
- * $dolgraph->setShowLegend(1);
+ * $dolgraph->setShowLegend(2);
* $dolgraph->setShowPercent(1);
* $dolgraph->SetType(array('pie'));
- * $dolgraph->setWidth('100%');
+ * $dolgraph->setHeight('200');
* $dolgraph->draw('idofgraph');
* print $dolgraph->show($total?0:1);
*/
@@ -92,31 +92,13 @@ class DolGraph
/**
* Constructor
*
- * @param string $library 'jflot' (default) or 'artichow' (no more supported)
+ * @param string $library 'auto' (default)
*/
- public function __construct($library = 'jflot')
+ public function __construct($library = 'auto')
{
global $conf;
global $theme_bordercolor, $theme_datacolor, $theme_bgcolor;
- // To use old feature
- if ($library == 'artichow')
- {
- $this->_library = 'artichow';
-
- // Test if module GD present
- $modules_list = get_loaded_extensions();
- $isgdinstalled = 0;
- foreach ($modules_list as $module)
- {
- if ($module == 'gd') $isgdinstalled = 1;
- }
- if (!$isgdinstalled)
- {
- $this->error = "Error: PHP GD module is not available. It is required to build graphics.";
- }
- }
-
$this->bordercolor = array(235, 235, 224);
$this->datacolor = array(array(120, 130, 150), array(160, 160, 180), array(190, 190, 220));
$this->bgcolor = array(235, 235, 224);
@@ -130,23 +112,14 @@ class DolGraph
if (isset($theme_bgcolor)) $this->bgcolor = $theme_bgcolor;
}
//print 'bgcolor: '.join(',',$this->bgcolor).' ';
+
+ $this->_library = $library;
+ if ($this->_library == 'auto') {
+ $this->_library = (empty($conf->global->MAIN_JS_GRAPH) ? 'jflot' : $conf->global->MAIN_JS_GRAPH);
+ }
}
- // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
- /**
- * Set Y precision
- *
- * @param float $which_prec Precision
- * @return boolean
- * @deprecated
- */
- public function SetPrecisionY($which_prec)
- {
- // phpcs:enable
- return true;
- }
-
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Utiliser SetNumTicks ou SetHorizTickIncrement mais pas les 2
@@ -287,7 +260,8 @@ class DolGraph
/**
* Set type
*
- * @param array $type Array with type for each serie. Example: array('pie'), array('lines',...,'bars')
+ * @param array $type Array with type for each serie. Example: array('type1', 'type2', ...) where type can be:
+ * 'pie', 'piesemicircle', 'polar', 'lines', 'linesnopoint', 'bars', ...
* @return void
*/
public function SetType($type)
@@ -448,7 +422,7 @@ class DolGraph
/**
* Show legend or not
*
- * @param int $showlegend 1=Show legend (default), 0=Hide legend
+ * @param int $showlegend 1=Show legend (default), 0=Hide legend, 2=Show legend on right
* @return void
*/
public function setShowLegend($showlegend)
@@ -561,6 +535,8 @@ class DolGraph
public function GetMaxValueInData()
{
// phpcs:enable
+ if (!is_array($this->data)) return 0;
+
$k = 0;
$vals = array();
@@ -588,6 +564,8 @@ class DolGraph
public function GetMinValueInData()
{
// phpcs:enable
+ if (!is_array($this->data)) return 0;
+
$k = 0;
$vals = array();
@@ -686,188 +664,6 @@ class DolGraph
call_user_func_array(array($this, $call), array($file, $fileurl));
}
-
- // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
- /**
- * Build a graph onto disk using Artichow library and return img string to it
- *
- * @param string $file Image file name to use if we save onto disk
- * @param string $fileurl Url path to show image if saved onto disk
- * @return void
- */
- private function draw_artichow($file, $fileurl)
- {
- // phpcs:enable
- global $artichow_defaultfont;
-
- dol_syslog(get_class($this)."::draw_artichow this->type=".join(',', $this->type));
-
- if (!defined('SHADOW_RIGHT_TOP')) define('SHADOW_RIGHT_TOP', 3);
- if (!defined('LEGEND_BACKGROUND')) define('LEGEND_BACKGROUND', 2);
- if (!defined('LEGEND_LINE')) define('LEGEND_LINE', 1);
-
- // Create graph
- $classname = '';
- if (!isset($this->type[0]) || $this->type[0] == 'bars') $classname = 'BarPlot'; // Only one type (first one) is supported by artichow
- elseif ($this->type[0] == 'lines' || $this->type[0] == 'linesnopoint') $classname = 'LinePlot';
- else $classname = 'TypeUnknown';
- include_once ARTICHOW_PATH.$classname.'.class.php';
-
- // Definition de couleurs
- $bgcolor = new Color($this->bgcolor[0], $this->bgcolor[1], $this->bgcolor[2]);
- $bgcolorgrid = new Color($this->bgcolorgrid[0], $this->bgcolorgrid[1], $this->bgcolorgrid[2]);
- $colortrans = new Color(0, 0, 0, 100);
- $colorsemitrans = new Color(255, 255, 255, 60);
- $colorgradient = new LinearGradient(new Color(235, 235, 235), new Color(255, 255, 255), 0);
- $colorwhite = new Color(255, 255, 255);
-
- // Graph
- $graph = new Graph($this->width, $this->height);
- $graph->border->hide();
- $graph->setAntiAliasing(true);
- if (isset($this->title))
- {
- $graph->title->set($this->title);
- //print $artichow_defaultfont;exit;
- $graph->title->setFont(new $artichow_defaultfont(10));
- }
-
- if (is_array($this->bgcolor)) $graph->setBackgroundColor($bgcolor);
- else $graph->setBackgroundGradient($colorgradient);
-
- $group = new PlotGroup;
- //$group->setSpace(5, 5, 0, 0);
-
- $paddleft = 50;
- $paddright = 10;
- $strl = dol_strlen(max(abs($this->MaxValue), abs($this->MinValue)));
- if ($strl > 6) $paddleft += ($strl * 4);
- $group->setPadding($paddleft, $paddright); // Width on left and right for Y axis values
- $group->legend->setSpace(0);
- $group->legend->setPadding(2, 2, 2, 2);
- $group->legend->setPosition(null, 0.1);
- $group->legend->setBackgroundColor($colorsemitrans);
-
- if (is_array($this->bgcolorgrid)) $group->grid->setBackgroundColor($bgcolorgrid);
- else $group->grid->setBackgroundColor($colortrans);
-
- if ($this->hideXGrid) $group->grid->hideVertical(true);
- if ($this->hideYGrid) $group->grid->hideHorizontal(true);
-
- // On boucle sur chaque lot de donnees
- $legends = array();
- $i = 0;
- $nblot = count($this->data[0]) - 1;
-
- while ($i < $nblot)
- {
- $x = 0;
- $values = array();
- foreach ($this->data as $key => $valarray)
- {
- $legends[$x] = $valarray[0];
- $values[$x] = $valarray[$i + 1];
- $x++;
- }
-
- // We fix unknown values to null
- $newvalues = array();
- foreach ($values as $val)
- {
- $newvalues[] = (is_numeric($val) ? $val : null);
- }
-
-
- if ($this->type[0] == 'bars')
- {
- //print "Lot de donnees $i ";
- //print_r($values);
- //print ' ';
-
- $color = new Color($this->datacolor[$i][0], $this->datacolor[$i][1], $this->datacolor[$i][2], 20);
- $colorbis = new Color(min($this->datacolor[$i][0] + 50, 255), min($this->datacolor[$i][1] + 50, 255), min($this->datacolor[$i][2] + 50, 255), 50);
-
- $colorgrey = new Color(100, 100, 100);
- $colorborder = new Color($this->datacolor[$i][0], $this->datacolor[$i][1], $this->datacolor[$i][2]);
-
- if ($this->mode == 'side') $plot = new BarPlot($newvalues, $i + 1, $nblot);
- if ($this->mode == 'depth') $plot = new BarPlot($newvalues, 1, 1, ($nblot - $i - 1) * 5);
-
- $plot->barBorder->setColor($colorgrey);
- //$plot->setBarColor($color);
- $plot->setBarGradient(new LinearGradient($colorbis, $color, 90));
-
- if ($this->mode == 'side') $plot->setBarPadding(0.1, 0.1);
- if ($this->mode == 'depth') $plot->setBarPadding(0.1, 0.4);
- if ($this->mode == 'side') $plot->setBarSpace(5);
- if ($this->mode == 'depth') $plot->setBarSpace(2);
-
- $plot->barShadow->setSize($this->SetShading);
- $plot->barShadow->setPosition(SHADOW_RIGHT_TOP);
- $plot->barShadow->setColor(new Color(160, 160, 160, 50));
- $plot->barShadow->smooth(true);
- //$plot->setSize(1, 0.96);
- //$plot->setCenter(0.5, 0.52);
-
- // Le mode automatique est plus efficace
- $plot->SetYMax($this->MaxValue);
- $plot->SetYMin($this->MinValue);
- }
-
- if ($this->type[0] == 'lines' || $this->type[0] == 'linesnopoint')
- {
- $color = new Color($this->datacolor[$i][0], $this->datacolor[$i][1], $this->datacolor[$i][2], 20);
- $colorbis = new Color(min($this->datacolor[$i][0] + 20, 255), min($this->datacolor[$i][1] + 20, 255), min($this->datacolor[$i][2] + 20, 255), 60);
- $colorter = new Color(min($this->datacolor[$i][0] + 50, 255), min($this->datacolor[$i][1] + 50, 255), min($this->datacolor[$i][2] + 50, 255), 90);
-
- $plot = new LinePlot($newvalues);
- //$plot->setSize(1, 0.96);
- //$plot->setCenter(0.5, 0.52);
-
- $plot->setColor($color);
- $plot->setThickness(1);
-
- // Set line background gradient
- $plot->setFillGradient(new LinearGradient($colorter, $colorbis, 90));
-
- $plot->xAxis->setLabelText($legends);
-
- // Le mode automatique est plus efficace
- $plot->SetYMax($this->MaxValue);
- $plot->SetYMin($this->MinValue);
- //$plot->setYAxis(0);
- //$plot->hideLine(true);
- }
-
- //$plot->reduce(80); // Evite temps d'affichage trop long et nombre de ticks absisce satures
-
- $group->legend->setTextFont(new $artichow_defaultfont(10)); // This is to force Artichow to use awFileFontDriver to
- // solve a bug in Artichow with UTF8
- if (count($this->Legend))
- {
- if ($this->type[0] == 'bars') $group->legend->add($plot, $this->Legend[$i], LEGEND_BACKGROUND);
- if ($this->type[0] == 'lines' || $this->type[0] == 'linesnopoint') $group->legend->add($plot, $this->Legend[$i], LEGEND_LINE);
- }
- $group->add($plot);
-
- $i++;
- }
-
- $group->axis->bottom->setLabelText($legends);
- $group->axis->bottom->label->setFont(new $artichow_defaultfont(7));
-
- //print $group->axis->bottom->getLabelNumber();
- if ($this->labelInterval > 0) $group->axis->bottom->setLabelInterval($this->labelInterval);
-
- $graph->add($group);
-
- // Generate file
- $graph->draw($file);
-
- $this->stringtoshow = ' ';
- }
-
-
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Build a graph using JFlot library. Input when calling this method should be:
@@ -875,7 +671,7 @@ class DolGraph
* $this->data = array(array(0=>'labelxA',1=>yA1,...,n=>yAn), array('labelxB',yB1,...yBn)); // or when there is n series to show for each x
* $this->data = array(array('label'=>'labelxA','data'=>yA), array('labelxB',yB)); // Syntax deprecated
* $this->legend= array("Val1",...,"Valn"); // list of n series name
- * $this->type = array('bars',...'lines'); or array('pie')
+ * $this->type = array('bars',...'lines','linesnopoint'); or array('pie') or array('polar')
* $this->mode = 'depth' ???
* $this->bgcolorgrid
* $this->datacolor
@@ -888,7 +684,7 @@ class DolGraph
private function draw_jflot($file, $fileurl)
{
// phpcs:enable
- global $langs;
+ global $conf, $langs;
dol_syslog(get_class($this)."::draw_jflot this->type=".join(',', $this->type)." this->MaxValue=".$this->MaxValue);
@@ -924,8 +720,7 @@ class DolGraph
$x++;
}
- // TODO Avoid push by adding generated long array...
- if (isset($this->type[$firstlot]) && $this->type[$firstlot] == 'pie')
+ if (isset($this->type[$firstlot]) && in_array($this->type[$firstlot], array('pie', 'piesemicircle', 'polar')))
{
foreach ($values as $x => $y) {
if (isset($y)) $serie[$i] .= 'd'.$i.'.push({"label":"'.dol_escape_js($legends[$x]).'", "data":'.$y.'});'."\n";
@@ -943,38 +738,46 @@ class DolGraph
}
$tag = dol_escape_htmltag(dol_string_unaccent(dol_string_nospecial(basename($file), '_', array('-', '.'))));
- $this->stringtoshow = ''."\n";
+ $this->stringtoshow = ''."\n";
if (!empty($this->title)) $this->stringtoshow .= ''.$this->title.'
';
if (!empty($this->shownographyet))
{
$this->stringtoshow .= '
';
- $this->stringtoshow .= ''.$langs->trans("NotEnoughDataYet").'
';
+ $this->stringtoshow .= ''.$langs->trans("NotEnoughDataYet").'...
';
return;
}
- $this->stringtoshow .= '
'."\n";
+
+ // Start the div that will contains all the graph
+ $dolxaxisvertical = '';
+ if (count($this->data) > 20) $dolxaxisvertical = 'dol-xaxis-vertical';
+ $this->stringtoshow .= '
'."\n";
$this->stringtoshow .= ''."\n";
}
+
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+ /**
+ * Build a graph using Chart library. Input when calling this method should be:
+ * $this->data = array(array(0=>'labelxA',1=>yA), array('labelxB',yB));
+ * $this->data = array(array(0=>'labelxA',1=>yA1,...,n=>yAn), array('labelxB',yB1,...yBn)); // or when there is n series to show for each x
+ * $this->data = array(array('label'=>'labelxA','data'=>yA), array('labelxB',yB)); // Syntax deprecated
+ * $this->legend= array("Val1",...,"Valn"); // list of n series name
+ * $this->type = array('bars',...'lines', 'linesnopoint'); or array('pie') or array('polar') or array('piesemicircle');
+ * $this->mode = 'depth' ???
+ * $this->bgcolorgrid
+ * $this->datacolor
+ * $this->shownodatagraph
+ *
+ * @param string $file Image file name to use to save onto disk (also used as javascript unique id)
+ * @param string $fileurl Url path to show image if saved onto disk. Never used here.
+ * @return void
+ */
+ private function draw_chart($file, $fileurl)
+ {
+ // phpcs:enable
+ global $conf, $langs;
+
+ dol_syslog(get_class($this)."::draw_chart this->type=".join(',', $this->type)." this->MaxValue=".$this->MaxValue);
+
+ if (empty($this->width) && empty($this->height))
+ {
+ print 'Error width or height not set';
+ return;
+ }
+
+ $showlegend = $this->showlegend;
+
+ $legends = array();
+ $nblot = 0;
+ if (is_array($this->data)) {
+ foreach ($this->data as $valarray) // Loop on each x
+ {
+ $nblot = max($nblot, count($valarray) - 1); // -1 to remove legend
+ }
+ }
+ //var_dump($nblot);
+ if ($nblot < 0) dol_syslog('Bad value for property ->data. Must be set by mydolgraph->SetData before calling mydolgrapgh->draw', LOG_WARNING);
+ $firstlot = 0;
+ // Works with line but not with bars
+ //if ($nblot > 2) $firstlot = ($nblot - 2); // We limit nblot to 2 because jflot can't manage more than 2 bars on same x
+
+ $serie = array(); $arrayofgroupslegend = array();
+ //var_dump($this->data);
+
+ $i = $firstlot;
+ while ($i < $nblot) // Loop on each serie
+ {
+ $values = array(); // Array with horizontal y values (specific values of a serie) for each abscisse x (with x=0,1,2,...)
+ $serie[$i] = "";
+
+ // Fill array $values
+ $x = 0;
+ foreach ($this->data as $valarray) // Loop on each x
+ {
+ $legends[$x] = (array_key_exists('label', $valarray) ? $valarray['label'] : $valarray[0]);
+ $array_of_ykeys = array_keys($valarray);
+ $alabelexists = 1;
+ $tmpykey = explode('_', ($array_of_ykeys[$i + ($alabelexists ? 1 : 0)]), 3);
+ if (!empty($tmpykey[2]) || $tmpykey[2] == '0') { // This is a 'Group by' array
+ $tmpvalue = (array_key_exists('y_'.$tmpykey[1].'_'.$tmpykey[2], $valarray) ? $valarray['y_'.$tmpykey[1].'_'.$tmpykey[2]] : $valarray[$i + 1]);
+ $values[$x] = (is_numeric($tmpvalue) ? $tmpvalue : null);
+ $arrayofgroupslegend[$i] = array(
+ 'stacknum'=> $tmpykey[1],
+ 'legend' => $this->Legend[$tmpykey[1]],
+ 'legendwithgroup' => $this->Legend[$tmpykey[1]].' - '.$tmpykey[2]
+ );
+ } else {
+ $tmpvalue = (array_key_exists('y_'.$i, $valarray) ? $valarray['y_'.$i] : $valarray[$i + 1]);
+ //var_dump($i.'_'.$x.'_'.$tmpvalue);
+ $values[$x] = (is_numeric($tmpvalue) ? $tmpvalue : null);
+ }
+ $x++;
+ }
+ //var_dump($values);
+ $j = 0;
+ foreach ($values as $x => $y) {
+ if (isset($y)) {
+ $serie[$i] .= ($j > 0 ? ", " : "").$y;
+ } else {
+ $serie[$i] .= ($j > 0 ? ", " : "").'null';
+ }
+ $j++;
+ }
+
+ $values = null; // Free mem
+ $i++;
+ }
+ //var_dump($serie);
+ //var_dump($arrayofgroupslegend);
+
+ $tag = dol_escape_htmltag(dol_string_unaccent(dol_string_nospecial(basename($file), '_', array('-', '.'))));
+
+ $this->stringtoshow = ''."\n";
+ if (!empty($this->title)) $this->stringtoshow .= ''.$this->title.'
';
+ if (!empty($this->shownographyet))
+ {
+ $this->stringtoshow .= '
';
+ $this->stringtoshow .= ''.$langs->trans("NotEnoughDataYet").'...
';
+ return;
+ }
+
+ // Start the div that will contains all the graph
+ $dolxaxisvertical='';
+ if (count($this->data) > 20) $dolxaxisvertical='dol-xaxis-vertical';
+ // No height for the pie grah
+ $cssfordiv = 'dolgraphchart';
+ if (isset($this->type[$firstlot])) $cssfordiv .= ' dolgraphchar'.$this->type[$firstlot];
+ $this->stringtoshow .= '
'."\n";
+
+ $this->stringtoshow .= ''."\n";
+ }
+
+
/**
* Output HTML string to total value
*
@@ -1155,11 +1313,11 @@ class DolGraph
if ($shownographyet)
{
$s = '
';
- $s .= '';
+ $s .= '
';
if (is_numeric($shownographyet)) {
- $s .= $langs->trans("NotEnoughDataYet");
+ $s .= $langs->trans("NotEnoughDataYet").'...';
} else {
- $s .= $shownographyet;
+ $s .= $shownographyet.'...';
}
$s .= '
';
return $s;
diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php
index e8e43281d79..d241c2a8c5a 100644
--- a/htdocs/core/class/dolreceiptprinter.class.php
+++ b/htdocs/core/class/dolreceiptprinter.class.php
@@ -49,6 +49,8 @@
*
Print object total tax
* Print object local tax
* Print object total
+ * Print order lines for Printer1
+ * Print order lines for Printer2
* Print payment method
*
* Code which can be placed everywhere
@@ -59,8 +61,6 @@
* Replaced by month number
* Replaced by day number
* Replaced by day number
- * Replaced by table number (for restaurant, bar...)
- * Replaced by number of cutlery (for restaurant)
* Replaced by object id
* Replaced by object ref
* Replaced by customer firstname
@@ -180,8 +180,6 @@ class dolReceiptPrinter extends Printer
'dol_value_month',
'dol_value_day',
'dol_value_day_letters',
- 'dol_value_table',
- 'dol_value_cutlery',
'dol_print_payment',
'dol_print_logo',
'dol_print_logo_old',
@@ -192,6 +190,8 @@ class dolReceiptPrinter extends Printer
'dol_print_object_local_tax',
'dol_print_object_total',
'dol_print_object_number',
+ 'dol_print_order_lines_printer1',
+ 'dol_print_order_lines_printer2',
'dol_value_customer_firstname',
'dol_value_customer_lastname',
'dol_value_customer_mail',
@@ -579,15 +579,13 @@ class dolReceiptPrinter extends Printer
$this->template = str_replace('', $object->vendor_firstname, $this->template);
$this->template = str_replace('', $object->vendor_lastname, $this->template);
$this->template = str_replace('', $object->vendor_mail, $this->template);
- $this->template = str_replace('', $object->date, $this->template);
- $this->template = str_replace('', $object->date_time, $this->template);
- $this->template = str_replace('', $object->date_time, $this->template);
- $this->template = str_replace('', $object->date_time, $this->template);
- $this->template = str_replace('', $object->date_time, $this->template);
- $this->template = str_replace('', $object->date_time, $this->template);
- $this->template = str_replace('', $object->date_time, $this->template);
- $this->template = str_replace('', $object->table, $this->template);
- $this->template = str_replace('', $object->cutlery, $this->template);
+ $this->template = str_replace('', dol_print_date($object->date, 'day'), $this->template);
+ $this->template = str_replace('', dol_print_date($object->date, 'dayhour'), $this->template);
+ $this->template = str_replace('', dol_print_date($object->date, '%Y'), $this->template);
+ $this->template = str_replace('', $langs->trans("Month".dol_print_date($object->date, '%m')), $this->template);
+ $this->template = str_replace('', dol_print_date($object->date, '%m'), $this->template);
+ $this->template = str_replace('', dol_print_date($object->date, '%d'), $this->template);
+ $this->template = str_replace('', $langs->trans("Day".dol_print_date($object->date, '%m')[1]), $this->template);
// parse template
$p = xml_parser_create();
@@ -726,6 +724,28 @@ class dolReceiptPrinter extends Printer
case 'DOL_BEEP':
$this->printer->getPrintConnector() -> write("\x1e");
break;
+ case 'DOL_PRINT_ORDER_LINES_PRINTER1':
+ foreach ($object->lines as $line) {
+ if ($line->special_code==1)
+ {
+ $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - 10 - 1;
+ $spaces = str_repeat(' ', $spacestoadd);
+ $this->printer->text($line->ref.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n");
+ $this->printer->text(strip_tags(htmlspecialchars_decode($line->desc))."\n");
+ }
+ }
+ break;
+ case 'DOL_PRINT_ORDER_LINES_PRINTER2':
+ foreach ($object->lines as $line) {
+ if ($line->special_code==2)
+ {
+ $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - 10 - 1;
+ $spaces = str_repeat(' ', $spacestoadd);
+ $this->printer->text($line->ref.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n");
+ $this->printer->text(strip_tags(htmlspecialchars_decode($line->desc))."\n");
+ }
+ }
+ break;
default:
$this->printer->text($vals[$tplline]['tag']);
$this->printer->text($vals[$tplline]['value']);
diff --git a/htdocs/core/class/evalmath.class.php b/htdocs/core/class/evalmath.class.php
new file mode 100644
index 00000000000..a520ebb3a21
--- /dev/null
+++ b/htdocs/core/class/evalmath.class.php
@@ -0,0 +1,507 @@
+
+ *
+ * ================================================================================
+ *
+ * NAME
+ * EvalMath - safely evaluate math expressions
+ *
+ * SYNOPSIS
+ * include('evalmath.class.php');
+ * $m = new EvalMath;
+ * // basic evaluation:
+ * $result = $m->evaluate('2+2');
+ * // supports: order of operation; parentheses; negation; built-in functions
+ * $result = $m->evaluate('-8(5/2)^2*(1-sqrt(4))-8');
+ * // create your own variables
+ * $m->evaluate('a = e^(ln(pi))');
+ * // or functions
+ * $m->evaluate('f(x,y) = x^2 + y^2 - 2x*y + 1');
+ * // and then use them
+ * $result = $m->evaluate('3*f(42,a)');
+ *
+ * DESCRIPTION
+ * Use the EvalMath class when you want to evaluate mathematical expressions
+ * from untrusted sources. You can define your own variables and functions,
+ * which are stored in the object. Try it, it's fun!
+ *
+ * METHODS
+ * $m->evalute($expr)
+ * Evaluates the expression and returns the result. If an error occurs,
+ * prints a warning and returns false. If $expr is a function assignment,
+ * returns true on success.
+ *
+ * $m->e($expr)
+ * A synonym for $m->evaluate().
+ *
+ * $m->vars()
+ * Returns an associative array of all user-defined variables and values.
+ *
+ * $m->funcs()
+ * Returns an array of all user-defined functions.
+ *
+ * PARAMETERS
+ * $m->suppress_errors
+ * Set to true to turn off warnings when evaluating expressions
+ *
+ * $m->last_error
+ * If the last evaluation failed, contains a string describing the error.
+ * (Useful when suppress_errors is on).
+ *
+ * $m->last_error_code
+ * If the last evaluation failed, 2 element array with numeric code and extra info
+ *
+ * AUTHOR INFORMATION
+ * Copyright 2005, Miles Kaufmann.
+ *
+ * LICENSE
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1 Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file core/class/evalmath.class.php
+ * \ingroup core
+ * \brief This file for Math evaluation
+ */
+
+/**
+ * Class EvalMath
+ */
+class EvalMath
+{
+
+ public $suppress_errors = false;
+
+ public $last_error = null;
+
+ public $last_error_code = null;
+
+ public $v = array('e' => 2.71,'pi' => 3.14159);
+
+ // variables (and constants)
+ public $f = array();
+
+ // user-defined functions
+ public $vb = array('e','pi');
+
+ // constants
+ public $fb = array( // built-in functions
+ 'sin','sinh','arcsin','asin','arcsinh','asinh','cos','cosh','arccos','acos','arccosh','acosh','tan','tanh','arctan','atan','arctanh','atanh','sqrt','abs','ln','log','intval');
+
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ // make the variables a little more accurate
+ $this->v['pi'] = pi();
+ $this->v['e'] = exp(1);
+ }
+
+ /**
+ * Evaluate
+ *
+ * @param string $expr String
+ * @return boolean|number|NULL|mixed Result
+ */
+ public function e($expr)
+ {
+ return $this->evaluate($expr);
+ }
+
+ /**
+ * Evaluate
+ *
+ * @param string $expr String
+ * @return boolean|number|NULL|mixed Result
+ */
+ public function evaluate($expr)
+ {
+ $this->last_error = null;
+ $this->last_error_code = null;
+ $expr = trim($expr);
+ if (substr($expr, - 1, 1) == ';')
+ $expr = substr($expr, 0, strlen($expr) - 1); // strip semicolons at the end
+ // ===============
+ // is it a variable assignment?
+ $matches = array();
+ if (preg_match('/^\s*([a-z]\w*)\s*=\s*(.+)$/', $expr, $matches)) {
+ if (in_array($matches[1], $this->vb)) { // make sure we're not assigning to a constant
+ return $this->trigger(1, "cannot assign to constant '$matches[1]'", $matches[1]);
+ }
+ if (($tmp = $this->pfx($this->nfx($matches[2]))) === false)
+ return false; // get the result and make sure it's good
+ $this->v[$matches[1]] = $tmp; // if so, stick it in the variable array
+ return $this->v[$matches[1]]; // and return the resulting value
+ // ===============
+ // is it a function assignment?
+ } elseif (preg_match('/^\s*([a-z]\w*)\s*\(\s*([a-z]\w*(?:\s*,\s*[a-z]\w*)*)\s*\)\s*=\s*(.+)$/', $expr, $matches)) {
+ $fnn = $matches[1]; // get the function name
+ if (in_array($matches[1], $this->fb)) { // make sure it isn't built in
+ return $this->trigger(2, "cannot redefine built-in function '$matches[1]()'", $matches[1]);
+ }
+ $args = explode(",", preg_replace("/\s+/", "", $matches[2])); // get the arguments
+ if (($stack = $this->nfx($matches[3])) === false)
+ return false; // see if it can be converted to postfix
+ $nbstack = count($stack);
+ for ($i = 0; $i < $nbstack; $i ++) { // freeze the state of the non-argument variables
+ $token = $stack[$i];
+ if (preg_match('/^[a-z]\w*$/', $token) and ! in_array($token, $args)) {
+ if (array_key_exists($token, $this->v)) {
+ $stack[$i] = $this->v[$token];
+ } else {
+ return $this->trigger(3, "undefined variable '$token' in function definition", $token);
+ }
+ }
+ }
+ $this->f[$fnn] = array('args' => $args,'func' => $stack);
+ return true;
+ // ===============
+ } else {
+ return $this->pfx($this->nfx($expr)); // straight up evaluation, woo
+ }
+ }
+
+ /**
+ * vars
+ *
+ * @return string Output
+ */
+ private function vars()
+ {
+ $output = $this->v;
+ unset($output['pi']);
+ unset($output['e']);
+ return $output;
+ }
+
+ /**
+ * vars
+ *
+ * @return string Output
+ */
+ private function funcs()
+ {
+ $output = array();
+ foreach ($this->f as $fnn => $dat)
+ $output[] = $fnn . '(' . implode(',', $dat['args']) . ')';
+ return $output;
+ }
+
+ // ===================== HERE BE INTERNAL METHODS ====================\\
+
+ /**
+ * Convert infix to postfix notation
+ *
+ * @param string $expr Expression
+ * @return string Output
+ */
+ private function nfx($expr)
+ {
+ $index = 0;
+ $stack = new EvalMathStack();
+ $output = array(); // postfix form of expression, to be passed to pfx()
+ $expr = trim(strtolower($expr));
+
+ $ops = array('+','-','*','/','^','_');
+ $ops_r = array('+' => 0,'-' => 0,'*' => 0,'/' => 0,'^' => 1); // right-associative operator?
+ $ops_p = array('+' => 0,'-' => 0,'*' => 1,'/' => 1,'_' => 1,'^' => 2); // operator precedence
+
+ $expecting_op = false; // we use this in syntax-checking the expression
+ // and determining when a - is a negation
+
+ $matches = array();
+ if (preg_match("/[^\w\s+*^\/()\.,-]/", $expr, $matches)) { // make sure the characters are all good
+ return $this->trigger(4, "illegal character '{$matches[0]}'", $matches[0]);
+ }
+
+ while (1) { // 1 Infinite Loop ;)
+ $op = substr($expr, $index, 1); // get the first character at the current index
+ // find out if we're currently at the beginning of a number/variable/function/parenthesis/operand
+ $match = array();
+ $ex = preg_match('/^([a-z]\w*\(?|\d+(?:\.\d*)?|\.\d+|\()/', substr($expr, $index), $match);
+ // ===============
+ if ($op == '-' and ! $expecting_op) { // is it a negation instead of a minus?
+ $stack->push('_'); // put a negation on the stack
+ $index ++;
+ } elseif ($op == '_') { // we have to explicitly deny this, because it's legal on the stack
+ return $this->trigger(4, "illegal character '_'", "_"); // but not in the input expression
+ // ===============
+ } elseif ((in_array($op, $ops) or $ex) and $expecting_op) { // are we putting an operator on the stack?
+ if ($ex) { // are we expecting an operator but have a number/variable/function/opening parethesis?
+ $op = '*';
+ $index --; // it's an implicit multiplication
+ }
+ // heart of the algorithm:
+ while ($stack->count > 0 and ($o2 = $stack->last()) and in_array($o2, $ops) and ($ops_r[$op] ? $ops_p[$op] < $ops_p[$o2] : $ops_p[$op] <= $ops_p[$o2])) {
+ $output[] = $stack->pop(); // pop stuff off the stack into the output
+ }
+ // many thanks: http://en.wikipedia.org/wiki/Reverse_Polish_notation#The_algorithm_in_detail
+ $stack->push($op); // finally put OUR operator onto the stack
+ $index ++;
+ $expecting_op = false;
+ // ===============
+ } elseif ($op == ')' and $expecting_op) { // ready to close a parenthesis?
+ while (($o2 = $stack->pop()) != '(') { // pop off the stack back to the last (
+ if (is_null($o2))
+ return $this->trigger(5, "unexpected ')'", ")");
+ else
+ $output[] = $o2;
+ }
+ if (preg_match("/^([a-z]\w*)\($/", $stack->last(2), $matches)) { // did we just close a function?
+ $fnn = $matches[1]; // get the function name
+ $arg_count = $stack->pop(); // see how many arguments there were (cleverly stored on the stack, thank you)
+ $output[] = $stack->pop(); // pop the function and push onto the output
+ if (in_array($fnn, $this->fb)) { // check the argument count
+ if ($arg_count > 1)
+ return $this->trigger(6, "wrong number of arguments ($arg_count given, 1 expected)", array($arg_count,1));
+ } elseif (array_key_exists($fnn, $this->f)) {
+ if ($arg_count != count($this->f[$fnn]['args']))
+ return $this->trigger(6, "wrong number of arguments ($arg_count given, " . count($this->f[$fnn]['args']) . " expected)", array($arg_count,count($this->f[$fnn]['args'])));
+ } else { // did we somehow push a non-function on the stack? this should never happen
+ return $this->trigger(7, "internal error");
+ }
+ }
+ $index ++;
+ // ===============
+ } elseif ($op == ',' and $expecting_op) { // did we just finish a function argument?
+ while (($o2 = $stack->pop()) != '(') {
+ if (is_null($o2))
+ return $this->trigger(5, "unexpected ','", ","); // oops, never had a (
+ else
+ $output[] = $o2; // pop the argument expression stuff and push onto the output
+ }
+ // make sure there was a function
+ if (! preg_match("/^([a-z]\w*)\($/", $stack->last(2), $matches))
+ return $this->trigger(5, "unexpected ','", ",");
+ $stack->push($stack->pop() + 1); // increment the argument count
+ $stack->push('('); // put the ( back on, we'll need to pop back to it again
+ $index ++;
+ $expecting_op = false;
+ // ===============
+ } elseif ($op == '(' and ! $expecting_op) {
+ $stack->push('('); // that was easy
+ $index ++;
+ $allow_neg = true;
+ // ===============
+ } elseif ($ex and ! $expecting_op) { // do we now have a function/variable/number?
+ $expecting_op = true;
+ $val = $match[1];
+ if (preg_match("/^([a-z]\w*)\($/", $val, $matches)) { // may be func, or variable w/ implicit multiplication against parentheses...
+ if (in_array($matches[1], $this->fb) or array_key_exists($matches[1], $this->f)) { // it's a func
+ $stack->push($val);
+ $stack->push(1);
+ $stack->push('(');
+ $expecting_op = false;
+ } else { // it's a var w/ implicit multiplication
+ $val = $matches[1];
+ $output[] = $val;
+ }
+ } else { // it's a plain old var or num
+ $output[] = $val;
+ }
+ $index += strlen($val);
+ // ===============
+ } elseif ($op == ')') { // miscellaneous error checking
+ return $this->trigger(5, "unexpected ')'", ")");
+ } elseif (in_array($op, $ops) and ! $expecting_op) {
+ return $this->trigger(8, "unexpected operator '$op'", $op);
+ } else { // I don't even want to know what you did to get here
+ return $this->trigger(9, "an unexpected error occured");
+ }
+ if ($index == strlen($expr)) {
+ if (in_array($op, $ops)) { // did we end with an operator? bad.
+ return $this->trigger(10, "operator '$op' lacks operand", $op);
+ } else {
+ break;
+ }
+ }
+ while (substr($expr, $index, 1) == ' ') { // step the index past whitespace (pretty much turns whitespace
+ $index ++; // into implicit multiplication if no operator is there)
+ }
+ }
+ while (! is_null($op = $stack->pop())) { // pop everything off the stack and push onto output
+ if ($op == '(')
+ return $this->trigger(11, "expecting ')'", ")"); // if there are (s on the stack, ()s were unbalanced
+ $output[] = $op;
+ }
+ return $output;
+ }
+
+ /**
+ * evaluate postfix notation
+ *
+ * @param string $tokens Expression
+ * @param array $vars Array
+ * @return string Output
+ */
+ private function pfx($tokens, $vars = array())
+ {
+ if ($tokens == false)
+ return false;
+
+ $stack = new EvalMathStack();
+
+ foreach ($tokens as $token) { // nice and easy
+ // if the token is a binary operator, pop two values off the stack, do the operation, and push the result back on
+ $matches = array();
+ if (in_array($token, array('+','-','*','/','^'))) {
+ if (is_null($op2 = $stack->pop()))
+ return $this->trigger(12, "internal error");
+ if (is_null($op1 = $stack->pop()))
+ return $this->trigger(13, "internal error");
+ switch ($token) {
+ case '+':
+ $stack->push($op1 + $op2);
+ break;
+ case '-':
+ $stack->push($op1 - $op2);
+ break;
+ case '*':
+ $stack->push($op1 * $op2);
+ break;
+ case '/':
+ if ($op2 == 0)
+ return $this->trigger(14, "division by zero");
+ $stack->push($op1 / $op2);
+ break;
+ case '^':
+ $stack->push(pow($op1, $op2));
+ break;
+ }
+ // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on
+ } elseif ($token == "_") {
+ $stack->push(- 1 * $stack->pop());
+ // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on
+ } elseif (preg_match("/^([a-z]\w*)\($/", $token, $matches)) { // it's a function!
+ $fnn = $matches[1];
+ if (in_array($fnn, $this->fb)) { // built-in function:
+ if (is_null($op1 = $stack->pop()))
+ return $this->trigger(15, "internal error");
+ $fnn = preg_replace("/^arc/", "a", $fnn); // for the 'arc' trig synonyms
+ if ($fnn == 'ln')
+ $fnn = 'log';
+ eval('$stack->push(' . $fnn . '($op1));'); // perfectly safe eval()
+ } elseif (array_key_exists($fnn, $this->f)) { // user function
+ // get args
+ $args = array();
+ for ($i = count($this->f[$fnn]['args']) - 1; $i >= 0; $i --) {
+ if (is_null($args[$this->f[$fnn]['args'][$i]] = $stack->pop()))
+ return $this->trigger(16, "internal error");
+ }
+ $stack->push($this->pfx($this->f[$fnn]['func'], $args)); // yay... recursion!!!!
+ }
+ // if the token is a number or variable, push it on the stack
+ } else {
+ if (is_numeric($token)) {
+ $stack->push($token);
+ } elseif (array_key_exists($token, $this->v)) {
+ $stack->push($this->v[$token]);
+ } elseif (array_key_exists($token, $vars)) {
+ $stack->push($vars[$token]);
+ } else {
+ return $this->trigger(17, "undefined variable '$token'", $token);
+ }
+ }
+ }
+ // when we're out of tokens, the stack should have a single element, the final result
+ if ($stack->count != 1)
+ return $this->trigger(18, "internal error");
+ return $stack->pop();
+ }
+
+ /**
+ * trigger an error, but nicely, if need be
+ *
+ * @param string $code Code
+ * @param string $msg Msg
+ * @param string|null $info String
+ * @return boolean False
+ */
+ public function trigger($code, $msg, $info = null)
+ {
+ $this->last_error = $msg;
+ $this->last_error_code = array($code,$info);
+ if (! $this->suppress_errors)
+ trigger_error($msg, E_USER_WARNING);
+ return false;
+ }
+}
+
+/**
+ * Class for internal use
+ */
+class EvalMathStack
+{
+
+ public $stack = array();
+
+ public $count = 0;
+
+ /**
+ * push
+ *
+ * @param string $val Val
+ * @return void
+ */
+ public function push($val)
+ {
+ $this->stack[$this->count] = $val;
+ $this->count ++;
+ }
+
+ /**
+ * pop
+ *
+ * @return mixed Stack
+ */
+ public function pop()
+ {
+ if ($this->count > 0) {
+ $this->count --;
+ return $this->stack[$this->count];
+ }
+ return null;
+ }
+
+ /**
+ * last
+ *
+ * @param int $n N
+ * @return mixed Stack
+ */
+ public function last($n = 1)
+ {
+ if (isset($this->stack[$this->count - $n])) {
+ return $this->stack[$this->count - $n];
+ }
+ return;
+ }
+}
diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php
index 5d5540d77b8..a9b908203fe 100644
--- a/htdocs/core/class/extrafields.class.php
+++ b/htdocs/core/class/extrafields.class.php
@@ -225,9 +225,10 @@ class ExtraFields
* @param string $langfile Language file
* @param string $enabled Condition to have the field enabled or not
* @param int $totalizable Is a measure. Must show a total on lists
+ * @param int $printable Is extrafield displayed on PDF
* @return int <=0 if KO, >0 if OK
*/
- public function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique = 0, $required = 0, $default_value = '', $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0)
+ public function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique = 0, $required = 0, $default_value = '', $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0)
{
if (empty($attrname)) return -1;
if (empty($label)) return -1;
@@ -245,7 +246,7 @@ class ExtraFields
if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate')
{
// Add declaration of field into table
- $result2 = $this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable);
+ $result2 = $this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable, $printable);
$err2 = $this->errno;
if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS'))
{
@@ -374,9 +375,11 @@ class ExtraFields
* @param string $langfile Language file
* @param string $enabled Condition to have the field enabled or not
* @param int $totalizable Is a measure. Must show a total on lists
+ * @param int $printable Is extrafield displayed on PDF
* @return int <=0 if KO, >0 if OK
+ * @throws Exception
*/
- private function create_label($attrname, $label = '', $type = '', $pos = 0, $size = 0, $elementtype = 'member', $unique = 0, $required = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0)
+ private function create_label($attrname, $label = '', $type = '', $pos = 0, $size = 0, $elementtype = 'member', $unique = 0, $required = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0)
{
// phpcs:enable
global $conf, $user;
@@ -390,6 +393,7 @@ class ExtraFields
if (empty($required)) $required = 0;
if (empty($unique)) $unique = 0;
if (empty($alwayseditable)) $alwayseditable = 0;
+ if (empty($totalizable)) $totalizable = 0;
if (!empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/", $attrname) && !is_numeric($attrname))
{
@@ -421,6 +425,7 @@ class ExtraFields
$sql .= " perms,";
$sql .= " langs,";
$sql .= " list,";
+ $sql .= " printable,";
$sql .= " fielddefault,";
$sql .= " fieldcomputed,";
$sql .= " fk_user_author,";
@@ -444,6 +449,7 @@ class ExtraFields
$sql .= " ".($perms ? "'".$this->db->escape($perms)."'" : "null").",";
$sql .= " ".($langfile ? "'".$this->db->escape($langfile)."'" : "null").",";
$sql .= " '".$this->db->escape($list)."',";
+ $sql .= " '".$this->db->escape($printable)."',";
$sql .= " ".($default ? "'".$this->db->escape($default)."'" : "null").",";
$sql .= " ".($computed ? "'".$this->db->escape($computed)."'" : "null").",";
$sql .= " ".(is_object($user) ? $user->id : 0).",";
@@ -451,7 +457,7 @@ class ExtraFields
$sql .= "'".$this->db->idate(dol_now())."',";
$sql .= " ".($enabled ? "'".$this->db->escape($enabled)."'" : "1").",";
$sql .= " ".($help ? "'".$this->db->escape($help)."'" : "null").",";
- $sql .= " ".($totalizable ? '1' : '0');
+ $sql .= " ".($totalizable ? 'TRUE' : 'FALSE');
$sql .= ')';
dol_syslog(get_class($this)."::create_label", LOG_DEBUG);
@@ -590,9 +596,11 @@ class ExtraFields
* @param string $langfile Language file
* @param string $enabled Condition to have the field enabled or not
* @param int $totalizable Is extrafield totalizable on list
+ * @param int $printable Is extrafield displayed on PDF
* @return int >0 if OK, <=0 if KO
+ * @throws Exception
*/
- public function update($attrname, $label, $type, $length, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0)
+ public function update($attrname, $label, $type, $length, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0)
{
if ($elementtype == 'thirdparty') $elementtype = 'societe';
if ($elementtype == 'contact') $elementtype = 'socpeople';
@@ -642,7 +650,7 @@ class ExtraFields
{
if ($label)
{
- $result = $this->update_label($attrname, $label, $type, $length, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default, $computed, $entity, $langfile, $enabled, $totalizable);
+ $result = $this->update_label($attrname, $label, $type, $length, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default, $computed, $entity, $langfile, $enabled, $totalizable, $printable);
}
if ($result > 0)
{
@@ -700,13 +708,15 @@ class ExtraFields
* @param string $langfile Language file
* @param string $enabled Condition to have the field enabled or not
* @param int $totalizable Is extrafield totalizable on list
+ * @param int $printable Is extrafield displayed on PDF
* @return int <=0 if KO, >0 if OK
+ * @throws Exception
*/
- private function update_label($attrname, $label, $type, $size, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '0', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0)
+ private function update_label($attrname, $label, $type, $size, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '0', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0)
{
// phpcs:enable
global $conf, $user;
- dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled.", ".$totalizable);
+ dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled.", ".$totalizable.", ".$printable);
// Clean parameters
if ($elementtype == 'thirdparty') $elementtype = 'societe';
@@ -771,6 +781,7 @@ class ExtraFields
$sql .= " alwayseditable,";
$sql .= " param,";
$sql .= " list,";
+ $sql .= " printable,";
$sql .= " totalizable,";
$sql .= " fielddefault,";
$sql .= " fieldcomputed,";
@@ -794,7 +805,8 @@ class ExtraFields
$sql .= " '".$this->db->escape($alwayseditable)."',";
$sql .= " '".$this->db->escape($params)."',";
$sql .= " '".$this->db->escape($list)."', ";
- $sql .= " ".$totalizable.",";
+ $sql .= " '".$this->db->escape($printable)."', ";
+ $sql .= " ".($totalizable ? 'TRUE' : 'FALSE').",";
$sql .= " ".(($default != '') ? "'".$this->db->escape($default)."'" : "null").",";
$sql .= " ".($computed ? "'".$this->db->escape($computed)."'" : "null").",";
$sql .= " ".$user->id.",";
@@ -871,7 +883,7 @@ class ExtraFields
}*/
// We should not have several time this request. If we have, there is some optimization to do by calling a simple $extrafields->fetch_optionals() in top of code and not into subcode
- $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,totalizable,fielddefault,fieldcomputed,entity,enabled,help";
+ $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,printable,totalizable,fielddefault,fieldcomputed,entity,enabled,help";
$sql .= " FROM ".MAIN_DB_PREFIX."extrafields";
//$sql.= " WHERE entity IN (0,".$conf->entity.")"; // Filter is done later
if ($elementtype) $sql .= " WHERE elementtype = '".$elementtype."'"; // Filed with object->table_element
@@ -933,7 +945,8 @@ class ExtraFields
$this->attributes[$tab->elementtype]['perms'][$tab->name] = (strlen($tab->perms) == 0 ? 1 : $tab->perms);
$this->attributes[$tab->elementtype]['langfile'][$tab->name] = $tab->langs;
$this->attributes[$tab->elementtype]['list'][$tab->name] = $tab->list;
- $this->attributes[$tab->elementtype]['totalizable'][$tab->name] = $tab->totalizable;
+ $this->attributes[$tab->elementtype]['printable'][$tab->name] = $tab->printable;
+ $this->attributes[$tab->elementtype]['totalizable'][$tab->name] = ($tab->totalizable ? 1 : 0);
$this->attributes[$tab->elementtype]['entityid'][$tab->name] = $tab->entity;
$this->attributes[$tab->elementtype]['enabled'][$tab->name] = $tab->enabled;
$this->attributes[$tab->elementtype]['help'][$tab->name] = $tab->help;
diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php
index 39493825377..437ac507462 100644
--- a/htdocs/core/class/hookmanager.class.php
+++ b/htdocs/core/class/hookmanager.class.php
@@ -177,6 +177,7 @@ class HookManager
'getFormatedCustomerRef',
'getFormatedSupplierRef',
'getIdProfUrl',
+ 'getInputIdProf',
'moveUploadedFile',
'moreHtmlStatus',
'pdf_build_address',
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index b8ec41c7c16..02b8529257d 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -202,7 +202,7 @@ class Form
$ret .= ' ';
if (empty($notabletag)) $ret .= '';
if (empty($notabletag)) $ret .= '';
- if (preg_match('/^(string|email)/', $typeofdata))
+ if (preg_match('/^(string|safehtmlstring|email)/', $typeofdata))
{
$tmp = explode(':', $typeofdata);
$ret .= ' ';
@@ -276,6 +276,7 @@ class Form
if (preg_match('/^(email)/', $typeofdata)) $ret .= dol_print_email($value, 0, 0, 0, 0, 1);
elseif (preg_match('/^(amount|numeric)/', $typeofdata)) $ret .= ($value != '' ? price($value, '', $langs, 0, -1, -1, $conf->currency) : '');
elseif (preg_match('/^text/', $typeofdata) || preg_match('/^note/', $typeofdata)) $ret .= dol_htmlentitiesbr($value);
+ elseif (preg_match('/^safehtmlstring/', $typeofdata)) $ret .= dol_string_onlythesehtmltags($value);
elseif ($typeofdata == 'day' || $typeofdata == 'datepicker') $ret .= dol_print_date($value, 'day');
elseif ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker') $ret .= dol_print_date($value, 'dayhour');
elseif (preg_match('/^select;/', $typeofdata))
@@ -298,9 +299,13 @@ class Form
$firstline = preg_replace('/[\n\r].*/', '', $firstline);
$tmpcontent = $firstline.((strlen($firstline) != strlen($tmpcontent)) ? '...' : '');
}
- $ret .= $tmpcontent;
+ // We dont use dol_escape_htmltag to get the html formating active, but this need we must also
+ // clean data from some dangerous html
+ $ret .= dol_string_onlythesehtmltags(dol_htmlentitiesbr($tmpcontent));
+ }
+ else {
+ $ret .= dol_escape_htmltag($value);
}
- else $ret .= dol_escape_htmltag($value);
if ($formatfunc && method_exists($object, $formatfunc))
{
@@ -461,8 +466,6 @@ class Form
*/
public function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 3, $incbefore = '', $noencodehtmltext = 0, $tooltiptrigger = '', $forcenowrap = 0)
{
- global $conf;
-
if ($incbefore) $text = $incbefore.$text;
if (!$htmltext) return $text;
@@ -470,9 +473,7 @@ class Form
if ($notabs == 2) $tag = 'div';
if ($notabs == 3) $tag = 'span';
// Sanitize tooltip
- //$htmltext=str_replace("\\","\\\\",$htmltext);
- $htmltext = str_replace("\r", "", $htmltext);
- $htmltext = str_replace("\n", "", $htmltext);
+ $htmltext = str_replace(array("\r", "\n"), '', $htmltext);
$extrastyle = '';
if ($direction < 0) { $extracss = ($extracss ? $extracss.' ' : '').($notabs != 3 ? 'inline-block' : ''); $extrastyle = 'padding: 0px; padding-left: 3px !important;'; }
@@ -484,7 +485,7 @@ class Form
if ($tooltiptrigger == '')
{
- $htmltext = str_replace('"', """, $htmltext);
+ $htmltext = str_replace('"', '"', $htmltext);
}
else
{
@@ -2109,7 +2110,7 @@ class Form
}
}
- $selectFields = " p.rowid, p.label, p.ref, p.description, p.barcode, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.duration, p.fk_price_expression";
+ $selectFields = " p.rowid, p.ref, p.label, p.description, p.barcode, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.duration, p.fk_price_expression";
if (count($warehouseStatusArray))
{
$selectFieldsGrouped = ", sum(".$db->ifsql("e.statut IS NULL", "0", "ps.reel").") as stock"; // e.statut is null if there is no record in stock
@@ -2400,9 +2401,10 @@ class Form
* @param string $selected Preselected value
* @param int $hidepriceinlabel Hide price in label
* @param string $filterkey Filter key to highlight
+ * @param int $novirtualstock Do not load virtual stock, even if slow option STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO is on.
* @return void
*/
- protected function constructProductListOption(&$objp, &$opt, &$optJson, $price_level, $selected, $hidepriceinlabel = 0, $filterkey = '')
+ protected function constructProductListOption(&$objp, &$opt, &$optJson, $price_level, $selected, $hidepriceinlabel = 0, $filterkey = '', $novirtualstock = 0)
{
global $langs, $conf, $user, $db;
@@ -2431,6 +2433,7 @@ class Form
$outlabel = $objp->label;
$outdesc = $objp->description;
$outbarcode = $objp->barcode;
+ $outpbq = empty($objp->price_by_qty_rowid) ? '' : $objp->price_by_qty_rowid;
$outtype = $objp->fk_product_type;
$outdurationvalue = $outtype == Product::TYPE_SERVICE ?substr($objp->duration, 0, dol_strlen($objp->duration) - 1) : '';
@@ -2478,7 +2481,7 @@ class Form
$opt .= ($objp->rowid == $selected) ? ' selected' : '';
if (!empty($objp->price_by_qty_rowid) && $objp->price_by_qty_rowid > 0)
{
- $opt .= ' pbq="'.$objp->price_by_qty_rowid.'" data-pbq="'.$objp->price_by_qty_rowid.'" data-pbqqty="'.$objp->price_by_qty_quantity.'" data-pbqpercent="'.$objp->price_by_qty_remise_percent.'"';
+ $opt .= ' pbq="'.$objp->price_by_qty_rowid.'" data-pbq="'.$objp->price_by_qty_rowid.'" data-pbqup="'.$objp->price_by_qty_unitprice.'" data-pbqbase="'.$objp->price_by_qty_price_base_type.'" data-pbqqty="'.$objp->price_by_qty_quantity.'" data-pbqpercent="'.$objp->price_by_qty_remise_percent.'"';
}
if (!empty($conf->stock->enabled) && isset($objp->stock) && ($objp->fk_product_type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES)))
{
@@ -2638,7 +2641,7 @@ class Form
}
$outval .= $langs->transnoentities("Stock").':'.$objp->stock;
$outval .= '';
- if (!empty($conf->global->STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO)) // Warning, this option may slow down combo list generation
+ if (empty($novirtualstock) && !empty($conf->global->STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO)) // Warning, this option may slow down combo list generation
{
$langs->load("stocks");
@@ -2664,7 +2667,7 @@ class Form
}
$opt .= "\n";
- $optJson = array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'label2'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>price2num($outprice_ht), 'price_ttc'=>price2num($outprice_ttc), 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, 'discount'=>$outdiscount, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit);
+ $optJson = array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'label2'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>price2num($outprice_ht), 'price_ttc'=>price2num($outprice_ttc), 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, 'discount'=>$outdiscount, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit, 'pbq'=>$outpbq);
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
@@ -2736,13 +2739,15 @@ class Form
$out = '';
$outarray = array();
+ $maxlengtharticle = (empty($conf->global->PRODUCT_MAX_LENGTH_COMBO) ? 48 : $conf->global->PRODUCT_MAX_LENGTH_COMBO);
+
$langs->load('stocks');
// Units
if ($conf->global->PRODUCT_USE_UNITS) {
$langs->load('other');
}
- $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, p.fk_product_type,";
+ $sql = "SELECT p.rowid, p.ref, p.label, p.price, p.duration, p.fk_product_type,";
$sql .= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice,";
$sql .= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.fk_soc, s.nom as name,";
$sql .= " pfp.supplier_reputation";
@@ -2750,7 +2755,7 @@ class Form
if ($conf->global->PRODUCT_USE_UNITS) {
$sql .= ", u.label as unit_long, u.short_label as unit_short, p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units";
}
- if (!empty($conf->barcode->enabled)) $sql .= " ,pfp.barcode";
+ if (!empty($conf->barcode->enabled)) $sql .= ", pfp.barcode";
$sql .= " FROM ".MAIN_DB_PREFIX."product as p";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
if ($socid) $sql .= " AND pfp.fk_soc = ".$socid;
@@ -2813,6 +2818,7 @@ class Form
$outref = $objp->ref;
$outval = '';
+ $outbarcode = $objp->barcode;
$outqty = 1;
$outdiscount = 0;
$outtype = $objp->fk_product_type;
@@ -2863,12 +2869,22 @@ class Form
if ($filterkey && $filterkey != '') $label = preg_replace('/('.preg_quote($filterkey).')/i', '$1 ', $label, 1);
$optlabel = $objp->ref;
- if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn))
+ if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) {
$optlabel .= ' ('.$objp->ref_fourn.') ';
+ }
+ if (!empty($conf->barcode->enabled) && !empty($objp->barcode)) {
+ $optlabel .= ' ('.$outbarcode.')';
+ }
+ $optlabel .= ' - '.dol_trunc($label, $maxlengtharticle);
$outvallabel = $objRef;
- if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn))
+ if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) {
$outvallabel .= ' ('.$objRefFourn.')';
+ }
+ if (!empty($conf->barcode->enabled) && !empty($objp->barcode)) {
+ $outvallabel .= ' ('.$outbarcode.')';
+ }
+ $outvallabel .= ' - '.dol_trunc($label, $maxlengtharticle);
// Units
$optlabel .= $outvalUnits;
@@ -2891,7 +2907,7 @@ class Form
$objp->fprice = $price_result;
if ($objp->quantity >= 1)
{
- $objp->unitprice = $objp->fprice / $objp->quantity;
+ $objp->unitprice = $objp->fprice / $objp->quantity; // Replace dynamically unitprice
}
}
}
@@ -2930,12 +2946,6 @@ class Form
$optlabel .= " - ".dol_trunc($objp->name, 8);
$outvallabel .= " - ".dol_trunc($objp->name, 8);
}
- if (!empty($conf->barcode->enabled) && !empty($objp->barcode))
- {
- //$optlabel .= " - ".$objp->barcode;
- $optlabel .= " - ".$objp->barcode;
- $outvallabel .= " - ".$objp->barcode;
- }
if ($objp->supplier_reputation)
{
//TODO dictionary
@@ -2964,7 +2974,7 @@ class Form
if (empty($objp->idprodfournprice) && empty($alsoproductwithnosupplierprice)) $opt .= ' disabled';
if (!empty($objp->idprodfournprice) && $objp->idprodfournprice > 0)
{
- $opt .= ' pbq="'.$objp->idprodfournprice.'" data-pbq="'.$objp->idprodfournprice.'" data-pbqqty="'.$objp->quantity.'" data-pbqpercent="'.$objp->remise_percent.'"';
+ $opt .= ' pbq="'.$objp->idprodfournprice.'" data-pbq="'.$objp->idprodfournprice.'" data-pbqqty="'.$objp->quantity.'" data-pbqup="'.$objp->unitprice.'" data-pbqpercent="'.$objp->remise_percent.'"';
}
$opt .= ' data-html="'.dol_escape_htmltag($optlabel).'"';
$opt .= '>';
@@ -2979,7 +2989,7 @@ class Form
// "key" value of json key array is used by jQuery automatically as selected value
// "label" value of json key array is used by jQuery automatically as text for combo box
$out .= $opt;
- array_push($outarray, array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'qty'=>$outqty, 'discount'=>$outdiscount, 'type'=>$outtype, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit, 'disabled'=>(empty($objp->idprodfournprice) ?true:false)));
+ array_push($outarray, array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'qty'=>$outqty, 'up'=>$objp->unitprice, 'discount'=>$outdiscount, 'type'=>$outtype, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit, 'disabled'=>(empty($objp->idprodfournprice) ?true:false)));
// Exemple of var_dump $outarray
// array(1) {[0]=>array(6) {[key"]=>string(1) "2" ["value"]=>string(3) "ppp"
// ["label"]=>string(76) "ppp (f ff2) - ppp - 20,00 Euros/1unité (20,00 Euros/unité)"
@@ -3023,7 +3033,7 @@ class Form
$langs->load('stocks');
- $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, pfp.fk_soc,";
+ $sql = "SELECT p.rowid, p.ref, p.label, p.price, p.duration, pfp.fk_soc,";
$sql .= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.remise_percent, pfp.quantity, pfp.unitprice,";
$sql .= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, s.nom as name";
$sql .= " FROM ".MAIN_DB_PREFIX."product as p";
@@ -3498,6 +3508,7 @@ class Form
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Return list of payment methods
+ * Constant MAIN_DEFAULT_PAYMENT_TYPE_ID can used to set default value but scope is all application, probably not what you want.
*
* @param string $selected Id du mode de paiement pre-selectionne
* @param string $htmlname Nom de la zone select
@@ -3513,7 +3524,7 @@ class Form
public function select_types_paiements($selected = '', $htmlname = 'paiementtype', $filtertype = '', $format = 0, $empty = 1, $noadmininfo = 0, $maxlength = 0, $active = 1, $morecss = '')
{
// phpcs:enable
- global $langs, $user;
+ global $langs, $user, $conf;
dol_syslog(__METHOD__." ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG);
@@ -3524,6 +3535,9 @@ class Form
$this->load_cache_types_paiements();
+ // Set default value if not already set by caller
+ if (empty($selected) && !empty($conf->global->MAIN_DEFAULT_PAYMENT_TYPE_ID)) $selected = $conf->global->MAIN_DEFAULT_PAYMENT_TYPE_ID;
+
print '';
if ($empty) print ' ';
foreach ($this->cache_types_paiements as $id => $arraytypes)
@@ -5255,8 +5269,9 @@ class Form
$disabled = false; $title = '';
if (is_object($societe_vendeuse) && $societe_vendeuse->id == $mysoc->id && $societe_vendeuse->tva_assuj == "0")
{
- // Override/enable VAT for expense report regardless of global setting - needed if expense report used for business expenses
- if (empty($conf->global->OVERRIDE_VAT_FOR_EXPENSE_REPORT))
+ // Override/enable VAT for expense report regardless of global setting - needed if expense report used for business expenses instead
+ // of using supplier invoices (this is a very bad idea !)
+ if (empty($conf->global->EXPENSEREPORT_OVERRIDE_VAT))
{
$title = ' title="'.$langs->trans('VATIsNotUsed').'"';
$disabled = true;
@@ -6037,7 +6052,7 @@ class Form
// Search data
$sql = "SELECT t.rowid, ".$fieldstoshow." FROM ".MAIN_DB_PREFIX.$objecttmp->table_element." as t";
- if (isset($objecttmp->ismultientitymanaged) && ! is_numeric($objecttmp->ismultientitymanaged)) {
+ if (isset($objecttmp->ismultientitymanaged) && !is_numeric($objecttmp->ismultientitymanaged)) {
$tmparray = explode('@', $objecttmp->ismultientitymanaged);
$sql .= ' INNER JOIN '.MAIN_DB_PREFIX.$tmparray[1].' as parenttable ON parenttable.rowid = t.'.$tmparray[0];
}
@@ -6045,7 +6060,7 @@ class Form
if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql .= " WHERE 1=1";
if (isset($objecttmp->ismultientitymanaged) && $objecttmp->ismultientitymanaged == 1) $sql .= " AND t.entity IN (".getEntity($objecttmp->table_element).")";
- if (isset($objecttmp->ismultientitymanaged) && ! is_numeric($objecttmp->ismultientitymanaged)) {
+ if (isset($objecttmp->ismultientitymanaged) && !is_numeric($objecttmp->ismultientitymanaged)) {
$sql .= ' AND parenttable.entity = t.'.$tmparray[0];
}
if ($objecttmp->ismultientitymanaged == 1 && !empty($user->socid)) {
@@ -6188,7 +6203,7 @@ class Form
$out .= ajax_combobox($htmlname);
}
- $out .= '
jQuery(document).ready(function () {
$(\'.multiselectcheckbox'.$htmlname.' input[type="checkbox"]\').on(\'click\', function () {
- console.log("A new field was added/removed")
- $("input:hidden[name=formfilteraction]").val(\'listafterchangingselectedfields\')
+ console.log("A new field was added/removed, we edit field input[name=formfilteraction]");
+
+ $("input:hidden[name=formfilteraction]").val(\'listafterchangingselectedfields\'); // Update field so we know we changed something on selected fields after POST
+
var title = $(this).val() + ",";
if ($(this).is(\':checked\')) {
$(\'.'.$htmlname.'\').val(title + $(\'.'.$htmlname.'\').val());
@@ -6691,8 +6708,10 @@ class Form
$(\'.'.$htmlname.'\').val( $(\'.'.$htmlname.'\').val().replace(title, \'\') )
}
// Now, we submit page
- $(this).parents(\'form:first\').submit();
+ //$(this).parents(\'form:first\').submit();
});
+
+
});
@@ -7058,7 +7077,6 @@ class Form
jQuery(".linkto").click(function() {
console.log("We choose to show/hide link for rel="+jQuery(this).attr(\'rel\'));
jQuery("#"+jQuery(this).attr(\'rel\')+"list").toggle();
- jQuery(this).toggle();
});
});
@@ -7306,21 +7324,21 @@ class Form
}
elseif ($fieldref != 'none')
{
- $ret.=dol_htmlentities($object->$fieldref);
+ $ret .= dol_htmlentities($object->$fieldref);
}
if ($morehtmlref)
{
// don't add a additional space, when "$morehtmlref" starts with a HTML div tag
- if(substr($morehtmlref, 0, 4) != '';
+ $ret .= '
';
$ret .= '';
@@ -8059,11 +8077,15 @@ class Form
$ret .= $langs->trans("Filters");
$ret .= '';
//$ret .= ' ';
- $ret .= '';
- $ret .= '
';
+ $ret .= '
';
+ $texttoshow = '
'.$langs->trans("Search").'
';
+
+ $ret .= '
'.$texttoshow.'
';
$ret .= '
';
- foreach($arrayofcriterias as $criterias) {
- foreach($criterias as $criteriafamilykey => $criteriafamilyval) {
+ $ret .= '
';
+ // For compatibility with forms that show themself the search criteria in addition of this component, we output the fields
+ foreach ($arrayofcriterias as $criterias) {
+ foreach ($criterias as $criteriafamilykey => $criteriafamilyval) {
if (in_array('search_'.$criteriafamilykey, $arrayofinputfieldsalreadyoutput)) continue;
if (in_array($criteriafamilykey, array('rowid', 'ref_ext', 'entity', 'extraparams'))) continue;
if (in_array($criteriafamilyval['type'], array('date', 'datetime', 'timestamp'))) {
diff --git a/htdocs/core/class/html.formaccounting.class.php b/htdocs/core/class/html.formaccounting.class.php
index 64e027db537..19fa3f6fb26 100644
--- a/htdocs/core/class/html.formaccounting.class.php
+++ b/htdocs/core/class/html.formaccounting.class.php
@@ -461,12 +461,12 @@ class FormAccounting extends Form
$sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
$sql .= " WHERE entity IN (".getEntity('accountancy').")";
$sql .= " ORDER BY date_format(doc_date, '%Y')";
- dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$this->error = "Error ".$this->db->lasterror();
- dol_syslog(get_class($this)."::".__METHOD__.$this->error, LOG_ERR);
+ dol_syslog(__METHOD__.$this->error, LOG_ERR);
return -1;
}
while ($obj = $this->db->fetch_object($resql)) {
diff --git a/htdocs/core/class/html.formadmin.class.php b/htdocs/core/class/html.formadmin.class.php
index 7012b813f7d..21c15b3b7c6 100644
--- a/htdocs/core/class/html.formadmin.class.php
+++ b/htdocs/core/class/html.formadmin.class.php
@@ -50,7 +50,7 @@ class FormAdmin
* @param string $selected Language pre-selected
* @param string $htmlname Name of HTML select
* @param int $showauto Show 'auto' choice
- * @param array $filter Array of keys to exclude in list
+ * @param array $filter Array of keys to exclude in list (opposite of $onlykeys)
* @param string $showempty '1'=Add empty value or string to show
* @param int $showwarning Show a warning if language is not complete
* @param int $disabled Disable edit of select
@@ -58,16 +58,18 @@ class FormAdmin
* @param int $showcode 1=Add language code into label at begining, 2=Add language code into label at end
* @param int $forcecombo Force to use combo box (so no ajax beautify effect)
* @param int $multiselect Make the combo a multiselect
+ * @param array $onlykeys Show only the following keys (opposite of $filter)
+ * @param int $mainlangonly 1=Show only main languages ('fr_FR' no' fr_BE', 'es_ES' not 'es_MX', ...)
* @return string Return HTML select string with list of languages
*/
- public function select_language($selected = '', $htmlname = 'lang_id', $showauto = 0, $filter = null, $showempty = '', $showwarning = 0, $disabled = 0, $morecss = '', $showcode = 0, $forcecombo = 0, $multiselect = 0)
+ public function select_language($selected = '', $htmlname = 'lang_id', $showauto = 0, $filter = null, $showempty = '', $showwarning = 0, $disabled = 0, $morecss = '', $showcode = 0, $forcecombo = 0, $multiselect = 0, $onlykeys = array(), $mainlangonly = 0)
{
// phpcs:enable
global $conf, $langs;
if (!empty($conf->global->MAIN_DEFAULT_LANGUAGE_FILTER)) $filter[$conf->global->MAIN_DEFAULT_LANGUAGE_FILTER] = 1;
- $langs_available=$langs->get_available_languages(DOL_DOCUMENT_ROOT, 12);
+ $langs_available=$langs->get_available_languages(DOL_DOCUMENT_ROOT, 12, 0, $mainlangonly);
$out='';
@@ -94,19 +96,28 @@ class FormAdmin
{
$valuetoshow=$value;
if ($showcode == 1) $valuetoshow=$key.' - '.$value;
- if ($showcode == 2) $valuetoshow=$value.' ('.$key.')';
+ if ($showcode == 2) {
+ if ($mainlangonly) $valuetoshow=$value.' ('.preg_replace('/[_-].*$/', '', $key).')';
+ else $valuetoshow=$value.' ('.$key.')';
+ }
- if ($filter && is_array($filter) && array_key_exists($key, $filter))
- {
+ $keytouse = $key;
+ if ($mainlangonly) $keytouse = preg_replace('/[_-].*$/', '', $key);
+
+ if ($filter && is_array($filter) && array_key_exists($keytouse, $filter)) {
continue;
}
- elseif ($selected == $key)
+ if ($onlykeys && is_array($onlykeys) && ! array_key_exists($keytouse, $onlykeys)) {
+ continue;
+ }
+
+ if ($selected == $keytouse)
{
- $out.= '
'.$valuetoshow.' ';
+ $out.= '
'.$valuetoshow.' ';
}
else
{
- $out.= '
'.$valuetoshow.' ';
+ $out.= '
'.$valuetoshow.' ';
}
}
$out.= '';
@@ -134,49 +145,49 @@ class FormAdmin
public function select_menu($selected, $htmlname, $dirmenuarray, $moreattrib = '')
{
// phpcs:enable
- global $langs,$conf;
+ global $langs, $conf;
// Clean parameters
// Check parameters
- if (! is_array($dirmenuarray)) return -1;
+ if (!is_array($dirmenuarray)) return -1;
- $menuarray=array();
+ $menuarray = array();
foreach ($conf->file->dol_document_root as $dirroot)
{
- foreach($dirmenuarray as $dirtoscan)
+ foreach ($dirmenuarray as $dirtoscan)
{
- $dir=$dirroot.$dirtoscan;
+ $dir = $dirroot.$dirtoscan;
//print $dir.'
';
if (is_dir($dir))
{
- $handle=opendir($dir);
+ $handle = opendir($dir);
if (is_resource($handle))
{
- while (($file = readdir($handle))!==false)
+ while (($file = readdir($handle)) !== false)
{
if (is_file($dir."/".$file) && substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS' && substr($file, 0, 5) != 'index')
{
- if (preg_match('/lib\.php$/i', $file)) continue; // We exclude library files
- if (preg_match('/eldy_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files
- if (preg_match('/auguria_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files
- if (preg_match('/smartphone_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files
+ if (preg_match('/lib\.php$/i', $file)) continue; // We exclude library files
+ if (preg_match('/eldy_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files
+ if (preg_match('/auguria_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files
+ if (preg_match('/smartphone_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files
- $filelib=preg_replace('/\.php$/i', '', $file);
- $prefix='';
+ $filelib = preg_replace('/\.php$/i', '', $file);
+ $prefix = '';
// 0=Recommanded, 1=Experimental, 2=Developpement, 3=Other
- if (preg_match('/^eldy/i', $file)) $prefix='0';
- elseif (preg_match('/^smartphone/i', $file)) $prefix='2';
- else $prefix='3';
+ if (preg_match('/^eldy/i', $file)) $prefix = '0';
+ elseif (preg_match('/^smartphone/i', $file)) $prefix = '2';
+ else $prefix = '3';
if ($file == $selected)
{
- $menuarray[$prefix.'_'.$file]='
'.$filelib.' ';
+ $menuarray[$prefix.'_'.$file] = '
'.$filelib.' ';
}
else
{
- $menuarray[$prefix.'_'.$file]='
'.$filelib.' ';
+ $menuarray[$prefix.'_'.$file] = '
'.$filelib.' ';
}
}
}
@@ -188,26 +199,26 @@ class FormAdmin
ksort($menuarray);
// Output combo list of menus
- print '
';
- $oldprefix='';
+ print '';
+ $oldprefix = '';
foreach ($menuarray as $key => $val)
{
- $tab=explode('_', $key);
- $newprefix=$tab[0];
- if ($newprefix=='1' && ($conf->global->MAIN_FEATURES_LEVEL < 1)) continue;
- if ($newprefix=='2' && ($conf->global->MAIN_FEATURES_LEVEL < 2)) continue;
+ $tab = explode('_', $key);
+ $newprefix = $tab[0];
+ if ($newprefix == '1' && ($conf->global->MAIN_FEATURES_LEVEL < 1)) continue;
+ if ($newprefix == '2' && ($conf->global->MAIN_FEATURES_LEVEL < 2)) continue;
if ($newprefix != $oldprefix) // Add separators
{
// Affiche titre
print '';
- if ($newprefix=='0') print '-- '.$langs->trans("VersionRecommanded").' --';
- if ($newprefix=='1') print '-- '.$langs->trans("VersionExperimental").' --';
- if ($newprefix=='2') print '-- '.$langs->trans("VersionDevelopment").' --';
- if ($newprefix=='3') print '-- '.$langs->trans("Other").' --';
+ if ($newprefix == '0') print '-- '.$langs->trans("VersionRecommanded").' --';
+ if ($newprefix == '1') print '-- '.$langs->trans("VersionExperimental").' --';
+ if ($newprefix == '2') print '-- '.$langs->trans("VersionDevelopment").' --';
+ if ($newprefix == '3') print '-- '.$langs->trans("Other").' --';
print ' ';
- $oldprefix=$newprefix;
+ $oldprefix = $newprefix;
}
- print $val."\n"; // Show menu entry
+ print $val."\n"; // Show menu entry
}
print ' ';
}
@@ -224,37 +235,37 @@ class FormAdmin
public function select_menu_families($selected, $htmlname, $dirmenuarray)
{
// phpcs:enable
- global $langs,$conf;
+ global $langs, $conf;
//$expdevmenu=array('smartphone_backoffice.php','smartphone_frontoffice.php'); // Menu to disable if $conf->global->MAIN_FEATURES_LEVEL is not set
- $expdevmenu=array();
+ $expdevmenu = array();
- $menuarray=array();
+ $menuarray = array();
- foreach($dirmenuarray as $dirmenu)
+ foreach ($dirmenuarray as $dirmenu)
{
foreach ($conf->file->dol_document_root as $dirroot)
{
- $dir=$dirroot.$dirmenu;
+ $dir = $dirroot.$dirmenu;
if (is_dir($dir))
{
- $handle=opendir($dir);
+ $handle = opendir($dir);
if (is_resource($handle))
{
- while (($file = readdir($handle))!==false)
+ while (($file = readdir($handle)) !== false)
{
if (is_file($dir."/".$file) && substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS')
{
- $filelib=preg_replace('/(_backoffice|_frontoffice)?\.php$/i', '', $file);
+ $filelib = preg_replace('/(_backoffice|_frontoffice)?\.php$/i', '', $file);
if (preg_match('/^index/i', $filelib)) continue;
if (preg_match('/^default/i', $filelib)) continue;
if (preg_match('/^empty/i', $filelib)) continue;
if (preg_match('/\.lib/i', $filelib)) continue;
if (empty($conf->global->MAIN_FEATURES_LEVEL) && in_array($file, $expdevmenu)) continue;
- $menuarray[$filelib]=1;
+ $menuarray[$filelib] = 1;
}
- $menuarray['all']=1;
+ $menuarray['all'] = 1;
}
closedir($handle);
}
@@ -266,11 +277,11 @@ class FormAdmin
// Affichage liste deroulante des menus
print '';
- $oldprefix='';
+ $oldprefix = '';
foreach ($menuarray as $key => $val)
{
- $tab=explode('_', $key);
- $newprefix=$tab[0];
+ $tab = explode('_', $key);
+ $newprefix = $tab[0];
print '';
print ' ';
@@ -356,21 +367,21 @@ class FormAdmin
$langs->load("dict");
$sql = "SELECT code, label, width, height, unit";
- $sql.= " FROM ".MAIN_DB_PREFIX."c_paper_format";
- $sql.= " WHERE active=1";
- if ($filter) $sql.=" AND code LIKE '%".$this->db->escape($filter)."%'";
+ $sql .= " FROM ".MAIN_DB_PREFIX."c_paper_format";
+ $sql .= " WHERE active=1";
+ if ($filter) $sql .= " AND code LIKE '%".$this->db->escape($filter)."%'";
- $resql=$this->db->query($sql);
+ $resql = $this->db->query($sql);
if ($resql)
{
- $num=$this->db->num_rows($resql);
- $i=0;
+ $num = $this->db->num_rows($resql);
+ $i = 0;
while ($i < $num)
{
- $obj=$this->db->fetch_object($resql);
+ $obj = $this->db->fetch_object($resql);
$unitKey = $langs->trans('SizeUnit'.$obj->unit);
- $paperformat[$obj->code]= $langs->trans('PaperFormat'.strtoupper($obj->code)).' - '.round($obj->width).'x'.round($obj->height).' '.($unitKey == 'SizeUnit'.$obj->unit ? $obj->unit : $unitKey);
+ $paperformat[$obj->code] = $langs->trans('PaperFormat'.strtoupper($obj->code)).' - '.round($obj->width).'x'.round($obj->height).' '.($unitKey == 'SizeUnit'.$obj->unit ? $obj->unit : $unitKey);
$i++;
}
@@ -380,27 +391,27 @@ class FormAdmin
dol_print_error($this->db);
return '';
}
- $out='';
+ $out = '';
- $out.= '';
+ $out .= '';
if ($showempty)
{
- $out.= ' ';
+ $out .= ' $value)
{
if ($selected == $key)
{
- $out.= ' '.$value.' ';
+ $out .= ''.$value.' ';
}
else
{
- $out.= ''.$value.' ';
+ $out .= ''.$value.' ';
}
}
- $out.= ' ';
+ $out .= ' ';
return $out;
}
diff --git a/htdocs/core/class/html.formcategory.class.php b/htdocs/core/class/html.formcategory.class.php
new file mode 100644
index 00000000000..4dd8bed247b
--- /dev/null
+++ b/htdocs/core/class/html.formcategory.class.php
@@ -0,0 +1,58 @@
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \file htdocs/core/class/html.formcategory.class.php
+ * \ingroup core
+ * \brief File of class to build HTML component for category filtering
+ */
+
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
+
+class FormCategory extends Form
+{
+ /**
+ * Return a HTML filter box for a list filter view
+ *
+ * @param string $type The categorie type (e.g Categorie::TYPE_WAREHOUSE)
+ * @param Array $preSelected A list with the elements that should pre-selected
+ * @return string A HTML filter box (Note: selected results can get with GETPOST("search_category_".$type."_list"))
+ */
+ public function getFilterBox($type, $preSelected)
+ {
+ // phpcs:enable
+ global $langs;
+
+ if (empty($preSelected) || !is_array($preSelected))
+ {
+ $preSelected = array();
+ }
+
+ $htmlName = "search_category_".$type."_list";
+
+ $categoryArray = $this->select_all_categories($type, "", "", 64, 0, 1);
+ $categoryArray[-2] = "- ".$langs->trans('NotCategorized')." -";
+
+ $filter = '';
+ $filter .= '';
+ $filter .= $langs->trans('Categories').": ";
+ $filter .= Form::multiselectarray($htmlName, $categoryArray, $preSelected, 0, 0, "minwidth300");
+ $filter .= "
";
+
+ return $filter;
+ }
+}
diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php
index a08694560ec..e084028b430 100644
--- a/htdocs/core/class/html.formcompany.class.php
+++ b/htdocs/core/class/html.formcompany.class.php
@@ -249,8 +249,7 @@ class FormCompany extends Form
}
}
- if ((!empty($selected) && $selected == $obj->rowid)
- || (empty($selected) && !empty($conf->global->MAIN_FORCE_DEFAULT_STATE_ID) && $conf->global->MAIN_FORCE_DEFAULT_STATE_ID == $obj->rowid))
+ if (!empty($selected) && $selected == $obj->rowid)
{
$out .= '';
}
@@ -455,9 +454,10 @@ class FormCompany extends Form
* @param int $country_codeid 0=list for all countries, otherwise list only country requested
* @param string $filter Add a SQL filter on list
* @param string $htmlname HTML name of select
+ * @param string $morecss More CSS
* @return string String with HTML select
*/
- public function select_juridicalstatus($selected = '', $country_codeid = 0, $filter = '', $htmlname = 'forme_juridique_code')
+ public function select_juridicalstatus($selected = '', $country_codeid = 0, $filter = '', $htmlname = 'forme_juridique_code', $morecss = '')
{
// phpcs:enable
global $conf, $langs, $user;
@@ -479,7 +479,7 @@ class FormCompany extends Form
if ($resql)
{
$out .= '';
- $out .= '
';
+ $out .= '';
if ($country_codeid) $out .= ' '; // When country_codeid is set, we force to add an empty line because it does not appears from select. When not set, we already get the empty line from select.
$num = $this->db->num_rows($resql);
@@ -767,7 +767,7 @@ class FormCompany extends Form
if ($rendermode === 'edit')
{
- $contactType = $contact->listeTypeContacts('external', '', 1);
+ $contactType = $contact->listeTypeContacts('external', '', 1, '', '', 'agenda'); // We exclude agenda as there is no contact on such element
if (count($selected) > 0) {
$newselected = array();
foreach ($selected as $key=>$val) {
@@ -832,7 +832,7 @@ class FormCompany extends Form
public function get_input_id_prof($idprof, $htmlname, $preselected, $country_code, $morecss = 'maxwidth100onsmartphone quatrevingtpercent')
{
// phpcs:enable
- global $conf, $langs;
+ global $conf, $langs, $hookmanager;
$formlength = 0;
if (empty($conf->global->MAIN_DISABLEPROFIDRULES)) {
@@ -865,7 +865,16 @@ class FormCompany extends Form
$maxlength = $formlength;
if (empty($formlength)) { $formlength = 24; $maxlength = 128; }
- $out = ' ';
+ $out = '';
+
+ // Execute hook getInputIdProf to complete or replace $out
+ $parameters=array('formlength'=>$formlength, 'selected'=>$preselected, 'idprof'=>$idprof, 'htmlname'=>$htmlname, 'country_code'=>$country_code);
+ $reshook=$hookmanager->executeHooks('getInputIdProf', $parameters);
+ if (empty($reshook))
+ {
+ $out .= ' ';
+ }
+ $out .= $hookmanager->resPrint;
return $out;
}
@@ -950,7 +959,7 @@ class FormCompany extends Form
$out .= ''.$langs->trans('Prospect').' ';
}
$out .= ''.$langs->trans('Supplier').' ';
- $out .= ''.$langs->trans('Others').' ';
+ $out .= ''.$langs->trans('Other').' ';
} elseif ($typeinput == 'admin') {
if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTSCUSTOMERS)) {
$out .= ''.$langs->trans('ProspectCustomer').' ';
diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
index 7a3b48e1c40..111605d38b7 100644
--- a/htdocs/core/class/html.formfile.class.php
+++ b/htdocs/core/class/html.formfile.class.php
@@ -325,7 +325,7 @@ class FormFile
* @param int $notused Not used
* @param integer $noform Do not output html form tags
* @param string $param More param on http links
- * @param string $title Title to show on top of form
+ * @param string $title Title to show on top of form. Example: '' (Default to "Documents") or 'none'
* @param string $buttonlabel Label on submit button
* @param string $codelang Default language code to use on lang combo box if multilang is enabled
* @param string $morepicto Add more HTML content into cell with picto
@@ -408,7 +408,7 @@ class FormFile
}
$titletoshow = $langs->trans("Documents");
- if (!empty($title)) $titletoshow = $title;
+ if (!empty($title)) $titletoshow = ($title == 'none' ? '' : $title);
// Show table
if ($genallowed)
@@ -1099,7 +1099,7 @@ class FormFile
if ($disablecrop == -1)
{
$disablecrop = 1;
- if (in_array($modulepart, array('bank', 'bom', 'expensereport', 'holiday', 'member', 'mrp', 'project', 'product', 'produit', 'propal', 'service', 'societe', 'tax', 'ticket', 'user'))) $disablecrop = 0;
+ if (in_array($modulepart, array('bank', 'bom', 'expensereport', 'holiday', 'member', 'mrp', 'project', 'product', 'produit', 'propal', 'service', 'societe', 'tax', 'tax-vat', 'ticket', 'user'))) $disablecrop = 0;
}
// Define relative path used to store the file
@@ -1121,6 +1121,8 @@ class FormFile
$relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $upload_dir);
$relativedir = preg_replace('/^[\\/]/', '', $relativedir);
}
+ // For example here $upload_dir = '/pathtodocuments/commande/SO2001-123/'
+ // For example here $upload_dir = '/pathtodocuments/tax/vat/1'
$hookmanager->initHooks(array('formfile'));
$parameters = array(
diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php
index b7e9c53a845..d961cd20536 100644
--- a/htdocs/core/class/html.formmail.class.php
+++ b/htdocs/core/class/html.formmail.class.php
@@ -112,14 +112,7 @@ class FormMail extends Form
public $withfrom;
/**
- * @var int
- * @deprecated Fill withto with array before calling method.
- * @see $withto
- */
- public $withtosocid;
-
- /**
- * @var int|int[]
+ * @var int|string|array
*/
public $withto; // Show recipient emails
@@ -1034,6 +1027,7 @@ class FormMail extends Form
$out .= ' $(document).on("keypress", \'#mailform\', function (e) { /* Note this is called at every key pressed ! */
var code = e.keyCode || e.which;
if (code == 13) {
+ console.log("Enter was intercepted and blocked");
e.preventDefault();
return false;
}
diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php
index c379d1912d1..cc4d0d0b8e5 100644
--- a/htdocs/core/class/html.formother.class.php
+++ b/htdocs/core/class/html.formother.class.php
@@ -97,7 +97,7 @@ class FormOther
if ($obj->fk_user == 0) {
$label .= ' ('.$langs->trans("Everybody").') ';
}
- elseif (! empty($conf->global->EXPORTS_SHARE_MODELS) && empty($fk_user) && is_object($user) && $user->id != $obj->fk_user) {
+ elseif (!empty($conf->global->EXPORTS_SHARE_MODELS) && empty($fk_user) && is_object($user) && $user->id != $obj->fk_user) {
$tmpuser = new User($this->db);
$tmpuser->fetch($obj->fk_user);
$label .= ' ('.$tmpuser->getFullName($langs).') ';
@@ -164,7 +164,7 @@ class FormOther
if ($obj->fk_user == 0) {
$label .= ' ('.$langs->trans("Everybody").') ';
}
- elseif (! empty($conf->global->EXPORTS_SHARE_MODELS) && empty($fk_user) && is_object($user) && $user->id != $obj->fk_user) {
+ elseif (!empty($conf->global->EXPORTS_SHARE_MODELS) && empty($fk_user) && is_object($user) && $user->id != $obj->fk_user) {
$tmpuser = new User($this->db);
$tmpuser->fetch($obj->fk_user);
$label .= ' ('.$tmpuser->getFullName($langs).') ';
@@ -432,61 +432,61 @@ class FormOther
// Enhance with select2
if ($conf->use_javascript_ajax)
{
- include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
+ include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
$comboenhancement = ajax_combobox($htmlname);
if ($comboenhancement)
{
- $out.=$comboenhancement;
+ $out .= $comboenhancement;
}
}
// Select each sales and print them in a select input
- $out.='';
- if ($showempty) $out.=' ';
+ $out .= '';
+ if ($showempty) $out .= ' ';
// Get list of users allowed to be viewed
$sql_usr = "SELECT u.rowid, u.lastname, u.firstname, u.statut, u.login";
- $sql_usr.= " FROM ".MAIN_DB_PREFIX."user as u";
+ $sql_usr .= " FROM ".MAIN_DB_PREFIX."user as u";
- if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
+ if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
{
- if (! empty($user->admin) && empty($user->entity) && $conf->entity == 1) {
- $sql_usr.= " WHERE u.entity IS NOT NULL"; // Show all users
+ if (!empty($user->admin) && empty($user->entity) && $conf->entity == 1) {
+ $sql_usr .= " WHERE u.entity IS NOT NULL"; // Show all users
} else {
- $sql_usr.= " WHERE EXISTS (SELECT ug.fk_user FROM ".MAIN_DB_PREFIX."usergroup_user as ug WHERE u.rowid = ug.fk_user AND ug.entity IN (".getEntity('usergroup')."))";
- $sql_usr.= " OR u.entity = 0"; // Show always superadmin
+ $sql_usr .= " WHERE EXISTS (SELECT ug.fk_user FROM ".MAIN_DB_PREFIX."usergroup_user as ug WHERE u.rowid = ug.fk_user AND ug.entity IN (".getEntity('usergroup')."))";
+ $sql_usr .= " OR u.entity = 0"; // Show always superadmin
}
}
else
{
- $sql_usr.= " WHERE u.entity IN (".getEntity('user').")";
+ $sql_usr .= " WHERE u.entity IN (".getEntity('user').")";
}
- if (empty($user->rights->user->user->lire)) $sql_usr.=" AND u.rowid = ".$user->id;
- if (! empty($user->socid)) $sql_usr.=" AND u.fk_soc = ".$user->socid;
+ if (empty($user->rights->user->user->lire)) $sql_usr .= " AND u.rowid = ".$user->id;
+ if (!empty($user->socid)) $sql_usr .= " AND u.fk_soc = ".$user->socid;
// Add existing sales representatives of thirdparty of external user
if (empty($user->rights->user->user->lire) && $user->socid)
{
- $sql_usr.=" UNION ";
- $sql_usr.= "SELECT u2.rowid, u2.lastname, u2.firstname, u2.statut, u2.login";
- $sql_usr.= " FROM ".MAIN_DB_PREFIX."user as u2, ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ $sql_usr .= " UNION ";
+ $sql_usr .= "SELECT u2.rowid, u2.lastname, u2.firstname, u2.statut, u2.login";
+ $sql_usr .= " FROM ".MAIN_DB_PREFIX."user as u2, ".MAIN_DB_PREFIX."societe_commerciaux as sc";
- if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
+ if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
{
- if (! empty($user->admin) && empty($user->entity) && $conf->entity == 1) {
- $sql_usr.= " WHERE u2.entity IS NOT NULL"; // Show all users
+ if (!empty($user->admin) && empty($user->entity) && $conf->entity == 1) {
+ $sql_usr .= " WHERE u2.entity IS NOT NULL"; // Show all users
} else {
- $sql_usr.= " WHERE EXISTS (SELECT ug2.fk_user FROM ".MAIN_DB_PREFIX."usergroup_user as ug2 WHERE u2.rowid = ug2.fk_user AND ug2.entity IN (".getEntity('usergroup')."))";
+ $sql_usr .= " WHERE EXISTS (SELECT ug2.fk_user FROM ".MAIN_DB_PREFIX."usergroup_user as ug2 WHERE u2.rowid = ug2.fk_user AND ug2.entity IN (".getEntity('usergroup')."))";
}
}
else
{
- $sql_usr.= " WHERE u2.entity IN (".getEntity('user').")";
+ $sql_usr .= " WHERE u2.entity IN (".getEntity('user').")";
}
- $sql_usr.= " AND u2.rowid = sc.fk_user AND sc.fk_soc=".$user->socid;
+ $sql_usr .= " AND u2.rowid = sc.fk_user AND sc.fk_soc=".$user->socid;
}
- $sql_usr.= " ORDER BY statut DESC, lastname ASC"; // Do not use 'ORDER BY u.statut' here, not compatible with the UNION.
+ $sql_usr .= " ORDER BY statut DESC, lastname ASC"; // Do not use 'ORDER BY u.statut' here, not compatible with the UNION.
//print $sql_usr;exit;
$resql_usr = $this->db->query($sql_usr);
@@ -494,34 +494,34 @@ class FormOther
{
while ($obj_usr = $this->db->fetch_object($resql_usr))
{
- $out.='rowid.'"';
- if ($obj_usr->rowid == $selected) $out.=' selected';
+ if ($obj_usr->rowid == $selected) $out .= ' selected';
- $out.='>';
- $out.=dolGetFirstLastname($obj_usr->firstname, $obj_usr->lastname);
+ $out .= '>';
+ $out .= dolGetFirstLastname($obj_usr->firstname, $obj_usr->lastname);
// Complete name with more info
- $moreinfo=0;
- if (! empty($conf->global->MAIN_SHOW_LOGIN))
+ $moreinfo = 0;
+ if (!empty($conf->global->MAIN_SHOW_LOGIN))
{
- $out.=($moreinfo?' - ':' (').$obj_usr->login;
+ $out .= ($moreinfo ? ' - ' : ' (').$obj_usr->login;
$moreinfo++;
}
if ($showstatus >= 0)
{
if ($obj_usr->statut == 1 && $showstatus == 1)
{
- $out.=($moreinfo?' - ':' (').$langs->trans('Enabled');
+ $out .= ($moreinfo ? ' - ' : ' (').$langs->trans('Enabled');
$moreinfo++;
}
if ($obj_usr->statut == 0)
{
- $out.=($moreinfo?' - ':' (').$langs->trans('Disabled');
+ $out .= ($moreinfo ? ' - ' : ' (').$langs->trans('Disabled');
$moreinfo++;
}
}
- $out.=($moreinfo?')':'');
- $out.=' ';
+ $out .= ($moreinfo ? ')' : '');
+ $out .= '';
}
$this->db->free($resql_usr);
}
@@ -533,10 +533,10 @@ class FormOther
if ($norepresentative)
{
$langs->load("companies");
- $out.='- '.$langs->trans("NoSalesRepresentativeAffected").' - ';
+ $out .= '- '.$langs->trans("NoSalesRepresentativeAffected").' - ';
}
- $out.=' ';
+ $out .= ' ';
return $out;
}
@@ -742,7 +742,7 @@ class FormOther
if (!is_array($arrayofcolors) || count($arrayofcolors) < 1)
{
$langs->load("other");
- if (empty($conf->dol_use_jmobile))
+ if (empty($conf->dol_use_jmobile) && !empty($conf->use_javascript_ajax))
{
$out .= ' ';
$out .= '';
@@ -788,7 +788,7 @@ class FormOther
}
else // In most cases, this is not used. We used instead function with no specific list of colors
{
- if (empty($conf->dol_use_jmobile))
+ if (empty($conf->dol_use_jmobile) && !empty($conf->use_javascript_ajax))
{
$out .= ' ';
$out .= '';
@@ -1331,11 +1331,129 @@ class FormOther
}
else
{
- $selected=(($useempty && $value != '0' && $value != 'manual')?'':' selected');
+ $selected = (($useempty && $value != '0' && $value != 'manual') ? '' : ' selected');
$resultautomanual .= ''.$langs->trans("Automatic").' '."\n";
$resultautomanual .= ''.$langs->trans("Manual").' '."\n";
}
$resultautomanual .= ' '."\n";
return $resultautomanual;
}
+
+
+ /**
+ * Return HTML select list to select a group by field
+ *
+ * @param mixed $object Object analyzed
+ * @param array $search_groupby Array of preselected fields
+ * @param array $arrayofgroupby Array of groupby to fill
+ * @return string HTML string component
+ */
+ public function selectGroupByField($object, $search_groupby, &$arrayofgroupby)
+ {
+ global $langs, $extrafields, $form;
+
+ $YYYY = substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1);
+ $MM = substr($langs->trans("Month"), 0, 1).substr($langs->trans("Month"), 0, 1);
+ $DD = substr($langs->trans("Day"), 0, 1).substr($langs->trans("Day"), 0, 1);
+ $HH = substr($langs->trans("Hour"), 0, 1).substr($langs->trans("Hour"), 0, 1);
+ $MI = substr($langs->trans("Minute"), 0, 1).substr($langs->trans("Minute"), 0, 1);
+ $SS = substr($langs->trans("Second"), 0, 1).substr($langs->trans("Second"), 0, 1);
+
+ foreach ($object->fields as $key => $val) {
+ if (!$val['measure']) {
+ if (in_array($key, array(
+ 'id', 'ref_int', 'ref_ext', 'rowid', 'entity', 'last_main_doc', 'logo', 'logo_squarred', 'extraparams',
+ 'parent', 'photo', 'socialnetworks', 'webservices_url', 'webservices_key'))) continue;
+ if (isset($val['enabled']) && !dol_eval($val['enabled'], 1)) continue;
+ if (isset($val['visible']) && !dol_eval($val['visible'], 1)) continue;
+ if (preg_match('/^fk_/', $key) && !preg_match('/^fk_statu/', $key)) continue;
+ if (preg_match('/^pass/', $key)) continue;
+ if (in_array($val['type'], array('html', 'text'))) continue;
+ if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) {
+ $arrayofgroupby['t.'.$key.'-year'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.')', 'position' => $val['position'].'-y');
+ $arrayofgroupby['t.'.$key.'-month'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')', 'position' => $val['position'].'-m');
+ $arrayofgroupby['t.'.$key.'-day'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')', 'position' => $val['position'].'-d');
+ } else {
+ $arrayofgroupby['t.'.$key] = array('label' => $langs->trans($val['label']), 'position' => (int) $val['position']);
+ }
+ }
+ }
+ // Add extrafields to Group by
+ if ($object->isextrafieldmanaged) {
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
+ if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') continue;
+ if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key])) continue;
+ $arrayofgroupby['te.'.$key] = array('label' => $langs->trans($extrafields->attributes[$object->table_element]['label'][$key]), 'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key]);
+ }
+ }
+
+ $arrayofgroupby = dol_sort_array($arrayofgroupby, 'position', 'asc', 0, 0, 1);
+ $arrayofgroupbylabel = array();
+ foreach ($arrayofgroupby as $key => $val) {
+ $arrayofgroupbylabel[$key] = $val['label'];
+ }
+ $result = $form->selectarray('search_groupby', $arrayofgroupbylabel, $search_groupby, 1, 0, 0, '', 0, 0, 0, '', 'minwidth250', 1);
+
+ return $result;
+ }
+
+ /**
+ * Return HTML select list to select a group by field
+ *
+ * @param mixed $object Object analyzed
+ * @param array $search_xaxis Array of preselected fields
+ * @param array $arrayofxaxis Array of groupby to fill
+ * @return string HTML string component
+ */
+ public function selectXAxisField($object, $search_xaxis, &$arrayofxaxis)
+ {
+ global $langs, $extrafields, $form;
+
+ $YYYY = substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1);
+ $MM = substr($langs->trans("Month"), 0, 1).substr($langs->trans("Month"), 0, 1);
+ $DD = substr($langs->trans("Day"), 0, 1).substr($langs->trans("Day"), 0, 1);
+ $HH = substr($langs->trans("Hour"), 0, 1).substr($langs->trans("Hour"), 0, 1);
+ $MI = substr($langs->trans("Minute"), 0, 1).substr($langs->trans("Minute"), 0, 1);
+ $SS = substr($langs->trans("Second"), 0, 1).substr($langs->trans("Second"), 0, 1);
+
+
+ foreach ($object->fields as $key => $val) {
+ if (!$val['measure']) {
+ if (in_array($key, array(
+ 'id', 'ref_int', 'ref_ext', 'rowid', 'entity', 'last_main_doc', 'logo', 'logo_squarred', 'extraparams',
+ 'parent', 'photo', 'socialnetworks', 'webservices_url', 'webservices_key'))) continue;
+ if (isset($val['enabled']) && !dol_eval($val['enabled'], 1)) continue;
+ if (isset($val['visible']) && !dol_eval($val['visible'], 1)) continue;
+ if (preg_match('/^fk_/', $key) && !preg_match('/^fk_statu/', $key)) continue;
+ if (preg_match('/^pass/', $key)) continue;
+ if (in_array($val['type'], array('html', 'text'))) continue;
+ if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) {
+ $arrayofxaxis['t.'.$key.'-year'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.')', 'position' => $val['position'].'-y');
+ $arrayofxaxis['t.'.$key.'-month'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')', 'position' => $val['position'].'-m');
+ $arrayofxaxis['t.'.$key.'-day'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')', 'position' => $val['position'].'-d');
+ } else {
+ $arrayofxaxis['t.'.$key] = array('label' => $langs->trans($val['label']), 'position' => (int) $val['position']);
+ }
+ }
+ }
+
+ // Add extrafields to X-Axis
+ if ($object->isextrafieldmanaged) {
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
+ if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') continue;
+ if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key])) continue;
+ $arrayofxaxis['te.'.$key] = array('label' => $langs->trans($extrafields->attributes[$object->table_element]['label'][$key]), 'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key]);
+ }
+ }
+
+ $arrayofxaxis = dol_sort_array($arrayofxaxis, 'position', 'asc', 0, 0, 1);
+
+ $arrayofxaxislabel = array();
+ foreach ($arrayofxaxis as $key => $val) {
+ $arrayofxaxislabel[$key] = $val['label'];
+ }
+ $result = $form->selectarray('search_xaxis', $arrayofxaxislabel, $search_xaxis, 1, 0, 0, '', 0, 0, 0, '', 'minwidth250', 1);
+
+ return $result;
+ }
}
diff --git a/htdocs/core/class/html.formsms.class.php b/htdocs/core/class/html.formsms.class.php
index fc30f0798b3..d16ec9efc94 100644
--- a/htdocs/core/class/html.formsms.class.php
+++ b/htdocs/core/class/html.formsms.class.php
@@ -53,6 +53,11 @@ class FormSms
public $withtopic;
public $withbody;
+ /**
+ * @var int Id of company
+ */
+ public $withtosocid;
+
public $withfromreadonly;
public $withreplytoreadonly;
public $withtoreadonly;
diff --git a/htdocs/core/class/html.formwebsite.class.php b/htdocs/core/class/html.formwebsite.class.php
index 6cd88175a67..7b067fa11d6 100644
--- a/htdocs/core/class/html.formwebsite.class.php
+++ b/htdocs/core/class/html.formwebsite.class.php
@@ -269,7 +269,15 @@ class FormWebsite
$valueforoption = '['.$valpage->type_container.' '.sprintf("%03d", $valpage->id).'] ';
$valueforoption .= $valpage->pageurl.' - '.$valpage->title;
- if ($website->fk_default_home && $key == $website->fk_default_home) $valueforoption .= ' ('.$langs->trans("HomePage").') ';
+ if ($website->otherlang) { // If there is alternative lang for this web site, we show the language code
+ if ($valpage->lang) {
+ $valueforoption .= ' ('.$valpage->lang.') ';
+ }
+ }
+ if ($website->fk_default_home && $key == $website->fk_default_home) {
+ //$valueforoption .= ' ('.$langs->trans("HomePage").') ';
+ $valueforoption .= ' ';
+ }
$out .= ' 0 && $pageid == $key) $out .= ' selected'; // To preselect a value
diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php
index b22473ec483..10d34afd867 100644
--- a/htdocs/core/class/ldap.class.php
+++ b/htdocs/core/class/ldap.class.php
@@ -1397,7 +1397,8 @@ class Ldap
//Parse flags to text
$retval = array();
- while (list($flag, $val) = each($flags)) {
+ //while (list($flag, $val) = each($flags)) {
+ foreach ($flags as $flag => $val) {
if ($uacf >= $val) {
$uacf -= $val;
$retval[$val] = $flag;
diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php
index 06e2e99397f..72ff932bfa6 100644
--- a/htdocs/core/class/menubase.class.php
+++ b/htdocs/core/class/menubase.class.php
@@ -102,7 +102,7 @@ class Menubase
/**
* @var string Key for menu translation
* @deprecated
- * @see title
+ * @see $title
*/
public $titre;
diff --git a/htdocs/core/class/stats.class.php b/htdocs/core/class/stats.class.php
index c4f10c69469..26de63f10cc 100644
--- a/htdocs/core/class/stats.class.php
+++ b/htdocs/core/class/stats.class.php
@@ -30,8 +30,8 @@
abstract class Stats
{
protected $db;
- protected $lastfetchdate=array(); // Dates of cache file read by methods
- public $cachefilesuffix=''; // Suffix to add to name of cache file (to avoid file name conflicts)
+ protected $lastfetchdate = array(); // Dates of cache file read by methods
+ public $cachefilesuffix = ''; // Suffix to add to name of cache file (to avoid file name conflicts)
/**
* Return nb of elements by month for several years
@@ -46,33 +46,33 @@ abstract class Stats
*/
public function getNbByMonthWithPrevYear($endyear, $startyear, $cachedelay = 0, $format = 0, $startmonth = 1)
{
- global $conf,$user,$langs;
+ global $conf, $user, $langs;
if ($startyear > $endyear) return -1;
- $datay=array();
+ $datay = array();
// Search into cache
- if (! empty($cachedelay))
+ if (!empty($cachedelay))
{
include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
include_once DOL_DOCUMENT_ROOT.'/core/lib/json.lib.php';
}
- $newpathofdestfile=$conf->user->dir_temp.'/'.get_class($this).'_'.__FUNCTION__.'_'.(empty($this->cachefilesuffix)?'':$this->cachefilesuffix.'_').$langs->defaultlang.'_entity.'.$conf->entity.'_user'.$user->id.'.cache';
- $newmask='0644';
+ $newpathofdestfile = $conf->user->dir_temp.'/'.get_class($this).'_'.__FUNCTION__.'_'.(empty($this->cachefilesuffix) ? '' : $this->cachefilesuffix.'_').$langs->defaultlang.'_entity.'.$conf->entity.'_user'.$user->id.'.cache';
+ $newmask = '0644';
$nowgmt = dol_now();
- $foundintocache=0;
+ $foundintocache = 0;
if ($cachedelay > 0)
{
- $filedate=dol_filemtime($newpathofdestfile);
+ $filedate = dol_filemtime($newpathofdestfile);
if ($filedate >= ($nowgmt - $cachedelay))
{
- $foundintocache=1;
+ $foundintocache = 1;
- $this->lastfetchdate[get_class($this).'_'.__FUNCTION__]=$filedate;
+ $this->lastfetchdate[get_class($this).'_'.__FUNCTION__] = $filedate;
}
else
{
@@ -87,7 +87,7 @@ abstract class Stats
}
else
{
- $year=$startyear;
+ $year = $startyear;
$sm = $startmonth - 1;
if ($sm != 0) $year = $year - 1;
while ($year <= $endyear)
@@ -98,13 +98,13 @@ abstract class Stats
$data = array();
- for ($i = 0 ; $i < 12 ; $i++)
+ for ($i = 0; $i < 12; $i++)
{
- $data[$i][]=$datay[$endyear][($i+$sm)%12][0];
- $year=$startyear;
- while($year <= $endyear)
+ $data[$i][] = $datay[$endyear][($i + $sm) % 12][0];
+ $year = $startyear;
+ while ($year <= $endyear)
{
- $data[$i][]=$datay[$year - (1 - ((int) ($i+$sm)/12)) + ($sm == 0 ? 1 : 0)][($i+$sm)%12][1];
+ $data[$i][] = $datay[$year - (1 - ((int) ($i + $sm) / 12)) + ($sm == 0 ? 1 : 0)][($i + $sm) % 12][1];
$year++;
}
}
@@ -114,14 +114,14 @@ abstract class Stats
if (empty($foundintocache) && ($cachedelay > 0 || $cachedelay == -1))
{
dol_syslog(get_class($this).'::'.__FUNCTION__." save cache file ".$newpathofdestfile." onto disk.");
- if (! dol_is_dir($conf->user->dir_temp)) dol_mkdir($conf->user->dir_temp);
+ if (!dol_is_dir($conf->user->dir_temp)) dol_mkdir($conf->user->dir_temp);
$fp = fopen($newpathofdestfile, 'w');
fwrite($fp, json_encode($data));
fclose($fp);
- if (! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
+ if (!empty($conf->global->MAIN_UMASK)) $newmask = $conf->global->MAIN_UMASK;
@chmod($newpathofdestfile, octdec($newmask));
- $this->lastfetchdate[get_class($this).'_'.__FUNCTION__]=$nowgmt;
+ $this->lastfetchdate[get_class($this).'_'.__FUNCTION__] = $nowgmt;
}
// return array(array('Month',val1,val2,val3),...)
@@ -143,33 +143,33 @@ abstract class Stats
*/
public function getAmountByMonthWithPrevYear($endyear, $startyear, $cachedelay = 0, $format = 0, $startmonth = 1)
{
- global $conf,$user,$langs;
+ global $conf, $user, $langs;
if ($startyear > $endyear) return -1;
- $datay=array();
+ $datay = array();
// Search into cache
- if (! empty($cachedelay))
+ if (!empty($cachedelay))
{
include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
include_once DOL_DOCUMENT_ROOT.'/core/lib/json.lib.php';
}
- $newpathofdestfile=$conf->user->dir_temp.'/'.get_class($this).'_'.__FUNCTION__.'_'.(empty($this->cachefilesuffix)?'':$this->cachefilesuffix.'_').$langs->defaultlang.'_entity.'.$conf->entity.'_user'.$user->id.'.cache';
- $newmask='0644';
+ $newpathofdestfile = $conf->user->dir_temp.'/'.get_class($this).'_'.__FUNCTION__.'_'.(empty($this->cachefilesuffix) ? '' : $this->cachefilesuffix.'_').$langs->defaultlang.'_entity.'.$conf->entity.'_user'.$user->id.'.cache';
+ $newmask = '0644';
$nowgmt = dol_now();
- $foundintocache=0;
+ $foundintocache = 0;
if ($cachedelay > 0)
{
- $filedate=dol_filemtime($newpathofdestfile);
+ $filedate = dol_filemtime($newpathofdestfile);
if ($filedate >= ($nowgmt - $cachedelay))
{
- $foundintocache=1;
+ $foundintocache = 1;
- $this->lastfetchdate[get_class($this).'_'.__FUNCTION__]=$filedate;
+ $this->lastfetchdate[get_class($this).'_'.__FUNCTION__] = $filedate;
}
else
{
@@ -185,10 +185,10 @@ abstract class Stats
}
else
{
- $year=$startyear;
+ $year = $startyear;
$sm = $startmonth - 1;
if ($sm != 0) $year = $year - 1;
- while($year <= $endyear)
+ while ($year <= $endyear)
{
$datay[$year] = $this->getAmountByMonth($year, $format);
$year++;
@@ -196,13 +196,13 @@ abstract class Stats
$data = array();
// $data = array('xval'=>array(0=>xlabel,1=>yval1,2=>yval2...),...)
- for ($i = 0 ; $i < 12 ; $i++)
+ for ($i = 0; $i < 12; $i++)
{
- $data[$i][]=$datay[$endyear][($i+$sm)%12][0]; // set label
- $year=$startyear;
- while($year <= $endyear)
+ $data[$i][] = $datay[$endyear][($i + $sm) % 12]['label']; // set label
+ $year = $startyear;
+ while ($year <= $endyear)
{
- $data[$i][]=$datay[$year - (1 - ((int) ($i+$sm)/12)) + ($sm == 0 ? 1 : 0)][($i+$sm)%12][1]; // set yval for x=i
+ $data[$i][] = $datay[$year - (1 - ((int) ($i + $sm) / 12)) + ($sm == 0 ? 1 : 0)][($i + $sm) % 12][1]; // set yval for x=i
$year++;
}
}
@@ -212,17 +212,17 @@ abstract class Stats
if (empty($foundintocache) && ($cachedelay > 0 || $cachedelay == -1))
{
dol_syslog(get_class($this).'::'.__FUNCTION__." save cache file ".$newpathofdestfile." onto disk.");
- if (! dol_is_dir($conf->user->dir_temp)) dol_mkdir($conf->user->dir_temp);
+ if (!dol_is_dir($conf->user->dir_temp)) dol_mkdir($conf->user->dir_temp);
$fp = fopen($newpathofdestfile, 'w');
if ($fp)
{
fwrite($fp, json_encode($data));
fclose($fp);
- if (! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
+ if (!empty($conf->global->MAIN_UMASK)) $newmask = $conf->global->MAIN_UMASK;
@chmod($newpathofdestfile, octdec($newmask));
}
else dol_syslog("Failed to write cache file", LOG_ERR);
- $this->lastfetchdate[get_class($this).'_'.__FUNCTION__]=$nowgmt;
+ $this->lastfetchdate[get_class($this).'_'.__FUNCTION__] = $nowgmt;
}
return $data;
@@ -239,10 +239,10 @@ abstract class Stats
{
if ($startyear > $endyear) return -1;
- $datay=array();
+ $datay = array();
- $year=$startyear;
- while($year <= $endyear)
+ $year = $startyear;
+ while ($year <= $endyear)
{
$datay[$year] = $this->getAverageByMonth($year);
$year++;
@@ -250,13 +250,13 @@ abstract class Stats
$data = array();
- for ($i = 0 ; $i < 12 ; $i++)
+ for ($i = 0; $i < 12; $i++)
{
- $data[$i][]=$datay[$endyear][$i][0];
- $year=$startyear;
- while($year <= $endyear)
+ $data[$i][] = $datay[$endyear][$i][0];
+ $year = $startyear;
+ while ($year <= $endyear)
{
- $data[$i][]=$datay[$year][$i][1];
+ $data[$i][] = $datay[$year][$i][1];
$year++;
}
}
@@ -269,35 +269,36 @@ abstract class Stats
*
* @param int $year Year
* @param int $cachedelay Delay we accept for cache file (0=No read, no save of cache, -1=No read but save)
+ * @param int $limit Limit
* @return array Array of values
*/
- public function getAllByProductEntry($year, $cachedelay = 0)
+ public function getAllByProductEntry($year, $cachedelay = 0, $limit = 10)
{
- global $conf,$user,$langs;
+ global $conf, $user, $langs;
- $datay=array();
+ $data = array();
// Search into cache
- if (! empty($cachedelay))
+ if (!empty($cachedelay))
{
include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
include_once DOL_DOCUMENT_ROOT.'/core/lib/json.lib.php';
}
- $newpathofdestfile=$conf->user->dir_temp.'/'.get_class($this).'_'.__FUNCTION__.'_'.(empty($this->cachefilesuffix)?'':$this->cachefilesuffix.'_').$langs->defaultlang.'_entity.'.$conf->entity.'_user'.$user->id.'.cache';
- $newmask='0644';
+ $newpathofdestfile = $conf->user->dir_temp.'/'.get_class($this).'_'.__FUNCTION__.'_'.(empty($this->cachefilesuffix) ? '' : $this->cachefilesuffix.'_').$langs->defaultlang.'_entity.'.$conf->entity.'_user'.$user->id.'.cache';
+ $newmask = '0644';
$nowgmt = dol_now();
- $foundintocache=0;
+ $foundintocache = 0;
if ($cachedelay > 0)
{
- $filedate=dol_filemtime($newpathofdestfile);
+ $filedate = dol_filemtime($newpathofdestfile);
if ($filedate >= ($nowgmt - $cachedelay))
{
- $foundintocache=1;
+ $foundintocache = 1;
- $this->lastfetchdate[get_class($this).'_'.__FUNCTION__]=$filedate;
+ $this->lastfetchdate[get_class($this).'_'.__FUNCTION__] = $filedate;
}
else
{
@@ -313,7 +314,7 @@ abstract class Stats
}
else
{
- $data=$this->getAllByProduct($year);
+ $data = $this->getAllByProduct($year, $limit);
// $data[$i][]=$datay[$year][$i][1]; // set yval for x=i
}
@@ -321,16 +322,16 @@ abstract class Stats
if (empty($foundintocache) && ($cachedelay > 0 || $cachedelay == -1))
{
dol_syslog(get_class($this).'::'.__FUNCTION__." save cache file ".$newpathofdestfile." onto disk.");
- if (! dol_is_dir($conf->user->dir_temp)) dol_mkdir($conf->user->dir_temp);
+ if (!dol_is_dir($conf->user->dir_temp)) dol_mkdir($conf->user->dir_temp);
$fp = fopen($newpathofdestfile, 'w');
if ($fp)
{
fwrite($fp, json_encode($data));
fclose($fp);
- if (! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
+ if (!empty($conf->global->MAIN_UMASK)) $newmask = $conf->global->MAIN_UMASK;
@chmod($newpathofdestfile, octdec($newmask));
}
- $this->lastfetchdate[get_class($this).'_'.__FUNCTION__]=$nowgmt;
+ $this->lastfetchdate[get_class($this).'_'.__FUNCTION__] = $nowgmt;
}
return $data;
@@ -353,7 +354,7 @@ abstract class Stats
$result = array();
dol_syslog(get_class($this).'::'.__FUNCTION__."", LOG_DEBUG);
- $resql=$this->db->query($sql);
+ $resql = $this->db->query($sql);
if ($resql)
{
$num = $this->db->num_rows($resql);
@@ -385,7 +386,7 @@ abstract class Stats
$result = array();
dol_syslog(get_class($this).'::'.__FUNCTION__."", LOG_DEBUG);
- $resql=$this->db->query($sql);
+ $resql = $this->db->query($sql);
if ($resql)
{
$num = $this->db->num_rows($resql);
@@ -395,16 +396,16 @@ abstract class Stats
$row = $this->db->fetch_object($resql);
$result[$i]['year'] = $row->year;
$result[$i]['nb'] = $row->nb;
- if($i>0 && $row->nb>0) $result[$i-1]['nb_diff'] = ($result[$i-1]['nb'] - $row->nb) / $row->nb * 100;
+ if ($i > 0 && $row->nb > 0) $result[$i - 1]['nb_diff'] = ($result[$i - 1]['nb'] - $row->nb) / $row->nb * 100;
$result[$i]['total'] = $row->total;
- if($i>0 && $row->total>0) $result[$i-1]['total_diff'] = ($result[$i-1]['total'] - $row->total) / $row->total * 100;
+ if ($i > 0 && $row->total > 0) $result[$i - 1]['total_diff'] = ($result[$i - 1]['total'] - $row->total) / $row->total * 100;
$result[$i]['avg'] = $row->avg;
- if($i>0 && $row->avg>0) $result[$i-1]['avg_diff'] = ($result[$i-1]['avg'] - $row->avg) / $row->avg * 100;
+ if ($i > 0 && $row->avg > 0) $result[$i - 1]['avg_diff'] = ($result[$i - 1]['avg'] - $row->avg) / $row->avg * 100;
// For some $sql only
if (isset($row->weighted))
{
$result[$i]['weighted'] = $row->weighted;
- if($i>0 && $row->weighted>0) $result[$i-1]['avg_weighted'] = ($result[$i-1]['weighted'] - $row->weighted) / $row->weighted * 100;
+ if ($i > 0 && $row->weighted > 0) $result[$i - 1]['avg_weighted'] = ($result[$i - 1]['weighted'] - $row->weighted) / $row->weighted * 100;
}
$i++;
}
@@ -431,11 +432,11 @@ abstract class Stats
// phpcs:enable
global $langs;
- $result=array();
- $res=array();
+ $result = array();
+ $res = array();
dol_syslog(get_class($this).'::'.__FUNCTION__."", LOG_DEBUG);
- $resql=$this->db->query($sql);
+ $resql = $this->db->query($sql);
if ($resql)
{
$num = $this->db->num_rows($resql);
@@ -454,22 +455,22 @@ abstract class Stats
dol_print_error($this->db);
}
- for ($i = 1 ; $i < 13 ; $i++)
+ for ($i = 1; $i < 13; $i++)
{
- $res[$i] = (isset($result[$i])?$result[$i]:0);
+ $res[$i] = (isset($result[$i]) ? $result[$i] : 0);
}
$data = array();
- for ($i = 1 ; $i < 13 ; $i++)
+ for ($i = 1; $i < 13; $i++)
{
- $month='unknown';
- if ($format == 0) $month=$langs->transnoentitiesnoconv('MonthShort'.sprintf("%02d", $i));
- elseif ($format == 1) $month=$i;
- elseif ($format == 2) $month=$langs->transnoentitiesnoconv('MonthVeryShort'.sprintf("%02d", $i));
+ $month = 'unknown';
+ if ($format == 0) $month = $langs->transnoentitiesnoconv('MonthShort'.sprintf("%02d", $i));
+ elseif ($format == 1) $month = $i;
+ elseif ($format == 2) $month = $langs->transnoentitiesnoconv('MonthVeryShort'.sprintf("%02d", $i));
//$month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b"));
//$month=dol_substr($month,0,3);
- $data[$i-1] = array($month, $res[$i]);
+ $data[$i - 1] = array($month, $res[$i]);
}
return $data;
@@ -478,7 +479,6 @@ abstract class Stats
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
/**
- * Renvoie le montant totalise par mois pour une annee donnee
* Return the amount per month for a given year
*
* @param int $year Year
@@ -491,12 +491,12 @@ abstract class Stats
// phpcs:enable
global $langs;
- $result=array();
- $res=array();
+ $result = array();
+ $res = array();
dol_syslog(get_class($this).'::'.__FUNCTION__."", LOG_DEBUG);
- $resql=$this->db->query($sql);
+ $resql = $this->db->query($sql);
if ($resql)
{
$num = $this->db->num_rows($resql);
@@ -512,22 +512,22 @@ abstract class Stats
}
else dol_print_error($this->db);
- for ($i = 1 ; $i < 13 ; $i++)
+ for ($i = 1; $i < 13; $i++)
{
- $res[$i] = (int) round((isset($result[$i])?$result[$i]:0));
+ $res[$i] = (int) round((isset($result[$i]) ? $result[$i] : 0));
}
$data = array();
- for ($i = 1 ; $i < 13 ; $i++)
+ for ($i = 1; $i < 13; $i++)
{
- $month='unknown';
- if ($format == 0) $month=$langs->transnoentitiesnoconv('MonthShort'.sprintf("%02d", $i));
- elseif ($format == 1) $month=$i;
- elseif ($format == 2) $month=$langs->transnoentitiesnoconv('MonthVeryShort'.sprintf("%02d", $i));
+ $month = 'unknown';
+ if ($format == 0) $month = $langs->transnoentitiesnoconv('MonthShort'.sprintf("%02d", $i));
+ elseif ($format == 1) $month = $i;
+ elseif ($format == 2) $month = $langs->transnoentitiesnoconv('MonthVeryShort'.sprintf("%02d", $i));
//$month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b"));
//$month=dol_substr($month,0,3);
- $data[$i-1] = array($month, $res[$i]);
+ $data[$i - 1] = array($month, $res[$i]);
}
return $data;
@@ -548,11 +548,11 @@ abstract class Stats
// phpcs:enable
global $langs;
- $result=array();
- $res=array();
+ $result = array();
+ $res = array();
dol_syslog(get_class($this).'::'.__FUNCTION__."", LOG_DEBUG);
- $resql=$this->db->query($sql);
+ $resql = $this->db->query($sql);
if ($resql)
{
$num = $this->db->num_rows($resql);
@@ -568,22 +568,22 @@ abstract class Stats
}
else dol_print_error($this->db);
- for ($i = 1 ; $i < 13 ; $i++)
+ for ($i = 1; $i < 13; $i++)
{
- $res[$i] = (isset($result[$i])?$result[$i]:0);
+ $res[$i] = (isset($result[$i]) ? $result[$i] : 0);
}
$data = array();
- for ($i = 1 ; $i < 13 ; $i++)
+ for ($i = 1; $i < 13; $i++)
{
- $month='unknown';
- if ($format == 0) $month=$langs->transnoentitiesnoconv('MonthShort'.sprintf("%02d", $i));
- elseif ($format == 1) $month=$i;
- elseif ($format == 2) $month=$langs->transnoentitiesnoconv('MonthVeryShort'.sprintf("%02d", $i));
+ $month = 'unknown';
+ if ($format == 0) $month = $langs->transnoentitiesnoconv('MonthShort'.sprintf("%02d", $i));
+ elseif ($format == 1) $month = $i;
+ elseif ($format == 2) $month = $langs->transnoentitiesnoconv('MonthVeryShort'.sprintf("%02d", $i));
//$month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b"));
//$month=dol_substr($month,0,3);
- $data[$i-1] = array($month, $res[$i]);
+ $data[$i - 1] = array($month, $res[$i]);
}
return $data;
@@ -603,23 +603,22 @@ abstract class Stats
// phpcs:enable
global $langs;
- $result=array();
- $res=array();
+ $result = array();
dol_syslog(get_class($this).'::'.__FUNCTION__."", LOG_DEBUG);
- $resql=$this->db->query($sql);
+ $resql = $this->db->query($sql);
if ($resql)
{
$num = $this->db->num_rows($resql);
- $i = 0; $other=0;
+ $i = 0; $other = 0;
while ($i < $num)
{
$row = $this->db->fetch_row($resql);
- if ($i < $limit || $num == $limit) $result[$i] = array($row[0],$row[1]); // Ref of product, nb
+ if ($i < $limit || $num == $limit) $result[$i] = array($row[0], $row[1]); // Ref of product, nb
else $other += $row[1];
$i++;
}
- if ($num > $limit) $result[$i] = array($langs->transnoentitiesnoconv("Other"),$other);
+ if ($num > $limit) $result[$i] = array($langs->transnoentitiesnoconv("Other"), $other);
$this->db->free($resql);
}
else dol_print_error($this->db);
diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php
index fb9e292ba83..2f2b44d6d79 100644
--- a/htdocs/core/class/translate.class.php
+++ b/htdocs/core/class/translate.class.php
@@ -282,7 +282,7 @@ class Translate
* and split the rest until a line feed.
* This is more efficient than fgets + explode + trim by a factor of ~2.
*/
- while ($line = fscanf($fp, "%[^= ]%*[ =]%[^\n]"))
+ while ($line = fscanf($fp, "%[^= ]%*[ =]%[^\n\r]"))
{
if (isset($line[1]))
{
@@ -764,28 +764,62 @@ class Translate
* @param string $langdir Directory to scan
* @param integer $maxlength Max length for each value in combo box (will be truncated)
* @param int $usecode 1=Show code instead of country name for language variant, 2=Show only code
+ * @param int $mainlangonly 1=Show only main languages ('fr_FR' no' fr_BE', 'es_ES' not 'es_MX', ...)
* @return array List of languages
*/
- public function get_available_languages($langdir = DOL_DOCUMENT_ROOT, $maxlength = 0, $usecode = 0)
+ public function get_available_languages($langdir = DOL_DOCUMENT_ROOT, $maxlength = 0, $usecode = 0, $mainlangonly = 0)
{
// phpcs:enable
global $conf;
+ $this->load("languages");
+
// We scan directory langs to detect available languages
$handle = opendir($langdir."/langs");
$langs_available = array();
while ($dir = trim(readdir($handle)))
{
- if (preg_match('/^[a-z]+_[A-Z]+/i', $dir))
+ $regs = array();
+ if (preg_match('/^([a-z]+)_([A-Z]+)/i', $dir, $regs))
{
- $this->load("languages");
-
+ // We must keep only main languages
+ if ($mainlangonly) {
+ $arrayofspecialmainlanguages = array(
+ 'en'=>'en_US',
+ 'sq'=>'sq_AL',
+ 'ar'=>'ar_SA',
+ 'eu'=>'eu_ES',
+ 'bn'=>'bn_DB',
+ 'bs'=>'bs_BA',
+ 'ca'=>'ca_ES',
+ 'zh'=>'zh_TW',
+ 'cs'=>'cs_CZ',
+ 'da'=>'da_DK',
+ 'et'=>'et_EE',
+ 'ka'=>'ka_GE',
+ 'el'=>'el_GR',
+ 'he'=>'he_IL',
+ 'kn'=>'kn_IN',
+ 'km'=>'km_KH',
+ 'ko'=>'ko_KR',
+ 'lo'=>'lo_LA',
+ 'nb'=>'nb_NO',
+ 'fa'=>'fa_IR',
+ 'sr'=>'sr_RS',
+ 'sl'=>'sl_SI',
+ 'uk'=>'uk_UA',
+ 'vi'=>'vi_VN'
+ );
+ if (strtolower($regs[1]) != strtolower($regs[2]) && ! in_array($dir, $arrayofspecialmainlanguages)) continue;
+ }
+ // We must keep only languages into MAIN_LANGUAGES_ALLOWED
if (!empty($conf->global->MAIN_LANGUAGES_ALLOWED) && !in_array($dir, explode(',', $conf->global->MAIN_LANGUAGES_ALLOWED))) continue;
if ($usecode == 2)
{
$langs_available[$dir] = $dir;
}
+
if ($usecode == 1 || !empty($conf->global->MAIN_SHOW_LANGUAGE_CODE))
{
$langs_available[$dir] = $dir.': '.dol_trunc($this->trans('Language_'.$dir), $maxlength);
@@ -794,6 +828,9 @@ class Translate
{
$langs_available[$dir] = $this->trans('Language_'.$dir);
}
+ if ($mainlangonly) {
+ $langs_available[$dir] = str_replace(' (United States)', '', $langs_available[$dir]);
+ }
}
}
return $langs_available;
diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php
index 7904d27d17a..6dc243d3723 100644
--- a/htdocs/core/class/utils.class.php
+++ b/htdocs/core/class/utils.class.php
@@ -305,12 +305,12 @@ class Utils
if ($compression == 'gz') $handle = gzopen($outputfile, 'w');
if ($compression == 'bz') $handle = bzopen($outputfile, 'w');
+ $ok = 0;
if ($handle)
{
if (!empty($conf->global->MAIN_EXEC_USE_POPEN)) $execmethod = $conf->global->MAIN_EXEC_USE_POPEN;
if (empty($execmethod)) $execmethod = 1;
- $ok = 0;
dol_syslog("Utils::dumpDatabase execmethod=".$execmethod." command:".$fullcommandcrypted, LOG_DEBUG);
// TODO Replace with executeCLI function
@@ -388,7 +388,9 @@ class Utils
if ($compression == 'none') fclose($handle);
if ($compression == 'gz') gzclose($handle);
if ($compression == 'bz') bzclose($handle);
- if ($ok && preg_match('/^-- MySql/i', $errormsg)) $errormsg = ''; // Pas erreur
+ if ($ok && preg_match('/^-- (MySql|MariaDB)/i', $errormsg)) { // No error
+ $errormsg = '';
+ }
else
{
// Renommer fichier sortie en fichier erreur
diff --git a/htdocs/core/customreports.php b/htdocs/core/customreports.php
index 31db8fe5447..9a93f886ef4 100644
--- a/htdocs/core/customreports.php
+++ b/htdocs/core/customreports.php
@@ -13,6 +13,10 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
+ *
+ * This tool can be included into a list page with
+ * define('USE_CUSTOME_REPORT_AS_INCLUDE', 1);
+ * include DOL_DOCUMENT_ROOT.'/core/customreports.php';
*/
/**
@@ -21,50 +25,57 @@
* \brief Page to make custom reports
*/
-require '../main.inc.php';
+if (!defined('USE_CUSTOME_REPORT_AS_INCLUDE'))
+{
+ require '../main.inc.php';
+
+ // Get parameters
+ $action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
+ $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
+
+ $mode = GETPOST('mode', 'alpha') ? GETPOST('mode', 'alpha') : 'graph';
+ $objecttype = GETPOST('objecttype', 'aZ09');
+ $tabfamily = GETPOST('tabfamily', 'aZ09');
+
+ if (empty($objecttype)) $objecttype = 'thirdparty';
+
+ $search_filters = GETPOST('search_filters', 'array');
+ $search_measures = GETPOST('search_measures', 'array');
+
+ //$search_xaxis = GETPOST('search_xaxis', 'array');
+ if (GETPOST('search_xaxis', 'alpha') && GETPOST('search_xaxis', 'alpha') != '-1') $search_xaxis = array(GETPOST('search_xaxis', 'alpha'));
+ else $search_xaxis = array();
+ //$search_groupby = GETPOST('search_groupby', 'array');
+ if (GETPOST('search_groupby', 'alpha') && GETPOST('search_groupby', 'alpha') != '-1') $search_groupby = array(GETPOST('search_groupby', 'alpha'));
+ else $search_groupby = array();
+
+ $search_yaxis = GETPOST('search_yaxis', 'array');
+ $search_graph = GETPOST('search_graph', 'none');
+
+ // Load variable for pagination
+ $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
+ $sortfield = GETPOST('sortfield', 'alpha');
+ $sortorder = GETPOST('sortorder', 'alpha');
+ $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
+ if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
+ $offset = $limit * $page;
+ $pageprev = $page - 1;
+ $pagenext = $page + 1;
+
+ $diroutputmassaction = $conf->user->dir_temp.'/'.$user->id.'/customreport';
+}
+
require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
require_once DOL_DOCUMENT_ROOT."/core/lib/company.lib.php";
require_once DOL_DOCUMENT_ROOT."/core/class/dolgraph.class.php";
require_once DOL_DOCUMENT_ROOT."/core/class/doleditor.class.php";
+require_once DOL_DOCUMENT_ROOT."/core/class/html.formother.class.php";
// Load traductions files requiredby by page
-$langs->loadLangs(array("companies", "bills", "other", "exports"));
-
-// Get parameters
-$action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
-$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
-
-$mode = GETPOST('mode', 'alpha') ? GETPOST('mode', 'alpha') : 'graph';
-$objecttype = GETPOST('objecttype', 'aZ09');
-$tabfamily = GETPOST('tabfamily', 'aZ09');
-
-if (empty($objecttype)) $objecttype = 'thirdparty';
-
-$search_filters = GETPOST('search_filters', 'array');
-$search_measures = GETPOST('search_measures', 'array');
-$search_xaxis = GETPOST('search_xaxis', 'array');
-$search_yaxis = GETPOST('search_yaxis', 'array');
-$search_graph = GETPOST('search_graph', 'none');
-
-// Load variable for pagination
-$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
-$sortfield = GETPOST('sortfield', 'alpha');
-$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
-if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
-$offset = $limit * $page;
-$pageprev = $page - 1;
-$pagenext = $page + 1;
-
-// Protection if external user
-if ($user->societe_id > 0)
-{
- //accessforbidden();
-}
+$langs->loadLangs(array("companies", "other", "exports", "sendings"));
$extrafields = new ExtraFields($db);
-$diroutputmassaction = $conf->user->dir_temp.'/'.$user->id.'/customreport';
$hookmanager->initHooks(array('customreport')); // Note that conf->hooks_modules contains array
$title = '';
@@ -74,34 +85,36 @@ $object = null;
$ObjectClassName = '';
// Objects available by default
$arrayoftype = array(
- 'thirdparty' => array('label' => 'ThirdParties', 'ObjectClassName' => 'Societe', 'enabled' => $conf->societe->enabled, 'ClassPath' => DOL_DOCUMENT_ROOT."/societe/class/societe.class.php"),
- 'contact' => array('label' => 'Contacts', 'ObjectClassName' => 'Contact', 'enabled' => $conf->societe->enabled, 'ClassPath' => DOL_DOCUMENT_ROOT."/contact/class/contact.class.php"),
- 'contract' => array('label' => 'Contracts', 'ObjectClassName' => 'Contrat', 'enabled' => $conf->contrat->enabled, 'ClassPath' => DOL_DOCUMENT_ROOT."/contrat/class/contrat.class.php", 'langs'=>'contract'),
- 'invoice' => array('label' => 'Invoices', 'ObjectClassName' => 'Facture', 'enabled' => $conf->facture->enabled, 'ClassPath' => DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php"),
- 'invoice_template'=>array('label' => 'PredefinedInvoices', 'ObjectClassName' => 'FactureRec', 'enabled' => $conf->facture->enabled, 'ClassPath' => DOL_DOCUMENT_ROOT."/compta/class/facturerec.class.php"),
+ 'thirdparty' => array('label' => 'ThirdParties', 'ObjectClassName' => 'Societe', 'enabled' => $conf->societe->enabled, 'ClassPath' => "/societe/class/societe.class.php"),
+ 'contact' => array('label' => 'Contacts', 'ObjectClassName' => 'Contact', 'enabled' => $conf->societe->enabled, 'ClassPath' => "/contact/class/contact.class.php"),
+ 'proposal' => array('label' => 'Proposals', 'ObjectClassName' => 'Propal', 'enabled' => $conf->propal->enabled, 'ClassPath' => "/comm/propal/class/propal.class.php"),
+ 'order' => array('label' => 'Orders', 'ObjectClassName' => 'Commande', 'enabled' => $conf->commande->enabled, 'ClassPath' => "/commande/class/commande.class.php"),
+ 'invoice' => array('label' => 'Invoices', 'ObjectClassName' => 'Facture', 'enabled' => $conf->facture->enabled, 'ClassPath' => "/compta/facture/class/facture.class.php"),
+ 'invoice_template'=>array('label' => 'PredefinedInvoices', 'ObjectClassName' => 'FactureRec', 'enabled' => $conf->facture->enabled, 'ClassPath' => "/compta/class/facturerec.class.php", 'langs'=>'bills'),
+ 'contract' => array('label' => 'Contracts', 'ObjectClassName' => 'Contrat', 'enabled' => $conf->contrat->enabled, 'ClassPath' => "/contrat/class/contrat.class.php", 'langs'=>'contract'),
'bom' => array('label' => 'BOM', 'ObjectClassName' => 'Bom', 'enabled' => $conf->bom->enabled),
- 'mo' => array('label' => 'MO', 'ObjectClassName' => 'Mo', 'enabled' => $conf->mo->enabled, 'ClassPath' => DOL_DOCUMENT_ROOT."/mrp/class/mo.class.php"),
+ 'mo' => array('label' => 'MO', 'ObjectClassName' => 'Mo', 'enabled' => $conf->mrp->enabled, 'ClassPath' => "/mrp/class/mo.class.php"),
'ticket' => array('label' => 'Ticket', 'ObjectClassName' => 'Ticket', 'enabled' => $conf->ticket->enabled),
- 'member' => array('label' => 'Adherent', 'ObjectClassName' => 'Adherent', 'enabled' => $conf->adherent->enabled, 'ClassPath' => DOL_DOCUMENT_ROOT."/adherents/class/adherent.class.php", 'langs'=>'members'),
- 'cotisation' => array('label' => 'Subscriptions', 'ObjectClassName' => 'Subscription', 'enabled' => $conf->adherent->enabled, 'ClassPath' => DOL_DOCUMENT_ROOT."/adherents/class/subscription.class.php", 'langs'=>'members'),
+ 'member' => array('label' => 'Adherent', 'ObjectClassName' => 'Adherent', 'enabled' => $conf->adherent->enabled, 'ClassPath' => "/adherents/class/adherent.class.php", 'langs'=>'members'),
+ 'cotisation' => array('label' => 'Subscriptions', 'ObjectClassName' => 'Subscription', 'enabled' => $conf->adherent->enabled, 'ClassPath' => "/adherents/class/subscription.class.php", 'langs'=>'members'),
);
-// Complete $arrayoftype
+// Complete $arrayoftype by external modules
$parameters = array('objecttype'=>$objecttype, 'tabfamily'=>$tabfamily);
$reshook = $hookmanager->executeHooks('loadDataForCustomReports', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
elseif (is_array($hookmanager->resArray)) {
- if (! empty($hookmanager->resArray['title'])) { // Add entries for tabs
+ if (!empty($hookmanager->resArray['title'])) { // Add entries for tabs
$title = $hookmanager->resArray['title'];
}
- if (! empty($hookmanager->resArray['picto'])) { // Add entries for tabs
+ if (!empty($hookmanager->resArray['picto'])) { // Add entries for tabs
$picto = $hookmanager->resArray['picto'];
}
- if (! empty($hookmanager->resArray['head'])) { // Add entries for tabs
+ if (!empty($hookmanager->resArray['head'])) { // Add entries for tabs
$head = array_merge($head, $hookmanager->resArray['head']);
}
- if (! empty($hookmanager->resArray['arrayoftype'])) { // Add entries from hook
- foreach($hookmanager->resArray['arrayoftype'] as $key => $val) {
+ if (!empty($hookmanager->resArray['arrayoftype'])) { // Add entries from hook
+ foreach ($hookmanager->resArray['arrayoftype'] as $key => $val) {
$arrayoftype[$key] = $val;
}
}
@@ -109,18 +122,15 @@ elseif (is_array($hookmanager->resArray)) {
if ($objecttype) {
try {
- if ($arrayoftype[$objecttype]['langs']) {
- $langs->load($arrayoftype[$objecttype]['langs']);
- }
- if ($arrayoftype[$objecttype]['ClassPath']) {
- include_once $arrayoftype[$objecttype]['ClassPath'];
+ if (!empty($arrayoftype[$objecttype]['ClassPath'])) {
+ dol_include_once($arrayoftype[$objecttype]['ClassPath']);
} else {
- include_once DOL_DOCUMENT_ROOT."/".$objecttype."/class/".$objecttype.".class.php";
+ dol_include_once("/".$objecttype."/class/".$objecttype.".class.php");
}
$ObjectClassName = $arrayoftype[$objecttype]['ObjectClassName'];
$object = new $ObjectClassName($db);
}
- catch(Exception $e) {
+ catch (Exception $e) {
print 'Failed to load class for type '.$objecttype;
}
}
@@ -132,6 +142,7 @@ if ($user->socid > 0) // Protection if external user
//$socid = $user->socid;
accessforbidden();
}
+
$result = restrictedArea($user, $object->element, 0, '');
// Fetch optionals attributes and labels
@@ -140,7 +151,24 @@ $extrafields->fetch_name_optionals_label($object->table_element);
$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
-$search_component_params=array('');
+$search_component_params = array('');
+
+$MAXUNIQUEVALFORGROUP = 20;
+$MAXMEASURESINBARGRAPH = 20;
+
+$YYYY = substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1).substr($langs->trans("Year"), 0, 1);
+$MM = substr($langs->trans("Month"), 0, 1).substr($langs->trans("Month"), 0, 1);
+$DD = substr($langs->trans("Day"), 0, 1).substr($langs->trans("Day"), 0, 1);
+$HH = substr($langs->trans("Hour"), 0, 1).substr($langs->trans("Hour"), 0, 1);
+$MI = substr($langs->trans("Minute"), 0, 1).substr($langs->trans("Minute"), 0, 1);
+$SS = substr($langs->trans("Second"), 0, 1).substr($langs->trans("Second"), 0, 1);
+
+$arrayofmesures = array('t.count'=>'Count');
+$arrayofxaxis = array();
+$arrayofgroupby = array();
+$arrayofyaxis = array();
+$arrayofvaluesforgroupby = array();
+
/*
@@ -155,39 +183,119 @@ $search_component_params=array('');
* View
*/
-$form=new Form($db);
+$form = new Form($db);
+$formother = new FormOther($db);
-llxHeader('', $langs->transnoentitiesnoconv('CustomReports'), '');
+if (!defined('USE_CUSTOME_REPORT_AS_INCLUDE')) {
+ llxHeader('', $langs->transnoentitiesnoconv('CustomReports'), '');
+
+ dol_fiche_head($head, 'customreports', $title, -1, $picto);
+}
// Check parameters
-if ($mode == 'graph' && $search_graph == 'bars' && count($search_measures) > 3) {
- setEventMessages($langs->trans("GraphInBarsAreLimitedTo3Measures"), null, 'warnings');
- $search_graph = 'lines';
-}
-if ($mode == 'graph' && count($search_xaxis) > 1) {
- setEventMessages($langs->trans("OnlyOneFieldForXAxisIsPossible"), null, 'warnings');
- $search_xaxis = array(0 => $search_xaxis[0]);
+if ($action == 'viewgraph') {
+ if (!count($search_measures)) {
+ setEventMessages($langs->trans("AtLeastOneMeasureIsRequired"), null, 'warnings');
+ } elseif ($mode == 'graph' && count($search_xaxis) > 1) {
+ setEventMessages($langs->trans("OnlyOneFieldForXAxisIsPossible"), null, 'warnings');
+ $search_xaxis = array(0 => $search_xaxis[0]);
+ }
+ if (count($search_groupby) >= 2) {
+ setEventMessages($langs->trans("ErrorOnlyOneFieldForGroupByIsPossible"), null, 'warnings');
+ $search_groupby = array(0 => $search_groupby[0]);
+ }
+ if (!count($search_xaxis)) {
+ setEventMessages($langs->trans("AtLeastOneXAxisIsRequired"), null, 'warnings');
+ } elseif ($mode == 'graph' && $search_graph == 'bars' && count($search_measures) > $MAXMEASURESINBARGRAPH) {
+ $langs->load("errors");
+ setEventMessages($langs->trans("GraphInBarsAreLimitedToNMeasures", $MAXMEASURESINBARGRAPH), null, 'warnings');
+ $search_graph = 'lines';
+ }
}
+// Get all possible values of fields when a 'group by' is set, and save this into $arrayofvaluesforgroupby
+if (is_array($search_groupby) && count($search_groupby)) {
+ foreach ($search_groupby as $gkey => $gval) {
+ $gvalwithoutprefix = preg_replace('/^[a-z]+\./', '', $gval);
-//$head = commande_prepare_head(null);
-dol_fiche_head($head, 'customreports', $title, -1, $picto);
+ if (preg_match('/\-year$/', $search_groupby[$gkey])) {
+ $tmpval = preg_replace('/\-year$/', '', $search_groupby[$gkey]);
+ $fieldtocount .= 'DATE_FORMAT('.$tmpval.", '%Y')";
+ } elseif (preg_match('/\-month$/', $search_groupby[$gkey])) {
+ $tmpval = preg_replace('/\-month$/', '', $search_groupby[$gkey]);
+ $fieldtocount .= 'DATE_FORMAT('.$tmpval.", '%Y-%m')";
+ } elseif (preg_match('/\-day$/', $search_groupby[$gkey])) {
+ $tmpval = preg_replace('/\-day$/', '', $search_groupby[$gkey]);
+ $fieldtocount .= 'DATE_FORMAT('.$tmpval.", '%Y-%m-%d')";
+ } else {
+ $fieldtocount = $search_groupby[$gkey];
+ }
+
+ $sql = 'SELECT DISTINCT '.$fieldtocount.' as val';
+ if (strpos($fieldtocount, 'te.') === 0) {
+ $sql .= ' FROM '.MAIN_DB_PREFIX.$object->table_element.'_extrafields as te';
+ } else {
+ $sql .= ' FROM '.MAIN_DB_PREFIX.$object->table_element.' as t';
+ }
+ // TODO Add the where here
+
+ $sql .= ' LIMIT '.($MAXUNIQUEVALFORGROUP + 1);
+
+ //print $sql;
+ $resql = $db->query($sql);
+ if (!$resql) {
+ dol_print_error($db);
+ }
+
+ while ($obj = $db->fetch_object($resql)) {
+ if (is_null($obj->val)) {
+ $keytouse = '__NULL__';
+ $valuetranslated = $langs->transnoentitiesnoconv("NotDefined");
+ }
+ elseif ($obj->val === '') {
+ $keytouse = '';
+ $valuetranslated = $langs->transnoentitiesnoconv("Empty");
+ }
+ else {
+ $keytouse = (string) $obj->val;
+ $valuetranslated = $obj->val;
+ }
+ if (!empty($object->fields[$gvalwithoutprefix]['arrayofkeyval'])) {
+ $valuetranslated = $object->fields[$gvalwithoutprefix]['arrayofkeyval'][$obj->val];
+ if (is_null($valuetranslated)) $valuetranslated = $langs->transnoentitiesnoconv("UndefinedKey");
+ $valuetranslated = $langs->trans($valuetranslated);
+ }
+
+ $arrayofvaluesforgroupby['g_'.$gkey][$keytouse] = $valuetranslated;
+ }
+ asort($arrayofvaluesforgroupby['g_'.$gkey]);
+
+ if (count($arrayofvaluesforgroupby['g_'.$gkey]) > $MAXUNIQUEVALFORGROUP) {
+ $langs->load("errors");
+ //var_dump($gkey.' '.$gval.' '.$gvalwithoutprefix);
+ $gvalwithoutprefix = preg_replace('/\-(year|month|day)/', '', $gvalwithoutprefix);
+ $labeloffield = $langs->transnoentitiesnoconv($object->fields[$gvalwithoutprefix]['label']);
+ setEventMessages($langs->trans("ErrorTooManyDifferentValueForSelectedGroupBy", $MAXUNIQUEVALFORGROUP, $labeloffield), null, 'warnings');
+ $search_groupby = array();
+ }
+
+ $db->free($resql);
+ }
+}
+//var_dump($arrayofvaluesforgroupby);exit;
-$tmparray=dol_getdate(dol_now());
-$endyear=$tmparray['year'];
-$endmonth=$tmparray['mon'];
-$datelastday=dol_get_last_day($endyear, $endmonth, 1);
-$startyear=$endyear-2;
+$tmparray = dol_getdate(dol_now());
+$endyear = $tmparray['year'];
+$endmonth = $tmparray['mon'];
+$datelastday = dol_get_last_day($endyear, $endmonth, 1);
+$startyear = $endyear - 2;
$param = '';
-$arrayofmesures = array('t.count'=>'Count');
-$arrayofxaxis = array();
-$arrayofyaxis = array();
-
print '';
print ' ';
+print ' ';
print ' ';
print '';
@@ -195,40 +303,48 @@ print '
';
// Select object
print '
';
print '
'.$langs->trans("StatisticsOn").'
';
-print $form->selectarray('objecttype', $arrayoftype, $objecttype, 0, 0, 0, '', 1, 0, 0, '', '', 1);
+$newarrayoftype = array();
+foreach ($arrayoftype as $key => $val) {
+ if (dol_eval($val['enabled'], 1)) {
+ $newarrayoftype[$key] = $arrayoftype[$key];
+ }
+ if ($val['langs']) {
+ $langs->load($val['langs']);
+ }
+}
+print $form->selectarray('objecttype', $newarrayoftype, $objecttype, 0, 0, 0, '', 1, 0, 0, '', 'minwidth200', 1);
if (empty($conf->use_javascript_ajax)) print '
';
else {
print '';
}
print '
';
-
// Add Filter
print '
';
print $form->searchComponent(array($object->element => $object->fields), $search_component_params);
print '
';
-// Measures
+// Add measures into array
print '
';
-foreach($object->fields as $key => $val) {
- if ($val['isameasure']) {
+foreach ($object->fields as $key => $val) {
+ if (!empty($val['isameasure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1))) {
$arrayofmesures['t.'.$key.'-sum'] = $langs->trans($val['label']).'
('.$langs->trans("Sum").') ';
$arrayofmesures['t.'.$key.'-average'] = $langs->trans($val['label']).'
('.$langs->trans("Average").') ';
$arrayofmesures['t.'.$key.'-min'] = $langs->trans($val['label']).'
('.$langs->trans("Minimum").') ';
$arrayofmesures['t.'.$key.'-max'] = $langs->trans($val['label']).'
('.$langs->trans("Maximum").') ';
}
}
-// Add measure from extrafields
+// Add extrafields to Measures
if ($object->isextrafieldmanaged) {
- foreach($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
- if (! empty($extrafields->attributes[$object->table_element]['totalizable'][$key])) {
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
+ if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key]) && (!isset($extrafields->attributes[$object->table_element]['enabled'][$key]) || dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1))) {
$arrayofmesures['te.'.$key.'-sum'] = $langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).'
('.$langs->trans("Sum").') ';
$arrayofmesures['te.'.$key.'-average'] = $langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).'
('.$langs->trans("Average").') ';
$arrayofmesures['te.'.$key.'-min'] = $langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).'
('.$langs->trans("Minimum").') ';
@@ -236,76 +352,53 @@ if ($object->isextrafieldmanaged) {
}
}
}
-print '
'.$langs->trans("Measures").'
';
+print '
'.$langs->trans("Measures").'
';
print $form->multiselectarray('search_measures', $arrayofmesures, $search_measures, 0, 0, 'minwidth500', 1);
print '
';
-// XAxis
+
+// Group by
print '
';
-foreach($object->fields as $key => $val) {
- if (! $val['measure']) {
- if (in_array($key, array(
- 'id', 'ref_int', 'ref_ext', 'rowid', 'entity', 'last_main_doc', 'logo', 'logo_squarred', 'extraparams',
- 'parent', 'photo', 'socialnetworks', 'webservices_url', 'webservices_key'))) continue;
- if (isset($val['enabled']) && ! dol_eval($val['enabled'], 1)) continue;
- if (isset($val['visible']) && ! dol_eval($val['visible'], 1)) continue;
- if (preg_match('/^fk_/', $key) && ! preg_match('/^fk_statu/', $key)) continue;
- if (preg_match('/^pass/', $key)) continue;
- if (in_array($val['type'], array('html', 'text'))) continue;
- if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) {
- $arrayofxaxis['t.'.$key.'-year'] = array('label' => $langs->trans($val['label']).' ('.$langs->trans("Year").')', 'position' => $val['position']);
- $arrayofxaxis['t.'.$key.'-month'] = array('label' => $langs->trans($val['label']).' ('.$langs->trans("Month").')', 'position' => $val['position']);
- $arrayofxaxis['t.'.$key.'-day'] = array('label' => $langs->trans($val['label']).' ('.$langs->trans("Day").')', 'position' => $val['position']);
- } else {
- $arrayofxaxis['t.'.$key] = array('label' => $val['label'], 'position' => (int) $val['position']);
- }
- }
- // Add measure from extrafields
- if ($object->isextrafieldmanaged) {
- foreach($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
- if (! empty($extrafields->attributes[$object->table_element]['totalizable'][$key])) {
- $arrayofxaxis['te.'.$key] = array('label' => $extrafields->attributes[$object->table_element]['label'][$key], 'position' => (int) $extrafields->attributes[$object->table_element]['pos'][$key]);
- }
- }
- }
-}
-$arrayofxaxis = dol_sort_array($arrayofxaxis, 'position');
-$arrayofxaxislabel = array();
-foreach($arrayofxaxis as $key => $val) {
- $arrayofxaxislabel[$key] = $val['label'];
-}
-print '
'.$langs->trans("XAxis").'
';
-print $form->multiselectarray('search_xaxis', $arrayofxaxislabel, $search_xaxis, 0, 0, 'minwidth500', 1);
+print '
'.$langs->trans("GroupBy").'
';
+print $formother->selectGroupByField($object, $search_groupby, $arrayofgroupby);
print '
';
-// YAxis
+
+// XAxis
+print '
';
+print '
'.$langs->trans("XAxis").'
';
+print $formother->selectXAxisField($object, $search_xaxis, $arrayofxaxis);
+print '
';
+
+
if ($mode == 'grid') {
- print '
';
- foreach($object->fields as $key => $val) {
- if (! $val['measure']) {
+ // YAxis
+ print '
';
+ foreach ($object->fields as $key => $val) {
+ if (empty($val['measure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1))) {
if (in_array($key, array('id', 'rowid', 'entity', 'last_main_doc', 'extraparams'))) continue;
if (preg_match('/^fk_/', $key)) continue;
if (in_array($val['type'], array('html', 'text'))) continue;
if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) {
- $arrayofyaxis['t.'.$key.'-year'] = array('label' => $langs->trans($val['label']).' ('.$langs->trans("Year").')', 'position' => $val['position']);
- $arrayofyaxis['t.'.$key.'-month'] = array('label' => $langs->trans($val['label']).' ('.$langs->trans("Month").')', 'position' => $val['position']);
- $arrayofyaxis['t.'.$key.'-day'] = array('label' => $langs->trans($val['label']).' ('.$langs->trans("Day").')', 'position' => $val['position']);
+ $arrayofyaxis['t.'.$key.'-year'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.')', 'position' => $val['position']);
+ $arrayofyaxis['t.'.$key.'-month'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')', 'position' => $val['position']);
+ $arrayofyaxis['t.'.$key.'-day'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')', 'position' => $val['position']);
} else {
$arrayofyaxis['t.'.$key] = array('label' => $val['label'], 'position' => (int) $val['position']);
}
}
// Add measure from extrafields
if ($object->isextrafieldmanaged) {
- foreach($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
- if (! empty($extrafields->attributes[$object->table_element]['totalizable'][$key])) {
- $arrayofyaxis['te.'.$key] = array('label' => $extrafields->attributes[$object->table_element]['label'][$key], 'position' => (int) $extrafields->attributes[$object->table_element]['pos'][$key]);
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
+ if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key]) && (!isset($extrafields->attributes[$object->table_element]['enabled'][$key]) || dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1))) {
+ $arrayofyaxis['te.'.$key] = array('label' => $extrafields->attributes[$object->table_element]['label'][$key], 'position' => (int) $extrafields->attributes[$object->table_element]['pos'][$key]);
}
}
}
}
$arrayofyaxis = dol_sort_array($arrayofyaxis, 'position');
$arrayofyaxislabel = array();
- foreach($arrayofyaxis as $key => $val) {
+ foreach ($arrayofyaxis as $key => $val) {
$arrayofyaxislabel[$key] = $val['label'];
}
print '
'.$langs->trans("YAxis").'
';
@@ -326,15 +419,14 @@ print '
';
print '
';
print '';
-
// Generate the SQL request
$sql = '';
-if (! empty($search_measures) && ! empty($search_xaxis))
+if (!empty($search_measures) && !empty($search_xaxis))
{
$fieldid = 'rowid';
$sql = 'SELECT ';
- foreach($search_xaxis as $key => $val) {
+ foreach ($search_xaxis as $key => $val) {
if (preg_match('/\-year$/', $val)) {
$tmpval = preg_replace('/\-year$/', '', $val);
$sql .= 'DATE_FORMAT('.$tmpval.", '%Y') as x_".$key.', ';
@@ -347,14 +439,27 @@ if (! empty($search_measures) && ! empty($search_xaxis))
}
else $sql .= $val.' as x_'.$key.', ';
}
- foreach($search_measures as $key => $val) {
+ foreach ($search_groupby as $key => $val) {
+ if (preg_match('/\-year$/', $val)) {
+ $tmpval = preg_replace('/\-year$/', '', $val);
+ $sql .= 'DATE_FORMAT('.$tmpval.", '%Y') as g_".$key.', ';
+ } elseif (preg_match('/\-month$/', $val)) {
+ $tmpval = preg_replace('/\-month$/', '', $val);
+ $sql .= 'DATE_FORMAT('.$tmpval.", '%Y-%m') as g_".$key.', ';
+ } elseif (preg_match('/\-day$/', $val)) {
+ $tmpval = preg_replace('/\-day$/', '', $val);
+ $sql .= 'DATE_FORMAT('.$tmpval.", '%Y-%m-%d') as g_".$key.', ';
+ }
+ else $sql .= $val.' as g_'.$key.', ';
+ }
+ foreach ($search_measures as $key => $val) {
if ($val == 't.count') $sql .= 'COUNT(t.'.$fieldid.') as y_'.$key.', ';
elseif (preg_match('/\-sum$/', $val)) {
- $tmpval = preg_replace('/\-sum$/', '', $val);
+ $tmpval = preg_replace('/\-sum$/', '', $val);
$sql .= 'SUM('.$db->ifsql($tmpval.' IS NULL', '0', $tmpval).') as y_'.$key.', ';
}
elseif (preg_match('/\-average$/', $val)) {
- $tmpval = preg_replace('/\-average$/', '', $val);
+ $tmpval = preg_replace('/\-average$/', '', $val);
$sql .= 'AVG('.$db->ifsql($tmpval.' IS NULL', '0', $tmpval).') as y_'.$key.', ';
}
elseif (preg_match('/\-min$/', $val)) {
@@ -362,7 +467,7 @@ if (! empty($search_measures) && ! empty($search_xaxis))
$sql .= 'MIN('.$db->ifsql($tmpval.' IS NULL', '0', $tmpval).') as y_'.$key.', ';
}
elseif (preg_match('/\-max$/', $val)) {
- $tmpval = preg_replace('/\-max$/', '', $val);
+ $tmpval = preg_replace('/\-max$/', '', $val);
$sql .= 'MAX('.$db->ifsql($tmpval.' IS NULL', '0', $tmpval).') as y_'.$key.', ';
}
}
@@ -385,11 +490,11 @@ if (! empty($search_measures) && ! empty($search_xaxis))
if ($object->ismultientitymanaged == 1) {
$sql .= ' AND entity IN ('.getEntity($object->element).')';
}
- foreach($search_filters as $key => $val) {
- // TODO
+ foreach ($search_filters as $key => $val) {
+ // TODO Add the where here
}
$sql .= ' GROUP BY ';
- foreach($search_xaxis as $key => $val) {
+ foreach ($search_xaxis as $key => $val) {
if (preg_match('/\-year$/', $val)) {
$tmpval = preg_replace('/\-year$/', '', $val);
$sql .= 'DATE_FORMAT('.$tmpval.", '%Y'), ";
@@ -402,9 +507,22 @@ if (! empty($search_measures) && ! empty($search_xaxis))
}
else $sql .= $val.', ';
}
+ foreach ($search_groupby as $key => $val) {
+ if (preg_match('/\-year$/', $val)) {
+ $tmpval = preg_replace('/\-year$/', '', $val);
+ $sql .= 'DATE_FORMAT('.$tmpval.", '%Y'), ";
+ } elseif (preg_match('/\-month$/', $val)) {
+ $tmpval = preg_replace('/\-month$/', '', $val);
+ $sql .= 'DATE_FORMAT('.$tmpval.", '%Y-%m'), ";
+ } elseif (preg_match('/\-day$/', $val)) {
+ $tmpval = preg_replace('/\-day$/', '', $val);
+ $sql .= 'DATE_FORMAT('.$tmpval.", '%Y-%m-%d'), ";
+ }
+ else $sql .= $val.', ';
+ }
$sql = preg_replace('/,\s*$/', '', $sql);
$sql .= ' ORDER BY ';
- foreach($search_xaxis as $key => $val) {
+ foreach ($search_xaxis as $key => $val) {
if (preg_match('/\-year$/', $val)) {
$tmpval = preg_replace('/\-year$/', '', $val);
$sql .= 'DATE_FORMAT('.$tmpval.", '%Y'), ";
@@ -417,47 +535,149 @@ if (! empty($search_measures) && ! empty($search_xaxis))
}
else $sql .= $val.', ';
}
+ foreach ($search_groupby as $key => $val) {
+ if (preg_match('/\-year$/', $val)) {
+ $tmpval = preg_replace('/\-year$/', '', $val);
+ $sql .= 'DATE_FORMAT('.$tmpval.", '%Y'), ";
+ } elseif (preg_match('/\-month$/', $val)) {
+ $tmpval = preg_replace('/\-month$/', '', $val);
+ $sql .= 'DATE_FORMAT('.$tmpval.", '%Y-%m'), ";
+ } elseif (preg_match('/\-day$/', $val)) {
+ $tmpval = preg_replace('/\-day$/', '', $val);
+ $sql .= 'DATE_FORMAT('.$tmpval.", '%Y-%m-%d'), ";
+ }
+ else $sql .= $val.', ';
+ }
$sql = preg_replace('/,\s*$/', '', $sql);
}
+//print $sql;
-
-$legend=array();
-foreach($search_measures as $key => $val) {
+$legend = array();
+foreach ($search_measures as $key => $val) {
$legend[] = $langs->trans($arrayofmesures[$val]);
}
+$useagroupby = (is_array($search_groupby) && count($search_groupby));
+//var_dump($useagroupby);
+//var_dump($arrayofvaluesforgroupby);
+
// Execute the SQL request
$totalnbofrecord = 0;
$data = array();
if ($sql) {
$resql = $db->query($sql);
- if (! $resql) {
+ if (!$resql) {
dol_print_error($db);
}
- while($obj = $db->fetch_object($resql)) {
- // $this->data = array(array(0=>'labelxA',1=>yA1,...,n=>yAn), array('labelxB',yB1,...yBn)); // or when there is n series to show for each x
- foreach($search_xaxis as $xkey => $xval) {
- $fieldforxkey = 'x_'.$xkey;
- $xlabel = $obj->$fieldforxkey;
- $xvalwithoutprefix = preg_replace('/^[a-z]+\./', '', $xval);
- if (! empty($object->fields[$xvalwithoutprefix]['arrayofkeyval'])) {
- $xlabel = $object->fields[$xvalwithoutprefix]['arrayofkeyval'][$obj->$fieldforxkey];
- }
- $xarray = array(0 => (($xlabel || $xlabel == '0') ? dol_trunc($xlabel, 20, 'middle') : $langs->trans("NotDefined")));
- foreach($search_measures as $key => $val) {
- $fieldfory = 'y_'.$key;
- $xarray[] = $obj->$fieldfory;
- }
- $data[] = $xarray;
- }
+ $ifetch = 0; $xi = 0; $oldlabeltouse = '';
+ while ($obj = $db->fetch_object($resql)) {
+ $ifetch++;
+ if ($useagroupby) {
+ $xval = $search_xaxis[0];
+ $fieldforxkey = 'x_0';
+ $xlabel = $obj->$fieldforxkey;
+ $xvalwithoutprefix = preg_replace('/^[a-z]+\./', '', $xval);
+ if (!empty($object->fields[$xvalwithoutprefix]['arrayofkeyval'])) {
+ $xlabel = $object->fields[$xvalwithoutprefix]['arrayofkeyval'][$obj->$fieldforxkey];
+ }
+ $labeltouse = (($xlabel || $xlabel == '0') ? dol_trunc($xlabel, 20, 'middle') : ($xlabel === '' ? $langs->trans("Empty") : $langs->trans("NotDefined")));
+
+ if ($oldlabeltouse && ($labeltouse != $oldlabeltouse)) {
+ $xi++; // Increase $xi
+ }
+ //var_dump($labeltouse.' '.$oldlabeltouse.' '.$xi);
+ $oldlabeltouse = $labeltouse;
+
+ /* Example of value for $arrayofvaluesforgroupby
+ * array (size=1)
+ * 'g_0' =>
+ * array (size=6)
+ * 0 => string '0' (length=1)
+ * '' => string 'Empty' (length=5)
+ * '__NULL__' => string 'Not defined' (length=11)
+ * 'done' => string 'done' (length=4)
+ * 'processing' => string 'processing' (length=10)
+ * 'undeployed' => string 'undeployed' (length=10)
+ */
+ foreach ($search_measures as $key => $val) {
+ $gi = 0;
+ foreach ($search_groupby as $gkey) {
+ //var_dump('*** Fetch #'.$ifetch.' for labeltouse='.$labeltouse.' measure number '.$key.' and group g_'.$gi);
+ //var_dump($arrayofvaluesforgroupby);
+ foreach ($arrayofvaluesforgroupby['g_'.$gi] as $gvaluepossiblekey => $gvaluepossiblelabel) {
+ $ykeysuffix = $gvaluepossiblelabel;
+ $gvalwithoutprefix = preg_replace('/^[a-z]+\./', '', $gval);
+
+ $fieldfory = 'y_'.$key;
+ $fieldforg = 'g_'.$gi;
+ $fieldforybis = 'y_'.$key.'_'.$ykeysuffix;
+ //var_dump('gvaluepossiblekey='.$gvaluepossiblekey.' gvaluepossiblelabel='.$gvaluepossiblelabel.' ykeysuffix='.$ykeysuffix.' gval='.$gval.' gvalwithoutsuffix='.$gvalwithoutprefix);
+ //var_dump('fieldforg='.$fieldforg.' obj->$fieldforg='.$obj->$fieldforg.' fieldfory='.$fieldfory.' obj->$fieldfory='.$obj->$fieldfory.' fieldforybis='.$fieldforybis);
+
+ if (!is_array($data[$xi])) $data[$xi] = array();
+
+ if (!array_key_exists('label', $data[$xi])) {
+ $data[$xi] = array();
+ $data[$xi]['label'] = $labeltouse;
+ }
+
+ $objfieldforg = $obj->$fieldforg;
+ if (is_null($objfieldforg)) $objfieldforg = '__NULL__';
+
+ if ($gvaluepossiblekey == '0') { // $gvaluepossiblekey can have type int or string. So we create a special if, used when value is '0'
+ //var_dump($objfieldforg.' == \'0\' -> '.($objfieldforg == '0'));
+ if ($objfieldforg == '0') {
+ // The record we fetch is for this group
+ $data[$xi][$fieldforybis] = $obj->$fieldfory;
+ }
+ // The record we fetch is not for this group
+ elseif (!isset($data[$xi][$fieldforybis])) {
+ $data[$xi][$fieldforybis] = '0';
+ }
+ } else {
+ //var_dump((string) $objfieldforg.' === '.(string) $gvaluepossiblekey.' -> '.((string) $objfieldforg === (string) $gvaluepossiblekey));
+ if ((string) $objfieldforg === (string) $gvaluepossiblekey) {
+ // The record we fetch is for this group
+ $data[$xi][$fieldforybis] = $obj->$fieldfory;
+ }
+ // The record we fetch is not for this group
+ elseif (!isset($data[$xi][$fieldforybis])) {
+ $data[$xi][$fieldforybis] = '0';
+ }
+ }
+ }
+ //var_dump($data[$xi]);
+ $gi++;
+ }
+ }
+ } else { // No group by
+ $xval = $search_xaxis[0];
+ $fieldforxkey = 'x_0';
+ $xlabel = $obj->$fieldforxkey;
+ $xvalwithoutprefix = preg_replace('/^[a-z]+\./', '', $xval);
+
+ if (!empty($object->fields[$xvalwithoutprefix]['arrayofkeyval'])) {
+ $xlabel = $object->fields[$xvalwithoutprefix]['arrayofkeyval'][$obj->$fieldforxkey];
+ }
+
+ $labeltouse = (($xlabel || $xlabel == '0') ? dol_trunc($xlabel, 20, 'middle') : ($xlabel === '' ? $langs->trans("Empty") : $langs->trans("NotDefined")));
+ $xarrayforallseries = array('label' => $labeltouse);
+ foreach ($search_measures as $key => $val) {
+ $fieldfory = 'y_'.$key;
+ $xarrayforallseries[$fieldfory] = $obj->$fieldfory;
+ }
+ $data[$xi] = $xarrayforallseries;
+ $xi++;
+ }
}
$totalnbofrecord = count($data);
}
+//var_dump($data);
-print '
';
+print '
';
if ($mode == 'grid') {
@@ -471,13 +691,15 @@ if ($mode == 'graph') {
// Show graph
$px1 = new DolGraph();
$mesg = $px1->isGraphKo();
- if (! $mesg)
+ if (!$mesg)
{
+ /*var_dump($legend);
+ var_dump($data);*/
$px1->SetData($data);
unset($data);
$arrayoftypes = array();
- foreach($search_measures as $key => $val) {
+ foreach ($search_measures as $key => $val) {
$arrayoftypes[] = $search_graph;
}
@@ -491,10 +713,10 @@ if ($mode == 'graph') {
$px1->SetHorizTickIncrement(1);
$px1->SetCssPrefix("cssboxes");
$px1->SetType($arrayoftypes);
- $px1->mode='depth';
+ $px1->mode = 'depth';
$px1->SetTitle('');
- $dir=$conf->user->dir_temp;
+ $dir = $conf->user->dir_temp;
dol_mkdir($dir);
$filenamenb = $dir.'/customreport_'.$object->element.'.png';
$fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=user&file=customreport_'.$object->element.'.png';
@@ -507,13 +729,14 @@ if ($mode == 'graph') {
if ($sql) {
// Show admin info
- print '
'.info_admin($langs->trans("SQLUsedForExport").':
'.$sql);
+ print '
'.info_admin($langs->trans("SQLUsedForExport").':
'.$sql, 0, 0, 1, '', 'TechnicalInformation');
}
print '
';
-dol_fiche_end();
-
+if (!defined('USE_CUSTOME_REPORT_AS_INCLUDE')) {
+ dol_fiche_end();
+}
// End of page
llxFooter();
diff --git a/htdocs/core/js/lib_foot.js.php b/htdocs/core/js/lib_foot.js.php
index 3d708101d13..c40dd571190 100644
--- a/htdocs/core/js/lib_foot.js.php
+++ b/htdocs/core/js/lib_foot.js.php
@@ -81,13 +81,31 @@ print "});\n";
// Wrapper to manage dropdown
if (! defined('JS_JQUERY_DISABLE_DROPDOWN'))
{
- print "\n/* JS CODE TO ENABLE dropdown */\n";
+ print "\n/* JS CODE TO ENABLE dropdown (hamburger, linkto, ...) */\n";
print '
- jQuery(document).ready(function () {
- $(".dropdown dt a").on(\'click\', function () {
- console.log("We click on dropdown");
- //console.log($(this).parent().parent().find(\'dd ul\'));
- $(this).parent().parent().find(\'dd ul\').slideToggle(\'fast\');
+ jQuery(document).ready(function () {
+ var lastopendropdown = null;
+
+ // Click onto the link "link to" or "hamburger", toggle dropdown
+ $(".dropdown dt a").on(\'click\', function () {
+ console.log("toggle dropdown dt a");
+
+ //$(this).parent().parent().find(\'dd ul\').slideToggle(\'fast\');
+ $(this).parent().parent().find(\'dd ul\').toggleClass("open");
+
+ if ($(this).parent().parent().find(\'dd ul\').hasClass("open")) {
+ lastopendropdown = $(this).parent().parent().find(\'dd ul\');
+ //console.log(lastopendropdown);
+ } else {
+ // We closed the dropdown for hamburger selectfields
+ if ($("input:hidden[name=formfilteraction]").val() == "listafterchangingselectedfields") {
+ console.log("resubmit the form saved into lastopendropdown after clicking on hamburger");
+ //$(".dropdown dt a").parents(\'form:first\').submit();
+ //$(".dropdown dt a").closest("form").submit();
+ lastopendropdown.closest("form").submit();
+ }
+ }
+
// Note: Did not find a way to get exact height (value is update at exit) so i calculate a generic from nb of lines
heigthofcontent = 21 * $(this).parent().parent().find(\'dd div ul li\').length;
if (heigthofcontent > 300) heigthofcontent = 300; // limited by max-height on css .dropdown dd ul
@@ -101,19 +119,32 @@ if (! defined('JS_JQUERY_DISABLE_DROPDOWN'))
console.log("We reposition top by "+pix);
$(this).parent().parent().find(\'dd\').css("top", pix);
}
- // $(".dropdown dd ul").slideToggle(\'fast\');
- });
- $(".dropdowncloseonclick").on(\'click\', function () {
- console.log("Link has class dropdowncloseonclick, so we close/hide the popup ul");
- $(this).parent().parent().hide();
});
- $(document).bind(\'click\', function (e) {
- //console.log("We click outside of dropdown, so we close it.");
- var $clicked = $(e.target);
- if (!$clicked.parents().hasClass("dropdown")) $(".dropdown dd ul").hide();
+ // Click on a link into the popup "link to" or other dropdown that ask to close drop down on element click, so close dropdown
+ $(".dropdowncloseonclick").on(\'click\', function () {
+ console.log("Link has class dropdowncloseonclick, so we close/hide the popup ul");
+ //$(this).parent().parent().hide(); // $(this).parent().parent() is ul
+ $(this).parent().parent().removeClass("open"); // $(this).parent().parent() is ul
});
- });
+
+ // Click outside of any dropdown
+ $(document).bind(\'click\', function (e) {
+ var $clicked = $(e.target); // This is element we click on
+ if (!$clicked.parents().hasClass("dropdown")) {
+ //console.log("close dropdown dd ul - we click outside");
+ //$(".dropdown dd ul").hide();
+ $(".dropdown dd ul").removeClass("open");
+
+ if ($("input:hidden[name=formfilteraction]").val() == "listafterchangingselectedfields") {
+ console.log("resubmit form saved into lastopendropdown after clicking outside of dropdown and having change selectlist from selectlist field of hamburger dropdown");
+ //$(".dropdown dt a").parents(\'form:first\').submit();
+ //$(".dropdown dt a").closest("form").submit();
+ lastopendropdown.closest("form").submit();
+ }
+ }
+ });
+ });
';
}
diff --git a/htdocs/core/js/lib_head.js.php b/htdocs/core/js/lib_head.js.php
index 103e3df3c5b..9f8fda42d61 100644
--- a/htdocs/core/js/lib_head.js.php
+++ b/htdocs/core/js/lib_head.js.php
@@ -523,14 +523,16 @@ function hideMessage(fieldId,message) {
* @param string intput Input
* @param int entity Entity
* @param int strict Strict
+ * @param int forcereload Force reload
*/
-function setConstant(url, code, input, entity, strict) {
+function setConstant(url, code, input, entity, strict, forcereload) {
$.get( url, {
action: "set",
name: code,
entity: entity
},
function() {
+ console.log("url request success forcereload="+forcereload);
$("#set_" + code).hide();
$("#del_" + code).show();
$.each(input, function(type, data) {
@@ -576,6 +578,9 @@ function setConstant(url, code, input, entity, strict) {
});
}
});
+ if (forcereload) {
+ location.reload();
+ }
});
}
@@ -587,14 +592,16 @@ function setConstant(url, code, input, entity, strict) {
* @param string intput Input
* @param int entity Entity
* @param int strict Strict
+ * @param int forcereload Force reload
*/
-function delConstant(url, code, input, entity, strict) {
+function delConstant(url, code, input, entity, strict, forcereload) {
$.get( url, {
action: "del",
name: code,
entity: entity
},
function() {
+ console.log("url request success forcereload="+forcereload);
$("#del_" + code).hide();
$("#set_" + code).show();
$.each(input, function(type, data) {
@@ -636,6 +643,9 @@ function delConstant(url, code, input, entity, strict) {
});
}
});
+ if (forcereload) {
+ location.reload();
+ }
});
}
diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php
index 2433f284a2c..7d3658d4f97 100644
--- a/htdocs/core/lib/admin.lib.php
+++ b/htdocs/core/lib/admin.lib.php
@@ -273,9 +273,9 @@ function run_sql($sqlfile, $silent = 1, $entity = '', $usesavepoint = 1, $handle
if ($offsetforchartofaccount > 0)
{
// Replace lines
- // 'INSERT INTO llx_accounting_account (__ENTITY__, rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (1401, 'PCG99-ABREGE','CAPIT', 'XXXXXX', '1', 0, '...', 1);'
+ // 'INSERT INTO llx_accounting_account (__ENTITY__, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (1401, 'PCG99-ABREGE','CAPIT', 'XXXXXX', '1', 0, '...', 1);'
// with
- // 'INSERT INTO llx_accounting_account (__ENTITY__, rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (1401 + 200100000, 'PCG99-ABREGE','CAPIT', 'XXXXXX', '1', 0, '...', 1);'
+ // 'INSERT INTO llx_accounting_account (__ENTITY__, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (1401 + 200100000, 'PCG99-ABREGE','CAPIT', 'XXXXXX', '1', 0, '...', 1);'
$newsql = preg_replace('/VALUES\s*\(__ENTITY__, \s*(\d+)\s*,(\s*\'[^\',]*\'\s*,\s*\'[^\',]*\'\s*,\s*\'[^\',]*\'\s*,\s*\'[^\',]*\'\s*),\s*\'?([^\',]*)\'?/ims', 'VALUES (__ENTITY__, \1 + '.$offsetforchartofaccount.', \2, \3 + '.$offsetforchartofaccount, $newsql);
$newsql = preg_replace('/([,\s])0 \+ '.$offsetforchartofaccount.'/ims', '\1 0', $newsql);
//var_dump($newsql);
diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php
index d2626414ba6..58567748f7f 100644
--- a/htdocs/core/lib/ajax.lib.php
+++ b/htdocs/core/lib/ajax.lib.php
@@ -45,21 +45,21 @@
*/
function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLength = 2, $autoselect = 0, $ajaxoptions = array())
{
- if (empty($minLength)) $minLength=1;
+ if (empty($minLength)) $minLength = 1;
- $dataforrenderITem='ui-autocomplete';
- $dataforitem='ui-autocomplete-item';
+ $dataforrenderITem = 'ui-autocomplete';
+ $dataforitem = 'ui-autocomplete-item';
// Allow two constant to use other values for backward compatibility
- if (defined('JS_QUERY_AUTOCOMPLETE_RENDERITEM')) $dataforrenderITem=constant('JS_QUERY_AUTOCOMPLETE_RENDERITEM');
- if (defined('JS_QUERY_AUTOCOMPLETE_ITEM')) $dataforitem=constant('JS_QUERY_AUTOCOMPLETE_ITEM');
+ if (defined('JS_QUERY_AUTOCOMPLETE_RENDERITEM')) $dataforrenderITem = constant('JS_QUERY_AUTOCOMPLETE_RENDERITEM');
+ if (defined('JS_QUERY_AUTOCOMPLETE_ITEM')) $dataforitem = constant('JS_QUERY_AUTOCOMPLETE_ITEM');
// Input search_htmlname is original field
// Input htmlname is a second input field used when using ajax autocomplete.
$script = '
';
- $script.= ''."\n";
- $script.= '';
+ $script .= '';
return $script;
}
@@ -224,8 +225,8 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen
function ajax_multiautocompleter($htmlname, $fields, $url, $option = '', $minLength = 2, $autoselect = 0)
{
$script = ''."\n";
- $script.= '';
+ $script .= '';
return $script;
}
@@ -332,11 +333,11 @@ function ajax_dialog($title, $message, $w = 350, $h = 150)
{
global $langs;
- $newtitle=dol_textishtml($title)?dol_string_nohtmltag($title, 1):$title;
- $msg= '
';
- $msg.= $message;
- $msg.= '
'."\n";
- $msg.= '';
- $msg.= "\n";
+ $msg .= "\n";
return $msg;
}
@@ -376,20 +377,20 @@ function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete =
global $conf;
// select2 can be disabled for smartphones
- if (! empty($conf->browser->layout) && $conf->browser->layout == 'phone' && ! empty($conf->global->MAIN_DISALLOW_SELECT2_WITH_SMARTPHONE)) return '';
+ if (!empty($conf->browser->layout) && $conf->browser->layout == 'phone' && !empty($conf->global->MAIN_DISALLOW_SELECT2_WITH_SMARTPHONE)) return '';
- if (! empty($conf->global->MAIN_DISABLE_AJAX_COMBOX)) return '';
+ if (!empty($conf->global->MAIN_DISABLE_AJAX_COMBOX)) return '';
if (empty($conf->use_javascript_ajax)) return '';
- if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) && ! defined('REQUIRE_JQUERY_MULTISELECT')) return '';
- if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) return '';
+ if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) && !defined('REQUIRE_JQUERY_MULTISELECT')) return '';
+ if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) return '';
- if (empty($minLengthToAutocomplete)) $minLengthToAutocomplete=0;
+ if (empty($minLengthToAutocomplete)) $minLengthToAutocomplete = 0;
- $tmpplugin='select2';
- $msg="\n".'
+ $tmpplugin = 'select2';
+ $msg = "\n".'
\n";
+ $msg .= '});'."\n";
+ $msg .= "\n";
return $msg;
}
@@ -473,14 +474,16 @@ function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete =
/**
* On/off button for constant
*
- * @param string $code Name of constant
- * @param array $input Array of type->list of CSS element to switch. Example: array('disabled'=>array(0=>'cssid'))
- * @param int $entity Entity to set
- * @param int $revertonoff Revert on/off
- * @param bool $strict Use only "disabled" with delConstant and "enabled" with setConstant
+ * @param string $code Name of constant
+ * @param array $input Array of options. ("disabled"|"enabled'|'set'|'del') => CSS element to switch, 'alert' => message to show, ... Example: array('disabled'=>array(0=>'cssid'))
+ * @param int $entity Entity to set. Use current entity if null.
+ * @param int $revertonoff Revert on/off
+ * @param int $strict Use only "disabled" with delConstant and "enabled" with setConstant
+ * @param int $forcereload Force to reload page if we click/change value (this is supported only when there is no 'alert' option in input)
+ * @param string $marginleftonlyshort 1 = Add a short left margin on picto, 2 = Add a larger left margin on picto, 0 = No margin left. Works for fontawesome picto only.
* @return string
*/
-function ajax_constantonoff($code, $input = array(), $entity = null, $revertonoff = 0, $strict = 0)
+function ajax_constantonoff($code, $input = array(), $entity = null, $revertonoff = 0, $strict = 0, $forcereload = 0, $marginleftonlyshort = 2)
{
global $conf, $langs;
@@ -493,7 +496,7 @@ function ajax_constantonoff($code, $input = array(), $entity = null, $revertonof
}
else
{
- $out= "\n".'
+ $out = "\n".'
'."\n";
- $out.= '
';
- $out.= '
'.($revertonoff?img_picto($langs->trans("Enabled"), 'switch_on'):img_picto($langs->trans("Disabled"), 'switch_off')).' ';
- $out.= '
'.($revertonoff?img_picto($langs->trans("Disabled"), 'switch_off'):img_picto($langs->trans("Enabled"), 'switch_on')).' ';
- $out.="\n";
+ $out .= '
';
+ $out .= '
'.($revertonoff ?img_picto($langs->trans("Enabled"), 'switch_on', '', false, 0, 0, '', '', $marginleftonlyshort) : img_picto($langs->trans("Disabled"), 'switch_off', '', false, 0, 0, '', '', $marginleftonlyshort)).' ';
+ $out .= '
'.($revertonoff ?img_picto($langs->trans("Disabled"), 'switch_off', '', false, 0, 0, '', '', $marginleftonlyshort) : img_picto($langs->trans("Enabled"), 'switch_on', '', false, 0, 0, '', '', $marginleftonlyshort)).' ';
+ $out .= "\n";
}
return $out;
@@ -553,7 +556,7 @@ function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input =
{
global $langs;
- $out= '';
- $out.= '
'.img_picto($langs->trans($text_off), 'switch_off').' ';
- $out.= '
'.img_picto($langs->trans($text_on), 'switch_on').' ';
+ $out .= '
'.img_picto($langs->trans($text_off), 'switch_off').' ';
+ $out .= '
'.img_picto($langs->trans($text_on), 'switch_on').' ';
return $out;
}
diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php
index a3771d53cff..012261ce592 100644
--- a/htdocs/core/lib/company.lib.php
+++ b/htdocs/core/lib/company.lib.php
@@ -872,7 +872,7 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '')
$optioncss = GETPOST('optioncss', 'alpha');
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
- $page = GETPOST('page', 'int');
+ $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
$search_status = GETPOST("search_status", 'int');
if ($search_status == '') $search_status = 1; // always display active customer first
diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php
index 38264ac9029..1cd80af55ed 100644
--- a/htdocs/core/lib/files.lib.php
+++ b/htdocs/core/lib/files.lib.php
@@ -2401,10 +2401,11 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
$original_file = (!empty($conf->product->multidir_temp[$entity]) ? $conf->product->multidir_temp[$entity] : $conf->service->multidir_temp[$entity]).'/'.$original_file;
}
// Wrapping for taxes
- elseif ($modulepart == 'tax' && !empty($conf->tax->dir_output))
+ elseif (in_array($modulepart, array('tax', 'tax-vat')) && !empty($conf->tax->dir_output))
{
if ($fuser->rights->tax->charges->{$lire}) $accessallowed = 1;
- $original_file = $conf->tax->dir_output.'/'.$original_file;
+ $modulepartsuffix = str_replace('tax-', '', $modulepart);
+ $original_file = $conf->tax->dir_output.'/'.($modulepartsuffix != 'tax' ? $modulepartsuffix.'/' : '').$original_file;
}
// Wrapping for events
elseif ($modulepart == 'actions' && !empty($conf->agenda->dir_output))
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 38b5a2d2a2d..8434755bef1 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -65,7 +65,7 @@ function getDoliDBInstance($type, $host, $user, $pass, $name, $port)
*
* @param string $element Current element
* 'societe', 'socpeople', 'actioncomm', 'agenda', 'resource',
- * 'product', 'productprice', 'stock',
+ * 'product', 'productprice', 'stock', 'bom', 'mo',
* 'propal', 'supplier_proposal', 'invoice', 'facture_fourn', 'payment_various',
* 'categorie', 'bank_account', 'bank_account', 'adherent', 'user',
* 'commande', 'commande_fournisseur', 'expedition', 'intervention', 'survey',
@@ -291,14 +291,15 @@ function GETPOSTISSET($paramname)
* 'array'=check it's array
* 'san_alpha'=Use filter_var with FILTER_SANITIZE_STRING (do not use this for free text string)
* 'nohtml', 'alphanohtml'=check there is no html content
+ * 'restricthtml'=check html content is restricted to some tags only
* 'custom'= custom filter specify $filter and $options)
* @param int $method Type of method (0 = get then post, 1 = only get, 2 = only post, 3 = post then get)
* @param int $filter Filter to apply when $check is set to 'custom'. (See http://php.net/manual/en/filter.filters.php for détails)
* @param mixed $options Options to pass to filter_var when $check is set to 'custom'
* @param string $noreplace Force disable of replacement of __xxx__ strings.
- * @return string|string[] Value found (string or array), or '' if check fails
+ * @return string|array Value found (string or array), or '' if check fails
*/
-function GETPOST($paramname, $check = 'none', $method = 0, $filter = null, $options = null, $noreplace = 0)
+function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null, $options = null, $noreplace = 0)
{
global $mysoc, $user, $conf;
@@ -558,11 +559,9 @@ function GETPOST($paramname, $check = 'none', $method = 0, $filter = null, $opti
case 'alpha':
if (!is_array($out))
{
- $out = trim($out);
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
// '../' is dangerous because it allows dir transversals
- if (preg_match('/"/', $out)) $out = '';
- elseif (preg_match('/\.\.\//', $out)) $out = '';
+ $out = str_replace(array('"', '../'), '', trim($out));
}
break;
case 'san_alpha':
@@ -592,17 +591,15 @@ function GETPOST($paramname, $check = 'none', $method = 0, $filter = null, $opti
case 'array':
if (!is_array($out) || empty($out)) $out = array();
break;
- case 'nohtml': // Recommended for most scalar parameters
+ case 'nohtml':
$out = dol_string_nohtmltag($out, 0);
break;
- case 'alphanohtml': // Recommended for search parameters
+ case 'alphanohtml': // Recommended for most scalar parameters and search parameters
if (!is_array($out))
{
- $out = trim($out);
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
// '../' is dangerous because it allows dir transversals
- if (preg_match('/"/', $out)) $out = '';
- elseif (preg_match('/\.\.\//', $out)) $out = '';
+ $out = str_replace(array('"', '../'), '', trim($out));
$out = dol_string_nohtmltag($out);
}
break;
@@ -817,7 +814,7 @@ function dol_buildpath($path, $type = 0, $returnemptyifnotfound = 0)
* With native = 1: Use PHP clone. Property that are reference are same pointer. This means $this->db of new object is still valid but point to same this->db than original object.
*
* @param object $object Object to clone
- * @param int $native Native method or full isolation method
+ * @param int $native 0=Full isolation method, 1=Native PHP method
* @return object Clone object
* @see https://php.net/manual/language.oop5.cloning.php
*/
@@ -990,23 +987,32 @@ function dol_escape_js($stringtoescape, $mode = 0, $noescapebackslashn = 0)
/**
* Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
*
- * @param string $stringtoescape String to escape
- * @param int $keepb 1=Preserve b tags (otherwise, remove them)
- * @param int $keepn 1=Preserve \r\n strings (otherwise, replace them with escaped value). Set to 1 when escaping for a
.
- * @param string $keepmoretags '' or 'common' or list of tags
- * @return string Escaped string
+ * @param string $stringtoescape String to escape
+ * @param int $keepb 1=Preserve b tags (otherwise, remove them)
+ * @param int $keepn 1=Preserve \r\n strings (otherwise, replace them with escaped value). Set to 1 when escaping for a .
+ * @param string $keepmoretags '' or 'common' or list of tags
+ * @param int $escapeonlyhtmltags 1=Escape only html tags, not the special chars like accents.
+ * @return string Escaped string
* @see dol_string_nohtmltag(), dol_string_nospecial(), dol_string_unaccent()
*/
-function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $keepmoretags = '')
+function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $keepmoretags = '', $escapeonlyhtmltags = 0)
{
if ($keepmoretags == 'common') $keepmoretags = 'html,body,a,em,i,u,ul,li,br,div,img,font,p,span,strong,table,tr,td,th,tbody';
// TODO Implement $keepmoretags
// escape quotes and backslashes, newlines, etc.
- $tmp = html_entity_decode($stringtoescape, ENT_COMPAT, 'UTF-8'); // TODO Use htmlspecialchars_decode instead, that make only required change for html tags
+ if ($escapeonlyhtmltags) {
+ $tmp = htmlspecialchars_decode($stringtoescape, ENT_COMPAT);
+ } else {
+ $tmp = html_entity_decode($stringtoescape, ENT_COMPAT, 'UTF-8');
+ }
if (!$keepb) $tmp = strtr($tmp, array(""=>'', ' '=>''));
if (!$keepn) $tmp = strtr($tmp, array("\r"=>'\\r', "\n"=>'\\n'));
- return htmlentities($tmp, ENT_COMPAT, 'UTF-8'); // TODO Use htmlspecialchars instead, that make only required change for html tags
+ if ($escapeonlyhtmltags) {
+ return htmlspecialchars($tmp, ENT_COMPAT, 'UTF-8');
+ } else {
+ return htmlentities($tmp, ENT_COMPAT, 'UTF-8');
+ }
}
@@ -1105,8 +1111,8 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename =
'ip' => false
);
- $remoteip = getUserRemoteIP(); // Get ip when page run on a web server
- if (! empty($remoteip)) {
+ $remoteip = getUserRemoteIP(); // Get ip when page run on a web server
+ if (!empty($remoteip)) {
$data['ip'] = $remoteip;
// This is when server run behind a reverse proxy
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != $remoteip) $data['ip'] = $_SERVER['HTTP_X_FORWARDED_FOR'].' -> '.$data['ip'];
@@ -1148,15 +1154,16 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename =
* @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto.
* @param string $morehtmlright Add more html content on right of tabs title
* @param string $morecss More Css
+ * @param int $limittoshow Limit number of tabs to show. Use 0 to use automatic default value.
* @return void
*/
-function dol_fiche_head($links = array(), $active = '0', $title = '', $notab = 0, $picto = '', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '')
+function dol_fiche_head($links = array(), $active = '0', $title = '', $notab = 0, $picto = '', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '', $limittoshow = 0)
{
- print dol_get_fiche_head($links, $active, $title, $notab, $picto, $pictoisfullpath, $morehtmlright, $morecss);
+ print dol_get_fiche_head($links, $active, $title, $notab, $picto, $pictoisfullpath, $morehtmlright, $morecss, $limittoshow);
}
/**
- * Show tab header of a card
+ * Show tabs of a record
*
* @param array $links Array of tabs
* @param string $active Active tab name
@@ -1166,9 +1173,10 @@ function dol_fiche_head($links = array(), $active = '0', $title = '', $notab = 0
* @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto.
* @param string $morehtmlright Add more html content on right of tabs title
* @param string $morecss More Css
+ * @param int $limittoshow Limit number of tabs to show. Use 0 to use automatic default value.
* @return string
*/
-function dol_get_fiche_head($links = array(), $active = '', $title = '', $notab = 0, $picto = '', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '')
+function dol_get_fiche_head($links = array(), $active = '', $title = '', $notab = 0, $picto = '', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '', $limittoshow = 0)
{
global $conf, $langs, $hookmanager;
@@ -1205,11 +1213,13 @@ function dol_get_fiche_head($links = array(), $active = '', $title = '', $notab
if (count($keys)) $maxkey = max($keys);
}
- if (!empty($conf->dol_optimize_smallscreen)) $conf->global->MAIN_MAXTABS_IN_CARD = 2;
-
// Show tabs
// if =0 we don't use the feature
- $limittoshow = (empty($conf->global->MAIN_MAXTABS_IN_CARD) ? 99 : $conf->global->MAIN_MAXTABS_IN_CARD);
+ if (empty($limittoshow)) {
+ $limittoshow = (empty($conf->global->MAIN_MAXTABS_IN_CARD) ? 99 : $conf->global->MAIN_MAXTABS_IN_CARD);
+ }
+ if (!empty($conf->dol_optimize_smallscreen)) $limittoshow = 2;
+
$displaytab = 0;
$nbintab = 0;
$popuptab = 0;
@@ -1301,7 +1311,7 @@ function dol_get_fiche_head($links = array(), $active = '', $title = '', $notab
$tabsname = str_replace("@", "", $picto);
$out .= '';
$out .= '
'.$langs->trans("More").'... ('.$nbintab.') ';
- $out .= '
';
+ $out .= '
';
$out .= $outmore;
$out .= '
';
$out .= '
';
@@ -1882,6 +1892,7 @@ function dol_print_date($time, $format = '', $tzoutput = 'tzserver', $outputlang
$format = str_replace('%A', '__A__', $format);
}
+
// Analyze date
$reg = array();
if (preg_match('/^([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])$/i', $time, $reg)) // Deprecated. Ex: 1970-01-01, 1970-01-01 01:00:00, 19700101010000
@@ -2105,8 +2116,6 @@ function dol_now($mode = 'gmt')
{
$ret = 0;
- // Note that gmmktime and mktime return same value (GMT) when used without parameters
- //if ($mode == 'gmt') $ret=gmmktime(); // Strict Standards: gmmktime(): You should be using the time() function instead
if ($mode == 'gmt') $ret = time(); // Time for now at greenwich.
elseif ($mode == 'tzserver') // Time for now with PHP server timezone added
{
@@ -2122,7 +2131,7 @@ function dol_now($mode = 'gmt')
}*/
elseif ($mode == 'tzuser') // Time for now with user timezone added
{
- //print 'time: '.time().'-'.mktime().'-'.gmmktime();
+ //print 'time: '.time();
$offsettz = (empty($_SESSION['dol_tz']) ? 0 : $_SESSION['dol_tz']) * 60 * 60;
$offsetdst = (empty($_SESSION['dol_dst']) ? 0 : $_SESSION['dol_dst']) * 60 * 60;
$ret = (int) (dol_now('gmt') + ($offsettz + $offsetdst));
@@ -3078,7 +3087,7 @@ function dol_trunc($string, $size = 40, $trunc = 'right', $stringencoding = 'UTF
* @param int $srconly Return only content of the src attribute of img.
* @param int $notitle 1=Disable tag title. Use it if you add js tooltip, to avoid duplicate tooltip.
* @param string $alt Force alt for bind people
- * @param string $morecss Add more class css on img tag (For example 'myclascss'). Work only if $moreatt is empty.
+ * @param string $morecss Add more class css on img tag (For example 'myclascss').
* @param string $marginleftonlyshort 1 = Add a short left margin on picto, 2 = Add a larger left margin on picto, 0 = No margin left. Works for fontawesome picto only.
* @return string Return img tag
* @see img_object(), img_picto_common()
@@ -3110,15 +3119,14 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
//if (in_array($picto, array('switch_off', 'switch_on', 'off', 'on')))
if (empty($srconly) && in_array($pictowithouttext, array(
'1downarrow', '1uparrow', '1leftarrow', '1rightarrow', '1uparrow_selected', '1downarrow_selected', '1leftarrow_selected', '1rightarrow_selected',
- 'address', 'barcode', 'bank', 'bookmark', 'building', 'cash-register', 'close_title', 'cubes', 'delete', 'dolly', 'edit', 'ellipsis-h',
+ 'address', 'barcode', 'bank', 'bookmark', 'building', 'cash-register', 'check', 'close_title', 'cubes', 'delete', 'dolly', 'edit', 'ellipsis-h',
'filter', 'file-code', 'grip', 'grip_title', 'list', 'listlight', 'note',
'object_bookmark', 'object_list', 'object_calendar', 'object_calendarweek', 'object_calendarmonth', 'object_calendarday', 'object_calendarperuser',
'off', 'on', 'play', 'playdisabled', 'printer', 'resize', 'stats',
'note', 'setup', 'sign-out', 'split', 'switch_off', 'switch_on', 'tools', 'unlink', 'uparrow', 'user', 'wrench', 'globe',
- 'jabber', 'skype', 'twitter', 'facebook', 'linkedin',
- 'instagram', 'snapchat', 'youtube', 'google-plus-g', 'whatsapp',
+ 'jabber', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'youtube', 'google-plus-g', 'whatsapp',
'chevron-left', 'chevron-right', 'chevron-down', 'chevron-top',
- 'home', 'companies', 'products', 'commercial', 'invoicing', 'accountancy', 'project', 'hrm', 'members', 'ticket', 'generic',
+ 'home', 'companies', 'products', 'commercial', 'invoicing', 'accountancy', 'preview', 'project', 'hrm', 'members', 'ticket', 'generic',
'error', 'warning',
'title_setup', 'title_accountancy', 'title_bank', 'title_hrm', 'title_agenda'
)
@@ -3134,13 +3142,14 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
}
$arrayconvpictotofa = array(
- 'address'=> 'address-book', 'setup'=>'cog', 'companies'=>'building', 'products'=>'cube', 'commercial'=>'suitcase', 'invoicing'=>'coins', 'accountancy'=>'money-check-alt', 'project'=>'sitemap',
+ 'address'=> 'address-book', 'setup'=>'cog', 'companies'=>'building', 'products'=>'cube', 'commercial'=>'suitcase', 'invoicing'=>'coins', 'accountancy'=>'money-check-alt',
'hrm'=>'umbrella-beach', 'members'=>'users', 'ticket'=>'ticket-alt', 'generic'=>'folder-open',
- 'switch_off'=>'toggle-off', 'switch_on'=>'toggle-on', 'object_bookmark'=>'star', 'bookmark'=>'star', 'stats' => 'chart-bar',
+ 'switch_off'=>'toggle-off', 'switch_on'=>'toggle-on', 'check'=>'check', 'object_bookmark'=>'star', 'bookmark'=>'star', 'stats' => 'chart-bar',
'bank'=>'university', 'close_title'=>'window-close', 'delete'=>'trash', 'edit'=>'pencil', 'filter'=>'filter', 'split'=>'code-branch',
'object_list'=>'list-alt', 'object_calendar'=>'calendar-alt', 'object_calendarweek'=>'calendar-week', 'object_calendarmonth'=>'calendar-alt', 'object_calendarday'=>'calendar-day', 'object_calendarperuser'=>'table',
'error'=>'exclamation-triangle', 'warning'=>'exclamation-triangle',
- 'title_setup'=>'tools', 'title_accountancy'=>'money-check-alt', 'title_bank'=>'university', 'title_hrm'=>'umbrella-beach', 'title_agenda'=>'calendar-alt'
+ 'title_setup'=>'tools', 'title_accountancy'=>'money-check-alt', 'title_bank'=>'university', 'title_hrm'=>'umbrella-beach', 'title_agenda'=>'calendar-alt',
+ 'preview'=>'binoculars', 'project'=>'sitemap'
);
if ($pictowithouttext == 'error' || $pictowithouttext == 'warning') {
$facolor = '';
@@ -3155,6 +3164,10 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
$morecss .= ($morecss ? ' ' : '').'font-status4';
$fakey = 'fa-'.$arrayconvpictotofa[$pictowithouttext];
}
+ elseif ($pictowithouttext == 'check') {
+ $morecss .= ($morecss ? ' ' : '').'font-status4';
+ $fakey = 'fa-'.$arrayconvpictotofa[$pictowithouttext];
+ }
elseif ($pictowithouttext == 'off') {
$fakey = 'fa-square';
$fasize = '1.3em';
@@ -3822,23 +3835,44 @@ function img_searchclear($titlealt = 'default', $other = '')
/**
* Show information for admin users or standard users
*
- * @param string $text Text info
- * @param integer $infoonimgalt Info is shown only on alt of star picto, otherwise it is show on output after the star picto
- * @param int $nodiv No div
- * @param string $admin '1'=Info for admin users. '0'=Info for standard users (change only the look), 'error','xxx'=Other
- * @param string $morecss More CSS ('', 'warning', 'error')
- * @return string String with info text
+ * @param string $text Text info
+ * @param integer $infoonimgalt Info is shown only on alt of star picto, otherwise it is show on output after the star picto
+ * @param int $nodiv No div
+ * @param string $admin '1'=Info for admin users. '0'=Info for standard users (change only the look), 'error','xxx'=Other
+ * @param string $morecss More CSS ('', 'warning', 'error')
+ * @param string $textfordropdown Show a text to click to dropdown the info box.
+ * @return string String with info text
*/
-function info_admin($text, $infoonimgalt = 0, $nodiv = 0, $admin = '1', $morecss = '')
+function info_admin($text, $infoonimgalt = 0, $nodiv = 0, $admin = '1', $morecss = '', $textfordropdown = '')
{
global $conf, $langs;
if ($infoonimgalt)
{
- return img_picto($text, 'info', 'class="hideonsmartphone'.($morecss ? ' '.$morecss : '').'"');
+ $result = img_picto($text, 'info', 'class="hideonsmartphone'.($morecss ? ' '.$morecss : '').'"');
+ }
+ else {
+ if (empty($conf->use_javascript_ajax)) $textfordropdown = '';
+
+ $class = (empty($admin) ? 'undefined' : ($admin == '1' ? 'info' : $admin));
+ $result = ($nodiv ? '' : '
').' '.$text.($nodiv ? '' : '
');
+
+ if ($textfordropdown) {
+ $tmpresult .= '
'.$langs->trans($textfordropdown).' '.img_picto($langs->trans($textfordropdown), '1downarrow').' ';
+ $tmpresult .= '';
+
+ $result = $tmpresult.$result;
+ }
}
- return ($nodiv ? '' : '
').' '.$text.($nodiv ? '' : '
');
+ return $result;
}
@@ -4066,11 +4100,22 @@ function getTitleFieldOfList($name, $thead = 0, $file = "", $field = "", $begin
$tmpfield = explode(',', $field);
$field1 = trim($tmpfield[0]); // If $field is 'd.datep,d.id', it becomes 'd.datep'
+ if (empty($conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE)) {
+ $prefix = 'wrapcolumntitle '.$prefix;
+ }
//var_dump('field='.$field.' field1='.$field1.' sortfield='.$sortfield.' sortfield1='.$sortfield1);
// If field is used as sort criteria we use a specific css class liste_titre_sel
// Example if (sortfield,field)=("nom","xxx.nom") or (sortfield,field)=("nom","nom")
- if ($field1 && ($sortfield1 == $field1 || $sortfield1 == preg_replace("/^[^\.]+\./", "", $field1))) $out .= '<'.$tag.' class="'.$prefix.'liste_titre_sel" '.$moreattrib.'>';
- else $out .= '<'.$tag.' class="'.$prefix.'liste_titre" '.$moreattrib.'>';
+ if ($field1 && ($sortfield1 == $field1 || $sortfield1 == preg_replace("/^[^\.]+\./", "", $field1))) {
+ $out .= '<'.$tag.' class="'.$prefix.'liste_titre_sel" '.$moreattrib;
+ $out .= (($field && empty($conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE) && preg_match('/^[a-zA-Z_0-9\s\.\-:]*$/', $name)) ? ' title="'.dol_escape_htmltag($langs->trans($name)).'"' : '');
+ $out .= '>';
+ }
+ else {
+ $out .= '<'.$tag.' class="'.$prefix.'liste_titre" '.$moreattrib;
+ $out .= (($field && empty($conf->global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE) && preg_match('/^[a-zA-Z_0-9\s\.\-:]*$/', $name)) ? ' title="'.dol_escape_htmltag($langs->trans($name)).'"' : '');
+ $out .= '>';
+ }
if (empty($thead) && $field && empty($disablesortlink)) // If this is a sort field
{
@@ -4103,7 +4148,9 @@ function getTitleFieldOfList($name, $thead = 0, $file = "", $field = "", $begin
}
}
$sortordertouseinlink = preg_replace('/,$/', '', $sortordertouseinlink);
- $out .= '
';
+ $out .= ' global->MAIN_DISABLE_WRAPPING_ON_COLUMN_TITLE) ? ' title="'.dol_escape_htmltag($langs->trans($name)).'"' : '');
+ $out .= '>';
}
if ($tooltip) $out .= $form->textwithpicto($langs->trans($name), $langs->trans($tooltip));
@@ -4234,14 +4281,15 @@ function load_fiche_titre($titre, $morehtmlright = '', $picto = 'generic', $pict
* @param int|string $totalnboflines Total number of records/lines for all pages (if known). Use a negative value of number to not show number. Use '' if unknown.
* @param string $picto Icon to use before title (should be a 32x32 transparent png file)
* @param int $pictoisfullpath 1=Icon name is a full absolute url of image
- * @param string $morehtmlright More html to show
+ * @param string $morehtmlright More html to show
* @param string $morecss More css to the table
* @param int $limit Max number of lines (-1 = use default, 0 = no limit, > 0 = limit).
* @param int $hideselectlimit Force to hide select limit
* @param int $hidenavigation Force to hide all navigation tools
+ * @param int $pagenavastextinput 1=Do not suggest list of pages to navigate but suggest the page number into an input field.
* @return void
*/
-function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '', $sortorder = '', $morehtmlcenter = '', $num = -1, $totalnboflines = '', $picto = 'generic', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '', $limit = -1, $hideselectlimit = 0, $hidenavigation = 0)
+function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '', $sortorder = '', $morehtmlcenter = '', $num = -1, $totalnboflines = '', $picto = 'generic', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '', $limit = -1, $hideselectlimit = 0, $hidenavigation = 0, $pagenavastextinput = 0)
{
global $conf, $langs;
@@ -4271,7 +4319,7 @@ function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '',
if ($picto && $titre) print ' '.img_picto('', $picto, 'class="valignmiddle pictotitle widthpictotitle"', $pictoisfullpath).' ';
print '
';
print ''.$titre;
- if (!empty($titre) && $savtotalnboflines >= 0 && (string) $savtotalnboflines != '') print ' ('.$totalnboflines.')';
+ if (!empty($titre) && $savtotalnboflines >= 0 && (string) $savtotalnboflines != '') print '('.$totalnboflines.') ';
print '
';
// Center
@@ -4300,30 +4348,47 @@ function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '',
if ($cpt >= 1)
{
- $pagelist .= '';
- if ($cpt > 2) $pagelist .= '';
- elseif ($cpt == 2) $pagelist .= '';
+ if (empty($pagenavastextinput)) {
+ $pagelist .= '';
+ if ($cpt > 2) $pagelist .= '';
+ elseif ($cpt == 2) $pagelist .= '';
+ }
}
do
{
- if ($cpt == $page)
- {
- $pagelist .= '';
- }
- else
- {
- $pagelist .= '';
+ if ($pagenavastextinput) {
+ if ($cpt == $page)
+ {
+ $pagelist .= '';
+ if (($cpt + 1) < $nbpages) $pagelist .= '/';
+ }
+ } else {
+ if ($cpt == $page)
+ {
+ $pagelist .= '';
+ }
+ else
+ {
+ $pagelist .= '';
+ }
}
$cpt++;
}
- while ($cpt < $nbpages && $cpt <= $page + $maxnbofpage);
+ while ($cpt < $nbpages && $cpt <= ($page + $maxnbofpage));
- if ($cpt < $nbpages)
- {
- if ($cpt < $nbpages - 2) $pagelist .= '';
- elseif ($cpt == $nbpages - 2) $pagelist .= '';
- $pagelist .= '';
+ if (empty($pagenavastextinput)) {
+ if ($cpt < $nbpages)
+ {
+ if ($cpt < $nbpages - 2) $pagelist .= '';
+ elseif ($cpt == $nbpages - 2) $pagelist .= '';
+ $pagelist .= '';
+ }
+ } else {
+ //var_dump($page.' '.$cpt.' '.$nbpages);
+ if (($page + 1) < $nbpages) {
+ $pagelist .= '';
+ }
}
}
else
@@ -4336,6 +4401,11 @@ function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '',
print_fleche_navigation($page, $file, $options, $nextpage, $pagelist, $morehtmlright, $savlimit, $totalnboflines, $hideselectlimit); // output the div and ul for previous/last completed with page numbers into $pagelist
}
+ // js to autoselect page field on focus
+ if ($pagenavastextinput) {
+ print ajax_autoselect('.pageplusone');
+ }
+
print '
';
print '
'."\n";
@@ -5560,22 +5630,27 @@ function dol_string_nohtmltag($stringtoclean, $removelinefeed = 1, $pagecodeto =
/**
* Clean a string to keep only desirable HTML tags.
*
- * @param string $stringtoclean String to clean
- * @return string String cleaned
+ * @param string $stringtoclean String to clean
+ * @param string $cleanalsosomestyles Clean also some tags
+ * @return string String cleaned
*
* @see dol_escape_htmltag() strip_tags() dol_string_nohtmltag() dol_string_neverthesehtmltags()
*/
-function dol_string_onlythesehtmltags($stringtoclean)
+function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1)
{
$allowed_tags = array(
- "html", "head", "meta", "body", "article", "a", "b", "br", "div", "em", "font", "img", "ins", "hr", "i", "li", "link",
- "ol", "p", "s", "section", "span", "strong", "title",
+ "html", "head", "meta", "body", "article", "a", "abbr", "b", "blockquote", "br", "cite", "div", "dl", "dd", "dt", "em", "font", "img", "ins", "hr", "i", "li", "link",
+ "ol", "p", "q", "s", "section", "span", "strike", "strong", "title",
"table", "tr", "th", "td", "u", "ul"
);
-
$allowed_tags_string = join("><", $allowed_tags);
$allowed_tags_string = preg_replace('/^>/', '', $allowed_tags_string);
$allowed_tags_string = preg_replace('/<$/', '', $allowed_tags_string);
+ $allowed_tags_string = '<'.$allowed_tags_string.'>';
+
+ if ($cleanalsosomestyles) {
+ $stringtoclean = preg_replace('/position\s*:\s*(absolute|fixed)\s*!\s*important/', '', $stringtoclean); // Note: If hacker try to introduce css comment into string to avoid this, string should be encoded by the dol_htmlentitiesbr so be harmless
+ }
$temp = strip_tags($stringtoclean, $allowed_tags_string);
@@ -5584,14 +5659,16 @@ function dol_string_onlythesehtmltags($stringtoclean)
/**
* Clean a string from some undesirable HTML tags.
+ * Note. Not enough secured as dol_string_onlythesehtmltags().
*
- * @param string $stringtoclean String to clean
- * @param array $disallowed_tags Array of tags not allowed
- * @return string String cleaned
+ * @param string $stringtoclean String to clean
+ * @param array $disallowed_tags Array of tags not allowed
+ * @param string $cleanalsosomestyles Clean also some tags
+ * @return string String cleaned
*
* @see dol_escape_htmltag() strip_tags() dol_string_nohtmltag() dol_string_onlythesehtmltags()
*/
-function dol_string_neverthesehtmltags($stringtoclean, $disallowed_tags = array('textarea'))
+function dol_string_neverthesehtmltags($stringtoclean, $disallowed_tags = array('textarea'), $cleanalsosomestyles = 0)
{
$temp = $stringtoclean;
foreach ($disallowed_tags as $tagtoremove)
@@ -5599,6 +5676,11 @@ function dol_string_neverthesehtmltags($stringtoclean, $disallowed_tags = array(
$temp = preg_replace('/<\/?'.$tagtoremove.'>/', '', $temp);
$temp = preg_replace('/<\/?'.$tagtoremove.'\s+[^>]*>/', '', $temp);
}
+
+ if ($cleanalsosomestyles) {
+ $temp = preg_replace('/position\s*:\s*(absolute|fixed)\s*!\s*important/', '', $temp); // Note: If hacker try to introduce css comment into string to avoid this, string should be encoded by the dol_htmlentitiesbr so be harmless
+ }
+
return $temp;
}
@@ -5883,6 +5965,7 @@ function dol_textishtml($msg, $option = 0)
{
if (preg_match('//i', $msg)) return true;
elseif (preg_match('/ /i', $msg)) return true;
elseif (preg_match('/<(br|div|font|li|p|span|strong|table)>/i', $msg)) return true;
@@ -5971,7 +6055,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null,
$substitutionarray = array_merge($substitutionarray, array(
'__USER_ID__' => (string) $user->id,
'__USER_LOGIN__' => (string) $user->login,
- '__USER_LASTNAME__' => (string) $user->lastname,
+ '__USER_EMAIL__' => (string) $user->email,
+ '__USER_LASTNAME__' => (string) $user->lastname,
'__USER_FIRSTNAME__' => (string) $user->firstname,
'__USER_FULLNAME__' => (string) $user->getFullName($outputlangs),
'__USER_SUPERVISOR_ID__' => (string) ($user->fk_user ? $user->fk_user : '0'),
@@ -6096,7 +6181,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null,
$substitutionarray['__REFCLIENT__'] = (isset($object->ref_client) ? $object->ref_client : (isset($object->ref_customer) ? $object->ref_customer : null));
$substitutionarray['__REFSUPPLIER__'] = (isset($object->ref_supplier) ? $object->ref_supplier : null);
$substitutionarray['__SUPPLIER_ORDER_DATE_DELIVERY__'] = (isset($object->date_livraison) ? dol_print_date($object->date_livraison, 'day', 0, $outputlangs) : '');
- $substitutionarray['__SUPPLIER_ORDER_DELAY_DELIVERY__'] = $outputlangs->transnoentities("AvailabilityType".$object->availability_code)!=('AvailabilityType'.$object->availability_code)?$outputlangs->transnoentities("AvailabilityType".$object->availability_code):$outputlangs->convToOutputCharset(isset($object->availability)?$object->availability:'');
+ $substitutionarray['__SUPPLIER_ORDER_DELAY_DELIVERY__'] = $outputlangs->transnoentities("AvailabilityType".$object->availability_code) != ('AvailabilityType'.$object->availability_code) ? $outputlangs->transnoentities("AvailabilityType".$object->availability_code) : $outputlangs->convToOutputCharset(isset($object->availability) ? $object->availability : '');
$birthday = dol_print_date($object->birth, 'day');
@@ -6272,6 +6357,10 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null,
$substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__'] = $object->getLastMainDocLink($object->element);
}
else $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__'] = '';
+
+ if (is_object($object) && $object->element == 'propal') $substitutionarray['__URL_PROPOSAL__'] = DOL_MAIN_URL_ROOT."/comm/propal/card.php?id=".$object->id;
+ if (is_object($object) && $object->element == 'commande') $substitutionarray['__URL_ORDER__'] = DOL_MAIN_URL_ROOT."/commande/card.php?id=".$object->id;
+ if (is_object($object) && $object->element == 'facture') $substitutionarray['__URL_INVOICE__'] = DOL_MAIN_URL_ROOT."/compta/facture/card.php?id=".$object->id;
}
}
}
@@ -6921,9 +7010,9 @@ function ascii_check($str)
{
if (function_exists('mb_check_encoding')) {
//if (mb_detect_encoding($str, 'ASCII', true) return false;
- if (! mb_check_encoding($str, 'ASCII')) return false;
+ if (!mb_check_encoding($str, 'ASCII')) return false;
} else {
- if (preg_match('/[^\x00-\x7f]/', $str)) return false; // Contains a byte > 7f
+ if (preg_match('/[^\x00-\x7f]/', $str)) return false; // Contains a byte > 7f
}
return true;
@@ -7590,15 +7679,12 @@ function printCommonFooter($zone = 'private')
$micro_end_time = microtime(true);
print ' - Build time: '.ceil(1000 * ($micro_end_time - $micro_start_time)).' ms';
}
- if (function_exists("memory_get_usage"))
- {
- print ' - Mem: '.memory_get_usage();
+
+ if (function_exists("memory_get_usage")) {
+ print ' - Mem: '.memory_get_usage(); // Do not use true here, it seems it takes the peak amount
}
- if (function_exists("xdebug_memory_usage"))
- {
- print ' - XDebug time: '.ceil(1000 * xdebug_time_index()).' ms';
- print ' - XDebug mem: '.xdebug_memory_usage();
- print ' - XDebug mem peak: '.xdebug_peak_memory_usage();
+ if (function_exists("memory_get_peak_usage")) {
+ print ' - Real mem peak: '.memory_get_peak_usage(true);
}
if (function_exists("zend_loader_file_encoded"))
{
@@ -7815,12 +7901,11 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0)
}
else // $mode=0
{
- $textcrit = '';
$tmpcrits = explode('|', $crit);
$i3 = 0;
foreach ($tmpcrits as $tmpcrit)
{
- if (empty($tmpcrit)) continue;
+ if ($tmpcrit !== '0' && empty($tmpcrit)) continue;
$newres .= (($i2 > 0 || $i3 > 0) ? ' OR ' : '');
@@ -7957,7 +8042,7 @@ function getAdvancedPreviewUrl($modulepart, $relativepath, $alldata = 0, $param
/**
* Make content of an input box selected when we click into input field.
*
- * @param string $htmlname Id of html object
+ * @param string $htmlname Id of html object ('#idvalue' or '.classvalue')
* @param string $addlink Add a 'link to' after
* @return string
*/
@@ -7966,7 +8051,7 @@ function ajax_autoselect($htmlname, $addlink = '')
global $langs;
$out = '';
if ($addlink) $out .= ' '.$langs->trans("Link").' ';
@@ -8011,7 +8096,7 @@ function dol_mimetype($file, $default = 'application/octet-stream', $mode = 0)
if (preg_match('/\.bas$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'bas'; $famime = 'file-code-o'; }
if (preg_match('/\.(c)$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'c'; $famime = 'file-code-o'; }
if (preg_match('/\.(cpp)$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'cpp'; $famime = 'file-code-o'; }
- if (preg_match('/\.cs$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'cs'; $famime = 'file-code-o'; }
+ if (preg_match('/\.cs$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'cs'; $famime = 'file-code-o'; }
if (preg_match('/\.(h)$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'h'; $famime = 'file-code-o'; }
if (preg_match('/\.(java|jsp)$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'java'; $famime = 'file-code-o'; }
if (preg_match('/\.php([0-9]{1})?$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'php.png'; $srclang = 'php'; $famime = 'file-code-o'; }
@@ -8568,6 +8653,160 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u
return $button;
}
+/**
+ * Get an array with properties of an element.
+ * Called by fetchObjectByElement.
+ *
+ * @param string $element_type Element type (Value of $object->element). Example: 'action', 'facture', 'project_task' or 'object@mymodule'...
+ * @return array (module, classpath, element, subelement, classfile, classname)
+ */
+function getElementProperties($element_type)
+{
+ $regs = array();
+
+ $classfile = $classname = $classpath = '';
+
+ // Parse element/subelement (ex: project_task)
+ $module = $element_type;
+ $element = $element_type;
+ $subelement = $element_type;
+
+ // If we ask an resource form external module (instead of default path)
+ if (preg_match('/^([^@]+)@([^@]+)$/i', $element_type, $regs)) {
+ $element = $subelement = $regs[1];
+ $module = $regs[2];
+ }
+
+ //print ' 1. element : '.$element.' - module : '.$module .' ';
+ if (preg_match('/^([^_]+)_([^_]+)/i', $element, $regs)) {
+ $module = $element = $regs[1];
+ $subelement = $regs[2];
+ }
+
+ // For compat
+ if ($element_type == "action") {
+ $classpath = 'comm/action/class';
+ $subelement = 'Actioncomm';
+ $module = 'agenda';
+ }
+
+ // To work with non standard path
+ if ($element_type == 'facture' || $element_type == 'invoice') {
+ $classpath = 'compta/facture/class';
+ $module = 'facture';
+ $subelement = 'facture';
+ }
+ if ($element_type == 'commande' || $element_type == 'order') {
+ $classpath = 'commande/class';
+ $module = 'commande';
+ $subelement = 'commande';
+ }
+ if ($element_type == 'propal') {
+ $classpath = 'comm/propal/class';
+ }
+ if ($element_type == 'supplier_proposal') {
+ $classpath = 'supplier_proposal/class';
+ }
+ if ($element_type == 'shipping') {
+ $classpath = 'expedition/class';
+ $subelement = 'expedition';
+ $module = 'expedition_bon';
+ }
+ if ($element_type == 'delivery') {
+ $classpath = 'livraison/class';
+ $subelement = 'livraison';
+ $module = 'livraison_bon';
+ }
+ if ($element_type == 'contract') {
+ $classpath = 'contrat/class';
+ $module = 'contrat';
+ $subelement = 'contrat';
+ }
+ if ($element_type == 'member') {
+ $classpath = 'adherents/class';
+ $module = 'adherent';
+ $subelement = 'adherent';
+ }
+ if ($element_type == 'cabinetmed_cons') {
+ $classpath = 'cabinetmed/class';
+ $module = 'cabinetmed';
+ $subelement = 'cabinetmedcons';
+ }
+ if ($element_type == 'fichinter') {
+ $classpath = 'fichinter/class';
+ $module = 'ficheinter';
+ $subelement = 'fichinter';
+ }
+ if ($element_type == 'dolresource' || $element_type == 'resource') {
+ $classpath = 'resource/class';
+ $module = 'resource';
+ $subelement = 'dolresource';
+ }
+ if ($element_type == 'propaldet') {
+ $classpath = 'comm/propal/class';
+ $module = 'propal';
+ $subelement = 'propaleligne';
+ }
+ if ($element_type == 'order_supplier') {
+ $classpath = 'fourn/class';
+ $module = 'fournisseur';
+ $subelement = 'commandefournisseur';
+ $classfile = 'fournisseur.commande';
+ }
+ if ($element_type == 'invoice_supplier') {
+ $classpath = 'fourn/class';
+ $module = 'fournisseur';
+ $subelement = 'facturefournisseur';
+ $classfile = 'fournisseur.facture';
+ }
+ if ($element_type == "service") {
+ $classpath = 'product/class';
+ $subelement = 'product';
+ }
+
+ if (empty($classfile)) $classfile = strtolower($subelement);
+ if (empty($classname)) $classname = ucfirst($subelement);
+ if (empty($classpath)) $classpath = $module.'/class';
+
+ $element_properties = array(
+ 'module' => $module,
+ 'classpath' => $classpath,
+ 'element' => $element,
+ 'subelement' => $subelement,
+ 'classfile' => $classfile,
+ 'classname' => $classname
+ );
+ return $element_properties;
+}
+
+/**
+ * Fetch an object from its id and element_type
+ * Inclusion of classes is automatic
+ *
+ * @param int $element_id Element id
+ * @param string $element_type Element type
+ * @param string $element_ref Element ref (Use this or element_id but not both)
+ * @return int|object object || 0 || -1 if error
+ */
+function fetchObjectByElement($element_id, $element_type, $element_ref = '')
+{
+ global $conf, $db;
+
+ $element_prop = getElementProperties($element_type);
+ if (is_array($element_prop) && $conf->{$element_prop['module']}->enabled)
+ {
+ dol_include_once('/'.$element_prop['classpath'].'/'.$element_prop['classfile'].'.class.php');
+
+ $objecttmp = new $element_prop['classname']($db);
+ $ret = $objecttmp->fetch($element_id, $element_ref);
+ if ($ret >= 0)
+ {
+ return $objecttmp;
+ }
+ }
+ return 0;
+}
+
/**
* Return if a file can contains executable content
*
diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php
index 98d636e97dd..531e0fe242c 100644
--- a/htdocs/core/lib/functions2.lib.php
+++ b/htdocs/core/lib/functions2.lib.php
@@ -2058,157 +2058,6 @@ function cleanCorruptedTree($db, $tabletocleantree, $fieldfkparent)
}
}
-/**
- * Get an array with properties of an element
- *
- * @param string $element_type Element type: 'action', 'facture', 'project_task' or 'object@mymodule'...
- * @return array (module, classpath, element, subelement, classfile, classname)
- */
-function getElementProperties($element_type)
-{
- $regs = array();
-
- // Parse element/subelement (ex: project_task)
- $module = $element_type;
- $element = $element_type;
- $subelement = $element_type;
-
- // If we ask an resource form external module (instead of default path)
- if (preg_match('/^([^@]+)@([^@]+)$/i', $element_type, $regs)) {
- $element = $subelement = $regs[1];
- $module = $regs[2];
- }
-
- //print ' 1. element : '.$element.' - module : '.$module .' ';
- if (preg_match('/^([^_]+)_([^_]+)/i', $element, $regs)) {
- $module = $element = $regs[1];
- $subelement = $regs[2];
- }
-
- // For compat
- if ($element_type == "action") {
- $classpath = 'comm/action/class';
- $subelement = 'Actioncomm';
- $module = 'agenda';
- }
-
- // To work with non standard path
- if ($element_type == 'facture' || $element_type == 'invoice') {
- $classpath = 'compta/facture/class';
- $module = 'facture';
- $subelement = 'facture';
- }
- if ($element_type == 'commande' || $element_type == 'order') {
- $classpath = 'commande/class';
- $module = 'commande';
- $subelement = 'commande';
- }
- if ($element_type == 'propal') {
- $classpath = 'comm/propal/class';
- }
- if ($element_type == 'supplier_proposal') {
- $classpath = 'supplier_proposal/class';
- }
- if ($element_type == 'shipping') {
- $classpath = 'expedition/class';
- $subelement = 'expedition';
- $module = 'expedition_bon';
- }
- if ($element_type == 'delivery') {
- $classpath = 'livraison/class';
- $subelement = 'livraison';
- $module = 'livraison_bon';
- }
- if ($element_type == 'contract') {
- $classpath = 'contrat/class';
- $module = 'contrat';
- $subelement = 'contrat';
- }
- if ($element_type == 'member') {
- $classpath = 'adherents/class';
- $module = 'adherent';
- $subelement = 'adherent';
- }
- if ($element_type == 'cabinetmed_cons') {
- $classpath = 'cabinetmed/class';
- $module = 'cabinetmed';
- $subelement = 'cabinetmedcons';
- }
- if ($element_type == 'fichinter') {
- $classpath = 'fichinter/class';
- $module = 'ficheinter';
- $subelement = 'fichinter';
- }
- if ($element_type == 'dolresource' || $element_type == 'resource') {
- $classpath = 'resource/class';
- $module = 'resource';
- $subelement = 'dolresource';
- }
- if ($element_type == 'propaldet') {
- $classpath = 'comm/propal/class';
- $module = 'propal';
- $subelement = 'propaleligne';
- }
- if ($element_type == 'order_supplier') {
- $classpath = 'fourn/class';
- $module = 'fournisseur';
- $subelement = 'commandefournisseur';
- $classfile = 'fournisseur.commande';
- }
- if ($element_type == 'invoice_supplier') {
- $classpath = 'fourn/class';
- $module = 'fournisseur';
- $subelement = 'facturefournisseur';
- $classfile = 'fournisseur.facture';
- }
- if ($element_type == "service") {
- $classpath = 'product/class';
- $subelement = 'product';
- }
-
- if (!isset($classfile)) $classfile = strtolower($subelement);
- if (!isset($classname)) $classname = ucfirst($subelement);
- if (!isset($classpath)) $classpath = $module.'/class';
-
- $element_properties = array(
- 'module' => $module,
- 'classpath' => $classpath,
- 'element' => $element,
- 'subelement' => $subelement,
- 'classfile' => $classfile,
- 'classname' => $classname
- );
- return $element_properties;
-}
-
-/**
- * Fetch an object from its id and element_type
- * Inclusion of classes is automatic
- *
- * @param int $element_id Element id
- * @param string $element_type Element type
- * @param string $element_ref Element ref (Use this or element_id but not both)
- * @return int|object object || 0 || -1 if error
- */
-function fetchObjectByElement($element_id, $element_type, $element_ref = '')
-{
- global $conf, $db;
-
- $element_prop = getElementProperties($element_type);
- if (is_array($element_prop) && $conf->{$element_prop['module']}->enabled)
- {
- dol_include_once('/'.$element_prop['classpath'].'/'.$element_prop['classfile'].'.class.php');
-
- $objecttmp = new $element_prop['classname']($db);
- $ret = $objecttmp->fetch($element_id, $element_ref);
- if ($ret >= 0)
- {
- return $objecttmp;
- }
- }
- return 0;
-}
-
/**
* Convert an array with RGB value into hex RGB value.
@@ -2377,7 +2226,7 @@ function colorLighten($hex, $percent)
/**
* @param string $hex color in hex
* @param float $alpha 0 to 1 to add alpha channel
- * @param bool $returnArray Array set to 1 to return an array instead of string
+ * @param bool $returnArray true=return an array instead, false=return string
* @return string|array String or array
*/
function colorHexToRgb($hex, $alpha = false, $returnArray = false)
diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
index e7538725bc2..e097c6d7120 100644
--- a/htdocs/core/lib/pdf.lib.php
+++ b/htdocs/core/lib/pdf.lib.php
@@ -348,7 +348,7 @@ function pdfBuildThirdpartyName($thirdparty, Translate $outputlangs, $includeali
if ($thirdparty instanceof Societe) {
$socname .= $thirdparty->name;
if (($includealias || !empty($conf->global->PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME)) && !empty($thirdparty->name_alias)) {
- $socname .= "\n".$thirdparty->name_alias;
+ $socname .= " - ".$thirdparty->name_alias;
}
} elseif ($thirdparty instanceof Contact) {
$socname = $thirdparty->socname;
@@ -386,7 +386,7 @@ function pdf_build_address($outputlangs, $sourcecompany, $targetcompany = '', $t
$stringaddress = '';
if (is_object($hookmanager))
{
- $parameters = array('sourcecompany'=>&$sourcecompany, 'targetcompany'=>&$targetcompany, 'targetcontact'=>&$targetcontact, 'outputlangs'=>$outputlangs, 'mode'=>$mode, 'usecontact'=>$usecontact);
+ $parameters = array('sourcecompany' => &$sourcecompany, 'targetcompany' => &$targetcompany, 'targetcontact' => &$targetcontact, 'outputlangs' => $outputlangs, 'mode' => $mode, 'usecontact' => $usecontact);
$action = '';
$reshook = $hookmanager->executeHooks('pdf_build_address', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
$stringaddress .= $hookmanager->resPrint;
@@ -1401,7 +1401,7 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0,
foreach ($tblcateg as $cate)
{
// Adding the descriptions if they are filled
- $desccateg = $cate->add_description;
+ $desccateg = $cate->description;
if ($desccateg)
$libelleproduitservice .= '__N__'.$desccateg;
}
diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php
index 9cf28ff20ee..79d77e0268f 100644
--- a/htdocs/core/lib/product.lib.php
+++ b/htdocs/core/lib/product.lib.php
@@ -76,13 +76,13 @@ function product_prepare_head($object)
}
// Sub products
- if (! empty($conf->global->PRODUIT_SOUSPRODUITS))
+ if (!empty($conf->global->PRODUIT_SOUSPRODUITS))
{
$head[$h][0] = DOL_URL_ROOT."/product/composition/card.php?id=".$object->id;
$head[$h][1] = $langs->trans('AssociatedProducts');
$nbFatherAndChild = $object->hasFatherOrChild();
- if ($nbFatherAndChild > 0) $head[$h][1].= ''.$nbFatherAndChild.' ';
+ if ($nbFatherAndChild > 0) $head[$h][1] .= ''.$nbFatherAndChild.' ';
$head[$h][2] = 'subproduct';
$h++;
}
@@ -110,15 +110,15 @@ function product_prepare_head($object)
$head[$h][1] = $langs->trans('ProductCombinations');
$head[$h][2] = 'combinations';
$nbVariant = $prodcomb->countNbOfCombinationForFkProductParent($object->id);
- if ($nbVariant > 0) $head[$h][1].= ''.$nbVariant.' ';
+ if ($nbVariant > 0) $head[$h][1] .= ''.$nbVariant.' ';
}
$h++;
}
- if ($object->isProduct() || ($object->isService() && ! empty($conf->global->STOCK_SUPPORTS_SERVICES))) // If physical product we can stock (or service with option)
+ if ($object->isProduct() || ($object->isService() && !empty($conf->global->STOCK_SUPPORTS_SERVICES))) // If physical product we can stock (or service with option)
{
- if (! empty($conf->stock->enabled) && $user->rights->stock->lire)
+ if (!empty($conf->stock->enabled) && $user->rights->stock->lire)
{
$head[$h][0] = DOL_URL_ROOT."/product/stock/product.php?id=".$object->id;
$head[$h][1] = $langs->trans("Stock");
@@ -156,11 +156,11 @@ function product_prepare_head($object)
if (empty($conf->global->MAIN_DISABLE_NOTES_TAB))
{
$nbNote = 0;
- if(!empty($object->note_private)) $nbNote++;
- if(!empty($object->note_public)) $nbNote++;
+ if (!empty($object->note_private)) $nbNote++;
+ if (!empty($object->note_public)) $nbNote++;
$head[$h][0] = DOL_URL_ROOT.'/product/note.php?id='.$object->id;
$head[$h][1] = $langs->trans('Notes');
- if ($nbNote > 0) $head[$h][1].= ''.$nbNote.' ';
+ if ($nbNote > 0) $head[$h][1] .= ''.$nbNote.' ';
$head[$h][2] = 'note';
$h++;
}
@@ -168,18 +168,18 @@ function product_prepare_head($object)
// Attachments
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
- if (! empty($conf->product->enabled) && ($object->type==Product::TYPE_PRODUCT)) $upload_dir = $conf->product->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref);
- if (! empty($conf->service->enabled) && ($object->type==Product::TYPE_SERVICE)) $upload_dir = $conf->service->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref);
+ if (!empty($conf->product->enabled) && ($object->type == Product::TYPE_PRODUCT)) $upload_dir = $conf->product->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref);
+ if (!empty($conf->service->enabled) && ($object->type == Product::TYPE_SERVICE)) $upload_dir = $conf->service->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref);
$nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
- if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) {
- if (! empty($conf->product->enabled) && ($object->type==Product::TYPE_PRODUCT)) $upload_dir = $conf->product->multidir_output[$object->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'product').$object->id.'/photos';
- if (! empty($conf->service->enabled) && ($object->type==Product::TYPE_SERVICE)) $upload_dir = $conf->service->multidir_output[$object->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'product').$object->id.'/photos';
+ if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) {
+ if (!empty($conf->product->enabled) && ($object->type == Product::TYPE_PRODUCT)) $upload_dir = $conf->product->multidir_output[$object->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'product').$object->id.'/photos';
+ if (!empty($conf->service->enabled) && ($object->type == Product::TYPE_SERVICE)) $upload_dir = $conf->service->multidir_output[$object->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'product').$object->id.'/photos';
$nbFiles += count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
}
- $nbLinks=Link::count($db, $object->element, $object->id);
+ $nbLinks = Link::count($db, $object->element, $object->id);
$head[$h][0] = DOL_URL_ROOT.'/product/document.php?id='.$object->id;
$head[$h][1] = $langs->trans('Documents');
- if (($nbFiles+$nbLinks) > 0) $head[$h][1].= ''.($nbFiles+$nbLinks).' ';
+ if (($nbFiles + $nbLinks) > 0) $head[$h][1] .= ''.($nbFiles + $nbLinks).' ';
$head[$h][2] = 'documents';
$h++;
@@ -225,10 +225,10 @@ function productlot_prepare_head($object)
require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
$upload_dir = $conf->productbatch->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref);
$nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
- $nbLinks=Link::count($db, $object->element, $object->id);
+ $nbLinks = Link::count($db, $object->element, $object->id);
$head[$h][0] = DOL_URL_ROOT."/product/stock/productlot_document.php?id=".$object->id;
$head[$h][1] = $langs->trans("Documents");
- if (($nbFiles+$nbLinks) > 0) $head[$h][1].= ''.($nbFiles+$nbLinks).' ';
+ if (($nbFiles + $nbLinks) > 0) $head[$h][1] .= ''.($nbFiles + $nbLinks).' ';
$head[$h][2] = 'documents';
$h++;
@@ -425,6 +425,24 @@ function show_stats_for_company($product, $socid)
print '';
print '';
}
+ // MO
+ if (!empty($conf->mrp->enabled) && $user->rights->mrp->read)
+ {
+ $nblines++;
+ //$ret = $product->load_stats_mo($socid);
+ if ($ret < 0) dol_print_error($db);
+ $langs->load("orders");
+ print '';
+ print ''.img_object('', 'mrp').' '.$langs->trans("MO").' ';
+ print ' ';
+ print $product->stats_mo['suppliers'];
+ print ' ';
+ print $product->stats_mo['nb'];
+ print ' ';
+ print $product->stats_mo['qty'];
+ print ' ';
+ print ' ';
+ }
// Customer invoices
if (!empty($conf->facture->enabled) && $user->rights->facture->lire)
{
@@ -504,7 +522,7 @@ function measuring_units_string($scale = '', $measuring_style = '', $unit = 0, $
* Return translation label of a unit key
*
* @param int $unit ID of unit (rowid in llx_c_units table)
- * @param string $measuring_style Style of unit: weight, volume,...
+ * @param string $measuring_style Style of unit: 'weight', 'volume', ..., '' = 'net_measure' for option PRODUCT_ADD_NET_MEASURE
* @param string $scale Scale of unit: '0', '-3', '6', ...
* @param int $use_short_label 1=Use short label ('g' instead of 'gram'). Short labels are not translated.
* @return string Unit string
@@ -518,9 +536,16 @@ function measuringUnitString($unit, $measuring_style = '', $scale = '', $use_sho
if (empty($measuring_unit_cache[$unit.'_'.$measuring_style.'_'.$scale.'_'.$use_short_label]))
{
require_once DOL_DOCUMENT_ROOT.'/core/class/cunits.class.php';
- $measuringUnits= new CUnits($db);
+ $measuringUnits = new CUnits($db);
- if ($scale !== '')
+ if ($measuring_style == '' && $scale == '')
+ {
+ $arrayforfilter = array(
+ 't.rowid' => $unit,
+ 't.active' => 1
+ );
+ }
+ elseif ($scale !== '')
{
$arrayforfilter = array(
't.scale' => $scale,
diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php
index 16e78d24414..ee80a525f04 100644
--- a/htdocs/core/lib/project.lib.php
+++ b/htdocs/core/lib/project.lib.php
@@ -265,7 +265,7 @@ function project_timesheet_prepare_head($mode, $fuser = null)
if (empty($conf->global->PROJECT_DISABLE_TIMESHEET_PERMONTH))
{
- $head[$h][0] = DOL_URL_ROOT."/projet/activity/permonth.php".($param?'?'.$param:'');
+ $head[$h][0] = DOL_URL_ROOT."/projet/activity/permonth.php".($param ? '?'.$param : '');
$head[$h][1] = $langs->trans("InputPerMonth");
$head[$h][2] = 'inputpermonth';
$h++;
@@ -1735,19 +1735,19 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
global $conf, $db, $user, $bc, $langs;
global $form, $formother, $projectstatic, $taskstatic, $thirdpartystatic;
- $numlines=count($lines);
+ $numlines = count($lines);
- $lastprojectid=0;
- $workloadforid=array();
- $totalforeachweek=array();
- $lineswithoutlevel0=array();
+ $lastprojectid = 0;
+ $workloadforid = array();
+ $totalforeachweek = array();
+ $lineswithoutlevel0 = array();
// Create a smaller array with sublevels only to be used later. This increase dramatically performances.
if ($parent == 0) // Always and only if at first level
{
- for ($i = 0 ; $i < $numlines ; $i++)
+ for ($i = 0; $i < $numlines; $i++)
{
- if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i];
+ if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[] = $lines[$i];
}
}
@@ -1755,24 +1755,24 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
if (empty($oldprojectforbreak))
{
- $oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)?0:-1); // 0 = start break, -1 = never break
+ $oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT) ? 0 : -1); // 0 = start break, -1 = never break
}
- for ($i = 0 ; $i < $numlines ; $i++)
+ for ($i = 0; $i < $numlines; $i++)
{
if ($parent == 0) $level = 0;
if ($lines[$i]->fk_task_parent == $parent)
{
// If we want all or we have a role on task, we show it
- if (empty($mine) || ! empty($tasksrole[$lines[$i]->id]))
+ if (empty($mine) || !empty($tasksrole[$lines[$i]->id]))
{
//dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project);
// Break on a new project
if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid)
{
- $lastprojectid=$lines[$i]->fk_project;
+ $lastprojectid = $lines[$i]->fk_project;
$projectstatic->id = $lines[$i]->fk_project;
}
@@ -1780,32 +1780,32 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
//var_dump($projectstatic->weekWorkLoadPerTask);
if (empty($workloadforid[$projectstatic->id]))
{
- $projectstatic->loadTimeSpentMonth($firstdaytoshow, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week
- $workloadforid[$projectstatic->id]=1;
+ $projectstatic->loadTimeSpentMonth($firstdaytoshow, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week
+ $workloadforid[$projectstatic->id] = 1;
}
//var_dump($projectstatic->weekWorkLoadPerTask);
//var_dump('--- '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]);
- $projectstatic->id=$lines[$i]->fk_project;
- $projectstatic->ref=$lines[$i]->projectref;
- $projectstatic->title=$lines[$i]->projectlabel;
- $projectstatic->public=$lines[$i]->public;
- $projectstatic->thirdparty_name=$lines[$i]->thirdparty_name;
+ $projectstatic->id = $lines[$i]->fk_project;
+ $projectstatic->ref = $lines[$i]->projectref;
+ $projectstatic->title = $lines[$i]->projectlabel;
+ $projectstatic->public = $lines[$i]->public;
+ $projectstatic->thirdparty_name = $lines[$i]->thirdparty_name;
- $taskstatic->id=$lines[$i]->id;
- $taskstatic->ref=($lines[$i]->ref?$lines[$i]->ref:$lines[$i]->id);
- $taskstatic->label=$lines[$i]->label;
- $taskstatic->date_start=$lines[$i]->date_start;
- $taskstatic->date_end=$lines[$i]->date_end;
+ $taskstatic->id = $lines[$i]->id;
+ $taskstatic->ref = ($lines[$i]->ref ? $lines[$i]->ref : $lines[$i]->id);
+ $taskstatic->label = $lines[$i]->label;
+ $taskstatic->date_start = $lines[$i]->date_start;
+ $taskstatic->date_end = $lines[$i]->date_end;
- $thirdpartystatic->id=$lines[$i]->thirdparty_id;
- $thirdpartystatic->name=$lines[$i]->thirdparty_name;
- $thirdpartystatic->email=$lines[$i]->thirdparty_email;
+ $thirdpartystatic->id = $lines[$i]->thirdparty_id;
+ $thirdpartystatic->name = $lines[$i]->thirdparty_name;
+ $thirdpartystatic->email = $lines[$i]->thirdparty_email;
if (empty($oldprojectforbreak) || ($oldprojectforbreak != -1 && $oldprojectforbreak != $projectstatic->id))
{
print ''."\n";
- print '';
+ print ' ';
print $projectstatic->getNomUrl(1, '', 0, ''.$langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]);
if ($thirdpartystatic->id > 0) print ' - '.$thirdpartystatic->getNomUrl(1);
if ($projectstatic->title)
@@ -1840,11 +1840,11 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
// Ref
print ' ';
print '';
- for ($k = 0 ; $k < $level ; $k++) print " ";
+ for ($k = 0; $k < $level; $k++) print " ";
print $taskstatic->getNomUrl(1, 'withproject', 'time');
// Label task
print ' ';
- for ($k = 0 ; $k < $level ; $k++) print " ";
+ for ($k = 0; $k < $level; $k++) print " ";
//print $taskstatic->getNomUrl(0, 'withproject', 'time');
print $taskstatic->label;
//print " ";
@@ -1860,7 +1860,7 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
// Progress declared %
print ' ';
- print $formother->select_percent($lines[$i]->progress, $lines[$i]->id . 'progress');
+ print $formother->select_percent($lines[$i]->progress, $lines[$i]->id.'progress');
print ' ';
// Time spent by everybody
@@ -1877,66 +1877,66 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
// Time spent by user
print '';
- $tmptimespent=$taskstatic->getSummaryOfTimeSpent($fuser->id);
+ $tmptimespent = $taskstatic->getSummaryOfTimeSpent($fuser->id);
if ($tmptimespent['total_duration']) print convertSecondToTime($tmptimespent['total_duration'], 'allhourmin');
else print '--:--';
print " \n";
- $disabledproject=1;$disabledtask=1;
+ $disabledproject = 1; $disabledtask = 1;
//print "x".$lines[$i]->fk_project;
//var_dump($lines[$i]);
//var_dump($projectsrole[$lines[$i]->fk_project]);
// If at least one role for project
- if ($lines[$i]->public || ! empty($projectsrole[$lines[$i]->fk_project]) || $user->rights->projet->all->creer)
+ if ($lines[$i]->public || !empty($projectsrole[$lines[$i]->fk_project]) || $user->rights->projet->all->creer)
{
- $disabledproject=0;
- $disabledtask=0;
+ $disabledproject = 0;
+ $disabledtask = 0;
}
// If $restricteditformytask is on and I have no role on task, i disable edit
if ($restricteditformytask && empty($tasksrole[$lines[$i]->id]))
{
- $disabledtask=1;
+ $disabledtask = 1;
}
//var_dump($projectstatic->weekWorkLoadPerTask);
//TODO
// Fields to show current time
- $tableCell=''; $modeinput='hours';
+ $tableCell = ''; $modeinput = 'hours';
$TFirstDay = getFirstDayOfEachWeek($TWeek, date('Y', $firstdaytoshow));
$TFirstDay[reset($TWeek)] = 1;
- foreach($TFirstDay as &$fday) {
+ foreach ($TFirstDay as &$fday) {
$fday--;
}
foreach ($TWeek as $weekNb)
{
$weekWorkLoad = $projectstatic->monthWorkLoadPerTask[$weekNb][$lines[$i]->id];
- $totalforeachweek[$weekNb]+=$weekWorkLoad;
+ $totalforeachweek[$weekNb] += $weekWorkLoad;
- $alreadyspent='';
- if ($weekWorkLoad > 0) $alreadyspent=convertSecondToTime($weekWorkLoad, 'allhourmin');
- $alttitle=$langs->trans("AddHereTimeSpentForWeek", $weekNb);
+ $alreadyspent = '';
+ if ($weekWorkLoad > 0) $alreadyspent = convertSecondToTime($weekWorkLoad, 'allhourmin');
+ $alttitle = $langs->trans("AddHereTimeSpentForWeek", $weekNb);
- $tableCell ='';
- $placeholder='';
+ $tableCell = ' ';
+ $placeholder = '';
if ($alreadyspent)
{
- $tableCell.=' ';
+ $tableCell .= ' ';
//$placeholder=' placeholder="00:00"';
//$tableCell.='+';
}
- $tableCell.=' ';
- $tableCell.=' ';
+ $tableCell .= ' ';
+ $tableCell .= '';
print $tableCell;
}
// Warning
print '';
- if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('', $langs->trans("UserIsNotContactOfProject"));
+ if ((!$lines[$i]->public) && $disabledproject) print $form->textwithpicto('', $langs->trans("UserIsNotContactOfProject"));
elseif ($disabledtask)
{
$titleassigntask = $langs->trans("AssignTaskToMe");
@@ -1959,9 +1959,9 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
$ret = projectLinesPerMonth($inc, $firstdaytoshow, $fuser, $lines[$i]->id, ($parent == 0 ? $lineswithoutlevel0 : $lines), $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable, $oldprojectforbreak, $TWeek);
//var_dump('ret with parent='.$lines[$i]->id.' level='.$level);
//var_dump($ret);
- foreach($ret as $key => $val)
+ foreach ($ret as $key => $val)
{
- $totalforeachweek[$key]+=$val;
+ $totalforeachweek[$key] += $val;
}
//var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level.' + subtasks');
//var_dump($totalforeachday);
@@ -2030,9 +2030,26 @@ function searchTaskInChild(&$inc, $parent, &$lines, &$taskrole)
function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks = 0, $status = -1, $listofoppstatus = array(), $hiddenfields = array())
{
global $langs, $conf, $user, $bc;
+ global $theme_datacolor;
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
+ $listofstatus = array_keys($listofoppstatus);
+
+ if (is_array($listofstatus) && ! empty($conf->global->USE_COLOR_FOR_PROSPECTION_STATUS)) {
+ // Define $themeColorId and array $statusOppList for each $listofstatus
+ $themeColorId = 0;
+ $statusOppList = array();
+ foreach ($listofstatus as $oppStatus) {
+ $oppStatusCode = dol_getIdFromCode($db, $oppStatus, 'c_lead_status', 'rowid', 'code');
+ if ($oppStatusCode) {
+ $statusOppList[$oppStatus]['code'] = $oppStatusCode;
+ $statusOppList[$oppStatus]['color'] = isset($theme_datacolor[$themeColorId]) ? implode(', ', $theme_datacolor[$themeColorId]) : '';
+ }
+ $themeColorId++;
+ }
+ }
+
$projectstatic = new Project($db);
$thirdpartystatic = new Societe($db);
@@ -2109,14 +2126,14 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks
if (empty($arrayidofprojects)) $arrayidofprojects[0] = -1;
// Get list of project with calculation on tasks
- $sql2 = "SELECT p.rowid as projectid, p.ref, p.title, p.fk_soc, s.nom as socname, p.fk_user_creat, p.public, p.fk_statut as status, p.fk_opp_status as opp_status, p.opp_amount,";
+ $sql2 = "SELECT p.rowid as projectid, p.ref, p.title, p.fk_soc, s.nom as socname, p.fk_user_creat, p.public, p.fk_statut as status, p.fk_opp_status as opp_status, p.opp_percent, p.opp_amount,";
$sql2 .= " p.dateo, p.datee,";
$sql2 .= " COUNT(t.rowid) as nb, SUM(t.planned_workload) as planned_workload, SUM(t.planned_workload * t.progress / 100) as declared_progess_workload";
$sql2 .= " FROM ".MAIN_DB_PREFIX."projet as p";
$sql2 .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = p.fk_soc";
$sql2 .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t ON p.rowid = t.fk_projet";
$sql2 .= " WHERE p.rowid IN (".join(',', $arrayidofprojects).")";
- $sql2 .= " GROUP BY p.rowid, p.ref, p.title, p.fk_soc, s.nom, p.fk_user_creat, p.public, p.fk_statut, p.fk_opp_status, p.opp_amount, p.dateo, p.datee";
+ $sql2 .= " GROUP BY p.rowid, p.ref, p.title, p.fk_soc, s.nom, p.fk_user_creat, p.public, p.fk_statut, p.fk_opp_status, p.opp_percent, p.opp_amount, p.dateo, p.datee";
$sql2 .= " ORDER BY p.title, p.ref";
$resql = $db->query($sql2);
@@ -2134,16 +2151,17 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks
print_liste_field_titre("ThirdParty", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES))
{
+ if (!in_array('prospectionstatus', $hiddenfields)) print_liste_field_titre("OpportunityStatus", "", "", "", "", '', $sortfield, $sortorder, 'right ');
print_liste_field_titre("OpportunityAmount", "", "", "", "", 'align="right"', $sortfield, $sortorder);
- print_liste_field_titre("OpportunityStatus", "", "", "", "", 'align="right"', $sortfield, $sortorder);
+ print_liste_field_titre('OpportunityWeightedAmount', '', '', '', '', 'align="right"', $sortfield, $sortorder);
}
if (empty($conf->global->PROJECT_HIDE_TASKS))
{
print_liste_field_titre("Tasks", "", "", "", "", 'align="right"', $sortfield, $sortorder);
- if (!in_array('plannedworkload', $hiddenfields)) print_liste_field_titre("PlannedWorkload", "", "", "", "", 'align="right"', $sortfield, $sortorder);
- if (!in_array('declaredprogress', $hiddenfields)) print_liste_field_titre("ProgressDeclared", "", "", "", "", 'align="right"', $sortfield, $sortorder);
+ if (!in_array('plannedworkload', $hiddenfields)) print_liste_field_titre("PlannedWorkload", "", "", "", "", '', $sortfield, $sortorder, 'right ');
+ if (!in_array('declaredprogress', $hiddenfields)) print_liste_field_titre("ProgressDeclared", "", "", "", "", '', $sortfield, $sortorder, 'right ');
}
- print_liste_field_titre("Status", "", "", "", "", 'align="right"', $sortfield, $sortorder);
+ if (!in_array('projectstatus', $hiddenfields)) print_liste_field_titre("Status", "", "", "", "", '', $sortfield, $sortorder, 'right ');
print " \n";
$total_plannedworkload = 0;
@@ -2161,16 +2179,17 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks
if ($userAccess >= 0)
{
$projectstatic->ref = $objp->ref;
- $projectstatic->statut = $objp->status;
+ $projectstatic->statut = $objp->status; // deprecated
+ $projectstatic->status = $objp->status;
$projectstatic->title = $objp->title;
$projectstatic->datee = $db->jdate($objp->datee);
$projectstatic->dateo = $db->jdate($objp->dateo);
-
print '';
+
print '';
print $projectstatic->getNomUrl(1);
- if (!in_array('projectlabel', $hiddenfields)) print ' '.dol_trunc($objp->title, 24);
+ if (!in_array('projectlabel', $hiddenfields)) print ''.dol_trunc($objp->title, 24).' ';
print ' ';
print '';
if ($objp->fk_soc > 0)
@@ -2181,16 +2200,48 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks
print $thirdpartystatic->getNomUrl(1);
}
print ' ';
+
if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES))
{
+ if (!in_array('prospectionstatus', $hiddenfields)) {
+ print '';
+ // Because color of prospection status has no meaning yet, it is used if hidden constant is set
+ if (empty($conf->global->USE_COLOR_FOR_PROSPECTION_STATUS)) {
+ $oppStatusCode = dol_getIdFromCode($db, $objp->opp_status, 'c_lead_status', 'rowid', 'code');
+ if ($langs->trans("OppStatus".$oppStatusCode) != "OppStatus".$oppStatusCode) {
+ print $langs->trans("OppStatus".$oppStatusCode);
+ }
+ } else {
+ if (isset($statusOppList[$objp->opp_status])) {
+ $oppStatusCode = $statusOppList[$objp->opp_status]['code'];
+ $oppStatusColor = $statusOppList[$objp->opp_status]['color'];
+ } else {
+ $oppStatusCode = dol_getIdFromCode($db, $objp->opp_status, 'c_lead_status', 'rowid', 'code');
+ $oppStatusColor = '';
+ }
+ if ($oppStatusCode) {
+ if (!empty($oppStatusColor)) {
+ print ' ';
+ } else {
+ print ''.$oppStatusCode.' ';
+ }
+ }
+ }
+ print ' ';
+ }
+
print '';
if ($objp->opp_amount) print price($objp->opp_amount, 0, '', 1, -1, -1, $conf->currency);
print ' ';
print '';
- $code = dol_getIdFromCode($db, $objp->opp_status, 'c_lead_status', 'rowid', 'code');
- if ($code) print $langs->trans("OppStatus".$code);
+ if ($objp->opp_percent && $objp->opp_amount) {
+ $opp_weighted_amount = $objp->opp_percent * $objp->opp_amount / 100;
+ print price($opp_weighted_amount, 0, '', 1, -1, -1, $conf->currency);
+ $ponderated_opp_amount += price2num($opp_weighted_amount);
+ }
print ' ';
}
+
if (empty($conf->global->PROJECT_HIDE_TASKS))
{
print ''.$objp->nb.' ';
@@ -2212,12 +2263,16 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks
}
}
- print ''.$projectstatic->getLibStatut(3).' ';
+ if (!in_array('projectstatus', $hiddenfields)) {
+ print '';
+ print $projectstatic->getLibStatut(3);
+ print ' ';
+ }
+
print " \n";
$total_task = $total_task + $objp->nb;
$total_opp_amount = $total_opp_amount + $objp->opp_amount;
- $ponderated_opp_amount = $ponderated_opp_amount + price2num($listofoppstatus[$objp->opp_status] * $objp->opp_amount / 100);
}
$i++;
@@ -2227,6 +2282,9 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks
print ''.$langs->trans("Total")." ";
if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES))
{
+ if (!in_array('prospectionstatus', $hiddenfields)) {
+ print ' ';
+ }
print ''.price($total_opp_amount, 0, '', 1, -1, -1, $conf->currency).' ';
print ''.$form->textwithpicto(price($ponderated_opp_amount, 0, '', 1, -1, -1, $conf->currency), $langs->trans("OpportunityPonderatedAmountDesc"), 1).' ';
}
@@ -2236,7 +2294,9 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks
if (!in_array('plannedworkload', $hiddenfields)) print ''.($total_plannedworkload ?convertSecondToTime($total_plannedworkload) : '').' ';
if (!in_array('declaredprogress', $hiddenfields)) print ''.($total_plannedworkload ?round(100 * $total_declaredprogressworkload / $total_plannedworkload, 0).'%' : '').' ';
}
- print ' ';
+ if (!in_array('projectstatus', $hiddenfields)) {
+ print ' ';
+ }
print '';
$db->free($resql);
@@ -2400,7 +2460,7 @@ function getTaskProgressView($task, $label = true, $progressNumber = true, $hide
*/
function getTaskProgressBadge($task, $label = '', $tooltip = '')
{
- global $conf;
+ global $conf, $langs;
$out = '';
$badgeClass = '';
@@ -2418,12 +2478,15 @@ function getTaskProgressBadge($task, $label = '', $tooltip = '')
if (doubleval($progressCalculated) > doubleval($task->progress * $warningRatio)) {
$badgeClass .= 'badge-danger';
+ if (empty($tooltip)) $tooltip = $task->progress.'% < '.$langs->trans("Expected").' '.$progressCalculated.'%';
}
elseif (doubleval($progressCalculated) > doubleval($task->progress)) { // warning if close at 10%
$badgeClass .= 'badge-warning';
+ if (empty($tooltip)) $tooltip = $task->progress.'% < '.$langs->trans("Expected").' '.$progressCalculated.'%';
}
else {
$badgeClass .= 'badge-success';
+ if (empty($tooltip)) $tooltip = $task->progress.'% >= '.$langs->trans("Expected").' '.$progressCalculated.'%';
}
}
}
diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php
index c09f43cdedd..6749f32ffbe 100644
--- a/htdocs/core/lib/security.lib.php
+++ b/htdocs/core/lib/security.lib.php
@@ -107,7 +107,7 @@ function dol_decode($chain, $key = '1')
* If constant MAIN_SECURITY_SALT is defined, we use it as a salt (used only if hashing algorightm is something else than 'password_hash').
*
* @param string $chain String to hash
- * @param string $type Type of hash ('0':auto will use MAIN_SECURITY_HASH_ALGO else md5, '1':sha1, '2':sha1+md5, '3':md5, '4':md5 for OpenLdap, '5':sha256). Use '3' here, if hash is not needed for security purpose, for security need, prefer '0'.
+ * @param string $type Type of hash ('0':auto will use MAIN_SECURITY_HASH_ALGO else md5, '1':sha1, '2':sha1+md5, '3':md5, '4':md5 for OpenLdap with no salt, '5':sha256). Use '3' here, if hash is not needed for security purpose, for security need, prefer '0'.
* @return string Hash of string
* @see getRandomPassword()
*/
@@ -122,7 +122,7 @@ function dol_hash($chain, $type = '0')
}
// Salt value
- if (!empty($conf->global->MAIN_SECURITY_SALT)) $chain = $conf->global->MAIN_SECURITY_SALT.$chain;
+ if (!empty($conf->global->MAIN_SECURITY_SALT) && $type != '4' && $type !== 'md5openldap') $chain = $conf->global->MAIN_SECURITY_SALT.$chain;
if ($type == '1' || $type == 'sha1') return sha1($chain);
elseif ($type == '2' || $type == 'sha1md5') return sha1(md5($chain));
@@ -196,8 +196,13 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
// Get more permissions checks from hooks
$parameters = array('features'=>$features, 'objectid'=>$objectid, 'idtype'=>$dbt_select);
$reshook = $hookmanager->executeHooks('restrictedArea', $parameters);
- if (!empty($hookmanager->resArray['result'])) return true;
- if ($reshook > 0) return false;
+
+ if (isset($hookmanager->resArray['result'])) {
+ if ($hookmanager->resArray['result'] == 0) accessforbidden(); // Module returns 0, so access forbidden
+ }
+ if ($reshook > 0) { // No other test done.
+ return 1;
+ }
if ($dbt_select != 'rowid' && $dbt_select != 'id') $objectid = "'".$objectid."'";
@@ -316,6 +321,9 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
{
foreach ($feature2 as $subfeature)
{
+ if ($subfeature == 'user' && $user->id == $objectid && $user->rights->user->self->creer) continue; // User can edit its own card
+ if ($subfeature == 'user' && $user->id == $objectid && $user->rights->user->self->password) continue; // User can edit its own password
+
if (empty($user->rights->$feature->$subfeature->creer)
&& empty($user->rights->$feature->$subfeature->write)
&& empty($user->rights->$feature->$subfeature->create)) {
diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php
index c943220a5ac..b9a606b98b4 100644
--- a/htdocs/core/lib/security2.lib.php
+++ b/htdocs/core/lib/security2.lib.php
@@ -232,13 +232,9 @@ if (!function_exists('dol_loginfunction'))
$urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/'.$mysoc->logo);
$width = 128;
}
- elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png'))
+ elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.svg'))
{
- $urllogo = DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png';
- }
- elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.png'))
- {
- $urllogo = DOL_URL_ROOT.'/theme/dolibarr_logo.png';
+ $urllogo = DOL_URL_ROOT.'/theme/dolibarr_logo.svg';
}
// Security graphical code
diff --git a/htdocs/core/lib/takepos.lib.php b/htdocs/core/lib/takepos.lib.php
index dc86853859e..6cf8189f3c8 100644
--- a/htdocs/core/lib/takepos.lib.php
+++ b/htdocs/core/lib/takepos.lib.php
@@ -38,13 +38,10 @@ function takepos_prepare_head()
$head[$h][2] = 'setup';
$h++;
- if ($conf->global->TAKEPOS_CUSTOM_RECEIPT)
- {
- $head[$h][0] = DOL_URL_ROOT.'/takepos/admin/receipt.php';
- $head[$h][1] = $langs->trans("Receipt");
- $head[$h][2] = 'receipt';
- $h++;
- }
+ $head[$h][0] = DOL_URL_ROOT.'/takepos/admin/receipt.php';
+ $head[$h][1] = $langs->trans("Receipt");
+ $head[$h][2] = 'receipt';
+ $h++;
$numterminals = max(1, $conf->global->TAKEPOS_NUM_TERMINALS);
for ($i = 1; $i <= $numterminals; $i++)
@@ -55,7 +52,12 @@ function takepos_prepare_head()
$h++;
}
- complete_head_from_modules($conf, $langs, null, $head, $h, 'takepos');
+ $head[$h][0] = DOL_URL_ROOT.'/takepos/admin/other.php';
+ $head[$h][1] = $langs->trans("Other");
+ $head[$h][2] = 'other';
+ $h++;
+
+ complete_head_from_modules($conf, $langs, null, $head, $h, 'takepos');
return $head;
}
diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php
index 709832118c2..a234f4ed5e0 100644
--- a/htdocs/core/lib/usergroups.lib.php
+++ b/htdocs/core/lib/usergroups.lib.php
@@ -448,7 +448,8 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false)
print ''.$langs->trans("EnableShowLogo").' ';
if ($edit)
{
- print $form->selectyesno('MAIN_SHOW_LOGO', $conf->global->MAIN_SHOW_LOGO, 1);
+ print ajax_constantonoff('MAIN_SHOW_LOGO', array(), null, 0, 0, 1);
+ //print $form->selectyesno('MAIN_SHOW_LOGO', $conf->global->MAIN_SHOW_LOGO, 1);
}
else
{
@@ -494,7 +495,8 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false)
print ' ';
if ($edit)
{
- print $form->selectyesno('THEME_TOPMENU_DISABLE_IMAGE', $conf->global->THEME_TOPMENU_DISABLE_IMAGE, 1);
+ print ajax_constantonoff('THEME_TOPMENU_DISABLE_IMAGE', array(), null, 0, 0, 1);
+ //print $form->selectyesno('THEME_TOPMENU_DISABLE_IMAGE', $conf->global->THEME_TOPMENU_DISABLE_IMAGE, 1);
}
else
{
diff --git a/htdocs/core/lib/vat.lib.php b/htdocs/core/lib/vat.lib.php
index f8c7b579c18..1649e686ec2 100644
--- a/htdocs/core/lib/vat.lib.php
+++ b/htdocs/core/lib/vat.lib.php
@@ -49,7 +49,7 @@ function vat_prepare_head($object)
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
- $upload_dir = $conf->tax->dir_output . "/" . dol_sanitizeFileName($object->ref);
+ $upload_dir = $conf->tax->dir_output . "/vat/" . dol_sanitizeFileName($object->ref);
$nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
$nbLinks=Link::count($db, $object->element, $object->id);
$head[$tab][0] = DOL_URL_ROOT.'/compta/tva/document.php?id='.$object->id;
diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php
index f97c6efed1c..bd46b975120 100644
--- a/htdocs/core/lib/website.lib.php
+++ b/htdocs/core/lib/website.lib.php
@@ -38,8 +38,8 @@ function dolStripPhpCode($str, $replacewith = '')
$parts = explode('', $part);
if (!empty($partlings))
{
- $phppart = $partlings[0];
+ //$phppart = $partlings[0];
//remove content before closing tag
- if (count($partlings) > 1) $partlings[0] = ''; // Todo why a count > 1 and not >= 1 ?
+ if (count($partlings) > 1) $partlings[0] = ''; // Todo why a count > 1 and not >= 1 ?
//append to out string
- $newstr .= ''.$replacewith.' '.implode('', $partlings);
+ //$newstr .= ''.$replacewith.' '.implode('', $partlings);
+ //$newstr .= ''.$replacewith.' '.implode('', $partlings);
+ $newstr .= ''.$replacewith.' '.implode('', $partlings);
+ //$newstr .= $replacewith.implode('', $partlings);
}
}
}
@@ -85,7 +88,7 @@ function dolKeepOnlyPhpCode($str)
$i++;
continue;
}
- $newstr.='', $part, 2);
if (!empty($partlings))
@@ -117,33 +120,33 @@ function dolWebsiteReplacementOfLinks($website, $content, $removephppart = 0, $c
{
$nbrep = 0;
- dol_syslog('dolWebsiteReplacementOfLinks start (contenttype='.$contenttype." containerid=".$containerid." USEDOLIBARREDITOR=".(defined('USEDOLIBARREDITOR')?'1':'')." USEDOLIBARRSERVER=".(defined('USEDOLIBARRSERVER')?'1':'').')', LOG_DEBUG);
+ dol_syslog('dolWebsiteReplacementOfLinks start (contenttype='.$contenttype." containerid=".$containerid." USEDOLIBARREDITOR=".(defined('USEDOLIBARREDITOR') ? '1' : '')." USEDOLIBARRSERVER=".(defined('USEDOLIBARRSERVER') ? '1' : '').')', LOG_DEBUG);
//if ($contenttype == 'html') { print $content;exit; }
// Replace php code. Note $content may come from database and does not contains body tags.
- $replacewith='...php...';
- if ($removephppart) $replacewith='';
+ $replacewith = '...php...';
+ if ($removephppart) $replacewith = '';
$content = preg_replace('/value="<\?php((?!\?>).)*\?>\n*/ims', 'value="'.$replacewith.'"', $content);
- $replacewith='"callto=#';
- if ($removephppart) $replacewith='';
+ $replacewith = '"callto=#';
+ if ($removephppart) $replacewith = '';
$content = preg_replace('/"callto:<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content);
- $replacewith='"mailto=#';
- if ($removephppart) $replacewith='';
+ $replacewith = '"mailto=#';
+ if ($removephppart) $replacewith = '';
$content = preg_replace('/"mailto:<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content);
- $replacewith='src="php';
- if ($removephppart) $replacewith='';
+ $replacewith = 'src="php';
+ if ($removephppart) $replacewith = '';
$content = preg_replace('/src="<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content);
- $replacewith='href="php';
- if ($removephppart) $replacewith='';
+ $replacewith = 'href="php';
+ if ($removephppart) $replacewith = '';
$content = preg_replace('/href="<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content);
//$replacewith='...php... ';
- $replacewith='...php...';
- if ($removephppart) $replacewith='';
+ $replacewith = '...php...';
+ if ($removephppart) $replacewith = '';
//$content = preg_replace('/<\?php((?!\?toremove>).)*\?toremove>\n*/ims', $replacewith, $content);
/*if ($content === null) {
if (preg_last_error() == PREG_JIT_STACKLIMIT_ERROR) $content = 'preg_replace error (when removing php tags) PREG_JIT_STACKLIMIT_ERROR';
@@ -163,15 +166,15 @@ function dolWebsiteReplacementOfLinks($website, $content, $removephppart = 0, $c
$content = str_replace('href="'.DOL_URL_ROOT.'/document.php', 'href="!~!~!~'.DOL_URL_ROOT.'/document.php', $content);
// Replace relative link '/' with dolibarr URL
- $content = preg_replace('/(href=")\/\"/', '\1!~!~!~'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageid='.$website->fk_default_home.'"', $content, -1, $nbrep);
+ $content = preg_replace('/(href=")\/(#[^\"<>]*)?\"/', '\1!~!~!~'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageid='.$website->fk_default_home.'\2"', $content, -1, $nbrep);
// Replace relative link /xxx.php#aaa or /xxx.php with dolibarr URL (we discard param ?...)
$content = preg_replace('/(href=")\/?([^:\"\!]*)\.php(#[^\"<>]*)?\"/', '\1!~!~!~'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageref=\2\3"', $content, -1, $nbrep);
// Replace relative link /xxx.php?a=b&c=d#aaa or /xxx.php?a=b&c=d with dolibarr URL
$content = preg_replace('/(href=")\/?([^:\"\!]*)\.php\?([^#\"<>]*)(#[^\"<>]*)?\"/', '\1!~!~!~'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageref=\2&\3\4"', $content, -1, $nbrep);
// Fix relative link into medias with correct URL after the DOL_URL_ROOT: ../url("medias/
- $content = preg_replace('/url\((["\']?)medias\//', 'url(\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
- $content = preg_replace('/data-slide-bg=(["\']?)medias\//', 'data-slide-bg=\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
+ $content = preg_replace('/url\((["\']?)\/?medias\//', 'url(\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
+ $content = preg_replace('/data-slide-bg=(["\']?)\/?medias\//', 'data-slide-bg=\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
// ref.'&pageref=\2"', $content, -1, $nbrep);
// Fix relative link /document.php with correct URL after the DOL_URL_ROOT: ...href="/document.php?modulepart="
- $content=preg_replace('/(href=")(\/?document\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1!~!~!~'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
- $content=preg_replace('/(src=")(\/?document\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1!~!~!~'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
+ $content = preg_replace('/(href=")(\/?document\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1!~!~!~'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
+ $content = preg_replace('/(src=")(\/?document\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1!~!~!~'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
// Fix relative link /viewimage.php with correct URL after the DOL_URL_ROOT: ...href="/viewimage.php?modulepart="
- $content=preg_replace('/(url\(")(\/?viewimage\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1!~!~!~'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
+ $content = preg_replace('/(url\(")(\/?viewimage\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1!~!~!~'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
// Fix relative URL
$content = str_replace('src="!~!~!~/viewimage.php', 'src="!~!~!~'.DOL_URL_ROOT.'/viewimage.php', $content);
@@ -218,11 +221,11 @@ function dolWebsiteOutput($content, $contenttype = 'html', $containerid = '')
global $db, $langs, $conf, $user;
global $dolibarr_main_url_root, $dolibarr_main_data_root;
- dol_syslog("dolWebsiteOutput start (contenttype=".$contenttype." containerid=".$containerid." USEDOLIBARREDITOR=".(defined('USEDOLIBARREDITOR')?'1':'')." USEDOLIBARRSERVER=".(defined('USEDOLIBARRSERVER')?'1':'').')');
+ dol_syslog("dolWebsiteOutput start (contenttype=".$contenttype." containerid=".$containerid." USEDOLIBARREDITOR=".(defined('USEDOLIBARREDITOR') ? '1' : '')." USEDOLIBARRSERVER=".(defined('USEDOLIBARRSERVER') ? '1' : '').')');
// Define $urlwithroot
- $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
- $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
+ $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
+ $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
if (defined('USEDOLIBARREDITOR')) // REPLACEMENT OF LINKS When page called from Dolibarr editor
@@ -239,15 +242,15 @@ function dolWebsiteOutput($content, $contenttype = 'html', $containerid = '')
{
global $website;
+ $content = str_replace('
// become
//
- $nbrep=0;
- if (! $symlinktomediaexists)
+ $nbrep = 0;
+ if (!$symlinktomediaexists)
{
// ]*src=")\/?image\//', '\1/wrapper.php?modulepart=medias&file=medias/image/', $content, -1, $nbrep);
- $content=preg_replace('/(url\(["\']?)\/?image\//', '\1/wrapper.php?modulepart=medias&file=medias/image/', $content, -1, $nbrep);
+ $content = preg_replace('/( ]*src=")\/?image\//', '\1/wrapper.php?modulepart=medias&file=medias/image/', $content, -1, $nbrep);
+ $content = preg_replace('/(url\(["\']?)\/?image\//', '\1/wrapper.php?modulepart=medias&file=medias/image/', $content, -1, $nbrep);
- $content=preg_replace('/('."\n";
@@ -603,8 +607,8 @@ function getStructuredData($type, $data = array())
elseif ($type == 'product')
{
$ret = ''."\n";
- $ret.= ''."\n";
+ $ret .= ''."\n";
}
return $ret;
}
@@ -652,55 +656,55 @@ function getStructuredData($type, $data = array())
*/
function getPagesFromSearchCriterias($type, $algo, $searchstring, $max = 25)
{
- global $conf, $db, $hookmanager, $langs, $mysoc, $user, $website, $websitepage, $weblangs; // Very important. Required to have var available when running inluded containers.
+ global $conf, $db, $hookmanager, $langs, $mysoc, $user, $website, $websitepage, $weblangs; // Very important. Required to have var available when running inluded containers.
$error = 0;
$arrayresult = array('code'=>'', 'list'=>array());
- if (! is_object($weblangs)) $weblangs = $langs;
+ if (!is_object($weblangs)) $weblangs = $langs;
if (empty($searchstring))
{
$error++;
- $arrayresult['code']='KO';
- $arrayresult['message']=$weblangs->trans("EmptySearchString");
+ $arrayresult['code'] = 'KO';
+ $arrayresult['message'] = $weblangs->trans("EmptySearchString");
}
elseif (dol_strlen($searchstring) < 2)
{
$weblangs->load("errors");
$error++;
- $arrayresult['code']='KO';
- $arrayresult['message']=$weblangs->trans("ErrorSearchCriteriaTooSmall");
+ $arrayresult['code'] = 'KO';
+ $arrayresult['message'] = $weblangs->trans("ErrorSearchCriteriaTooSmall");
}
- elseif (! in_array($type, array('', 'page')))
+ elseif (!in_array($type, array('', 'page')))
{
$error++;
- $arrayresult['code']='KO';
- $arrayresult['message']='Bad value for parameter $type';
+ $arrayresult['code'] = 'KO';
+ $arrayresult['message'] = 'Bad value for parameter $type';
}
$searchdone = 0;
$found = 0;
- if (! $error && (empty($max) || ($found < $max)) && (preg_match('/meta/', $algo) || preg_match('/content/', $algo)))
+ if (!$error && (empty($max) || ($found < $max)) && (preg_match('/meta/', $algo) || preg_match('/content/', $algo)))
{
$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'website_page';
- $sql.= " WHERE fk_website = ".$website->id;
- if ($type) $sql.= " AND type_container = '".$db->escape($type)."'";
- $sql.= " AND (";
+ $sql .= " WHERE fk_website = ".$website->id;
+ if ($type) $sql .= " AND type_container = '".$db->escape($type)."'";
+ $sql .= " AND (";
$searchalgo = '';
if (preg_match('/meta/', $algo))
{
- $searchalgo.= ($searchalgo?' OR ':'')."title LIKE '%".$db->escape($searchstring)."%' OR description LIKE '%".$db->escape($searchstring)."%'";
- $searchalgo.= ($searchalgo?' OR ':'')."keywords LIKE '".$db->escape($searchstring).",%' OR keywords LIKE '% ".$db->escape($searchstring)."%'"; // TODO Use a better way to scan keywords
+ $searchalgo .= ($searchalgo ? ' OR ' : '')."title LIKE '%".$db->escape($searchstring)."%' OR description LIKE '%".$db->escape($searchstring)."%'";
+ $searchalgo .= ($searchalgo ? ' OR ' : '')."keywords LIKE '".$db->escape($searchstring).",%' OR keywords LIKE '% ".$db->escape($searchstring)."%'"; // TODO Use a better way to scan keywords
}
if (preg_match('/content/', $algo))
{
- $searchalgo.= ($searchalgo?' OR ':'')."content LIKE '%".$db->escape($searchstring)."%'";
+ $searchalgo .= ($searchalgo ? ' OR ' : '')."content LIKE '%".$db->escape($searchstring)."%'";
}
- $sql.=$searchalgo;
- $sql.= ")";
- $sql.= $db->plimit($max);
+ $sql .= $searchalgo;
+ $sql .= ")";
+ $sql .= $db->plimit($max);
$resql = $db->query($sql);
if ($resql)
@@ -712,7 +716,7 @@ function getPagesFromSearchCriterias($type, $algo, $searchstring, $max = 25)
{
$tmpwebsitepage = new WebsitePage($db);
$tmpwebsitepage->fetch($obj->rowid);
- if ($tmpwebsitepage->id > 0) $arrayresult['list'][]=$tmpwebsitepage;
+ if ($tmpwebsitepage->id > 0) $arrayresult['list'][] = $tmpwebsitepage;
$found++;
}
$i++;
@@ -721,69 +725,69 @@ function getPagesFromSearchCriterias($type, $algo, $searchstring, $max = 25)
else
{
$error++;
- $arrayresult['code']=$db->lasterrno();
- $arrayresult['message']=$db->lasterror();
+ $arrayresult['code'] = $db->lasterrno();
+ $arrayresult['message'] = $db->lasterror();
}
$searchdone = 1;
}
- if (! $error && (empty($max) || ($found < $max)) && (preg_match('/sitefiles/', $algo)))
+ if (!$error && (empty($max) || ($found < $max)) && (preg_match('/sitefiles/', $algo)))
{
global $dolibarr_main_data_root;
- $pathofwebsite=$dolibarr_main_data_root.'/website/'.$website->ref;
- $filehtmlheader=$pathofwebsite.'/htmlheader.html';
- $filecss=$pathofwebsite.'/styles.css.php';
- $filejs=$pathofwebsite.'/javascript.js.php';
- $filerobot=$pathofwebsite.'/robots.txt';
- $filehtaccess=$pathofwebsite.'/.htaccess';
- $filemanifestjson=$pathofwebsite.'/manifest.json.php';
- $filereadme=$pathofwebsite.'/README.md';
+ $pathofwebsite = $dolibarr_main_data_root.'/website/'.$website->ref;
+ $filehtmlheader = $pathofwebsite.'/htmlheader.html';
+ $filecss = $pathofwebsite.'/styles.css.php';
+ $filejs = $pathofwebsite.'/javascript.js.php';
+ $filerobot = $pathofwebsite.'/robots.txt';
+ $filehtaccess = $pathofwebsite.'/.htaccess';
+ $filemanifestjson = $pathofwebsite.'/manifest.json.php';
+ $filereadme = $pathofwebsite.'/README.md';
$filecontent = file_get_contents($filehtmlheader);
if ((empty($max) || ($found < $max)) && preg_match('/'.preg_quote($searchstring, '/').'/', $filecontent))
{
- $arrayresult['list'][]=array('type'=>'website_htmlheadercontent');
+ $arrayresult['list'][] = array('type'=>'website_htmlheadercontent');
}
$filecontent = file_get_contents($filecss);
if ((empty($max) || ($found < $max)) && preg_match('/'.preg_quote($searchstring, '/').'/', $filecontent))
{
- $arrayresult['list'][]=array('type'=>'website_csscontent');
+ $arrayresult['list'][] = array('type'=>'website_csscontent');
}
$filecontent = file_get_contents($filejs);
if ((empty($max) || ($found < $max)) && preg_match('/'.preg_quote($searchstring, '/').'/', $filecontent))
{
- $arrayresult['list'][]=array('type'=>'website_jscontent');
+ $arrayresult['list'][] = array('type'=>'website_jscontent');
}
$filerobot = file_get_contents($filerobot);
if ((empty($max) || ($found < $max)) && preg_match('/'.preg_quote($searchstring, '/').'/', $filecontent))
{
- $arrayresult['list'][]=array('type'=>'website_robotcontent');
+ $arrayresult['list'][] = array('type'=>'website_robotcontent');
}
$searchdone = 1;
}
- if (! $error)
+ if (!$error)
{
if ($searchdone)
{
- $arrayresult['code']='OK';
+ $arrayresult['code'] = 'OK';
if (empty($arrayresult['list']))
{
- $arrayresult['code']='KO';
- $arrayresult['message']=$weblangs->trans("NoRecordFound");
+ $arrayresult['code'] = 'KO';
+ $arrayresult['message'] = $weblangs->trans("NoRecordFound");
}
}
else
{
$error++;
- $arrayresult['code']='KO';
- $arrayresult['message']='No supported algorithm found';
+ $arrayresult['code'] = 'KO';
+ $arrayresult['message'] = 'No supported algorithm found';
}
}
diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php
index 2ef48e94bda..89df263b026 100644
--- a/htdocs/core/lib/website2.lib.php
+++ b/htdocs/core/lib/website2.lib.php
@@ -55,6 +55,7 @@ function dolSaveMasterFile($filemaster)
* @param Website $object Object website
* @param WebsitePage $objectpage Object websitepage
* @return boolean True if OK
+ * @see dolSavePageContent()
*/
function dolSavePageAlias($filealias, $object, $objectpage)
{
@@ -74,6 +75,24 @@ function dolSavePageAlias($filealias, $object, $objectpage)
@chmod($filealias, octdec($conf->global->MAIN_UMASK));
}
+ // Save also alias into language subdirectory if we have to
+ if ($objectpage->lang && in_array($objectpage->lang, explode(',', $object->otherlang))) {
+ $dirname = dirname($filealias);
+ $filename = basename($filealias);
+ $filealias = $dirname.'/'.$objectpage->lang.'/'.$filename;
+
+ $aliascontent = 'id.'.tpl.php\'; ';
+ $aliascontent .= 'else require $dolibarr_main_data_root.\'/website/\'.$website->ref.\'/page'.$objectpage->id.'.tpl.php\';'."\n";
+ $aliascontent .= '?>'."\n";
+ $result = file_put_contents($filealias, $aliascontent);
+ if (!empty($conf->global->MAIN_UMASK)) {
+ @chmod($filealias, octdec($conf->global->MAIN_UMASK));
+ }
+ }
+
return ($result ?true:false);
}
@@ -85,6 +104,7 @@ function dolSavePageAlias($filealias, $object, $objectpage)
* @param Website $object Object website
* @param WebsitePage $objectpage Object websitepage
* @return boolean True if OK
+ * @see dolSavePageAlias()
*/
function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage)
{
@@ -96,12 +116,15 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage)
dol_delete_file($filetpl);
$shortlangcode = '';
- if ($objectpage->lang) $shortlangcode = preg_replace('/[_-].*$/', '', $objectpage->lang); // en_US or en-US -> en
+ if ($objectpage->lang) $shortlangcode = substr($objectpage->lang, 0, 2); // en_US or en-US -> en
$tplcontent = '';
$tplcontent .= "isMultiLang()) {
// Add myself
- $tplcontent .= ' '."\n";
+ $tplcontent .= ' '."\n";
+
// Add page "translation of"
$translationof = $objectpage->fk_page;
if ($translationof) {
@@ -135,7 +159,7 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage)
$tmpshortlangcode = '';
if ($tmppage->lang) $tmpshortlangcode = preg_replace('/[_-].*$/', '', $tmppage->lang); // en_US or en-US -> en
if ($tmpshortlangcode != $shortlangcode) {
- $tplcontent .= ' '."\n";
+ $tplcontent .= ' '."\n";
}
}
}
@@ -152,7 +176,7 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage)
$tmpshortlangcode = '';
if ($obj->lang) $tmpshortlangcode = preg_replace('/[_-].*$/', '', $obj->lang); // en_US or en-US -> en
if ($tmpshortlangcode != $shortlangcode) {
- $tplcontent .= ' '."\n";
+ $tplcontent .= ' '."\n";
}
}
}
@@ -160,11 +184,11 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage)
else dol_print_error($db);
}
// Add canonical reference
- $tplcontent .= ' '."\n";
+ $tplcontent .= ' '."\n";
// Add manifest.json on homepage
$tplcontent .= 'use_manifest) { print \' \'."\n"; } ?>'."\n";
$tplcontent .= ''."\n";
- $tplcontent .= ' '."\n";
+ $tplcontent .= ' '."\n";
$tplcontent .= ''."\n";
$tplcontent .= '/ims\', \'\', file_get_contents(DOL_DATA_ROOT."/website/".$websitekey."/htmlheader.html")); ?>'."\n";
$tplcontent .= ''."\n";
diff --git a/htdocs/core/login/functions_googleoauth.php b/htdocs/core/login/functions_googleoauth.php
index 2f1fbcf3667..e621f41e562 100644
--- a/htdocs/core/login/functions_googleoauth.php
+++ b/htdocs/core/login/functions_googleoauth.php
@@ -48,7 +48,7 @@ function check_user_password_googleoauth($usertotest, $passwordtotest, $entityto
$login = '';
// Get identity from user and redirect browser to Google OAuth Server
- if (isset($_POST['username']))
+ if (GETPOSTISSET('username'))
{
/*$openid = new SimpleOpenID();
$openid->SetIdentity($_POST['username']);
diff --git a/htdocs/core/login/functions_openid.php b/htdocs/core/login/functions_openid.php
index c20b2a32f90..a401dfd7764 100644
--- a/htdocs/core/login/functions_openid.php
+++ b/htdocs/core/login/functions_openid.php
@@ -36,26 +36,26 @@ include_once DOL_DOCUMENT_ROOT.'/core/class/openid.class.php';
*/
function check_user_password_openid($usertotest, $passwordtotest, $entitytotest)
{
- global $_POST,$db,$conf,$langs;
+ global $_POST, $db, $conf, $langs;
dol_syslog("functions_openid::check_user_password_openid usertotest=".$usertotest);
- $login='';
+ $login = '';
// Get identity from user and redirect browser to OpenID Server
- if (isset($_POST['username']))
+ if (GETPOSISSET('username'))
{
$openid = new SimpleOpenID();
$openid->SetIdentity($_POST['username']);
$protocol = ($conf->file->main_force_https ? 'https://' : 'http://');
- $openid->SetTrustRoot($protocol . $_SERVER["HTTP_HOST"]);
- $openid->SetRequiredFields(array('email','fullname'));
+ $openid->SetTrustRoot($protocol.$_SERVER["HTTP_HOST"]);
+ $openid->SetRequiredFields(array('email', 'fullname'));
$_SESSION['dol_entity'] = $_POST["entity"];
//$openid->SetOptionalFields(array('dob','gender','postcode','country','language','timezone'));
if ($openid->sendDiscoveryRequestToGetXRDS())
{
- $openid->SetApprovedURL($protocol . $_SERVER["HTTP_HOST"] . $_SERVER["SCRIPT_NAME"]); // Send Response from OpenID server to this script
- $openid->Redirect(); // This will redirect user to OpenID Server
+ $openid->SetApprovedURL($protocol.$_SERVER["HTTP_HOST"].$_SERVER["SCRIPT_NAME"]); // Send Response from OpenID server to this script
+ $openid->Redirect(); // This will redirect user to OpenID Server
}
else
{
@@ -65,7 +65,7 @@ function check_user_password_openid($usertotest, $passwordtotest, $entitytotest)
return false;
}
// Perform HTTP Request to OpenID server to validate key
- elseif($_GET['openid_mode'] == 'id_res')
+ elseif ($_GET['openid_mode'] == 'id_res')
{
$openid = new SimpleOpenID();
$openid->SetIdentity($_GET['openid_identity']);
@@ -74,23 +74,23 @@ function check_user_password_openid($usertotest, $passwordtotest, $entitytotest)
{
// OK HERE KEY IS VALID
- $sql ="SELECT login";
- $sql.=" FROM ".MAIN_DB_PREFIX."user";
- $sql.=" WHERE openid = '".$db->escape($_GET['openid_identity'])."'";
- $sql.=" AND entity IN (0," . ($_SESSION["dol_entity"] ? $_SESSION["dol_entity"] : 1) . ")";
+ $sql = "SELECT login";
+ $sql .= " FROM ".MAIN_DB_PREFIX."user";
+ $sql .= " WHERE openid = '".$db->escape($_GET['openid_identity'])."'";
+ $sql .= " AND entity IN (0,".($_SESSION["dol_entity"] ? $_SESSION["dol_entity"] : 1).")";
dol_syslog("functions_openid::check_user_password_openid", LOG_DEBUG);
- $resql=$db->query($sql);
+ $resql = $db->query($sql);
if ($resql)
{
- $obj=$db->fetch_object($resql);
+ $obj = $db->fetch_object($resql);
if ($obj)
{
- $login=$obj->login;
+ $login = $obj->login;
}
}
}
- elseif($openid->IsError() === true)
+ elseif ($openid->IsError() === true)
{
// ON THE WAY, WE GOT SOME ERROR
$error = $openid->GetError();
diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql
index 8948c391899..66ed948585f 100644
--- a/htdocs/core/menus/init_menu_auguria.sql
+++ b/htdocs/core/menus/init_menu_auguria.sql
@@ -281,7 +281,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left
-- Balance
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2435__+MAX_llx_menu__, 'accountancy', 'balance', 2400__+MAX_llx_menu__, '/accountancy/bookkeeping/balance.php?mainmenu=accountancy&leftmenu=accountancy_balance', 'AccountBalance', 1, 'accountancy', '$user->rights->accounting->mouvements->lire', '', 0, 16, __ENTITY__);
-- Export accounting documents
- insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2436__+MAX_llx_menu__, 'accountancy', 'accountancy_files', 2400__+MAX_llx_menu__, '/compta/compta-files.php?mainmenu=accountancy&leftmenu=accountancy_files', 'AccountantFiles', 1, 'accountancy', '$user->rights->accounting->mouvements->lire', '', 0, 17, __ENTITY__);
+ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->comptabilite->enabled || $conf->accounting->enabled', __HANDLER__, 'left', 2436__+MAX_llx_menu__, 'accountancy', 'accountancy_files', 2400__+MAX_llx_menu__, '/compta/accounting-files.php?mainmenu=accountancy&leftmenu=accountancy_files', 'AccountantFiles', 1, 'accountancy', '$user->rights->compta->resultat->lire || $user->rights->accounting->mouvements->lire', '', 0, 17, __ENTITY__);
-- Reports
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2440__+MAX_llx_menu__, 'accountancy', 'accountancy_report', 2400__+MAX_llx_menu__, '/compta/resultat/index.php?mainmenu=accountancy&leftmenu=accountancy_report', 'Reportings', 1, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 17, __ENTITY__);
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_report"', __HANDLER__, 'left', 2441__+MAX_llx_menu__, 'accountancy', 'accountancy_report', 2440__+MAX_llx_menu__, '/compta/resultat/index.php?mainmenu=accountancy&leftmenu=accountancy_report', 'MenuReportInOut', 2, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 18, __ENTITY__);
diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php
index e35f45576d1..390c50aa748 100644
--- a/htdocs/core/menus/standard/auguria.lib.php
+++ b/htdocs/core/menus/standard/auguria.lib.php
@@ -548,7 +548,7 @@ function print_left_auguria_menu($db, $menu_array_before, $menu_array_after, &$t
if ($menu_array[$i]['enabled']) // Enabled so visible
{
print '
@@ -251,7 +265,7 @@
(3)
-
+
L’organisme bénéficiaire peut cocher une ou plusieurs cases.
L’organisme bénéficiaire peut, en application de l’article L. 80 C du livre des procédures fiscales, demander à l’administration s’il relève
de l’une des catégories d’organismes mentionnées aux articles 200 et 238 bis du code général des impôts.
@@ -262,7 +276,7 @@
(4)
-
+
Notamment : abandon de revenus ou de produits ; frais engagés par les bénévoles, dont ils renoncent expressément au remboursement
@@ -274,10 +288,10 @@
-
+
-
- Date et signature
+
+ Date et signature
diff --git a/htdocs/core/modules/dons/html_cerfafr.modules.php b/htdocs/core/modules/dons/html_cerfafr.modules.php
index bcda35459f6..4c025750f04 100644
--- a/htdocs/core/modules/dons/html_cerfafr.modules.php
+++ b/htdocs/core/modules/dons/html_cerfafr.modules.php
@@ -3,7 +3,7 @@
* Copyright (C) 2005-2006 Laurent Destailleur
* Copyright (C) 2012 Regis Houssin
* Copyright (C) 2012 Marcos García
- * Copyright (C) 2014-2015 Alexandre Spangaro
+ * Copyright (C) 2014-2020 Alexandre Spangaro
* Copyright (C) 2015 Benoit Bruchard
*
* This program is free software; you can redistribute it and/or modify
@@ -42,11 +42,11 @@ class html_cerfafr extends ModeleDon
*/
public function __construct($db)
{
- global $conf,$langs;
+ global $conf, $langs;
$this->db = $db;
$this->name = "cerfafr";
- $this->description = $langs->trans('DonationsReceiptModel').' - fr_FR - Cerfa 11580*03';
+ $this->description = $langs->trans('DonationsReceiptModel').' - fr_FR - Cerfa 11580*04';
// Dimension page for size A4
$this->type = 'html';
@@ -76,46 +76,46 @@ class html_cerfafr extends ModeleDon
public function write_file($don, $outputlangs, $currency = '')
{
// phpcs:enable
- global $user,$conf,$langs,$mysoc;
+ global $user, $conf, $langs, $mysoc;
- $now=dol_now();
- $id = (! is_object($don)?$don:'');
+ $now = dol_now();
+ $id = (!is_object($don) ? $don : '');
- if (! is_object($outputlangs)) $outputlangs=$langs;
+ if (!is_object($outputlangs)) $outputlangs = $langs;
// Load traductions files required by page
$outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "donations"));
$currency = !empty($currency) ? $currency : $conf->currency;
- if (! empty($conf->don->dir_output))
+ if (!empty($conf->don->dir_output))
{
// Definition of the object don (for upward compatibility)
- if (! is_object($don))
+ if (!is_object($don))
{
$don = new Don($this->db);
- $ret=$don->fetch($id);
- $id=$don->id;
+ $ret = $don->fetch($id);
+ $id = $don->id;
}
// Definition of $dir and $file
- if (! empty($don->specimen))
+ if (!empty($don->specimen))
{
$dir = $conf->don->dir_output;
- $file = $dir . "/SPECIMEN.html";
+ $file = $dir."/SPECIMEN.html";
}
else
{
$donref = dol_sanitizeFileName($don->ref);
- $dir = $conf->don->dir_output . "/" . $donref;
- $file = $dir . "/" . $donref . ".html";
+ $dir = $conf->don->dir_output."/".$donref;
+ $file = $dir."/".$donref.".html";
}
- if (! file_exists($dir))
+ if (!file_exists($dir))
{
if (dol_mkdir($dir) < 0)
{
- $this->error=$langs->trans("ErrorCanNotCreateDir", $dir);
+ $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
return -1;
}
}
@@ -133,13 +133,13 @@ class html_cerfafr extends ModeleDon
}
else $paymentmode = '';
- if ($don->modepaymentcode=='CHQ'){
+ if ($don->modepaymentcode == 'CHQ') {
$ModePaiement = ' Remise d\'espèces Chèque Virement, prélèvement, carte bancaire ';
}
- elseif ($don->modepaymentcode=='LIQ'){
+ elseif ($don->modepaymentcode == 'LIQ') {
$ModePaiement = ' Remise d\'espèces Chèque Virement, prélèvement, carte bancaire ';
}
- elseif ($don->modepaymentcode=='VIR' || $don->modepaymentcode=='PRE' || $don->modepaymentcode=='CB'){
+ elseif ($don->modepaymentcode == 'VIR' || $don->modepaymentcode == 'PRE' || $don->modepaymentcode == 'CB') {
$ModePaiement = ' Remise d\'espèces Chèque Virement, prélèvement, carte bancaire ';
}
else
@@ -150,16 +150,16 @@ class html_cerfafr extends ModeleDon
/*
if (empty($don->societe))
{
- $CodeDon = ' 200 du CGI 238 bis du CGI 885-0 V bis A du CGI ';
+ $CodeDon = ' 200 du CGI 238 bis du CGI 978 du CGI ';
}
else
{
- $CodeDon = ' 200 du CGI 238 bis du CGI 885-0 V bis A du CGI ';
+ $CodeDon = ' 200 du CGI 238 bis du CGI 978 du CGI ';
}
*/
// Define contents
- $donmodel=DOL_DOCUMENT_ROOT ."/core/modules/dons/html_cerfafr.html";
+ $donmodel = DOL_DOCUMENT_ROOT."/core/modules/dons/html_cerfafr.html";
$form = implode('', file($donmodel));
$form = str_replace('__REF__', $don->id, $form);
$form = str_replace('__DATE__', dol_print_date($don->date, 'day', false, $outputlangs), $form);
@@ -203,59 +203,59 @@ class html_cerfafr extends ModeleDon
$form = str_replace('__ModePaiement__', $ModePaiement, $form);
- $frencharticle='';
- if (preg_match('/fr/i', $outputlangs->defaultlang)) $frencharticle='Article 200, 238 bis et 885-0 V bis A du code général des impôts (CGI) ';
+ $frencharticle = '';
+ if (preg_match('/fr/i', $outputlangs->defaultlang)) $frencharticle = 'Article 200, 238 bis et 978 du code général des impôts (CGI) ';
$form = str_replace('__FrenchArticle__', $frencharticle, $form);
- $frencheligibility='';
- if (preg_match('/fr/i', $outputlangs->defaultlang)) $frencheligibility='Le bénéficiaire certifie sur l\'honneur que les dons et versements qu\'il reçoit ouvrent droit à la réduction d\'impôt prévue à l\'article :';
+ $frencheligibility = '';
+ if (preg_match('/fr/i', $outputlangs->defaultlang)) $frencheligibility = 'Le bénéficiaire certifie sur l\'honneur que les dons et versements qu\'il reçoit ouvrent droit à la réduction d\'impôt prévue à l\'article :';
$form = str_replace('__FrenchEligibility__', $frencheligibility, $form);
- $art200='';
+ $art200 = '';
if (preg_match('/fr/i', $outputlangs->defaultlang)) {
if ($conf->global->DONATION_ART200 >= 1)
{
- $art200=' 200 du CGI';
+ $art200 = ' 200 du CGI';
}
else
{
- $art200=' 200 du CGI';
+ $art200 = ' 200 du CGI';
}
}
$form = str_replace('__ARTICLE200__', $art200, $form);
- $art238='';
+ $art238 = '';
if (preg_match('/fr/i', $outputlangs->defaultlang)) {
if ($conf->global->DONATION_ART238 >= 1)
{
- $art238=' 238 bis du CGI';
+ $art238 = ' 238 bis du CGI';
}
else
{
- $art238=' 238 bis du CGI';
+ $art238 = ' 238 bis du CGI';
}
}
$form = str_replace('__ARTICLE238__', $art238, $form);
- $art885='';
+ $art978 = '';
if (preg_match('/fr/i', $outputlangs->defaultlang)) {
- if ($conf->global->DONATION_ART885 >= 1)
+ if ($conf->global->DONATION_ART978 >= 1)
{
- $art885=' 885-0 V bis du CGI';
+ $art978 = ' 978 du CGI';
}
else
{
- $art885=' 885-0 V bis du CGI';
+ $art978 = ' 978 du CGI';
}
}
- $form = str_replace('__ARTICLE885__', $art885, $form);
+ $form = str_replace('__ARTICLE978__', $art978, $form);
// Save file on disk
dol_syslog("html_cerfafr::write_file $file");
- $handle=fopen($file, "w");
+ $handle = fopen($file, "w");
fwrite($handle, $form);
fclose($handle);
- if (! empty($conf->global->MAIN_UMASK))
+ if (!empty($conf->global->MAIN_UMASK))
@chmod($file, octdec($conf->global->MAIN_UMASK));
$this->result = array('fullpath'=>$file);
@@ -264,13 +264,13 @@ class html_cerfafr extends ModeleDon
}
else
{
- $this->error=$langs->trans("ErrorCanNotCreateDir", $dir);
+ $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
return 0;
}
}
else
{
- $this->error=$langs->trans("ErrorConstantNotDefined", "DON_OUTPUTDIR");
+ $this->error = $langs->trans("ErrorConstantNotDefined", "DON_OUTPUTDIR");
return 0;
}
}
@@ -288,147 +288,147 @@ class html_cerfafr extends ModeleDon
$unite = array();
$dix = array();
$cent = array();
- if(empty($devise1)) $dev1='euros';
- else $dev1=$devise1;
- if(empty($devise2)) $dev2='centimes';
- else $dev2=$devise2;
- $valeur_entiere=intval($montant);
- $valeur_decimal=intval(round($montant-intval($montant), 2)*100);
- $dix_c=intval($valeur_decimal%100/10);
- $cent_c=intval($valeur_decimal%1000/100);
- $unite[1]=$valeur_entiere%10;
- $dix[1]=intval($valeur_entiere%100/10);
- $cent[1]=intval($valeur_entiere%1000/100);
- $unite[2]=intval($valeur_entiere%10000/1000);
- $dix[2]=intval($valeur_entiere%100000/10000);
- $cent[2]=intval($valeur_entiere%1000000/100000);
- $unite[3]=intval($valeur_entiere%10000000/1000000);
- $dix[3]=intval($valeur_entiere%100000000/10000000);
- $cent[3]=intval($valeur_entiere%1000000000/100000000);
- $chif=array('', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix sept', 'dix huit', 'dix neuf');
- $secon_c='';
- $trio_c='';
- for($i=1; $i<=3; $i++) {
- $prim[$i]='';
- $secon[$i]='';
- $trio[$i]='';
- if ($dix[$i]==0) {
- $secon[$i]='';
- $prim[$i]=$chif[$unite[$i]];
+ if (empty($devise1)) $dev1 = 'euros';
+ else $dev1 = $devise1;
+ if (empty($devise2)) $dev2 = 'centimes';
+ else $dev2 = $devise2;
+ $valeur_entiere = intval($montant);
+ $valeur_decimal = intval(round($montant - intval($montant), 2) * 100);
+ $dix_c = intval($valeur_decimal % 100 / 10);
+ $cent_c = intval($valeur_decimal % 1000 / 100);
+ $unite[1] = $valeur_entiere % 10;
+ $dix[1] = intval($valeur_entiere % 100 / 10);
+ $cent[1] = intval($valeur_entiere % 1000 / 100);
+ $unite[2] = intval($valeur_entiere % 10000 / 1000);
+ $dix[2] = intval($valeur_entiere % 100000 / 10000);
+ $cent[2] = intval($valeur_entiere % 1000000 / 100000);
+ $unite[3] = intval($valeur_entiere % 10000000 / 1000000);
+ $dix[3] = intval($valeur_entiere % 100000000 / 10000000);
+ $cent[3] = intval($valeur_entiere % 1000000000 / 100000000);
+ $chif = array('', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix sept', 'dix huit', 'dix neuf');
+ $secon_c = '';
+ $trio_c = '';
+ for ($i = 1; $i <= 3; $i++) {
+ $prim[$i] = '';
+ $secon[$i] = '';
+ $trio[$i] = '';
+ if ($dix[$i] == 0) {
+ $secon[$i] = '';
+ $prim[$i] = $chif[$unite[$i]];
}
- elseif ($dix[$i]==1) {
- $secon[$i]='';
- $prim[$i]=$chif[($unite[$i]+10)];
+ elseif ($dix[$i] == 1) {
+ $secon[$i] = '';
+ $prim[$i] = $chif[($unite[$i] + 10)];
}
- elseif ($dix[$i]==2) {
- if ($unite[$i]==1) {
- $secon[$i]='vingt et';
- $prim[$i]=$chif[$unite[$i]];
+ elseif ($dix[$i] == 2) {
+ if ($unite[$i] == 1) {
+ $secon[$i] = 'vingt et';
+ $prim[$i] = $chif[$unite[$i]];
} else {
- $secon[$i]='vingt';
- $prim[$i]=$chif[$unite[$i]];
+ $secon[$i] = 'vingt';
+ $prim[$i] = $chif[$unite[$i]];
}
}
- elseif ($dix[$i]==3) {
- if ($unite[$i]==1) {
- $secon[$i]='trente et';
- $prim[$i]=$chif[$unite[$i]];
+ elseif ($dix[$i] == 3) {
+ if ($unite[$i] == 1) {
+ $secon[$i] = 'trente et';
+ $prim[$i] = $chif[$unite[$i]];
} else {
- $secon[$i]='trente';
- $prim[$i]=$chif[$unite[$i]];
+ $secon[$i] = 'trente';
+ $prim[$i] = $chif[$unite[$i]];
}
}
- elseif ($dix[$i]==4) {
- if ($unite[$i]==1) {
- $secon[$i]='quarante et';
- $prim[$i]=$chif[$unite[$i]];
+ elseif ($dix[$i] == 4) {
+ if ($unite[$i] == 1) {
+ $secon[$i] = 'quarante et';
+ $prim[$i] = $chif[$unite[$i]];
}
else {
- $secon[$i]='quarante';
- $prim[$i]=$chif[$unite[$i]];
+ $secon[$i] = 'quarante';
+ $prim[$i] = $chif[$unite[$i]];
}
}
- elseif ($dix[$i]==5) {
- if ($unite[$i]==1) {
- $secon[$i]='cinquante et';
- $prim[$i]=$chif[$unite[$i]];
+ elseif ($dix[$i] == 5) {
+ if ($unite[$i] == 1) {
+ $secon[$i] = 'cinquante et';
+ $prim[$i] = $chif[$unite[$i]];
}
else {
- $secon[$i]='cinquante';
- $prim[$i]=$chif[$unite[$i]];
+ $secon[$i] = 'cinquante';
+ $prim[$i] = $chif[$unite[$i]];
}
}
- elseif ($dix[$i]==6) {
- if ($unite[$i]==1) {
- $secon[$i]='soixante et';
- $prim[$i]=$chif[$unite[$i]];
+ elseif ($dix[$i] == 6) {
+ if ($unite[$i] == 1) {
+ $secon[$i] = 'soixante et';
+ $prim[$i] = $chif[$unite[$i]];
}
else {
- $secon[$i]='soixante';
- $prim[$i]=$chif[$unite[$i]];
+ $secon[$i] = 'soixante';
+ $prim[$i] = $chif[$unite[$i]];
}
}
- elseif ($dix[$i]==7) {
- if ($unite[$i]==1) {
- $secon[$i]='soixante et';
- $prim[$i]=$chif[$unite[$i]+10];
+ elseif ($dix[$i] == 7) {
+ if ($unite[$i] == 1) {
+ $secon[$i] = 'soixante et';
+ $prim[$i] = $chif[$unite[$i] + 10];
}
else {
- $secon[$i]='soixante';
- $prim[$i]=$chif[$unite[$i]+10];
+ $secon[$i] = 'soixante';
+ $prim[$i] = $chif[$unite[$i] + 10];
}
}
- elseif ($dix[$i]==8) {
- if ($unite[$i]==1) {
- $secon[$i]='quatre-vingts et';
- $prim[$i]=$chif[$unite[$i]];
+ elseif ($dix[$i] == 8) {
+ if ($unite[$i] == 1) {
+ $secon[$i] = 'quatre-vingts et';
+ $prim[$i] = $chif[$unite[$i]];
}
else {
- $secon[$i]='quatre-vingt';
- $prim[$i]=$chif[$unite[$i]];
+ $secon[$i] = 'quatre-vingt';
+ $prim[$i] = $chif[$unite[$i]];
}
}
- elseif ($dix[$i]==9) {
- if ($unite[$i]==1) {
- $secon[$i]='quatre-vingts et';
- $prim[$i]=$chif[$unite[$i]+10];
+ elseif ($dix[$i] == 9) {
+ if ($unite[$i] == 1) {
+ $secon[$i] = 'quatre-vingts et';
+ $prim[$i] = $chif[$unite[$i] + 10];
}
else {
- $secon[$i]='quatre-vingts';
- $prim[$i]=$chif[$unite[$i]+10];
+ $secon[$i] = 'quatre-vingts';
+ $prim[$i] = $chif[$unite[$i] + 10];
}
}
- if($cent[$i]==1) $trio[$i]='cent';
- elseif($cent[$i]!=0 || $cent[$i]!='') $trio[$i]=$chif[$cent[$i]] .' cents';
+ if ($cent[$i] == 1) $trio[$i] = 'cent';
+ elseif ($cent[$i] != 0 || $cent[$i] != '') $trio[$i] = $chif[$cent[$i]].' cents';
}
- $chif2=array('', 'dix', 'vingt', 'trente', 'quarante', 'cinquante', 'soixante', 'soixante-dix', 'quatre-vingts', 'quatre-vingts dix');
- $secon_c=$chif2[$dix_c];
- if ($cent_c==1) $trio_c='cent';
- elseif ($cent_c!=0 || $cent_c!='') $trio_c=$chif[$cent_c] .' cents';
+ $chif2 = array('', 'dix', 'vingt', 'trente', 'quarante', 'cinquante', 'soixante', 'soixante-dix', 'quatre-vingts', 'quatre-vingts dix');
+ $secon_c = $chif2[$dix_c];
+ if ($cent_c == 1) $trio_c = 'cent';
+ elseif ($cent_c != 0 || $cent_c != '') $trio_c = $chif[$cent_c].' cents';
- if (($cent[3]==0 || $cent[3]=='') && ($dix[3]==0 || $dix[3]=='') && ($unite[3]==1))
- $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]. ' million ';
- elseif (($cent[3]!=0 && $cent[3]!='') || ($dix[3]!=0 && $dix[3]!='') || ($unite[3]!=0 && $unite[3]!=''))
- $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]. ' millions ';
+ if (($cent[3] == 0 || $cent[3] == '') && ($dix[3] == 0 || $dix[3] == '') && ($unite[3] == 1))
+ $somme = $trio[3].' '.$secon[3].' '.$prim[3].' million ';
+ elseif (($cent[3] != 0 && $cent[3] != '') || ($dix[3] != 0 && $dix[3] != '') || ($unite[3] != 0 && $unite[3] != ''))
+ $somme = $trio[3].' '.$secon[3].' '.$prim[3].' millions ';
else
- $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3];
+ $somme = $trio[3].' '.$secon[3].' '.$prim[3];
- if (($cent[2]==0 || $cent[2]=='') && ($dix[2]==0 || $dix[2]=='') && ($unite[2]==1))
+ if (($cent[2] == 0 || $cent[2] == '') && ($dix[2] == 0 || $dix[2] == '') && ($unite[2] == 1))
$somme = $somme.' mille ';
- elseif (($cent[2]!=0 && $cent[2]!='') || ($dix[2]!=0 && $dix[2]!='') || ($unite[2]!=0 && $unite[2]!=''))
- $somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2]. ' milles ';
+ elseif (($cent[2] != 0 && $cent[2] != '') || ($dix[2] != 0 && $dix[2] != '') || ($unite[2] != 0 && $unite[2] != ''))
+ $somme = $somme.$trio[2].' '.$secon[2].' '.$prim[2].' milles ';
else
- $somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2];
+ $somme = $somme.$trio[2].' '.$secon[2].' '.$prim[2];
- $somme = $somme. $trio[1]. ' ' .$secon[1]. ' ' . $prim[1];
+ $somme = $somme.$trio[1].' '.$secon[1].' '.$prim[1];
- $somme = $somme. ' '. $dev1 .' ' ;
+ $somme = $somme.' '.$dev1.' ';
- if (($cent_c=='0' || $cent_c=='') && ($dix_c=='0' || $dix_c==''))
- return $somme. ' et zéro '. $dev2;
+ if (($cent_c == '0' || $cent_c == '') && ($dix_c == '0' || $dix_c == ''))
+ return $somme.' et zéro '.$dev2;
else
- return $somme. $trio_c. ' ' .$secon_c. ' ' . $dev2;
+ return $somme.$trio_c.' '.$secon_c.' '.$dev2;
}
}
diff --git a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php
index b47149f26a6..6268f84d127 100644
--- a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php
+++ b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php
@@ -313,6 +313,8 @@ class pdf_espadon extends ModelePdfExpedition
$tab_height = 130;
$tab_height_newpage = 150;
+ $this->posxdesc = $this->marge_gauche + 1;
+
// Incoterm
$height_incoterms = 0;
if ($conf->incoterm->enabled)
@@ -336,7 +338,17 @@ class pdf_espadon extends ModelePdfExpedition
}
}
- if (!empty($object->note_public) || !empty($object->tracking_number))
+ // display note
+ $notetoshow = empty($object->note_public) ? '' : $object->note_public;
+
+ // Extrafields in note
+ $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
+ if (!empty($extranote))
+ {
+ $notetoshow = dol_concatdesc($notetoshow, $extranote);
+ }
+
+ if (!empty($notetoshow) || !empty($object->tracking_number))
{
$tab_top = 88 + $height_incoterms;
$tab_top_alt = $tab_top;
@@ -375,10 +387,10 @@ class pdf_espadon extends ModelePdfExpedition
}
// Notes
- if (!empty($object->note_public))
+ if (!empty($notetoshow))
{
$pdf->SetFont('', '', $default_font_size - 1); // In loop to manage multi-page
- $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top_alt, dol_htmlentitiesbr($object->note_public), 0, 1);
+ $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top_alt, dol_htmlentitiesbr($notetoshow), 0, 1);
}
$nexY = $pdf->GetY();
@@ -406,9 +418,7 @@ class pdf_espadon extends ModelePdfExpedition
$pdf->rollbackTransaction(true);
- $iniY = $tab_top + $this->tabTitleHeight + 2;
- $curY = $tab_top + $this->tabTitleHeight + 2;
- $nexY = $tab_top + $this->tabTitleHeight + 2;
+ $nexY = $tab_top + $this->tabTitleHeight;
// Loop on each lines
for ($i = 0; $i < $nblines; $i++)
@@ -461,15 +471,15 @@ class pdf_espadon extends ModelePdfExpedition
if ($this->getColumnStatus('desc'))
{
$pdf->startTransaction();
- pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc);
- $pageposafter = $pdf->getPage();
+
+ $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
+
+ $pageposafter = $pdf->getPage();
if ($pageposafter > $pageposbefore) // There is a pagebreak
{
$pdf->rollbackTransaction(true);
- $pageposafter = $pageposbefore;
- //print $pageposafter.'-'.$pageposbefore;exit;
- $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
- pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc);
+
+ $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
$pageposafter = $pdf->getPage();
$posyafter = $pdf->GetY();
@@ -558,10 +568,17 @@ class pdf_espadon extends ModelePdfExpedition
$nexY = max($pdf->GetY(), $nexY);
}
-
-
- $nexY += 3;
- if ($weighttxt && $voltxt) $nexY += 2;
+ // Extrafields
+ if(!empty($object->lines[$i]->array_options)){
+ foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue){
+ if ($this->getColumnStatus($extrafieldColKey))
+ {
+ $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey);
+ $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
+ $nexY = max($pdf->GetY(), $nexY);
+ }
+ }
+ }
// Add line
if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1))
@@ -569,7 +586,7 @@ class pdf_espadon extends ModelePdfExpedition
$pdf->setPage($pageposafter);
$pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
//$pdf->SetDrawColor(190,190,200);
- $pdf->line($this->marge_gauche, $nexY - 1, $this->page_largeur - $this->marge_droite, $nexY - 1);
+ $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY);
$pdf->SetLineStyle(array('dash'=>0));
}
@@ -1099,7 +1116,7 @@ class pdf_espadon extends ModelePdfExpedition
// Default field style for content
$this->defaultContentsFieldsStyle = array(
'align' => 'R', // R,C,L
- 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
);
// Default field style for content
@@ -1136,10 +1153,10 @@ class pdf_espadon extends ModelePdfExpedition
'align' => 'L',
// 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
// 'label' => ' ', // the final label
- 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ 'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
),
'content' => array(
- 'align' => 'L',
+ 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
),
);
@@ -1225,6 +1242,11 @@ class pdf_espadon extends ModelePdfExpedition
),
);
+ // Add extrafields cols
+ if(!empty($object->lines)) {
+ $line = reset($object->lines);
+ $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
+ }
$parameters = array(
'object' => $object,
diff --git a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php
index 76743258193..0adf7cd2a6a 100644
--- a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php
+++ b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php
@@ -576,8 +576,10 @@ class pdf_standard extends ModeleExpenseReport
}
$expensereporttypecode = $object->lines[$linenumber]->type_fees_code;
- $expensereporttypecodetoshow = $outputlangs->trans($expensereporttypecode);
- if ($expensereporttypecodetoshow == $expensereporttypecode) {
+ $expensereporttypecodetoshow = ($outputlangs->trans(($expensereporttypecode)) == $expensereporttypecode ? $object->lines[$linenumber]->type_fees_libelle : $outputlangs->trans($expensereporttypecode));
+
+
+ if ($expensereporttypecodetoshow == $expensereporttypecode) {
$expensereporttypecodetoshow = preg_replace('/^(EX_|TF_)/', '', $expensereporttypecodetoshow);
}
//$expensereporttypecodetoshow = dol_trunc($expensereporttypecodetoshow, 9);
diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php
index ef05b9b2df9..acbebd54da8 100644
--- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php
+++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php
@@ -41,7 +41,7 @@ class doc_generic_invoice_odt extends ModelePDFFactures
{
/**
* Issuer
- * @var Company object that emits
+ * @var Societe Object that emits
*/
public $emetteur;
@@ -435,9 +435,11 @@ class doc_generic_invoice_odt extends ModelePDFFactures
}
if ($foundtagforlines)
{
+ $linenumber = 0;
foreach ($object->lines as $line)
{
- $tmparray = $this->get_substitutionarray_lines($line, $outputlangs);
+ $linenumber++;
+ $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber);
complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines");
// Call the ODTSubstitutionLine hook
$parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line);
diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
index f0a3230595e..112a3fec279 100644
--- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
+++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
@@ -494,7 +494,7 @@ class pdf_crabe extends ModelePDFFactures
$curY = $tab_top_newpage;
// Allows data in the first page if description is long enough to break in multiples pages
- if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
+ if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
$showpricebeforepagebreak = 1;
else
$showpricebeforepagebreak = 0;
@@ -539,7 +539,7 @@ class pdf_crabe extends ModelePDFFactures
// We found a page break
// Allows data in the first page if description is long enough to break in multiples pages
- if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
+ if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
$showpricebeforepagebreak = 1;
else
$showpricebeforepagebreak = 0;
@@ -1051,15 +1051,15 @@ class pdf_crabe extends ModelePDFFactures
$pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
// Show online payment link
- $useonlinepayment = ((! empty($conf->paypal->enabled) || ! empty($conf->stripe->enabled) || ! empty($conf->paybox->enabled)) && !empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT));
+ $useonlinepayment = ((!empty($conf->paypal->enabled) || !empty($conf->stripe->enabled) || !empty($conf->paybox->enabled)) && !empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT));
if (($object->mode_reglement_code == 'CB' || $object->mode_reglement_code == 'VAD') && $object->statut != Facture::STATUS_DRAFT && $useonlinepayment) {
require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
global $langs;
$langs->loadLangs(array('payment', 'paybox'));
- $servicename=$langs->transnoentities('Online');
+ $servicename = $langs->transnoentities('Online');
$paiement_url = getOnlinePaymentUrl('', 'invoice', $object->ref, '', '', '');
- $linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' '.$outputlangs->transnoentities("ClickHere").' ';
+ $linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' '.$outputlangs->transnoentities("ClickHere").' ';
$pdf->writeHTMLCell(80, 10, '', '', dol_htmlentitiesbr($linktopay), 0, 1);
}
@@ -1115,10 +1115,9 @@ class pdf_crabe extends ModelePDFFactures
// If payment mode not forced or forced to VIR, show payment with BAN
if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR')
{
- if (!empty($object->fk_account) || !empty($object->fk_bank) || !empty($conf->global->FACTURE_RIB_NUMBER))
- {
- $bankid = (empty($object->fk_account) ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
- if (!empty($object->fk_bank)) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
+ if ($object->fk_account > 0 || $object->fk_bank > 0 || !empty($conf->global->FACTURE_RIB_NUMBER)) {
+ $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
+ if ($object->fk_bank > 0) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
$account = new Account($this->db);
$account->fetch($bankid);
@@ -1707,6 +1706,30 @@ class pdf_crabe extends ModelePDFFactures
$pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R');
}
+ if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE))
+ {
+ $object->fetch_projet();
+ if (!empty($object->project->ref))
+ {
+ $posy += 3;
+ $pdf->SetXY($posx, $posy);
+ $pdf->SetTextColor(0, 0, 60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R');
+ }
+ }
+
+ if (!empty($conf->global->PDF_SHOW_PROJECT))
+ {
+ $object->fetch_projet();
+ if (!empty($object->project->ref))
+ {
+ $posy += 3;
+ $pdf->SetXY($posx, $posy);
+ $pdf->SetTextColor(0, 0, 60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R');
+ }
+ }
+
$objectidnext = $object->getIdReplacingInvoice('validated');
if ($object->type == 0 && $objectidnext)
{
diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
index 60d4650921b..220c83d5d63 100644
--- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
+++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
@@ -126,10 +126,11 @@ class pdf_sponge extends ModelePDFFactures
*/
public $situationinvoice;
+
/**
- * @var float X position for the situation progress column
+ * @var array of document table collumns
*/
- public $posxprogress;
+ public $cols;
/**
@@ -396,7 +397,7 @@ class pdf_sponge extends ModelePDFFactures
if (!empty($tplidx)) $pdf->useTemplate($tplidx);
$pagenb++;
- $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
+ $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs, $outputlangsbis);
$pdf->SetFont('', '', $default_font_size - 1);
$pdf->MultiCell(0, 3, ''); // Set interline to 3
$pdf->SetTextColor(0, 0, 0);
@@ -407,6 +408,8 @@ class pdf_sponge extends ModelePDFFactures
$tab_height_newpage = 150;
if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $tab_height_newpage -= $top_shift;
+ $nexY = $tab_top - 1;
+
// Incoterm
$height_incoterms = 0;
if ($conf->incoterm->enabled)
@@ -444,6 +447,13 @@ class pdf_sponge extends ModelePDFFactures
}
}
+ // Extrafields in note
+ $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
+ if (!empty($extranote))
+ {
+ $notetoshow = dol_concatdesc($notetoshow, $extranote);
+ }
+
$pagenb = $pdf->getPage();
if ($notetoshow)
{
@@ -572,9 +582,7 @@ class pdf_sponge extends ModelePDFFactures
$this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
$pdf->rollbackTransaction(true);
- $iniY = $tab_top + $this->tabTitleHeight + 2;
- $curY = $tab_top + $this->tabTitleHeight + 2;
- $nexY = $tab_top + $this->tabTitleHeight + 2;
+ $nexY = $tab_top + $this->tabTitleHeight;
// Loop on each lines
$pageposbeforeprintlines = $pdf->getPage();
@@ -595,7 +603,6 @@ class pdf_sponge extends ModelePDFFactures
$showpricebeforepagebreak = 1;
$posYAfterImage = 0;
- $posYAfterDescription = 0;
if ($this->getColumnStatus('photo'))
{
@@ -609,7 +616,7 @@ class pdf_sponge extends ModelePDFFactures
$curY = $tab_top_newpage;
// Allows data in the first page if description is long enough to break in multiples pages
- if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
+ if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
$showpricebeforepagebreak = 1;
else
$showpricebeforepagebreak = 0;
@@ -627,15 +634,17 @@ class pdf_sponge extends ModelePDFFactures
if ($this->getColumnStatus('desc'))
{
$pdf->startTransaction();
- pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc);
+
+ $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
$pageposafter = $pdf->getPage();
+
if ($pageposafter > $pageposbefore) // There is a pagebreak
{
$pdf->rollbackTransaction(true);
- $pageposafter = $pageposbefore;
- //print $pageposafter.'-'.$pageposbefore;exit;
$pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
- pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc);
+
+ $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
+
$pageposafter = $pdf->getPage();
$posyafter = $pdf->GetY();
//var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
@@ -652,7 +661,7 @@ class pdf_sponge extends ModelePDFFactures
{
// We found a page break
// Allows data in the first page if description is long enough to break in multiples pages
- if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
+ if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
$showpricebeforepagebreak = 1;
else
$showpricebeforepagebreak = 0;
@@ -662,10 +671,9 @@ class pdf_sponge extends ModelePDFFactures
{
$pdf->commitTransaction();
}
- $posYAfterDescription = $pdf->GetY();
}
- $nexY = $pdf->GetY();
+ $nexY = $pdf->GetY();
$pageposafter = $pdf->getPage();
$pdf->setPage($pageposbefore);
$pdf->setTopMargin($this->marge_haute);
@@ -735,6 +743,18 @@ class pdf_sponge extends ModelePDFFactures
$nexY = max($pdf->GetY(), $nexY);
}
+ // Extrafields
+ if(!empty($object->lines[$i]->array_options)){
+ foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue){
+ if ($this->getColumnStatus($extrafieldColKey))
+ {
+ $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey);
+ $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
+ $nexY = max($pdf->GetY(), $nexY);
+ }
+ }
+ }
+
$parameters = array(
'object' => $object,
@@ -803,21 +823,19 @@ class pdf_sponge extends ModelePDFFactures
$pdf->setPage($pageposafter);
$pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
//$pdf->SetDrawColor(190,190,200);
- $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1);
+ $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY);
$pdf->SetLineStyle(array('dash'=>0));
}
- $nexY += 2; // Add space between lines
-
// Detect if some page were added automatically and output _tableau for past pages
while ($pagenb < $pageposafter) {
$pdf->setPage($pagenb);
if ($pagenb == $pageposbeforeprintlines) {
- $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code);
+ $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
}
else
{
- $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
+ $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
}
$this->_pagefoot($pdf, $object, $outputlangs, 1);
$pagenb++;
@@ -828,11 +846,11 @@ class pdf_sponge extends ModelePDFFactures
if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
if ($pagenb == $pageposafter) {
- $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code);
+ $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
}
else
{
- $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
+ $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
}
$this->_pagefoot($pdf, $object, $outputlangs, 1);
// New page
@@ -846,12 +864,12 @@ class pdf_sponge extends ModelePDFFactures
// Show square
if ($pagenb == $pageposbeforeprintlines)
{
- $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code);
+ $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis);
$bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
}
else
{
- $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
+ $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis);
$bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
}
@@ -1052,7 +1070,7 @@ class pdf_sponge extends ModelePDFFactures
/**
* Show miscellaneous information (payment mode, payment term, ...)
*
- * @param PDF $pdf Object PDF
+ * @param tcpdf $pdf Object PDF
* @param Object $object Object to show
* @param int $posy Y
* @param Translate $outputlangs Langs object
@@ -1132,33 +1150,33 @@ class pdf_sponge extends ModelePDFFactures
$pdf->SetFont('', '', $default_font_size - 2);
$pdf->SetXY($posxval, $posy);
- $lib_mode_reg=$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code)!=('PaymentType'.$object->mode_reglement_code)?$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code):$outputlangs->convToOutputCharset($object->mode_reglement);
+ $lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != ('PaymentType'.$object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement);
$pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
// Show online payment link
- $useonlinepayment = ((! empty($conf->paypal->enabled) || ! empty($conf->stripe->enabled) || ! empty($conf->paybox->enabled)) && !empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT));
+ $useonlinepayment = ((!empty($conf->paypal->enabled) || !empty($conf->stripe->enabled) || !empty($conf->paybox->enabled)) && !empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT));
if (($object->mode_reglement_code == 'CB' || $object->mode_reglement_code == 'VAD') && $object->statut != Facture::STATUS_DRAFT && $useonlinepayment) {
require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
global $langs;
$langs->loadLangs(array('payment', 'paybox'));
- $servicename=$langs->transnoentities('Online');
+ $servicename = $langs->transnoentities('Online');
$paiement_url = getOnlinePaymentUrl('', 'invoice', $object->ref, '', '', '');
- $linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' '.$outputlangs->transnoentities("ClickHere").' ';
+ $linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' '.$outputlangs->transnoentities("ClickHere").' ';
$pdf->writeHTMLCell(80, 10, '', '', dol_htmlentitiesbr($linktopay), 0, 1);
}
- $posy=$pdf->GetY()+2;
+ $posy = $pdf->GetY() + 2;
}
// Show payment mode CHQ
if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ')
{
// If payment mode unregulated or payment mode forced to CHQ
- if (! empty($conf->global->FACTURE_CHQ_NUMBER))
+ if (!empty($conf->global->FACTURE_CHQ_NUMBER))
{
- $diffsizetitle=(empty($conf->global->PDF_DIFFSIZE_TITLE)?3:$conf->global->PDF_DIFFSIZE_TITLE);
+ $diffsizetitle = (empty($conf->global->PDF_DIFFSIZE_TITLE) ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
if ($conf->global->FACTURE_CHQ_NUMBER > 0)
{
@@ -1199,10 +1217,9 @@ class pdf_sponge extends ModelePDFFactures
// If payment mode not forced or forced to VIR, show payment with BAN
if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR')
{
- if (!empty($object->fk_account) || !empty($object->fk_bank) || !empty($conf->global->FACTURE_RIB_NUMBER))
- {
- $bankid = (empty($object->fk_account) ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
- if (!empty($object->fk_bank)) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
+ if ($object->fk_account > 0 || $object->fk_bank > 0 || !empty($conf->global->FACTURE_RIB_NUMBER)) {
+ $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
+ if ($object->fk_bank > 0) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
$account = new Account($this->db);
$account->fetch($bankid);
@@ -1223,7 +1240,7 @@ class pdf_sponge extends ModelePDFFactures
/**
* Show total to pay
*
- * @param PDF $pdf Object PDF
+ * @param TCPDI $pdf Object PDF
* @param Facture $object Object invoice
* @param int $deja_regle Amount already paid (in the currency of invoice)
* @param int $posy Position depart
@@ -1789,7 +1806,7 @@ class pdf_sponge extends ModelePDFFactures
/**
* Show table for lines
*
- * @param PDF $pdf Object PDF
+ * @param tcpdf $pdf Object PDF
* @param string $tab_top Top position of table
* @param string $tab_height Height of table (rectangle)
* @param int $nexY Y (not used)
@@ -1797,9 +1814,10 @@ class pdf_sponge extends ModelePDFFactures
* @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title
* @param int $hidebottom Hide bottom bar of array
* @param string $currency Currency code
+ * @param Translate $outputlangsbis Langs object bis
* @return void
*/
- protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '')
+ protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
{
global $conf;
@@ -1817,6 +1835,10 @@ class pdf_sponge extends ModelePDFFactures
if (empty($hidetop))
{
$titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
+ if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
+ $titre .= ' - '.$outputlangsbis->transnoentities("AmountInCurrency", $outputlangsbis->transnoentitiesnoconv("Currency".$currency));
+ }
+
$pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
$pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
@@ -1844,13 +1866,14 @@ class pdf_sponge extends ModelePDFFactures
/**
* Show top header of page.
*
- * @param PDF $pdf Object PDF
+ * @param Tcpdf $pdf Object PDF
* @param Object $object Object to show
* @param int $showaddress 0=no, 1=yes
* @param Translate $outputlangs Object lang for output
+ * @param Translate $outputlangsbis Object lang for output bis
* @return void
*/
- protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
+ protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null)
{
global $conf, $langs;
@@ -1920,6 +1943,17 @@ class pdf_sponge extends ModelePDFFactures
if ($object->type == 3) $title = $outputlangs->transnoentities("InvoiceDeposit");
if ($object->type == 4) $title = $outputlangs->transnoentities("InvoiceProForma");
if ($this->situationinvoice) $title = $outputlangs->transnoentities("InvoiceSituation");
+ if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
+ $title .= ' - ';
+ if ($object->type == 0) {
+ if ($this->situationinvoice) $title .= $outputlangsbis->transnoentities("InvoiceSituation");
+ $title .= $outputlangsbis->transnoentities("PdfInvoiceTitle");
+ }
+ elseif ($object->type == 1) $title .= $outputlangsbis->transnoentities("InvoiceReplacement");
+ elseif ($object->type == 2) $title .= $outputlangsbis->transnoentities("InvoiceAvoir");
+ elseif ($object->type == 3) $title .= $outputlangsbis->transnoentities("InvoiceDeposit");
+ elseif ($object->type == 4) $title .= $outputlangsbis->transnoentities("InvoiceProForma");
+ }
$pdf->MultiCell($w, 3, $title, '', 'R');
$pdf->SetFont('', 'B', $default_font_size);
@@ -1946,6 +1980,30 @@ class pdf_sponge extends ModelePDFFactures
$pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R');
}
+ if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE))
+ {
+ $object->fetch_projet();
+ if (!empty($object->project->ref))
+ {
+ $posy += 3;
+ $pdf->SetXY($posx, $posy);
+ $pdf->SetTextColor(0, 0, 60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R');
+ }
+ }
+
+ if (!empty($conf->global->PDF_SHOW_PROJECT))
+ {
+ $object->fetch_projet();
+ if (!empty($object->project->ref))
+ {
+ $posy += 3;
+ $pdf->SetXY($posx, $posy);
+ $pdf->SetTextColor(0, 0, 60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R');
+ }
+ }
+
$objectidnext = $object->getIdReplacingInvoice('validated');
if ($object->type == 0 && $objectidnext)
{
@@ -2156,7 +2214,7 @@ class pdf_sponge extends ModelePDFFactures
// Default field style for content
$this->defaultContentsFieldsStyle = array(
'align' => 'R', // R,C,L
- 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
);
// Default field style for content
@@ -2197,6 +2255,7 @@ class pdf_sponge extends ModelePDFFactures
),
'content' => array(
'align' => 'L',
+ 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
),
);
@@ -2304,7 +2363,7 @@ class pdf_sponge extends ModelePDFFactures
$this->cols['discount']['status'] = true;
}
- $rank = $rank + 10;
+ $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100
$this->cols['totalexcltax'] = array(
'rank' => $rank,
'width' => 26, // in mm
@@ -2315,6 +2374,11 @@ class pdf_sponge extends ModelePDFFactures
'border-left' => true, // add left line separator
);
+ // Add extrafields cols
+ if(!empty($object->lines)) {
+ $line = reset($object->lines);
+ $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
+ }
$parameters = array(
'object' => $object,
diff --git a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php
index ff7bff51230..ff913d724f8 100644
--- a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php
+++ b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php
@@ -108,7 +108,7 @@ class pdf_soleil extends ModelePDFFicheinter
/**
* Issuer
- * @var Company object that emits
+ * @var Societe Object that emits
*/
public $emetteur;
diff --git a/htdocs/core/modules/fichinter/mod_arctic.php b/htdocs/core/modules/fichinter/mod_arctic.php
index e8d2aeff63e..f2f3a135785 100644
--- a/htdocs/core/modules/fichinter/mod_arctic.php
+++ b/htdocs/core/modules/fichinter/mod_arctic.php
@@ -46,7 +46,7 @@ class mod_arctic extends ModeleNumRefFicheinter
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom = 'arctic';
diff --git a/htdocs/core/modules/fichinter/mod_pacific.php b/htdocs/core/modules/fichinter/mod_pacific.php
index 97784ce0639..3ecd3d6833d 100644
--- a/htdocs/core/modules/fichinter/mod_pacific.php
+++ b/htdocs/core/modules/fichinter/mod_pacific.php
@@ -46,7 +46,7 @@ class mod_pacific extends ModeleNumRefFicheinter
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='pacific';
diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php
index 93d68691a11..6c9dd9062a8 100644
--- a/htdocs/core/modules/import/import_csv.modules.php
+++ b/htdocs/core/modules/import/import_csv.modules.php
@@ -425,6 +425,7 @@ class ImportCsv extends ModeleImports
// New val can be an id or ref. If it start with id: it is forced to id, if it start with ref: it is forced to ref. It not, we try to guess.
$isidorref = 'id';
if (!is_numeric($newval) && $newval != '' && !preg_match('/^id:/i', $newval)) $isidorref = 'ref';
+
$newval = preg_replace('/^(id|ref):/i', '', $newval); // Remove id: or ref: that was used to force if field is id or ref
//print 'Val is now '.$newval.' and is type '.$isidorref." \n";
@@ -448,8 +449,7 @@ class ImportCsv extends ModeleImports
$classinstance = new $class($this->db);
// Try the fetch from code or ref
$param_array = array('', $newval);
- if ($class == 'AccountingAccount')
- {
+ if ($class == 'AccountingAccount') {
//var_dump($arrayrecord[0]['val']);
/*include_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancysystem.class.php';
$tmpchartofaccount = new AccountancySystem($this->db);
@@ -464,6 +464,7 @@ class ImportCsv extends ModeleImports
}*/
$param_array = array('', $newval, 0, $arrayrecord[0]['val']); // Param to fetch parent from account, in chart.
}
+
call_user_func_array(array($classinstance, $method), $param_array);
// If not found, try the fetch from label
if (! ($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel')
diff --git a/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php b/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php
index 9c80c6a9020..cdbb2cd0bb7 100644
--- a/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php
+++ b/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php
@@ -107,7 +107,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
/**
* Issuer
- * @var Company object that emits
+ * @var Societe Object that emits
*/
public $emetteur;
diff --git a/htdocs/core/modules/mailings/modules_mailings.php b/htdocs/core/modules/mailings/modules_mailings.php
index d6cae560298..ffba2571d23 100644
--- a/htdocs/core/modules/mailings/modules_mailings.php
+++ b/htdocs/core/modules/mailings/modules_mailings.php
@@ -39,9 +39,9 @@ class MailingTargets // This can't be abstract as it is used for some method
/**
* @var string Error code (or message)
*/
- public $error='';
+ public $error = '';
- public $tooltip='';
+ public $tooltip = '';
/**
@@ -64,12 +64,12 @@ class MailingTargets // This can't be abstract as it is used for some method
global $langs, $form;
$langs->load("mails");
- $transstring="MailingModuleDesc".$this->name;
- $s='';
+ $transstring = "MailingModuleDesc".$this->name;
+ $s = '';
- if ($langs->trans($this->name) != $this->name) $s=$langs->trans($this->name);
- elseif ($langs->trans($transstring) != $transstring) $s=$langs->trans($transstring);
- else $s=$this->desc;
+ if ($langs->trans($this->name) != $this->name) $s = $langs->trans($this->name);
+ elseif ($langs->trans($transstring) != $transstring) $s = $langs->trans($transstring);
+ else $s = $this->desc;
if ($this->tooltip && is_object($form)) $s .= ' '.$form->textwithpicto('', $langs->trans($this->tooltip), 1, 1);
return $s;
@@ -93,7 +93,7 @@ class MailingTargets // This can't be abstract as it is used for some method
*/
public function getNbOfRecipients($sql)
{
- $result=$this->db->query($sql);
+ $result = $this->db->query($sql);
if ($result)
{
$obj = $this->db->fetch_object($result);
@@ -101,7 +101,7 @@ class MailingTargets // This can't be abstract as it is used for some method
}
else
{
- $this->error=$this->db->lasterror();
+ $this->error = $this->db->lasterror();
return -1;
}
}
@@ -130,18 +130,18 @@ class MailingTargets // This can't be abstract as it is used for some method
// Mise a jour nombre de destinataire dans table des mailings
$sql = "SELECT COUNT(*) nb FROM ".MAIN_DB_PREFIX."mailing_cibles";
$sql .= " WHERE fk_mailing = ".$mailing_id;
- $result=$this->db->query($sql);
+ $result = $this->db->query($sql);
if ($result)
{
- $obj=$this->db->fetch_object($result);
- $nb=$obj->nb;
+ $obj = $this->db->fetch_object($result);
+ $nb = $obj->nb;
$sql = "UPDATE ".MAIN_DB_PREFIX."mailing";
$sql .= " SET nbemail = ".$nb." WHERE rowid = ".$mailing_id;
if (!$this->db->query($sql))
{
dol_syslog($this->db->error());
- $this->error=$this->db->error();
+ $this->error = $this->db->error();
return -1;
}
}
@@ -169,26 +169,26 @@ class MailingTargets // This can't be abstract as it is used for some method
$num = count($cibles);
foreach ($cibles as $targetarray)
{
- if (! empty($targetarray['email'])) // avoid empty email address
+ if (!empty($targetarray['email'])) // avoid empty email address
{
$sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing_cibles";
- $sql.= " (fk_mailing,";
- $sql.= " fk_contact,";
- $sql.= " lastname, firstname, email, other, source_url, source_id,";
- $sql.= " tag,";
- $sql.= " source_type)";
- $sql.= " VALUES (".$mailing_id.",";
- $sql.= (empty($targetarray['fk_contact']) ? '0' : "'".$targetarray['fk_contact']."'") .",";
- $sql.= "'".$this->db->escape($targetarray['lastname'])."',";
- $sql.= "'".$this->db->escape($targetarray['firstname'])."',";
- $sql.= "'".$this->db->escape($targetarray['email'])."',";
- $sql.= "'".$this->db->escape($targetarray['other'])."',";
- $sql.= "'".$this->db->escape($targetarray['source_url'])."',";
- $sql.= (empty($targetarray['source_id']) ? 'null' : "'".$this->db->escape($targetarray['source_id'])."'").",";
+ $sql .= " (fk_mailing,";
+ $sql .= " fk_contact,";
+ $sql .= " lastname, firstname, email, other, source_url, source_id,";
+ $sql .= " tag,";
+ $sql .= " source_type)";
+ $sql .= " VALUES (".$mailing_id.",";
+ $sql .= (empty($targetarray['fk_contact']) ? '0' : "'".$targetarray['fk_contact']."'").",";
+ $sql .= "'".$this->db->escape($targetarray['lastname'])."',";
+ $sql .= "'".$this->db->escape($targetarray['firstname'])."',";
+ $sql .= "'".$this->db->escape($targetarray['email'])."',";
+ $sql .= "'".$this->db->escape($targetarray['other'])."',";
+ $sql .= "'".$this->db->escape($targetarray['source_url'])."',";
+ $sql .= (empty($targetarray['source_id']) ? 'null' : "'".$this->db->escape($targetarray['source_id'])."'").",";
$sql .= "'".$this->db->escape(dol_hash($targetarray['email'].';'.$targetarray['lastname'].';'.$mailing_id.';'.$conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY))."',";
$sql .= "'".$this->db->escape($targetarray['source_type'])."')";
- dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
- $result=$this->db->query($sql);
+ dol_syslog(__METHOD__, LOG_DEBUG);
+ $result = $this->db->query($sql);
if ($result)
{
$j++;
@@ -199,7 +199,7 @@ class MailingTargets // This can't be abstract as it is used for some method
{
// Si erreur autre que doublon
dol_syslog($this->db->error().' : '.$targetarray['email']);
- $this->error=$this->db->error().' : '.$targetarray['email'];
+ $this->error = $this->db->error().' : '.$targetarray['email'];
$this->db->rollback();
return -1;
}
@@ -207,7 +207,7 @@ class MailingTargets // This can't be abstract as it is used for some method
}
}
- dol_syslog(get_class($this)."::".__METHOD__.": mailing ".$j." targets added");
+ dol_syslog(__METHOD__.": mailing ".$j." targets added");
/*
//Update the status to show thirdparty mail that don't want to be contacted anymore'
@@ -215,7 +215,7 @@ class MailingTargets // This can't be abstract as it is used for some method
$sql .= " SET statut=3";
$sql .= " WHERE fk_mailing=".$mailing_id." AND email in (SELECT email FROM ".MAIN_DB_PREFIX."societe where fk_stcomm=-1)";
$sql .= " AND source_type='thirdparty'";
- dol_syslog(get_class($this)."::".__METHOD__.": mailing update status to display thirdparty mail that do not want to be contacted");
+ dol_syslog(__METHOD__.": mailing update status to display thirdparty mail that do not want to be contacted");
$result=$this->db->query($sql);
//Update the status to show contact mail that don't want to be contacted anymore'
@@ -223,7 +223,7 @@ class MailingTargets // This can't be abstract as it is used for some method
$sql .= " SET statut=3";
$sql .= " WHERE fk_mailing=".$mailing_id." AND source_type='contact' AND (email in (SELECT sc.email FROM ".MAIN_DB_PREFIX."socpeople AS sc ";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid=sc.fk_soc WHERE s.fk_stcomm=-1 OR no_email=1))";
- dol_syslog(get_class($this)."::".__METHOD__.": mailing update status to display contact mail that do not want to be contacted",LOG_DEBUG);
+ dol_syslog(__METHOD__.": mailing update status to display contact mail that do not want to be contacted",LOG_DEBUG);
$result=$this->db->query($sql);
*/
@@ -231,9 +231,9 @@ class MailingTargets // This can't be abstract as it is used for some method
$sql .= " SET statut=3";
$sql .= " WHERE fk_mailing=".$mailing_id." AND email IN (SELECT mu.email FROM ".MAIN_DB_PREFIX."mailing_unsubscribe AS mu WHERE mu.entity IN ('".getEntity('mailing')."'))";
- dol_syslog(get_class($this)."::".__METHOD__.":mailing update status to display emails that do not want to be contacted anymore", LOG_DEBUG);
- $result=$this->db->query($sql);
- if (! $result)
+ dol_syslog(__METHOD__.":mailing update status to display emails that do not want to be contacted anymore", LOG_DEBUG);
+ $result = $this->db->query($sql);
+ if (!$result)
{
dol_print_error($this->db);
}
@@ -258,7 +258,7 @@ class MailingTargets // This can't be abstract as it is used for some method
$sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_cibles";
$sql .= " WHERE fk_mailing = ".$mailing_id;
- if (! $this->db->query($sql))
+ if (!$this->db->query($sql))
{
dol_syslog($this->db->error());
}
diff --git a/htdocs/core/modules/modAccounting.class.php b/htdocs/core/modules/modAccounting.class.php
index 70b461d6048..2ab0429fe5f 100644
--- a/htdocs/core/modules/modAccounting.class.php
+++ b/htdocs/core/modules/modAccounting.class.php
@@ -258,9 +258,9 @@ class modAccounting extends DolibarrModules
$this->export_label[$r]='Chartofaccounts';
$this->export_icon[$r]='accounting';
$this->export_permission[$r]=array(array("accounting","chartofaccount"));
- $this->export_fields_array[$r]=array('ac.rowid'=>'ChartofaccountsId','ac.pcg_version'=>'Chartofaccounts','aa.rowid'=>'Id','aa.account_number'=>"AccountAccounting",'aa.label'=>"Label",'aa.account_parent'=>"Accountparent",'aa.pcg_type'=>"Pcgtype",'aa.pcg_subtype'=>'Pcgsubtype','aa.active'=>'Status');
- $this->export_TypeFields_array[$r]=array('ac.rowid'=>'List:accounting_system:pcg_version','aa.account_number'=>"Text",'aa.label'=>"Text",'aa.account_parent'=>"Text",'aa.pcg_type'=>'Text','aa.pcg_subtype'=>'Text','aa.active'=>'Status');
- $this->export_entities_array[$r]=array('ac.rowid'=>"Accounting",'ac.pcg_version'=>"Accounting",'aa.rowid'=>'Accounting','aa.account_number'=>"Accounting",'aa.label'=>"Accounting",'aa.accountparent'=>"Accounting",'aa.pcg_type'=>"Accounting",'aa.pcgsubtype'=>"Accounting",'aa_active'=>"Accounting");
+ $this->export_fields_array[$r]=array('ac.rowid'=>'ChartofaccountsId','ac.pcg_version'=>'Chartofaccounts','aa.rowid'=>'Id','aa.account_number'=>"AccountAccounting",'aa.label'=>"Label",'aa.account_parent'=>"Accountparent",'aa.pcg_type'=>"Pcgtype",'aa.active'=>'Status');
+ $this->export_TypeFields_array[$r]=array('ac.rowid'=>'List:accounting_system:pcg_version','aa.account_number'=>"Text",'aa.label'=>"Text",'aa.account_parent'=>"Text",'aa.pcg_type'=>'Text','aa.active'=>'Status');
+ $this->export_entities_array[$r]=array('ac.rowid'=>"Accounting",'ac.pcg_version'=>"Accounting",'aa.rowid'=>'Accounting','aa.account_number'=>"Accounting",'aa.label'=>"Accounting",'aa.accountparent'=>"Accounting",'aa.pcg_type'=>"Accounting",'aa_active'=>"Accounting");
$this->export_sql_start[$r]='SELECT DISTINCT ';
$this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'accounting_account as aa';
@@ -320,13 +320,13 @@ class modAccounting extends DolibarrModules
$this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon
$this->import_tables_array[$r]=array('aa'=>MAIN_DB_PREFIX.'accounting_account');
$this->import_tables_creator_array[$r]=array('aa'=>'fk_user_author'); // Fields to store import user id
- $this->import_fields_array[$r]=array('aa.fk_pcg_version'=>"Chartofaccounts*",'aa.account_number'=>"AccountAccounting*",'aa.label'=>"Label*",'aa.account_parent'=>"Accountparent","aa.fk_accounting_category"=>"AccountingCategory","aa.pcg_type"=>"Pcgtype*",'aa.pcg_subtype'=>'Pcgsubtype*','aa.active'=>'Status*','aa.datec'=>"DateCreation");
- $this->import_regex_array[$r]=array('aa.fk_pcg_version'=>'pcg_version@'.MAIN_DB_PREFIX.'accounting_system','aa.account_number'=>'^.{1,32}$','aa.label'=>'^.{1,255}$','aa.account_parent'=>'^.{0,32}$','aa.fk_accounting_category'=>'rowid@'.MAIN_DB_PREFIX.'c_accounting_category','aa.pcg_type'=>'^.{1,20}$','aa.pcg_subtype'=>'^.{1,20}$','aa.active'=>'^0|1$','aa.datec'=>'^\d{4}-\d{2}-\d{2}$');
+ $this->import_fields_array[$r]=array('aa.fk_pcg_version'=>"Chartofaccounts*",'aa.account_number'=>"AccountAccounting*",'aa.label'=>"Label*",'aa.account_parent'=>"Accountparent","aa.fk_accounting_category"=>"AccountingCategory","aa.pcg_type"=>"Pcgtype*",'aa.active'=>'Status*','aa.datec'=>"DateCreation");
+ $this->import_regex_array[$r]=array('aa.fk_pcg_version'=>'pcg_version@'.MAIN_DB_PREFIX.'accounting_system','aa.account_number'=>'^.{1,32}$','aa.label'=>'^.{1,255}$','aa.account_parent'=>'^.{0,32}$','aa.fk_accounting_category'=>'rowid@'.MAIN_DB_PREFIX.'c_accounting_category','aa.pcg_type'=>'^.{1,20}$','aa.active'=>'^0|1$','aa.datec'=>'^\d{4}-\d{2}-\d{2}$');
$this->import_convertvalue_array[$r]=array(
'aa.account_parent'=>array('rule'=>'fetchidfromref','classfile'=>'/accountancy/class/accountingaccount.class.php','class'=>'AccountingAccount','method'=>'fetch','element'=>'AccountingAccount'),
'aa.fk_accounting_category'=>array('rule'=>'fetchidfromcodeorlabel','classfile'=>'/accountancy/class/accountancycategory.class.php','class'=>'AccountancyCategory','method'=>'fetch','dict'=>'DictionaryAccountancyCategory'),
);
- $this->import_examplevalues_array[$r]=array('aa.fk_pcg_version'=>"PCG99-ABREGE",'aa.account_number'=>"707",'aa.label'=>"Product sales",'aa.account_parent'=>"ref:7 or id:1407","aa.fk_accounting_category"=>"","aa.pcg_type"=>"PROD",'aa.pcg_subtype'=>'PRODUCT','aa.active'=>'1','aa.datec'=>"2017-04-28");
+ $this->import_examplevalues_array[$r]=array('aa.fk_pcg_version'=>"PCG99-ABREGE",'aa.account_number'=>"707",'aa.label'=>"Product sales",'aa.account_parent'=>"ref:7 or id:1407","aa.fk_accounting_category"=>"","aa.pcg_type"=>"PROD",'aa.active'=>'1','aa.datec'=>"2017-04-28");
$this->import_updatekeys_array[$r]=array('aa.fk_pcg_version'=>'Chartofaccounts','aa.account_number'=>'AccountAccounting');
}
}
diff --git a/htdocs/core/modules/modCategorie.class.php b/htdocs/core/modules/modCategorie.class.php
index b53a9630598..61a4dd67d5c 100644
--- a/htdocs/core/modules/modCategorie.class.php
+++ b/htdocs/core/modules/modCategorie.class.php
@@ -24,7 +24,7 @@
* \ingroup category
* \brief Fichier de description et activation du module Categorie
*/
-include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
+include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
/**
@@ -64,11 +64,11 @@ class modCategorie extends DolibarrModules
// Config pages
$this->config_page_url = array('categorie.php@categories');
- $this->langfiles = array("products","companies","categories","members");
+ $this->langfiles = array("products", "companies", "categories", "members");
// Constants
$this->const = array();
- $r=0;
+ $r = 0;
$this->const[$r][0] = "CATEGORIE_RECURSIV_ADD";
$this->const[$r][1] = "yesno";
$this->const[$r][2] = "0";
@@ -83,7 +83,7 @@ class modCategorie extends DolibarrModules
$this->rights = array();
$this->rights_class = 'categorie';
- $r=0;
+ $r = 0;
$this->rights[$r][0] = 241; // id de la permission
$this->rights[$r][1] = 'Lire les categories'; // libelle de la permission
@@ -109,115 +109,115 @@ class modCategorie extends DolibarrModules
// Menus
//-------
- $this->menu = 1; // This module add menu entries. They are coded into menu manager.
+ $this->menu = 1; // This module add menu entries. They are coded into menu manager.
// Exports
//--------
- $r=0;
+ $r = 0;
$r++;
- $this->export_code[$r]='category_'.$r;
- $this->export_label[$r]='CatSupList';
- $this->export_icon[$r]='category';
- $this->export_enabled[$r]='$conf->fournisseur->enabled';
- $this->export_permission[$r]=array(array("categorie","lire"),array("fournisseur","lire"));
- $this->export_fields_array[$r]=array(
- 'u.rowid'=>"CategId",'u.label'=>"Label",'u.description'=>"Description",'s.rowid'=>'IdThirdParty','s.nom'=>'Name','s.prefix_comm'=>"Prefix",
- 's.client'=>"Customer",'s.datec'=>"DateCreation",'s.tms'=>"DateLastModification",'s.code_client'=>"CustomerCode",'s.address'=>"Address",
- 's.zip'=>"Zip",'s.town'=>"Town",'c.label'=>"Country",'c.code'=>"CountryCode",'s.phone'=>"Phone",'s.fax'=>"Fax",'s.url'=>"Url",'s.email'=>"Email",
- 's.siret'=>"ProfId1",'s.siren'=>"ProfId2",'s.ape'=>"ProfId3",'s.idprof4'=>"ProfId4",'s.tva_intra'=>"VATIntraShort",'s.capital'=>"Capital",
+ $this->export_code[$r] = 'category_'.$r;
+ $this->export_label[$r] = 'CatSupList';
+ $this->export_icon[$r] = 'category';
+ $this->export_enabled[$r] = '$conf->fournisseur->enabled';
+ $this->export_permission[$r] = array(array("categorie", "lire"), array("fournisseur", "lire"));
+ $this->export_fields_array[$r] = array(
+ 'u.rowid'=>"CategId", 'u.label'=>"Label", 'u.description'=>"Description", 's.rowid'=>'IdThirdParty', 's.nom'=>'Name', 's.prefix_comm'=>"Prefix",
+ 's.client'=>"Customer", 's.datec'=>"DateCreation", 's.tms'=>"DateLastModification", 's.code_client'=>"CustomerCode", 's.address'=>"Address",
+ 's.zip'=>"Zip", 's.town'=>"Town", 'c.label'=>"Country", 'c.code'=>"CountryCode", 's.phone'=>"Phone", 's.fax'=>"Fax", 's.url'=>"Url", 's.email'=>"Email",
+ 's.siret'=>"ProfId1", 's.siren'=>"ProfId2", 's.ape'=>"ProfId3", 's.idprof4'=>"ProfId4", 's.tva_intra'=>"VATIntraShort", 's.capital'=>"Capital",
's.note_public'=>"NotePublic"
);
- $this->export_TypeFields_array[$r]=array(
- 'u.label'=>"Text",'u.description'=>"Text",'s.rowid'=>'List:societe:nom','s.nom'=>'Text','s.prefix_comm'=>"Text",'s.client'=>"Text",'s.datec'=>"Date",
- 's.tms'=>"Date",'s.code_client'=>"Text",'s.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'c.label'=>"List:c_country:label:label",'c.code'=>"Text",
- 's.phone'=>"Text",'s.fax'=>"Text",'s.url'=>"Text",'s.email'=>"Text",'s.siret'=>"Text",'s.siren'=>"Text",'s.ape'=>"Text",'s.idprof4'=>"Text",
- 's.tva_intra'=>"Text",'s.capital'=>"Numeric",'s.note_public'=>"Text"
+ $this->export_TypeFields_array[$r] = array(
+ 'u.label'=>"Text", 'u.description'=>"Text", 's.rowid'=>'List:societe:nom', 's.nom'=>'Text', 's.prefix_comm'=>"Text", 's.client'=>"Text", 's.datec'=>"Date",
+ 's.tms'=>"Date", 's.code_client'=>"Text", 's.address'=>"Text", 's.zip'=>"Text", 's.town'=>"Text", 'c.label'=>"List:c_country:label:label", 'c.code'=>"Text",
+ 's.phone'=>"Text", 's.fax'=>"Text", 's.url'=>"Text", 's.email'=>"Text", 's.siret'=>"Text", 's.siren'=>"Text", 's.ape'=>"Text", 's.idprof4'=>"Text",
+ 's.tva_intra'=>"Text", 's.capital'=>"Numeric", 's.note_public'=>"Text"
);
- $this->export_entities_array[$r]=array(
- 's.rowid'=>'company','s.nom'=>'company','s.prefix_comm'=>"company",'s.client'=>"company",'s.datec'=>"company",'s.tms'=>"company",
- 's.code_client'=>"company",'s.address'=>"company",'s.zip'=>"company",'s.town'=>"company",'c.label'=>"company",'c.code'=>"company",
- 's.phone'=>"company",'s.fax'=>"company",'s.url'=>"company",'s.email'=>"company",'s.siret'=>"company",'s.siren'=>"company",'s.ape'=>"company",
- 's.idprof4'=>"company",'s.tva_intra'=>"company",'s.capital'=>"company",'s.note_public'=>"company"
- ); // We define here only fields that use another picto
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'categorie as u, ';
+ $this->export_entities_array[$r] = array(
+ 's.rowid'=>'company', 's.nom'=>'company', 's.prefix_comm'=>"company", 's.client'=>"company", 's.datec'=>"company", 's.tms'=>"company",
+ 's.code_client'=>"company", 's.address'=>"company", 's.zip'=>"company", 's.town'=>"company", 'c.label'=>"company", 'c.code'=>"company",
+ 's.phone'=>"company", 's.fax'=>"company", 's.url'=>"company", 's.email'=>"company", 's.siret'=>"company", 's.siren'=>"company", 's.ape'=>"company",
+ 's.idprof4'=>"company", 's.tva_intra'=>"company", 's.capital'=>"company", 's.note_public'=>"company"
+ ); // We define here only fields that use another picto
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'categorie as u, ';
$this->export_sql_end[$r] .= MAIN_DB_PREFIX.'categorie_fournisseur as cf, ';
$this->export_sql_end[$r] .= MAIN_DB_PREFIX.'societe as s LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code';
- $this->export_sql_end[$r] .=' WHERE u.rowid = cf.fk_categorie AND cf.fk_soc = s.rowid';
- $this->export_sql_end[$r] .=' AND u.entity IN ('.getEntity('category').')';
- $this->export_sql_end[$r] .=' AND u.type = 1'; // Supplier categories
+ $this->export_sql_end[$r] .= ' WHERE u.rowid = cf.fk_categorie AND cf.fk_soc = s.rowid';
+ $this->export_sql_end[$r] .= ' AND u.entity IN ('.getEntity('category').')';
+ $this->export_sql_end[$r] .= ' AND u.type = 1'; // Supplier categories
$r++;
- $this->export_code[$r]='category_'.$r;
- $this->export_label[$r]='CatCusList';
- $this->export_icon[$r]='category';
- $this->export_enabled[$r]='$conf->societe->enabled';
- $this->export_permission[$r]=array(array("categorie","lire"),array("societe","lire"));
- $this->export_fields_array[$r]=array(
- 'u.rowid'=>"CategId",'u.label'=>"Label",'u.description'=>"Description",'s.rowid'=>'IdThirdParty','s.nom'=>'Name','s.prefix_comm'=>"Prefix",
- 's.client'=>"Customer",'s.datec'=>"DateCreation",'s.tms'=>"DateLastModification",'s.code_client'=>"CustomerCode",'s.address'=>"Address",
- 's.zip'=>"Zip",'s.town'=>"Town",'c.label'=>"Country",'c.code'=>"CountryCode",'s.phone'=>"Phone",'s.fax'=>"Fax",'s.url'=>"Url",'s.email'=>"Email",
- 's.siret'=>"ProfId1",'s.siren'=>"ProfId2",'s.ape'=>"ProfId3",'s.idprof4'=>"ProfId4",'s.tva_intra'=>"VATIntraShort",'s.capital'=>"Capital",
- 's.note_public'=>"NotePublic",'s.fk_prospectlevel'=>'ProspectLevel','s.fk_stcomm'=>'ProspectStatus'
+ $this->export_code[$r] = 'category_'.$r;
+ $this->export_label[$r] = 'CatCusList';
+ $this->export_icon[$r] = 'category';
+ $this->export_enabled[$r] = '$conf->societe->enabled';
+ $this->export_permission[$r] = array(array("categorie", "lire"), array("societe", "lire"));
+ $this->export_fields_array[$r] = array(
+ 'u.rowid'=>"CategId", 'u.label'=>"Label", 'u.description'=>"Description", 's.rowid'=>'IdThirdParty', 's.nom'=>'Name', 's.prefix_comm'=>"Prefix",
+ 's.client'=>"Customer", 's.datec'=>"DateCreation", 's.tms'=>"DateLastModification", 's.code_client'=>"CustomerCode", 's.address'=>"Address",
+ 's.zip'=>"Zip", 's.town'=>"Town", 'c.label'=>"Country", 'c.code'=>"CountryCode", 's.phone'=>"Phone", 's.fax'=>"Fax", 's.url'=>"Url", 's.email'=>"Email",
+ 's.siret'=>"ProfId1", 's.siren'=>"ProfId2", 's.ape'=>"ProfId3", 's.idprof4'=>"ProfId4", 's.tva_intra'=>"VATIntraShort", 's.capital'=>"Capital",
+ 's.note_public'=>"NotePublic", 's.fk_prospectlevel'=>'ProspectLevel', 's.fk_stcomm'=>'ProspectStatus'
);
- $this->export_TypeFields_array[$r]=array(
- 'u.label'=>"Text",'u.description'=>"Text",'s.rowid'=>'List:societe:nom','s.nom'=>'Text','s.prefix_comm'=>"Text",'s.client'=>"Text",
- 's.datec'=>"Date",'s.tms'=>"Date",'s.code_client'=>"Text",'s.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'c.label'=>"List:c_country:label:label",
- 'c.code'=>"Text",'s.phone'=>"Text",'s.fax'=>"Text",'s.url'=>"Text",'s.email'=>"Text",'s.siret'=>"Text",'s.siren'=>"Text",'s.ape'=>"Text",
- 's.idprof4'=>"Text",'s.tva_intra'=>"Text",'s.capital'=>"Numeric",'s.note_public'=>"Text",'s.fk_prospectlevel'=>'List:c_prospectlevel:label:code',
+ $this->export_TypeFields_array[$r] = array(
+ 'u.label'=>"Text", 'u.description'=>"Text", 's.rowid'=>'List:societe:nom', 's.nom'=>'Text', 's.prefix_comm'=>"Text", 's.client'=>"Text",
+ 's.datec'=>"Date", 's.tms'=>"Date", 's.code_client'=>"Text", 's.address'=>"Text", 's.zip'=>"Text", 's.town'=>"Text", 'c.label'=>"List:c_country:label:label",
+ 'c.code'=>"Text", 's.phone'=>"Text", 's.fax'=>"Text", 's.url'=>"Text", 's.email'=>"Text", 's.siret'=>"Text", 's.siren'=>"Text", 's.ape'=>"Text",
+ 's.idprof4'=>"Text", 's.tva_intra'=>"Text", 's.capital'=>"Numeric", 's.note_public'=>"Text", 's.fk_prospectlevel'=>'List:c_prospectlevel:label:code',
's.fk_stcomm'=>'List:c_stcomm:libelle:code'
);
- $this->export_entities_array[$r]=array(
- 's.rowid'=>'company','s.nom'=>'company','s.prefix_comm'=>"company",'s.client'=>"company",'s.datec'=>"company",'s.tms'=>"company",
- 's.code_client'=>"company",'s.address'=>"company",'s.zip'=>"company",'s.town'=>"company",'c.label'=>"company",'c.code'=>"company",
- 's.phone'=>"company",'s.fax'=>"company",'s.url'=>"company",'s.email'=>"company",'s.siret'=>"company",'s.siren'=>"company",'s.ape'=>"company",
- 's.idprof4'=>"company",'s.tva_intra'=>"company",'s.capital'=>"company",'s.note_public'=>"company",'s.fk_prospectlevel'=>'company',
+ $this->export_entities_array[$r] = array(
+ 's.rowid'=>'company', 's.nom'=>'company', 's.prefix_comm'=>"company", 's.client'=>"company", 's.datec'=>"company", 's.tms'=>"company",
+ 's.code_client'=>"company", 's.address'=>"company", 's.zip'=>"company", 's.town'=>"company", 'c.label'=>"company", 'c.code'=>"company",
+ 's.phone'=>"company", 's.fax'=>"company", 's.url'=>"company", 's.email'=>"company", 's.siret'=>"company", 's.siren'=>"company", 's.ape'=>"company",
+ 's.idprof4'=>"company", 's.tva_intra'=>"company", 's.capital'=>"company", 's.note_public'=>"company", 's.fk_prospectlevel'=>'company',
's.fk_stcomm'=>'company'
- ); // We define here only fields that use another picto
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'categorie as u, ';
+ ); // We define here only fields that use another picto
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'categorie as u, ';
$this->export_sql_end[$r] .= MAIN_DB_PREFIX.'categorie_societe as cf, ';
$this->export_sql_end[$r] .= MAIN_DB_PREFIX.'societe as s LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extra ON s.rowid = extra.fk_object ';
- $this->export_sql_end[$r] .=' WHERE u.rowid = cf.fk_categorie AND cf.fk_soc = s.rowid';
- $this->export_sql_end[$r] .=' AND u.entity IN ('.getEntity('category').')';
- $this->export_sql_end[$r] .=' AND u.type = 2'; // Customer/Prospect categories
+ $this->export_sql_end[$r] .= ' WHERE u.rowid = cf.fk_categorie AND cf.fk_soc = s.rowid';
+ $this->export_sql_end[$r] .= ' AND u.entity IN ('.getEntity('category').')';
+ $this->export_sql_end[$r] .= ' AND u.type = 2'; // Customer/Prospect categories
// Add extra fields
- $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'societe' AND entity IN (0, ".$conf->entity.")";
- $resql=$this->db->query($sql);
+ $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'societe' AND entity IN (0, ".$conf->entity.")";
+ $resql = $this->db->query($sql);
if ($resql) // This can fail when class is used on old database (during migration for example)
{
- while ($obj=$this->db->fetch_object($resql))
+ while ($obj = $this->db->fetch_object($resql))
{
- $fieldname='extra.'.$obj->name;
- $fieldlabel=ucfirst($obj->label);
- $typeFilter="Text";
- switch($obj->type)
+ $fieldname = 'extra.'.$obj->name;
+ $fieldlabel = ucfirst($obj->label);
+ $typeFilter = "Text";
+ switch ($obj->type)
{
case 'int':
case 'double':
case 'price':
- $typeFilter="Numeric";
+ $typeFilter = "Numeric";
break;
case 'date':
case 'datetime':
- $typeFilter="Date";
+ $typeFilter = "Date";
break;
case 'boolean':
- $typeFilter="Boolean";
+ $typeFilter = "Boolean";
break;
case 'sellist':
- $typeFilter="List:".$obj->param;
+ $typeFilter = "List:".$obj->param;
break;
case 'select':
- $typeFilter="Select:".$obj->param;
+ $typeFilter = "Select:".$obj->param;
break;
}
- $this->export_fields_array[$r][$fieldname]=$fieldlabel;
- $this->export_TypeFields_array[$r][$fieldname]=$typeFilter;
- $this->export_entities_array[$r][$fieldname]='company';
+ $this->export_fields_array[$r][$fieldname] = $fieldlabel;
+ $this->export_TypeFields_array[$r][$fieldname] = $typeFilter;
+ $this->export_entities_array[$r][$fieldname] = 'company';
}
}
// End add axtra fields
@@ -227,42 +227,42 @@ class modCategorie extends DolibarrModules
$r++;
- $this->export_code[$r]='category_'.$r;
- $this->export_label[$r]='CatProdList';
- $this->export_icon[$r]='category';
- $this->export_enabled[$r]='$conf->product->enabled || $conf->service->enabled';
- $this->export_permission[$r]=array(array("categorie","lire"),array("produit","lire"));
- $this->export_fields_array[$r]=array('u.rowid'=>"CategId",'u.label'=>"Label",'u.description'=>"Description",'p.rowid'=>'ProductId','p.ref'=>'Ref');
- $this->export_TypeFields_array[$r]=array('u.label'=>"Text",'u.description'=>"Text",'p.ref'=>'Text');
- $this->export_entities_array[$r]=array('p.rowid'=>'product','p.ref'=>'product'); // We define here only fields that use another picto
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'categorie as u, '.MAIN_DB_PREFIX.'categorie_product as cp, '.MAIN_DB_PREFIX.'product as p';
- $this->export_sql_end[$r] .=' WHERE u.rowid = cp.fk_categorie AND cp.fk_product = p.rowid';
- $this->export_sql_end[$r] .=' AND u.entity IN ('.getEntity('category').')';
- $this->export_sql_end[$r] .=' AND u.type = 0'; // Supplier categories
+ $this->export_code[$r] = 'category_'.$r;
+ $this->export_label[$r] = 'CatProdList';
+ $this->export_icon[$r] = 'category';
+ $this->export_enabled[$r] = '$conf->product->enabled || $conf->service->enabled';
+ $this->export_permission[$r] = array(array("categorie", "lire"), array("produit", "lire"));
+ $this->export_fields_array[$r] = array('u.rowid'=>"CategId", 'u.label'=>"Label", 'u.description'=>"Description", 'p.rowid'=>'ProductId', 'p.ref'=>'Ref');
+ $this->export_TypeFields_array[$r] = array('u.label'=>"Text", 'u.description'=>"Text", 'p.ref'=>'Text');
+ $this->export_entities_array[$r] = array('p.rowid'=>'product', 'p.ref'=>'product'); // We define here only fields that use another picto
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'categorie as u, '.MAIN_DB_PREFIX.'categorie_product as cp, '.MAIN_DB_PREFIX.'product as p';
+ $this->export_sql_end[$r] .= ' WHERE u.rowid = cp.fk_categorie AND cp.fk_product = p.rowid';
+ $this->export_sql_end[$r] .= ' AND u.entity IN ('.getEntity('category').')';
+ $this->export_sql_end[$r] .= ' AND u.type = 0'; // Supplier categories
$r++;
- $this->export_code[$r]='category_'.$r;
- $this->export_label[$r]='CatMemberList';
- $this->export_icon[$r]='category';
- $this->export_enabled[$r]='$conf->adherent->enabled';
- $this->export_permission[$r]=array(array("categorie","lire"),array("adherent","lire"));
- $this->export_fields_array[$r]=array('u.rowid'=>"CategId",'u.label'=>"Label",'u.description'=>"Description",'p.rowid'=>'MemberId','p.lastname'=>'LastName','p.firstname'=>'Firstname');
- $this->export_TypeFields_array[$r]=array('u.label'=>"Text",'u.description'=>"Text",'p.lastname'=>'Text','p.firstname'=>'Text');
- $this->export_entities_array[$r]=array('p.rowid'=>'member','p.lastname'=>'member','p.firstname'=>'member'); // We define here only fields that use another picto
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'categorie as u, '.MAIN_DB_PREFIX.'categorie_member as cp, '.MAIN_DB_PREFIX.'adherent as p';
- $this->export_sql_end[$r] .=' WHERE u.rowid = cp.fk_categorie AND cp.fk_member = p.rowid';
- $this->export_sql_end[$r] .=' AND u.entity IN ('.getEntity('category').')';
- $this->export_sql_end[$r] .=' AND u.type = 3'; // Member categories
+ $this->export_code[$r] = 'category_'.$r;
+ $this->export_label[$r] = 'CatMemberList';
+ $this->export_icon[$r] = 'category';
+ $this->export_enabled[$r] = '$conf->adherent->enabled';
+ $this->export_permission[$r] = array(array("categorie", "lire"), array("adherent", "lire"));
+ $this->export_fields_array[$r] = array('u.rowid'=>"CategId", 'u.label'=>"Label", 'u.description'=>"Description", 'p.rowid'=>'MemberId', 'p.lastname'=>'LastName', 'p.firstname'=>'Firstname');
+ $this->export_TypeFields_array[$r] = array('u.label'=>"Text", 'u.description'=>"Text", 'p.lastname'=>'Text', 'p.firstname'=>'Text');
+ $this->export_entities_array[$r] = array('p.rowid'=>'member', 'p.lastname'=>'member', 'p.firstname'=>'member'); // We define here only fields that use another picto
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'categorie as u, '.MAIN_DB_PREFIX.'categorie_member as cp, '.MAIN_DB_PREFIX.'adherent as p';
+ $this->export_sql_end[$r] .= ' WHERE u.rowid = cp.fk_categorie AND cp.fk_member = p.rowid';
+ $this->export_sql_end[$r] .= ' AND u.entity IN ('.getEntity('category').')';
+ $this->export_sql_end[$r] .= ' AND u.type = 3'; // Member categories
$r++;
- $this->export_code[$r]='category_'.$r;
- $this->export_label[$r]='CatContactList';
- $this->export_icon[$r]='category';
- $this->export_enabled[$r]='$conf->societe->enabled';
- $this->export_permission[$r]=array(array("categorie", "lire"), array ("societe", "lire"));
- $this->export_fields_array[$r]=array (
+ $this->export_code[$r] = 'category_'.$r;
+ $this->export_label[$r] = 'CatContactList';
+ $this->export_icon[$r] = 'category';
+ $this->export_enabled[$r] = '$conf->societe->enabled';
+ $this->export_permission[$r] = array(array("categorie", "lire"), array("societe", "lire"));
+ $this->export_fields_array[$r] = array(
'u.rowid' => "CategId",
'u.label' => "Label",
'u.description' => "Description",
@@ -297,7 +297,7 @@ class modCategorie extends DolibarrModules
's.url'=>"Url",
's.email'=>"Email"
);
- $this->export_TypeFields_array[$r] = array (
+ $this->export_TypeFields_array[$r] = array(
'u.label' => "Text",
'u.description' => "Text",
'p.lastname' => 'Text',
@@ -313,7 +313,7 @@ class modCategorie extends DolibarrModules
's.url'=>"Text",
's.email'=>"Text"
);
- $this->export_entities_array[$r] = array (
+ $this->export_entities_array[$r] = array(
'u.rowid' => "category",
'u.label' => "category",
'u.description' => "category",
@@ -350,67 +350,67 @@ class modCategorie extends DolibarrModules
); // We define here only fields that use another picto
// Add extra fields
- $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'socpeople' AND entity IN (0, ".$conf->entity.")";
- $resql=$this->db->query($sql);
+ $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'socpeople' AND entity IN (0, ".$conf->entity.")";
+ $resql = $this->db->query($sql);
if ($resql) // This can fail when class is used on old database (during migration for example)
{
- while ($obj=$this->db->fetch_object($resql))
+ while ($obj = $this->db->fetch_object($resql))
{
- $fieldname='extra.'.$obj->name;
- $fieldlabel=ucfirst($obj->label);
- $typeFilter="Text";
- switch($obj->type)
+ $fieldname = 'extra.'.$obj->name;
+ $fieldlabel = ucfirst($obj->label);
+ $typeFilter = "Text";
+ switch ($obj->type)
{
case 'int':
case 'double':
case 'price':
- $typeFilter="Numeric";
+ $typeFilter = "Numeric";
break;
case 'date':
case 'datetime':
- $typeFilter="Date";
+ $typeFilter = "Date";
break;
case 'boolean':
- $typeFilter="Boolean";
+ $typeFilter = "Boolean";
break;
case 'sellist':
- $typeFilter="List:".$obj->param;
+ $typeFilter = "List:".$obj->param;
break;
case 'select':
- $typeFilter="Select:".$obj->param;
+ $typeFilter = "Select:".$obj->param;
break;
}
- $this->export_fields_array[$r][$fieldname]=$fieldlabel;
- $this->export_TypeFields_array[$r][$fieldname]=$typeFilter;
- $this->export_entities_array[$r][$fieldname]='contact';
+ $this->export_fields_array[$r][$fieldname] = $fieldlabel;
+ $this->export_TypeFields_array[$r][$fieldname] = $typeFilter;
+ $this->export_entities_array[$r][$fieldname] = 'contact';
}
}
// End add axtra fields
$this->export_sql_start[$r] = 'SELECT DISTINCT ';
- $this->export_sql_end[$r] = ' FROM ' . MAIN_DB_PREFIX . 'categorie as u, '.MAIN_DB_PREFIX . 'categorie_contact as cp, '.MAIN_DB_PREFIX . 'socpeople as p';
- $this->export_sql_end[$r] .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_country as country ON p.fk_pays = country.rowid';
- $this->export_sql_end[$r] .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'societe as s ON s.rowid = p.fk_soc';
- $this->export_sql_end[$r] .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'socpeople_extrafields as extra ON extra.fk_object = p.rowid';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'categorie as u, '.MAIN_DB_PREFIX.'categorie_contact as cp, '.MAIN_DB_PREFIX.'socpeople as p';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as country ON p.fk_pays = country.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON s.rowid = p.fk_soc';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'socpeople_extrafields as extra ON extra.fk_object = p.rowid';
$this->export_sql_end[$r] .= ' WHERE u.rowid = cp.fk_categorie AND cp.fk_socpeople = p.rowid AND u.entity IN ('.getEntity('category').')';
$this->export_sql_end[$r] .= ' AND u.type = 4'; // contact categories
// Imports
//--------
- $r=0;
+ $r = 0;
$r++;
- $this->import_code[$r]=$this->rights_class.'_'.$r;
- $this->import_label[$r]="CatList"; // Translation key
- $this->import_icon[$r]=$this->picto;
- $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon
- $this->import_tables_array[$r]=array('ca'=>MAIN_DB_PREFIX.'categorie');
- $this->import_fields_array[$r]=array(
- 'ca.label'=>"Label*",'ca.type'=>"Type*",'ca.description'=>"Description",
+ $this->import_code[$r] = $this->rights_class.'_'.$r;
+ $this->import_label[$r] = "CatList"; // Translation key
+ $this->import_icon[$r] = $this->picto;
+ $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon
+ $this->import_tables_array[$r] = array('ca'=>MAIN_DB_PREFIX.'categorie');
+ $this->import_fields_array[$r] = array(
+ 'ca.label'=>"Label*", 'ca.type'=>"Type*", 'ca.description'=>"Description",
'ca.fk_parent' => 'Parent'
);
- $this->import_regex_array[$r]=array('ca.type'=>'^[0|1|2|3]');
+ $this->import_regex_array[$r] = array('ca.type'=>'^[0|1|2|3]');
$this->import_convertvalue_array[$r] = array(
'ca.fk_parent' => array(
'rule' => 'fetchidfromcodeandlabel',
@@ -421,77 +421,96 @@ class modCategorie extends DolibarrModules
'codefromfield' => 'ca.type'
)
);
- $typeexample="";
- if ($conf->product->enabled) { $typeexample.=($typeexample?"/":"")."0=Product"; }
- if ($conf->fournisseur->enabled) { $typeexample.=($typeexample?"/":"")."1=Supplier"; }
- if ($conf->societe->enabled) { $typeexample.=($typeexample?"/":"")."2=Customer-Prospect"; }
- if ($conf->adherent->enabled) { $typeexample.=($typeexample?"/":"")."3=Member"; }
+ $typeexample = "";
+ if ($conf->product->enabled) { $typeexample .= ($typeexample ? "/" : "")."0=Product"; }
+ if ($conf->fournisseur->enabled) { $typeexample .= ($typeexample ? "/" : "")."1=Supplier"; }
+ if ($conf->societe->enabled) { $typeexample .= ($typeexample ? "/" : "")."2=Customer-Prospect"; }
+ if ($conf->adherent->enabled) { $typeexample .= ($typeexample ? "/" : "")."3=Member"; }
$this->import_examplevalues_array[$r] = array(
- 'ca.label'=>"Supplier Category",'ca.type'=>$typeexample,'ca.description'=>"My Category description",
+ 'ca.label'=>"Supplier Category", 'ca.type'=>$typeexample, 'ca.description'=>"My Category description",
'ca.fk_parent' => '0'
);
- if (! empty($conf->product->enabled))
+ if (!empty($conf->product->enabled))
{
//Products
$r++;
- $this->import_code[$r]=$this->rights_class.'_'.$r;
- $this->import_label[$r]="CatProdLinks"; // Translation key
- $this->import_icon[$r]=$this->picto;
- $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon
- $this->import_tables_array[$r]=array('cp'=>MAIN_DB_PREFIX.'categorie_product');
- $this->import_fields_array[$r]=array('cp.fk_categorie'=>"Category*",'cp.fk_product'=>"Product*");
- $this->import_regex_array[$r]=array('cp.fk_categorie'=>'rowid@'.MAIN_DB_PREFIX.'categorie:type=0');
+ $this->import_code[$r] = $this->rights_class.'_'.$r;
+ $this->import_label[$r] = "CatProdLinks"; // Translation key
+ $this->import_icon[$r] = $this->picto;
+ $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon
+ $this->import_tables_array[$r] = array('cp'=>MAIN_DB_PREFIX.'categorie_product');
+ $this->import_fields_array[$r] = array('cp.fk_categorie'=>"Category*", 'cp.fk_product'=>"Product*");
+ $this->import_regex_array[$r] = array('cp.fk_categorie'=>'rowid@'.MAIN_DB_PREFIX.'categorie:type=0');
- $this->import_convertvalue_array[$r]=array(
- 'cp.fk_categorie'=>array('rule'=>'fetchidfromref','classfile'=>'/categories/class/categorie.class.php','class'=>'Categorie','method'=>'fetch','element'=>'category'),
- 'cp.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'product')
+ $this->import_convertvalue_array[$r] = array(
+ 'cp.fk_categorie'=>array('rule'=>'fetchidfromref', 'classfile'=>'/categories/class/categorie.class.php', 'class'=>'Categorie', 'method'=>'fetch', 'element'=>'category'),
+ 'cp.fk_product'=>array('rule'=>'fetchidfromref', 'classfile'=>'/product/class/product.class.php', 'class'=>'Product', 'method'=>'fetch', 'element'=>'product')
);
- $this->import_examplevalues_array[$r]=array('cp.fk_categorie'=>"Imported category",'cp.fk_product'=>"PREF123456");
+ $this->import_examplevalues_array[$r] = array('cp.fk_categorie'=>"Imported category", 'cp.fk_product'=>"PREF123456");
}
- if (! empty($conf->societe->enabled))
+ if (!empty($conf->societe->enabled))
{
- //Customers
+ // Customers
$r++;
- $this->import_code[$r]=$this->rights_class.'_'.$r;
- $this->import_label[$r]="CatCusLinks"; // Translation key
- $this->import_icon[$r]=$this->picto;
- $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon
- $this->import_tables_array[$r]=array('cs'=>MAIN_DB_PREFIX.'categorie_societe');
- $this->import_fields_array[$r]=array('cs.fk_categorie'=>"Category*",'cs.fk_soc'=>"ThirdParty*");
- $this->import_regex_array[$r]=array(
+ $this->import_code[$r] = $this->rights_class.'_'.$r;
+ $this->import_label[$r] = "CatCusLinks"; // Translation key
+ $this->import_icon[$r] = $this->picto;
+ $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon
+ $this->import_tables_array[$r] = array('cs'=>MAIN_DB_PREFIX.'categorie_societe');
+ $this->import_fields_array[$r] = array('cs.fk_categorie'=>"Category*", 'cs.fk_soc'=>"ThirdParty*");
+ $this->import_regex_array[$r] = array(
'cs.fk_categorie'=>'rowid@'.MAIN_DB_PREFIX.'categorie:type=2',
'cs.fk_soc'=>'rowid@'.MAIN_DB_PREFIX.'societe:client>0'
);
- $this->import_convertvalue_array[$r]=array(
- 'cs.fk_categorie'=>array('rule'=>'fetchidfromref','classfile'=>'/categories/class/categorie.class.php','class'=>'Categorie','method'=>'fetch','element'=>'category'),
- 'cs.fk_soc'=>array('rule'=>'fetchidfromref','classfile'=>'/societe/class/societe.class.php','class'=>'Societe','method'=>'fetch','element'=>'ThirdParty')
+ $this->import_convertvalue_array[$r] = array(
+ 'cs.fk_categorie'=>array('rule'=>'fetchidfromref', 'classfile'=>'/categories/class/categorie.class.php', 'class'=>'Categorie', 'method'=>'fetch', 'element'=>'category'),
+ 'cs.fk_soc'=>array('rule'=>'fetchidfromref', 'classfile'=>'/societe/class/societe.class.php', 'class'=>'Societe', 'method'=>'fetch', 'element'=>'ThirdParty')
);
- $this->import_examplevalues_array[$r]=array('cs.fk_categorie'=>"Imported category",'cs.fk_soc'=>"MyBigCompany");
+ $this->import_examplevalues_array[$r] = array('cs.fk_categorie'=>"Imported category", 'cs.fk_soc'=>"MyBigCompany");
+
+ // Contacts/Addresses
+ $r++;
+ $this->import_code[$r] = $this->rights_class.'_'.$r;
+ $this->import_label[$r] = "CatContactsLinks"; // Translation key
+ $this->import_icon[$r] = $this->picto;
+ $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon
+ $this->import_tables_array[$r] = array('cs'=>MAIN_DB_PREFIX.'categorie_contact');
+ $this->import_fields_array[$r] = array('cs.fk_categorie'=>"Category*", 'cs.fk_socpeople'=>"Contact ID*");
+ $this->import_regex_array[$r] = array(
+ 'cs.fk_categorie'=>'rowid@'.MAIN_DB_PREFIX.'categorie:type=4'
+ //'cs.fk_socpeople'=>'rowid@'.MAIN_DB_PREFIX.'socpeople'
+ );
+
+ $this->import_convertvalue_array[$r] = array(
+ 'cs.fk_categorie'=>array('rule'=>'fetchidfromref', 'classfile'=>'/categories/class/categorie.class.php', 'class'=>'Categorie', 'method'=>'fetch', 'element'=>'category')
+ //'cs.fk_socpeople'=>array('rule'=>'fetchidfromref','classfile'=>'/contact/class/contact.class.php','class'=>'Contact','method'=>'fetch','element'=>'Contact')
+ );
+ $this->import_examplevalues_array[$r] = array('cs.fk_categorie'=>"Imported category", 'cs.fk_socpeople'=>"123");
}
- if (! empty($conf->fournisseur->enabled))
+ if (!empty($conf->fournisseur->enabled))
{
// Suppliers
$r++;
- $this->import_code[$r]=$this->rights_class.'_'.$r;
- $this->import_label[$r]="CatSupLinks"; // Translation key
- $this->import_icon[$r]=$this->picto;
- $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon
- $this->import_tables_array[$r]=array('cs'=>MAIN_DB_PREFIX.'categorie_fournisseur');
- $this->import_fields_array[$r]=array('cs.fk_categorie'=>"Category*",'cs.fk_soc'=>"Supplier*");
- $this->import_regex_array[$r]=array(
+ $this->import_code[$r] = $this->rights_class.'_'.$r;
+ $this->import_label[$r] = "CatSupLinks"; // Translation key
+ $this->import_icon[$r] = $this->picto;
+ $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon
+ $this->import_tables_array[$r] = array('cs'=>MAIN_DB_PREFIX.'categorie_fournisseur');
+ $this->import_fields_array[$r] = array('cs.fk_categorie'=>"Category*", 'cs.fk_soc'=>"Supplier*");
+ $this->import_regex_array[$r] = array(
'cs.fk_categorie'=>'rowid@'.MAIN_DB_PREFIX.'categorie:type=1',
'cs.fk_soc'=>'rowid@'.MAIN_DB_PREFIX.'societe:fournisseur>0'
);
- $this->import_convertvalue_array[$r]=array(
- 'cs.fk_categorie'=>array('rule'=>'fetchidfromref','classfile'=>'/categories/class/categorie.class.php','class'=>'Categorie','method'=>'fetch','element'=>'category'),
- 'cs.fk_soc'=>array('rule'=>'fetchidfromref','classfile'=>'/societe/class/societe.class.php','class'=>'Societe','method'=>'fetch','element'=>'ThirdParty')
+ $this->import_convertvalue_array[$r] = array(
+ 'cs.fk_categorie'=>array('rule'=>'fetchidfromref', 'classfile'=>'/categories/class/categorie.class.php', 'class'=>'Categorie', 'method'=>'fetch', 'element'=>'category'),
+ 'cs.fk_soc'=>array('rule'=>'fetchidfromref', 'classfile'=>'/societe/class/societe.class.php', 'class'=>'Societe', 'method'=>'fetch', 'element'=>'ThirdParty')
);
- $this->import_examplevalues_array[$r]=array('cs.fk_categorie'=>"Imported category",'cs.fk_soc'=>"MyBigCompany");
+ $this->import_examplevalues_array[$r] = array('cs.fk_categorie'=>"Imported category", 'cs.fk_soc'=>"MyBigCompany");
}
}
diff --git a/htdocs/core/modules/modDon.class.php b/htdocs/core/modules/modDon.class.php
index 42b4a8ef2b2..f4999f309c2 100644
--- a/htdocs/core/modules/modDon.class.php
+++ b/htdocs/core/modules/modDon.class.php
@@ -91,10 +91,10 @@ class modDon extends DolibarrModules
$this->const[$r][4] = 0;
$r++;
- $this->const[$r][0] = "DONATION_ART885";
+ $this->const[$r][0] = "DONATION_ART978";
$this->const[$r][1] = "yesno";
$this->const[$r][2] = "0";
- $this->const[$r][3] = 'Option Française - Eligibilité Art885-0 V bis du CGI';
+ $this->const[$r][3] = 'Option Française - Eligibilité Art978 du CGI';
$this->const[$r][4] = 0;
$r++;
diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php
index 2042e8b35da..b8bc72d423f 100644
--- a/htdocs/core/modules/modFournisseur.class.php
+++ b/htdocs/core/modules/modFournisseur.class.php
@@ -25,7 +25,7 @@
* \ingroup fournisseur
* \brief Description and activation file for module Supplier
*/
-include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
+include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
/**
@@ -58,7 +58,7 @@ class modFournisseur extends DolibarrModules
$this->version = 'dolibarr';
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
- $this->picto='company';
+ $this->picto = 'company';
// Data directories to create when module is enabled
$this->dirs = array(
@@ -71,7 +71,7 @@ class modFournisseur extends DolibarrModules
// Dependencies
$this->depends = array("modSociete");
- $this->requiredby = array();
+ $this->requiredby = array("modSupplierProposal");
$this->langfiles = array('bills', 'companies', 'suppliers', 'orders', 'sendings');
// Config pages
@@ -79,7 +79,7 @@ class modFournisseur extends DolibarrModules
// Constants
$this->const = array();
- $r=0;
+ $r = 0;
$this->const[$r][0] = "COMMANDE_SUPPLIER_ADDON_PDF";
$this->const[$r][1] = "chaine";
@@ -120,19 +120,19 @@ class modFournisseur extends DolibarrModules
// Boxes
$this->boxes = array(
- 0=>array('file'=>'box_graph_invoices_supplier_permonth.php','enabledbydefaulton'=>'Home'),
- 1=>array('file'=>'box_graph_orders_supplier_permonth.php','enabledbydefaulton'=>'Home'),
- 2=>array('file'=>'box_fournisseurs.php','enabledbydefaulton'=>'Home'),
- 3=>array('file'=>'box_factures_fourn_imp.php','enabledbydefaulton'=>'Home'),
- 4=>array('file'=>'box_factures_fourn.php','enabledbydefaulton'=>'Home'),
- 5=>array('file'=>'box_supplier_orders.php','enabledbydefaulton'=>'Home'),
- 6=>array('file'=>'box_supplier_orders_awaiting_reception.php','enabledbydefaulton'=>'Home'),
+ 0=>array('file'=>'box_graph_invoices_supplier_permonth.php', 'enabledbydefaulton'=>'Home'),
+ 1=>array('file'=>'box_graph_orders_supplier_permonth.php', 'enabledbydefaulton'=>'Home'),
+ 2=>array('file'=>'box_fournisseurs.php', 'enabledbydefaulton'=>'Home'),
+ 3=>array('file'=>'box_factures_fourn_imp.php', 'enabledbydefaulton'=>'Home'),
+ 4=>array('file'=>'box_factures_fourn.php', 'enabledbydefaulton'=>'Home'),
+ 5=>array('file'=>'box_supplier_orders.php', 'enabledbydefaulton'=>'Home'),
+ 6=>array('file'=>'box_supplier_orders_awaiting_reception.php', 'enabledbydefaulton'=>'Home'),
);
// Permissions
$this->rights = array();
$this->rights_class = 'fournisseur';
- $r=0;
+ $r = 0;
$r++;
$this->rights[$r][0] = 1181;
@@ -205,11 +205,11 @@ class modFournisseur extends DolibarrModules
$this->rights[$r][4] = 'commande';
$this->rights[$r][5] = 'supprimer';
- if (! empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED))
+ if (!empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED))
{
$r++;
$this->rights[$r][0] = 1190;
- $this->rights[$r][1] = 'Approve supplier order (second level)'; // $langs->trans("Permission1190");
+ $this->rights[$r][1] = 'Approve supplier order (second level)'; // $langs->trans("Permission1190");
$this->rights[$r][2] = 'w';
$this->rights[$r][3] = 0;
$this->rights[$r][4] = 'commande';
@@ -275,27 +275,28 @@ class modFournisseur extends DolibarrModules
// Menus
//-------
- $this->menu = 1; // This module add menu entries. They are coded into menu manager.
+ $this->menu = 1; // This module add menu entries. They are coded into menu manager.
// Exports
//--------
- $r=0;
+ $r = 0;
$r++;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]='Vendor invoices and lines of invoices';
- $this->export_icon[$r]='bill';
- $this->export_permission[$r]=array(array("fournisseur","facture","export"));
- $this->export_fields_array[$r]=array(
- 's.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','c.code'=>'CountryCode','s.phone'=>'Phone',
- 's.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.idprof5'=>'ProfId5','s.idprof6'=>'ProfId6','s.tva_intra'=>'VATIntra',
- 'f.rowid'=>"InvoiceId",'f.ref'=>"InvoiceRef",'f.ref_supplier'=>"RefSupplier",'f.datec'=>"InvoiceDateCreation",'f.datef'=>"DateInvoice",'f.date_lim_reglement'=>'DateMaxPayment',
- 'f.total_ht'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.total_tva'=>"TotalVAT",'f.paye'=>"InvoicePaid",'f.fk_statut'=>'InvoiceStatus','f.note_public'=>"InvoiceNote",
- 'fd.rowid'=>'LineId','fd.description'=>"LineDescription",'fd.tva_tx'=>"LineVATRate",'fd.qty'=>"LineQty",'fd.remise_percent'=>"Discount",'fd.total_ht'=>"LineTotalHT",
- 'fd.total_ttc'=>"LineTotalTTC",'fd.tva'=>"LineTotalVAT",'fd.product_type'=>'TypeOfLineServiceOrProduct','fd.fk_product'=>'ProductId',
- 'p.ref'=>'ProductRef','p.label'=>'ProductLabel','p.accountancy_code_buy'=>'ProductAccountancyBuyCode','project.rowid'=>'ProjectId',
- 'project.ref'=>'ProjectRef','project.title'=>'ProjectLabel'
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = 'Vendor invoices and lines of invoices';
+ $this->export_icon[$r] = 'bill';
+ $this->export_permission[$r] = array(array("fournisseur", "facture", "export"));
+ $this->export_fields_array[$r] = array(
+ 's.rowid'=>"IdCompany", 's.nom'=>'CompanyName', 's.address'=>'Address', 's.zip'=>'Zip', 's.town'=>'Town', 'c.code'=>'CountryCode', 's.phone'=>'Phone',
+ 's.siren'=>'ProfId1', 's.siret'=>'ProfId2', 's.ape'=>'ProfId3', 's.idprof4'=>'ProfId4', 's.idprof5'=>'ProfId5', 's.idprof6'=>'ProfId6',
+ 's.code_compta'=>'CustomerAccountancyCode', 's.code_compta_fournisseur'=>'SupplierAccountancyCode', 's.tva_intra'=>'VATIntra',
+ 'f.rowid'=>"InvoiceId", 'f.ref'=>"InvoiceRef", 'f.ref_supplier'=>"RefSupplier", 'f.datec'=>"InvoiceDateCreation", 'f.datef'=>"DateInvoice", 'f.date_lim_reglement'=>'DateMaxPayment',
+ 'f.total_ht'=>"TotalHT", 'f.total_ttc'=>"TotalTTC", 'f.total_tva'=>"TotalVAT", 'f.paye'=>"InvoicePaid", 'f.fk_statut'=>'InvoiceStatus', 'f.note_public'=>"InvoiceNote",
+ 'fd.rowid'=>'LineId', 'fd.description'=>"LineDescription", 'fd.tva_tx'=>"LineVATRate", 'fd.qty'=>"LineQty", 'fd.remise_percent'=>"Discount", 'fd.total_ht'=>"LineTotalHT",
+ 'fd.total_ttc'=>"LineTotalTTC", 'fd.tva'=>"LineTotalVAT", 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.fk_product'=>'ProductId',
+ 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel', 'p.accountancy_code_buy'=>'ProductAccountancyBuyCode', 'project.rowid'=>'ProjectId',
+ 'project.ref'=>'ProjectRef', 'project.title'=>'ProjectLabel'
);
//$this->export_TypeFields_array[$r]=array(
// 's.rowid'=>"List:societe:CompanyName",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text',
@@ -303,122 +304,123 @@ class modFournisseur extends DolibarrModules
// 'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_public'=>"Text",'fd.description'=>"Text",'fd.tva_tx'=>"Text",'fd.qty'=>"Numeric",'fd.total_ht'=>"Numeric",'fd.total_ttc'=>"Numeric",
// 'fd.tva'=>"Numeric",'fd.product_type'=>'Numeric','fd.fk_product'=>'List:product:label','p.ref'=>'Text','p.label'=>'Text'
//);
- $this->export_TypeFields_array[$r]=array(
- 's.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text',
- 's.tva_intra'=>'Text','f.ref'=>"Text",'f.ref_supplier'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>'Date','f.total_ht'=>"Numeric",'f.total_ttc'=>"Numeric",
- 'f.total_tva'=>"Numeric",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_public'=>"Text",'fd.description'=>"Text",'fd.tva_tx'=>"Text",'fd.qty'=>"Numeric",'fd.total_ht'=>"Numeric",
- 'fd.total_ttc'=>"Numeric",'fd.tva'=>"Numeric",'fd.product_type'=>'Numeric','fd.fk_product'=>'List:product:label',
- 'p.ref'=>'Text','p.label'=>'Text','project.ref'=>'Text','project.title'=>'Text'
+ $this->export_TypeFields_array[$r] = array(
+ 's.nom'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 'c.code'=>'Text', 's.phone'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 's.idprof5'=>'Text', 's.idprof6'=>'Text',
+ 's.code_compta'=>'Text', 's.code_compta_fournisseur'=>'Text', 's.tva_intra'=>'Text', 'f.ref'=>"Text", 'f.ref_supplier'=>"Text", 'f.datec'=>"Date", 'f.datef'=>"Date", 'f.date_lim_reglement'=>'Date',
+ 'f.total_ht'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.total_tva'=>"Numeric", 'f.paye'=>"Boolean", 'f.fk_statut'=>'Status', 'f.note_public'=>"Text", 'fd.description'=>"Text", 'fd.tva_tx'=>"Text",
+ 'fd.qty'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.tva'=>"Numeric", 'fd.product_type'=>'Numeric', 'fd.fk_product'=>'List:product:label',
+ 'p.ref'=>'Text', 'p.label'=>'Text', 'project.ref'=>'Text', 'project.title'=>'Text'
);
- $this->export_entities_array[$r]=array(
- 's.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','c.code'=>'company','s.phone'=>'company','s.siren'=>'company','s.siret'=>'company',
- 's.ape'=>'company','s.idprof4'=>'company','s.idprof5'=>'company','s.idprof6'=>'company','s.tva_intra'=>'company','f.rowid'=>"invoice",'f.ref'=>"invoice",'f.ref_supplier'=>"invoice",
- 'f.datec'=>"invoice",'f.datef'=>"invoice",'f.date_lim_reglement'=>'invoice','f.total_ht'=>"invoice",'f.total_ttc'=>"invoice",'f.total_tva'=>"invoice",'f.paye'=>"invoice",'f.fk_statut'=>'invoice',
- 'f.note_public'=>"invoice",'fd.rowid'=>'invoice_line','fd.description'=>"invoice_line",'fd.tva_tx'=>"invoice_line",'fd.qty'=>"invoice_line",'fd.remise_percent'=>"invoice_line",
- 'fd.total_ht'=>"invoice_line",'fd.total_ttc'=>"invoice_line",'fd.tva'=>"invoice_line",'fd.product_type'=>'invoice_line','fd.fk_product'=>'product',
- 'p.ref'=>'product','p.label'=>'product','p.accountancy_code_buy'=>'product','project.rowid'=>'project','project.ref'=>'project','project.title'=>'project'
+ $this->export_entities_array[$r] = array(
+ 's.rowid'=>"company", 's.nom'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 'c.code'=>'company', 's.phone'=>'company', 's.siren'=>'company', 's.siret'=>'company',
+ 's.ape'=>'company', 's.idprof4'=>'company', 's.idprof5'=>'company', 's.idprof6'=>'company', 's.code_compta'=>'company', 's.code_compta_fournisseur'=>'company', 's.tva_intra'=>'company', 'f.rowid'=>"invoice",
+ 'f.ref'=>"invoice", 'f.ref_supplier'=>"invoice", 'f.datec'=>"invoice", 'f.datef'=>"invoice", 'f.date_lim_reglement'=>'invoice', 'f.total_ht'=>"invoice", 'f.total_ttc'=>"invoice", 'f.total_tva'=>"invoice",
+ 'f.paye'=>"invoice", 'f.fk_statut'=>'invoice', 'f.note_public'=>"invoice", 'fd.rowid'=>'invoice_line', 'fd.description'=>"invoice_line", 'fd.tva_tx'=>"invoice_line", 'fd.qty'=>"invoice_line",
+ 'fd.remise_percent'=>"invoice_line", 'fd.total_ht'=>"invoice_line", 'fd.total_ttc'=>"invoice_line", 'fd.tva'=>"invoice_line", 'fd.product_type'=>'invoice_line', 'fd.fk_product'=>'product',
+ 'p.ref'=>'product', 'p.label'=>'product', 'p.accountancy_code_buy'=>'product', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project'
);
- $this->export_dependencies_array[$r]=array('invoice_line'=>'fd.rowid','product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them
+ $this->export_dependencies_array[$r] = array('invoice_line'=>'fd.rowid', 'product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them
// Add extra fields object
- $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")";
- $resql=$this->db->query($sql);
+ $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")";
+ $resql = $this->db->query($sql);
if ($resql) // This can fail when class is used on old database (during migration for example)
{
- while ($obj=$this->db->fetch_object($resql))
+ while ($obj = $this->db->fetch_object($resql))
{
- $fieldname='extra.'.$obj->name;
- $fieldlabel=ucfirst($obj->label);
- $typeFilter="Text";
- switch($obj->type)
+ $fieldname = 'extra.'.$obj->name;
+ $fieldlabel = ucfirst($obj->label);
+ $typeFilter = "Text";
+ switch ($obj->type)
{
case 'int':
case 'double':
case 'price':
- $typeFilter="Numeric";
+ $typeFilter = "Numeric";
break;
case 'date':
case 'datetime':
- $typeFilter="Date";
+ $typeFilter = "Date";
break;
case 'boolean':
- $typeFilter="Boolean";
+ $typeFilter = "Boolean";
break;
case 'sellist':
- $tmp='';
- $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null
- if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp=array_shift(array_keys($tmpparam['options']));
- if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp;
+ $tmp = '';
+ $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null
+ if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp = array_shift(array_keys($tmpparam['options']));
+ if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter = "List:".$tmp;
break;
}
- $this->export_fields_array[$r][$fieldname]=$fieldlabel;
- $this->export_TypeFields_array[$r][$fieldname]=$typeFilter;
- $this->export_entities_array[$r][$fieldname]='invoice';
+ $this->export_fields_array[$r][$fieldname] = $fieldlabel;
+ $this->export_TypeFields_array[$r][$fieldname] = $typeFilter;
+ $this->export_entities_array[$r][$fieldname] = 'invoice';
}
}
// End add extra fields
// Add extra fields line
- $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn_det' AND entity IN (0, ".$conf->entity.")";
- $resql=$this->db->query($sql);
+ $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn_det' AND entity IN (0, ".$conf->entity.")";
+ $resql = $this->db->query($sql);
if ($resql) // This can fail when class is used on old database (during migration for example)
{
- while ($obj=$this->db->fetch_object($resql))
+ while ($obj = $this->db->fetch_object($resql))
{
- $fieldname='extraline.'.$obj->name;
- $fieldlabel=ucfirst($obj->label);
- $typeFilter="Text";
- switch($obj->type)
+ $fieldname = 'extraline.'.$obj->name;
+ $fieldlabel = ucfirst($obj->label);
+ $typeFilter = "Text";
+ switch ($obj->type)
{
case 'int':
case 'double':
case 'price':
- $typeFilter="Numeric";
+ $typeFilter = "Numeric";
break;
case 'date':
case 'datetime':
- $typeFilter="Date";
+ $typeFilter = "Date";
break;
case 'boolean':
- $typeFilter="Boolean";
+ $typeFilter = "Boolean";
break;
case 'sellist':
- $tmp='';
- $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null
- if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp=array_shift(array_keys($tmpparam['options']));
- if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp;
+ $tmp = '';
+ $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null
+ if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp = array_shift(array_keys($tmpparam['options']));
+ if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter = "List:".$tmp;
break;
}
- $this->export_fields_array[$r][$fieldname]=$fieldlabel;
- $this->export_TypeFields_array[$r][$fieldname]=$typeFilter;
- $this->export_entities_array[$r][$fieldname]='invoice_line';
+ $this->export_fields_array[$r][$fieldname] = $fieldlabel;
+ $this->export_TypeFields_array[$r][$fieldname] = $typeFilter;
+ $this->export_entities_array[$r][$fieldname] = 'invoice_line';
}
}
// End add extra fields line
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'societe as s';
- if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,';
- $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'facture_fourn as f';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn_extrafields as extra ON f.rowid = extra.fk_object';
- $this->export_sql_end[$r] .=' , '.MAIN_DB_PREFIX.'facture_fourn_det as fd';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn_det_extrafields as extraline ON fd.rowid = extraline.fk_object';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product as p on (fd.fk_product = p.rowid)';
- $this->export_sql_end[$r] .=' WHERE f.fk_soc = s.rowid AND f.rowid = fd.fk_facture_fourn';
- $this->export_sql_end[$r] .=' AND f.entity IN ('.getEntity('supplier_invoice').')';
- if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' AND sc.fk_user = '.$user->id;
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'societe as s';
+ if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,';
+ $this->export_sql_end[$r] .= ' '.MAIN_DB_PREFIX.'facture_fourn as f';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn_extrafields as extra ON f.rowid = extra.fk_object';
+ $this->export_sql_end[$r] .= ' , '.MAIN_DB_PREFIX.'facture_fourn_det as fd';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn_det_extrafields as extraline ON fd.rowid = extraline.fk_object';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p on (fd.fk_product = p.rowid)';
+ $this->export_sql_end[$r] .= ' WHERE f.fk_soc = s.rowid AND f.rowid = fd.fk_facture_fourn';
+ $this->export_sql_end[$r] .= ' AND f.entity IN ('.getEntity('supplier_invoice').')';
+ if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' AND sc.fk_user = '.$user->id;
$r++;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]='Factures fournisseurs et reglements';
- $this->export_icon[$r]='bill';
- $this->export_permission[$r]=array(array("fournisseur","facture","export"));
- $this->export_fields_array[$r]=array(
- 's.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','c.code'=>'CountryCode','s.phone'=>'Phone',
- 's.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.idprof5'=>'ProfId5','s.idprof6'=>'ProfId6',
- 's.tva_intra'=>'VATIntra','f.rowid'=>"InvoiceId",'f.ref'=>"InvoiceRef",'f.ref_supplier'=>"RefSupplier",'f.datec'=>"InvoiceDateCreation",
- 'f.datef'=>"DateInvoice",'f.total_ht'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.total_tva'=>"TotalVAT",'f.paye'=>"InvoicePaid",
- 'f.fk_statut'=>'InvoiceStatus','f.note_public'=>"InvoiceNote",'p.rowid'=>'PaymentId','pf.amount'=>'AmountPayment',
- 'p.datep'=>'DatePayment','p.num_paiement'=>'PaymentNumber','project.rowid'=>'ProjectId','project.ref'=>'ProjectRef','project.title'=>'ProjectLabel'
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = 'Factures fournisseurs et reglements';
+ $this->export_icon[$r] = 'bill';
+ $this->export_permission[$r] = array(array("fournisseur", "facture", "export"));
+ $this->export_fields_array[$r] = array(
+ 's.rowid'=>"IdCompany", 's.nom'=>'CompanyName', 's.address'=>'Address', 's.zip'=>'Zip', 's.town'=>'Town', 'c.code'=>'CountryCode', 's.phone'=>'Phone',
+ 's.siren'=>'ProfId1', 's.siret'=>'ProfId2', 's.ape'=>'ProfId3', 's.idprof4'=>'ProfId4', 's.idprof5'=>'ProfId5', 's.idprof6'=>'ProfId6',
+ 's.code_compta'=>'CustomerAccountancyCode', 's.code_compta_fournisseur'=>'SupplierAccountancyCode', 's.tva_intra'=>'VATIntra',
+ 'f.rowid'=>"InvoiceId", 'f.ref'=>"InvoiceRef", 'f.ref_supplier'=>"RefSupplier", 'f.datec'=>"InvoiceDateCreation",
+ 'f.datef'=>"DateInvoice", 'f.total_ht'=>"TotalHT", 'f.total_ttc'=>"TotalTTC", 'f.total_tva'=>"TotalVAT", 'f.paye'=>"InvoicePaid",
+ 'f.fk_statut'=>'InvoiceStatus', 'f.note_public'=>"InvoiceNote", 'p.rowid'=>'PaymentId', 'pf.amount'=>'AmountPayment',
+ 'p.datep'=>'DatePayment', 'p.num_paiement'=>'PaymentNumber', 'project.rowid'=>'ProjectId', 'project.ref'=>'ProjectRef', 'project.title'=>'ProjectLabel'
);
//$this->export_TypeFields_array[$r]=array(
// 's.rowid'=>"List:societe:CompanyName",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text',
@@ -426,200 +428,201 @@ class modFournisseur extends DolibarrModules
// 'f.total_ht'=>"Numeric",'f.total_ttc'=>"Numeric",'f.total_tva'=>"Numeric",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_public'=>"Text",
// 'pf.amount'=>'Numeric','p.datep'=>'Date','p.num_paiement'=>'Numeric'
//);
- $this->export_TypeFields_array[$r]=array(
- 's.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text',
- 's.idprof4'=>'Text','s.tva_intra'=>'Text','f.ref'=>"Text",'f.ref_supplier'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.total_ht'=>"Numeric",
- 'f.total_ttc'=>"Numeric",'f.total_tva'=>"Numeric",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_public'=>"Text",'pf.amount'=>'Numeric',
- 'p.datep'=>'Date','p.num_paiement'=>'Numeric','project.ref'=>'Text','project.title'=>'Text'
+ $this->export_TypeFields_array[$r] = array(
+ 's.nom'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 'c.code'=>'Text', 's.phone'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text',
+ 's.idprof4'=>'Text', 's.code_compta'=>'Text', 's.code_compta_fournisseur'=>'Text', 's.tva_intra'=>'Text', 'f.ref'=>"Text", 'f.ref_supplier'=>"Text", 'f.datec'=>"Date", 'f.datef'=>"Date", 'f.total_ht'=>"Numeric",
+ 'f.total_ttc'=>"Numeric", 'f.total_tva'=>"Numeric", 'f.paye'=>"Boolean", 'f.fk_statut'=>'Status', 'f.note_public'=>"Text", 'pf.amount'=>'Numeric',
+ 'p.datep'=>'Date', 'p.num_paiement'=>'Numeric', 'project.ref'=>'Text', 'project.title'=>'Text'
);
- $this->export_entities_array[$r]=array(
- 's.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','c.code'=>'company','s.phone'=>'company',
- 's.siren'=>'company','s.siret'=>'company','s.ape'=>'company','s.idprof4'=>'company','s.idprof5'=>'company','s.idprof6'=>'company','s.tva_intra'=>'company',
- 'f.rowid'=>"invoice",'f.ref'=>"invoice",'f.ref_supplier'=>"invoice",'f.datec'=>"invoice",'f.datef'=>"invoice",'f.total_ht'=>"invoice",
- 'f.total_ttc'=>"invoice",'f.total_tva'=>"invoice",'f.paye'=>"invoice",'f.fk_statut'=>'invoice','f.note_public'=>"invoice",'p.rowid'=>'payment','pf.amount'=>'payment',
- 'p.datep'=>'payment','p.num_paiement'=>'payment','project.rowid'=>'project','project.ref'=>'project','project.title'=>'project');
- $this->export_dependencies_array[$r]=array('payment'=>'p.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them
+ $this->export_entities_array[$r] = array(
+ 's.rowid'=>"company", 's.nom'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 'c.code'=>'company', 's.phone'=>'company',
+ 's.siren'=>'company', 's.siret'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.idprof5'=>'company', 's.idprof6'=>'company',
+ 's.code_compta'=>'company', 's.code_compta_fournisseur'=>'company', 's.tva_intra'=>'company',
+ 'f.rowid'=>"invoice", 'f.ref'=>"invoice", 'f.ref_supplier'=>"invoice", 'f.datec'=>"invoice", 'f.datef'=>"invoice", 'f.total_ht'=>"invoice",
+ 'f.total_ttc'=>"invoice", 'f.total_tva'=>"invoice", 'f.paye'=>"invoice", 'f.fk_statut'=>'invoice', 'f.note_public'=>"invoice", 'p.rowid'=>'payment', 'pf.amount'=>'payment',
+ 'p.datep'=>'payment', 'p.num_paiement'=>'payment', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project');
+ $this->export_dependencies_array[$r] = array('payment'=>'p.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them
// Add extra fields object
- $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")";
- $resql=$this->db->query($sql);
+ $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")";
+ $resql = $this->db->query($sql);
if ($resql) // This can fail when class is used on old database (during migration for example)
{
- while ($obj=$this->db->fetch_object($resql))
+ while ($obj = $this->db->fetch_object($resql))
{
- $fieldname='extra.'.$obj->name;
- $fieldlabel=ucfirst($obj->label);
- $typeFilter="Text";
- switch($obj->type)
+ $fieldname = 'extra.'.$obj->name;
+ $fieldlabel = ucfirst($obj->label);
+ $typeFilter = "Text";
+ switch ($obj->type)
{
case 'int':
case 'double':
case 'price':
- $typeFilter="Numeric";
+ $typeFilter = "Numeric";
break;
case 'date':
case 'datetime':
- $typeFilter="Date";
+ $typeFilter = "Date";
break;
case 'boolean':
- $typeFilter="Boolean";
+ $typeFilter = "Boolean";
break;
case 'sellist':
- $tmp='';
- $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null
- if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp=array_shift(array_keys($tmpparam['options']));
- if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp;
+ $tmp = '';
+ $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null
+ if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp = array_shift(array_keys($tmpparam['options']));
+ if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter = "List:".$tmp;
break;
}
- $this->export_fields_array[$r][$fieldname]=$fieldlabel;
- $this->export_TypeFields_array[$r][$fieldname]=$typeFilter;
- $this->export_entities_array[$r][$fieldname]='invoice';
+ $this->export_fields_array[$r][$fieldname] = $fieldlabel;
+ $this->export_TypeFields_array[$r][$fieldname] = $typeFilter;
+ $this->export_entities_array[$r][$fieldname] = 'invoice';
}
}
// End add extra fields object
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'societe as s';
- if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,';
- $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'facture_fourn as f';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn_extrafields as extra ON f.rowid = extra.fk_object';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_facturefourn = f.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn as p ON pf.fk_paiementfourn = p.rowid';
- $this->export_sql_end[$r] .=' WHERE f.fk_soc = s.rowid';
- $this->export_sql_end[$r] .=' AND f.entity IN ('.getEntity('supplier_invoice').')';
- if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' AND sc.fk_user = '.$user->id;
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'societe as s';
+ if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,';
+ $this->export_sql_end[$r] .= ' '.MAIN_DB_PREFIX.'facture_fourn as f';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn_extrafields as extra ON f.rowid = extra.fk_object';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_facturefourn = f.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn as p ON pf.fk_paiementfourn = p.rowid';
+ $this->export_sql_end[$r] .= ' WHERE f.fk_soc = s.rowid';
+ $this->export_sql_end[$r] .= ' AND f.entity IN ('.getEntity('supplier_invoice').')';
+ if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' AND sc.fk_user = '.$user->id;
// Order
$r++;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]='Purchase Orders and lines of purchase orders';
- $this->export_icon[$r]='order';
- $this->export_permission[$r]=array(array("fournisseur","commande","export"));
- $this->export_fields_array[$r]=array(
- 's.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','c.code'=>'CountryCode','s.phone'=>'Phone',
- 's.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.idprof5'=>'ProfId5','s.idprof6'=>'ProfId6','s.tva_intra'=>'VATIntra',
- 'f.rowid'=>"OrderId",'f.ref'=>"Ref",'f.ref_supplier'=>"RefSupplier",'f.date_creation'=>"DateCreation",'f.date_commande'=>"OrderDate",'f.date_livraison'=>"DateDeliveryPlanned",
- 'f.total_ht'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.tva'=>"TotalVAT",'f.fk_statut'=>'Status','f.date_approve'=>'DateApprove','f.date_approve2'=>'DateApprove2',
- 'f.note_public'=>"NotePublic",'f.note_private'=>"NotePrivate",'ua1.login'=>'ApprovedBy','ua2.login'=>'ApprovedBy2','fd.rowid'=>'LineId','fd.description'=>"LineDescription",
- 'fd.tva_tx'=>"LineVATRate",'fd.qty'=>"LineQty",'fd.remise_percent'=>"Discount",'fd.total_ht'=>"LineTotalHT",'fd.total_ttc'=>"LineTotalTTC",
- 'fd.total_tva'=>"LineTotalVAT",'fd.product_type'=>'TypeOfLineServiceOrProduct','fd.ref'=>'RefSupplier','fd.fk_product'=>'ProductId',
- 'p.ref'=>'ProductRef','p.label'=>'ProductLabel','project.rowid'=>'ProjectId','project.ref'=>'ProjectRef','project.title'=>'ProjectLabel'
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = 'Purchase Orders and lines of purchase orders';
+ $this->export_icon[$r] = 'order';
+ $this->export_permission[$r] = array(array("fournisseur", "commande", "export"));
+ $this->export_fields_array[$r] = array(
+ 's.rowid'=>"IdCompany", 's.nom'=>'CompanyName', 's.address'=>'Address', 's.zip'=>'Zip', 's.town'=>'Town', 'c.code'=>'CountryCode', 's.phone'=>'Phone',
+ 's.siren'=>'ProfId1', 's.siret'=>'ProfId2', 's.ape'=>'ProfId3', 's.idprof4'=>'ProfId4', 's.idprof5'=>'ProfId5', 's.idprof6'=>'ProfId6', 's.tva_intra'=>'VATIntra',
+ 'f.rowid'=>"OrderId", 'f.ref'=>"Ref", 'f.ref_supplier'=>"RefSupplier", 'f.date_creation'=>"DateCreation", 'f.date_commande'=>"OrderDate", 'f.date_livraison'=>"DateDeliveryPlanned",
+ 'f.total_ht'=>"TotalHT", 'f.total_ttc'=>"TotalTTC", 'f.tva'=>"TotalVAT", 'f.fk_statut'=>'Status', 'f.date_approve'=>'DateApprove', 'f.date_approve2'=>'DateApprove2',
+ 'f.note_public'=>"NotePublic", 'f.note_private'=>"NotePrivate", 'ua1.login'=>'ApprovedBy', 'ua2.login'=>'ApprovedBy2', 'fd.rowid'=>'LineId', 'fd.description'=>"LineDescription",
+ 'fd.tva_tx'=>"LineVATRate", 'fd.qty'=>"LineQty", 'fd.remise_percent'=>"Discount", 'fd.total_ht'=>"LineTotalHT", 'fd.total_ttc'=>"LineTotalTTC",
+ 'fd.total_tva'=>"LineTotalVAT", 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.ref'=>'RefSupplier', 'fd.fk_product'=>'ProductId',
+ 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel', 'project.rowid'=>'ProjectId', 'project.ref'=>'ProjectRef', 'project.title'=>'ProjectLabel'
);
if (empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED))
{
unset($this->export_fields_array['f.date_approve2']);
unset($this->export_fields_array['ua2.login']);
}
- $this->export_TypeFields_array[$r]=array(
- 's.rowid'=>"company",'s.nom'=>'Text','s.address'=>'Text','s.cp'=>'Text','s.ville'=>'Text','c.code'=>'Text','s.tel'=>'Text','s.siren'=>'Text',
- 's.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.idprof5'=>'Text','s.idprof6'=>'Text','s.tva_intra'=>'Text','f.ref'=>"Text",'f.ref_supplier'=>"Text",
- 'f.date_creation'=>"Date",'f.date_commande'=>"Date",'f.date_livraison'=>"Date",'f.total_ht'=>"Numeric",'f.total_ttc'=>"Numeric",'f.tva'=>"Numeric",
- 'f.fk_statut'=>'Status','f.date_approve'=>'Date','f.date_approve2'=>'Date','f.note_public'=>"Text",'f.note_private'=>"Text",'fd.description'=>"Text",
- 'fd.tva_tx'=>"Numeric",'fd.qty'=>"Numeric",'fd.remise_percent'=>"Numeric",'fd.total_ht'=>"Numeric",'fd.total_ttc'=>"Numeric",'fd.total_tva'=>"Numeric",
- 'fd.product_type'=>'Numeric','fd.ref'=>'Text','fd.fk_product'=>'List:product:label','p.ref'=>'Text','p.label'=>'Text','project.ref'=>'Text','project.title'=>'Text'
+ $this->export_TypeFields_array[$r] = array(
+ 's.rowid'=>"company", 's.nom'=>'Text', 's.address'=>'Text', 's.cp'=>'Text', 's.ville'=>'Text', 'c.code'=>'Text', 's.tel'=>'Text', 's.siren'=>'Text',
+ 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 's.idprof5'=>'Text', 's.idprof6'=>'Text', 's.tva_intra'=>'Text', 'f.ref'=>"Text", 'f.ref_supplier'=>"Text",
+ 'f.date_creation'=>"Date", 'f.date_commande'=>"Date", 'f.date_livraison'=>"Date", 'f.total_ht'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.tva'=>"Numeric",
+ 'f.fk_statut'=>'Status', 'f.date_approve'=>'Date', 'f.date_approve2'=>'Date', 'f.note_public'=>"Text", 'f.note_private'=>"Text", 'fd.description'=>"Text",
+ 'fd.tva_tx'=>"Numeric", 'fd.qty'=>"Numeric", 'fd.remise_percent'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.total_tva'=>"Numeric",
+ 'fd.product_type'=>'Numeric', 'fd.ref'=>'Text', 'fd.fk_product'=>'List:product:label', 'p.ref'=>'Text', 'p.label'=>'Text', 'project.ref'=>'Text', 'project.title'=>'Text'
);
- $this->export_entities_array[$r]=array(
- 's.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','c.code'=>'company','s.phone'=>'company','s.siren'=>'company',
- 's.siret'=>'company','s.ape'=>'company','s.idprof4'=>'company','s.idprof5'=>'company','s.idprof6'=>'company','s.tva_intra'=>'company','ua1.login'=>'user',
- 'ua2.login'=>'user','fd.rowid'=>'order_line','fd.description'=>"order_line",'fd.tva_tx'=>"order_line",'fd.qty'=>"order_line",'fd.remise_percent'=>"order_line",
- 'fd.total_ht'=>"order_line",'fd.total_ttc'=>"order_line",'fd.total_tva'=>"order_line",'fd.product_type'=>'order_line','fd.ref'=>'order_line','fd.fk_product'=>'product',
- 'p.ref'=>'product','p.label'=>'product','project.rowid'=>'project','project.ref'=>'project','project.title'=>'project'
+ $this->export_entities_array[$r] = array(
+ 's.rowid'=>"company", 's.nom'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 'c.code'=>'company', 's.phone'=>'company', 's.siren'=>'company',
+ 's.siret'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.idprof5'=>'company', 's.idprof6'=>'company', 's.tva_intra'=>'company', 'ua1.login'=>'user',
+ 'ua2.login'=>'user', 'fd.rowid'=>'order_line', 'fd.description'=>"order_line", 'fd.tva_tx'=>"order_line", 'fd.qty'=>"order_line", 'fd.remise_percent'=>"order_line",
+ 'fd.total_ht'=>"order_line", 'fd.total_ttc'=>"order_line", 'fd.total_tva'=>"order_line", 'fd.product_type'=>'order_line', 'fd.ref'=>'order_line', 'fd.fk_product'=>'product',
+ 'p.ref'=>'product', 'p.label'=>'product', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project'
);
- $this->export_dependencies_array[$r]=array('order_line'=>'fd.rowid','product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them
+ $this->export_dependencies_array[$r] = array('order_line'=>'fd.rowid', 'product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them
// Add extra fields object
- $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseur' AND entity IN (0, ".$conf->entity.")";
- $resql=$this->db->query($sql);
+ $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseur' AND entity IN (0, ".$conf->entity.")";
+ $resql = $this->db->query($sql);
if ($resql) // This can fail when class is used on old database (during migration for example)
{
- while ($obj=$this->db->fetch_object($resql))
+ while ($obj = $this->db->fetch_object($resql))
{
- $fieldname='extra.'.$obj->name;
- $fieldlabel=ucfirst($obj->label);
- $typeFilter="Text";
- switch($obj->type)
+ $fieldname = 'extra.'.$obj->name;
+ $fieldlabel = ucfirst($obj->label);
+ $typeFilter = "Text";
+ switch ($obj->type)
{
case 'int':
case 'double':
case 'price':
- $typeFilter="Numeric";
+ $typeFilter = "Numeric";
break;
case 'date':
case 'datetime':
- $typeFilter="Date";
+ $typeFilter = "Date";
break;
case 'boolean':
- $typeFilter="Boolean";
+ $typeFilter = "Boolean";
break;
case 'sellist':
- $tmp='';
- $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null
- $tmpkey=array_keys($tmpparam['options']);
- if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp=array_shift($tmpkey);
- if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp;
+ $tmp = '';
+ $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null
+ $tmpkey = array_keys($tmpparam['options']);
+ if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp = array_shift($tmpkey);
+ if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter = "List:".$tmp;
break;
}
- $this->export_fields_array[$r][$fieldname]=$fieldlabel;
- $this->export_TypeFields_array[$r][$fieldname]=$typeFilter;
- $this->export_entities_array[$r][$fieldname]='order';
+ $this->export_fields_array[$r][$fieldname] = $fieldlabel;
+ $this->export_TypeFields_array[$r][$fieldname] = $typeFilter;
+ $this->export_entities_array[$r][$fieldname] = 'order';
}
}
// End add extra fields object
// Add extra fields line
- $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseurdet' AND entity IN (0, ".$conf->entity.")";
- $resql=$this->db->query($sql);
+ $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseurdet' AND entity IN (0, ".$conf->entity.")";
+ $resql = $this->db->query($sql);
if ($resql) // This can fail when class is used on old database (during migration for example)
{
- while ($obj=$this->db->fetch_object($resql))
+ while ($obj = $this->db->fetch_object($resql))
{
- $fieldname='extraline.'.$obj->name;
- $fieldlabel=ucfirst($obj->label);
- $typeFilter="Text";
- switch($obj->type)
+ $fieldname = 'extraline.'.$obj->name;
+ $fieldlabel = ucfirst($obj->label);
+ $typeFilter = "Text";
+ switch ($obj->type)
{
case 'int':
case 'double':
case 'price':
- $typeFilter="Numeric";
+ $typeFilter = "Numeric";
break;
case 'date':
case 'datetime':
- $typeFilter="Date";
+ $typeFilter = "Date";
break;
case 'boolean':
- $typeFilter="Boolean";
+ $typeFilter = "Boolean";
break;
case 'sellist':
- $tmp='';
- $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null
+ $tmp = '';
+ $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null
if ($tmpparam['options'] && is_array($tmpparam['options'])) {
- $tmpparam_param_key=array_keys($tmpparam['options']);
- $tmp=array_shift($tmpparam_param_key);
+ $tmpparam_param_key = array_keys($tmpparam['options']);
+ $tmp = array_shift($tmpparam_param_key);
}
- if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp;
+ if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter = "List:".$tmp;
break;
}
- $this->export_fields_array[$r][$fieldname]=$fieldlabel;
- $this->export_TypeFields_array[$r][$fieldname]=$typeFilter;
- $this->export_entities_array[$r][$fieldname]='order_line';
+ $this->export_fields_array[$r][$fieldname] = $fieldlabel;
+ $this->export_TypeFields_array[$r][$fieldname] = $typeFilter;
+ $this->export_entities_array[$r][$fieldname] = 'order_line';
}
}
// End add extra fields line
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'societe as s';
- if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,';
- $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'commande_fournisseur as f';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'user as ua1 ON ua1.rowid = f.fk_user_approve';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'user as ua2 ON ua2.rowid = f.fk_user_approve2';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'commande_fournisseur_extrafields as extra ON f.rowid = extra.fk_object,';
- $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'commande_fournisseurdet as fd';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'commande_fournisseurdet_extrafields as extraline ON fd.rowid = extraline.fk_object';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product as p on (fd.fk_product = p.rowid)';
- $this->export_sql_end[$r] .=' WHERE f.fk_soc = s.rowid AND f.rowid = fd.fk_commande';
- $this->export_sql_end[$r] .=' AND f.entity IN ('.getEntity('supplier_order').')';
- if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' AND sc.fk_user = '.$user->id;
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'societe as s';
+ if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,';
+ $this->export_sql_end[$r] .= ' '.MAIN_DB_PREFIX.'commande_fournisseur as f';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user as ua1 ON ua1.rowid = f.fk_user_approve';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user as ua2 ON ua2.rowid = f.fk_user_approve2';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'commande_fournisseur_extrafields as extra ON f.rowid = extra.fk_object,';
+ $this->export_sql_end[$r] .= ' '.MAIN_DB_PREFIX.'commande_fournisseurdet as fd';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'commande_fournisseurdet_extrafields as extraline ON fd.rowid = extraline.fk_object';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p on (fd.fk_product = p.rowid)';
+ $this->export_sql_end[$r] .= ' WHERE f.fk_soc = s.rowid AND f.rowid = fd.fk_commande';
+ $this->export_sql_end[$r] .= ' AND f.entity IN ('.getEntity('supplier_order').')';
+ if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' AND sc.fk_user = '.$user->id;
}
@@ -638,19 +641,19 @@ class modFournisseur extends DolibarrModules
$this->remove($options);
//ODT template
- $src=DOL_DOCUMENT_ROOT.'/install/doctemplates/supplier_orders/template_supplier_order.odt';
- $dirodt=DOL_DATA_ROOT.'/doctemplates/supplier_orders';
- $dest=$dirodt.'/template_supplier_order.odt';
+ $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/supplier_orders/template_supplier_order.odt';
+ $dirodt = DOL_DATA_ROOT.'/doctemplates/supplier_orders';
+ $dest = $dirodt.'/template_supplier_order.odt';
- if (file_exists($src) && ! file_exists($dest))
+ if (file_exists($src) && !file_exists($dest))
{
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
dol_mkdir($dirodt);
- $result=dol_copy($src, $dest, 0, 0);
+ $result = dol_copy($src, $dest, 0, 0);
if ($result < 0)
{
$langs->load("errors");
- $this->error=$langs->trans('ErrorFailToCopyFile', $src, $dest);
+ $this->error = $langs->trans('ErrorFailToCopyFile', $src, $dest);
return 0;
}
}
diff --git a/htdocs/core/modules/modMrp.class.php b/htdocs/core/modules/modMrp.class.php
index 1ca8e380aa4..73df7523843 100644
--- a/htdocs/core/modules/modMrp.class.php
+++ b/htdocs/core/modules/modMrp.class.php
@@ -62,7 +62,7 @@ class modMrp extends DolibarrModules
// Used only if file README.md and README-LL.md not found.
$this->descriptionlong = "Module to Manage Manufacturing Orders (MO)";
// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
- $this->version = 'experimental';
+ $this->version = 'dolibarr';
// Url to the file with your last numberversion of this module
//$this->url_last_version = 'http://www.example.com/versionmodule.txt';
diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php
index 9c094aa122e..87f11decb5e 100644
--- a/htdocs/core/modules/modProduct.class.php
+++ b/htdocs/core/modules/modProduct.class.php
@@ -7,6 +7,7 @@
* Copyright (C) 2012-2013 Juanjo Menent
* Copyright (C) 2014 Christophe Battarel
* Copyright (C) 2014 Cedric Gross
+ * Copyright (C) 2020 Alexandre Spangaro
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -168,209 +169,214 @@ class modProduct extends DolibarrModules
// Exports
//--------
- $r=0;
+ $r = 0;
$r++;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]="Products"; // Translation key (used only if key ExportDataset_xxx_z not found)
- $this->export_permission[$r]=array(array("produit","export"));
- $this->export_fields_array[$r]=array(
- 'p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",
- 'p.fk_product_type'=>'Type','p.tosell'=>"OnSell",'p.tobuy'=>"OnBuy",
- 'p.description'=>"Description",'p.url'=>"PublicUrl",
- 'p.customcode'=>'CustomCode','p.fk_country'=>'IDCountry',
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = "Products"; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_permission[$r] = array(array("produit", "export"));
+ $this->export_fields_array[$r] = array(
+ 'p.rowid'=>"Id", 'p.ref'=>"Ref", 'p.label'=>"Label",
+ 'p.fk_product_type'=>'Type', 'p.tosell'=>"OnSell", 'p.tobuy'=>"OnBuy",
+ 'p.description'=>"Description", 'p.url'=>"PublicUrl",
+ 'p.customcode'=>'CustomCode', 'p.fk_country'=>'IDCountry',
'p.accountancy_code_sell'=>"ProductAccountancySellCode", 'p.accountancy_code_sell_intra'=>"ProductAccountancySellIntraCode",
'p.accountancy_code_sell_export'=>"ProductAccountancySellExportCode", 'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",
- 'p.note'=>"NotePrivate",'p.note_public'=>'NotePublic',
+ 'p.accountancy_code_buy_intra'=>"ProductAccountancyBuyIntraCode", 'p.accountancy_code_buy_export'=>"ProductAccountancyBuyExportCode",
+ 'p.note'=>"NotePrivate", 'p.note_public'=>'NotePublic',
'p.weight'=>"Weight", 'p.weight_units'=>"WeightUnits", 'p.length'=>"Length", 'p.length_units'=>"LengthUnits", 'p.width'=>"Width", 'p.width_units'=>"WidthUnits", 'p.height'=>"Height", 'p.height_units'=>"HeightUnits",
'p.surface'=>"Surface", 'p.surface_units'=>"SurfaceUnits", 'p.volume'=>"Volume", 'p.volume_units'=>"VolumeUnits",
'p.duration'=>"Duration",
'p.finished' => 'Nature',
- 'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",
+ 'p.price_base_type'=>"PriceBase", 'p.price'=>"UnitPriceHT", 'p.price_ttc'=>"UnitPriceTTC",
'p.tva_tx'=>'VATRate',
- 'p.datec'=>'DateCreation','p.tms'=>'DateModification'
+ 'p.datec'=>'DateCreation', 'p.tms'=>'DateModification'
);
- if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['p.recuperableonly']='NPR';
- if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.cost_price'=>'CostPrice'));
- if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue'));
- if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode'));
- $keyforselect='product'; $keyforelement='product'; $keyforaliasextra='extra';
+ if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['p.recuperableonly'] = 'NPR';
+ if (!empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.cost_price'=>'CostPrice'));
+ if (!empty($conf->stock->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock', 'p.seuil_stock_alerte'=>'StockLimit', 'p.desiredstock'=>'DesiredStock', 'p.pmp'=>'PMPValue'));
+ if (!empty($conf->barcode->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode'));
+ $keyforselect = 'product'; $keyforelement = 'product'; $keyforaliasextra = 'extra';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
- if (! empty($conf->fournisseur->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('s.nom'=>'Supplier','pf.ref_fourn'=>'SupplierRef','pf.quantity'=>'QtyMin','pf.remise_percent'=>'DiscountQtyMin','pf.unitprice'=>'BuyingPrice','pf.delivery_time_days'=>'NbDaysToDelivery'));
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('group_concat(cat.label)'=>'Categories'));
- if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('l.lang'=>'Language', 'l.label'=>'TranslatedLabel','l.description'=>'TranslatedDescription','l.note'=>'TranslatedNote'));
- if (! empty($conf->global->PRODUCT_USE_UNITS)) $this->export_fields_array[$r]['p.fk_unit'] = 'Unit';
- $this->export_TypeFields_array[$r]=array(
- 'p.ref'=>"Text",'p.label'=>"Text",
- 'p.fk_product_type'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",
- 'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text",
- 'p.accountancy_code_sell_intra'=>"Text",'p.accountancy_code_sell_export'=>"Text",'p.accountancy_code_buy'=>"Text",
- 'p.note'=>"Text",'p.note_public'=>"Text",
- 'p.weight'=>"Numeric",'p.length'=>"Numeric",'p.width'=>"Numeric",'p.height'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric",
+ if (!empty($conf->fournisseur->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('s.nom'=>'Supplier', 'pf.ref_fourn'=>'SupplierRef', 'pf.quantity'=>'QtyMin', 'pf.remise_percent'=>'DiscountQtyMin', 'pf.unitprice'=>'BuyingPrice', 'pf.delivery_time_days'=>'NbDaysToDelivery'));
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('group_concat(cat.label)'=>'Categories'));
+ if (!empty($conf->global->MAIN_MULTILANGS)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('l.lang'=>'Language', 'l.label'=>'TranslatedLabel', 'l.description'=>'TranslatedDescription', 'l.note'=>'TranslatedNote'));
+ if (!empty($conf->global->PRODUCT_USE_UNITS)) $this->export_fields_array[$r]['p.fk_unit'] = 'Unit';
+ $this->export_TypeFields_array[$r] = array(
+ 'p.ref'=>"Text", 'p.label'=>"Text",
+ 'p.fk_product_type'=>'Numeric', 'p.tosell'=>"Boolean", 'p.tobuy'=>"Boolean",
+ 'p.description'=>"Text", 'p.url'=>"Text",
+ 'p.accountancy_code_sell'=>"Text", 'p.accountancy_code_sell_intra'=>"Text", 'p.accountancy_code_sell_export'=>"Text",
+ 'p.accountancy_code_buy'=>"Text", 'p.accountancy_code_buy_intra'=>"Text", 'p.accountancy_code_buy_export'=>"Text",
+ 'p.note'=>"Text", 'p.note_public'=>"Text",
+ 'p.weight'=>"Numeric", 'p.length'=>"Numeric", 'p.width'=>"Numeric", 'p.height'=>"Numeric", 'p.surface'=>"Numeric", 'p.volume'=>"Numeric",
'p.customcode'=>'Text',
'p.duration'=>"Text",
'p.finished' => 'Numeric',
- 'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric',
- 'p.datec'=>'Date','p.tms'=>'Date'
+ 'p.price_base_type'=>"Text", 'p.price'=>"Numeric", 'p.price_ttc'=>"Numeric", 'p.tva_tx'=>'Numeric',
+ 'p.datec'=>'Date', 'p.tms'=>'Date'
);
- if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric','p.seuil_stock_alerte'=>'Numeric','p.desiredstock'=>'Numeric','p.pmp'=>'Numeric','p.cost_price'=>'Numeric'));
- if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text'));
- if (! empty($conf->fournisseur->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('s.nom'=>'Text','pf.ref_fourn'=>'Text','pf.unitprice'=>'Numeric','pf.quantity'=>'Numeric','pf.remise_percent'=>'Numeric','pf.delivery_time_days'=>'Numeric'));
- if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('l.lang'=>'Text', 'l.label'=>'Text','l.description'=>'Text','l.note'=>'Text'));
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array("group_concat(cat.label)"=>'Text'));
- $this->export_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array("group_concat(cat.label)"=>'category'));
- if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'product','p.pmp'=>'product'));
- if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'product'));
- if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref'));
- if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation'));
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid');
- if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'product','p.pmp'=>'product'));
- if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'product'));
- if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref'));
- if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation'));
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid');
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p';
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product = p.rowid LEFT JOIN '.MAIN_DB_PREFIX.'categorie as cat ON cp.fk_categorie = cat.rowid';
- if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_lang as l ON l.fk_product = p.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object';
- if (! empty($conf->fournisseur->enabled)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_fournisseur_price as pf ON pf.fk_product = p.rowid LEFT JOIN '.MAIN_DB_PREFIX.'societe s ON s.rowid = pf.fk_soc';
- $this->export_sql_end[$r] .=' WHERE p.fk_product_type = 0 AND p.entity IN ('.getEntity('product').')';
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_sql_order[$r] =' GROUP BY p.rowid'; // FIXME The group by used a generic value to say "all fields in select except function fields"
+ if (!empty($conf->stock->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric', 'p.seuil_stock_alerte'=>'Numeric', 'p.desiredstock'=>'Numeric', 'p.pmp'=>'Numeric', 'p.cost_price'=>'Numeric'));
+ if (!empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text'));
+ if (!empty($conf->fournisseur->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('s.nom'=>'Text', 'pf.ref_fourn'=>'Text', 'pf.unitprice'=>'Numeric', 'pf.quantity'=>'Numeric', 'pf.remise_percent'=>'Numeric', 'pf.delivery_time_days'=>'Numeric'));
+ if (!empty($conf->global->MAIN_MULTILANGS)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('l.lang'=>'Text', 'l.label'=>'Text', 'l.description'=>'Text', 'l.note'=>'Text'));
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array("group_concat(cat.label)"=>'Text'));
+ $this->export_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array("group_concat(cat.label)"=>'category'));
+ if (!empty($conf->stock->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.stock'=>'product', 'p.pmp'=>'product'));
+ if (!empty($conf->barcode->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode'=>'product'));
+ if (!empty($conf->fournisseur->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref', 'pf.ref_fourn'=>'product_supplier_ref', 'pf.unitprice'=>'product_supplier_ref', 'pf.quantity'=>'product_supplier_ref', 'pf.remise_percent'=>'product_supplier_ref', 'pf.delivery_time_days'=>'product_supplier_ref'));
+ if (!empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation', 'l.description'=>'translation', 'l.note'=>'translation'));
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r] = array('category'=>'p.rowid');
+ if (!empty($conf->stock->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.stock'=>'product', 'p.pmp'=>'product'));
+ if (!empty($conf->barcode->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode'=>'product'));
+ if (!empty($conf->fournisseur->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref', 'pf.ref_fourn'=>'product_supplier_ref', 'pf.unitprice'=>'product_supplier_ref', 'pf.quantity'=>'product_supplier_ref', 'pf.remise_percent'=>'product_supplier_ref', 'pf.delivery_time_days'=>'product_supplier_ref'));
+ if (!empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation', 'l.description'=>'translation', 'l.note'=>'translation'));
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r] = array('category'=>'p.rowid');
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'product as p';
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product = p.rowid LEFT JOIN '.MAIN_DB_PREFIX.'categorie as cat ON cp.fk_categorie = cat.rowid';
+ if (!empty($conf->global->MAIN_MULTILANGS)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_lang as l ON l.fk_product = p.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object';
+ if (!empty($conf->fournisseur->enabled)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_fournisseur_price as pf ON pf.fk_product = p.rowid LEFT JOIN '.MAIN_DB_PREFIX.'societe s ON s.rowid = pf.fk_soc';
+ $this->export_sql_end[$r] .= ' WHERE p.fk_product_type = 0 AND p.entity IN ('.getEntity('product').')';
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_sql_order[$r] = ' GROUP BY p.rowid'; // FIXME The group by used a generic value to say "all fields in select except function fields"
- if (! empty($conf->global->PRODUIT_MULTIPRICES))
+ if (!empty($conf->global->PRODUIT_MULTIPRICES))
{
// Exports product multiprice
$r++;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]="ProductsMultiPrice"; // Translation key (used only if key ExportDataset_xxx_z not found)
- $this->export_permission[$r]=array(array("produit","export"));
- $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref",
- 'pr.price_base_type'=>"PriceBase",'pr.price_level'=>"PriceLevel",
- 'pr.price'=>"PriceLevelUnitPriceHT",'pr.price_ttc'=>"PriceLevelUnitPriceTTC",
- 'pr.price_min'=>"MinPriceLevelUnitPriceHT",'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC",
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = "ProductsMultiPrice"; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_permission[$r] = array(array("produit", "export"));
+ $this->export_fields_array[$r] = array('p.rowid'=>"Id", 'p.ref'=>"Ref",
+ 'pr.price_base_type'=>"PriceBase", 'pr.price_level'=>"PriceLevel",
+ 'pr.price'=>"PriceLevelUnitPriceHT", 'pr.price_ttc'=>"PriceLevelUnitPriceTTC",
+ 'pr.price_min'=>"MinPriceLevelUnitPriceHT", 'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC",
'pr.tva_tx'=>'PriceLevelVATRate',
'pr.date_price'=>'DateCreation');
- if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['pr.recuperableonly']='NPR';
+ if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['pr.recuperableonly'] = 'NPR';
//$this->export_TypeFields_array[$r]=array(
// 'p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text",'p.accountancy_code_buy'=>"Text",
// 'p.note'=>"Text",'p.length'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric",'p.weight'=>"Numeric",'p.customcode'=>'Text',
// 'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",
// 'p.datec'=>'Date','p.tms'=>'Date'
//);
- $this->export_entities_array[$r]=array('p.rowid'=>"product",'p.ref'=>"product",
- 'pr.price_base_type'=>"product",'pr.price_level'=>"product",'pr.price'=>"product",
+ $this->export_entities_array[$r] = array('p.rowid'=>"product", 'p.ref'=>"product",
+ 'pr.price_base_type'=>"product", 'pr.price_level'=>"product", 'pr.price'=>"product",
'pr.price_ttc'=>"product",
- 'pr.price_min'=>"product",'pr.price_min_ttc'=>"product",
+ 'pr.price_min'=>"product", 'pr.price_min_ttc'=>"product",
'pr.tva_tx'=>'product',
'pr.recuperableonly'=>'product',
'pr.date_price'=>"product");
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity
- $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'product as p';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity
+ $this->export_sql_end[$r] .= ' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile
}
- if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
+ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES))
{
// Exports product multiprice
$r++;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]="ProductsPricePerCustomer"; // Translation key (used only if key ExportDataset_xxx_z not found)
- $this->export_permission[$r]=array(array("produit","export"));
- $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref",
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = "ProductsPricePerCustomer"; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_permission[$r] = array(array("produit", "export"));
+ $this->export_fields_array[$r] = array('p.rowid'=>"Id", 'p.ref'=>"Ref",
's.nom'=>'ThirdParty',
'pr.price_base_type'=>"PriceBase",
- 'pr.price'=>"PriceUnitPriceHT",'pr.price_ttc'=>"PriceUnitPriceTTC",
- 'pr.price_min'=>"MinPriceUnitPriceHT",'pr.price_min_ttc'=>"MinPriceUnitPriceTTC",
+ 'pr.price'=>"PriceUnitPriceHT", 'pr.price_ttc'=>"PriceUnitPriceTTC",
+ 'pr.price_min'=>"MinPriceUnitPriceHT", 'pr.price_min_ttc'=>"MinPriceUnitPriceTTC",
'pr.tva_tx'=>'PriceVATRate',
'pr.default_vat_code'=>'PriceVATCode',
'pr.datec'=>'DateCreation');
- if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['pr.recuperableonly']='NPR';
- $this->export_entities_array[$r]=array('p.rowid'=>"product",'p.ref'=>"product",
+ if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['pr.recuperableonly'] = 'NPR';
+ $this->export_entities_array[$r] = array('p.rowid'=>"product", 'p.ref'=>"product",
's.nom'=>'company',
- 'pr.price_base_type'=>"product",'pr.price'=>"product",
+ 'pr.price_base_type'=>"product", 'pr.price'=>"product",
'pr.price_ttc'=>"product",
- 'pr.price_min'=>"product",'pr.price_min_ttc'=>"product",
+ 'pr.price_min'=>"product", 'pr.price_min_ttc'=>"product",
'pr.tva_tx'=>'product',
'pr.default_vat_code'=>'product',
'pr.recuperableonly'=>'product',
'pr.datec'=>"product");
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_customer_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON pr.fk_soc = s.rowid';
- $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'product as p';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_customer_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON pr.fk_soc = s.rowid';
+ $this->export_sql_end[$r] .= ' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile
}
- if (! empty($conf->global->PRODUIT_SOUSPRODUITS))
+ if (!empty($conf->global->PRODUIT_SOUSPRODUITS))
{
// Exports virtual products
$r++;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]="AssociatedProducts"; // Translation key (used only if key ExportDataset_xxx_z not found)
- $this->export_permission[$r]=array(array("produit","export"));
- $this->export_fields_array[$r]=array(
- 'p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",'p.description'=>"Description",'p.url'=>"PublicUrl",
- 'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_sell_intra'=>"ProductAccountancySellIntraCode",
- 'p.accountancy_code_sell_export'=>"ProductAccountancySellExportCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",
- 'p.note'=>"NotePrivate",'p.note_public'=>'NotePublic',
- 'p.weight'=>"Weight",'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume",'p.customcode'=>'CustomCode',
- 'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell",
- 'p.tobuy'=>"OnBuy",'p.datec'=>'DateCreation','p.tms'=>'DateModification'
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = "AssociatedProducts"; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_permission[$r] = array(array("produit", "export"));
+ $this->export_fields_array[$r] = array(
+ 'p.rowid'=>"Id", 'p.ref'=>"Ref", 'p.label'=>"Label", 'p.description'=>"Description", 'p.url'=>"PublicUrl",
+ 'p.accountancy_code_sell'=>"ProductAccountancySellCode", 'p.accountancy_code_sell_intra'=>"ProductAccountancySellIntraCode",
+ 'p.accountancy_code_sell_export'=>"ProductAccountancySellExportCode", 'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",
+ 'p.accountancy_code_buy_intra'=>"ProductAccountancyBuyIntraCode", 'p.accountancy_code_buy_export'=>"ProductAccountancyBuyExportCode",
+ 'p.note'=>"NotePrivate", 'p.note_public'=>'NotePublic',
+ 'p.weight'=>"Weight", 'p.length'=>"Length", 'p.surface'=>"Surface", 'p.volume'=>"Volume", 'p.customcode'=>'CustomCode',
+ 'p.price_base_type'=>"PriceBase", 'p.price'=>"UnitPriceHT", 'p.price_ttc'=>"UnitPriceTTC", 'p.tva_tx'=>'VATRate', 'p.tosell'=>"OnSell",
+ 'p.tobuy'=>"OnBuy", 'p.datec'=>'DateCreation', 'p.tms'=>'DateModification'
);
- if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue'));
- if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode'));
- $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('pa.qty'=>'Qty','pa.incdec'=>'ComposedProductIncDecStock'));
- $this->export_TypeFields_array[$r]=array(
- 'p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text",
- 'p.accountancy_code_sell'=>"Text",'p.accountancy_code_sell_intra'=>"Text",'p.accountancy_code_sell_export'=>"Text",'p.accountancy_code_buy'=>"Text",
- 'p.note'=>"Text",'p.note_public'=>"Text",
- 'p.weight'=>"Numeric",'p.length'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric",'p.customcode'=>'Text',
- 'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",
- 'p.datec'=>'Date','p.tms'=>'Date'
+ if (!empty($conf->stock->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock', 'p.seuil_stock_alerte'=>'StockLimit', 'p.desiredstock'=>'DesiredStock', 'p.pmp'=>'PMPValue'));
+ if (!empty($conf->barcode->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode'));
+ $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('pa.qty'=>'Qty', 'pa.incdec'=>'ComposedProductIncDecStock'));
+ $this->export_TypeFields_array[$r] = array(
+ 'p.ref'=>"Text", 'p.label'=>"Text", 'p.description'=>"Text", 'p.url'=>"Text",
+ 'p.accountancy_code_sell'=>"Text", 'p.accountancy_code_sell_intra'=>"Text", 'p.accountancy_code_sell_export'=>"Text",
+ 'p.accountancy_code_buy'=>"Text", 'p.accountancy_code_buy_intra'=>"Text", 'p.accountancy_code_buy_export'=>"Text",
+ 'p.note'=>"Text", 'p.note_public'=>"Text",
+ 'p.weight'=>"Numeric", 'p.length'=>"Numeric", 'p.surface'=>"Numeric", 'p.volume'=>"Numeric", 'p.customcode'=>'Text',
+ 'p.price_base_type'=>"Text", 'p.price'=>"Numeric", 'p.price_ttc'=>"Numeric", 'p.tva_tx'=>'Numeric', 'p.tosell'=>"Boolean", 'p.tobuy'=>"Boolean",
+ 'p.datec'=>'Date', 'p.tms'=>'Date'
);
- if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric','p.seuil_stock_alerte'=>'Numeric','p.desiredstock'=>'Numeric','p.pmp'=>'Numeric','p.cost_price'=>'Numeric'));
- if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text'));
- $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('pa.qty'=>'Numeric'));
- $this->export_entities_array[$r]=array(
- 'p.rowid'=>"virtualproduct",'p.ref'=>"virtualproduct",'p.label'=>"virtualproduct",'p.description'=>"virtualproduct",'p.url'=>"virtualproduct",
- 'p.accountancy_code_sell'=>'virtualproduct','p.accountancy_code_sell_intra'=>'virtualproduct','p.accountancy_code_sell_export'=>'virtualproduct',
- 'p.accountancy_code_buy'=>'virtualproduct','p.note'=>"virtualproduct",'p.length'=>"virtualproduct",
- 'p.surface'=>"virtualproduct",'p.volume'=>"virtualproduct",'p.weight'=>"virtualproduct",'p.customcode'=>'virtualproduct',
- 'p.price_base_type'=>"virtualproduct",'p.price'=>"virtualproduct",'p.price_ttc'=>"virtualproduct",'p.tva_tx'=>"virtualproduct",
- 'p.tosell'=>"virtualproduct",'p.tobuy'=>"virtualproduct",'p.datec'=>"virtualproduct",'p.tms'=>"virtualproduct"
+ if (!empty($conf->stock->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric', 'p.seuil_stock_alerte'=>'Numeric', 'p.desiredstock'=>'Numeric', 'p.pmp'=>'Numeric', 'p.cost_price'=>'Numeric'));
+ if (!empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text'));
+ $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('pa.qty'=>'Numeric'));
+ $this->export_entities_array[$r] = array(
+ 'p.rowid'=>"virtualproduct", 'p.ref'=>"virtualproduct", 'p.label'=>"virtualproduct", 'p.description'=>"virtualproduct", 'p.url'=>"virtualproduct",
+ 'p.accountancy_code_sell'=>'virtualproduct', 'p.accountancy_code_sell_intra'=>'virtualproduct', 'p.accountancy_code_sell_export'=>'virtualproduct',
+ 'p.accountancy_code_buy'=>'virtualproduct', 'p.accountancy_code_buy_intra'=>'virtualproduct', 'p.accountancy_code_buy_export'=>'virtualproduct',
+ 'p.note'=>"virtualproduct", 'p.length'=>"virtualproduct",
+ 'p.surface'=>"virtualproduct", 'p.volume'=>"virtualproduct", 'p.weight'=>"virtualproduct", 'p.customcode'=>'virtualproduct',
+ 'p.price_base_type'=>"virtualproduct", 'p.price'=>"virtualproduct", 'p.price_ttc'=>"virtualproduct", 'p.tva_tx'=>"virtualproduct",
+ 'p.tosell'=>"virtualproduct", 'p.tobuy'=>"virtualproduct", 'p.datec'=>"virtualproduct", 'p.tms'=>"virtualproduct"
);
- if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'virtualproduct','p.seuil_stock_alerte'=>'virtualproduct','p.desiredstock'=>'virtualproduct','p.pmp'=>'virtualproduct'));
- if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'virtualproduct'));
- $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('pa.qty'=>"subproduct",'pa.incdec'=>'subproduct'));
- $keyforselect='product'; $keyforelement='product'; $keyforaliasextra='extra';
+ if (!empty($conf->stock->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.stock'=>'virtualproduct', 'p.seuil_stock_alerte'=>'virtualproduct', 'p.desiredstock'=>'virtualproduct', 'p.pmp'=>'virtualproduct'));
+ if (!empty($conf->barcode->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode'=>'virtualproduct'));
+ $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('pa.qty'=>"subproduct", 'pa.incdec'=>'subproduct'));
+ $keyforselect = 'product'; $keyforelement = 'product'; $keyforaliasextra = 'extra';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
- $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p2.rowid'=>"Id",'p2.ref'=>"Ref",'p2.label'=>"Label",'p2.description'=>"Description"));
- $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p2.rowid'=>"subproduct",'p2.ref'=>"subproduct",'p2.label'=>"subproduct",'p2.description'=>"subproduct"));
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object,';
- $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'product_association as pa, '.MAIN_DB_PREFIX.'product as p2';
- $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile
- $this->export_sql_end[$r] .=' AND p.rowid = pa.fk_product_pere AND p2.rowid = pa.fk_product_fils';
+ $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p2.rowid'=>"Id", 'p2.ref'=>"Ref", 'p2.label'=>"Label", 'p2.description'=>"Description"));
+ $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p2.rowid'=>"subproduct", 'p2.ref'=>"subproduct", 'p2.label'=>"subproduct", 'p2.description'=>"subproduct"));
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'product as p';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object,';
+ $this->export_sql_end[$r] .= ' '.MAIN_DB_PREFIX.'product_association as pa, '.MAIN_DB_PREFIX.'product as p2';
+ $this->export_sql_end[$r] .= ' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile
+ $this->export_sql_end[$r] .= ' AND p.rowid = pa.fk_product_pere AND p2.rowid = pa.fk_product_fils';
}
// Imports
//--------
- $r=0;
+ $r = 0;
// Import list of products
$r++;
- $this->import_code[$r]=$this->rights_class.'_'.$r;
- $this->import_label[$r]="Products"; // Translation key
- $this->import_icon[$r]=$this->picto;
- $this->import_entities_array[$r]=array(); // We define here only fields that use a different icon from the one defined in import_icon
- $this->import_tables_array[$r]=array('p'=>MAIN_DB_PREFIX.'product','extra'=>MAIN_DB_PREFIX.'product_extrafields');
- $this->import_tables_creator_array[$r]=array('p'=>'fk_user_author'); // Fields to store import user id
- $this->import_fields_array[$r]=array(
+ $this->import_code[$r] = $this->rights_class.'_'.$r;
+ $this->import_label[$r] = "Products"; // Translation key
+ $this->import_icon[$r] = $this->picto;
+ $this->import_entities_array[$r] = array(); // We define here only fields that use a different icon from the one defined in import_icon
+ $this->import_tables_array[$r] = array('p'=>MAIN_DB_PREFIX.'product', 'extra'=>MAIN_DB_PREFIX.'product_extrafields');
+ $this->import_tables_creator_array[$r] = array('p'=>'fk_user_author'); // Fields to store import user id
+ $this->import_fields_array[$r] = array(
'p.ref' => "Ref*",
'p.label' => "Label*",
'p.fk_product_type' => "Type*",
@@ -384,6 +390,8 @@ class modProduct extends DolibarrModules
'p.accountancy_code_sell_intra' => "ProductAccountancySellIntraCode",
'p.accountancy_code_sell_export' => "ProductAccountancySellExportCode",
'p.accountancy_code_buy' => "ProductAccountancyBuyCode",
+ 'p.accountancy_code_buy_intra' => "ProductAccountancyBuyIntraCode",
+ 'p.accountancy_code_buy_export' => "ProductAccountancyBuyExportCode",
'p.note_public' => "NotePublic",
'p.note' => "NotePrivate",
'p.weight' => "Weight",
@@ -533,6 +541,8 @@ class modProduct extends DolibarrModules
'p.accountancy_code_sell_intra' => "",
'p.accountancy_code_sell_export' => "",
'p.accountancy_code_buy' => "",
+ 'p.accountancy_code_buy_intra' => "",
+ 'p.accountancy_code_buy_export' => "",
'p.weight' => "",
'p.weight_units' => 'kg', // Use a unit of measure from the dictionary. g/Kg/T etc....matches field "Short label" for unit type "weight" in table "' . MAIN_DB_PREFIX . 'c_units',
'p.length' => "",
@@ -566,7 +576,7 @@ class modProduct extends DolibarrModules
)
);
- if (! is_array($this->import_convertvalue_array[$r])) $this->import_convertvalue_array[$r] = array();
+ if (!is_array($this->import_convertvalue_array[$r])) $this->import_convertvalue_array[$r] = array();
$this->import_convertvalue_array[$r] = array_merge($this->import_convertvalue_array[$r], array(
'p.fk_unit' => array(
'rule' => 'fetchidfromcodeorlabel',
diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php
index 5489e2b92ca..77d339da035 100644
--- a/htdocs/core/modules/modProjet.class.php
+++ b/htdocs/core/modules/modProjet.class.php
@@ -28,7 +28,7 @@
* \ingroup projet
* \brief Fichier de description et activation du module Projet
*/
-include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
+include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
/**
@@ -58,22 +58,22 @@ class modProjet extends DolibarrModules
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
$this->config_page_url = array("project.php@projet");
- $this->picto='project';
+ $this->picto = 'project';
// Data directories to create when module is enabled
$this->dirs = array("/projet/temp");
// Dependencies
- $this->hidden = false; // A condition to hide module
- $this->depends = array(); // List of module class names as string that must be enabled if this module is enabled
- $this->requiredby = array(); // List of module ids to disable if this one is disabled
- $this->conflictwith = array(); // List of module class names as string this module is in conflict with
- $this->phpmin = array(5,4); // Minimum version of PHP required by module
+ $this->hidden = false; // A condition to hide module
+ $this->depends = array(); // List of module class names as string that must be enabled if this module is enabled
+ $this->requiredby = array(); // List of module ids to disable if this one is disabled
+ $this->conflictwith = array(); // List of module class names as string this module is in conflict with
+ $this->phpmin = array(5, 4); // Minimum version of PHP required by module
$this->langfiles = array('projects');
// Constants
$this->const = array();
- $r=0;
+ $r = 0;
$this->const[$r][0] = "PROJECT_ADDON_PDF";
$this->const[$r][1] = "chaine";
@@ -139,7 +139,7 @@ class modProjet extends DolibarrModules
// Boxes
$this->boxes = array();
- $r=0;
+ $r = 0;
$this->boxes[$r][1] = "box_project.php";
$r++;
$this->boxes[$r][1] = "box_task.php";
@@ -148,7 +148,7 @@ class modProjet extends DolibarrModules
// Permissions
$this->rights = array();
$this->rights_class = 'projet';
- $r=0;
+ $r = 0;
$r++;
$this->rights[$r][0] = 41; // id de la permission
@@ -205,34 +205,43 @@ class modProjet extends DolibarrModules
// Menus
//-------
- $this->menu = 1; // This module add menu entries. They are coded into menu manager.
+ $this->menu = 1; // This module add menu entries. They are coded into menu manager.
//Exports
//--------
- $r=1;
+ $r = 1;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]='ProjectsAndTasksLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
- $this->export_permission[$r]=array(array("projet","export"));
- $this->export_dependencies_array[$r]=array('projecttask'=>'pt.rowid', 'task_time'=>'ptt.rowid');
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = 'ProjectsAndTasksLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_permission[$r] = array(array("projet", "export"));
+ $this->export_dependencies_array[$r] = array('projecttask'=>'pt.rowid', 'task_time'=>'ptt.rowid');
- $this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom::thirdparty",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','s.fk_pays'=>'List:c_country:label',
- 's.phone'=>'Text','s.email'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text',
- 'p.rowid'=>"List:projet:ref::project",'p.ref'=>"Text",'p.title'=>"Text",'p.datec'=>"Date",'p.dateo'=>"Date",'p.datee'=>"Date",'p.fk_statut'=>'Status','cls.code'=>"Text",'p.opp_percent'=>'Numeric','p.opp_amount'=>'Numeric','p.description'=>"Text",'p.entity'=>'Numeric',
- 'pt.rowid'=>'Numeric','pt.ref'=>'Text','pt.label'=>'Text','pt.dateo'=>"Date",'pt.datee'=>"Date",'pt.duration_effective'=>"Duree",'pt.planned_workload'=>"Numeric",'pt.progress'=>"Numeric",'pt.description'=>"Text",
- 'ptt.rowid'=>'Numeric','ptt.task_date'=>'Date','ptt.task_duration'=>"Duree",'ptt.fk_user'=>"List:user:CONCAT(lastname,' ',firstname)",'ptt.note'=>"Text");
- $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','s.fk_pays'=>'company',
- 's.phone'=>'company','s.email'=>'company','s.siren'=>'company','s.siret'=>'company','s.ape'=>'company','s.idprof4'=>'company','s.code_compta'=>'company','s.code_compta_fournisseur'=>'company');
-
- $this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','s.fk_pays'=>'Country',
- 's.phone'=>'Phone','s.email'=>'Email','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.code_compta'=>'CustomerAccountancyCode','s.code_compta_fournisseur'=>'SupplierAccountancyCode',
- 'p.rowid'=>"ProjectId",'p.ref'=>"RefProject",'p.title'=>'ProjectLabel', 'p.datec'=>"DateCreation",'p.dateo'=>"DateStart",'p.datee'=>"DateEnd",'p.fk_statut'=>'ProjectStatus','cls.code'=>'OpportunityStatus','p.opp_percent'=>'OpportunityProbability','p.opp_amount'=>'OpportunityAmount','p.description'=>"Description");
+ $this->export_TypeFields_array[$r] = array(
+ 's.rowid'=>"List:societe:nom::thirdparty", 's.nom'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 's.fk_pays'=>'List:c_country:label',
+ 's.phone'=>'Text', 's.email'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 's.code_compta'=>'Text', 's.code_compta_fournisseur'=>'Text',
+ 'p.rowid'=>"List:projet:ref::project", 'p.ref'=>"Text", 'p.title'=>"Text",
+ 'p.usage_opportunity'=>'Boolean', 'p.usage_task'=>'Boolean', 'p.usage_bill_time'=>'Boolean',
+ 'p.datec'=>"Date", 'p.dateo'=>"Date", 'p.datee'=>"Date", 'p.fk_statut'=>'Status', 'cls.code'=>"Text", 'p.opp_percent'=>'Numeric', 'p.opp_amount'=>'Numeric', 'p.description'=>"Text", 'p.entity'=>'Numeric',
+ 'pt.rowid'=>'Numeric', 'pt.ref'=>'Text', 'pt.label'=>'Text', 'pt.dateo'=>"Date", 'pt.datee'=>"Date", 'pt.duration_effective'=>"Duree", 'pt.planned_workload'=>"Numeric", 'pt.progress'=>"Numeric", 'pt.description'=>"Text",
+ 'ptt.rowid'=>'Numeric', 'ptt.task_date'=>'Date', 'ptt.task_duration'=>"Duree", 'ptt.fk_user'=>"List:user:CONCAT(lastname,' ',firstname)", 'ptt.note'=>"Text"
+ );
+ $this->export_entities_array[$r] = array(
+ 's.rowid'=>"company", 's.nom'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 's.fk_pays'=>'company',
+ 's.phone'=>'company', 's.email'=>'company', 's.siren'=>'company', 's.siret'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.code_compta'=>'company', 's.code_compta_fournisseur'=>'company'
+ );
+ $this->export_fields_array[$r] = array(
+ 's.rowid'=>"IdCompany", 's.nom'=>'CompanyName', 's.address'=>'Address', 's.zip'=>'Zip', 's.town'=>'Town', 's.fk_pays'=>'Country',
+ 's.phone'=>'Phone', 's.email'=>'Email', 's.siren'=>'ProfId1', 's.siret'=>'ProfId2', 's.ape'=>'ProfId3', 's.idprof4'=>'ProfId4', 's.code_compta'=>'CustomerAccountancyCode', 's.code_compta_fournisseur'=>'SupplierAccountancyCode',
+ 'p.rowid'=>"ProjectId", 'p.ref'=>"RefProject", 'p.title'=>'ProjectLabel',
+ 'p.usage_opportunity'=>'ProjectFollowOpportunity', 'p.usage_task'=>'ProjectFollowTasks', 'p.usage_bill_time'=>'BillTime',
+ 'p.datec'=>"DateCreation", 'p.dateo'=>"DateStart", 'p.datee'=>"DateEnd", 'p.fk_statut'=>'ProjectStatus', 'cls.code'=>'OpportunityStatus', 'p.opp_percent'=>'OpportunityProbability', 'p.opp_amount'=>'OpportunityAmount', 'p.description'=>"Description"
+ );
// Add multicompany field
- if (! empty($conf->global->MULTICOMPANY_ENTITY_IN_EXPORT_IF_SHARED))
+ if (!empty($conf->global->MULTICOMPANY_ENTITY_IN_EXPORT_IF_SHARED))
{
- $nbofallowedentities=count(explode(',', getEntity('project'))); // If project are shared, nb will be > 1
- if (! empty($conf->multicompany->enabled) && $nbofallowedentities > 1) $this->export_fields_array[$r]+=array('p.entity'=>'Entity');
+ $nbofallowedentities = count(explode(',', getEntity('project'))); // If project are shared, nb will be > 1
+ if (!empty($conf->multicompany->enabled) && $nbofallowedentities > 1) $this->export_fields_array[$r] += array('p.entity'=>'Entity');
}
if (empty($conf->global->PROJECT_USE_OPPORTUNITIES))
{
@@ -242,62 +251,68 @@ class modProjet extends DolibarrModules
}
// Add fields for project
- $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array());
+ $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array());
// Add extra fields for project
- $keyforselect='projet'; $keyforelement='project'; $keyforaliasextra='extra';
+ $keyforselect = 'projet'; $keyforelement = 'project'; $keyforaliasextra = 'extra';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
// Add fields for tasks
- $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('pt.rowid'=>'TaskId', 'pt.ref'=>'RefTask', 'pt.label'=>'LabelTask', 'pt.dateo'=>"TaskDateStart", 'pt.datee'=>"TaskDateEnd", 'pt.duration_effective'=>"DurationEffective", 'pt.planned_workload'=>"PlannedWorkload", 'pt.progress'=>"Progress", 'pt.description'=>"TaskDescription"));
- $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('pt.rowid'=>'projecttask', 'pt.ref'=>'projecttask', 'pt.label'=>'projecttask', 'pt.dateo'=>"projecttask", 'pt.datee'=>"projecttask", 'pt.duration_effective'=>"projecttask", 'pt.planned_workload'=>"projecttask", 'pt.progress'=>"projecttask", 'pt.description'=>"projecttask"));
+ $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('pt.rowid'=>'TaskId', 'pt.ref'=>'RefTask', 'pt.label'=>'LabelTask', 'pt.dateo'=>"TaskDateStart", 'pt.datee'=>"TaskDateEnd", 'pt.duration_effective'=>"DurationEffective", 'pt.planned_workload'=>"PlannedWorkload", 'pt.progress'=>"Progress", 'pt.description'=>"TaskDescription"));
+ $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('pt.rowid'=>'projecttask', 'pt.ref'=>'projecttask', 'pt.label'=>'projecttask', 'pt.dateo'=>"projecttask", 'pt.datee'=>"projecttask", 'pt.duration_effective'=>"projecttask", 'pt.planned_workload'=>"projecttask", 'pt.progress'=>"projecttask", 'pt.description'=>"projecttask"));
// Add extra fields for task
- $keyforselect='projet_task'; $keyforelement='projecttask'; $keyforaliasextra='extra2';
+ $keyforselect = 'projet_task'; $keyforelement = 'projecttask'; $keyforaliasextra = 'extra2';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
// End add extra fields
- $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('ptt.rowid'=>'IdTaskTime','ptt.task_date'=>'TaskTimeDate','ptt.task_duration'=>"TimesSpent",'ptt.fk_user'=>"TaskTimeUser",'ptt.note'=>"TaskTimeNote"));
- $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('ptt.rowid'=>'task_time','ptt.task_date'=>'task_time','ptt.task_duration'=>"task_time",'ptt.fk_user'=>"task_time",'ptt.note'=>"task_time"));
-
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'projet as p';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'projet_extrafields as extra ON p.rowid = extra.fk_object';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_lead_status as cls ON p.fk_opp_status = cls.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX."projet_task as pt ON p.rowid = pt.fk_projet";
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'projet_task_extrafields as extra2 ON pt.rowid = extra2.fk_object';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX."projet_task_time as ptt ON pt.rowid = ptt.fk_task";
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON p.fk_soc = s.rowid';
- $this->export_sql_end[$r] .=" WHERE p.entity IN (".getEntity('project').")";
+ $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('ptt.rowid'=>'IdTaskTime', 'ptt.task_date'=>'TaskTimeDate', 'ptt.task_duration'=>"TimesSpent", 'ptt.fk_user'=>"TaskTimeUser", 'ptt.note'=>"TaskTimeNote"));
+ $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('ptt.rowid'=>'task_time', 'ptt.task_date'=>'task_time', 'ptt.task_duration'=>"task_time", 'ptt.fk_user'=>"task_time", 'ptt.note'=>"task_time"));
+ if (empty($conf->global->PROJECT_HIDE_TASKS)) {
+ $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('f.ref'=>"Billed"));
+ $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('f.ref'=>"task_time"));
+ }
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'projet as p';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet_extrafields as extra ON p.rowid = extra.fk_object';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_lead_status as cls ON p.fk_opp_status = cls.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX."projet_task as pt ON p.rowid = pt.fk_projet";
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet_task_extrafields as extra2 ON pt.rowid = extra2.fk_object';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX."projet_task_time as ptt ON pt.rowid = ptt.fk_task";
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON p.fk_soc = s.rowid';
+ if (empty($conf->global->PROJECT_HIDE_TASKS)) {
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture as f ON ptt.invoice_id = f.rowid';
+ }
+ $this->export_sql_end[$r] .= " WHERE p.entity IN (".getEntity('project').")";
// Import list of tasks
if (empty($conf->global->PROJECT_HIDE_TASKS))
{
$r++;
- $this->import_code[$r]='tasksofprojects';
- $this->import_label[$r]='ImportDatasetTasks';
- $this->import_icon[$r]='task';
- $this->import_entities_array[$r]=array('t.fk_projet'=>'project'); // We define here only fields that use another icon that the one defined into import_icon
- $this->import_tables_array[$r]=array('t'=>MAIN_DB_PREFIX.'projet_task','extra'=>MAIN_DB_PREFIX.'projet_task_extrafields'); // List of tables to insert into (insert done in same order)
- $this->import_fields_array[$r]=array('t.fk_projet'=>'ProjectRef*','t.ref'=>'RefTask*','t.label'=>'LabelTask*','t.dateo'=>"DateStart",'t.datee'=>"DateEnd",'t.planned_workload'=>"PlannedWorkload",'t.progress'=>"Progress",'t.note_private'=>"NotePrivate",'t.note_public'=>"NotePublic",'t.datec'=>"DateCreation");
+ $this->import_code[$r] = 'tasksofprojects';
+ $this->import_label[$r] = 'ImportDatasetTasks';
+ $this->import_icon[$r] = 'task';
+ $this->import_entities_array[$r] = array('t.fk_projet'=>'project'); // We define here only fields that use another icon that the one defined into import_icon
+ $this->import_tables_array[$r] = array('t'=>MAIN_DB_PREFIX.'projet_task', 'extra'=>MAIN_DB_PREFIX.'projet_task_extrafields'); // List of tables to insert into (insert done in same order)
+ $this->import_fields_array[$r] = array('t.fk_projet'=>'ProjectRef*', 't.ref'=>'RefTask*', 't.label'=>'LabelTask*', 't.dateo'=>"DateStart", 't.datee'=>"DateEnd", 't.planned_workload'=>"PlannedWorkload", 't.progress'=>"Progress", 't.note_private'=>"NotePrivate", 't.note_public'=>"NotePublic", 't.datec'=>"DateCreation");
// Add extra fields
- $sql="SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'projet_task' AND entity IN (0,".$conf->entity.")";
- $resql=$this->db->query($sql);
+ $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'projet_task' AND entity IN (0,".$conf->entity.")";
+ $resql = $this->db->query($sql);
if ($resql) // This can fail when class is used on old database (during migration for example)
{
- while ($obj=$this->db->fetch_object($resql))
+ while ($obj = $this->db->fetch_object($resql))
{
- $fieldname='extra.'.$obj->name;
- $fieldlabel=ucfirst($obj->label);
- $this->import_fields_array[$r][$fieldname]=$fieldlabel.($obj->fieldrequired?'*':'');
+ $fieldname = 'extra.'.$obj->name;
+ $fieldlabel = ucfirst($obj->label);
+ $this->import_fields_array[$r][$fieldname] = $fieldlabel.($obj->fieldrequired ? '*' : '');
}
}
// End add extra fields
- $this->import_fieldshidden_array[$r]=array('t.fk_user_creat'=>'user->id','extra.fk_object'=>'lastrowid-'.MAIN_DB_PREFIX.'projet_task'); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent)
- $this->import_convertvalue_array[$r]=array(
- 't.fk_projet'=>array('rule'=>'fetchidfromref','classfile'=>'/projet/class/project.class.php','class'=>'Project','method'=>'fetch','element'=>'Project'),
+ $this->import_fieldshidden_array[$r] = array('t.fk_user_creat'=>'user->id', 'extra.fk_object'=>'lastrowid-'.MAIN_DB_PREFIX.'projet_task'); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent)
+ $this->import_convertvalue_array[$r] = array(
+ 't.fk_projet'=>array('rule'=>'fetchidfromref', 'classfile'=>'/projet/class/project.class.php', 'class'=>'Project', 'method'=>'fetch', 'element'=>'Project'),
't.ref'=>array('rule'=>'getrefifauto')
);
//$this->import_convertvalue_array[$r]=array('s.fk_soc'=>array('rule'=>'lastrowid',table='t');
- $this->import_regex_array[$r]=array('t.dateo'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$','t.datee'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$','t.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]( [0-9][0-9]:[0-9][0-9]:[0-9][0-9])?$');
- $this->import_examplevalues_array[$r]=array('t.fk_projet'=>'MyProjectRef','t.ref'=>"auto or TK2010-1234",'t.label'=>"My task",'t.progress'=>"0 (not started) to 100 (finished)",'t.datec'=>'1972-10-10','t.note_private'=>"My private note",'t.note_public'=>"My public note");
+ $this->import_regex_array[$r] = array('t.dateo'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$', 't.datee'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$', 't.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]( [0-9][0-9]:[0-9][0-9]:[0-9][0-9])?$');
+ $this->import_examplevalues_array[$r] = array('t.fk_projet'=>'MyProjectRef', 't.ref'=>"auto or TK2010-1234", 't.label'=>"My task", 't.progress'=>"0 (not started) to 100 (finished)", 't.datec'=>'1972-10-10', 't.note_private'=>"My private note", 't.note_public'=>"My public note");
}
}
@@ -312,54 +327,54 @@ class modProjet extends DolibarrModules
*/
public function init($options = '')
{
- global $conf,$langs;
+ global $conf, $langs;
// Permissions
$this->remove($options);
//ODT template for project
- $src=DOL_DOCUMENT_ROOT.'/install/doctemplates/projects/template_project.odt';
- $dirodt=DOL_DATA_ROOT.'/doctemplates/projects';
- $dest=$dirodt.'/template_project.odt';
+ $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/projects/template_project.odt';
+ $dirodt = DOL_DATA_ROOT.'/doctemplates/projects';
+ $dest = $dirodt.'/template_project.odt';
- if (file_exists($src) && ! file_exists($dest))
+ if (file_exists($src) && !file_exists($dest))
{
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
dol_mkdir($dirodt);
- $result=dol_copy($src, $dest, 0, 0);
+ $result = dol_copy($src, $dest, 0, 0);
if ($result < 0)
{
$langs->load("errors");
- $this->error=$langs->trans('ErrorFailToCopyFile', $src, $dest);
+ $this->error = $langs->trans('ErrorFailToCopyFile', $src, $dest);
return 0;
}
}
//ODT template for tasks
- $src=DOL_DOCUMENT_ROOT.'/install/doctemplates/tasks/template_task_summary.odt';
- $dirodt=DOL_DATA_ROOT.'/doctemplates/tasks';
- $dest=$dirodt.'/template_task_summary.odt';
+ $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/tasks/template_task_summary.odt';
+ $dirodt = DOL_DATA_ROOT.'/doctemplates/tasks';
+ $dest = $dirodt.'/template_task_summary.odt';
- if (file_exists($src) && ! file_exists($dest))
+ if (file_exists($src) && !file_exists($dest))
{
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
dol_mkdir($dirodt);
- $result=dol_copy($src, $dest, 0, 0);
+ $result = dol_copy($src, $dest, 0, 0);
if ($result < 0)
{
$langs->load("errors");
- $this->error=$langs->trans('ErrorFailToCopyFile', $src, $dest);
+ $this->error = $langs->trans('ErrorFailToCopyFile', $src, $dest);
return 0;
}
}
$sql = array();
- $sql[] ="DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = '".$this->db->escape($this->const[3][2])."' AND type = 'task' AND entity = ".$conf->entity;
- $sql[] ="INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('".$this->db->escape($this->const[3][2])."','task',".$conf->entity.")";
- $sql[] ="DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'beluga' AND type = 'project' AND entity = ".$conf->entity;
- $sql[] ="INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('beluga','project',".$conf->entity.")";
- $sql[] ="DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'baleine' AND type = 'project' AND entity = ".$conf->entity;
- $sql[] ="INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('baleine','project',".$conf->entity.")";
+ $sql[] = "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = '".$this->db->escape($this->const[3][2])."' AND type = 'task' AND entity = ".$conf->entity;
+ $sql[] = "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('".$this->db->escape($this->const[3][2])."','task',".$conf->entity.")";
+ $sql[] = "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'beluga' AND type = 'project' AND entity = ".$conf->entity;
+ $sql[] = "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('beluga','project',".$conf->entity.")";
+ $sql[] = "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'baleine' AND type = 'project' AND entity = ".$conf->entity;
+ $sql[] = "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('baleine','project',".$conf->entity.")";
return $this->_init($sql, $options);
diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php
index 4fb5cb175b0..e99f94aa154 100644
--- a/htdocs/core/modules/modService.class.php
+++ b/htdocs/core/modules/modService.class.php
@@ -4,6 +4,7 @@
* Copyright (C) 2004 Sebastien Di Cintio
* Copyright (C) 2004 Benoit Mortier
* Copyright (C) 2005-2012 Regis Houssin
+ * Copyright (C) 2020 Alexandre Spangaro
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -135,211 +136,216 @@ class modService extends DolibarrModules
// Exports
//--------
- $r=0;
+ $r = 0;
$r++;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]="Services"; // Translation key (used only if key ExportDataset_xxx_z not found)
- $this->export_permission[$r]=array(array("service","export"));
- $this->export_fields_array[$r]=array(
- 'p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",
- 'p.fk_product_type'=>'Type','p.tosell'=>"OnSell",'p.tobuy'=>"OnBuy",
- 'p.description'=>"Description",'p.url'=>"PublicUrl",
- 'p.customcode'=>'CustomCode','p.fk_country'=>'IDCountry',
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = "Services"; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_permission[$r] = array(array("service", "export"));
+ $this->export_fields_array[$r] = array(
+ 'p.rowid'=>"Id", 'p.ref'=>"Ref", 'p.label'=>"Label",
+ 'p.fk_product_type'=>'Type', 'p.tosell'=>"OnSell", 'p.tobuy'=>"OnBuy",
+ 'p.description'=>"Description", 'p.url'=>"PublicUrl",
+ 'p.customcode'=>'CustomCode', 'p.fk_country'=>'IDCountry',
'p.accountancy_code_sell'=>"ProductAccountancySellCode", 'p.accountancy_code_sell_intra'=>"ProductAccountancySellIntraCode",
'p.accountancy_code_sell_export'=>"ProductAccountancySellExportCode", 'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",
- 'p.note'=>"NotePrivate",'p.note_public'=>'NotePublic',
- 'p.weight'=>"Weight",'p.length'=>"Length",'p.width'=>"Width",'p.height'=>"Height",'p.surface'=>"Surface",'p.volume'=>"Volume",
+ 'p.accountancy_code_buy_intra'=>"ProductAccountancyBuyIntraCode", 'p.accountancy_code_buy_export'=>"ProductAccountancyBuyExportCode",
+ 'p.note'=>"NotePrivate", 'p.note_public'=>'NotePublic',
+ 'p.weight'=>"Weight", 'p.length'=>"Length", 'p.width'=>"Width", 'p.height'=>"Height", 'p.surface'=>"Surface", 'p.volume'=>"Volume",
'p.duration'=>"Duration",
'p.finished' => 'Nature',
- 'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",
+ 'p.price_base_type'=>"PriceBase", 'p.price'=>"UnitPriceHT", 'p.price_ttc'=>"UnitPriceTTC",
'p.tva_tx'=>'VATRate',
- 'p.datec'=>'DateCreation','p.tms'=>'DateModification'
+ 'p.datec'=>'DateCreation', 'p.tms'=>'DateModification'
);
- if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['p.recuperableonly']='NPR';
- if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.cost_price'=>'CostPrice'));
- if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue'));
- if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode'));
- $keyforselect='product'; $keyforelement='product'; $keyforaliasextra='extra';
+ if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['p.recuperableonly'] = 'NPR';
+ if (!empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.cost_price'=>'CostPrice'));
+ if (!empty($conf->stock->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock', 'p.seuil_stock_alerte'=>'StockLimit', 'p.desiredstock'=>'DesiredStock', 'p.pmp'=>'PMPValue'));
+ if (!empty($conf->barcode->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode'));
+ $keyforselect = 'product'; $keyforelement = 'product'; $keyforaliasextra = 'extra';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
- if (! empty($conf->fournisseur->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('s.nom'=>'Supplier','pf.ref_fourn'=>'SupplierRef','pf.quantity'=>'QtyMin','pf.remise_percent'=>'DiscountQtyMin','pf.unitprice'=>'BuyingPrice','pf.delivery_time_days'=>'NbDaysToDelivery'));
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('group_concat(cat.label)'=>'Categories'));
- if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('l.lang'=>'Language', 'l.label'=>'TranslatedLabel','l.description'=>'TranslatedDescription','l.note'=>'TranslatedNote'));
- if (! empty($conf->global->PRODUCT_USE_UNITS)) $this->export_fields_array[$r]['p.fk_unit'] = 'Unit';
- $this->export_TypeFields_array[$r]=array(
- 'p.ref'=>"Text",'p.label'=>"Text",
- 'p.fk_product_type'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",
- 'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text",
- 'p.accountancy_code_sell_intra'=>"Text",'p.accountancy_code_sell_export'=>"Text",'p.accountancy_code_buy'=>"Text",
- 'p.note'=>"Text",'p.note_public'=>"Text",
- 'p.weight'=>"Numeric",'p.length'=>"Numeric",'p.width'=>"Numeric",'p.height'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric",
+ if (!empty($conf->fournisseur->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('s.nom'=>'Supplier', 'pf.ref_fourn'=>'SupplierRef', 'pf.quantity'=>'QtyMin', 'pf.remise_percent'=>'DiscountQtyMin', 'pf.unitprice'=>'BuyingPrice', 'pf.delivery_time_days'=>'NbDaysToDelivery'));
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('group_concat(cat.label)'=>'Categories'));
+ if (!empty($conf->global->MAIN_MULTILANGS)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('l.lang'=>'Language', 'l.label'=>'TranslatedLabel', 'l.description'=>'TranslatedDescription', 'l.note'=>'TranslatedNote'));
+ if (!empty($conf->global->PRODUCT_USE_UNITS)) $this->export_fields_array[$r]['p.fk_unit'] = 'Unit';
+ $this->export_TypeFields_array[$r] = array(
+ 'p.ref'=>"Text", 'p.label'=>"Text",
+ 'p.fk_product_type'=>'Numeric', 'p.tosell'=>"Boolean", 'p.tobuy'=>"Boolean",
+ 'p.description'=>"Text", 'p.url'=>"Text", 'p.accountancy_code_sell'=>"Text",
+ 'p.accountancy_code_sell_intra'=>"Text", 'p.accountancy_code_sell_export'=>"Text", 'p.accountancy_code_buy'=>"Text",
+ 'p.accountancy_code_buy_intra'=>"Text", 'p.accountancy_code_buy_export'=>"Text",
+ 'p.note'=>"Text", 'p.note_public'=>"Text",
+ 'p.weight'=>"Numeric", 'p.length'=>"Numeric", 'p.width'=>"Numeric", 'p.height'=>"Numeric", 'p.surface'=>"Numeric", 'p.volume'=>"Numeric",
'p.customcode'=>'Text',
'p.duration'=>"Text",
'p.finished' => 'Numeric',
- 'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric',
- 'p.datec'=>'Date','p.tms'=>'Date'
+ 'p.price_base_type'=>"Text", 'p.price'=>"Numeric", 'p.price_ttc'=>"Numeric", 'p.tva_tx'=>'Numeric',
+ 'p.datec'=>'Date', 'p.tms'=>'Date'
);
- if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric','p.seuil_stock_alerte'=>'Numeric','p.desiredstock'=>'Numeric','p.pmp'=>'Numeric','p.cost_price'=>'Numeric'));
- if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text'));
- if (! empty($conf->fournisseur->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('s.nom'=>'Text','pf.ref_fourn'=>'Text','pf.unitprice'=>'Numeric','pf.quantity'=>'Numeric','pf.remise_percent'=>'Numeric','pf.delivery_time_days'=>'Numeric'));
- if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('l.lang'=>'Text', 'l.label'=>'Text','l.description'=>'Text','l.note'=>'Text'));
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array("group_concat(cat.label)"=>'Text'));
- $this->export_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array("group_concat(cat.label)"=>'category'));
- if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'product','p.pmp'=>'product'));
- if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'product'));
- if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref'));
- if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation'));
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid');
- if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'product','p.pmp'=>'product'));
- if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'product'));
- if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref'));
- if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation'));
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid');
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p';
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product = p.rowid LEFT JOIN '.MAIN_DB_PREFIX.'categorie as cat ON cp.fk_categorie = cat.rowid';
- if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_lang as l ON l.fk_product = p.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object';
- if (! empty($conf->fournisseur->enabled)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_fournisseur_price as pf ON pf.fk_product = p.rowid LEFT JOIN '.MAIN_DB_PREFIX.'societe s ON s.rowid = pf.fk_soc';
- $this->export_sql_end[$r] .=' WHERE p.fk_product_type = 1 AND p.entity IN ('.getEntity('product').')';
- if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_sql_order[$r] =' GROUP BY p.rowid'; // FIXME The group by used a generic value to say "all fields in select except function fields"
+ if (!empty($conf->stock->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric', 'p.seuil_stock_alerte'=>'Numeric', 'p.desiredstock'=>'Numeric', 'p.pmp'=>'Numeric', 'p.cost_price'=>'Numeric'));
+ if (!empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text'));
+ if (!empty($conf->fournisseur->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('s.nom'=>'Text', 'pf.ref_fourn'=>'Text', 'pf.unitprice'=>'Numeric', 'pf.quantity'=>'Numeric', 'pf.remise_percent'=>'Numeric', 'pf.delivery_time_days'=>'Numeric'));
+ if (!empty($conf->global->MAIN_MULTILANGS)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('l.lang'=>'Text', 'l.label'=>'Text', 'l.description'=>'Text', 'l.note'=>'Text'));
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array("group_concat(cat.label)"=>'Text'));
+ $this->export_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array("group_concat(cat.label)"=>'category'));
+ if (!empty($conf->stock->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.stock'=>'product', 'p.pmp'=>'product'));
+ if (!empty($conf->barcode->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode'=>'product'));
+ if (!empty($conf->fournisseur->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref', 'pf.ref_fourn'=>'product_supplier_ref', 'pf.unitprice'=>'product_supplier_ref', 'pf.quantity'=>'product_supplier_ref', 'pf.remise_percent'=>'product_supplier_ref', 'pf.delivery_time_days'=>'product_supplier_ref'));
+ if (!empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation', 'l.description'=>'translation', 'l.note'=>'translation'));
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r] = array('category'=>'p.rowid');
+ if (!empty($conf->stock->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.stock'=>'product', 'p.pmp'=>'product'));
+ if (!empty($conf->barcode->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode'=>'product'));
+ if (!empty($conf->fournisseur->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref', 'pf.ref_fourn'=>'product_supplier_ref', 'pf.unitprice'=>'product_supplier_ref', 'pf.quantity'=>'product_supplier_ref', 'pf.remise_percent'=>'product_supplier_ref', 'pf.delivery_time_days'=>'product_supplier_ref'));
+ if (!empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation', 'l.description'=>'translation', 'l.note'=>'translation'));
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r] = array('category'=>'p.rowid');
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'product as p';
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product = p.rowid LEFT JOIN '.MAIN_DB_PREFIX.'categorie as cat ON cp.fk_categorie = cat.rowid';
+ if (!empty($conf->global->MAIN_MULTILANGS)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_lang as l ON l.fk_product = p.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object';
+ if (!empty($conf->fournisseur->enabled)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_fournisseur_price as pf ON pf.fk_product = p.rowid LEFT JOIN '.MAIN_DB_PREFIX.'societe s ON s.rowid = pf.fk_soc';
+ $this->export_sql_end[$r] .= ' WHERE p.fk_product_type = 1 AND p.entity IN ('.getEntity('product').')';
+ if (!empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_sql_order[$r] = ' GROUP BY p.rowid'; // FIXME The group by used a generic value to say "all fields in select except function fields"
if (empty($conf->product->enabled)) // We enable next import templates only if module product not already enabled (to avoid duplicate entries)
{
- if (! empty($conf->global->PRODUIT_MULTIPRICES))
+ if (!empty($conf->global->PRODUIT_MULTIPRICES))
{
// Exports product multiprice
$r++;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]="ProductsMultiPrice"; // Translation key (used only if key ExportDataset_xxx_z not found)
- $this->export_permission[$r]=array(array("produit","export"));
- $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref",
- 'pr.price_base_type'=>"PriceBase",'pr.price_level'=>"PriceLevel",
- 'pr.price'=>"PriceLevelUnitPriceHT",'pr.price_ttc'=>"PriceLevelUnitPriceTTC",
- 'pr.price_min'=>"MinPriceLevelUnitPriceHT",'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC",
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = "ProductsMultiPrice"; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_permission[$r] = array(array("produit", "export"));
+ $this->export_fields_array[$r] = array('p.rowid'=>"Id", 'p.ref'=>"Ref",
+ 'pr.price_base_type'=>"PriceBase", 'pr.price_level'=>"PriceLevel",
+ 'pr.price'=>"PriceLevelUnitPriceHT", 'pr.price_ttc'=>"PriceLevelUnitPriceTTC",
+ 'pr.price_min'=>"MinPriceLevelUnitPriceHT", 'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC",
'pr.tva_tx'=>'PriceLevelVATRate',
'pr.date_price'=>'DateCreation');
- if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['pr.recuperableonly']='NPR';
+ if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['pr.recuperableonly'] = 'NPR';
//$this->export_TypeFields_array[$r]=array(
// 'p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text",'p.accountancy_code_buy'=>"Text",
// 'p.note'=>"Text",'p.length'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric",'p.weight'=>"Numeric",'p.customcode'=>'Text',
// 'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",
// 'p.datec'=>'Date','p.tms'=>'Date'
//);
- $this->export_entities_array[$r]=array('p.rowid'=>"product",'p.ref'=>"product",
- 'pr.price_base_type'=>"product",'pr.price_level'=>"product",'pr.price'=>"product",
+ $this->export_entities_array[$r] = array('p.rowid'=>"product", 'p.ref'=>"product",
+ 'pr.price_base_type'=>"product", 'pr.price_level'=>"product", 'pr.price'=>"product",
'pr.price_ttc'=>"product",
- 'pr.price_min'=>"product",'pr.price_min_ttc'=>"product",
+ 'pr.price_min'=>"product", 'pr.price_min_ttc'=>"product",
'pr.tva_tx'=>'product',
'pr.recuperableonly'=>'product',
'pr.date_price'=>"product");
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity
- $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'product as p';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity
+ $this->export_sql_end[$r] .= ' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile
}
- if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
+ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES))
{
// Exports product multiprice
$r++;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]="ProductsPricePerCustomer"; // Translation key (used only if key ExportDataset_xxx_z not found)
- $this->export_permission[$r]=array(array("produit","export"));
- $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref",
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = "ProductsPricePerCustomer"; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_permission[$r] = array(array("produit", "export"));
+ $this->export_fields_array[$r] = array('p.rowid'=>"Id", 'p.ref'=>"Ref",
's.nom'=>'ThirdParty',
'pr.price_base_type'=>"PriceBase",
- 'pr.price'=>"PriceUnitPriceHT",'pr.price_ttc'=>"PriceUnitPriceTTC",
- 'pr.price_min'=>"MinPriceUnitPriceHT",'pr.price_min_ttc'=>"MinPriceUnitPriceTTC",
+ 'pr.price'=>"PriceUnitPriceHT", 'pr.price_ttc'=>"PriceUnitPriceTTC",
+ 'pr.price_min'=>"MinPriceUnitPriceHT", 'pr.price_min_ttc'=>"MinPriceUnitPriceTTC",
'pr.tva_tx'=>'PriceVATRate',
'pr.default_vat_code'=>'PriceVATCode',
'pr.datec'=>'DateCreation');
- if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['pr.recuperableonly']='NPR';
- $this->export_entities_array[$r]=array('p.rowid'=>"product",'p.ref'=>"product",
+ if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['pr.recuperableonly'] = 'NPR';
+ $this->export_entities_array[$r] = array('p.rowid'=>"product", 'p.ref'=>"product",
's.nom'=>'company',
- 'pr.price_base_type'=>"product",'pr.price'=>"product",
+ 'pr.price_base_type'=>"product", 'pr.price'=>"product",
'pr.price_ttc'=>"product",
- 'pr.price_min'=>"product",'pr.price_min_ttc'=>"product",
+ 'pr.price_min'=>"product", 'pr.price_min_ttc'=>"product",
'pr.tva_tx'=>'product',
'pr.default_vat_code'=>'product',
'pr.recuperableonly'=>'product',
'pr.datec'=>"product");
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_customer_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON pr.fk_soc = s.rowid';
- $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'product as p';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_customer_price as pr ON p.rowid = pr.fk_product AND pr.entity = '.$conf->entity; // export prices only for the current entity
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON pr.fk_soc = s.rowid';
+ $this->export_sql_end[$r] .= ' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile
}
- if (! empty($conf->global->PRODUIT_SOUSPRODUITS))
+ if (!empty($conf->global->PRODUIT_SOUSPRODUITS))
{
// Exports virtual products
$r++;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]="AssociatedProducts"; // Translation key (used only if key ExportDataset_xxx_z not found)
- $this->export_permission[$r]=array(array("produit","export"));
- $this->export_fields_array[$r]=array(
- 'p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",'p.description'=>"Description",'p.url'=>"PublicUrl",
- 'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_sell_intra'=>"ProductAccountancySellIntraCode",
- 'p.accountancy_code_sell_export'=>"ProductAccountancySellExportCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",
- 'p.note'=>"NotePrivate",'p.note_public'=>'NotePublic',
- 'p.weight'=>"Weight",'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume",'p.customcode'=>'CustomCode',
- 'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell",
- 'p.tobuy'=>"OnBuy",'p.datec'=>'DateCreation','p.tms'=>'DateModification'
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = "AssociatedProducts"; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_permission[$r] = array(array("produit", "export"));
+ $this->export_fields_array[$r] = array(
+ 'p.rowid'=>"Id", 'p.ref'=>"Ref", 'p.label'=>"Label", 'p.description'=>"Description", 'p.url'=>"PublicUrl",
+ 'p.accountancy_code_sell'=>"ProductAccountancySellCode", 'p.accountancy_code_sell_intra'=>"ProductAccountancySellIntraCode",
+ 'p.accountancy_code_sell_export'=>"ProductAccountancySellExportCode", 'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",
+ 'p.accountancy_code_buy_intra'=>"ProductAccountancyBuyIntraCode", 'p.accountancy_code_buy_export'=>"ProductAccountancyBuyExportCode",
+ 'p.note'=>"NotePrivate", 'p.note_public'=>'NotePublic',
+ 'p.weight'=>"Weight", 'p.length'=>"Length", 'p.surface'=>"Surface", 'p.volume'=>"Volume", 'p.customcode'=>'CustomCode',
+ 'p.price_base_type'=>"PriceBase", 'p.price'=>"UnitPriceHT", 'p.price_ttc'=>"UnitPriceTTC", 'p.tva_tx'=>'VATRate', 'p.tosell'=>"OnSell",
+ 'p.tobuy'=>"OnBuy", 'p.datec'=>'DateCreation', 'p.tms'=>'DateModification'
);
- if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue'));
- if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode'));
- $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('pa.qty'=>'Qty','pa.incdec'=>'ComposedProductIncDecStock'));
- $this->export_TypeFields_array[$r]=array(
- 'p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text",
- 'p.accountancy_code_sell'=>"Text",'p.accountancy_code_sell_intra'=>"Text",'p.accountancy_code_sell_export'=>"Text",'p.accountancy_code_buy'=>"Text",
- 'p.note'=>"Text",'p.note_public'=>"Text",
- 'p.weight'=>"Numeric",'p.length'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric",'p.customcode'=>'Text',
- 'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",
- 'p.datec'=>'Date','p.tms'=>'Date'
+ if (!empty($conf->stock->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock', 'p.seuil_stock_alerte'=>'StockLimit', 'p.desiredstock'=>'DesiredStock', 'p.pmp'=>'PMPValue'));
+ if (!empty($conf->barcode->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode'));
+ $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('pa.qty'=>'Qty', 'pa.incdec'=>'ComposedProductIncDecStock'));
+ $this->export_TypeFields_array[$r] = array(
+ 'p.ref'=>"Text", 'p.label'=>"Text", 'p.description'=>"Text", 'p.url'=>"Text",
+ 'p.accountancy_code_sell'=>"Text", 'p.accountancy_code_sell_intra'=>"Text", 'p.accountancy_code_sell_export'=>"Text",
+ 'p.accountancy_code_buy'=>"Text", 'p.accountancy_code_buy_intra'=>"Text", 'p.accountancy_code_buy_export'=>"Text",
+ 'p.note'=>"Text", 'p.note_public'=>"Text",
+ 'p.weight'=>"Numeric", 'p.length'=>"Numeric", 'p.surface'=>"Numeric", 'p.volume'=>"Numeric", 'p.customcode'=>'Text',
+ 'p.price_base_type'=>"Text", 'p.price'=>"Numeric", 'p.price_ttc'=>"Numeric", 'p.tva_tx'=>'Numeric', 'p.tosell'=>"Boolean", 'p.tobuy'=>"Boolean",
+ 'p.datec'=>'Date', 'p.tms'=>'Date'
);
- if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric','p.seuil_stock_alerte'=>'Numeric','p.desiredstock'=>'Numeric','p.pmp'=>'Numeric','p.cost_price'=>'Numeric'));
- if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text'));
- $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('pa.qty'=>'Numeric'));
- $this->export_entities_array[$r]=array(
- 'p.rowid'=>"virtualproduct",'p.ref'=>"virtualproduct",'p.label'=>"virtualproduct",'p.description'=>"virtualproduct",'p.url'=>"virtualproduct",
- 'p.accountancy_code_sell'=>'virtualproduct','p.accountancy_code_sell_intra'=>'virtualproduct','p.accountancy_code_sell_export'=>'virtualproduct',
- 'p.accountancy_code_buy'=>'virtualproduct','p.note'=>"virtualproduct",'p.length'=>"virtualproduct",
- 'p.surface'=>"virtualproduct",'p.volume'=>"virtualproduct",'p.weight'=>"virtualproduct",'p.customcode'=>'virtualproduct',
- 'p.price_base_type'=>"virtualproduct",'p.price'=>"virtualproduct",'p.price_ttc'=>"virtualproduct",'p.tva_tx'=>"virtualproduct",
- 'p.tosell'=>"virtualproduct",'p.tobuy'=>"virtualproduct",'p.datec'=>"virtualproduct",'p.tms'=>"virtualproduct"
+ if (!empty($conf->stock->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric', 'p.seuil_stock_alerte'=>'Numeric', 'p.desiredstock'=>'Numeric', 'p.pmp'=>'Numeric', 'p.cost_price'=>'Numeric'));
+ if (!empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text'));
+ $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('pa.qty'=>'Numeric'));
+ $this->export_entities_array[$r] = array(
+ 'p.rowid'=>"virtualproduct", 'p.ref'=>"virtualproduct", 'p.label'=>"virtualproduct", 'p.description'=>"virtualproduct", 'p.url'=>"virtualproduct",
+ 'p.accountancy_code_sell'=>'virtualproduct', 'p.accountancy_code_sell_intra'=>'virtualproduct', 'p.accountancy_code_sell_export'=>'virtualproduct',
+ 'p.accountancy_code_buy'=>'virtualproduct', 'p.accountancy_code_buy_intra'=>'virtualproduct', 'p.accountancy_code_buy_export'=>'virtualproduct',
+ 'p.note'=>"virtualproduct", 'p.length'=>"virtualproduct",
+ 'p.surface'=>"virtualproduct", 'p.volume'=>"virtualproduct", 'p.weight'=>"virtualproduct", 'p.customcode'=>'virtualproduct',
+ 'p.price_base_type'=>"virtualproduct", 'p.price'=>"virtualproduct", 'p.price_ttc'=>"virtualproduct", 'p.tva_tx'=>"virtualproduct",
+ 'p.tosell'=>"virtualproduct", 'p.tobuy'=>"virtualproduct", 'p.datec'=>"virtualproduct", 'p.tms'=>"virtualproduct"
);
- if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'virtualproduct','p.seuil_stock_alerte'=>'virtualproduct','p.desiredstock'=>'virtualproduct','p.pmp'=>'virtualproduct'));
- if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'virtualproduct'));
- $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('pa.qty'=>"subproduct",'pa.incdec'=>'subproduct'));
- $keyforselect='product'; $keyforelement='product'; $keyforaliasextra='extra';
+ if (!empty($conf->stock->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.stock'=>'virtualproduct', 'p.seuil_stock_alerte'=>'virtualproduct', 'p.desiredstock'=>'virtualproduct', 'p.pmp'=>'virtualproduct'));
+ if (!empty($conf->barcode->enabled)) $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode'=>'virtualproduct'));
+ $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('pa.qty'=>"subproduct", 'pa.incdec'=>'subproduct'));
+ $keyforselect = 'product'; $keyforelement = 'product'; $keyforaliasextra = 'extra';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
- $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p2.rowid'=>"Id",'p2.ref'=>"Ref",'p2.label'=>"Label",'p2.description'=>"Description"));
- $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p2.rowid'=>"subproduct",'p2.ref'=>"subproduct",'p2.label'=>"subproduct",'p2.description'=>"subproduct"));
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object,';
- $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'product_association as pa, '.MAIN_DB_PREFIX.'product as p2';
- $this->export_sql_end[$r] .=' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile
- $this->export_sql_end[$r] .=' AND p.rowid = pa.fk_product_pere AND p2.rowid = pa.fk_product_fils';
+ $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p2.rowid'=>"Id", 'p2.ref'=>"Ref", 'p2.label'=>"Label", 'p2.description'=>"Description"));
+ $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p2.rowid'=>"subproduct", 'p2.ref'=>"subproduct", 'p2.label'=>"subproduct", 'p2.description'=>"subproduct"));
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'product as p';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object,';
+ $this->export_sql_end[$r] .= ' '.MAIN_DB_PREFIX.'product_association as pa, '.MAIN_DB_PREFIX.'product as p2';
+ $this->export_sql_end[$r] .= ' WHERE p.entity IN ('.getEntity('product').')'; // For product and service profile
+ $this->export_sql_end[$r] .= ' AND p.rowid = pa.fk_product_pere AND p2.rowid = pa.fk_product_fils';
}
}
// Imports
//--------
- $r=0;
+ $r = 0;
// Import list of services
$r++;
- $this->import_code[$r]=$this->rights_class.'_'.$r;
- $this->import_label[$r]="Products"; // Translation key
- $this->import_icon[$r]=$this->picto;
- $this->import_entities_array[$r]=array(); // We define here only fields that use a different icon from the one defined in import_icon
- $this->import_tables_array[$r]=array('p'=>MAIN_DB_PREFIX.'product','extra'=>MAIN_DB_PREFIX.'product_extrafields');
- $this->import_tables_creator_array[$r]=array('p'=>'fk_user_author'); // Fields to store import user id
- $this->import_fields_array[$r]=array(
+ $this->import_code[$r] = $this->rights_class.'_'.$r;
+ $this->import_label[$r] = "Products"; // Translation key
+ $this->import_icon[$r] = $this->picto;
+ $this->import_entities_array[$r] = array(); // We define here only fields that use a different icon from the one defined in import_icon
+ $this->import_tables_array[$r] = array('p'=>MAIN_DB_PREFIX.'product', 'extra'=>MAIN_DB_PREFIX.'product_extrafields');
+ $this->import_tables_creator_array[$r] = array('p'=>'fk_user_author'); // Fields to store import user id
+ $this->import_fields_array[$r] = array(
'p.ref' => "Ref*",
'p.label' => "Label*",
'p.fk_product_type' => "Type*",
@@ -353,6 +359,8 @@ class modService extends DolibarrModules
'p.accountancy_code_sell_intra' => "ProductAccountancySellIntraCode",
'p.accountancy_code_sell_export' => "ProductAccountancySellExportCode",
'p.accountancy_code_buy' => "ProductAccountancyBuyCode",
+ 'p.accountancy_code_buy_intra' => "ProductAccountancyBuyIntraCode",
+ 'p.accountancy_code_buy_export' => "ProductAccountancyBuyExportCode",
'p.note_public' => "NotePublic",
'p.note' => "NotePrivate",
'p.weight' => "Weight",
@@ -500,6 +508,8 @@ class modService extends DolibarrModules
'p.accountancy_code_sell_intra' => "",
'p.accountancy_code_sell_export' => "",
'p.accountancy_code_buy' => "",
+ 'p.accountancy_code_buy_intra' => "",
+ 'p.accountancy_code_buy_export' => "",
'p.weight' => "",
'p.weight_units' => 'kg', // Use a unit of measure from the dictionary. g/Kg/T etc....matches field "Short label" for unit type "weight" in table "' . MAIN_DB_PREFIX . 'c_units',
'p.length' => "",
@@ -533,7 +543,7 @@ class modService extends DolibarrModules
)
);
- if (! is_array($this->import_convertvalue_array[$r])) $this->import_convertvalue_array[$r] = array();
+ if (!is_array($this->import_convertvalue_array[$r])) $this->import_convertvalue_array[$r] = array();
$this->import_convertvalue_array[$r] = array_merge($this->import_convertvalue_array[$r], array(
'p.fk_unit' => array(
'rule' => 'fetchidfromcodeorlabel',
diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php
index 2cc525bd8aa..11c9f72c4c3 100644
--- a/htdocs/core/modules/modSociete.class.php
+++ b/htdocs/core/modules/modSociete.class.php
@@ -247,39 +247,39 @@ class modSociete extends DolibarrModules
// Menus
//-------
- $this->menu = 1; // This module add menu entries. They are coded into menu manager.
+ $this->menu = 1; // This module add menu entries. They are coded into menu manager.
// Exports
//--------
- $r=0;
+ $r = 0;
// Export list of third parties and attributes
$r++;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]='ExportDataset_company_1';
- $this->export_icon[$r]='company';
- $this->export_permission[$r]=array(array("societe","export"));
- $this->export_fields_array[$r]=array(
- 's.rowid'=>"Id",'s.nom'=>"Name",'s.name_alias'=>"AliasNameShort",'s.status'=>"Status",'s.client'=>"Customer",'s.fournisseur'=>"Supplier",'s.datec'=>"DateCreation",'s.tms'=>"DateLastModification",
- 's.code_client'=>"CustomerCode",'s.code_fournisseur'=>"SupplierCode",'s.code_compta'=>"AccountancyCode",'s.code_compta_fournisseur'=>"SupplierAccountancyCode",
- 's.address'=>"Address",'s.zip'=>"Zip",'s.town'=>"Town",'d.nom'=>'State','c.label'=>"Country",'c.code'=>"CountryCode",'s.phone'=>"Phone",'s.fax'=>"Fax",
- 's.url'=>"Url",'s.email'=>"Email",'s.default_lang'=>"DefaultLang",'s.siren'=>"ProfId1",'s.siret'=>"ProfId2",'s.ape'=>"ProfId3",'s.idprof4'=>"ProfId4",
- 's.idprof5'=>"ProfId5",'s.idprof6'=>"ProfId6",'s.tva_intra'=>"VATIntraShort",'s.capital'=>"Capital",'s.note_private'=>"NotePrivate",'s.note_public'=>"NotePublic",
- 't.libelle'=>"ThirdPartyType",'ce.code'=>"Staff","cfj.libelle"=>"JuridicalStatus",'s.fk_prospectlevel'=>'ProspectLevel',
- 'st.code'=>'ProspectStatus','payterm.libelle'=>'PaymentConditions','paymode.libelle'=>'PaymentMode'
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = 'ExportDataset_company_1';
+ $this->export_icon[$r] = 'company';
+ $this->export_permission[$r] = array(array("societe", "export"));
+ $this->export_fields_array[$r] = array(
+ 's.rowid'=>"Id", 's.nom'=>"Name", 's.name_alias'=>"AliasNameShort", 's.status'=>"Status", 's.client'=>"Customer", 's.fournisseur'=>"Supplier", 's.datec'=>"DateCreation", 's.tms'=>"DateLastModification",
+ 's.code_client'=>"CustomerCode", 's.code_fournisseur'=>"SupplierCode", 's.code_compta'=>"AccountancyCode", 's.code_compta_fournisseur'=>"SupplierAccountancyCode",
+ 's.address'=>"Address", 's.zip'=>"Zip", 's.town'=>"Town", 'd.nom'=>'State', 'c.label'=>"Country", 'c.code'=>"CountryCode", 's.phone'=>"Phone", 's.fax'=>"Fax",
+ 's.url'=>"Url", 's.email'=>"Email", 's.default_lang'=>"DefaultLang", 's.siren'=>"ProfId1", 's.siret'=>"ProfId2", 's.ape'=>"ProfId3", 's.idprof4'=>"ProfId4",
+ 's.idprof5'=>"ProfId5", 's.idprof6'=>"ProfId6", 's.tva_intra'=>"VATIntraShort", 's.capital'=>"Capital", 's.note_private'=>"NotePrivate", 's.note_public'=>"NotePublic",
+ 't.libelle'=>"ThirdPartyType", 'ce.code'=>"Staff", "cfj.libelle"=>"JuridicalStatus", 's.fk_prospectlevel'=>'ProspectLevel',
+ 'st.code'=>'ProspectStatus', 'payterm.libelle'=>'PaymentConditions', 'paymode.libelle'=>'PaymentMode'
);
- if (! empty($conf->global->SOCIETE_USEPREFIX)) $this->export_fields_array[$r]['s.prefix']='Prefix';
- if (! empty($conf->global->PRODUIT_MULTIPRICES)) $this->export_fields_array[$r]['s.price_level']='PriceLevel';
+ if (!empty($conf->global->SOCIETE_USEPREFIX)) $this->export_fields_array[$r]['s.prefix'] = 'Prefix';
+ if (!empty($conf->global->PRODUIT_MULTIPRICES)) $this->export_fields_array[$r]['s.price_level'] = 'PriceLevel';
// Add multicompany field
- if (! empty($conf->global->MULTICOMPANY_ENTITY_IN_EXPORT_IF_SHARED))
+ if (!empty($conf->global->MULTICOMPANY_ENTITY_IN_EXPORT_IF_SHARED))
{
- $nbofallowedentities=count(explode(',', getEntity('societe'))); // If project are shared, nb will be > 1
- if (! empty($conf->multicompany->enabled) && $nbofallowedentities > 1) $this->export_fields_array[$r]+=array('s.entity'=>'Entity');
+ $nbofallowedentities = count(explode(',', getEntity('societe'))); // If project are shared, nb will be > 1
+ if (!empty($conf->multicompany->enabled) && $nbofallowedentities > 1) $this->export_fields_array[$r] += array('s.entity'=>'Entity');
}
- $keyforselect='societe'; $keyforelement='company'; $keyforaliasextra='extra';
+ $keyforselect = 'societe'; $keyforelement = 'company'; $keyforaliasextra = 'extra';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
- $this->export_fields_array[$r]+=array('u.login'=>'SaleRepresentativeLogin','u.firstname'=>'SaleRepresentativeFirstname', 'u.lastname'=>'SaleRepresentativeLastname');
+ $this->export_fields_array[$r] += array('u.login'=>'SaleRepresentativeLogin', 'u.firstname'=>'SaleRepresentativeFirstname', 'u.lastname'=>'SaleRepresentativeLastname');
//$this->export_TypeFields_array[$r]=array(
// 's.rowid'=>"List:societe:nom",'s.nom'=>"Text",'s.status'=>"Text",'s.client'=>"Boolean",'s.fournisseur'=>"Boolean",'s.datec'=>"Date",'s.tms'=>"Date",
// 's.code_client'=>"Text",'s.code_fournisseur'=>"Text",'s.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'c.label'=>"List:c_country:label:label",
@@ -288,101 +288,104 @@ class modSociete extends DolibarrModules
// 't.libelle'=>"Text",'ce.code'=>"List:c_effectif:libelle:code","cfj.libelle"=>"Text",'s.fk_prospectlevel'=>'List:c_prospectlevel:label:code',
// 's.fk_stcomm'=>'List:c_stcomm:libelle:code','d.nom'=>'List:c_departements:nom:rowid'
//);
- $this->export_TypeFields_array[$r]=array(
- 's.rowid'=>"Numeric", 's.nom'=>"Text",'s.name_alias'=>"Text",'s.status'=>"Numeric",'s.client'=>"Numeric",'s.fournisseur'=>"Boolean",'s.datec'=>"Date",'s.tms'=>"Date",
- 's.code_client'=>"Text",'s.code_fournisseur'=>"Text",'s.code_compta'=>"Text",'s.code_compta_fournisseur'=>"Text",'s.address'=>"Text",'s.zip'=>"Text",
- 's.town'=>"Text",'c.label'=>"List:c_country:label:label",'c.code'=>"Text",'s.phone'=>"Text",'s.fax'=>"Text",'s.url'=>"Text",'s.email'=>"Text",
- 's.default_lang'=>"Text",'s.siret'=>"Text",'s.siren'=>"Text",'s.ape'=>"Text",'s.idprof4'=>"Text",'s.idprof5'=>"Text",'s.idprof6'=>"Text",
- 's.tva_intra'=>"Text",'s.capital'=>"Numeric",'s.note_private'=>"Text",'s.note_public'=>"Text",'t.libelle'=>"Text",
- 'ce.code'=>"List:c_effectif:libelle:code","cfj.libelle"=>"Text",'s.fk_prospectlevel'=>'List:c_prospectlevel:label:code',
- 'st.code'=>'List:c_stcomm:libelle:code','d.nom'=>'Text','u.login'=>'Text','u.firstname'=>'Text','u.lastname'=>'Text','payterm.libelle'=>'Text',
- 'paymode.libelle'=>'Text','s.entity'=>'Numeric',
+ $this->export_TypeFields_array[$r] = array(
+ 's.rowid'=>"Numeric", 's.nom'=>"Text", 's.name_alias'=>"Text", 's.status'=>"Numeric", 's.client'=>"Numeric", 's.fournisseur'=>"Boolean", 's.datec'=>"Date", 's.tms'=>"Date",
+ 's.code_client'=>"Text", 's.code_fournisseur'=>"Text", 's.code_compta'=>"Text", 's.code_compta_fournisseur'=>"Text", 's.address'=>"Text", 's.zip'=>"Text",
+ 's.town'=>"Text", 'c.label'=>"List:c_country:label:label", 'c.code'=>"Text", 's.phone'=>"Text", 's.fax'=>"Text", 's.url'=>"Text", 's.email'=>"Text",
+ 's.default_lang'=>"Text", 's.siret'=>"Text", 's.siren'=>"Text", 's.ape'=>"Text", 's.idprof4'=>"Text", 's.idprof5'=>"Text", 's.idprof6'=>"Text",
+ 's.tva_intra'=>"Text", 's.capital'=>"Numeric", 's.note_private'=>"Text", 's.note_public'=>"Text", 't.libelle'=>"Text",
+ 'ce.code'=>"List:c_effectif:libelle:code", "cfj.libelle"=>"Text", 's.fk_prospectlevel'=>'List:c_prospectlevel:label:code',
+ 'st.code'=>'List:c_stcomm:libelle:code', 'd.nom'=>'Text', 'u.login'=>'Text', 'u.firstname'=>'Text', 'u.lastname'=>'Text', 'payterm.libelle'=>'Text',
+ 'paymode.libelle'=>'Text', 's.entity'=>'Numeric',
's.price_level'=>'Numeric'
);
- $this->export_entities_array[$r]=array('u.login'=>'user','u.firstname'=>'user','u.lastname'=>'user'); // We define here only fields that use another picto
- $this->export_examplevalues_array[$r]=array('s.client'=>'0 (no customer no prospect)/1 (customer)/2 (prospect)/3 (customer and prospect)','s.fournisseur'=>'0 (not a supplier) or 1 (supplier)');
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'societe as s';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extra ON s.rowid = extra.fk_object';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON s.fk_departement = d.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_stcomm as st ON s.fk_stcomm = st.id';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid LEFT JOIN '.MAIN_DB_PREFIX.'user as u ON sc.fk_user = u.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as payterm ON s.cond_reglement = payterm.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as paymode ON s.mode_reglement = paymode.id';
- $this->export_sql_end[$r] .=' WHERE s.entity IN ('.getEntity('societe').')';
+ $this->export_entities_array[$r] = array('u.login'=>'user', 'u.firstname'=>'user', 'u.lastname'=>'user'); // We define here only fields that use another picto
+ $this->export_examplevalues_array[$r] = array('s.client'=>'0 (no customer no prospect)/1 (customer)/2 (prospect)/3 (customer and prospect)', 's.fournisseur'=>'0 (not a supplier) or 1 (supplier)');
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'societe as s';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extra ON s.rowid = extra.fk_object';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON s.fk_departement = d.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_stcomm as st ON s.fk_stcomm = st.id';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid LEFT JOIN '.MAIN_DB_PREFIX.'user as u ON sc.fk_user = u.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as payterm ON s.cond_reglement = payterm.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as paymode ON s.mode_reglement = paymode.id';
+ $this->export_sql_end[$r] .= ' WHERE s.entity IN ('.getEntity('societe').')';
if (is_object($user) && empty($user->rights->societe->client->voir)) {
- $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' ';
- if (! empty($conf->global->SOCIETE_EXPORT_SUBORDINATES_CHILDS)) {
+ $this->export_sql_end[$r] .= ' AND (sc.fk_user = '.$user->id.' ';
+ if (!empty($conf->global->SOCIETE_EXPORT_SUBORDINATES_CHILDS)) {
$subordinatesids = $user->getAllChildIds();
- $this->export_sql_end[$r] .=count($subordinatesids)>0 ? ' OR (sc.fk_user IN ('.implode(',', $subordinatesids).')' : '';
+ $this->export_sql_end[$r] .= count($subordinatesids) > 0 ? ' OR (sc.fk_user IN ('.implode(',', $subordinatesids).')' : '';
}
- $this->export_sql_end[$r] .=')';
+ $this->export_sql_end[$r] .= ')';
}
// Export list of contacts and attributes
$r++;
- $this->export_code[$r]=$this->rights_class.'_'.$r;
- $this->export_label[$r]='ExportDataset_company_2';
- $this->export_icon[$r]='contact';
- $this->export_permission[$r]=array(array("societe","contact","export"));
- $this->export_fields_array[$r]=array(
- 'c.rowid'=>"IdContact",'c.civility'=>"CivilityCode",'c.lastname'=>'Lastname','c.firstname'=>'Firstname','c.poste'=>'PostOrFunction',
- 'c.datec'=>"DateCreation",'c.tms'=>"DateLastModification",'c.priv'=>"ContactPrivate",'c.address'=>"Address",'c.zip'=>"Zip",'c.town'=>"Town",
- 'd.nom'=>'State','co.label'=>"Country",'co.code'=>"CountryCode",'c.phone'=>"Phone",'c.fax'=>"Fax",'c.phone_mobile'=>"Mobile",'c.email'=>"EMail",
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = 'ExportDataset_company_2';
+ $this->export_icon[$r] = 'contact';
+ $this->export_permission[$r] = array(array("societe", "contact", "export"));
+ $this->export_fields_array[$r] = array(
+ 'c.rowid'=>"IdContact", 'c.civility'=>"CivilityCode", 'c.lastname'=>'Lastname', 'c.firstname'=>'Firstname', 'c.poste'=>'PostOrFunction',
+ 'c.datec'=>"DateCreation", 'c.tms'=>"DateLastModification", 'c.priv'=>"ContactPrivate", 'c.address'=>"Address", 'c.zip'=>"Zip", 'c.town'=>"Town",
+ 'd.nom'=>'State', 'co.label'=>"Country", 'co.code'=>"CountryCode", 'c.phone'=>"Phone", 'c.fax'=>"Fax", 'c.phone_mobile'=>"Mobile", 'c.email'=>"EMail",
'c.statut'=>"Status",
- 's.rowid'=>"IdCompany",'s.nom'=>"CompanyName",'s.status'=>"Status",'s.code_client'=>"CustomerCode",'s.code_fournisseur'=>"SupplierCode",
- 's.client'=>'Customer','s.fournisseur'=>'Supplier',
- 's.address'=>'Address','s.zip'=>"Zip",'s.town'=>"Town",'s.phone'=>'Phone','s.email'=>"Email",
+ 's.rowid'=>"IdCompany", 's.nom'=>"CompanyName", 's.status'=>"Status", 's.code_client'=>"CustomerCode", 's.code_fournisseur'=>"SupplierCode",
+ 's.code_compta'=>"AccountancyCode", 's.code_compta_fournisseur'=>"SupplierAccountancyCode",
+ 's.client'=>'Customer', 's.fournisseur'=>'Supplier',
+ 's.address'=>'Address', 's.zip'=>"Zip", 's.town'=>"Town", 's.phone'=>'Phone', 's.email'=>"Email",
't.libelle'=>"ThirdPartyType"
);
- $this->export_examplevalues_array[$r]=array('s.client'=>'0 (no customer no prospect)/1 (customer)/2 (prospect)/3 (customer and prospect)','s.fournisseur'=>'0 (not a supplier) or 1 (supplier)');
- $this->export_TypeFields_array[$r]=array(
- 'c.civility'=>"List:c_civility:label:code",'c.lastname'=>'Text','c.firstname'=>'Text','c.poste'=>'Text','c.datec'=>"Date",'c.priv'=>"Boolean",
- 'c.address'=>"Text",'c.zip'=>"Text",'c.town'=>"Text",'d.nom'=>'Text','co.label'=>"List:c_country:label:rowid",'co.code'=>"Text",'c.phone'=>"Text",
- 'c.fax'=>"Text",'c.email'=>"Text",
+ $this->export_examplevalues_array[$r] = array('s.client'=>'0 (no customer no prospect)/1 (customer)/2 (prospect)/3 (customer and prospect)', 's.fournisseur'=>'0 (not a supplier) or 1 (supplier)');
+ $this->export_TypeFields_array[$r] = array(
+ 'c.civility'=>"List:c_civility:label:code", 'c.lastname'=>'Text', 'c.firstname'=>'Text', 'c.poste'=>'Text', 'c.datec'=>"Date", 'c.priv'=>"Boolean",
+ 'c.address'=>"Text", 'c.zip'=>"Text", 'c.town'=>"Text", 'd.nom'=>'Text', 'co.label'=>"List:c_country:label:rowid", 'co.code'=>"Text", 'c.phone'=>"Text",
+ 'c.fax'=>"Text", 'c.email'=>"Text",
'c.statut'=>"Status",
- 's.rowid'=>"List:societe:nom::thirdparty",'s.nom'=>"Text",'s.status'=>"Status",'s.code_client'=>"Text",'s.code_fournisseur'=>"Text",
- 's.client'=>"Text",'s.fournisseur'=>"Text",
- 's.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'s.phone'=>"Text",'s.email'=>"Text",
+ 's.rowid'=>"List:societe:nom::thirdparty", 's.nom'=>"Text", 's.status'=>"Status", 's.code_client'=>"Text", 's.code_fournisseur'=>"Text",
+ 's.code_compta'=>"Text", 's.code_compta_fournisseur'=>"Text",
+ 's.client'=>"Text", 's.fournisseur'=>"Text",
+ 's.address'=>"Text", 's.zip'=>"Text", 's.town'=>"Text", 's.phone'=>"Text", 's.email'=>"Text",
't.libelle'=>"Text"
);
- $this->export_entities_array[$r]=array(
- 's.rowid'=>"company",'s.nom'=>"company", 's.status'=>'company', 's.code_client'=>"company",'s.code_fournisseur'=>"company", 's.client'=>"company",
- 's.fournisseur'=>"company",
+ $this->export_entities_array[$r] = array(
+ 's.rowid'=>"company", 's.nom'=>"company", 's.status'=>'company', 's.code_client'=>"company", 's.code_fournisseur'=>"company",
+ 's.code_compta'=>"company", 's.code_compta_fournisseur'=>"company",
+ 's.client'=>"company", 's.fournisseur'=>"company",
's.address'=>"company", 's.zip'=>"company", 's.town'=>"company", 's.phone'=>"company", 's.email'=>"company",
't.libelle'=>"company"
- ); // We define here only fields that use another picto
+ ); // We define here only fields that use another picto
if (empty($conf->fournisseur->enabled))
{
unset($this->export_fields_array[$r]['s.code_fournisseur']);
unset($this->export_entities_array[$r]['s.code_fournisseur']);
}
- $keyforselect='socpeople'; $keyforelement='contact'; $keyforaliasextra='extra';
+ $keyforselect = 'socpeople'; $keyforelement = 'contact'; $keyforaliasextra = 'extra';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
- $keyforselect='societe'; $keyforelement='company'; $keyforaliasextra='extrasoc';
+ $keyforselect = 'societe'; $keyforelement = 'company'; $keyforaliasextra = 'extrasoc';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'socpeople as c';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON c.fk_soc = s.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extrasoc ON s.rowid = extrasoc.fk_object';
- if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON c.fk_departement = d.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as co ON c.fk_pays = co.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'socpeople_extrafields as extra ON extra.fk_object = c.rowid';
- $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id';
- $this->export_sql_end[$r] .=' WHERE c.entity IN ('.getEntity('socpeople').')';
+ $this->export_sql_start[$r] = 'SELECT DISTINCT ';
+ $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'socpeople as c';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON c.fk_soc = s.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extrasoc ON s.rowid = extrasoc.fk_object';
+ if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON c.fk_departement = d.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as co ON c.fk_pays = co.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'socpeople_extrafields as extra ON extra.fk_object = c.rowid';
+ $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id';
+ $this->export_sql_end[$r] .= ' WHERE c.entity IN ('.getEntity('socpeople').')';
if (is_object($user) && empty($user->rights->societe->client->voir)) {
- $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' ';
- if (! empty($conf->global->SOCIETE_EXPORT_SUBORDINATES_CHILDS)) {
+ $this->export_sql_end[$r] .= ' AND (sc.fk_user = '.$user->id.' ';
+ if (!empty($conf->global->SOCIETE_EXPORT_SUBORDINATES_CHILDS)) {
$subordinatesids = $user->getAllChildIds();
- $this->export_sql_end[$r] .=count($subordinatesids)>0 ? ' OR (sc.fk_user IN ('.implode(',', $subordinatesids).')' : '';
+ $this->export_sql_end[$r] .= count($subordinatesids) > 0 ? ' OR (sc.fk_user IN ('.implode(',', $subordinatesids).')' : '';
}
- $this->export_sql_end[$r] .=')';
+ $this->export_sql_end[$r] .= ')';
}
@@ -684,7 +687,9 @@ class modSociete extends DolibarrModules
'sr.domiciliation' => "BankAccountDomiciliation",
'sr.proprio' => "BankAccountOwner",
'sr.owner_address' => "BankAccountOwnerAddress",
- 'sr.default_rib' => 'Default'
+ 'sr.default_rib' => 'Default',
+ 'sr.rum' => 'RUM',
+ 'sr.type' => "Type ban is defaut",
);
$this->import_convertvalue_array[$r] = array(
@@ -711,7 +716,9 @@ class modSociete extends DolibarrModules
'sr.domiciliation' => 'bank branch address eg. "PARIS"',
'sr.proprio' => 'name on the bank account',
'sr.owner_address' => 'address of account holder',
- 'sr.default_rib' => '1 (default account) / 0 (not default)'
+ 'sr.default_rib' => '1 (default account) / 0 (not default)',
+ 'sr.rum' => 'RUM code',
+ 'sr.type' => 'ban',
);
// Import Company Sales representatives
diff --git a/htdocs/core/modules/modTakePos.class.php b/htdocs/core/modules/modTakePos.class.php
index 804ce8152ab..4671f40dd40 100644
--- a/htdocs/core/modules/modTakePos.class.php
+++ b/htdocs/core/modules/modTakePos.class.php
@@ -265,6 +265,10 @@ class modTakePos extends DolibarrModules
*/
public function init($options = '')
{
+ global $conf,$db;
+
+ dolibarr_set_const($db, "TAKEPOS_PRINT_METHOD", "browser", 'chaine', 0, '', $conf->entity);
+
$this->_load_tables('/takepos/sql/');
$sql = array();
diff --git a/htdocs/core/modules/modUser.class.php b/htdocs/core/modules/modUser.class.php
index ca1a8d22209..c2ce0fec86f 100644
--- a/htdocs/core/modules/modUser.class.php
+++ b/htdocs/core/modules/modUser.class.php
@@ -314,7 +314,8 @@ class modUser extends DolibarrModules
'u.birth'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$'
);
$this->import_examplevalues_array[$r] = array(
- 'u.lastname'=>"Doe", 'u.firstname'=>'John', 'u.login'=>'jdoe', 'u.employee'=>'0 or 1',
+ 'u.lastname'=>"Doe", 'u.firstname'=>'John', 'u.login'=>'jdoe', 'u.employee'=>'0 or 1', 'u.job'=>'CTO', 'u.gender'=>'0 or 1',
+ 'u.pass_crypted'=>'Encrypted password',
'u.fk_soc'=>'0 (internal user) or company name (external user)', 'u.datec'=>dol_print_date(dol_now(), '%Y-%m-%d'), 'u.address'=>"61 jump street",
'u.zip'=>"123456", 'u.town'=>"Big town", 'u.fk_country'=>'US, FR, DE...', 'u.office_phone'=>"0101010101", 'u.office_fax'=>"0101010102",
'u.email'=>"test@mycompany.com", 'u.salary'=>"10000", 'u.note'=>"This is an example of note for record", 'u.datec'=>"2015-01-01 or 2015-01-01 12:30:00",
diff --git a/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php b/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php
index 398c8670a47..e276fe1f5f7 100644
--- a/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php
+++ b/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php
@@ -418,9 +418,11 @@ class doc_generic_mo_odt extends ModelePDFMo
}
if ($foundtagforlines)
{
+ $linenumber = 0;
foreach ($object->lines as $line)
{
- $tmparray = $this->get_substitutionarray_lines($line, $outputlangs);
+ $linenumber++;
+ $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber);
complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines");
// Call the ODTSubstitutionLine hook
$parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line);
diff --git a/htdocs/core/modules/oauth/github_oauthcallback.php b/htdocs/core/modules/oauth/github_oauthcallback.php
index 919781baa93..4320481abb1 100644
--- a/htdocs/core/modules/oauth/github_oauthcallback.php
+++ b/htdocs/core/modules/oauth/github_oauthcallback.php
@@ -29,8 +29,8 @@ use OAuth\Common\Consumer\Credentials;
use OAuth\OAuth2\Service\GitHub;
// Define $urlwithroot
-$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
-$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
+$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
+$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
@@ -70,8 +70,8 @@ $credentials = new Credentials(
$currentUri->getAbsoluteUri()
);
-$requestedpermissionsarray=array();
-if (GETPOST('state')) $requestedpermissionsarray=explode(',', GETPOST('state')); // Example: 'userinfo_email,userinfo_profile,cloud_print'. 'state' parameter is standard to retrieve some parameters back
+$requestedpermissionsarray = array();
+if (GETPOST('state')) $requestedpermissionsarray = explode(',', GETPOST('state')); // Example: 'user'. 'state' parameter is standard to retrieve some parameters back
if ($action != 'delete' && empty($requestedpermissionsarray))
{
print 'Error, parameter state is not defined';
@@ -93,18 +93,17 @@ $langs->load("oauth");
* Actions
*/
-
if ($action == 'delete')
{
$storage->clearToken('GitHub');
setEventMessages($langs->trans('TokenDeleted'), null, 'mesgs');
- header('Location: ' . $backtourl);
+ header('Location: '.$backtourl);
exit();
}
-if (! empty($_GET['code'])) // We are coming from oauth provider page
+if (!empty($_GET['code'])) // We are coming from oauth provider page
{
// We should have
//$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16))
@@ -133,12 +132,12 @@ if (! empty($_GET['code'])) // We are coming from oauth provider page
// parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri)
// has not the ending parameter to true like the Google class constructor.
- setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
+ setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
$backtourl = $_SESSION["backtourlsavedbeforeoauthjump"];
unset($_SESSION["backtourlsavedbeforeoauthjump"]);
- header('Location: ' . $backtourl);
+ header('Location: '.$backtourl);
exit();
} catch (Exception $e) {
print $e->getMessage();
@@ -146,7 +145,7 @@ if (! empty($_GET['code'])) // We are coming from oauth provider page
}
else // If entry on page with no parameter, we arrive here
{
- $_SESSION["backtourlsavedbeforeoauthjump"]=$backtourl;
+ $_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl;
// This may create record into oauth_state before the header redirect.
// Creation of record with state in this tables depend on the Provider used (see its constructor).
@@ -156,11 +155,11 @@ else // If entry on page with no parameter, we arrive here
}
else
{
- $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated
+ $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated
}
// we go on oauth provider authorization page
- header('Location: ' . $url);
+ header('Location: '.$url);
exit();
}
diff --git a/htdocs/core/modules/oauth/google_oauthcallback.php b/htdocs/core/modules/oauth/google_oauthcallback.php
index c9fd9869caf..68aba389f31 100644
--- a/htdocs/core/modules/oauth/google_oauthcallback.php
+++ b/htdocs/core/modules/oauth/google_oauthcallback.php
@@ -29,8 +29,8 @@ use OAuth\Common\Consumer\Credentials;
use OAuth\OAuth2\Service\Google;
// Define $urlwithroot
-$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
-$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
+$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
+$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
@@ -70,8 +70,8 @@ $credentials = new Credentials(
$currentUri->getAbsoluteUri()
);
-$requestedpermissionsarray=array();
-if (GETPOST('state')) $requestedpermissionsarray=explode(',', GETPOST('state')); // Example: 'userinfo_email,userinfo_profile,cloud_print'. 'state' parameter is standard to retrieve some parameters back
+$requestedpermissionsarray = array();
+if (GETPOST('state')) $requestedpermissionsarray = explode(',', GETPOST('state')); // Example: 'userinfo_email,userinfo_profile,cloud_print'. 'state' parameter is standard to store a hash value and can be used to retrieve some parameters back
if ($action != 'delete' && empty($requestedpermissionsarray))
{
print 'Error, parameter state is not defined';
@@ -105,11 +105,11 @@ if ($action == 'delete')
setEventMessages($langs->trans('TokenDeleted'), null, 'mesgs');
- header('Location: ' . $backtourl);
+ header('Location: '.$backtourl);
exit();
}
-if (! empty($_GET['code'])) // We are coming from oauth provider page
+if (!empty($_GET['code'])) // We are coming from oauth provider page
{
dol_syslog("We are coming from the oauth provider page");
//llxHeader('',$langs->trans("OAuthSetup"));
@@ -130,12 +130,12 @@ if (! empty($_GET['code'])) // We are coming from oauth provider page
$token = $apiService->requestAccessToken($_GET['code'], $state);
- setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
+ setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
$backtourl = $_SESSION["backtourlsavedbeforeoauthjump"];
unset($_SESSION["backtourlsavedbeforeoauthjump"]);
- header('Location: ' . $backtourl);
+ header('Location: '.$backtourl);
exit();
} catch (Exception $e) {
print $e->getMessage();
@@ -143,7 +143,7 @@ if (! empty($_GET['code'])) // We are coming from oauth provider page
}
else // If entry on page with no parameter, we arrive here
{
- $_SESSION["backtourlsavedbeforeoauthjump"]=$backtourl;
+ $_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl;
// This may create record into oauth_state before the header redirect.
// Creation of record with state in this tables depend on the Provider used (see its constructor).
@@ -153,11 +153,11 @@ else // If entry on page with no parameter, we arrive here
}
else
{
- $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated
+ $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated
}
// we go on oauth provider authorization page
- header('Location: ' . $url);
+ header('Location: '.$url);
exit();
}
diff --git a/htdocs/core/modules/payment/mod_payment_ant.php b/htdocs/core/modules/payment/mod_payment_ant.php
index 612a411daed..a42b68b37e4 100644
--- a/htdocs/core/modules/payment/mod_payment_ant.php
+++ b/htdocs/core/modules/payment/mod_payment_ant.php
@@ -44,7 +44,7 @@ class mod_payment_ant extends ModeleNumRefPayments
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Ant';
diff --git a/htdocs/core/modules/payment/mod_payment_cicada.php b/htdocs/core/modules/payment/mod_payment_cicada.php
index cd796fbcd19..9c40a575f47 100644
--- a/htdocs/core/modules/payment/mod_payment_cicada.php
+++ b/htdocs/core/modules/payment/mod_payment_cicada.php
@@ -45,7 +45,7 @@ class mod_payment_cicada extends ModeleNumRefPayments
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Cicada';
diff --git a/htdocs/core/modules/project/mod_project_simple.php b/htdocs/core/modules/project/mod_project_simple.php
index d73ee22fbae..92f86a433c8 100644
--- a/htdocs/core/modules/project/mod_project_simple.php
+++ b/htdocs/core/modules/project/mod_project_simple.php
@@ -47,7 +47,7 @@ class mod_project_simple extends ModeleNumRefProjects
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Simple';
diff --git a/htdocs/core/modules/project/mod_project_universal.php b/htdocs/core/modules/project/mod_project_universal.php
index 9bf0d313ae8..f833ec280d2 100644
--- a/htdocs/core/modules/project/mod_project_universal.php
+++ b/htdocs/core/modules/project/mod_project_universal.php
@@ -44,7 +44,7 @@ class mod_project_universal extends ModeleNumRefProjects
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom = 'Universal';
diff --git a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php
index 386de7bfdd7..8a38450697f 100644
--- a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php
+++ b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php
@@ -57,7 +57,7 @@ class doc_generic_task_odt extends ModelePDFTask
{
/**
* Issuer
- * @var Company object that emits
+ * @var Societe Object that emits
*/
public $emetteur;
diff --git a/htdocs/core/modules/project/task/mod_task_simple.php b/htdocs/core/modules/project/task/mod_task_simple.php
index 65c7deb8edf..3f9debf9941 100644
--- a/htdocs/core/modules/project/task/mod_task_simple.php
+++ b/htdocs/core/modules/project/task/mod_task_simple.php
@@ -47,7 +47,7 @@ class mod_task_simple extends ModeleNumRefTask
/**
* @var string
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Simple';
diff --git a/htdocs/core/modules/project/task/mod_task_universal.php b/htdocs/core/modules/project/task/mod_task_universal.php
index 1eecf94734b..b1c4f576a74 100644
--- a/htdocs/core/modules/project/task/mod_task_universal.php
+++ b/htdocs/core/modules/project/task/mod_task_universal.php
@@ -44,7 +44,7 @@ class mod_task_universal extends ModeleNumRefTask
/**
* @var string
* @deprecated
- * @see name
+ * @see $name
*/
public $nom = 'Universal';
diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
index fde5f08d318..33850c5d882 100644
--- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
+++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
@@ -456,9 +456,11 @@ class doc_generic_proposal_odt extends ModelePDFPropales
}
if ($foundtagforlines)
{
+ $linenumber = 0;
foreach ($object->lines as $line)
{
- $tmparray = $this->get_substitutionarray_lines($line, $outputlangs);
+ $linenumber++;
+ $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber);
complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines");
// Call the ODTSubstitutionLine hook
$parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line);
diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php
index 9ed7a065cc1..0167d900b3f 100644
--- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php
+++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php
@@ -502,7 +502,7 @@ class pdf_azur extends ModelePDFPropales
$curY = $tab_top_newpage;
// Allows data in the first page if description is long enough to break in multiples pages
- if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
+ if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
$showpricebeforepagebreak = 1;
else
$showpricebeforepagebreak = 0;
@@ -548,7 +548,7 @@ class pdf_azur extends ModelePDFPropales
// We found a page break
// Allows data in the first page if description is long enough to break in multiples pages
- if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
+ if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
$showpricebeforepagebreak = 1;
else
$showpricebeforepagebreak = 0;
@@ -1101,28 +1101,28 @@ class pdf_azur extends ModelePDFPropales
//Local tax 1 before VAT
//if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
//{
- foreach($this->localtax1 as $localtax_type => $localtax_rate)
+ foreach ($this->localtax1 as $localtax_type => $localtax_rate)
{
- if (in_array((string) $localtax_type, array('1','3','5'))) continue;
+ if (in_array((string) $localtax_type, array('1', '3', '5'))) continue;
- foreach($localtax_rate as $tvakey => $tvaval)
+ foreach ($localtax_rate as $tvakey => $tvaval)
{
- if ($tvakey!=0) // On affiche pas taux 0
+ if ($tvakey != 0) // On affiche pas taux 0
{
//$this->atleastoneratenotnull++;
$index++;
$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
- $tvacompl='';
+ $tvacompl = '';
if (preg_match('/\*/', $tvakey))
{
- $tvakey=str_replace('*', '', $tvakey);
+ $tvakey = str_replace('*', '', $tvakey);
$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
}
$totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' ';
- $totalvat.=vatrate(abs($tvakey), 1).$tvacompl;
- $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+ $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
+ $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
@@ -1133,13 +1133,13 @@ class pdf_azur extends ModelePDFPropales
//Local tax 2 before VAT
//if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
//{
- foreach($this->localtax2 as $localtax_type => $localtax_rate)
+ foreach ($this->localtax2 as $localtax_type => $localtax_rate)
{
- if (in_array((string) $localtax_type, array('1','3','5'))) continue;
+ if (in_array((string) $localtax_type, array('1', '3', '5'))) continue;
- foreach($localtax_rate as $tvakey => $tvaval)
+ foreach ($localtax_rate as $tvakey => $tvaval)
{
- if ($tvakey!=0) // On affiche pas taux 0
+ if ($tvakey != 0) // On affiche pas taux 0
{
//$this->atleastoneratenotnull++;
@@ -1148,15 +1148,15 @@ class pdf_azur extends ModelePDFPropales
$index++;
$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
- $tvacompl='';
+ $tvacompl = '';
if (preg_match('/\*/', $tvakey))
{
- $tvakey=str_replace('*', '', $tvakey);
+ $tvakey = str_replace('*', '', $tvakey);
$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
}
$totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
- $totalvat.=vatrate(abs($tvakey), 1).$tvacompl;
- $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+ $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
+ $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
@@ -1192,11 +1192,11 @@ class pdf_azur extends ModelePDFPropales
//Local tax 1 after VAT
//if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
//{
- foreach($this->localtax1 as $localtax_type => $localtax_rate)
+ foreach ($this->localtax1 as $localtax_type => $localtax_rate)
{
- if (in_array((string) $localtax_type, array('2','4','6'))) continue;
+ if (in_array((string) $localtax_type, array('2', '4', '6'))) continue;
- foreach($localtax_rate as $tvakey => $tvaval)
+ foreach ($localtax_rate as $tvakey => $tvaval)
{
if ($tvakey != 0) // On affiche pas taux 0
{
@@ -1205,16 +1205,16 @@ class pdf_azur extends ModelePDFPropales
$index++;
$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
- $tvacompl='';
+ $tvacompl = '';
if (preg_match('/\*/', $tvakey))
{
- $tvakey=str_replace('*', '', $tvakey);
+ $tvakey = str_replace('*', '', $tvakey);
$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
}
$totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' ';
- $totalvat.=vatrate(abs($tvakey), 1).$tvacompl;
- $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+ $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
+ $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
}
@@ -1224,11 +1224,11 @@ class pdf_azur extends ModelePDFPropales
//Local tax 2 after VAT
//if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
//{
- foreach($this->localtax2 as $localtax_type => $localtax_rate)
+ foreach ($this->localtax2 as $localtax_type => $localtax_rate)
{
- if (in_array((string) $localtax_type, array('2','4','6'))) continue;
+ if (in_array((string) $localtax_type, array('2', '4', '6'))) continue;
- foreach($localtax_rate as $tvakey => $tvaval)
+ foreach ($localtax_rate as $tvakey => $tvaval)
{
// retrieve global local tax
if ($tvakey != 0) // On affiche pas taux 0
@@ -1238,16 +1238,16 @@ class pdf_azur extends ModelePDFPropales
$index++;
$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
- $tvacompl='';
+ $tvacompl = '';
if (preg_match('/\*/', $tvakey))
{
- $tvakey=str_replace('*', '', $tvakey);
+ $tvakey = str_replace('*', '', $tvakey);
$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
}
$totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
- $totalvat.=vatrate(abs($tvakey), 1).$tvacompl;
- $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+ $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
+ $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
@@ -1476,7 +1476,7 @@ class pdf_azur extends ModelePDFPropales
if ($this->emetteur->logo)
{
$logodir = $conf->mycompany->dir_output;
- if (! empty($conf->mycompany->multidir_output[$object->entity])) $logodir = $conf->mycompany->multidir_output[$object->entity];
+ if (!empty($conf->mycompany->multidir_output[$object->entity])) $logodir = $conf->mycompany->multidir_output[$object->entity];
if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO))
{
$logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
@@ -1528,6 +1528,30 @@ class pdf_azur extends ModelePDFPropales
$pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R');
}
+ if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE))
+ {
+ $object->fetch_projet();
+ if (!empty($object->project->ref))
+ {
+ $posy += 3;
+ $pdf->SetXY($posx, $posy);
+ $pdf->SetTextColor(0, 0, 60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R');
+ }
+ }
+
+ if (!empty($conf->global->PDF_SHOW_PROJECT))
+ {
+ $object->fetch_projet();
+ if (!empty($object->project->ref))
+ {
+ $posy += 3;
+ $pdf->SetXY($posx, $posy);
+ $pdf->SetTextColor(0, 0, 60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R');
+ }
+ }
+
$posy += 4;
$pdf->SetXY($posx, $posy);
$pdf->SetTextColor(0, 0, 60);
diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
index af04a52e21f..c45db2f8380 100644
--- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
+++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
@@ -418,6 +418,14 @@ class pdf_cyan extends ModelePDFPropales
if (!empty($salerepobj->signature)) $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature);
}
}
+
+ // Extrafields in note
+ $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
+ if (!empty($extranote))
+ {
+ $notetoshow = dol_concatdesc($notetoshow, $extranote);
+ }
+
if (!empty($conf->global->MAIN_ADD_CREATOR_IN_NOTE) && $object->user_author_id > 0)
{
$tmpuser = new User($this->db);
@@ -556,9 +564,7 @@ class pdf_cyan extends ModelePDFPropales
$this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
$pdf->rollbackTransaction(true);
- $iniY = $tab_top + $this->tabTitleHeight + 2;
- $curY = $tab_top + $this->tabTitleHeight + 2;
- $nexY = $tab_top + $this->tabTitleHeight + 2;
+ $nexY = $tab_top + $this->tabTitleHeight;
// Loop on each lines
$pageposbeforeprintlines = $pdf->getPage();
@@ -594,7 +600,7 @@ class pdf_cyan extends ModelePDFPropales
$curY = $tab_top_newpage;
// Allows data in the first page if description is long enough to break in multiples pages
- if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
+ if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
$showpricebeforepagebreak = 1;
else
$showpricebeforepagebreak = 0;
@@ -613,15 +619,17 @@ class pdf_cyan extends ModelePDFPropales
if ($this->getColumnStatus('desc'))
{
$pdf->startTransaction();
- pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc);
+
+ $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
$pageposafter = $pdf->getPage();
+
if ($pageposafter > $pageposbefore) // There is a pagebreak
{
$pdf->rollbackTransaction(true);
- $pageposafter = $pageposbefore;
- //print $pageposafter.'-'.$pageposbefore;exit;
+
$pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
- pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc);
+
+ $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
$pageposafter = $pdf->getPage();
$posyafter = $pdf->GetY();
@@ -640,7 +648,7 @@ class pdf_cyan extends ModelePDFPropales
{
// We found a page break
// Allows data in the first page if description is long enough to break in multiples pages
- if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
+ if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE))
$showpricebeforepagebreak = 1;
else
$showpricebeforepagebreak = 0;
@@ -717,6 +725,17 @@ class pdf_cyan extends ModelePDFPropales
$nexY = max($pdf->GetY(), $nexY);
}
+ // Extrafields
+ if(!empty($object->lines[$i]->array_options)){
+ foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue){
+ if ($this->getColumnStatus($extrafieldColKey))
+ {
+ $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey);
+ $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
+ $nexY = max($pdf->GetY(), $nexY);
+ }
+ }
+ }
$parameters = array(
'object' => $object,
@@ -775,11 +794,11 @@ class pdf_cyan extends ModelePDFPropales
$pdf->setPage($pageposafter);
$pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
//$pdf->SetDrawColor(190,190,200);
- $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1);
+ $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY);
$pdf->SetLineStyle(array('dash'=>0));
}
- $nexY += 2; // Add space between lines
+
// Detect if some page were added automatically and output _tableau for past pages
while ($pagenb < $pageposafter)
@@ -1588,6 +1607,30 @@ class pdf_cyan extends ModelePDFPropales
$pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R');
}
+ if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE))
+ {
+ $object->fetch_projet();
+ if (!empty($object->project->ref))
+ {
+ $posy += 3;
+ $pdf->SetXY($posx, $posy);
+ $pdf->SetTextColor(0, 0, 60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R');
+ }
+ }
+
+ if (!empty($conf->global->PDF_SHOW_PROJECT))
+ {
+ $object->fetch_projet();
+ if (!empty($object->project->ref))
+ {
+ $posy += 3;
+ $pdf->SetXY($posx, $posy);
+ $pdf->SetTextColor(0, 0, 60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R');
+ }
+ }
+
$posy += 4;
$pdf->SetXY($posx, $posy);
$pdf->SetTextColor(0, 0, 60);
@@ -1797,7 +1840,7 @@ class pdf_cyan extends ModelePDFPropales
// Default field style for content
$this->defaultContentsFieldsStyle = array(
'align' => 'R', // R,C,L
- 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
);
// Default field style for content
@@ -1834,10 +1877,11 @@ class pdf_cyan extends ModelePDFPropales
'align' => 'L',
// 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
// 'label' => ' ', // the final label
- 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ 'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
),
'content' => array(
'align' => 'L',
+ 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
),
);
@@ -1928,7 +1972,7 @@ class pdf_cyan extends ModelePDFPropales
$this->cols['discount']['status'] = true;
}
- $rank = $rank + 10;
+ $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100
$this->cols['totalexcltax'] = array(
'rank' => $rank,
'width' => 26, // in mm
@@ -1939,6 +1983,11 @@ class pdf_cyan extends ModelePDFPropales
'border-left' => true, // add left line separator
);
+ // Add extrafields cols
+ if(!empty($object->lines)) {
+ $line = reset($object->lines);
+ $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
+ }
$parameters = array(
'object' => $object,
diff --git a/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php b/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php
index 51438ed6bf8..89a532c2556 100644
--- a/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php
+++ b/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php
@@ -37,7 +37,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
class doc_generic_reception_odt extends ModelePdfReception
{
/**
- * @var Company Issuer object that emits
+ * @var Societe Issuer object that emits
*/
public $emetteur; // Objet societe qui emet
diff --git a/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php b/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php
index 23609ad4384..d5ccf5dbd89 100644
--- a/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php
+++ b/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php
@@ -209,7 +209,7 @@ class doc_generic_stock_odt extends ModelePDFStock
/**
* Function to build a document on disk using the generic odt module.
*
- * @param Stock $object Object source to build document
+ * @param Entrepot $object Object source to build document
* @param Translate $outputlangs Lang output object
* @param string $srctemplatepath Full path of source filename for generator using a template file
* @param int $hidedetails Do not show line details
@@ -250,7 +250,7 @@ class doc_generic_stock_odt extends ModelePDFStock
if (!is_object($object))
{
$id = $object;
- $object = new Stock($this->db);
+ $object = new Entrepot($this->db);
$result = $object->fetch($id);
if ($result < 0)
{
@@ -258,7 +258,8 @@ class doc_generic_stock_odt extends ModelePDFStock
return -1;
}
}
- $stockFournisseur = new StockFournisseur($this->db);
+
+ $stockFournisseur = new ProductFournisseur($this->db);
$supplierprices = $stockFournisseur->list_stock_fournisseur_price($object->id);
$object->supplierprices = $supplierprices;
diff --git a/htdocs/core/modules/stock/doc/pdf_standard.modules.php b/htdocs/core/modules/stock/doc/pdf_standard.modules.php
index b2898c2fbac..17071641817 100644
--- a/htdocs/core/modules/stock/doc/pdf_standard.modules.php
+++ b/htdocs/core/modules/stock/doc/pdf_standard.modules.php
@@ -181,7 +181,7 @@ class pdf_standard extends ModelePDFStock
/**
* Function to build a document on disk using the generic odt module.
*
- * @param Stock $object Object source to build document
+ * @param Entrepot $object Object source to build document
* @param Translate $outputlangs Lang output object
* @param string $srctemplatepath Full path of source filename for generator using a template file
* @param int $hidedetails Do not show line details
diff --git a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php
index 362f17c7e9c..c3a00bf667b 100644
--- a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php
+++ b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php
@@ -230,7 +230,7 @@ class pdf_stdmovement extends ModelePDFMovement
$search_type_mouvement = GETPOST('search_type_mouvement', 'int');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
- $page = GETPOST("page", 'int');
+ $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php
index 8708a2c01a2..7d2aafb4882 100644
--- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php
+++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php
@@ -47,7 +47,7 @@ class mod_facture_fournisseur_cactus extends ModeleNumRefSuppliersInvoices
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Cactus';
diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
index 85eb6673124..39360550d8c 100644
--- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
+++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
@@ -50,7 +50,7 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Tulip';
diff --git a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php
index c71fe8f59ec..d7f48915308 100644
--- a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php
+++ b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php
@@ -421,9 +421,11 @@ class doc_generic_supplier_order_odt extends ModelePDFSuppliersOrders
}
if ($foundtagforlines)
{
+ $linenumber = 0;
foreach ($object->lines as $line)
{
- $tmparray = $this->get_substitutionarray_lines($line, $outputlangs);
+ $linenumber++;
+ $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber);
complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines");
// Call the ODTSubstitutionLine hook
$parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line);
diff --git a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php
index 1c266ae89b6..2d3c766a7c2 100644
--- a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php
+++ b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php
@@ -369,6 +369,13 @@ class pdf_cornas extends ModelePDFSuppliersOrders
// Affiche notes
$notetoshow = empty($object->note_public) ? '' : $object->note_public;
+ // Extrafields in note
+ $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
+ if (!empty($extranote))
+ {
+ $notetoshow = dol_concatdesc($notetoshow, $extranote);
+ }
+
$pagenb = $pdf->getPage();
if ($notetoshow)
{
@@ -489,9 +496,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders
$height_note = 0;
}
- $iniY = $tab_top + 7;
- $curY = $tab_top + 7;
- $nexY = $tab_top + 7;
+ $nexY = $tab_top + 5;
// Use new auto collum system
$this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
@@ -548,15 +553,15 @@ class pdf_cornas extends ModelePDFSuppliersOrders
if ($this->getColumnStatus('desc'))
{
$pdf->startTransaction();
- pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc);
+ $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc, 1);
+
$pageposafter = $pdf->getPage();
if ($pageposafter > $pageposbefore) // There is a pagebreak
{
$pdf->rollbackTransaction(true);
- $pageposafter = $pageposbefore;
- //print $pageposafter.'-'.$pageposbefore;exit;
- $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
- pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc);
+
+ $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc, 1);
+
$pageposafter = $pdf->getPage();
$posyafter = $pdf->GetY();
if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // There is no space left for total+free text
@@ -649,6 +654,17 @@ class pdf_cornas extends ModelePDFSuppliersOrders
$nexY = max($pdf->GetY(), $nexY);
}
+ // Extrafields
+ if(!empty($object->lines[$i]->array_options)){
+ foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue){
+ if ($this->getColumnStatus($extrafieldColKey))
+ {
+ $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey);
+ $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
+ $nexY = max($pdf->GetY(), $nexY);
+ }
+ }
+ }
$parameters = array(
'object' => $object,
@@ -706,12 +722,10 @@ class pdf_cornas extends ModelePDFSuppliersOrders
$pdf->setPage($pageposafter);
$pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
//$pdf->SetDrawColor(190,190,200);
- $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1);
+ $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY);
$pdf->SetLineStyle(array('dash'=>0));
}
- $nexY += 2; // Add space between lines
-
// Detect if some page were added automatically and output _tableau for past pages
while ($pagenb < $pageposafter)
{
@@ -1465,7 +1479,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders
// Default field style for content
$this->defaultContentsFieldsStyle = array(
'align' => 'R', // R,C,L
- 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
);
// Default field style for content
@@ -1502,10 +1516,11 @@ class pdf_cornas extends ModelePDFSuppliersOrders
'align' => 'L',
// 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
// 'label' => ' ', // the final label
- 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ 'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
),
'content' => array(
'align' => 'L',
+ 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
),
);
@@ -1596,7 +1611,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders
$this->cols['discount']['status'] = true;
}
- $rank = $rank + 10;
+ $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100
$this->cols['totalexcltax'] = array(
'rank' => $rank,
'width' => 26, // in mm
@@ -1607,6 +1622,11 @@ class pdf_cornas extends ModelePDFSuppliersOrders
'border-left' => true, // add left line separator
);
+ // Add extrafields cols
+ if(!empty($object->lines)) {
+ $line = reset($object->lines);
+ $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
+ }
$parameters = array(
'object' => $object,
@@ -1630,230 +1650,4 @@ class pdf_cornas extends ModelePDFSuppliersOrders
$this->cols = $hookmanager->resArray;
}
}
-
- /*
- *
- * DEBUT PARTIE NORMALEMENT DANS LA CLASSE CommonDocGenerator
- *
- *
- */
-
- /**
- * uasort callback function to Sort columns fields
- *
- * @param array $a PDF lines array fields configs
- * @param array $b PDF lines array fields configs
- * @return int Return compare result
- */
- public function columnSort($a, $b)
- {
- if (empty($a['rank'])) { $a['rank'] = 0; }
- if (empty($b['rank'])) { $b['rank'] = 0; }
- if ($a['rank'] == $b['rank']) {
- return 0;
- }
- return ($a['rank'] > $b['rank']) ? -1 : 1;
- }
-
- /**
- * Prepare Array Column Field
- *
- * @param object $object common object
- * @param Translate $outputlangs langs
- * @param int $hidedetails Do not show line details
- * @param int $hidedesc Do not show desc
- * @param int $hideref Do not show ref
- * @return null
- */
- public function prepareArrayColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
- {
- global $conf;
-
- $this->defineColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
-
- // Sorting
- uasort($this->cols, array($this, 'columnSort'));
-
- // Positionning
- $curX = $this->page_largeur - $this->marge_droite; // start from right
-
- // Array width
- $arrayWidth = $this->page_largeur - $this->marge_droite - $this->marge_gauche;
-
- // Count flexible column
- $totalDefinedColWidth = 0;
- $countFlexCol = 0;
- foreach ($this->cols as $colKey => &$colDef)
- {
- if (!$this->getColumnStatus($colKey)) continue; // continue if disabled
-
- if (!empty($colDef['scale'])) {
- // In case of column widht is defined by percentage
- $colDef['width'] = abs($arrayWidth * $colDef['scale'] / 100);
- }
-
- if (empty($colDef['width'])) {
- $countFlexCol++;
- }
- else {
- $totalDefinedColWidth += $colDef['width'];
- }
- }
-
- foreach ($this->cols as $colKey => &$colDef)
- {
- // setting empty conf with default
- if (!empty($colDef['title'])) {
- $colDef['title'] = array_replace($this->defaultTitlesFieldsStyle, $colDef['title']);
- }
- else {
- $colDef['title'] = $this->defaultTitlesFieldsStyle;
- }
-
- // setting empty conf with default
- if (!empty($colDef['content'])) {
- $colDef['content'] = array_replace($this->defaultContentsFieldsStyle, $colDef['content']);
- }
- else {
- $colDef['content'] = $this->defaultContentsFieldsStyle;
- }
-
- if ($this->getColumnStatus($colKey))
- {
- // In case of flexible column
- if (empty($colDef['width'])) {
- $colDef['width'] = abs(($arrayWidth - $totalDefinedColWidth)) / $countFlexCol;
- }
-
- // Set positions
- $lastX = $curX;
- $curX = $lastX - $colDef['width'];
- $colDef['xStartPos'] = $curX;
- $colDef['xEndPos'] = $lastX;
- }
- }
- }
-
- /**
- * get column content width from column key
- *
- * @param string $colKey the column key
- * @return float width in mm
- */
- public function getColumnContentWidth($colKey)
- {
- $colDef = $this->cols[$colKey];
- return $colDef['width'] - $colDef['content']['padding'][3] - $colDef['content']['padding'][1];
- }
-
-
- /**
- * get column content X (abscissa) left position from column key
- *
- * @param string $colKey the column key
- * @return float X position in mm
- */
- public function getColumnContentXStart($colKey)
- {
- $colDef = $this->cols[$colKey];
- return $colDef['xStartPos'] + $colDef['content']['padding'][3];
- }
-
- /**
- * get column position rank from column key
- *
- * @param string $colKey the column key
- * @return int rank on success and -1 on error
- */
- public function getColumnRank($colKey)
- {
- if (!isset($this->cols[$colKey]['rank'])) return -1;
- return $this->cols[$colKey]['rank'];
- }
-
- /**
- * get column position rank from column key
- *
- * @param string $newColKey the new column key
- * @param array $defArray a single column definition array
- * @param string $targetCol target column used to place the new column beside
- * @param bool $insertAfterTarget insert before or after target column ?
- * @return int new rank on success and -1 on error
- */
- public function insertNewColumnDef($newColKey, $defArray, $targetCol = false, $insertAfterTarget = false)
- {
- // prepare wanted rank
- $rank = -1;
-
- // try to get rank from target column
- if (!empty($targetCol)) {
- $rank = $this->getColumnRank($targetCol);
- if ($rank >= 0 && $insertAfterTarget) { $rank++; }
- }
-
- // get rank from new column definition
- if ($rank < 0 && !empty($defArray['rank'])) {
- $rank = $defArray['rank'];
- }
-
- // error: no rank
- if ($rank < 0) { return -1; }
-
- foreach ($this->cols as $colKey =>& $colDef)
- {
- if ($rank <= $colDef['rank'])
- {
- $colDef['rank'] = $colDef['rank'] + 1;
- }
- }
-
- $defArray['rank'] = $rank;
- $this->cols[$newColKey] = $defArray; // array_replace is used to preserve keys
-
- return $rank;
- }
-
-
- /**
- * print standard column content
- *
- * @param PDF $pdf pdf object
- * @param float $curY curent Y position
- * @param string $colKey the column key
- * @param string $columnText column text
- * @return int new rank on success and -1 on error
- */
- public function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '')
- {
- global $hookmanager;
-
- $parameters = array(
- 'curY' =>& $curY,
- 'columnText' => $columnText,
- 'colKey' => $colKey
- );
- $reshook = $hookmanager->executeHooks('printStdColumnContent', $parameters, $this); // Note that $action and $object may have been modified by hook
- if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
- if (!$reshook)
- {
- if (empty($columnText)) return;
- $pdf->SetXY($this->getColumnContentXStart($colKey), $curY); // Set curent position
- $colDef = $this->cols[$colKey];
- $pdf->MultiCell($this->getColumnContentWidth($colKey), 2, $columnText, '', $colDef['content']['align']);
- }
- }
-
- /**
- * get column status from column key
- *
- * @param string $colKey the column key
- * @return float width in mm
- */
- public function getColumnStatus($colKey)
- {
- if (!empty($this->cols[$colKey]['status'])) {
- return true;
- }
- else return false;
- }
}
diff --git a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php
index ece2d8e5a7e..25fdd77991b 100644
--- a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php
+++ b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php
@@ -45,7 +45,7 @@ class mod_commande_fournisseur_muguet extends ModeleNumRefSuppliersOrders
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Muguet';
diff --git a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php
index 565e8cbd41d..72ba5f28186 100644
--- a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php
+++ b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php
@@ -46,7 +46,7 @@ class mod_commande_fournisseur_orchidee extends ModeleNumRefSuppliersOrders
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Orchidee';
diff --git a/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php b/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php
index 92a2862143f..60d25792988 100644
--- a/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php
+++ b/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php
@@ -44,7 +44,7 @@ class mod_supplier_payment_brodator extends ModeleNumRefSupplierPayments
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Brodator';
diff --git a/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php b/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php
index 1bc34d41bce..8a16475b383 100644
--- a/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php
+++ b/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php
@@ -45,7 +45,7 @@ class mod_supplier_payment_bronan extends ModeleNumRefSupplierPayments
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Bronan';
diff --git a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php
index 9c7305d1c07..3b4a39288ea 100644
--- a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php
+++ b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php
@@ -225,7 +225,7 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
/**
* Function to build a document on disk using the generic odt module.
*
- * @param Propale $object Object source to build document
+ * @param Propal $object Object source to build document
* @param Translate $outputlangs Lang output object
* @param string $srctemplatepath Full path of source filename for generator using a template file
* @param int $hidedetails Do not show line details
@@ -445,9 +445,11 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
}
if ($foundtagforlines)
{
+ $linenumber = 0;
foreach ($object->lines as $line)
{
- $tmparray = $this->get_substitutionarray_lines($line, $outputlangs);
+ $linenumber++;
+ $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber);
complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines");
// Call the ODTSubstitutionLine hook
$parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line);
diff --git a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php
index 8fa71cc1a3b..7bd15599e24 100644
--- a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php
+++ b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php
@@ -47,7 +47,7 @@ class mod_supplier_proposal_marbre extends ModeleNumRefSupplierProposal
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Marbre';
diff --git a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php
index bfaaa6b15fb..7cf4d295239 100644
--- a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php
+++ b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php
@@ -47,7 +47,7 @@ class mod_supplier_proposal_saphir extends ModeleNumRefSupplierProposal
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Saphir';
diff --git a/htdocs/core/modules/takepos/mod_takepos_ref_simple.php b/htdocs/core/modules/takepos/mod_takepos_ref_simple.php
new file mode 100644
index 00000000000..4275e202f6e
--- /dev/null
+++ b/htdocs/core/modules/takepos/mod_takepos_ref_simple.php
@@ -0,0 +1,193 @@
+
+ * Copyright (C) 2005-2009 Regis Houssin
+ * Copyright (C) 2013 Juanjo Menent
+ * Copyright (C) 2020 Open-DSI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/takepos/mod_takepos_ref_simple.php
+ * \ingroup takepos
+ * \brief File with Simple ref numbering module for takepos
+ */
+dol_include_once('/core/modules/takepos/modules_takepos.php');
+
+/**
+ * Class to manage ref numbering of takepos cards with rule Simple.
+ */
+class mod_takepos_ref_simple extends ModeleNumRefTakepos
+{
+ /**
+ * Dolibarr version of the loaded document 'development', 'experimental', 'dolibarr'
+ * @var string
+ */
+ public $version = 'dolibarr';
+
+ /**
+ * Prefix
+ * @var string
+ */
+ public $prefix = 'TK';
+
+ /**
+ * @var string Error code (or message)
+ */
+ public $error = '';
+
+ /**
+ * Name
+ * @var string
+ */
+ public $nom = 'Simple';
+
+ /**
+ * Return description of numbering module
+ *
+ * @return string Text with description
+ */
+ public function info()
+ {
+ global $langs;
+
+ return $langs->trans('SimpleNumRefModelDesc', $this->prefix . '0-');
+ }
+
+ /**
+ * Return an example of numbering module values
+ *
+ * @return string Example
+ */
+ public function getExample()
+ {
+ return $this->prefix . '0-0501-0001';
+ }
+
+ /**
+ * Test si les numeros deja en vigueur dans la base ne provoquent pas de
+ * de conflits qui empechera cette numerotation de fonctionner.
+ *
+ * @return boolean false si conflit, true si ok
+ */
+ public function canBeActivated()
+ {
+ global $conf, $langs, $db;
+
+ $pryymm = '';
+ $max = '';
+
+ $posindice = 8;
+ $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM " . $posindice . ") AS SIGNED)) as max";
+ $sql .= " FROM " . MAIN_DB_PREFIX . "facture";
+ $sql .= " WHERE ref LIKE '" . $db->escape($this->prefix) . "____-%'";
+ $sql .= " AND entity = " . $conf->entity;
+
+ $resql = $db->query($sql);
+ if ($resql) {
+ $row = $db->fetch_row($resql);
+ if ($row) {
+ $pryymm = substr($row[0], 0, 6);
+ $max = $row[0];
+ }
+ }
+
+ if (!$pryymm || preg_match('/' . $this->prefix . '[0-9][0-9][0-9][0-9]/i', $pryymm)) {
+ return true;
+ } else {
+ $langs->load("errors");
+ $this->error = $langs->trans('ErrorNumRefModel', $max);
+ return false;
+ }
+ }
+
+ /**
+ * Return next value
+ *
+ * @param Societe $objsoc Object third party
+ * @param Facture $invoice Object invoice
+ * @param string $mode 'next' for next value or 'last' for last value
+ * @return string Next value
+ */
+ public function getNextValue($objsoc = null, $invoice = null, $mode = 'next')
+ {
+ global $db;
+
+ $pos_source = is_object($invoice) && $invoice->pos_source > 0 ? $invoice->pos_source : 0;
+
+ // D'abord on recupere la valeur max
+ $posindice = strlen($this->prefix . $pos_source . '-____-') + 1;
+ $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM " . $posindice . ") AS SIGNED)) as max"; // This is standard SQL
+ $sql .= " FROM " . MAIN_DB_PREFIX . "facture";
+ $sql .= " WHERE ref LIKE '" . $db->escape($this->prefix . $pos_source) . "-____-%'";
+ $sql .= " AND entity IN (".getEntity('invoicenumber', 1, $invoice).")";
+
+ $resql = $db->query($sql);
+ if ($resql) {
+ $obj = $db->fetch_object($resql);
+ if ($obj) $max = intval($obj->max);
+ else $max = 0;
+ } else {
+ dol_syslog(get_class($this) . "::getNextValue", LOG_DEBUG);
+ return -1;
+ }
+
+ if ($mode == 'last')
+ {
+ if ($max >= (pow(10, 4) - 1)) $num=$max; // If counter > 9999, we do not format on 4 chars, we take number as it is
+ else $num = sprintf("%04s", $max);
+
+ $ref = '';
+ $sql = "SELECT ref as ref";
+ $sql .= " FROM ". MAIN_DB_PREFIX . "facture";
+ $sql .= " WHERE ref LIKE '" . $db->escape($this->prefix . $pos_source) . "-____-" . $num . "'";
+ $sql .= " AND entity IN (".getEntity('invoicenumber', 1, $invoice).")";
+ $sql .= " ORDER BY ref DESC";
+
+ $resql = $db->query($sql);
+ if ($resql) {
+ $obj = $db->fetch_object($resql);
+ if ($obj) $ref = $obj->ref;
+ }
+ else dol_print_error($db);
+
+ return $ref;
+ }
+ elseif ($mode == 'next')
+ {
+ $date = $invoice->date; // This is invoice date (not creation date)
+ $yymm = strftime("%y%m", $date);
+
+ if ($max >= (pow(10, 4) - 1)) $num=$max+1; // If counter > 9999, we do not format on 4 chars, we take number as it is
+ else $num = sprintf("%04s", $max+1);
+
+ dol_syslog(get_class($this)."::getNextValue return " . $this->prefix . $pos_source . '-' . $yymm . '-' . $num);
+ return $this->prefix . $pos_source . '-' . $yymm . '-' . $num;
+ }
+ else dol_print_error('', 'Bad parameter for getNextValue');
+ }
+
+ /**
+ * Return next free value
+ *
+ * @param Societe $objsoc Object third party
+ * @param Object $objforref Object for number to search
+ * @return string Next free value
+ */
+ public function getNumRef($objsoc, $objforref)
+ {
+ return $this->getNextValue($objsoc, $objforref);
+ }
+}
diff --git a/htdocs/core/modules/takepos/mod_takepos_ref_universal.php b/htdocs/core/modules/takepos/mod_takepos_ref_universal.php
new file mode 100644
index 00000000000..7fdff4c1c6b
--- /dev/null
+++ b/htdocs/core/modules/takepos/mod_takepos_ref_universal.php
@@ -0,0 +1,158 @@
+
+ * Copyright (C) 2004-2008 Laurent Destailleur
+ * Copyright (C) 2005-2009 Regis Houssin
+ * Copyright (C) 2008 Raphael Bertrand (Resultic)
+ * Copyright (C) 2013 Juanjo Menent
+ * Copyright (C) 2020 Open-DSI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/takepos/mod_takepos_ref_universal.php
+ * \ingroup takepos
+ * \brief File with Universal ref numbering module for takepos
+ */
+dol_include_once('/core/modules/takepos/modules_takepos.php');
+
+/**
+ * Class to manage ref numbering of takepos cards with rule universal.
+ */
+class mod_takepos_ref_universal extends ModeleNumRefTakepos
+{
+ /**
+ * Dolibarr version of the loaded document 'development', 'experimental', 'dolibarr'
+ * @var string
+ */
+ public $version = 'dolibarr';
+
+ /**
+ * @var string Error code (or message)
+ */
+ public $error = '';
+
+ /**
+ * Name
+ * @var string
+ */
+ public $nom = 'Universal';
+
+ /**
+ * Renvoi la description du modele de numerotation
+ *
+ * @return string Texte descripif
+ */
+ public function info()
+ {
+ global $conf, $langs;
+
+ $langs->load('cashdesk@cashdesk');
+
+ $form = new Form($this->db);
+
+ $texte = $langs->trans('GenericNumRefModelDesc') . " \n";
+ $texte .= '';
+ $texte .= ' ';
+ $texte .= ' ';
+ $texte .= ' ';
+ $texte .= '';
+ $texte .= ' ';
+
+ return $texte;
+ }
+
+ /**
+ * Renvoi un exemple de numerotation
+ *
+ * @return string Example
+ */
+ public function getExample()
+ {
+ global $conf, $langs, $mysoc;
+
+ $old_code_client = $mysoc->code_client;
+ $mysoc->code_client = 'CCCCCCCCCC';
+ $numExample = $this->getNextValue($mysoc, '');
+ $mysoc->code_client = $old_code_client;
+
+ if (!$numExample) {
+ $numExample = $langs->trans('NotConfigured');
+ }
+ return $numExample;
+ }
+
+ /**
+ * Return next free value
+ *
+ * @param Societe $objsoc Object thirdparty
+ * @param Facture $invoice Object invoice
+ * @param string $mode 'next' for next value or 'last' for last value
+ * @return string Value if KO, <0 if KO
+ */
+ public function getNextValue($objsoc = 0, $invoice = null, $mode = 'next')
+ {
+ global $db, $conf;
+
+ require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
+
+ // On defini critere recherche compteur
+ $mask = $conf->global->TAKEPOS_REF_UNIVERSAL_MASK;
+
+ if (!$mask) {
+ $this->error = 'NotConfigured';
+ return 0;
+ }
+
+ // Get entities
+ $entity = getEntity('invoicenumber', 1, $invoice);
+
+ $pos_source = is_object($invoice) && $invoice->pos_source > 0 ? $invoice->pos_source : 0;
+ $mask = str_replace('{TN}', $pos_source, $mask);
+ $numFinal = get_next_value($db, $mask, 'facture', 'ref', '', $objsoc, $invoice->date, $mode, false, null, $entity);
+
+ return $numFinal;
+ }
+
+
+ /**
+ * Return next free value
+ *
+ * @param Societe $objsoc Object third party
+ * @param Object $objforref Object for number to search
+ * @return string Next free value
+ */
+ public function getNumRef($objsoc, $objforref)
+ {
+ return $this->getNextValue($objsoc, $objforref);
+ }
+}
diff --git a/htdocs/core/modules/takepos/modules_takepos.php b/htdocs/core/modules/takepos/modules_takepos.php
new file mode 100644
index 00000000000..cb33fd2d9b3
--- /dev/null
+++ b/htdocs/core/modules/takepos/modules_takepos.php
@@ -0,0 +1,116 @@
+
+ * Copyright (C) 2004-2011 Laurent Destailleur
+ * Copyright (C) 2005-2012 Regis Houssin
+ * Copyright (C) 2011-2012 Philippe Grand
+ * Copyright (C) 2020 Open-DSI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/takepos/modules_takepos.php
+ * \ingroup takepos
+ * \brief Fichier contenant la classe mere de numerotation des tickets de caisse
+ */
+
+
+/**
+ * \class ModeleNumRefTakepos
+ * \brief Classe mere des modeles de numerotation des tickets de caisse
+ */
+abstract class ModeleNumRefTakepos
+{
+ /**
+ * @var string Error code (or message)
+ */
+ public $error='';
+
+
+ public $version = '';
+
+ /**
+ * Return if a module can be used or not
+ *
+ * @return boolean true if module can be used
+ */
+ public function isEnabled()
+ {
+ return true;
+ }
+
+ /**
+ * Renvoi la description par defaut du modele de numerotation
+ *
+ * @return string Texte descripif
+ */
+ public function info()
+ {
+ global $langs;
+ $langs->load("cashdesk@cashdesk");
+ return $langs->trans("NoDescription");
+ }
+
+ /**
+ * Return an example of numbering
+ *
+ * @return string Example
+ */
+ public function getExample()
+ {
+ global $langs;
+ $langs->load('cashdesk@cashdesk');
+ return $langs->trans('NoExample');
+ }
+
+ /**
+ * Checks if the numbers already in force in the data base do not
+ * cause conflicts that would prevent this numbering from working.
+ *
+ * @return boolean false if conflict, true if ok
+ */
+ public function canBeActivated()
+ {
+ return true;
+ }
+
+ /**
+ * Renvoi prochaine valeur attribuee
+ *
+ * @return string Valeur
+ */
+ public function getNextValue()
+ {
+ global $langs;
+ return $langs->trans('NotAvailable');
+ }
+
+ /**
+ * Renvoi version du modele de numerotation
+ *
+ * @return string Valeur
+ */
+ public function getVersion()
+ {
+ global $langs;
+ $langs->load("admin");
+
+ if ($this->version == 'development') return $langs->trans('VersionDevelopment');
+ if ($this->version == 'experimental') return $langs->trans('VersionExperimental');
+ if ($this->version == 'dolibarr') return DOL_VERSION;
+ if ($this->version) return $this->version;
+ return $langs->trans('NotAvailable');
+ }
+}
diff --git a/htdocs/core/modules/ticket/mod_ticket_simple.php b/htdocs/core/modules/ticket/mod_ticket_simple.php
index dbec61b67bf..3245f7b8e84 100644
--- a/htdocs/core/modules/ticket/mod_ticket_simple.php
+++ b/htdocs/core/modules/ticket/mod_ticket_simple.php
@@ -46,7 +46,7 @@ class mod_ticket_simple extends ModeleNumRefTicket
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Simple';
diff --git a/htdocs/core/modules/ticket/mod_ticket_universal.php b/htdocs/core/modules/ticket/mod_ticket_universal.php
index 5b5f5a55953..e6749bbb1f6 100644
--- a/htdocs/core/modules/ticket/mod_ticket_universal.php
+++ b/htdocs/core/modules/ticket/mod_ticket_universal.php
@@ -43,7 +43,7 @@ class mod_ticket_universal extends ModeleNumRefTicket
/**
* @var string Nom du modele
* @deprecated
- * @see name
+ * @see $name
*/
public $nom='Universal';
diff --git a/htdocs/core/photos_resize.php b/htdocs/core/photos_resize.php
index 17c7cb9e974..dd59b20c964 100644
--- a/htdocs/core/photos_resize.php
+++ b/htdocs/core/photos_resize.php
@@ -38,6 +38,10 @@ $original_file = GETPOST("file");
$backtourl = GETPOST('backtourl');
$cancel = GETPOST('cancel', 'alpha');
+$file = GETPOST('file', 'alpha');
+$num = GETPOST('num', 'alpha'); // Used for document on bank statement
+
+
// Security check
if (empty($modulepart)) accessforbidden('Bad value for modulepart');
$accessallowed = 0;
@@ -249,19 +253,25 @@ else {
if (empty($backtourl))
{
- if (in_array($modulepart, array('product', 'produit', 'service', 'produit|service'))) $backtourl = DOL_URL_ROOT."/product/document.php?id=".$id.'&file='.urldecode($_POST["file"]);
- elseif (in_array($modulepart, array('expensereport'))) $backtourl = DOL_URL_ROOT."/expensereport/document.php?id=".$id.'&file='.urldecode($_POST["file"]);
- elseif (in_array($modulepart, array('holiday'))) $backtourl = DOL_URL_ROOT."/holiday/document.php?id=".$id.'&file='.urldecode($_POST["file"]);
- elseif (in_array($modulepart, array('member'))) $backtourl = DOL_URL_ROOT."/adherents/document.php?id=".$id.'&file='.urldecode($_POST["file"]);
- elseif (in_array($modulepart, array('project'))) $backtourl = DOL_URL_ROOT."/projet/document.php?id=".$id.'&file='.urldecode($_POST["file"]);
- elseif (in_array($modulepart, array('propal'))) $backtourl = DOL_URL_ROOT."/comm/propal/document.php?id=".$id.'&file='.urldecode($_POST["file"]);
- elseif (in_array($modulepart, array('societe'))) $backtourl = DOL_URL_ROOT."/societe/document.php?id=".$id.'&file='.urldecode($_POST["file"]);
- elseif (in_array($modulepart, array('tax'))) $backtourl = DOL_URL_ROOT."/compta/sociales/document.php?id=".$id.'&file='.urldecode($_POST["file"]);
- elseif (in_array($modulepart, array('ticket'))) $backtourl = DOL_URL_ROOT."/ticket/document.php?id=".$id.'&file='.urldecode($_POST["file"]);
- elseif (in_array($modulepart, array('user'))) $backtourl = DOL_URL_ROOT."/user/document.php?id=".$id.'&file='.urldecode($_POST["file"]);
- elseif (in_array($modulepart, array('bank'))) $backtourl = DOL_URL_ROOT."/compta/bank/document.php?id=".$id.'&file='.urldecode($_POST["file"]);
- elseif (in_array($modulepart, array('mrp'))) $backtourl = DOL_URL_ROOT."/mrp/mo_document.php?id=".$id.'&file='.urldecode($_POST["file"]);
- else $backtourl = DOL_URL_ROOT."/".$modulepart."/".$modulepart."_document.php?id=".$id.'&file='.urldecode($_POST["file"]);
+ $regs = array();
+
+ if (in_array($modulepart, array('product', 'produit', 'service', 'produit|service'))) $backtourl = DOL_URL_ROOT."/product/document.php?id=".$id.'&file='.urldecode($file);
+ elseif (in_array($modulepart, array('expensereport'))) $backtourl = DOL_URL_ROOT."/expensereport/document.php?id=".$id.'&file='.urldecode($file);
+ elseif (in_array($modulepart, array('holiday'))) $backtourl = DOL_URL_ROOT."/holiday/document.php?id=".$id.'&file='.urldecode($file);
+ elseif (in_array($modulepart, array('member'))) $backtourl = DOL_URL_ROOT."/adherents/document.php?id=".$id.'&file='.urldecode($file);
+ elseif (in_array($modulepart, array('project'))) $backtourl = DOL_URL_ROOT."/projet/document.php?id=".$id.'&file='.urldecode($file);
+ elseif (in_array($modulepart, array('propal'))) $backtourl = DOL_URL_ROOT."/comm/propal/document.php?id=".$id.'&file='.urldecode($file);
+ elseif (in_array($modulepart, array('societe'))) $backtourl = DOL_URL_ROOT."/societe/document.php?id=".$id.'&file='.urldecode($file);
+ elseif (in_array($modulepart, array('tax'))) $backtourl = DOL_URL_ROOT."/compta/sociales/document.php?id=".$id.'&file='.urldecode($file);
+ elseif (in_array($modulepart, array('ticket'))) $backtourl = DOL_URL_ROOT."/ticket/document.php?id=".$id.'&file='.urldecode($file);
+ elseif (in_array($modulepart, array('user'))) $backtourl = DOL_URL_ROOT."/user/document.php?id=".$id.'&file='.urldecode($file);
+ elseif (in_array($modulepart, array('bank')) && preg_match('/\/statement\/([^\/]+)\//', $file, $regs)) {
+ $num = $regs[1];
+ $backtourl = DOL_URL_ROOT."/compta/bank/account_statement_document.php?id=".$id.'&num='.urlencode($num).'&file='.urldecode($file);
+ }
+ elseif (in_array($modulepart, array('bank'))) $backtourl = DOL_URL_ROOT."/compta/bank/document.php?id=".$id.'&file='.urldecode($file);
+ elseif (in_array($modulepart, array('mrp'))) $backtourl = DOL_URL_ROOT."/mrp/mo_document.php?id=".$id.'&file='.urldecode($file);
+ else $backtourl = DOL_URL_ROOT."/".$modulepart."/".$modulepart."_document.php?id=".$id.'&file='.urldecode($file);
}
@@ -283,11 +293,11 @@ if ($cancel)
}
}
-if ($action == 'confirm_resize' && (isset($_POST["file"]) != "") && (isset($_POST["sizex"]) != "") && (isset($_POST["sizey"]) != ""))
+if ($action == 'confirm_resize' && GETPOSTISSET("file") && GETPOSTISSET("sizex") && GETPOSTISSET("sizey"))
{
$fullpath = $dir."/".$original_file;
- $result = dol_imageResizeOrCrop($fullpath, 0, $_POST['sizex'], $_POST['sizey']);
+ $result = dol_imageResizeOrCrop($fullpath, 0, GETPOST('sizex', 'int'), GETPOST('sizey', 'int'));
if ($result == $fullpath)
{
@@ -357,7 +367,7 @@ if ($action == 'confirm_crop')
$fullpath = $dir."/".$original_file;
//var_dump($_POST['w'].'x'.$_POST['h'].'-'.$_POST['x'].'x'.$_POST['y']);exit;
- $result = dol_imageResizeOrCrop($fullpath, 1, $_POST['w'], $_POST['h'], $_POST['x'], $_POST['y']);
+ $result = dol_imageResizeOrCrop($fullpath, 1, GETPOST('w', 'int'), GETPOST('h', 'int'), GETPOST('x', 'int'), GETPOST('y', 'int'));
if ($result == $fullpath)
{
@@ -445,7 +455,7 @@ print ' '."\n";
*/
print ''."\n";
-print '';
+print ' ';
print ' ';
print '';
@@ -454,7 +464,7 @@ print $langs->trans("ResizeDesc").' ';
print $langs->trans("NewLength").': px '.$langs->trans("or").' ';
print $langs->trans("NewHeight").': px ';
-print ' ';
+print ' ';
print ' ';
print ' ';
print ' ';
@@ -497,7 +507,8 @@ if (!empty($conf->use_javascript_ajax))
print ' ';
print '';
print ' ';
- print '';
+
+ print ' ';
print ' ';
print '
diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php
index 37ca5e1ec10..6c25b5c07b5 100644
--- a/htdocs/core/tpl/admin_extrafields_add.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php
@@ -28,7 +28,7 @@
*/
// Protection to avoid direct call of template
-if (empty($conf) || ! is_object($conf))
+if (empty($conf) || !is_object($conf))
{
print "Error, template page can't be called as URL";
exit;
@@ -148,13 +148,13 @@ $langs->load("modulebuilder");
trans("LabelOrTranslationKey"); ?>
-trans("AttributeCode"); ?> (trans("AlphaNumOnlyLowerCharsAndNoSpace"); ?>)
+trans("AttributeCode"); ?> (trans("AlphaNumOnlyLowerCharsAndNoSpace"); ?>)
trans("Type"); ?>
selectarray('type', $type2label, GETPOST('type', 'alpha')); ?>
-
+
@@ -176,33 +176,36 @@ $langs->load("modulebuilder");
-trans("Position"); ?>
+trans("Position"); ?>
trans("LanguageFile"); ?>
global->MAIN_STORE_COMPUTED_EXTRAFIELDS)) { ?>
-
+
-
+
-
+
-
+
-
+
+
+
+
-
+
textwithpicto($langs->trans("HelpOnTooltip"), $langs->trans("HelpOnTooltipDesc")); ?>
multicompany->enabled) { ?>
- trans("AllEntities"); ?> >
+ trans("AllEntities"); ?> >
diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php
index 4063111a6fb..d0eaaec25f2 100644
--- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php
@@ -27,7 +27,7 @@
*/
// Protection to avoid direct call of template
-if (empty($conf) || ! is_object($conf))
+if (empty($conf) || !is_object($conf))
{
print "Error, template page can't be called as URL";
exit;
@@ -54,7 +54,7 @@ $langs->load("modulebuilder");
var list = jQuery("#list");
var totalizable = jQuery("#totalizable");
load("modulebuilder");
attributes[$elementtype]['label'][$attrname];
-$type=$extrafields->attributes[$elementtype]['type'][$attrname];
-$size=$extrafields->attributes[$elementtype]['size'][$attrname];
-$computed=$extrafields->attributes[$elementtype]['computed'][$attrname];
-$default=$extrafields->attributes[$elementtype]['default'][$attrname];
-$unique=$extrafields->attributes[$elementtype]['unique'][$attrname];
-$required=$extrafields->attributes[$elementtype]['required'][$attrname];
-$pos=$extrafields->attributes[$elementtype]['pos'][$attrname];
-$alwayseditable=$extrafields->attributes[$elementtype]['alwayseditable'][$attrname];
-$param=$extrafields->attributes[$elementtype]['param'][$attrname];
-$perms=$extrafields->attributes[$elementtype]['perms'][$attrname];
-$langfile=$extrafields->attributes[$elementtype]['langfile'][$attrname];
-$list=$extrafields->attributes[$elementtype]['list'][$attrname];
+$label = $extrafields->attributes[$elementtype]['label'][$attrname];
+$type = $extrafields->attributes[$elementtype]['type'][$attrname];
+$size = $extrafields->attributes[$elementtype]['size'][$attrname];
+$computed = $extrafields->attributes[$elementtype]['computed'][$attrname];
+$default = $extrafields->attributes[$elementtype]['default'][$attrname];
+$unique = $extrafields->attributes[$elementtype]['unique'][$attrname];
+$required = $extrafields->attributes[$elementtype]['required'][$attrname];
+$pos = $extrafields->attributes[$elementtype]['pos'][$attrname];
+$alwayseditable = $extrafields->attributes[$elementtype]['alwayseditable'][$attrname];
+$param = $extrafields->attributes[$elementtype]['param'][$attrname];
+$perms = $extrafields->attributes[$elementtype]['perms'][$attrname];
+$langfile = $extrafields->attributes[$elementtype]['langfile'][$attrname];
+$list = $extrafields->attributes[$elementtype]['list'][$attrname];
$totalizable = $extrafields->attributes[$elementtype]['totalizable'][$attrname];
-$help=$extrafields->attributes[$elementtype]['help'][$attrname];
-$entitycurrentorall=$extrafields->attributes[$elementtype]['entityid'][$attrname];
+$help = $extrafields->attributes[$elementtype]['help'][$attrname];
+$entitycurrentorall = $extrafields->attributes[$elementtype]['entityid'][$attrname];
+$printable = $extrafields->attributes[$elementtype]['printable'][$attrname];
-if((($type == 'select') || ($type == 'checkbox') || ($type == 'radio')) && is_array($param))
+if ((($type == 'select') || ($type == 'checkbox') || ($type == 'radio')) && is_array($param))
{
$param_chain = '';
foreach ($param['options'] as $key => $value)
{
- if(strlen($key))
+ if (strlen($key))
{
$param_chain .= $key.','.$value."\n";
}
}
}
-elseif (($type== 'sellist') || ($type == 'chkbxlst') || ($type == 'link') || ($type == 'password') || ($type == 'separate'))
+elseif (($type == 'sellist') || ($type == 'chkbxlst') || ($type == 'link') || ($type == 'password') || ($type == 'separate'))
{
- $paramlist=array_keys($param['options']);
+ $paramlist = array_keys($param['options']);
$param_chain = $paramlist[0];
}
?>
@@ -191,10 +192,10 @@ elseif (($type== 'sellist') || ($type == 'chkbxlst') || ($type == 'link') || ($t
trans("Type"); ?>
array('varchar', 'phone', 'mail', 'url', 'select', 'password', 'text', 'html'),
- 'text'=>array('text','html'),
- 'html'=>array('text','html'),
+ 'text'=>array('text', 'html'),
+ 'html'=>array('text', 'html'),
'password'=>array('password', 'varchar'),
'mail'=>array('varchar', 'phone', 'mail', 'url', 'select'),
'url'=>array('varchar', 'phone', 'mail', 'url', 'select'),
@@ -203,12 +204,12 @@ $typewecanchangeinto=array(
);
if (in_array($type, array_keys($typewecanchangeinto)))
{
- $newarray=array();
+ $newarray = array();
print '';
- foreach($type2label as $key => $val)
+ foreach ($type2label as $key => $val)
{
- $selected='';
- if ($key == (GETPOST('type', 'alpha')?GETPOST('type', 'alpha'):$type)) $selected=' selected="selected"';
+ $selected = '';
+ if ($key == (GETPOST('type', 'alpha') ?GETPOST('type', 'alpha') : $type)) $selected = ' selected="selected"';
if (in_array($key, $typewecanchangeinto[$type])) print ''.$val.' ';
else print ''.$val.' ';
}
@@ -244,9 +245,9 @@ else
-trans("Position"); ?>
+trans("Position"); ?>
-trans("LanguageFile"); ?>
+trans("LanguageFile"); ?>
global->MAIN_STORE_COMPUTED_EXTRAFIELDS)) { ?>
@@ -256,21 +257,24 @@ else
-
+
-
+
-
+
+
-
+
+
+
+
textwithpicto($langs->trans("HelpOnTooltip"), $langs->trans("HelpOnTooltipDesc")); ?>
multicompany->enabled) { ?>
- trans("AllEntities"); ?> >
+ trans("AllEntities"); ?> >
-
diff --git a/htdocs/core/tpl/admin_extrafields_view.tpl.php b/htdocs/core/tpl/admin_extrafields_view.tpl.php
index 0ddd3f5a8fa..b2bb69aa0bf 100644
--- a/htdocs/core/tpl/admin_extrafields_view.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_view.tpl.php
@@ -25,7 +25,7 @@
*/
// Protection to avoid direct call of template
-if (empty($langs) || ! is_object($langs))
+if (empty($langs) || !is_object($langs))
{
print "Error, template page can't be called as URL";
exit;
@@ -64,8 +64,9 @@ print ' '.$langs->trans("Unique").' ';
print ''.$langs->trans("Required").' ';
print ''.$langs->trans("AlwaysEditable").' ';
print ''.$form->textwithpicto($langs->trans("Visible"), $langs->trans("VisibleDesc")).' ';
+print ''.$form->textwithpicto($langs->trans("DisplayOnPdf"), $langs->trans("DisplayOnPdfDesc")).' ';
print ''.$form->textwithpicto($langs->trans("Totalizable"), $langs->trans("TotalizableDesc")).' ';
-if ($conf->multicompany->enabled) {
+if ($conf->multicompany->enabled) {
print ''.$langs->trans("Entities").' ';
}
print ' ';
@@ -73,16 +74,16 @@ print " \n";
if (is_array($extrafields->attributes[$elementtype]['type']) && count($extrafields->attributes[$elementtype]['type']))
{
- foreach($extrafields->attributes[$elementtype]['type'] as $key => $value)
+ foreach ($extrafields->attributes[$elementtype]['type'] as $key => $value)
{
// Load language if required
- if (! empty($extrafields->attributes[$elementtype]['langfile'][$key])) {
+ if (!empty($extrafields->attributes[$elementtype]['langfile'][$key])) {
$langs->load($extrafields->attributes[$elementtype]['langfile'][$key]);
}
print '';
print "".$extrafields->attributes[$elementtype]['pos'][$key]." \n";
- print "".$extrafields->attributes[$elementtype]['label'][$key]." \n"; // We don't translate here, we want admin to know what is the key not translated value
+ print "".$extrafields->attributes[$elementtype]['label'][$key]." \n"; // We don't translate here, we want admin to know what is the key not translated value
print "".$langs->trans($extrafields->attributes[$elementtype]['label'][$key])." \n";
print "".$key." \n";
print "".$type2label[$extrafields->attributes[$elementtype]['type'][$key]]." \n";
@@ -92,8 +93,9 @@ if (is_array($extrafields->attributes[$elementtype]['type']) && count($extrafiel
print ''.yn($extrafields->attributes[$elementtype]['required'][$key])." \n";
print ''.yn($extrafields->attributes[$elementtype]['alwayseditable'][$key])." \n";
print ''.$extrafields->attributes[$elementtype]['list'][$key]." \n";
+ print ''.$extrafields->attributes[$elementtype]['printable'][$key]." \n";
print ''.yn($extrafields->attributes[$elementtype]['totalizable'][$key])." \n";
- if (! empty($conf->multicompany->enabled)) {
+ if (!empty($conf->multicompany->enabled)) {
print '';
if (empty($extrafields->attributes[$elementtype]['entityid'][$key]))
{
@@ -101,7 +103,7 @@ if (is_array($extrafields->attributes[$elementtype]['type']) && count($extrafiel
}
else {
global $multicompanylabel_cache;
- if (! is_array($multicompanylabel_cache)) $multicompanylabel_cache = array();
+ if (!is_array($multicompanylabel_cache)) $multicompanylabel_cache = array();
if (empty($multicompanylabel_cache[$extrafields->attributes[$elementtype]['entityid'][$key]])) {
global $mc;
$mc->getInfo($extrafields->attributes[$elementtype]['entityid'][$key]);
@@ -118,8 +120,8 @@ if (is_array($extrafields->attributes[$elementtype]['type']) && count($extrafiel
}
else
{
- $colspan=13;
- if (! empty($conf->multicompany->enabled)) $colspan++;
+ $colspan = 13;
+ if (!empty($conf->multicompany->enabled)) $colspan++;
print ' ';
print '';
diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php
index 169b7753b92..795483b08ba 100644
--- a/htdocs/core/tpl/card_presend.tpl.php
+++ b/htdocs/core/tpl/card_presend.tpl.php
@@ -189,7 +189,7 @@ if ($action == 'presend')
}
$formmail->withto = $liste;
- $formmail->withtofree = (GETPOSTISSET('sendto') ? (GETPOST('sendto') ? GETPOST('sendto') : '1') : '');
+ $formmail->withtofree = (GETPOSTISSET('sendto') ? (GETPOST('sendto') ? GETPOST('sendto') : '1') : '1');
$formmail->withtocc = $liste;
$formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC;
$formmail->withtopic = $topicmail;
diff --git a/htdocs/core/tpl/contacts.tpl.php b/htdocs/core/tpl/contacts.tpl.php
index d14503a9039..eca100731ac 100644
--- a/htdocs/core/tpl/contacts.tpl.php
+++ b/htdocs/core/tpl/contacts.tpl.php
@@ -28,7 +28,6 @@ if (empty($object) || !is_object($object))
exit;
}
-
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
@@ -66,8 +65,9 @@ $userstatic = new User($db);
select_contacts(($selectedCompany > 0 ? $selectedCompany : -1), '', 'contactid', 3, '', '', 1, 'minwidth100imp');
+ $nbofcontacts = $form->select_contacts(($selectedCompany > 0 ? $selectedCompany : -1), '', 'contactid', 3, '', '', 1, 'minwidth100imp');
$newcardbutton = '';
- if (! empty($object->socid) && $object->socid > 1 && $user->rights->societe->creer)
+ if (!empty($object->socid) && $object->socid > 1 && $user->rights->societe->creer)
{
$newcardbutton .= '
id).'" title="'.$langs->trans('NewContact').'"> ';
}
@@ -140,111 +140,182 @@ if ($permission) {
element == 'shipping'|| $object->element == 'reception') && is_object($objectsrc)) $tmpobject=$objectsrc;
+ $tmpobject = $object;
+ if (($object->element == 'shipping' || $object->element == 'reception') && is_object($objectsrc)) $tmpobject = $objectsrc;
$formcompany->selectTypeContact($tmpobject, '', 'type', 'external', 'position', 0, 'minwidth100imp'); ?>
- ">
+ ">
-
- trans("NatureOfContact"); ?>
- trans("ThirdParty"); ?>
- trans("Users").'/'.$langs->trans("Contacts"); ?>
- trans("ContactType"); ?>
- trans("Status"); ?>
-
-
+print "";
-element == 'shipping'|| $object->element == 'reception') && is_object($objectsrc)) $tmpobject=$objectsrc;
+/**
+* Prepare list
+*/
+
+// TODO: replace this with direct SQL string to use $db->sort($sortfield, $sortorder)
+$list = array();
+foreach (array('internal', 'external') as $source)
+{
+ $tmpobject = $object;
+
+ if (($object->element == 'shipping' || $object->element == 'reception') && is_object($objectsrc))
+ {
+ $tmpobject = $objectsrc;
+ }
$tab = $tmpobject->liste_contact(-1, $source);
- $num=count($tab);
+ $num = count($tab);
$i = 0;
- while ($i < $num) {
- ?>
+ while ($i < $num)
+ {
+ $entry = new stdClass();
+
+ $entry->id = $tab[$i]['rowid'];
+ $entry->type = $tab[$i]['libelle'];
+
+ if ($tab[$i]['source'] == 'internal')
+ {
+ $entry->nature = $langs->trans("User");
+ }
+ elseif ($tab[$i]['source'] == 'external')
+ {
+ $entry->nature = $langs->trans("ThirdPartyContact");
+ }
-
-
- trans("User"); ?>
- trans("ThirdPartyContact"); ?>
-
-
- 0)
{
$companystatic->fetch($tab[$i]['socid']);
- echo $companystatic->getNomUrl(1);
+ $entry->thirdparty = $companystatic->getNomUrl(1);
}
- if ($tab[$i]['socid'] < 0)
+ elseif ($tab[$i]['socid'] < 0)
{
- echo $conf->global->MAIN_INFO_SOCIETE_NOM;
+ $entry->thirdparty = $conf->global->MAIN_INFO_SOCIETE_NOM;
}
- if (! $tab[$i]['socid'])
+ elseif (!$tab[$i]['socid'])
{
- echo ' ';
+ $entry->thirdparty = "";
}
- ?>
-
-
- fetch($tab[$i]['id']);
- echo $userstatic->getNomUrl(-1, '', 0, 0, 0, 0, '', 'valignmiddle');
+ $entry->contact = $userstatic->getNomUrl(-1, '', 0, 0, 0, 0, '', 'valignmiddle');
}
- if ($tab[$i]['source']=='external')
+ elseif ($tab[$i]['source'] == 'external')
{
$contactstatic->fetch($tab[$i]['id']);
- echo $contactstatic->getNomUrl(1, '', 0, '', 0, 0);
+ $entry->contact = $contactstatic->getNomUrl(1, '', 0, '', 0, 0);
}
- ?>
-
-
-
-
-
- status = $userstatic->LibStatut($tab[$i]['statuscontact'], 3);
+ }
+ elseif ($tab[$i]['source'] == 'external')
+ {
+ $entry->status = $contactstatic->LibStatut($tab[$i]['statuscontact'], 3);
+ }
+
+ $i++;
+ $list[] = $entry;
}
}
-print "\n";
-print "\n";
+
+$sortfield = GETPOST("sortfield", "alpha");
+$sortorder = GETPOST("sortorder", 'alpha');
+
+if (!$sortfield) $sortfield = "nature";
+if (!$sortorder) $sortorder = "asc";
+
+// Re-sort list
+$list = dol_sort_array($list, $sortfield, $sortorder, 1, 0, 1);
+
+$arrayfields = array(
+ 'rowid' => array('label'=>$langs->trans("Id"), 'checked'=>1),
+ 'nature' => array('label'=>$langs->trans("NatureOfContact"), 'checked'=>1),
+ 'thirdparty' => array('label'=>$langs->trans("ThirdParty"), 'checked'=>1),
+ 'contact' => array('label'=>$langs->trans("Users").'/'.$langs->trans("Contacts"), 'checked'=>1),
+ 'type' => array('label'=>$langs->trans("ContactType"), 'checked'=>1),
+ 'status' => array('label'=>$langs->trans("Status"), 'checked'=>1),
+ 'link' => array('label'=>$langs->trans("Link"), 'checked'=>1),
+);
+
+$param = 'id='.$object->id.'&mainmenu=home';
+
+/**
+ * Show list
+ */
+
+print ' ';
+
+print '';
+print ' ';
+print ' ';
+print ' ';
+print ' ';
+print ' ';
+
+print '';
+
+print '';
+print ' ';
+
+print '';
+print_liste_field_titre($arrayfields['nature']['label'], $_SERVER["PHP_SELF"], "nature", "", $param, "", $sortfield, $sortorder);
+print_liste_field_titre($arrayfields['thirdparty']['label'], $_SERVER["PHP_SELF"], "thirdparty", "", $param, "", $sortfield, $sortorder);
+print_liste_field_titre($arrayfields['contact']['label'], $_SERVER["PHP_SELF"], "contact", "", $param, "", $sortfield, $sortorder);
+print_liste_field_titre($arrayfields['type']['label'], $_SERVER["PHP_SELF"], "type", "", $param, "", $sortfield, $sortorder);
+print_liste_field_titre($arrayfields['status']['label'], $_SERVER["PHP_SELF"], "statut", "", $param, "", $sortfield, $sortorder, 'center ');
+print_liste_field_titre($arrayfields['link']['label'], $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder, 'center maxwidthsearch ');
+print " ";
+
+foreach ($list as $entry)
+{
+ print '';
+
+ print ''.$entry->nature.' ';
+ print ''.$entry->thirdparty.' ';
+ print ''.$entry->contact.' ';
+ print ''.$entry->type.' ';
+ print ''.$entry->status.' ';
+
+ if ($permission)
+ {
+ $href = $_SERVER["PHP_SELF"];
+ $href .= "?id=".$object->id;
+ $href .= "&action=deletecontact";
+ $href .= "&lineid=".$entry->id;
+
+ print "";
+ print "";
+ print img_picto($langs->trans("Unlink"), "unlink");
+ print " ";
+ print " ";
+ }
+
+ print " ";
+}
+
+print "
";
+print "";
+print " ";
+print "";
+
print "\n";
if (is_object($hookmanager)) {
$hookmanager->initHooks(array('contacttpl'));
- $parameters=array();
- $reshook=$hookmanager->executeHooks('formContactTpl', $parameters, $object, $action);
+ $parameters = array();
+ $reshook = $hookmanager->executeHooks('formContactTpl', $parameters, $object, $action);
}
print "\n";
+
diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php
index a3de72723a4..1b5cb242391 100644
--- a/htdocs/core/tpl/document_actions_post_headers.tpl.php
+++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php
@@ -23,6 +23,7 @@
// $permissiontoadd = permission or not to add a file (can use also $permission) and permission or not to edit file name or crop file (can use also $permtoedit)
// $modulepart = for download
// $param = param to add to download links
+// $moreparam = param to add to download link for the form_attach_new_file function
// $upload_dir
// $object
// $filearray
@@ -71,6 +72,7 @@ if ($action == 'delete')
$formfile=new FormFile($db);
+
// We define var to enable the feature to add prefix of uploaded files.
// Caller of this include can make
// $savingdocmask=dol_sanitizeFileName($object->ref).'-__file__';
@@ -92,6 +94,7 @@ if (!isset($savingdocmask) || !empty($conf->global->MAIN_DISABLE_SUGGEST_REF_AS_
'project_task',
'expensereport',
'tax',
+ 'tax-vat',
'produit',
'product_batch',
'bom',
@@ -109,7 +112,7 @@ if (!isset($savingdocmask) || !empty($conf->global->MAIN_DISABLE_SUGGEST_REF_AS_
// Show upload form (document and links)
$formfile->form_attach_new_file(
- $_SERVER["PHP_SELF"].'?id='.$object->id.(empty($withproject)?'':'&withproject=1'),
+ $_SERVER["PHP_SELF"].'?id='.$object->id.(empty($withproject)?'':'&withproject=1').(empty($moreparam)?'':$moreparam),
'',
0,
0,
diff --git a/htdocs/core/tpl/extrafields_add.tpl.php b/htdocs/core/tpl/extrafields_add.tpl.php
index 0579c464d30..45ca9a29197 100644
--- a/htdocs/core/tpl/extrafields_add.tpl.php
+++ b/htdocs/core/tpl/extrafields_add.tpl.php
@@ -37,11 +37,14 @@ if (empty($conf) || !is_object($conf))
executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
if (empty($reshook)) {
- $params = isset($tpl_context) ? array('tpl_context' => $tpl_context) : array(); // BUG #11554 : Add tpl_context in params
+ $params = array();
+ if (isset($tpl_context)) $params['tpl_context'] = $tpl_context;
+ $params['cols'] = $parameters['colspanvalue'];
print $object->showOptionals($extrafields, 'edit', $params); // BUG #11554 : Add context in params
}
diff --git a/htdocs/core/tpl/extrafields_edit.tpl.php b/htdocs/core/tpl/extrafields_edit.tpl.php
index adca8b50fab..dbc2b9745cd 100644
--- a/htdocs/core/tpl/extrafields_edit.tpl.php
+++ b/htdocs/core/tpl/extrafields_edit.tpl.php
@@ -26,7 +26,7 @@
*/
// Protection to avoid direct call of template
-if (empty($conf) || ! is_object($conf))
+if (empty($conf) || !is_object($conf))
{
print "Error, template page can't be called as URL";
exit;
@@ -37,11 +37,13 @@ if (empty($conf) || ! is_object($conf))
executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
if (empty($reshook)) {
- print $object->showOptionals($extrafields, 'edit');
+ $params = array();
+ $params['cols'] = $parameters['colspanvalue'];
+ print $object->showOptionals($extrafields, 'edit', $params);
}
?>
diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php
index f8767a82163..1ef3ef07255 100644
--- a/htdocs/core/tpl/extrafields_view.tpl.php
+++ b/htdocs/core/tpl/extrafields_view.tpl.php
@@ -73,7 +73,7 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element]
//print $key.'-'.$enabled.'-'.$perms.'-'.$label.$_POST["options_" . $key].' '."\n";
if (empty($enabled)) continue; // 0 = Never visible field
- if (abs($enabled) != 1 && abs($enabled) != 3) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list
+ if (abs($enabled) != 1 && abs($enabled) != 3 && abs($enabled) != 5) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list
if (empty($perms)) continue; // 0 = Not visible
// Load language if required
@@ -135,7 +135,7 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element]
if ($object->element == 'productlot') $permok = $user->rights->stock->creer;
if ($object->element == 'facturerec') $permok = $user->rights->facture->creer;
if (($object->statut == 0 || !empty($extrafields->attributes[$object->table_element]['alwayseditable'][$key]))
- && $permok && ($action != 'edit_extras' || GETPOST('attribute') != $key)
+ && $permok && $enabled != 5 && ($action != 'edit_extras' || GETPOST('attribute') != $key)
&& empty($extrafields->attributes[$object->table_element]['computed'][$key]))
{
$fieldid = 'id';
diff --git a/htdocs/core/tpl/notes.tpl.php b/htdocs/core/tpl/notes.tpl.php
index 7663af1c48e..28eb78fa61b 100644
--- a/htdocs/core/tpl/notes.tpl.php
+++ b/htdocs/core/tpl/notes.tpl.php
@@ -1,7 +1,7 @@
* Copyright (C) 2013 Florian Henry
- * Copyright (C) 2014-2017 Laurent Destailleur
+ * Copyright (C) 2014-2020 Laurent Destailleur
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,69 +29,70 @@ $module = $object->element;
$note_public = 'note_public';
$note_private = 'note_private';
-$colwidth=(isset($colwidth)?$colwidth:(empty($cssclass)?'25':''));
+$colwidth = (isset($colwidth) ? $colwidth : (empty($cssclass) ? '25' : ''));
// Set $permission from the $permissionnote var defined on calling page
-$permission=(isset($permissionnote)?$permissionnote:(isset($permission)?$permission:(isset($user->rights->$module->create)?$user->rights->$module->create:(isset($user->rights->$module->creer)?$user->rights->$module->creer:0))));
-$moreparam=(isset($moreparam)?$moreparam:'');
-$value_public=$object->note_public;
-$value_private=$object->note_private;
-if (! empty($conf->global->MAIN_AUTO_TIMESTAMP_IN_PUBLIC_NOTES))
+$permission = (isset($permissionnote) ? $permissionnote : (isset($permission) ? $permission : (isset($user->rights->$module->create) ? $user->rights->$module->create : (isset($user->rights->$module->creer) ? $user->rights->$module->creer : 0))));
+$moreparam = (isset($moreparam) ? $moreparam : '');
+$value_public = $object->note_public;
+$value_private = $object->note_private;
+if (!empty($conf->global->MAIN_AUTO_TIMESTAMP_IN_PUBLIC_NOTES))
{
- $stringtoadd=dol_print_date(dol_now(), 'dayhour').' '.$user->getFullName($langs).' --';
+ $stringtoadd = dol_print_date(dol_now(), 'dayhour').' '.$user->getFullName($langs).' --';
if (GETPOST('action', 'aZ09') == 'edit'.$note_public)
{
- $value_public=dol_concatdesc($value_public, ($value_public?"\n":"")."-- ".$stringtoadd);
- if (dol_textishtml($value_public)) $value_public.=" \n";
- else $value_public.="\n";
+ $value_public = dol_concatdesc($value_public, ($value_public ? "\n" : "")."-- ".$stringtoadd);
+ if (dol_textishtml($value_public)) $value_public .= " \n";
+ else $value_public .= "\n";
}
}
-if (! empty($conf->global->MAIN_AUTO_TIMESTAMP_IN_PRIVATE_NOTES))
+if (!empty($conf->global->MAIN_AUTO_TIMESTAMP_IN_PRIVATE_NOTES))
{
- $stringtoadd=dol_print_date(dol_now(), 'dayhour').' '.$user->getFullName($langs).' --';
+ $stringtoadd = dol_print_date(dol_now(), 'dayhour').' '.$user->getFullName($langs).' --';
if (GETPOST('action', 'aZ09') == 'edit'.$note_private)
{
- $value_private=dol_concatdesc($value_private, ($value_private?"\n":"")."-- ".$stringtoadd);
- if (dol_textishtml($value_private)) $value_private.=" \n";
- else $value_private.="\n";
+ $value_private = dol_concatdesc($value_private, ($value_private ? "\n" : "")."-- ".$stringtoadd);
+ if (dol_textishtml($value_private)) $value_private .= " \n";
+ else $value_private .= "\n";
}
}
// Special cases
-if ($module == 'propal') { $permission=$user->rights->propale->creer;}
-elseif ($module == 'supplier_proposal') { $permission=$user->rights->supplier_proposal->creer;}
-elseif ($module == 'fichinter') { $permission=$user->rights->ficheinter->creer;}
-elseif ($module == 'project') { $permission=$user->rights->projet->creer;}
-elseif ($module == 'project_task') { $permission=$user->rights->projet->creer;}
-elseif ($module == 'invoice_supplier') { $permission=$user->rights->fournisseur->facture->creer;}
-elseif ($module == 'order_supplier') { $permission=$user->rights->fournisseur->commande->creer;}
-elseif ($module == 'societe') { $permission=$user->rights->societe->creer;}
-elseif ($module == 'contact') { $permission=$user->rights->societe->creer;}
-elseif ($module == 'shipping') { $permission=$user->rights->expedition->creer;}
-elseif ($module == 'product') { $permission=$user->rights->produit->creer;}
+if ($module == 'propal') { $permission = $user->rights->propale->creer; }
+elseif ($module == 'supplier_proposal') { $permission = $user->rights->supplier_proposal->creer; }
+elseif ($module == 'fichinter') { $permission = $user->rights->ficheinter->creer; }
+elseif ($module == 'project') { $permission = $user->rights->projet->creer; }
+elseif ($module == 'project_task') { $permission = $user->rights->projet->creer; }
+elseif ($module == 'invoice_supplier') { $permission = $user->rights->fournisseur->facture->creer; }
+elseif ($module == 'order_supplier') { $permission = $user->rights->fournisseur->commande->creer; }
+elseif ($module == 'societe') { $permission = $user->rights->societe->creer; }
+elseif ($module == 'contact') { $permission = $user->rights->societe->creer; }
+elseif ($module == 'shipping') { $permission = $user->rights->expedition->creer; }
+elseif ($module == 'product') { $permission = $user->rights->produit->creer; }
//else dol_print_error('','Bad value '.$module.' for param module');
-if (! empty($conf->fckeditor->enabled) && ! empty($conf->global->FCKEDITOR_ENABLE_SOCIETE)) $typeofdata='ckeditor:dolibarr_notes:100%:200::1:12:95%:0'; // Rem: This var is for all notes, not only thirdparties note.
-else $typeofdata='textarea:12:95%';
+if (!empty($conf->fckeditor->enabled) && !empty($conf->global->FCKEDITOR_ENABLE_SOCIETE)) $typeofdata = 'ckeditor:dolibarr_notes:100%:200::1:12:95%:0'; // Rem: This var is for all notes, not only thirdparties note.
+else $typeofdata = 'textarea:12:95%';
print ''."\n";
print ''."\n";
if ($module != 'product') {
// No public note yet on products
print '
'."\n";
- print '
'."\n";
+ print '
'."\n";
print $form->editfieldkey("NotePublic", $note_public, $value_public, $object, $permission, $typeofdata, $moreparam, '', 0);
print '
'."\n";
- print '
'."\n";
+ print '
'."\n";
print $form->editfieldval("NotePublic", $note_public, $value_public, $object, $permission, $typeofdata, '', null, null, $moreparam, 1)."\n";
print '
'."\n";
print '
'."\n";
}
if (empty($user->socid)) {
+ // Private notes (always hidden to external users)
print '
'."\n";
- print '
'."\n";
+ print '
'."\n";
print $form->editfieldkey("NotePrivate", $note_private, $value_private, $object, $permission, $typeofdata, $moreparam, '', 0);
print '
'."\n";
- print '
'."\n";
+ print '
'."\n";
print $form->editfieldval("NotePrivate", $note_private, $value_private, $object, $permission, $typeofdata, '', null, null, $moreparam, 1);
print '
'."\n";
print '
'."\n";
diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php
index b60c48da09c..5fc268013c6 100644
--- a/htdocs/core/tpl/objectline_create.tpl.php
+++ b/htdocs/core/tpl/objectline_create.tpl.php
@@ -261,7 +261,7 @@ if ($nolinesbefore) {
if ($senderissupplier != 2)
{
$ajaxoptions = array(
- 'update' => array('qty'=>'qty', 'remise_percent' => 'discount', 'idprod' => 'idprod'), // html id tags that will be edited with which ajax json response key
+ 'update' => array('qty'=>'qty', 'remise_percent' => 'discount', 'idprod' => 'idprod'), // html id tags that will be edited with each ajax json response key
'option_disabled' => 'idthatdoesnotexists', // html id to disable once select is done
'warning' => $langs->trans("NoPriceDefinedForThisSupplier") // translation of an error saved into var 'warning' (for example shown we select a disabled option into combo)
);
@@ -378,7 +378,7 @@ if ($nolinesbefore) {
">
global->PRODUCT_USE_UNITS)) {
+ if (!empty($conf->global->PRODUCT_USE_UNITS)) {
$coldisplay++;
print '
';
print $form->selectUnits($line->fk_unit, "units");
@@ -432,7 +432,7 @@ if ($nolinesbefore) {
showOptionals($extrafields, 'edit', array('colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1);
+ print $objectline->showOptionals($extrafields, 'edit', array('colspan'=>$coldisplay), '', '', 1);
}
if ((!empty($conf->service->enabled) || ($object->element == 'contrat')) && $dateSelector && GETPOST('type') != '0') // We show date field if required
@@ -541,6 +541,7 @@ if (!empty($usemargins) && $user->rights->margins->creer)
else if (npRate == "np_markRate")
price = ((bpjs / (1 - ratejs / 100)) / (1 - remisejs / 100));
}
+
$("input[name='price_ht']:first").val(price); // TODO Must use a function like php price to have here a formated value
return true;
@@ -552,26 +553,26 @@ if (!empty($usemargins) && $user->rights->margins->creer)
/* JQuery for product free or predefined select */
jQuery(document).ready(function() {
- jQuery("#price_ht").keyup(function(event) {
- // console.log(event.which); // discard event tag and arrows
- if (event.which != 9 && (event.which < 37 ||event.which > 40) && jQuery("#price_ht").val() != '') {
- jQuery("#price_ttc").val('');
- jQuery("#multicurrency_subprice").val('');
- }
+ jQuery("#price_ht").keyup(function(event) {
+ // console.log(event.which); // discard event tag and arrows
+ if (event.which != 9 && (event.which < 37 ||event.which > 40) && jQuery("#price_ht").val() != '') {
+ jQuery("#price_ttc").val('');
+ jQuery("#multicurrency_subprice").val('');
+ }
});
jQuery("#price_ttc").keyup(function(event) {
- // console.log(event.which); // discard event tag and arrows
- if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') {
- jQuery("#price_ht").val('');
- jQuery("#multicurrency_subprice").val('');
- }
+ // console.log(event.which); // discard event tag and arrows
+ if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') {
+ jQuery("#price_ht").val('');
+ jQuery("#multicurrency_subprice").val('');
+ }
});
jQuery("#multicurrency_subprice").keyup(function(event) {
- // console.log(event.which); // discard event tag and arrows
- if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') {
- jQuery("#price_ht").val('');
- jQuery("#price_ttc").val('');
- }
+ // console.log(event.which); // discard event tag and arrows
+ if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') {
+ jQuery("#price_ht").val('');
+ jQuery("#price_ttc").val('');
+ }
});
$("#prod_entry_mode_free").on( "click", function() {
@@ -630,15 +631,28 @@ if (!empty($usemargins) && $user->rights->margins->creer)
if (empty($conf->global->MAIN_DISABLE_EDIT_PREDEF_PRICEHT) && empty($senderissupplier))
{
?>
- // Get the HT price for the product and display it
- console.log("Load price without tax and set it into #price_ht");
- $.post('/product/ajax/products.php?action=fetch',
- { 'id': $(this).val(), 'socid' : socid; ?> },
- function(data) { jQuery("#price_ht").val(data.price_ht); },
- 'json'
- );
+ var pbq = parseInt($('option:selected', this).attr('data-pbq'));
+ if ((jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val()) && ! isNaN(pbq) && pbq > 0)
+ {
+ console.log("We are in a price per qty context, we do not call ajax/product");
+ } else {
+ global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { ?>
+ if (isNaN(pbq)) { console.log("We use experimental option PRODUIT_CUSTOMER_PRICES_BY_QTY or PRODUIT_CUSTOMER_PRICES_BY_QTY but we are not yet able to get the id of pbq from product combo list, so load of price may be 0 if product has differet prices"); }
+
+ // Get the HT price for the product and display it
+ console.log("Load unit price without tax and set it into #price_ht for product id="+$(this).val()+" socid=socid; ?>");
+ $.post('/product/ajax/products.php?action=fetch',
+ { 'id': $(this).val(), 'socid': socid; ?> },
+ function(data) {
+ console.log("Load unit price end, we got value "+data.price_ht);
+ jQuery("#price_ht").val(data.price_ht);
+ },
+ 'json'
+ );
+ }
rights->margins->creer)
{
$langs->load('stocks');
@@ -648,95 +662,96 @@ if (!empty($usemargins) && $user->rights->margins->creer)
$("#fournprice_predef").find("option").remove();
$("#fournprice_predef").hide();
$("#buying_price").val("").show();
+
/* Call post to load content of combo list fournprice_predef */
$.post('/fourn/ajax/getSupplierPrices.php?bestpricefirst=1', { 'idprod': $(this).val() }, function(data) {
- if (data && data.length > 0)
- {
- var options = ''; var defaultkey = ''; var defaultprice = ''; var bestpricefound = 0;
-
- var bestpriceid = 0; var bestpricevalue = 0;
- var pmppriceid = 0; var pmppricevalue = 0;
- var costpriceid = 0; var costpricevalue = 0;
-
- /* setup of margin calculation */
- var defaultbuyprice = 'global->MARGIN_TYPE))
- {
- if ($conf->global->MARGIN_TYPE == '1') print 'bestsupplierprice';
- if ($conf->global->MARGIN_TYPE == 'pmp') print 'pmp';
- if ($conf->global->MARGIN_TYPE == 'costprice') print 'costprice';
- } ?>';
- console.log("we will set the field for margin. defaultbuyprice="+defaultbuyprice);
-
- var i = 0;
- $(data).each(function() {
- /* Warning: Lines must be processed in order: best supplier price, then pmpprice line then costprice */
- if (this.id != 'pmpprice' && this.id != 'costprice')
+ if (data && data.length > 0)
{
- i++;
- this.price = parseFloat(this.price); // to fix when this.price >0
- // If margin is calculated on best supplier price, we set it by defaut (but only if value is not 0)
- //console.log("id="+this.id+"-price="+this.price+"-"+(this.price > 0));
- if (bestpricefound == 0 && this.price > 0) { defaultkey = this.id; defaultprice = this.price; bestpriceid = this.id; bestpricevalue = this.price; bestpricefound=1; } // bestpricefound is used to take the first price > 0
- }
- if (this.id == 'pmpprice')
- {
- // If margin is calculated on PMP, we set it by defaut (but only if value is not 0)
- console.log("id="+this.id+"-price="+this.price);
- if ('pmp' == defaultbuyprice || 'costprice' == defaultbuyprice)
+ var options = ''; var defaultkey = ''; var defaultprice = ''; var bestpricefound = 0;
+
+ var bestpriceid = 0; var bestpricevalue = 0;
+ var pmppriceid = 0; var pmppricevalue = 0;
+ var costpriceid = 0; var costpricevalue = 0;
+
+ /* setup of margin calculation */
+ var defaultbuyprice = 'global->MARGIN_TYPE))
{
- if (this.price > 0) {
- defaultkey = this.id; defaultprice = this.price; pmppriceid = this.id; pmppricevalue = this.price;
- //console.log("pmppricevalue="+pmppricevalue);
+ if ($conf->global->MARGIN_TYPE == '1') print 'bestsupplierprice';
+ if ($conf->global->MARGIN_TYPE == 'pmp') print 'pmp';
+ if ($conf->global->MARGIN_TYPE == 'costprice') print 'costprice';
+ } ?>';
+ console.log("we will set the field for margin. defaultbuyprice="+defaultbuyprice);
+
+ var i = 0;
+ $(data).each(function() {
+ /* Warning: Lines must be processed in order: best supplier price, then pmpprice line then costprice */
+ if (this.id != 'pmpprice' && this.id != 'costprice')
+ {
+ i++;
+ this.price = parseFloat(this.price); // to fix when this.price >0
+ // If margin is calculated on best supplier price, we set it by defaut (but only if value is not 0)
+ //console.log("id="+this.id+"-price="+this.price+"-"+(this.price > 0));
+ if (bestpricefound == 0 && this.price > 0) { defaultkey = this.id; defaultprice = this.price; bestpriceid = this.id; bestpricevalue = this.price; bestpricefound=1; } // bestpricefound is used to take the first price > 0
}
- }
- }
- if (this.id == 'costprice')
- {
- // If margin is calculated on Cost price, we set it by defaut (but only if value is not 0)
- console.log("id="+this.id+"-price="+this.price+"-pmppricevalue="+pmppricevalue);
- if ('costprice' == defaultbuyprice)
+ if (this.id == 'pmpprice')
+ {
+ // If margin is calculated on PMP, we set it by defaut (but only if value is not 0)
+ console.log("id="+this.id+"-price="+this.price);
+ if ('pmp' == defaultbuyprice || 'costprice' == defaultbuyprice)
+ {
+ if (this.price > 0) {
+ defaultkey = this.id; defaultprice = this.price; pmppriceid = this.id; pmppricevalue = this.price;
+ //console.log("pmppricevalue="+pmppricevalue);
+ }
+ }
+ }
+ if (this.id == 'costprice')
+ {
+ // If margin is calculated on Cost price, we set it by defaut (but only if value is not 0)
+ console.log("id="+this.id+"-price="+this.price+"-pmppricevalue="+pmppricevalue);
+ if ('costprice' == defaultbuyprice)
+ {
+ if (this.price > 0) { defaultkey = this.id; defaultprice = this.price; costpriceid = this.id; costpricevalue = this.price; }
+ else if (pmppricevalue > 0) { defaultkey = 'pmpprice'; defaultprice = pmppricevalue; }
+ }
+ }
+ options += ''+this.label+' ';
+ });
+ options += 'trans("InputPrice"); ?> ';
+
+ console.log("finally selected defaultkey="+defaultkey+" defaultprice for buying price="+defaultprice);
+
+ $("#fournprice_predef").html(options).show();
+ if (defaultkey != '')
{
- if (this.price > 0) { defaultkey = this.id; defaultprice = this.price; costpriceid = this.id; costpricevalue = this.price; }
- else if (pmppricevalue > 0) { defaultkey = 'pmpprice'; defaultprice = pmppricevalue; }
+ $("#fournprice_predef").val(defaultkey);
}
+
+ /* At loading, no product are yet selected, so we hide field of buying_price */
+ $("#buying_price").hide();
+
+ /* Define default price at loading */
+ var defaultprice = $("#fournprice_predef").find('option:selected').attr("price");
+ $("#buying_price").val(defaultprice);
+
+ $("#fournprice_predef").change(function() {
+ console.log("change on fournprice_predef");
+ /* Hide field buying_price according to choice into list (if 'inputprice' or not) */
+ var linevalue=$(this).find('option:selected').val();
+ var pricevalue = $(this).find('option:selected').attr("price");
+ if (linevalue != 'inputprice' && linevalue != 'pmpprice') {
+ $("#buying_price").val(pricevalue).hide(); /* We set value then hide field */
+ }
+ if (linevalue == 'inputprice') {
+ $('#buying_price').show();
+ }
+ if (linevalue == 'pmpprice') {
+ $("#buying_price").val(pricevalue);
+ $('#buying_price').hide();
+ }
+ });
}
- options += ''+this.label+' ';
- });
- options += 'trans("InputPrice"); ?> ';
-
- console.log("finally selected defaultkey="+defaultkey+" defaultprice="+defaultprice);
-
- $("#fournprice_predef").html(options).show();
- if (defaultkey != '')
- {
- $("#fournprice_predef").val(defaultkey);
- }
-
- /* At loading, no product are yet selected, so we hide field of buying_price */
- $("#buying_price").hide();
-
- /* Define default price at loading */
- var defaultprice = $("#fournprice_predef").find('option:selected').attr("price");
- $("#buying_price").val(defaultprice);
-
- $("#fournprice_predef").change(function() {
- console.log("change on fournprice_predef");
- /* Hide field buying_price according to choice into list (if 'inputprice' or not) */
- var linevalue=$(this).find('option:selected').val();
- var pricevalue = $(this).find('option:selected').attr("price");
- if (linevalue != 'inputprice' && linevalue != 'pmpprice') {
- $("#buying_price").val(pricevalue).hide(); /* We set value then hide field */
- }
- if (linevalue == 'inputprice') {
- $('#buying_price').show();
- }
- if (linevalue == 'pmpprice') {
- $("#buying_price").val(pricevalue);
- $('#buying_price').hide();
- }
- });
- }
},
'json');
@@ -744,15 +759,20 @@ if (!empty($usemargins) && $user->rights->margins->creer)
}
?>
- /* To process customer price per quantity */
+ /* To process customer price per quantity (CUSTOMER_PRICE_PER_QTY works only if combo product is not an ajax after x key pressed) */
var pbq = parseInt($('option:selected', this).attr('data-pbq'));
+ var pbqup = parseFloat($('option:selected', this).attr('data-pbqup'));
+ var pbqbase = $('option:selected', this).attr('data-pbqbase');
var pbqqty = parseFloat($('option:selected', this).attr('data-pbqqty'));
var pbqpercent = parseFloat($('option:selected', this).attr('data-pbqpercent'));
- if ((jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val()) && typeof pbq !== "undefined")
+ if ((jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val()) && ! isNaN(pbq) && pbq > 0)
{
- console.log("We choose a price by quanty price_by_qty id = "+pbq+" price_by_qty qty = "+pbqqty+" price_by_qty percent = "+pbqpercent);
+ var pbqupht = pbqup; /* TODO support of price per qty TTC not yet available */
+
+ console.log("We choose a price by quanty price_by_qty id = "+pbq+" price_by_qty upht = "+pbqupht+" price_by_qty qty = "+pbqqty+" price_by_qty percent = "+pbqpercent);
jQuery("#pbq").val(pbq);
+ jQuery("#price_ht").val(pbqupht);
if (jQuery("#qty").val() < pbqqty)
{
jQuery("#qty").val(pbqqty);
@@ -809,7 +829,6 @@ if (!empty($usemargins) && $user->rights->margins->creer)
jQuery("#price_ht").val('').hide();
jQuery("#multicurrency_price_ht").val('').hide();
- jQuery("#price_ht").val('');
jQuery("#price_ttc, #fourn_ref, #tva_tx, #title_vat, #title_up_ht_currency, #title_up_ttc, #title_up_ttc_currency").hide();
jQuery("#np_marginRate, #np_markRate, .np_marginRate, .np_markRate, #units, #title_units").hide();
jQuery("#buying_price").show();
diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php
index 7c76a5c0e07..278b8eabdd8 100644
--- a/htdocs/core/tpl/objectline_edit.tpl.php
+++ b/htdocs/core/tpl/objectline_edit.tpl.php
@@ -260,7 +260,7 @@ $coldisplay++;
//Line extrafield
if (!empty($extrafields))
{
- print $line->showOptionals($extrafields, 'edit', array('class'=>'tredited', 'colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD)?0:1);
+ print $line->showOptionals($extrafields, 'edit', array('class'=>'tredited', 'colspan'=>$coldisplay), '', '', 1);
}
?>
diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php
index 19a10e0f560..59f2e1ef57c 100644
--- a/htdocs/core/tpl/objectline_view.tpl.php
+++ b/htdocs/core/tpl/objectline_view.tpl.php
@@ -356,7 +356,7 @@ print " \n";
//Line extrafield
if (!empty($extrafields))
{
- print $line->showOptionals($extrafields, 'view', array('style'=>'class="drag drop oddeven"', 'colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1);
+ print $line->showOptionals($extrafields, 'view', array('style'=>'class="drag drop oddeven"', 'colspan'=>$coldisplay), '', '', 1);
}
print "\n";
diff --git a/htdocs/core/triggers/interface_20_all_Logevents.class.php b/htdocs/core/triggers/interface_20_all_Logevents.class.php
index 93d1b37c690..7acd977e714 100644
--- a/htdocs/core/triggers/interface_20_all_Logevents.class.php
+++ b/htdocs/core/triggers/interface_20_all_Logevents.class.php
@@ -59,13 +59,13 @@ class InterfaceLogevents extends DolibarrTriggers
*/
public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
{
- if (! empty($conf->global->MAIN_LOGEVENTS_DISABLE_ALL)) return 0; // Log events is disabled (hidden features)
+ if (!empty($conf->global->MAIN_LOGEVENTS_DISABLE_ALL)) return 0; // Log events is disabled (hidden features)
- $key='MAIN_LOGEVENTS_'.$action;
+ $key = 'MAIN_LOGEVENTS_'.$action;
//dol_syslog("xxxxxxxxxxx".$key);
- if (empty($conf->global->$key)) return 0; // Log events not enabled for this action
+ if (empty($conf->global->$key)) return 0; // Log events not enabled for this action
- if (empty($conf->entity)) $conf->entity = $entity; // forcing of the entity if it's not defined (ex: in login form)
+ if (empty($conf->entity)) $conf->entity = $entity; // forcing of the entity if it's not defined (ex: in login form)
$date = dol_now();
@@ -76,18 +76,18 @@ class InterfaceLogevents extends DolibarrTriggers
$langs->load("users");
// Initialisation donnees (date,duree,texte,desc)
- $text="(UserLogged,".$object->login.")";
- $text.=(empty($object->trigger_mesg)?'':' - '.$object->trigger_mesg);
- $desc="(UserLogged,".$object->login.")";
- $desc.=(empty($object->trigger_mesg)?'':' - '.$object->trigger_mesg);
+ $text = "(UserLogged,".$object->login.")";
+ $text .= (empty($object->trigger_mesg) ? '' : ' - '.$object->trigger_mesg);
+ $desc = "(UserLogged,".$object->login.")";
+ $desc .= (empty($object->trigger_mesg) ? '' : ' - '.$object->trigger_mesg);
}
if ($action == 'USER_LOGIN_FAILED')
{
dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
// Initialisation donnees (date,duree,texte,desc)
- $text=$object->trigger_mesg; // Message direct
- $desc=$object->trigger_mesg; // Message direct
+ $text = $object->trigger_mesg; // Message direct
+ $desc = $object->trigger_mesg; // Message direct
}
if ($action == 'USER_LOGOUT')
{
@@ -95,8 +95,8 @@ class InterfaceLogevents extends DolibarrTriggers
$langs->load("users");
// Initialisation donnees (date,duree,texte,desc)
- $text="(UserLogoff,".$object->login.")";
- $desc="(UserLogoff,".$object->login.")";
+ $text = "(UserLogoff,".$object->login.")";
+ $desc = "(UserLogoff,".$object->login.")";
}
if ($action == 'USER_CREATE')
{
@@ -104,8 +104,8 @@ class InterfaceLogevents extends DolibarrTriggers
$langs->load("users");
// Initialisation donnees (date,duree,texte,desc)
- $text=$langs->transnoentities("NewUserCreated", $object->login);
- $desc=$langs->transnoentities("NewUserCreated", $object->login);
+ $text = $langs->transnoentities("NewUserCreated", $object->login);
+ $desc = $langs->transnoentities("NewUserCreated", $object->login);
}
elseif ($action == 'USER_MODIFY')
{
@@ -113,8 +113,8 @@ class InterfaceLogevents extends DolibarrTriggers
$langs->load("users");
// Initialisation donnees (date,duree,texte,desc)
- $text=$langs->transnoentities("EventUserModified", $object->login);
- $desc=$langs->transnoentities("EventUserModified", $object->login);
+ $text = $langs->transnoentities("EventUserModified", $object->login);
+ $desc = $langs->transnoentities("EventUserModified", $object->login);
}
elseif ($action == 'USER_NEW_PASSWORD')
{
@@ -122,8 +122,8 @@ class InterfaceLogevents extends DolibarrTriggers
$langs->load("users");
// Initialisation donnees (date,duree,texte,desc)
- $text=$langs->transnoentities("NewUserPassword", $object->login);
- $desc=$langs->transnoentities("NewUserPassword", $object->login);
+ $text = $langs->transnoentities("NewUserPassword", $object->login);
+ $desc = $langs->transnoentities("NewUserPassword", $object->login);
}
elseif ($action == 'USER_ENABLEDISABLE')
{
@@ -132,13 +132,13 @@ class InterfaceLogevents extends DolibarrTriggers
// Initialisation donnees (date,duree,texte,desc)
if ($object->statut == 0)
{
- $text=$langs->transnoentities("UserEnabled", $object->login);
- $desc=$langs->transnoentities("UserEnabled", $object->login);
+ $text = $langs->transnoentities("UserEnabled", $object->login);
+ $desc = $langs->transnoentities("UserEnabled", $object->login);
}
if ($object->statut == 1)
{
- $text=$langs->transnoentities("UserDisabled", $object->login);
- $desc=$langs->transnoentities("UserDisabled", $object->login);
+ $text = $langs->transnoentities("UserDisabled", $object->login);
+ $desc = $langs->transnoentities("UserDisabled", $object->login);
}
}
elseif ($action == 'USER_DELETE')
@@ -146,8 +146,8 @@ class InterfaceLogevents extends DolibarrTriggers
dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
$langs->load("users");
// Initialisation donnees (date,duree,texte,desc)
- $text=$langs->transnoentities("UserDeleted", $object->login);
- $desc=$langs->transnoentities("UserDeleted", $object->login);
+ $text = $langs->transnoentities("UserDeleted", $object->login);
+ $desc = $langs->transnoentities("UserDeleted", $object->login);
}
// Groupes
@@ -156,24 +156,24 @@ class InterfaceLogevents extends DolibarrTriggers
dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
$langs->load("users");
// Initialisation donnees (date,duree,texte,desc)
- $text=$langs->transnoentities("NewGroupCreated", $object->name);
- $desc=$langs->transnoentities("NewGroupCreated", $object->name);
+ $text = $langs->transnoentities("NewGroupCreated", $object->name);
+ $desc = $langs->transnoentities("NewGroupCreated", $object->name);
}
elseif ($action == 'GROUP_MODIFY')
{
dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
$langs->load("users");
// Initialisation donnees (date,duree,texte,desc)
- $text=$langs->transnoentities("GroupModified", $object->name);
- $desc=$langs->transnoentities("GroupModified", $object->name);
+ $text = $langs->transnoentities("GroupModified", $object->name);
+ $desc = $langs->transnoentities("GroupModified", $object->name);
}
elseif ($action == 'GROUP_DELETE')
{
dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
$langs->load("users");
// Initialisation donnees (date,duree,texte,desc)
- $text=$langs->transnoentities("GroupDeleted", $object->name);
- $desc=$langs->transnoentities("GroupDeleted", $object->name);
+ $text = $langs->transnoentities("GroupDeleted", $object->name);
+ $desc = $langs->transnoentities("GroupDeleted", $object->name);
}
// If not found
@@ -186,29 +186,30 @@ class InterfaceLogevents extends DolibarrTriggers
*/
// Add more information into desc from the context property
- if (! empty($desc) && ! empty($object->context['audit'])) $desc.=' - '.$object->context['audit'];
+ if (!empty($desc) && !empty($object->context['audit'])) $desc .= ' - '.$object->context['audit'];
// Add entry in event table
include_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php';
- $event=new Events($this->db);
- $event->type=$action;
- $event->dateevent=$date;
- $event->label=$text;
- $event->description=$desc;
- $event->user_agent=$_SERVER["HTTP_USER_AGENT"];
+ $event = new Events($this->db);
+ $event->type = $action;
+ $event->dateevent = $date;
+ $event->label = $text;
+ $event->description = $desc;
+ $event->user_agent = $_SERVER["HTTP_USER_AGENT"];
- $result=$event->create($user);
+ $result = $event->create($user);
if ($result > 0)
{
return 1;
}
else
{
- $error ="Failed to insert security event: ".$event->error;
- $this->error=$error;
+ $error = "Failed to insert security event: ".$event->error;
+ $this->errors[] = $error;
+ $this->error = $error;
- dol_syslog(get_class($this).": ".$this->error, LOG_ERR);
+ dol_syslog(get_class($this).": ".$error, LOG_ERR);
return -1;
}
}
diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
index 26958aed875..3fe9d63c380 100644
--- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
+++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
@@ -71,7 +71,7 @@ class InterfaceActionsAuto extends DolibarrTriggers
*/
public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
{
- if (empty($conf->agenda->enabled)) return 0; // Module not active, we do nothing
+ if (empty($conf->agenda->enabled)) return 0; // Module not active, we do nothing
$key = 'MAIN_AGENDA_ACTIONAUTO_'.$action;
@@ -82,25 +82,25 @@ class InterfaceActionsAuto extends DolibarrTriggers
$langs->load("agenda");
- if (empty($object->actiontypecode)) $object->actiontypecode='AC_OTH_AUTO';
+ if (empty($object->actiontypecode)) $object->actiontypecode = 'AC_OTH_AUTO';
// Actions
if ($action == 'COMPANY_CREATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","companies"));
+ $langs->loadLangs(array("agenda", "other", "companies"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("NewCompanyToDolibarr", $object->name);
- $object->actionmsg=$langs->transnoentities("NewCompanyToDolibarr", $object->name);
- if (! empty($object->prefix)) $object->actionmsg.=" (".$object->prefix.")";
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("NewCompanyToDolibarr", $object->name);
+ $object->actionmsg = $langs->transnoentities("NewCompanyToDolibarr", $object->name);
+ if (!empty($object->prefix)) $object->actionmsg .= " (".$object->prefix.")";
- $object->sendtoid=0;
- $object->socid=$object->id;
+ $object->sendtoid = 0;
+ $object->socid = $object->id;
}
elseif ($action == 'COMPANY_SENTBYMAIL')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","orders"));
+ $langs->loadLangs(array("agenda", "other", "orders"));
if (empty($object->actionmsg2)) dol_syslog('Trigger called with property actionmsg2 on object not defined', LOG_ERR);
@@ -110,22 +110,22 @@ class InterfaceActionsAuto extends DolibarrTriggers
elseif ($action == 'CONTRACT_VALIDATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","contracts"));
+ $langs->loadLangs(array("agenda", "other", "contracts"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ContractValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
- $object->actionmsg=$langs->transnoentities("ContractValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("ContractValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
+ $object->actionmsg = $langs->transnoentities("ContractValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'CONTRACT_SENTBYMAIL')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","contracts"));
+ $langs->loadLangs(array("agenda", "other", "contracts"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ContractSentByEMail", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("ContractSentByEMail", $object->ref);
if (empty($object->actionmsg))
{
- $object->actionmsg=$langs->transnoentities("ContractSentByEMail", $object->ref);
+ $object->actionmsg = $langs->transnoentities("ContractSentByEMail", $object->ref);
}
// Parameters $object->sendtoid defined by caller
@@ -134,22 +134,22 @@ class InterfaceActionsAuto extends DolibarrTriggers
elseif ($action == 'PROPAL_VALIDATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","propal"));
+ $langs->loadLangs(array("agenda", "other", "propal"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
- $object->actionmsg=$langs->transnoentities("PropalValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("PropalValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
+ $object->actionmsg = $langs->transnoentities("PropalValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'PROPAL_SENTBYMAIL')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","propal"));
+ $langs->loadLangs(array("agenda", "other", "propal"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProposalSentByEMail", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("ProposalSentByEMail", $object->ref);
if (empty($object->actionmsg))
{
- $object->actionmsg=$langs->transnoentities("ProposalSentByEMail", $object->ref);
+ $object->actionmsg = $langs->transnoentities("ProposalSentByEMail", $object->ref);
}
// Parameters $object->sendtoid defined by caller
@@ -158,82 +158,82 @@ class InterfaceActionsAuto extends DolibarrTriggers
elseif ($action == 'PROPAL_CLOSE_SIGNED')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","propal"));
+ $langs->loadLangs(array("agenda", "other", "propal"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalClosedSignedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("PropalClosedSignedInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("PropalClosedSignedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("PropalClosedSignedInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'PROPAL_CLASSIFY_BILLED')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","propal"));
+ $langs->loadLangs(array("agenda", "other", "propal"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalClassifiedBilledInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("PropalClassifiedBilledInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("PropalClassifiedBilledInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("PropalClassifiedBilledInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'PROPAL_CLOSE_REFUSED')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","propal"));
+ $langs->loadLangs(array("agenda", "other", "propal"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalClosedRefusedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("PropalClosedRefusedInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("PropalClosedRefusedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("PropalClosedRefusedInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'ORDER_VALIDATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","orders"));
+ $langs->loadLangs(array("agenda", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
- $object->actionmsg=$langs->transnoentities("OrderValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("OrderValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
+ $object->actionmsg = $langs->transnoentities("OrderValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'ORDER_CLOSE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","orders"));
+ $langs->loadLangs(array("agenda", "other", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderDeliveredInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("OrderDeliveredInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("OrderDeliveredInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("OrderDeliveredInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'ORDER_CLASSIFY_BILLED')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","orders"));
+ $langs->loadLangs(array("agenda", "other", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderBilledInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("OrderBilledInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("OrderBilledInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("OrderBilledInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'ORDER_CANCEL')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","orders"));
+ $langs->loadLangs(array("agenda", "other", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderCanceledInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("OrderCanceledInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("OrderCanceledInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("OrderCanceledInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'ORDER_SENTBYMAIL')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","orders"));
+ $langs->loadLangs(array("agenda", "other", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderSentByEMail", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("OrderSentByEMail", $object->ref);
if (empty($object->actionmsg))
{
- $object->actionmsg=$langs->transnoentities("OrderSentByEMail", $object->ref);
+ $object->actionmsg = $langs->transnoentities("OrderSentByEMail", $object->ref);
}
// Parameters $object->sendtoid defined by caller
@@ -242,32 +242,32 @@ class InterfaceActionsAuto extends DolibarrTriggers
elseif ($action == 'BILL_VALIDATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","bills"));
+ $langs->loadLangs(array("agenda", "other", "bills"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
- $object->actionmsg=$langs->transnoentities("InvoiceValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InvoiceValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
+ $object->actionmsg = $langs->transnoentities("InvoiceValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'BILL_UNVALIDATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","bills"));
+ $langs->loadLangs(array("agenda", "other", "bills"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceBackToDraftInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("InvoiceBackToDraftInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InvoiceBackToDraftInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("InvoiceBackToDraftInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'BILL_SENTBYMAIL')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","bills"));
+ $langs->loadLangs(array("agenda", "other", "bills"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceSentByEMail", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InvoiceSentByEMail", $object->ref);
if (empty($object->actionmsg))
{
- $object->actionmsg=$langs->transnoentities("InvoiceSentByEMail", $object->ref);
+ $object->actionmsg = $langs->transnoentities("InvoiceSentByEMail", $object->ref);
}
// Parameters $object->sendtoid defined by caller
@@ -276,69 +276,69 @@ class InterfaceActionsAuto extends DolibarrTriggers
elseif ($action == 'BILL_PAYED')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","bills"));
+ $langs->loadLangs(array("agenda", "other", "bills"));
// Values for this action can't be defined by caller.
- $object->actionmsg2=$langs->transnoentities("InvoicePaidInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("InvoicePaidInDolibarr", $object->ref);
+ $object->actionmsg2 = $langs->transnoentities("InvoicePaidInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("InvoicePaidInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'BILL_CANCEL')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","bills"));
+ $langs->loadLangs(array("agenda", "other", "bills"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceCanceledInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("InvoiceCanceledInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InvoiceCanceledInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("InvoiceCanceledInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'FICHINTER_CREATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","interventions"));
+ $langs->loadLangs(array("agenda", "other", "interventions"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionCreatedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("InterventionCreatedInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InterventionCreatedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("InterventionCreatedInDolibarr", $object->ref);
- $object->sendtoid=0;
- $object->fk_element=0;
- $object->elementtype='';
+ $object->sendtoid = 0;
+ $object->fk_element = 0;
+ $object->elementtype = '';
}
elseif ($action == 'FICHINTER_VALIDATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","interventions"));
+ $langs->loadLangs(array("agenda", "other", "interventions"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
- $object->actionmsg=$langs->transnoentities("InterventionValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InterventionValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
+ $object->actionmsg = $langs->transnoentities("InterventionValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
- $object->sendtoid=0;
- $object->fk_element=0;
- $object->elementtype='';
+ $object->sendtoid = 0;
+ $object->fk_element = 0;
+ $object->elementtype = '';
}
elseif ($action == 'FICHINTER_MODIFY')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","interventions"));
+ $langs->loadLangs(array("agenda", "other", "interventions"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionModifiedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("InterventionModifiedInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InterventionModifiedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("InterventionModifiedInDolibarr", $object->ref);
- $object->sendtoid=0;
- $object->fk_element=0;
- $object->elementtype='';
+ $object->sendtoid = 0;
+ $object->fk_element = 0;
+ $object->elementtype = '';
}
elseif ($action == 'FICHINTER_SENTBYMAIL')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","interventions"));
+ $langs->loadLangs(array("agenda", "other", "interventions"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionSentByEMail", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InterventionSentByEMail", $object->ref);
if (empty($object->actionmsg))
{
- $object->actionmsg=$langs->transnoentities("InterventionSentByEMail", $object->ref);
+ $object->actionmsg = $langs->transnoentities("InterventionSentByEMail", $object->ref);
}
// Parameters $object->sendtoid defined by caller
@@ -347,44 +347,44 @@ class InterfaceActionsAuto extends DolibarrTriggers
elseif ($action == 'FICHINTER_CLASSIFY_BILLED')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","interventions"));
+ $langs->loadLangs(array("agenda", "other", "interventions"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionClassifiedBilledInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("InterventionClassifiedBilledInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InterventionClassifiedBilledInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("InterventionClassifiedBilledInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'FICHINTER_CLASSIFY_UNBILLED')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","interventions"));
+ $langs->loadLangs(array("agenda", "other", "interventions"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionClassifiedUnbilledInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("InterventionClassifiedUnbilledInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InterventionClassifiedUnbilledInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("InterventionClassifiedUnbilledInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'FICHINTER_DELETE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","interventions"));
+ $langs->loadLangs(array("agenda", "other", "interventions"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionDeletedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("InterventionDeletedInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InterventionDeletedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("InterventionDeletedInDolibarr", $object->ref);
- $object->sendtoid=0;
- $object->fk_element=0;
- $object->elementtype='';
+ $object->sendtoid = 0;
+ $object->fk_element = 0;
+ $object->elementtype = '';
}
elseif ($action == 'SHIPPING_VALIDATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","sendings"));
+ $langs->loadLangs(array("agenda", "other", "sendings"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ShippingValidated", ($object->newref?$object->newref:$object->ref));
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("ShippingValidated", ($object->newref ? $object->newref : $object->ref));
if (empty($object->actionmsg))
{
- $object->actionmsg=$langs->transnoentities("ShippingValidated", ($object->newref?$object->newref:$object->ref));
+ $object->actionmsg = $langs->transnoentities("ShippingValidated", ($object->newref ? $object->newref : $object->ref));
}
// Parameters $object->sendtoid defined by caller
@@ -393,12 +393,12 @@ class InterfaceActionsAuto extends DolibarrTriggers
elseif ($action == 'SHIPPING_SENTBYMAIL')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","sendings"));
+ $langs->loadLangs(array("agenda", "other", "sendings"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ShippingSentByEMail", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("ShippingSentByEMail", $object->ref);
if (empty($object->actionmsg))
{
- $object->actionmsg=$langs->transnoentities("ShippingSentByEMail", $object->ref);
+ $object->actionmsg = $langs->transnoentities("ShippingSentByEMail", $object->ref);
}
// Parameters $object->sendtoid defined by caller
@@ -409,10 +409,10 @@ class InterfaceActionsAuto extends DolibarrTriggers
$langs->load("other");
$langs->load("receptions");
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ReceptionValidated", ($object->newref?$object->newref:$object->ref));
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("ReceptionValidated", ($object->newref ? $object->newref : $object->ref));
if (empty($object->actionmsg))
{
- $object->actionmsg=$langs->transnoentities("ReceptionValidated", ($object->newref?$object->newref:$object->ref));
+ $object->actionmsg = $langs->transnoentities("ReceptionValidated", ($object->newref ? $object->newref : $object->ref));
}
// Parameters $object->sendtoid defined by caller
@@ -424,10 +424,10 @@ class InterfaceActionsAuto extends DolibarrTriggers
$langs->load("other");
$langs->load("receptions");
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ReceptionSentByEMail", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("ReceptionSentByEMail", $object->ref);
if (empty($object->actionmsg))
{
- $object->actionmsg=$langs->transnoentities("ReceptionSentByEMail", $object->ref);
+ $object->actionmsg = $langs->transnoentities("ReceptionSentByEMail", $object->ref);
}
// Parameters $object->sendtoid defined by caller
@@ -436,22 +436,22 @@ class InterfaceActionsAuto extends DolibarrTriggers
elseif ($action == 'PROPOSAL_SUPPLIER_VALIDATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","propal"));
+ $langs->loadLangs(array("agenda", "other", "propal"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
- $object->actionmsg=$langs->transnoentities("PropalValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("PropalValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
+ $object->actionmsg = $langs->transnoentities("PropalValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'PROPOSAL_SUPPLIER_SENTBYMAIL')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","propal"));
+ $langs->loadLangs(array("agenda", "other", "propal"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProposalSentByEMail", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("ProposalSentByEMail", $object->ref);
if (empty($object->actionmsg))
{
- $object->actionmsg=$langs->transnoentities("ProposalSentByEMail", $object->ref);
+ $object->actionmsg = $langs->transnoentities("ProposalSentByEMail", $object->ref);
}
// Parameters $object->sendtoid defined by caller
@@ -460,92 +460,92 @@ class InterfaceActionsAuto extends DolibarrTriggers
elseif ($action == 'PROPOSAL_SUPPLIER_CLOSE_SIGNED')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","propal"));
+ $langs->loadLangs(array("agenda", "other", "propal"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalClosedSignedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("PropalClosedSignedInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("PropalClosedSignedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("PropalClosedSignedInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'PROPOSAL_SUPPLIER_CLOSE_REFUSED')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","propal"));
+ $langs->loadLangs(array("agenda", "other", "propal"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalClosedRefusedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("PropalClosedRefusedInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("PropalClosedRefusedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("PropalClosedRefusedInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'ORDER_SUPPLIER_CREATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","orders"));
+ $langs->loadLangs(array("agenda", "other", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderCreatedInDolibarr", ($object->newref?$object->newref:$object->ref));
- $object->actionmsg=$langs->transnoentities("OrderCreatedInDolibarr", ($object->newref?$object->newref:$object->ref));
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("OrderCreatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
+ $object->actionmsg = $langs->transnoentities("OrderCreatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'ORDER_SUPPLIER_VALIDATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","orders"));
+ $langs->loadLangs(array("agenda", "other", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
- $object->actionmsg=$langs->transnoentities("OrderValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("OrderValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
+ $object->actionmsg = $langs->transnoentities("OrderValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'ORDER_SUPPLIER_APPROVE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","orders"));
+ $langs->loadLangs(array("agenda", "other", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderApprovedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("OrderApprovedInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("OrderApprovedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("OrderApprovedInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'ORDER_SUPPLIER_REFUSE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","orders"));
+ $langs->loadLangs(array("agenda", "other", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderRefusedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("OrderRefusedInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("OrderRefusedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("OrderRefusedInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'ORDER_SUPPLIER_SUBMIT')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","orders"));
+ $langs->loadLangs(array("agenda", "other", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("SupplierOrderSubmitedInDolibarr", ($object->newref?$object->newref:$object->ref));
- $object->actionmsg=$langs->transnoentities("SupplierOrderSubmitedInDolibarr", ($object->newref?$object->newref:$object->ref));
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("SupplierOrderSubmitedInDolibarr", ($object->newref ? $object->newref : $object->ref));
+ $object->actionmsg = $langs->transnoentities("SupplierOrderSubmitedInDolibarr", ($object->newref ? $object->newref : $object->ref));
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'ORDER_SUPPLIER_RECEIVE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","orders"));
+ $langs->loadLangs(array("agenda", "other", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("SupplierOrderReceivedInDolibarr", ($object->newref?$object->newref:$object->ref));
- $object->actionmsg=$langs->transnoentities("SupplierOrderReceivedInDolibarr", ($object->newref?$object->newref:$object->ref));
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("SupplierOrderReceivedInDolibarr", ($object->newref ? $object->newref : $object->ref));
+ $object->actionmsg = $langs->transnoentities("SupplierOrderReceivedInDolibarr", ($object->newref ? $object->newref : $object->ref));
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'ORDER_SUPPLIER_SENTBYMAIL')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","bills","orders"));
+ $langs->loadLangs(array("agenda", "other", "bills", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("SupplierOrderSentByEMail", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("SupplierOrderSentByEMail", $object->ref);
if (empty($object->actionmsg))
{
- $object->actionmsg=$langs->transnoentities("SupplierOrderSentByEMail", $object->ref);
+ $object->actionmsg = $langs->transnoentities("SupplierOrderSentByEMail", $object->ref);
}
// Parameters $object->sendtoid defined by caller
@@ -554,45 +554,45 @@ class InterfaceActionsAuto extends DolibarrTriggers
elseif ($action == 'ORDER_SUPPLIER_CLASSIFY_BILLED')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","bills","orders"));
+ $langs->loadLangs(array("agenda", "other", "bills", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("SupplierOrderClassifiedBilled", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("SupplierOrderClassifiedBilled", $object->ref);
if (empty($object->actionmsg))
{
- $object->actionmsg=$langs->transnoentities("SupplierOrderClassifiedBilled", $object->ref);
+ $object->actionmsg = $langs->transnoentities("SupplierOrderClassifiedBilled", $object->ref);
}
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'BILL_SUPPLIER_VALIDATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","bills"));
+ $langs->loadLangs(array("agenda", "other", "bills"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
- $object->actionmsg=$langs->transnoentities("InvoiceValidatedInDolibarr", ($object->newref?$object->newref:$object->ref));
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InvoiceValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
+ $object->actionmsg = $langs->transnoentities("InvoiceValidatedInDolibarr", ($object->newref ? $object->newref : $object->ref));
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'BILL_SUPPLIER_UNVALIDATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","bills"));
+ $langs->loadLangs(array("agenda", "other", "bills"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceBackToDraftInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("InvoiceBackToDraftInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InvoiceBackToDraftInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("InvoiceBackToDraftInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'BILL_SUPPLIER_SENTBYMAIL')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","bills","orders"));
+ $langs->loadLangs(array("agenda", "other", "bills", "orders"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("SupplierInvoiceSentByEMail", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("SupplierInvoiceSentByEMail", $object->ref);
if (empty($object->actionmsg))
{
- $object->actionmsg=$langs->transnoentities("SupplierInvoiceSentByEMail", $object->ref);
+ $object->actionmsg = $langs->transnoentities("SupplierInvoiceSentByEMail", $object->ref);
}
// Parameters $object->sendtoid defined by caller
@@ -601,244 +601,244 @@ class InterfaceActionsAuto extends DolibarrTriggers
elseif ($action == 'BILL_SUPPLIER_PAYED')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","bills"));
+ $langs->loadLangs(array("agenda", "other", "bills"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoicePaidInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("InvoicePaidInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InvoicePaidInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("InvoicePaidInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'BILL_SUPPLIER_CANCELED')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","bills"));
+ $langs->loadLangs(array("agenda", "other", "bills"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceCanceledInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("InvoiceCanceledInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("InvoiceCanceledInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("InvoiceCanceledInDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
// Members
elseif ($action == 'MEMBER_VALIDATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","members"));
+ $langs->loadLangs(array("agenda", "other", "members"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberValidatedInDolibarr", $object->getFullName($langs));
- $object->actionmsg=$langs->transnoentities("MemberValidatedInDolibarr", $object->getFullName($langs));
- $object->actionmsg.="\n".$langs->transnoentities("Member").': '.$object->getFullName($langs);
- $object->actionmsg.="\n".$langs->transnoentities("Type").': '.$object->type;
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("MemberValidatedInDolibarr", $object->getFullName($langs));
+ $object->actionmsg = $langs->transnoentities("MemberValidatedInDolibarr", $object->getFullName($langs));
+ $object->actionmsg .= "\n".$langs->transnoentities("Member").': '.$object->getFullName($langs);
+ $object->actionmsg .= "\n".$langs->transnoentities("Type").': '.$object->type;
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'MEMBER_MODIFY')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","members"));
+ $langs->loadLangs(array("agenda", "other", "members"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberModifiedInDolibarr", $object->getFullName($langs));
- $object->actionmsg=$langs->transnoentities("MemberModifiedInDolibarr", $object->getFullName($langs));
- $object->actionmsg.="\n".$langs->transnoentities("Member").': '.$object->getFullName($langs);
- $object->actionmsg.="\n".$langs->transnoentities("Type").': '.$object->type;
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("MemberModifiedInDolibarr", $object->getFullName($langs));
+ $object->actionmsg = $langs->transnoentities("MemberModifiedInDolibarr", $object->getFullName($langs));
+ $object->actionmsg .= "\n".$langs->transnoentities("Member").': '.$object->getFullName($langs);
+ $object->actionmsg .= "\n".$langs->transnoentities("Type").': '.$object->type;
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'MEMBER_SUBSCRIPTION_CREATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","members"));
+ $langs->loadLangs(array("agenda", "other", "members"));
$member = $this->context['member'];
- if (! is_object($member)) // This should not happen
+ if (!is_object($member)) // This should not happen
{
include_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
$member = new Adherent($this->db);
$member->fetch($this->fk_adherent);
}
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberSubscriptionAddedInDolibarr", $object->id, $member->getFullName($langs));
- $object->actionmsg=$langs->transnoentities("MemberSubscriptionAddedInDolibarr", $object->id, $member->getFullName($langs));
- $object->actionmsg.="\n".$langs->transnoentities("Member").': '.$member->getFullName($langs);
- $object->actionmsg.="\n".$langs->transnoentities("Type").': '.$object->fk_type;
- $object->actionmsg.="\n".$langs->transnoentities("Amount").': '.$object->amount;
- $object->actionmsg.="\n".$langs->transnoentities("Period").': '.dol_print_date($object->dateh, 'day').' - '.dol_print_date($object->datef, 'day');
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("MemberSubscriptionAddedInDolibarr", $object->id, $member->getFullName($langs));
+ $object->actionmsg = $langs->transnoentities("MemberSubscriptionAddedInDolibarr", $object->id, $member->getFullName($langs));
+ $object->actionmsg .= "\n".$langs->transnoentities("Member").': '.$member->getFullName($langs);
+ $object->actionmsg .= "\n".$langs->transnoentities("Type").': '.$object->fk_type;
+ $object->actionmsg .= "\n".$langs->transnoentities("Amount").': '.$object->amount;
+ $object->actionmsg .= "\n".$langs->transnoentities("Period").': '.dol_print_date($object->dateh, 'day').' - '.dol_print_date($object->datef, 'day');
- $object->sendtoid=0;
- if ($object->fk_soc > 0) $object->socid=$object->fk_soc;
+ $object->sendtoid = 0;
+ if ($object->fk_soc > 0) $object->socid = $object->fk_soc;
}
elseif ($action == 'MEMBER_SUBSCRIPTION_MODIFY')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","members"));
+ $langs->loadLangs(array("agenda", "other", "members"));
$member = $this->context['member'];
- if (! is_object($member)) // This should not happen
+ if (!is_object($member)) // This should not happen
{
include_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
$member = new Adherent($this->db);
$member->fetch($this->fk_adherent);
}
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberSubscriptionModifiedInDolibarr", $object->id, $member->getFullName($langs));
- $object->actionmsg=$langs->transnoentities("MemberSubscriptionModifiedInDolibarr", $object->id, $member->getFullName($langs));
- $object->actionmsg.="\n".$langs->transnoentities("Member").': '.$member->getFullName($langs);
- $object->actionmsg.="\n".$langs->transnoentities("Type").': '.$object->fk_type;
- $object->actionmsg.="\n".$langs->transnoentities("Amount").': '.$object->amount;
- $object->actionmsg.="\n".$langs->transnoentities("Period").': '.dol_print_date($object->dateh, 'day').' - '.dol_print_date($object->datef, 'day');
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("MemberSubscriptionModifiedInDolibarr", $object->id, $member->getFullName($langs));
+ $object->actionmsg = $langs->transnoentities("MemberSubscriptionModifiedInDolibarr", $object->id, $member->getFullName($langs));
+ $object->actionmsg .= "\n".$langs->transnoentities("Member").': '.$member->getFullName($langs);
+ $object->actionmsg .= "\n".$langs->transnoentities("Type").': '.$object->fk_type;
+ $object->actionmsg .= "\n".$langs->transnoentities("Amount").': '.$object->amount;
+ $object->actionmsg .= "\n".$langs->transnoentities("Period").': '.dol_print_date($object->dateh, 'day').' - '.dol_print_date($object->datef, 'day');
- $object->sendtoid=0;
- if ($object->fk_soc > 0) $object->socid=$object->fk_soc;
+ $object->sendtoid = 0;
+ if ($object->fk_soc > 0) $object->socid = $object->fk_soc;
}
elseif ($action == 'MEMBER_SUBSCRIPTION_DELETE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","members"));
+ $langs->loadLangs(array("agenda", "other", "members"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberSubscriptionDeletedInDolibarr", $object->ref, $object->getFullName($langs));
- $object->actionmsg=$langs->transnoentities("MemberSubscriptionDeletedInDolibarr", $object->ref, $object->getFullName($langs));
- $object->actionmsg.="\n".$langs->transnoentities("Member").': '.$object->getFullName($langs);
- $object->actionmsg.="\n".$langs->transnoentities("Type").': '.$object->type;
- $object->actionmsg.="\n".$langs->transnoentities("Amount").': '.$object->last_subscription_amount;
- $object->actionmsg.="\n".$langs->transnoentities("Period").': '.dol_print_date($object->last_subscription_date_start, 'day').' - '.dol_print_date($object->last_subscription_date_end, 'day');
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("MemberSubscriptionDeletedInDolibarr", $object->ref, $object->getFullName($langs));
+ $object->actionmsg = $langs->transnoentities("MemberSubscriptionDeletedInDolibarr", $object->ref, $object->getFullName($langs));
+ $object->actionmsg .= "\n".$langs->transnoentities("Member").': '.$object->getFullName($langs);
+ $object->actionmsg .= "\n".$langs->transnoentities("Type").': '.$object->type;
+ $object->actionmsg .= "\n".$langs->transnoentities("Amount").': '.$object->last_subscription_amount;
+ $object->actionmsg .= "\n".$langs->transnoentities("Period").': '.dol_print_date($object->last_subscription_date_start, 'day').' - '.dol_print_date($object->last_subscription_date_end, 'day');
- $object->sendtoid=0;
- if ($object->fk_soc > 0) $object->socid=$object->fk_soc;
+ $object->sendtoid = 0;
+ if ($object->fk_soc > 0) $object->socid = $object->fk_soc;
}
elseif ($action == 'MEMBER_RESILIATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","members"));
+ $langs->loadLangs(array("agenda", "other", "members"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberResiliatedInDolibarr", $object->getFullName($langs));
- $object->actionmsg=$langs->transnoentities("MemberResiliatedInDolibarr", $object->getFullName($langs));
- $object->actionmsg.="\n".$langs->transnoentities("Member").': '.$object->getFullName($langs);
- $object->actionmsg.="\n".$langs->transnoentities("Type").': '.$object->type;
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("MemberResiliatedInDolibarr", $object->getFullName($langs));
+ $object->actionmsg = $langs->transnoentities("MemberResiliatedInDolibarr", $object->getFullName($langs));
+ $object->actionmsg .= "\n".$langs->transnoentities("Member").': '.$object->getFullName($langs);
+ $object->actionmsg .= "\n".$langs->transnoentities("Type").': '.$object->type;
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
elseif ($action == 'MEMBER_DELETE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","members"));
+ $langs->loadLangs(array("agenda", "other", "members"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberDeletedInDolibarr", $object->getFullName($langs));
- $object->actionmsg=$langs->transnoentities("MemberDeletedInDolibarr", $object->getFullName($langs));
- $object->actionmsg.="\n".$langs->transnoentities("Member").': '.$object->getFullName($langs);
- $object->actionmsg.="\n".$langs->transnoentities("Type").': '.$object->type;
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("MemberDeletedInDolibarr", $object->getFullName($langs));
+ $object->actionmsg = $langs->transnoentities("MemberDeletedInDolibarr", $object->getFullName($langs));
+ $object->actionmsg .= "\n".$langs->transnoentities("Member").': '.$object->getFullName($langs);
+ $object->actionmsg .= "\n".$langs->transnoentities("Type").': '.$object->type;
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
// Projects
elseif ($action == 'PROJECT_CREATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","projects"));
+ $langs->loadLangs(array("agenda", "other", "projects"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProjectCreatedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("ProjectCreatedInDolibarr", $object->ref);
- $object->actionmsg.="\n".$langs->transnoentities("Project").': '.$object->ref;
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("ProjectCreatedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("ProjectCreatedInDolibarr", $object->ref);
+ $object->actionmsg .= "\n".$langs->transnoentities("Project").': '.$object->ref;
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
- elseif($action == 'PROJECT_VALIDATE')
+ elseif ($action == 'PROJECT_VALIDATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","projects"));
+ $langs->loadLangs(array("agenda", "other", "projects"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProjectValidatedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("ProjectValidatedInDolibarr", $object->ref);
- $object->actionmsg.="\n".$langs->transnoentities("Project").': '.$object->ref;
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("ProjectValidatedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("ProjectValidatedInDolibarr", $object->ref);
+ $object->actionmsg .= "\n".$langs->transnoentities("Project").': '.$object->ref;
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
- elseif($action == 'PROJECT_MODIFY')
+ elseif ($action == 'PROJECT_MODIFY')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","projects"));
+ $langs->loadLangs(array("agenda", "other", "projects"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProjectModifiedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("ProjectModifiedInDolibarr", $object->ref);
- $object->actionmsg.="\n".$langs->transnoentities("Task").': '.$object->ref;
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("ProjectModifiedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("ProjectModifiedInDolibarr", $object->ref);
+ $object->actionmsg .= "\n".$langs->transnoentities("Task").': '.$object->ref;
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
// Project tasks
- elseif($action == 'TASK_CREATE')
+ elseif ($action == 'TASK_CREATE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","projects"));
+ $langs->loadLangs(array("agenda", "other", "projects"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("TaskCreatedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("TaskCreatedInDolibarr", $object->ref);
- $object->actionmsg.="\n".$langs->transnoentities("Task").': '.$object->ref;
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("TaskCreatedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("TaskCreatedInDolibarr", $object->ref);
+ $object->actionmsg .= "\n".$langs->transnoentities("Task").': '.$object->ref;
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
- elseif($action == 'TASK_MODIFY')
+ elseif ($action == 'TASK_MODIFY')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","projects"));
+ $langs->loadLangs(array("agenda", "other", "projects"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("TaskModifiedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("TaskModifieddInDolibarr", $object->ref);
- $object->actionmsg.="\n".$langs->transnoentities("Task").': '.$object->ref;
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("TaskModifiedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("TaskModifieddInDolibarr", $object->ref);
+ $object->actionmsg .= "\n".$langs->transnoentities("Task").': '.$object->ref;
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
- elseif($action == 'TASK_DELETE')
+ elseif ($action == 'TASK_DELETE')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","projects"));
+ $langs->loadLangs(array("agenda", "other", "projects"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("TaskDeletedInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("TaskDeletedInDolibarr", $object->ref);
- $object->actionmsg.="\n".$langs->transnoentities("Task").': '.$object->ref;
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("TaskDeletedInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("TaskDeletedInDolibarr", $object->ref);
+ $object->actionmsg .= "\n".$langs->transnoentities("Task").': '.$object->ref;
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
- elseif($action == 'TICKET_ASSIGNED')
+ elseif ($action == 'TICKET_ASSIGNED')
{
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other","projects"));
+ $langs->loadLangs(array("agenda", "other", "projects"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("TICKET_ASSIGNEDInDolibarr", $object->ref);
- $object->actionmsg=$langs->transnoentities("TICKET_ASSIGNEDInDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("TICKET_ASSIGNEDInDolibarr", $object->ref);
+ $object->actionmsg = $langs->transnoentities("TICKET_ASSIGNEDInDolibarr", $object->ref);
if ($object->oldcopy->fk_user_assign > 0)
{
- $tmpuser=new User($this->db);
+ $tmpuser = new User($this->db);
$tmpuser->fetch($object->oldcopy->fk_user_assign);
- $object->actionmsg.="\n".$langs->transnoentities("OldUser").': '.$tmpuser->getFullName($langs);
+ $object->actionmsg .= "\n".$langs->transnoentities("OldUser").': '.$tmpuser->getFullName($langs);
}
else
{
- $object->actionmsg.="\n".$langs->transnoentities("OldUser").': '.$langs->trans("None");
+ $object->actionmsg .= "\n".$langs->transnoentities("OldUser").': '.$langs->trans("None");
}
if ($object->fk_user_assign > 0)
{
- $tmpuser=new User($this->db);
+ $tmpuser = new User($this->db);
$tmpuser->fetch($object->fk_user_assign);
- $object->actionmsg.="\n".$langs->transnoentities("NewUser").': '.$tmpuser->getFullName($langs);
+ $object->actionmsg .= "\n".$langs->transnoentities("NewUser").': '.$tmpuser->getFullName($langs);
}
else
{
- $object->actionmsg.="\n".$langs->transnoentities("NewUser").': '.$langs->trans("None");
+ $object->actionmsg .= "\n".$langs->transnoentities("NewUser").': '.$langs->trans("None");
}
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
// TODO Merge all previous cases into this generic one
- else // $action = TICKET_CREATE, TICKET_MODIFY, TICKET_DELETE, ...
+ else // $action = BILL_DELETE, TICKET_CREATE, TICKET_MODIFY, TICKET_DELETE, ...
{
// Note: We are here only if $conf->global->MAIN_AGENDA_ACTIONAUTO_action is on (tested at begining of this function). Key can be set in agenda setup if defined into c_action_trigger
// Load translation files required by the page
- $langs->loadLangs(array("agenda","other"));
+ $langs->loadLangs(array("agenda", "other"));
- if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities($action."InDolibarr", $object->ref);
- if (empty($object->actionmsg)) $object->actionmsg=$langs->transnoentities($action."InDolibarr", $object->ref);
+ if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities($action."InDolibarr", $object->ref);
+ if (empty($object->actionmsg)) $object->actionmsg = $langs->transnoentities($action."InDolibarr", $object->ref);
- $object->sendtoid=0;
+ $object->sendtoid = 0;
}
$object->actionmsg = $langs->transnoentities("Author").': '.$user->login."\n".$object->actionmsg;
@@ -846,21 +846,21 @@ class InterfaceActionsAuto extends DolibarrTriggers
dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
// Add entry in event table
- $now=dol_now();
+ $now = dol_now();
if (isset($_SESSION['listofnames-'.$object->trackid]))
{
- $attachs=$_SESSION['listofnames-'.$object->trackid];
+ $attachs = $_SESSION['listofnames-'.$object->trackid];
if ($attachs && strpos($action, 'SENTBYMAIL'))
{
- $object->actionmsg=dol_concatdesc($object->actionmsg, "\n".$langs->transnoentities("AttachedFiles").': '.$attachs);
+ $object->actionmsg = dol_concatdesc($object->actionmsg, "\n".$langs->transnoentities("AttachedFiles").': '.$attachs);
}
}
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
- $contactforaction=new Contact($this->db);
- $societeforaction=new Societe($this->db);
+ $contactforaction = new Contact($this->db);
+ $societeforaction = new Societe($this->db);
// Set contactforaction if there is only 1 contact.
if (is_array($object->sendtoid))
{
@@ -874,7 +874,7 @@ class InterfaceActionsAuto extends DolibarrTriggers
if ($object->socid > 0) $societeforaction->fetch($object->socid);
elseif ($object->fk_soc > 0) $societeforaction->fetch($object->fk_soc);
- $projectid = isset($object->fk_project)?$object->fk_project:0;
+ $projectid = isset($object->fk_project) ? $object->fk_project : 0;
if ($object->element == 'project') $projectid = $object->id;
$elementid = $object->id;
@@ -889,20 +889,20 @@ class InterfaceActionsAuto extends DolibarrTriggers
// Insertion action
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
$actioncomm = new ActionComm($this->db);
- $actioncomm->type_code = $object->actiontypecode; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
+ $actioncomm->type_code = $object->actiontypecode; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
$actioncomm->code = 'AC_'.$action;
$actioncomm->label = $object->actionmsg2;
- $actioncomm->note_private= $object->actionmsg; // TODO Replace with ($actioncomm->email_msgid ? $object->email_content : $object->actionmsg)
+ $actioncomm->note_private = $object->actionmsg; // TODO Replace with ($actioncomm->email_msgid ? $object->email_content : $object->actionmsg)
$actioncomm->fk_project = $projectid;
$actioncomm->datep = $now;
$actioncomm->datef = $now;
$actioncomm->durationp = 0;
$actioncomm->punctual = 1;
- $actioncomm->percentage = -1; // Not applicable
+ $actioncomm->percentage = -1; // Not applicable
$actioncomm->socid = $societeforaction->id;
$actioncomm->contactid = $contactforaction->id;
- $actioncomm->authorid = $user->id; // User saving action
- $actioncomm->userownerid = $user->id; // Owner of action
+ $actioncomm->authorid = $user->id; // User saving action
+ $actioncomm->userownerid = $user->id; // Owner of action
// Fields defined when action is an email (content should be into object->actionmsg to be added into note, subject into object->actionms2 to be added into label)
$actioncomm->email_msgid = $object->email_msgid;
$actioncomm->email_from = $object->email_from;
@@ -915,28 +915,28 @@ class InterfaceActionsAuto extends DolibarrTriggers
// Object linked (if link is for thirdparty, contact, project it is a recording error. We should not have links in link table
// for such objects because there is already a dedicated field into table llx_actioncomm.
- if (! in_array($elementtype, array('societe','contact','project')))
+ if (!in_array($elementtype, array('societe', 'contact', 'project')))
{
$actioncomm->fk_element = $elementid;
$actioncomm->elementtype = $elementtype;
}
- if (property_exists($object, 'attachedfiles') && is_array($object->attachedfiles) && count($object->attachedfiles)>0) {
- $actioncomm->attachedfiles=$object->attachedfiles;
+ if (property_exists($object, 'attachedfiles') && is_array($object->attachedfiles) && count($object->attachedfiles) > 0) {
+ $actioncomm->attachedfiles = $object->attachedfiles;
}
- if (property_exists($object, 'sendtouserid') && is_array($object->sendtouserid) && count($object->sendtouserid)>0) {
- $actioncomm->userassigned=$object->sendtouserid;
+ if (property_exists($object, 'sendtouserid') && is_array($object->sendtouserid) && count($object->sendtouserid) > 0) {
+ $actioncomm->userassigned = $object->sendtouserid;
}
- $ret=$actioncomm->create($user); // User creating action
+ $ret = $actioncomm->create($user); // User creating action
if ($ret > 0 && $conf->global->MAIN_COPY_FILE_IN_EVENT_AUTO)
{
- if (is_array($object->attachedfiles) && array_key_exists('paths', $object->attachedfiles) && count($object->attachedfiles['paths'])>0) {
- foreach($object->attachedfiles['paths'] as $key=>$filespath) {
+ if (is_array($object->attachedfiles) && array_key_exists('paths', $object->attachedfiles) && count($object->attachedfiles['paths']) > 0) {
+ foreach ($object->attachedfiles['paths'] as $key=>$filespath) {
$srcfile = $filespath;
- $destdir = $conf->agenda->dir_output . '/' . $ret;
- $destfile = $destdir . '/' . $object->attachedfiles['names'][$key];
+ $destdir = $conf->agenda->dir_output.'/'.$ret;
+ $destfile = $destdir.'/'.$object->attachedfiles['names'][$key];
if (dol_mkdir($destdir) >= 0) {
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
dol_copy($srcfile, $destfile);
@@ -945,7 +945,7 @@ class InterfaceActionsAuto extends DolibarrTriggers
}
}
- unset($object->actionmsg); unset($object->actionmsg2); unset($object->actiontypecode); // When several action are called on same object, we must be sure to not reuse value of first action.
+ unset($object->actionmsg); unset($object->actionmsg2); unset($object->actiontypecode); // When several action are called on same object, we must be sure to not reuse value of first action.
if ($ret > 0)
{
@@ -954,8 +954,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
}
else
{
- $this->error="Failed to insert event : ".$actioncomm->error." ".join(',', $actioncomm->errors);
- $this->errors=$actioncomm->errors;
+ $this->error = "Failed to insert event : ".$actioncomm->error." ".join(',', $actioncomm->errors);
+ $this->errors = $actioncomm->errors;
dol_syslog("interface_modAgenda_ActionsAuto.class.php: ".$this->error, LOG_ERR);
return -1;
diff --git a/htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php b/htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php
index b50008dba2e..b51fd0a20b7 100644
--- a/htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php
+++ b/htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php
@@ -1,10 +1,11 @@
- * Copyright (C) 2009-2017 Regis Houssin
- * Copyright (C) 2011-2014 Juanjo Menent
- * Copyright (C) 2013 Cedric GROSS
- * Copyright (C) 2014 Marcos García
- * Copyright (C) 2015 Bahfir Abbes
+/*
+ * Copyright (C) 2005-2017 Laurent Destailleur
+ * Copyright (C) 2009-2017 Regis Houssin
+ * Copyright (C) 2011-2014 Juanjo Menent
+ * Copyright (C) 2013 Cedric GROSS
+ * Copyright (C) 2014 Marcos García
+ * Copyright (C) 2015 Bahfir Abbes
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,7 +14,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -21,29 +22,31 @@
*/
/**
- * \file htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php
- * \ingroup agenda
- * \brief Trigger file for company - contactroles
+ * \file htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php
+ * \ingroup agenda
+ * \brief Trigger file for company - contactroles
*/
-
require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
-
/**
- * Class of triggered functions for agenda module
+ * Class of triggered functions for agenda module
*/
class InterfaceContactRoles extends DolibarrTriggers
{
+
public $family = 'agenda';
+
public $description = "Triggers of this module auto link contact to company.";
/**
* Version of the trigger
+ *
* @var string
*/
public $version = self::VERSION_DOLIBARR;
/**
+ *
* @var string Image of the trigger
*/
public $picto = 'action';
@@ -53,56 +56,56 @@ class InterfaceContactRoles extends DolibarrTriggers
* All functions "runTrigger" are triggered if file is inside directory htdocs/core/triggers or htdocs/module/code/triggers (and declared)
*
* Following properties may be set before calling trigger. The may be completed by this trigger to be used for writing the event into database:
- * $object->socid or $object->fk_soc(id of thirdparty)
- * $object->element (element type of object)
+ * $object->socid or $object->fk_soc(id of thirdparty)
+ * $object->element (element type of object)
*
- * @param string $action Event action code
- * @param Object $object Object
- * @param User $user Object user
- * @param Translate $langs Object langs
- * @param conf $conf Object conf
- * @return int <0 if KO, 0 if no triggered ran, >0 if OK
+ * @param string $action Event action code
+ * @param Object $object Object
+ * @param User $user Object user
+ * @param Translate $langs Object langs
+ * @param conf $conf Object conf
+ * @return int <0 if KO, 0 if no triggered ran, >0 if OK
*/
public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
{
-
- if ($action === 'PROPAL_CREATE' || $action === 'ORDER_CREATE' || $action === 'BILL_CREATE' || $action === 'ORDER_SUPPLIER_CREATE' || $action === 'BILL_SUPPLIER_CREATE'
- || $action === 'CONTRACT_CREATE' || $action === 'FICHINTER_CREATE' || $action === 'PROJECT_CREATE' || $action === 'TICKET_CREATE' || $action === 'ACTION_CREATE') {
+ if ($action === 'PROPAL_CREATE' || $action === 'ORDER_CREATE' || $action === 'BILL_CREATE'
+ || $action === 'ORDER_SUPPLIER_CREATE' || $action === 'BILL_SUPPLIER_CREATE' || $action === 'PROPOSAL_SUPPLIER_CREATE'
+ || $action === 'CONTRACT_CREATE' || $action === 'FICHINTER_CREATE' || $action === 'PROJECT_CREATE' || $action === 'TICKET_CREATE') {
dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
- $socid=(property_exists($object, 'socid')?$object->socid:$object->fk_soc);
+ $socid = (property_exists($object, 'socid') ? $object->socid : $object->fk_soc);
- if (! empty($socid) && $socid > 0) {
+ if (!empty($socid) && $socid > 0) {
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
$contactdefault = new Contact($this->db);
- $contactdefault->socid=$socid;
+ $contactdefault->socid = $socid;
$TContact = $contactdefault->getContactRoles($object->element);
- $TContactAlreadyLinked = array();
- if ($object->id > 0)
- {
- $class = get_class($object);
- $cloneFrom = new $class($this->db);
- $r = $cloneFrom->fetch($object->id);
+ if (is_array($TContact) && !empty($TContact)) {
+ $TContactAlreadyLinked = array();
+ if ($object->id > 0) {
+ $cloneFrom = dol_clone($object, 1);
- if (!empty($cloneFrom->id)) $TContactAlreadyLinked = array_merge($cloneFrom->liste_contact(-1, 'external'), $cloneFrom->liste_contact(-1, 'internal'));
- }
+ if (!empty($cloneFrom->id)) {
+ $TContactAlreadyLinked = array_merge($cloneFrom->liste_contact(-1, 'external'), $cloneFrom->liste_contact(-1, 'internal'));
+ }
+ }
- if (is_array($TContact))
- {
- foreach($TContact as $i => $infos) {
+ foreach ($TContact as $i => $infos) {
foreach ($TContactAlreadyLinked as $contactData) {
- if ($contactData['id'] == $infos['fk_socpeople'] && $contactData['fk_c_type_contact'] == $infos['type_contact']) unset($TContact[$i]);
+ if ($contactData['id'] == $infos['fk_socpeople'] && $contactData['fk_c_type_contact'] == $infos['type_contact'])
+ unset($TContact[$i]);
}
}
$nb = 0;
- foreach($TContact as $infos) {
+ foreach ($TContact as $infos) {
$res = $object->add_contact($infos['fk_socpeople'], $infos['type_contact']);
- if ($res > 0) $nb++;
+ if ($res > 0)
+ $nb++;
}
- if($nb > 0) {
+ if ($nb > 0) {
setEventMessages($langs->trans('ContactAddedAutomatically', $nb), null, 'mesgs');
}
}
diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php
index 82a898a8ddf..6d7b17f7fe0 100644
--- a/htdocs/cron/class/cronjob.class.php
+++ b/htdocs/cron/class/cronjob.class.php
@@ -1094,7 +1094,7 @@ class Cronjob extends CommonObject
$errmsg = '';
if (!is_array($object->errors) || !in_array($object->error, $object->errors)) $errmsg .= $object->error;
- if (is_array($object->errors) && count($object->errors)) $errmsg .= ($errmsg ? ', '.$errmsg : '').join(', ', $object->errors);
+ if (is_array($object->errors) && count($object->errors)) $errmsg .= (($errmsg ? ', ' : '').join(', ', $object->errors));
if (empty($errmsg)) $errmsg = $langs->trans('ErrorUnknown');
dol_syslog(get_class($this)."::run_jobs END result=".$result." error=".$errmsg, LOG_ERR);
@@ -1320,9 +1320,9 @@ class Cronjob extends CommonObject
if ($processing) $moretext = ' ('.$langs->trans("Running").')';
elseif ($lastresult) $moretext .= ' ('.$langs->trans("Error").')';
- $this->labelStatus[self::STATUS_DISABLED] = $langs->trans('Draft').$moretext;
+ $this->labelStatus[self::STATUS_DISABLED] = $langs->trans('Disabled').$moretext;
$this->labelStatus[self::STATUS_ENABLED] = $langs->trans('Enabled').$moretext;
- $this->labelStatusShort[self::STATUS_DISABLED] = $langs->trans('Draft');
+ $this->labelStatusShort[self::STATUS_DISABLED] = $langs->trans('Disabled');
$this->labelStatusShort[self::STATUS_ENABLED] = $langs->trans('Enabled');
}
diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php
index ac9f178b163..0b73d95a140 100644
--- a/htdocs/cron/list.php
+++ b/htdocs/cron/list.php
@@ -47,7 +47,7 @@ $id = GETPOST('id', 'int');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/don/admin/donation.php b/htdocs/don/admin/donation.php
index 9387c1a099d..e8e7fa4f5b9 100644
--- a/htdocs/don/admin/donation.php
+++ b/htdocs/don/admin/donation.php
@@ -2,9 +2,9 @@
/* Copyright (C) 2005-2010 Laurent Destailleur
* Copyright (C) 2012-2015 Juanjo Menent
* Copyright (C) 2013-2017 Philippe Grand
- * Copyright (C) 2015-2017 Alexandre Spangaro
+ * Copyright (C) 2015-2020 Alexandre Spangaro
* Copyright (C) 2015 Benoit Bruchard
- * Copyright (C) 2019 Thibault FOUCART
+ * Copyright (C) 2019 Thibault FOUCART
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -431,13 +431,13 @@ if (preg_match('/fr/i', $conf->global->MAIN_INFO_SOCIETE_COUNTRY))
print '';
print '';
- print ''.$langs->trans("DONATION_ART885").' ';
+ print ''.$langs->trans("DONATION_ART978").' ';
print '';
if ($conf->use_javascript_ajax) {
- print ajax_constantonoff('DONATION_ART885');
+ print ajax_constantonoff('DONATION_ART978');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
- print $form->selectarray("DONATION_ART885", $arrval, $conf->global->DONATION_ART885);
+ print $form->selectarray("DONATION_ART978", $arrval, $conf->global->DONATION_ART978);
}
print ' ';
print "
\n";
diff --git a/htdocs/don/class/api_donations.class.php b/htdocs/don/class/api_donations.class.php
index 4adef57e816..95ea92f1ff3 100644
--- a/htdocs/don/class/api_donations.class.php
+++ b/htdocs/don/class/api_donations.class.php
@@ -284,10 +284,10 @@ class Donations extends DolibarrApi
*
* @url POST {id}/validate
*
- * @throws 304
- * @throws 401
- * @throws 404
- * @throws 500
+ * @throws RestException 304
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 500
*
* @return array
*/
diff --git a/htdocs/don/document.php b/htdocs/don/document.php
index 9e23fe46452..dba5b4cff7b 100644
--- a/htdocs/don/document.php
+++ b/htdocs/don/document.php
@@ -57,7 +57,7 @@ $result = restrictedArea($user, 'don', $id, '');
// Get parameters
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/don/index.php b/htdocs/don/index.php
index 6366d0fb6e6..39155dae768 100644
--- a/htdocs/don/index.php
+++ b/htdocs/don/index.php
@@ -137,10 +137,10 @@ if ($conf->use_javascript_ajax)
include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
$dolgraph = new DolGraph();
$dolgraph->SetData($dataseries);
- $dolgraph->setShowLegend(1);
+ $dolgraph->setShowLegend(2);
$dolgraph->setShowPercent(1);
$dolgraph->SetType(array('pie'));
- $dolgraph->setWidth('100%');
+ $dolgraph->setHeight('200');
$dolgraph->draw('idgraphstatus');
print $dolgraph->show($total ? 0 : 1);
@@ -159,7 +159,7 @@ $totalnb = 0;
foreach ($listofstatus as $status)
{
print '';
- print ''.$donstatic->LibStatut($status, 4).' ';
+ print ''.$donstatic->LibStatut($status, 4).' ';
print ''.(!empty($nb[$status]) ? $nb[$status] : ' ').' ';
print ''.(!empty($nb[$status]) ?price($somme[$status], 'MT') : ' ').' ';
print ''.(!empty($nb[$status]) ?price(price2num($somme[$status] / $nb[$status], 'MT')) : ' ').' ';
diff --git a/htdocs/don/list.php b/htdocs/don/list.php
index 48b5f108b81..a61a97f7c78 100644
--- a/htdocs/don/list.php
+++ b/htdocs/don/list.php
@@ -27,27 +27,27 @@
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
-if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
+if (!empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
// Load translation files required by the page
-$langs->loadLangs(array("companies","donations"));
+$langs->loadLangs(array("companies", "donations"));
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
-$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
+$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
-if (! $sortorder) $sortorder="DESC";
-if (! $sortfield) $sortfield="d.datedon";
+if (!$sortorder) $sortorder = "DESC";
+if (!$sortfield) $sortfield = "d.datedon";
-$search_status=(GETPOST("search_status", 'intcomma') != '') ? GETPOST("search_status", 'intcomma') : "-1";
-$search_all=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml'));
-$search_ref=GETPOST('search_ref', 'alpha');
-$search_company=GETPOST('search_company', 'alpha');
-$search_name=GETPOST('search_name', 'alpha');
+$search_status = (GETPOST("search_status", 'intcomma') != '') ? GETPOST("search_status", 'intcomma') : "-4";
+$search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
+$search_ref = GETPOST('search_ref', 'alpha');
+$search_company = GETPOST('search_company', 'alpha');
+$search_name = GETPOST('search_name', 'alpha');
$search_amount = GETPOST('search_amount', 'alpha');
$optioncss = GETPOST('optioncss', 'alpha');
@@ -60,6 +60,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
$search_company = "";
$search_name = "";
$search_amount = "";
+ $search_status = '';
}
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
@@ -78,26 +79,26 @@ $fieldstosearchall = array(
* View
*/
-$form=new Form($db);
-if (! empty($conf->projet->enabled)) $projectstatic=new Project($db);
+$form = new Form($db);
+if (!empty($conf->projet->enabled)) $projectstatic = new Project($db);
llxHeader('', $langs->trans("Donations"), 'EN:Module_Donations|FR:Module_Dons|ES:Módulo_Donaciones');
-$donationstatic=new Don($db);
+$donationstatic = new Don($db);
// Genere requete de liste des dons
$sql = "SELECT d.rowid, d.datedon, d.fk_soc as socid, d.firstname, d.lastname, d.societe,";
-$sql.= " d.amount, d.fk_statut as status,";
-$sql.= " p.rowid as pid, p.ref, p.title, p.public";
-$sql.= " FROM ".MAIN_DB_PREFIX."don as d LEFT JOIN ".MAIN_DB_PREFIX."projet AS p";
-$sql.= " ON p.rowid = d.fk_projet WHERE d.entity IN (".getEntity('donation').")";
-if ($search_status != '' && $search_status != '-1')
+$sql .= " d.amount, d.fk_statut as status,";
+$sql .= " p.rowid as pid, p.ref, p.title, p.public";
+$sql .= " FROM ".MAIN_DB_PREFIX."don as d LEFT JOIN ".MAIN_DB_PREFIX."projet AS p";
+$sql .= " ON p.rowid = d.fk_projet WHERE d.entity IN (".getEntity('donation').")";
+if ($search_status != '' && $search_status != '-4')
{
$sql .= " AND d.fk_statut IN (".$db->escape($search_status).")";
}
if (trim($search_ref) != '')
{
- $sql.= natural_search('d.ref', $search_ref);
+ $sql .= natural_search('d.ref', $search_ref);
}
if (trim($search_all) != '')
{
@@ -136,17 +137,17 @@ if ($resql)
$i = 0;
$param = '';
- if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss);
+ if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss);
if ($search_status && $search_status != -1) $param .= '&search_status='.urlencode($search_status);
if ($search_ref) $param .= '&search_ref='.urlencode($search_ref);
if ($search_company) $param .= '&search_company='.urlencode($search_company);
if ($search_name) $param .= '&search_name='.urlencode($search_name);
if ($search_amount) $param .= '&search_amount='.urlencode($search_amount);
- $newcardbutton='';
+ $newcardbutton = '';
if ($user->rights->don->creer)
{
- $newcardbutton.= dolGetButtonTitle($langs->trans('NewDonation'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/don/card.php?action=create');
+ $newcardbutton .= dolGetButtonTitle($langs->trans('NewDonation'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/don/card.php?action=create');
}
print ''."\n";
@@ -162,19 +163,19 @@ if ($resql)
if ($search_all)
{
- foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val);
- print ''.$langs->trans("FilterOnInto", $search_all) . join(', ', $fieldstosearchall).'
';
+ foreach ($fieldstosearchall as $key => $val) $fieldstosearchall[$key] = $langs->trans($val);
+ print ''.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
';
}
print '';
- print '
'."\n";
+ print ''."\n";
// Filters lines
print '';
print '';
print ' ';
print ' ';
- if (! empty($conf->global->DONATION_USE_THIRDPARTIES)) {
+ if (!empty($conf->global->DONATION_USE_THIRDPARTIES)) {
print '';
print ' ';
print ' ';
@@ -196,23 +197,31 @@ if ($resql)
print '';
}
print ' ';
- print ' ';
+ print '';
+ $liststatus = array(
+ Don::STATUS_DRAFT=>$langs->trans("DonationStatusPromiseNotValidated"),
+ Don::STATUS_VALIDATED=>$langs->trans("DonationStatusPromiseValidated"),
+ Don::STATUS_PAID=>$langs->trans("DonationStatusPaid"),
+ Don::STATUS_CANCELED=>$langs->trans("Canceled")
+ );
+ print $form->selectarray('search_status', $liststatus, $search_status, -4, 0, 0, '', 0, 0, 0, '', 'maxwidth100');
+ print ' ';
print '';
- $searchpicto=$form->showFilterAndCheckAddButtons(0);
+ $searchpicto = $form->showFilterAndCheckAddButtons(0);
print $searchpicto;
print ' ';
print " \n";
print '';
print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "d.rowid", "", $param, "", $sortfield, $sortorder);
- if (! empty($conf->global->DONATION_USE_THIRDPARTIES)) {
+ if (!empty($conf->global->DONATION_USE_THIRDPARTIES)) {
print_liste_field_titre("ThirdParty", $_SERVER["PHP_SELF"], "d.fk_soc", "", $param, "", $sortfield, $sortorder);
} else {
print_liste_field_titre("Company", $_SERVER["PHP_SELF"], "d.societe", "", $param, "", $sortfield, $sortorder);
}
print_liste_field_titre("Name", $_SERVER["PHP_SELF"], "d.lastname", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "d.datedon", "", $param, '', $sortfield, $sortorder, 'center ');
- if (! empty($conf->projet->enabled))
+ if (!empty($conf->projet->enabled))
{
$langs->load("projects");
print_liste_field_titre("Project", $_SERVER["PHP_SELF"], "d.fk_projet", "", $param, "", $sortfield, $sortorder);
@@ -227,15 +236,15 @@ if ($resql)
$objp = $db->fetch_object($resql);
print ' ';
- $donationstatic->id=$objp->rowid;
- $donationstatic->ref=$objp->rowid;
- $donationstatic->lastname=$objp->lastname;
- $donationstatic->firstname=$objp->firstname;
+ $donationstatic->id = $objp->rowid;
+ $donationstatic->ref = $objp->rowid;
+ $donationstatic->lastname = $objp->lastname;
+ $donationstatic->firstname = $objp->firstname;
print "".$donationstatic->getNomUrl(1)." ";
- if (! empty($conf->global->DONATION_USE_THIRDPARTIES)) {
- $company=new Societe($db);
- $result=$company->fetch($objp->socid);
- if (!empty($objp->socid) && $company->id > 0) {
+ if (!empty($conf->global->DONATION_USE_THIRDPARTIES)) {
+ $company = new Societe($db);
+ $result = $company->fetch($objp->socid);
+ if (!empty($objp->socid) && $company->id > 0) {
print "".$company->getNomUrl(1)." ";
} else {
print "".$objp->societe." ";
diff --git a/htdocs/don/payment/payment.php b/htdocs/don/payment/payment.php
index abdc35c850e..b3ab7e2d360 100644
--- a/htdocs/don/payment/payment.php
+++ b/htdocs/don/payment/payment.php
@@ -29,12 +29,12 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
$langs->load("bills");
-$chid=GETPOST("rowid");
-$action=GETPOST('action', 'aZ09');
+$chid = GETPOST("rowid");
+$action = GETPOST('action', 'aZ09');
$amounts = array();
// Security check
-$socid=0;
+$socid = 0;
if ($user->socid > 0) {
$socid = $user->socid;
}
@@ -48,7 +48,7 @@ $object = new Don($db);
if ($action == 'add_payment')
{
- $error=0;
+ $error = 0;
if ($_POST["cancel"])
{
@@ -59,7 +59,7 @@ if ($action == 'add_payment')
$datepaid = dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]);
- if (! $_POST["paymenttype"] > 0)
+ if (!$_POST["paymenttype"] > 0)
{
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("PaymentMode")), null, 'errors');
$error++;
@@ -69,13 +69,13 @@ if ($action == 'add_payment')
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Date")), null, 'errors');
$error++;
}
- if (! empty($conf->banque->enabled) && ! $_POST["accountid"] > 0)
+ if (!empty($conf->banque->enabled) && !$_POST["accountid"] > 0)
{
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AccountToCredit")), null, 'errors');
$error++;
}
- if (! $error)
+ if (!$error)
{
$paymentid = 0;
@@ -92,11 +92,11 @@ if ($action == 'add_payment')
if (count($amounts) <= 0)
{
$error++;
- $errmsg='ErrorNoPaymentDefined';
+ $errmsg = 'ErrorNoPaymentDefined';
setEventMessages($errmsg, null, 'errors');
}
- if (! $error)
+ if (!$error)
{
$db->begin();
@@ -104,34 +104,34 @@ if ($action == 'add_payment')
$payment = new PaymentDonation($db);
$payment->chid = $chid;
$payment->datepaid = $datepaid;
- $payment->amounts = $amounts; // Tableau de montant
+ $payment->amounts = $amounts; // Tableau de montant
$payment->paymenttype = GETPOST("paymenttype", 'int');
$payment->num_payment = GETPOST("num_payment", 'alphanohtml');
$payment->note_public = GETPOST("note_public", 'none');
- if (! $error)
+ if (!$error)
{
$paymentid = $payment->create($user);
if ($paymentid < 0)
{
- $errmsg=$payment->error;
+ $errmsg = $payment->error;
setEventMessages($errmsg, null, 'errors');
$error++;
}
}
- if (! $error)
+ if (!$error)
{
- $result=$payment->addPaymentToBank($user, 'payment_donation', '(DonationPayment)', $_POST['accountid'], '', '');
- if (! $result > 0)
+ $result = $payment->addPaymentToBank($user, 'payment_donation', '(DonationPayment)', $_POST['accountid'], '', '');
+ if (!$result > 0)
{
- $errmsg=$payment->error;
+ $errmsg = $payment->error;
setEventMessages($errmsg, null, 'errors');
$error++;
}
}
- if (! $error)
+ if (!$error)
{
$db->commit();
$loc = DOL_URL_ROOT.'/don/card.php?rowid='.$chid;
@@ -153,18 +153,18 @@ if ($action == 'add_payment')
* View
*/
-$form=new Form($db);
+$form = new Form($db);
llxHeader();
$sql = "SELECT sum(p.amount) as total";
-$sql.= " FROM ".MAIN_DB_PREFIX."payment_donation as p";
-$sql.= " WHERE p.fk_donation = ".$chid;
+$sql .= " FROM ".MAIN_DB_PREFIX."payment_donation as p";
+$sql .= " WHERE p.fk_donation = ".$chid;
$resql = $db->query($sql);
if ($resql)
{
- $obj=$db->fetch_object($resql);
+ $obj = $db->fetch_object($resql);
$sumpaid = $obj->total;
$db->free();
}
@@ -191,20 +191,20 @@ if ($action == 'create')
print ' '.$langs->trans("Date").' ';
$datepaid = dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]);
- $datepayment=empty($conf->global->MAIN_AUTOFILL_DATE)?(empty($_POST["remonth"])?-1:$datepaid):0;
+ $datepayment = empty($conf->global->MAIN_AUTOFILL_DATE) ? (empty($_POST["remonth"]) ?-1 : $datepaid) : 0;
print $form->selectDate($datepayment, '', 0, 0, 0, "add_payment", 1, 1, 0, '', '', $object->date, '', 1, $langs->trans("DonationDate"));
print " ";
print ' ';
print ''.$langs->trans("PaymentMode").' ';
- $form->select_types_paiements(isset($_POST["paymenttype"])?$_POST["paymenttype"]:$object->paymenttype, "paymenttype");
+ $form->select_types_paiements(GETPOSTISSET("paymenttype") ? GETPOST("paymenttype") : $object->paymenttype, "paymenttype");
print " \n";
print ' ';
print '';
print ''.$langs->trans('AccountToCredit').' ';
print '';
- $form->select_comptes(isset($_POST["accountid"])?$_POST["accountid"]:$object->accountid, "accountid", 0, '', 1); // Show open bank account list
+ $form->select_comptes(GETPOSTISSET("accountid") ? GETPOST("accountid") : $object->accountid, "accountid", 0, '', 1); // Show open bank account list
print ' ';
// Number
@@ -238,8 +238,8 @@ if ($action == 'create')
print ''.$langs->trans("Amount").' ';
print "\n";
- $total=0;
- $totalrecu=0;
+ $total = 0;
+ $totalrecu = 0;
while ($i < $num)
{
diff --git a/htdocs/ecm/dir_add_card.php b/htdocs/ecm/dir_add_card.php
index 4d04648a3d0..979d4cf2709 100644
--- a/htdocs/ecm/dir_add_card.php
+++ b/htdocs/ecm/dir_add_card.php
@@ -64,7 +64,7 @@ else // For example $module == 'medias'
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/ecm/dir_card.php b/htdocs/ecm/dir_card.php
index 45ef7370681..55aeeda5f90 100644
--- a/htdocs/ecm/dir_card.php
+++ b/htdocs/ecm/dir_card.php
@@ -44,7 +44,7 @@ if (empty($module)) $module='ecm';
// Get parameters
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/ecm/file_card.php b/htdocs/ecm/file_card.php
index 3664a2e7f28..4b2d6006c5c 100644
--- a/htdocs/ecm/file_card.php
+++ b/htdocs/ecm/file_card.php
@@ -48,7 +48,7 @@ if ($user->socid > 0)
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php
index e51efb01aaa..e88417c526a 100644
--- a/htdocs/ecm/index.php
+++ b/htdocs/ecm/index.php
@@ -47,7 +47,7 @@ $section_dir=GETPOST('section_dir', 'alpha');
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/ecm/index_auto.php b/htdocs/ecm/index_auto.php
index 2fb4e88368a..be3cc7a372c 100644
--- a/htdocs/ecm/index_auto.php
+++ b/htdocs/ecm/index_auto.php
@@ -49,7 +49,7 @@ $search_doc_ref=GETPOST('search_doc_ref', 'alpha');
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/ecm/search.php b/htdocs/ecm/search.php
index eb5eeef8c5d..c5c799d82c3 100644
--- a/htdocs/ecm/search.php
+++ b/htdocs/ecm/search.php
@@ -54,7 +54,7 @@ $upload_dir = $conf->ecm->dir_output.'/'.$section;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php
index e6968109bf7..11cf2477720 100644
--- a/htdocs/emailcollector/class/emailcollector.class.php
+++ b/htdocs/emailcollector/class/emailcollector.class.php
@@ -812,9 +812,9 @@ class EmailCollector extends CommonObject
//var_dump($tmpproperty.' - '.$regexstring.' - '.$regexoptions.' - '.$sourcestring);
if (preg_match('/'.$regexstring.'/'.$regexoptions, $sourcestring, $regforval))
{
- //var_dump($regforval[1]);exit;
+ //var_dump($regforval[count($regforval)-1]);exit;
// Overwrite param $tmpproperty
- $object->$tmpproperty = isset($regforval[1]) ?trim($regforval[1]) : null;
+ $object->$tmpproperty = isset($regforval[count($regforval) - 1]) ?trim($regforval[count($regforval) - 1]) : null;
}
else
{
@@ -1135,7 +1135,7 @@ class EmailCollector extends CommonObject
if (function_exists('imap_mime_header_decode')) {
$elements = imap_mime_header_decode($overview[0]->subject);
$newstring = '';
- if (! empty($elements)) {
+ if (!empty($elements)) {
$num = count($elements);
for ($i = 0; $i < $num; $i++) {
$newstring .= ($newstring ? ' ' : '').$elements[$i]->text;
@@ -1236,13 +1236,14 @@ class EmailCollector extends CommonObject
// References: <1542377954.SMTPs-dolibarr-tic649@8f6014fde11ec6cdec9a822234fc557e>
// References: <1542377954.SMTPs-dolibarr-abc649@8f6014fde11ec6cdec9a822234fc557e>
$trackid = '';
+ $objectid = 0;
+ $objectemail = null;
+
$reg = array();
if (!empty($headers['References']) && preg_match('/dolibarr-([a-z]+)([0-9]+)@'.preg_quote($host, '/').'/', $headers['References'], $reg))
{
$trackid = $reg[1].$reg[2];
- $objectid = 0;
- $objectemail = null;
if ($reg[1] == 'inv')
{
$objectid = $reg[2];
@@ -1423,9 +1424,9 @@ class EmailCollector extends CommonObject
//var_dump($regexstring);var_dump($sourcestring);
if (preg_match('/'.$regexstring.'/ms', $sourcestring, $regforval))
{
- //var_dump($regforval[1]);exit;
+ //var_dump($regforval[count($regforval)-1]);exit;
// Overwrite param $tmpproperty
- $nametouseforthirdparty = isset($regforval[1]) ?trim($regforval[1]) : null;
+ $nametouseforthirdparty = isset($regforval[count($regforval) - 1]) ?trim($regforval[count($regforval) - 1]) : null;
}
else
{
@@ -1793,6 +1794,39 @@ class EmailCollector extends CommonObject
}
$tickettocreate->ref = $defaultref;
}
+ // Create event specific on hook
+ // this code action is hook..... for support this call
+ elseif (substr($operation['type'], 0, 4) == 'hook') {
+ global $hookmanager;
+
+ if (!is_object($hookmanager))
+ $hookmanager->initHooks(array('emailcollectorcard'));
+
+ $parameters = array(
+ 'connection'=> $connection,
+ 'imapemail'=>$imapemail,
+ 'overview'=>$overview,
+
+ 'from' => $from,
+ 'fromtext' => $fromtext,
+
+ 'actionparam'=> $operation['actionparam'],
+
+
+
+ 'thirdpartyid' => $thirdpartyid,
+ 'objectid'=> $objectid,
+ 'objectemail'=> $objectemail,
+
+ 'messagetext'=>$messagetext,
+ 'subject'=>$subject,
+ 'header'=>$header,
+ );
+ $res = $hookmanager->executeHooks('doCollectOneCollector', $parameters, $this, $operation['type']);
+
+ if ($res < 0)
+ $this->error = $hookmanager->resPrint;
+ }
if ($errorforthisaction)
{
@@ -2013,7 +2047,7 @@ class EmailCollector extends CommonObject
// TEXT
if ($p->type == 0 && $data) {
- if(!empty($params['charset'])) {
+ if (!empty($params['charset'])) {
$data = $this->convertStringEncoding($data, $params['charset']);
}
// Messages may be split in different parts because of inline attachments,
@@ -2031,7 +2065,7 @@ class EmailCollector extends CommonObject
// There are no PHP functions to parse embedded messages,
// so this just appends the raw source to the main message.
elseif ($p->type == 2 && $data) {
- if(!empty($params['charset'])) {
+ if (!empty($params['charset'])) {
$data = $this->convertStringEncoding($data, $params['charset']);
}
$plainmsg .= $data."\n\n";
@@ -2057,14 +2091,14 @@ class EmailCollector extends CommonObject
*/
protected function convertStringEncoding($string, $fromEncoding, $toEncoding = 'UTF-8')
{
- if(!$string || $fromEncoding == $toEncoding) {
+ if (!$string || $fromEncoding == $toEncoding) {
return $string;
}
- $convertedString = function_exists('iconv') ? @iconv($fromEncoding, $toEncoding . '//IGNORE', $string) : null;
- if(!$convertedString && extension_loaded('mbstring')) {
+ $convertedString = function_exists('iconv') ? @iconv($fromEncoding, $toEncoding.'//IGNORE', $string) : null;
+ if (!$convertedString && extension_loaded('mbstring')) {
$convertedString = @mb_convert_encoding($string, $toEncoding, $fromEncoding);
}
- if(!$convertedString) {
+ if (!$convertedString) {
throw new Exception('Mime string encoding conversion failed');
}
return $convertedString;
diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php
index 66b47ab563f..b465297fe34 100644
--- a/htdocs/expedition/card.php
+++ b/htdocs/expedition/card.php
@@ -241,11 +241,11 @@ if (empty($reshook))
if ($objectsrc->lines[$i]->product_tobatch) // If product need a batch number
{
- if (isset($_POST[$batch]))
+ if (GETPOSTISSET($batch))
{
//shipment line with batch-enable product
$qty .= '_'.$j;
- while (isset($_POST[$batch]))
+ while (GETPOSTISSET($batch))
{
// save line of detail into sub_qty
$sub_qty[$j]['q'] = GETPOST($qty, 'int'); // the qty we want to move for this stock record
@@ -277,11 +277,11 @@ if (empty($reshook))
}
}
}
- elseif (isset($_POST[$stockLocation]))
+ elseif (GETPOSTISSET($stockLocation))
{
//shipment line from multiple stock locations
$qty .= '_'.$j;
- while (isset($_POST[$stockLocation]))
+ while (GETPOSTISSET($stockLocation))
{
// save sub line of warehouse
$stockLine[$i][$j]['qty'] = GETPOST($qty, 'int');
@@ -1578,7 +1578,7 @@ if ($action == 'create')
//$line->fetch_optionals($line->id);
$line->array_options = array_merge($line->array_options, $srcLine->array_options);
- print $expLine->showOptionals($extrafields, 'edit', array('style'=>'class="drag drop oddeven"', 'colspan'=>$colspan), $indiceAsked, '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1);
+ print $expLine->showOptionals($extrafields, 'edit', array('style'=>'class="drag drop oddeven"', 'colspan'=>$colspan), $indiceAsked, '', 1);
}
}
@@ -1967,7 +1967,7 @@ elseif ($id || $ref)
// Tracking Number
print ''.$form->editfieldkey("TrackingNumber", 'tracking_number', $object->tracking_number, $object, $user->rights->expedition->creer).' ';
- print $form->editfieldval("TrackingNumber", 'tracking_number', $object->tracking_url, $object, $user->rights->expedition->creer, 'string', $object->tracking_number);
+ print $form->editfieldval("TrackingNumber", 'tracking_number', $object->tracking_url, $object, $user->rights->expedition->creer, 'safehtmlstring', $object->tracking_number);
print ' ';
// Incoterms
diff --git a/htdocs/expedition/class/api_shipments.class.php b/htdocs/expedition/class/api_shipments.class.php
index 5aca14fb28d..8526f0c9610 100644
--- a/htdocs/expedition/class/api_shipments.class.php
+++ b/htdocs/expedition/class/api_shipments.class.php
@@ -373,8 +373,9 @@ class Shipments extends DolibarrApi
* @url DELETE {id}/lines/{lineid}
*
* @return int
- * @throws 401
- * @throws 404
+ *
+ * @throws RestException 401
+ * @throws RestException 404
*/
public function deleteLine($id, $lineid)
{
@@ -537,10 +538,10 @@ class Shipments extends DolibarrApi
// *
// * @return int
// *
- // * @throws 400
- // * @throws 401
- // * @throws 404
- // * @throws 405
+ // * @throws RestException 400
+ // * @throws RestException 401
+ // * @throws RestException 404
+ // * @throws RestException 405
// */
/*
public function setinvoiced($id)
@@ -574,10 +575,10 @@ class Shipments extends DolibarrApi
// * @url POST /createfromorder/{orderid}
// *
// * @return int
- // * @throws 400
- // * @throws 401
- // * @throws 404
- // * @throws 405
+ // * @throws RestException 400
+ // * @throws RestException 401
+ // * @throws RestException 404
+ // * @throws RestException 405
// */
/*
public function createShipmentFromOrder($orderid)
diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php
index bf20ac42611..52540901c33 100644
--- a/htdocs/expedition/class/expedition.class.php
+++ b/htdocs/expedition/class/expedition.class.php
@@ -85,6 +85,7 @@ class Expedition extends CommonObject
/**
* @var string internal ref
+ * @deprecated
*/
public $ref_int;
@@ -286,90 +287,90 @@ class Expedition extends CommonObject
$this->db->begin();
$sql = "INSERT INTO ".MAIN_DB_PREFIX."expedition (";
- $sql.= "ref";
- $sql.= ", entity";
- $sql.= ", ref_customer";
- $sql.= ", ref_int";
- $sql.= ", date_creation";
- $sql.= ", fk_user_author";
- $sql.= ", date_expedition";
- $sql.= ", date_delivery";
- $sql.= ", fk_soc";
- $sql.= ", fk_projet";
- $sql.= ", fk_address";
- $sql.= ", fk_shipping_method";
- $sql.= ", tracking_number";
- $sql.= ", weight";
- $sql.= ", size";
- $sql.= ", width";
- $sql.= ", height";
- $sql.= ", weight_units";
- $sql.= ", size_units";
- $sql.= ", note_private";
- $sql.= ", note_public";
- $sql.= ", model_pdf";
- $sql.= ", fk_incoterms, location_incoterms";
- $sql.= ") VALUES (";
- $sql.= "'(PROV)'";
- $sql.= ", ".$conf->entity;
- $sql.= ", ".($this->ref_customer?"'".$this->db->escape($this->ref_customer)."'":"null");
- $sql.= ", ".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null");
- $sql.= ", '".$this->db->idate($now)."'";
- $sql.= ", ".$user->id;
- $sql.= ", ".($this->date_expedition>0?"'".$this->db->idate($this->date_expedition)."'":"null");
- $sql.= ", ".($this->date_delivery>0?"'".$this->db->idate($this->date_delivery)."'":"null");
- $sql.= ", ".$this->socid;
- $sql.= ", ".$this->fk_project;
- $sql.= ", ".($this->fk_delivery_address>0?$this->fk_delivery_address:"null");
- $sql.= ", ".($this->shipping_method_id>0?$this->shipping_method_id:"null");
- $sql.= ", '".$this->db->escape($this->tracking_number)."'";
- $sql.= ", ".$this->weight;
- $sql.= ", ".$this->sizeS; // TODO Should use this->trueDepth
- $sql.= ", ".$this->sizeW; // TODO Should use this->trueWidth
- $sql.= ", ".$this->sizeH; // TODO Should use this->trueHeight
- $sql.= ", ".($this->weight_units != '' ? (int) $this->weight_units : 'NULL');
- $sql.= ", ".($this->size_units != '' ? (int) $this->size_units : 'NULL');
- $sql.= ", ".(!empty($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null");
- $sql.= ", ".(!empty($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null");
- $sql.= ", ".(!empty($this->model_pdf)?"'".$this->db->escape($this->model_pdf)."'":"null");
- $sql.= ", ".(int) $this->fk_incoterms;
- $sql.= ", '".$this->db->escape($this->location_incoterms)."'";
- $sql.= ")";
+ $sql .= "ref";
+ $sql .= ", entity";
+ $sql .= ", ref_customer";
+ $sql .= ", ref_int";
+ $sql .= ", date_creation";
+ $sql .= ", fk_user_author";
+ $sql .= ", date_expedition";
+ $sql .= ", date_delivery";
+ $sql .= ", fk_soc";
+ $sql .= ", fk_projet";
+ $sql .= ", fk_address";
+ $sql .= ", fk_shipping_method";
+ $sql .= ", tracking_number";
+ $sql .= ", weight";
+ $sql .= ", size";
+ $sql .= ", width";
+ $sql .= ", height";
+ $sql .= ", weight_units";
+ $sql .= ", size_units";
+ $sql .= ", note_private";
+ $sql .= ", note_public";
+ $sql .= ", model_pdf";
+ $sql .= ", fk_incoterms, location_incoterms";
+ $sql .= ") VALUES (";
+ $sql .= "'(PROV)'";
+ $sql .= ", ".$conf->entity;
+ $sql .= ", ".($this->ref_customer ? "'".$this->db->escape($this->ref_customer)."'" : "null");
+ $sql .= ", ".($this->ref_int ? "'".$this->db->escape($this->ref_int)."'" : "null");
+ $sql .= ", '".$this->db->idate($now)."'";
+ $sql .= ", ".$user->id;
+ $sql .= ", ".($this->date_expedition > 0 ? "'".$this->db->idate($this->date_expedition)."'" : "null");
+ $sql .= ", ".($this->date_delivery > 0 ? "'".$this->db->idate($this->date_delivery)."'" : "null");
+ $sql .= ", ".$this->socid;
+ $sql .= ", ".$this->fk_project;
+ $sql .= ", ".($this->fk_delivery_address > 0 ? $this->fk_delivery_address : "null");
+ $sql .= ", ".($this->shipping_method_id > 0 ? $this->shipping_method_id : "null");
+ $sql .= ", '".$this->db->escape($this->tracking_number)."'";
+ $sql .= ", ".$this->weight;
+ $sql .= ", ".$this->sizeS; // TODO Should use this->trueDepth
+ $sql .= ", ".$this->sizeW; // TODO Should use this->trueWidth
+ $sql .= ", ".$this->sizeH; // TODO Should use this->trueHeight
+ $sql .= ", ".($this->weight_units != '' ? (int) $this->weight_units : 'NULL');
+ $sql .= ", ".($this->size_units != '' ? (int) $this->size_units : 'NULL');
+ $sql .= ", ".(!empty($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : "null");
+ $sql .= ", ".(!empty($this->note_public) ? "'".$this->db->escape($this->note_public)."'" : "null");
+ $sql .= ", ".(!empty($this->model_pdf) ? "'".$this->db->escape($this->model_pdf)."'" : "null");
+ $sql .= ", ".(int) $this->fk_incoterms;
+ $sql .= ", '".$this->db->escape($this->location_incoterms)."'";
+ $sql .= ")";
dol_syslog(get_class($this)."::create", LOG_DEBUG);
- $resql=$this->db->query($sql);
+ $resql = $this->db->query($sql);
if ($resql)
{
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."expedition");
$sql = "UPDATE ".MAIN_DB_PREFIX."expedition";
- $sql.= " SET ref = '(PROV".$this->id.")'";
- $sql.= " WHERE rowid = ".$this->id;
+ $sql .= " SET ref = '(PROV".$this->id.")'";
+ $sql .= " WHERE rowid = ".$this->id;
dol_syslog(get_class($this)."::create", LOG_DEBUG);
if ($this->db->query($sql))
{
// Insert of lines
- $num=count($this->lines);
+ $num = count($this->lines);
for ($i = 0; $i < $num; $i++)
{
- if (! isset($this->lines[$i]->detail_batch))
+ if (!isset($this->lines[$i]->detail_batch))
{ // no batch management
- if (! $this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->rang, $this->lines[$i]->array_options) > 0)
+ if (!$this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->rang, $this->lines[$i]->array_options) > 0)
{
$error++;
}
}
else
{ // with batch management
- if (! $this->create_line_batch($this->lines[$i], $this->lines[$i]->array_options) > 0)
+ if (!$this->create_line_batch($this->lines[$i], $this->lines[$i]->array_options) > 0)
{
$error++;
}
}
}
- if (! $error && $this->id && $this->origin_id)
+ if (!$error && $this->id && $this->origin_id)
{
$ret = $this->add_object_linked();
if (!$ret)
@@ -523,35 +524,35 @@ class Expedition extends CommonObject
* @param int $id Id of object to load
* @param string $ref Ref of object
* @param string $ref_ext External reference of object
- * @param string $ref_int Internal reference of other object
+ * @param string $notused Internal reference of other object
* @return int >0 if OK, 0 if not found, <0 if KO
*/
- public function fetch($id, $ref = '', $ref_ext = '', $ref_int = '')
+ public function fetch($id, $ref = '', $ref_ext = '', $notused = '')
{
global $conf;
// Check parameters
- if (empty($id) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1;
+ if (empty($id) && empty($ref) && empty($ref_ext)) return -1;
$sql = "SELECT e.rowid, e.ref, e.fk_soc as socid, e.date_creation, e.ref_customer, e.ref_ext, e.ref_int, e.fk_user_author, e.fk_statut, e.fk_projet as fk_project, e.billed";
- $sql.= ", e.date_valid";
- $sql.= ", e.weight, e.weight_units, e.size, e.size_units, e.width, e.height";
- $sql.= ", e.date_expedition as date_expedition, e.model_pdf, e.fk_address, e.date_delivery";
- $sql.= ", e.fk_shipping_method, e.tracking_number";
- $sql.= ", e.note_private, e.note_public";
- $sql.= ', e.fk_incoterms, e.location_incoterms';
- $sql.= ', i.libelle as label_incoterms';
- $sql.= ', s.libelle as shipping_method';
- $sql.= ", el.fk_source as origin_id, el.sourcetype as origin";
- $sql.= " FROM ".MAIN_DB_PREFIX."expedition as e";
- $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = e.rowid AND el.targettype = '".$this->db->escape($this->element)."'";
- $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON e.fk_incoterms = i.rowid';
- $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_shipment_mode as s ON e.fk_shipping_method = s.rowid';
- $sql.= " WHERE e.entity IN (".getEntity('expedition').")";
- if ($id) $sql.= " AND e.rowid=".$id;
- if ($ref) $sql.= " AND e.ref='".$this->db->escape($ref)."'";
- if ($ref_ext) $sql.= " AND e.ref_ext='".$this->db->escape($ref_ext)."'";
- if ($ref_int) $sql.= " AND e.ref_int='".$this->db->escape($ref_int)."'";
+ $sql .= ", e.date_valid";
+ $sql .= ", e.weight, e.weight_units, e.size, e.size_units, e.width, e.height";
+ $sql .= ", e.date_expedition as date_expedition, e.model_pdf, e.fk_address, e.date_delivery";
+ $sql .= ", e.fk_shipping_method, e.tracking_number";
+ $sql .= ", e.note_private, e.note_public";
+ $sql .= ', e.fk_incoterms, e.location_incoterms';
+ $sql .= ', i.libelle as label_incoterms';
+ $sql .= ', s.libelle as shipping_method';
+ $sql .= ", el.fk_source as origin_id, el.sourcetype as origin";
+ $sql .= " FROM ".MAIN_DB_PREFIX."expedition as e";
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = e.rowid AND el.targettype = '".$this->db->escape($this->element)."'";
+ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON e.fk_incoterms = i.rowid';
+ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_shipment_mode as s ON e.fk_shipping_method = s.rowid';
+ $sql .= " WHERE e.entity IN (".getEntity('expedition').")";
+ if ($id) $sql .= " AND e.rowid=".$id;
+ if ($ref) $sql .= " AND e.ref='".$this->db->escape($ref)."'";
+ if ($ref_ext) $sql .= " AND e.ref_ext='".$this->db->escape($ref_ext)."'";
+ if ($notused) $sql .= " AND e.ref_int='".$this->db->escape($notused)."'";
dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
$result = $this->db->query($sql);
@@ -564,26 +565,26 @@ class Expedition extends CommonObject
$this->id = $obj->rowid;
$this->ref = $obj->ref;
$this->socid = $obj->socid;
- $this->ref_customer = $obj->ref_customer;
+ $this->ref_customer = $obj->ref_customer;
$this->ref_ext = $obj->ref_ext;
$this->ref_int = $obj->ref_int;
$this->statut = $obj->fk_statut;
$this->user_author_id = $obj->fk_user_author;
$this->date_creation = $this->db->jdate($obj->date_creation);
- $this->date_valid = $this->db->jdate($obj->date_valid);
- $this->date = $this->db->jdate($obj->date_expedition); // TODO deprecated
- $this->date_expedition = $this->db->jdate($obj->date_expedition); // TODO deprecated
- $this->date_shipping = $this->db->jdate($obj->date_expedition); // Date real
- $this->date_delivery = $this->db->jdate($obj->date_delivery); // Date planed
+ $this->date_valid = $this->db->jdate($obj->date_valid);
+ $this->date = $this->db->jdate($obj->date_expedition); // TODO deprecated
+ $this->date_expedition = $this->db->jdate($obj->date_expedition); // TODO deprecated
+ $this->date_shipping = $this->db->jdate($obj->date_expedition); // Date real
+ $this->date_delivery = $this->db->jdate($obj->date_delivery); // Date planed
$this->fk_delivery_address = $obj->fk_address;
$this->modelpdf = $obj->model_pdf;
$this->shipping_method_id = $obj->fk_shipping_method;
- $this->shipping_method = $obj->shipping_method;
+ $this->shipping_method = $obj->shipping_method;
$this->tracking_number = $obj->tracking_number;
- $this->origin = ($obj->origin?$obj->origin:'commande'); // For compatibility
+ $this->origin = ($obj->origin ? $obj->origin : 'commande'); // For compatibility
$this->origin_id = $obj->origin_id;
$this->billed = $obj->billed;
- $this->fk_project = $obj->fk_project;
+ $this->fk_project = $obj->fk_project;
$this->trueWeight = $obj->weight;
$this->weight_units = $obj->weight_units;
@@ -697,7 +698,7 @@ class Expedition extends CommonObject
{
$numref = "EXP".$this->id;
}
- $this->newref = $numref;
+ $this->newref = dol_sanitizeFileName($numref);
$now = dol_now();
@@ -762,7 +763,7 @@ class Expedition extends CommonObject
// line without batch detail
// We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record.
- $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr", $numref));
+ $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr", $numref));
if ($result < 0) {
$error++;
$this->error = $mouvS->error;
@@ -776,7 +777,7 @@ class Expedition extends CommonObject
// We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record.
// Note: ->fk_origin_stock = id into table llx_product_batch (may be rename into llx_product_stock_batch in another version)
- $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr", $numref), '', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock);
+ $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr", $numref), '', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock);
if ($result < 0) {
$error++;
$this->error = $mouvS->error;
@@ -818,17 +819,17 @@ class Expedition extends CommonObject
if (preg_match('/^[\(]?PROV/i', $this->ref))
{
// Now we rename also files into index
- $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref)+1).")), filepath = 'expedition/sending/".$this->db->escape($this->newref)."'";
- $sql.= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'expedition/sending/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
+ $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'expedition/sending/".$this->db->escape($this->newref)."'";
+ $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'expedition/sending/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
$resql = $this->db->query($sql);
- if (! $resql) { $error++; $this->error = $this->db->lasterror(); }
+ if (!$resql) { $error++; $this->error = $this->db->lasterror(); }
// We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
$oldref = dol_sanitizeFileName($this->ref);
$newref = dol_sanitizeFileName($numref);
$dirsource = $conf->expedition->dir_output.'/sending/'.$oldref;
$dirdest = $conf->expedition->dir_output.'/sending/'.$newref;
- if (! $error && file_exists($dirsource))
+ if (!$error && file_exists($dirsource))
{
dol_syslog(get_class($this)."::valid rename dir ".$dirsource." into ".$dirdest);
@@ -851,13 +852,13 @@ class Expedition extends CommonObject
}
// Set new ref and current status
- if (! $error)
+ if (!$error)
{
$this->ref = $numref;
$this->statut = self::STATUS_VALIDATED;
}
- if (! $error)
+ if (!$error)
{
$this->db->commit();
return 1;
@@ -865,7 +866,7 @@ class Expedition extends CommonObject
else
{
$this->db->rollback();
- return -1*$error;
+ return -1 * $error;
}
}
@@ -1172,32 +1173,32 @@ class Expedition extends CommonObject
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionbatch.class.php';
- $error=0;
- $this->error='';
+ $error = 0;
+ $this->error = '';
$this->db->begin();
// Add a protection to refuse deleting if shipment has at least one delivery
- $this->fetchObjectLinked($this->id, 'shipping', 0, 'delivery'); // Get deliveries linked to this shipment
+ $this->fetchObjectLinked($this->id, 'shipping', 0, 'delivery'); // Get deliveries linked to this shipment
if (count($this->linkedObjectsIds) > 0)
{
- $this->error='ErrorThereIsSomeDeliveries';
+ $this->error = 'ErrorThereIsSomeDeliveries';
$error++;
}
- if (! $error)
+ if (!$error)
{
- if (! $notrigger)
+ if (!$notrigger)
{
// Call trigger
- $result=$this->call_trigger('SHIPPING_DELETE', $user);
+ $result = $this->call_trigger('SHIPPING_DELETE', $user);
if ($result < 0) { $error++; }
// End call triggers
}
}
// Stock control
- if (! $error && $conf->stock->enabled &&
+ if (!$error && $conf->stock->enabled &&
(($conf->global->STOCK_CALCULATE_ON_SHIPMENT && $this->statut > self::STATUS_DRAFT) ||
($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE && $this->statut == self::STATUS_CLOSED && $also_update_stock)))
{
@@ -1386,20 +1387,20 @@ class Expedition extends CommonObject
// phpcs:enable
global $conf, $mysoc;
// TODO: recuperer les champs du document associe a part
- $this->lines=array();
+ $this->lines = array();
$sql = "SELECT cd.rowid, cd.fk_product, cd.label as custom_label, cd.description, cd.qty as qty_asked, cd.product_type";
- $sql.= ", cd.total_ht, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.total_tva";
- $sql.= ", cd.vat_src_code, cd.tva_tx, cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.info_bits, cd.price, cd.subprice, cd.remise_percent,cd.buy_price_ht as pa_ht";
- $sql.= ", cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc, cd.rang";
- $sql.= ", ed.rowid as line_id, ed.qty as qty_shipped, ed.fk_origin_line, ed.fk_entrepot";
- $sql.= ", p.ref as product_ref, p.label as product_label, p.fk_product_type";
- $sql.= ", p.weight, p.weight_units, p.length, p.length_units, p.surface, p.surface_units, p.volume, p.volume_units, p.tobatch as product_tobatch";
- $sql.= " FROM ".MAIN_DB_PREFIX."expeditiondet as ed, ".MAIN_DB_PREFIX."commandedet as cd";
- $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = cd.fk_product";
- $sql.= " WHERE ed.fk_expedition = ".$this->id;
- $sql.= " AND ed.fk_origin_line = cd.rowid";
- $sql.= " ORDER BY cd.rang, ed.fk_origin_line";
+ $sql .= ", cd.total_ht, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.total_tva";
+ $sql .= ", cd.vat_src_code, cd.tva_tx, cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.info_bits, cd.price, cd.subprice, cd.remise_percent,cd.buy_price_ht as pa_ht";
+ $sql .= ", cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc, cd.rang";
+ $sql .= ", ed.rowid as line_id, ed.qty as qty_shipped, ed.fk_origin_line, ed.fk_entrepot";
+ $sql .= ", p.ref as product_ref, p.label as product_label, p.fk_product_type";
+ $sql .= ", p.weight, p.weight_units, p.length, p.length_units, p.surface, p.surface_units, p.volume, p.volume_units, p.tobatch as product_tobatch";
+ $sql .= " FROM ".MAIN_DB_PREFIX."expeditiondet as ed, ".MAIN_DB_PREFIX."commandedet as cd";
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = cd.fk_product";
+ $sql .= " WHERE ed.fk_expedition = ".$this->id;
+ $sql .= " AND ed.fk_origin_line = cd.rowid";
+ $sql .= " ORDER BY cd.rang, ed.fk_origin_line";
dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG);
$resql = $this->db->query($sql);
@@ -1460,7 +1461,7 @@ class Expedition extends CommonObject
$line->label = $obj->custom_label;
$line->description = $obj->description;
$line->qty_asked = $obj->qty_asked;
- $line->rang = $obj->rang;
+ $line->rang = $obj->rang;
$line->weight = $obj->weight;
$line->weight_units = $obj->weight_units;
$line->length = $obj->length;
@@ -1749,23 +1750,23 @@ class Expedition extends CommonObject
$this->origin_id = 1;
$this->origin = 'commande';
- $this->note_private = 'Private note';
- $this->note_public = 'Public note';
+ $this->note_private = 'Private note';
+ $this->note_public = 'Public note';
$nbp = 5;
$xnbp = 0;
while ($xnbp < $nbp)
{
- $line=new ExpeditionLigne($this->db);
- $line->desc=$langs->trans("Description")." ".$xnbp;
- $line->libelle=$langs->trans("Description")." ".$xnbp; // deprecated
- $line->label=$langs->trans("Description")." ".$xnbp;
- $line->qty=10;
- $line->qty_asked=5;
- $line->qty_shipped=4;
- $line->fk_product=$this->commande->lines[$xnbp]->fk_product;
+ $line = new ExpeditionLigne($this->db);
+ $line->desc = $langs->trans("Description")." ".$xnbp;
+ $line->libelle = $langs->trans("Description")." ".$xnbp; // deprecated
+ $line->label = $langs->trans("Description")." ".$xnbp;
+ $line->qty = 10;
+ $line->qty_asked = 5;
+ $line->qty_shipped = 4;
+ $line->fk_product = $this->commande->lines[$xnbp]->fk_product;
- $this->lines[]=$line;
+ $this->lines[] = $line;
$xnbp++;
}
}
@@ -1819,17 +1820,17 @@ class Expedition extends CommonObject
$this->meths = array();
$sql = "SELECT em.rowid, em.code, em.libelle as label";
- $sql.= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as em";
- $sql.= " WHERE em.active = 1";
- $sql.= " ORDER BY em.libelle ASC";
+ $sql .= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as em";
+ $sql .= " WHERE em.active = 1";
+ $sql .= " ORDER BY em.libelle ASC";
$resql = $this->db->query($sql);
if ($resql)
{
while ($obj = $this->db->fetch_object($resql))
{
- $label=$langs->trans('SendingMethod'.$obj->code);
- $this->meths[$obj->rowid] = ($label != 'SendingMethod'.$obj->code?$label:$obj->label);
+ $label = $langs->trans('SendingMethod'.$obj->code);
+ $this->meths[$obj->rowid] = ($label != 'SendingMethod'.$obj->code ? $label : $obj->label);
}
}
}
@@ -1847,11 +1848,11 @@ class Expedition extends CommonObject
global $langs;
$this->listmeths = array();
- $i=0;
+ $i = 0;
$sql = "SELECT em.rowid, em.code, em.libelle as label, em.description, em.tracking, em.active";
- $sql.= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as em";
- if ($id!='') $sql.= " WHERE em.rowid=".$id;
+ $sql .= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as em";
+ if ($id != '') $sql .= " WHERE em.rowid=".$id;
$resql = $this->db->query($sql);
if ($resql)
@@ -1860,8 +1861,8 @@ class Expedition extends CommonObject
{
$this->listmeths[$i]['rowid'] = $obj->rowid;
$this->listmeths[$i]['code'] = $obj->code;
- $label=$langs->trans('SendingMethod'.$obj->code);
- $this->listmeths[$i]['libelle'] = ($label != 'SendingMethod'.$obj->code?$label:$obj->label);
+ $label = $langs->trans('SendingMethod'.$obj->code);
+ $this->listmeths[$i]['libelle'] = ($label != 'SendingMethod'.$obj->code ? $label : $obj->label);
$this->listmeths[$i]['description'] = $obj->description;
$this->listmeths[$i]['tracking'] = $obj->tracking;
$this->listmeths[$i]['active'] = $obj->active;
@@ -2315,16 +2316,16 @@ class Expedition extends CommonObject
*/
public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
{
- global $conf,$langs;
+ global $conf, $langs;
$langs->load("sendings");
- if (! dol_strlen($modele)) {
+ if (!dol_strlen($modele)) {
$modele = 'rouget';
if ($this->modelpdf) {
$modele = $this->modelpdf;
- } elseif (! empty($conf->global->EXPEDITION_ADDON_PDF)) {
+ } elseif (!empty($conf->global->EXPEDITION_ADDON_PDF)) {
$modele = $conf->global->EXPEDITION_ADDON_PDF;
}
}
@@ -2566,10 +2567,10 @@ class ExpeditionLigne extends CommonObjectLine
{
global $langs, $conf;
- $error=0;
+ $error = 0;
// Check parameters
- if (empty($this->fk_expedition) || empty($this->fk_origin_line) || ! is_numeric($this->qty))
+ if (empty($this->fk_expedition) || empty($this->fk_origin_line) || !is_numeric($this->qty))
{
$this->error = 'ErrorMandatoryParametersNotProvided';
return -1;
@@ -2588,18 +2589,18 @@ class ExpeditionLigne extends CommonObjectLine
}
$sql = "INSERT INTO ".MAIN_DB_PREFIX."expeditiondet (";
- $sql.= "fk_expedition";
- $sql.= ", fk_entrepot";
- $sql.= ", fk_origin_line";
- $sql.= ", qty";
- $sql.= ", rang";
- $sql.= ") VALUES (";
- $sql.= $this->fk_expedition;
- $sql.= ", ".(empty($this->entrepot_id) ? 'NULL' : $this->entrepot_id);
- $sql.= ", ".$this->fk_origin_line;
- $sql.= ", ".$this->qty;
- $sql.= ", ".$ranktouse;
- $sql.= ")";
+ $sql .= "fk_expedition";
+ $sql .= ", fk_entrepot";
+ $sql .= ", fk_origin_line";
+ $sql .= ", qty";
+ $sql .= ", rang";
+ $sql .= ") VALUES (";
+ $sql .= $this->fk_expedition;
+ $sql .= ", ".(empty($this->entrepot_id) ? 'NULL' : $this->entrepot_id);
+ $sql .= ", ".$this->fk_origin_line;
+ $sql .= ", ".$this->qty;
+ $sql .= ", ".$ranktouse;
+ $sql .= ")";
dol_syslog(get_class($this)."::insert", LOG_DEBUG);
$resql = $this->db->query($sql);
diff --git a/htdocs/expedition/document.php b/htdocs/expedition/document.php
index ab83142cc4b..65786dfbdae 100644
--- a/htdocs/expedition/document.php
+++ b/htdocs/expedition/document.php
@@ -55,7 +55,7 @@ $result = restrictedArea($user, 'expedition', $id, '');
// Get parameters
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php
index f7ff3565e10..5122ac5897e 100644
--- a/htdocs/expedition/list.php
+++ b/htdocs/expedition/list.php
@@ -69,7 +69,7 @@ $optioncss = GETPOST('optioncss', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (!$sortfield) $sortfield = "e.ref";
if (!$sortorder) $sortorder = "DESC";
if (empty($page) || $page == -1 || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1
diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php
index 60e5eafcb48..770d39ec951 100644
--- a/htdocs/expensereport/class/api_expensereports.class.php
+++ b/htdocs/expensereport/class/api_expensereports.class.php
@@ -33,7 +33,7 @@ class ExpenseReports extends DolibarrApi
* @var array $FIELDS Mandatory fields, checked when create and update object
*/
static $FIELDS = array(
- 'socid'
+ 'fk_user_author'
);
/**
@@ -384,6 +384,10 @@ class ExpenseReports extends DolibarrApi
* @param array $request_data Datas
*
* @return int
+ *
+ * @throws RestException 401 Not allowed
+ * @throws RestException 404 Expense report not found
+ * @throws RestException 500
*/
public function put($id, $request_data = null)
{
@@ -501,6 +505,11 @@ class ExpenseReports extends DolibarrApi
// phpcs:enable
$object = parent::_cleanObjectDatas($object);
+ unset($object->fk_statut);
+ unset($object->statut);
+ unset($object->user);
+ unset($object->thirdparty);
+
unset($object->cond_reglement);
unset($object->shipping_method_id);
@@ -509,6 +518,32 @@ class ExpenseReports extends DolibarrApi
unset($object->barcode_type_label);
unset($object->barcode_type_coder);
+ unset($object->code_paiement);
+ unset($object->code_statut);
+ unset($object->fk_c_paiement);
+ unset($object->fk_incoterms);
+ unset($object->label_incoterms);
+ unset($object->location_incoterms);
+ unset($object->mode_reglement_id);
+ unset($object->cond_reglement_id);
+
+ unset($object->name);
+ unset($object->lastname);
+ unset($object->firstname);
+ unset($object->civility_id);
+ unset($object->cond_reglement_id);
+ unset($object->contact);
+ unset($object->contact_id);
+
+ unset($object->state);
+ unset($object->state_id);
+ unset($object->state_code);
+ unset($object->country);
+ unset($object->country_id);
+ unset($object->country_code);
+
+ unset($object->note); // We already use note_public and note_pricate
+
return $object;
}
diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php
index 05272aa2ff7..d78ac9e6261 100644
--- a/htdocs/expensereport/class/expensereport.class.php
+++ b/htdocs/expensereport/class/expensereport.class.php
@@ -58,19 +58,20 @@ class ExpenseReport extends CommonObject
public $date_fin;
+ /**
+ * 0=draft, 2=validated (attente approb), 4=canceled, 5=approved, 6=payed, 99=denied
+ *
+ * @var int Status
+ */
public $status;
- public $fk_statut; // -- 0=draft, 2=validated (attente approb), 4=canceled, 5=approved, 6=payed, 99=denied
+ public $fk_statut;
+
public $fk_c_paiement;
public $paid;
public $user_author_infos;
public $user_validator_infos;
- public $fk_typepayment;
- public $num_payment;
- public $code_paiement;
- public $code_statut;
-
// ACTIONS
// Create
@@ -285,10 +286,33 @@ class ExpenseReport extends CommonObject
{
if (is_array($this->lines) && count($this->lines) > 0)
{
- foreach ($this->lines as $i => $val)
+ foreach ($this->lines as $line)
{
+ // Test and convert into object this->lines[$i]. When coming from REST API, we may still have an array
+ //if (! is_object($line)) $line=json_decode(json_encode($line), false); // convert recursively array into object.
+ if (!is_object($line)) {
+ $line = (object) $line;
+ $newndfline = new ExpenseReportLine($this->db);
+ $newndfline->fk_expensereport = $line->fk_expensereport;
+ $newndfline->fk_c_type_fees = $line->fk_c_type_fees;
+ $newndfline->fk_project = $line->fk_project;
+ $newndfline->vatrate = $line->vatrate;
+ $newndfline->vat_src_code = $line->vat_src_code;
+ $newndfline->comments = $line->comments;
+ $newndfline->qty = $line->qty;
+ $newndfline->value_unit = $line->value_unit;
+ $newndfline->total_ht = $line->total_ht;
+ $newndfline->total_ttc = $line->total_ttc;
+ $newndfline->total_tva = $line->total_tva;
+ $newndfline->date = $line->date;
+ $newndfline->rule_warning_message = $line->rule_warning_message;
+ $newndfline->fk_c_exp_tax_cat = $line->fk_c_exp_tax_cat;
+ $newndfline->fk_ecm_files = $line->fk_ecm_files;
+ }
+ else {
+ $newndfline = $line;
+ }
//$newndfline=new ExpenseReportLine($this->db);
- $newndfline = $this->lines[$i];
$newndfline->fk_expensereport = $this->id;
$result = $newndfline->insert();
if ($result < 0)
@@ -514,10 +538,8 @@ class ExpenseReport extends CommonObject
$sql .= " d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,"; // DATES (datetime)
$sql .= " d.fk_user_author, d.fk_user_modif, d.fk_user_validator,";
$sql .= " d.fk_user_valid, d.fk_user_approve,";
- $sql .= " d.fk_statut as status, d.fk_c_paiement, d.paid,";
- $sql .= " dp.libelle as label_payment, dp.code as code_paiement"; // INNER JOIN paiement
+ $sql .= " d.fk_statut as status, d.fk_c_paiement, d.paid";
$sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as d";
- $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as dp ON d.fk_c_paiement = dp.id";
if ($ref) $sql .= " WHERE d.ref = '".$this->db->escape($ref)."'";
else $sql .= " WHERE d.rowid = ".$id;
//$sql.= $restrict;
@@ -566,7 +588,7 @@ class ExpenseReport extends CommonObject
elseif ($this->fk_user_validator > 0) $user_approver->fetch($this->fk_user_validator); // For backward compatibility
$this->user_validator_infos = dolGetFirstLastname($user_approver->firstname, $user_approver->lastname);
- $this->fk_statut = $obj->status;
+ $this->fk_statut = $obj->status; // deprecated
$this->status = $obj->status;
$this->fk_c_paiement = $obj->fk_c_paiement;
$this->paid = $obj->paid;
@@ -578,9 +600,6 @@ class ExpenseReport extends CommonObject
$this->user_valid_infos = dolGetFirstLastname($user_valid->firstname, $user_valid->lastname);
}
- $this->code_statut = $obj->code_statut;
- $this->code_paiement = $obj->code_paiement;
-
$this->lines = array();
$result = $this->fetch_lines();
@@ -996,7 +1015,9 @@ class ExpenseReport extends CommonObject
public function fetch_lines()
{
// phpcs:enable
- $this->lines = array();
+ global $conf;
+
+ $this->lines = array();
$sql = ' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
$sql .= ' de.'.$this->fk_element.', de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project, de.tva_tx, de.fk_ecm_files,';
@@ -1144,7 +1165,7 @@ class ExpenseReport extends CommonObject
}
if (empty($num) || $num < 0) return -1;
- $this->newref = $num;
+ $this->newref = dol_sanitizeFileName($num);
$this->db->begin();
@@ -1486,7 +1507,7 @@ class ExpenseReport extends CommonObject
{
// phpcs:enable
$error = 0;
- $this->date_cancel = $this->db->idate(gmmktime());
+ $this->date_cancel = $this->db->idate(dol_now());
if ($this->fk_statut != self::STATUS_CANCELED)
{
$this->db->begin();
@@ -2650,7 +2671,7 @@ class ExpenseReportLine
$sql .= " ".$this->db->escape($this->total_ht).",";
$sql .= " ".$this->db->escape($this->total_tva).",";
$sql .= " ".$this->db->escape($this->total_ttc).",";
- $sql .= "'".$this->db->idate($this->date)."',";
+ $sql .= " '".$this->db->idate($this->date)."',";
$sql .= " '".$this->db->escape($this->rule_warning_message)."',";
$sql .= " ".$this->db->escape($this->fk_c_exp_tax_cat).",";
$sql .= " ".($this->fk_ecm_files > 0 ? $this->fk_ecm_files : 'null');
diff --git a/htdocs/expensereport/class/expensereport_ik.class.php b/htdocs/expensereport/class/expensereport_ik.class.php
index bac8522ca74..c7bf959e27e 100644
--- a/htdocs/expensereport/class/expensereport_ik.class.php
+++ b/htdocs/expensereport/class/expensereport_ik.class.php
@@ -32,17 +32,17 @@ class ExpenseReportIk extends CoreObject
/**
* @var string ID to identify managed object
*/
- public $element='expenseik';
+ public $element = 'expenseik';
/**
* @var string Name of table without prefix where object is stored
*/
- public $table_element='expensereport_ik';
+ public $table_element = 'expensereport_ik';
/**
* @var int Field with ID of parent key if this field has a parent
*/
- public $fk_element='fk_expense_ik';
+ public $fk_element = 'fk_expense_ik';
/**
* c_exp_tax_cat Id
@@ -72,10 +72,10 @@ class ExpenseReportIk extends CoreObject
* Attribute object linked with database
* @var array
*/
- protected $fields=array(
- 'rowid'=>array('type'=>'integer','index'=>true)
- ,'fk_c_exp_tax_cat'=>array('type'=>'integer','index'=>true)
- ,'fk_range'=>array('type'=>'integer','index'=>true)
+ public $fields = array(
+ 'rowid'=>array('type'=>'integer', 'index'=>true)
+ ,'fk_c_exp_tax_cat'=>array('type'=>'integer', 'index'=>true)
+ ,'fk_range'=>array('type'=>'integer', 'index'=>true)
,'coef'=>array('type'=>'double')
,'ikoffset'=>array('type'=>'double')
);
@@ -109,10 +109,10 @@ class ExpenseReportIk extends CoreObject
$categories = array();
$sql = 'SELECT rowid, label, entity, active';
- $sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_cat';
- $sql.= ' WHERE entity IN ('. getEntity('c_exp_tax_cat').')';
- if ($mode == 1) $sql.= ' AND active = 1';
- elseif ($mode == 2) $sql.= 'AND active = 0';
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_cat';
+ $sql .= ' WHERE entity IN ('.getEntity('c_exp_tax_cat').')';
+ if ($mode == 1) $sql .= ' AND active = 1';
+ elseif ($mode == 2) $sql .= 'AND active = 0';
dol_syslog(get_called_class().'::getTaxCategories sql='.$sql, LOG_DEBUG);
$resql = $db->query($sql);
@@ -144,8 +144,8 @@ class ExpenseReportIk extends CoreObject
$ranges = self::getRangesByCategory($fk_c_exp_tax_cat);
// substract 1 because array start from 0
- if (empty($ranges) || !isset($ranges[$default_range-1])) return false;
- else return $ranges[$default_range-1];
+ if (empty($ranges) || !isset($ranges[$default_range - 1])) return false;
+ else return $ranges[$default_range - 1];
}
/**
@@ -162,10 +162,10 @@ class ExpenseReportIk extends CoreObject
$ranges = array();
$sql = 'SELECT r.rowid FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r';
- if ($active) $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_c_exp_tax_cat = c.rowid)';
- $sql.= ' WHERE r.fk_c_exp_tax_cat = '.$fk_c_exp_tax_cat;
- if ($active) $sql.= ' AND r.active = 1 AND c.active = 1';
- $sql.= ' ORDER BY r.range_ik';
+ if ($active) $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_c_exp_tax_cat = c.rowid)';
+ $sql .= ' WHERE r.fk_c_exp_tax_cat = '.$fk_c_exp_tax_cat;
+ if ($active) $sql .= ' AND r.active = 1 AND c.active = 1';
+ $sql .= ' ORDER BY r.range_ik';
dol_syslog(get_called_class().'::getRangesByCategory sql='.$sql, LOG_DEBUG);
$resql = $db->query($sql);
@@ -203,11 +203,11 @@ class ExpenseReportIk extends CoreObject
$ranges = array();
$sql = ' SELECT r.rowid, r.fk_c_exp_tax_cat, r.range_ik, c.label, i.rowid as fk_expense_ik, r.active as range_active, c.active as cat_active';
- $sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r';
- $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_c_exp_tax_cat = c.rowid)';
- $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'expensereport_ik i ON (r.rowid = i.fk_range)';
- $sql.= ' WHERE r.entity IN (0, '. getEntity('').')';
- $sql.= ' ORDER BY r.fk_c_exp_tax_cat, r.range_ik';
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r';
+ $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_c_exp_tax_cat = c.rowid)';
+ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'expensereport_ik i ON (r.rowid = i.fk_range)';
+ $sql .= ' WHERE r.entity IN (0, '.getEntity('').')';
+ $sql .= ' ORDER BY r.fk_c_exp_tax_cat, r.range_ik';
dol_syslog(get_called_class().'::getAllRanges sql='.$sql, LOG_DEBUG);
$resql = $db->query($sql);
@@ -239,14 +239,14 @@ class ExpenseReportIk extends CoreObject
*/
public static function getMaxRangeNumber($default_c_exp_tax_cat = 0)
{
- global $db,$conf;
+ global $db, $conf;
$sql = 'SELECT MAX(counted) as nbRange FROM (';
- $sql.= ' SELECT COUNT(*) as counted';
- $sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r';
- $sql.= ' WHERE r.entity IN (0, '.$conf->entity.')';
+ $sql .= ' SELECT COUNT(*) as counted';
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r';
+ $sql .= ' WHERE r.entity IN (0, '.$conf->entity.')';
if ($default_c_exp_tax_cat > 0) $sql .= ' AND r.fk_c_exp_tax_cat = '.$default_c_exp_tax_cat;
- $sql.= ' GROUP BY r.fk_c_exp_tax_cat';
+ $sql .= ' GROUP BY r.fk_c_exp_tax_cat';
$sql .= ') as counts';
dol_syslog(get_called_class().'::getMaxRangeNumber sql='.$sql, LOG_DEBUG);
diff --git a/htdocs/expensereport/class/expensereport_rule.class.php b/htdocs/expensereport/class/expensereport_rule.class.php
index 9726184a94a..b98552f681d 100644
--- a/htdocs/expensereport/class/expensereport_rule.class.php
+++ b/htdocs/expensereport/class/expensereport_rule.class.php
@@ -32,17 +32,17 @@ class ExpenseReportRule extends CoreObject
/**
* @var string ID to identify managed object
*/
- public $element='expenserule';
+ public $element = 'expenserule';
/**
* @var string Name of table without prefix where object is stored
*/
- public $table_element='expensereport_rules';
+ public $table_element = 'expensereport_rules';
/**
* @var int Field with ID of parent key if this field has a parent
*/
- public $fk_element='fk_expense_rule';
+ public $fk_element = 'fk_expense_rule';
/**
* date start
@@ -111,8 +111,8 @@ class ExpenseReportRule extends CoreObject
* Attribute object linked with database
* @var array
*/
- protected $fields=array(
- 'rowid'=>array('type'=>'integer','index'=>true)
+ public $fields = array(
+ 'rowid'=>array('type'=>'integer', 'index'=>true)
,'dates'=>array('type'=>'date')
,'datee'=>array('type'=>'date')
,'amount'=>array('type'=>'double')
@@ -154,25 +154,25 @@ class ExpenseReportRule extends CoreObject
$rules = array();
$sql = 'SELECT er.rowid';
- $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_rules er';
- $sql.= ' WHERE er.entity IN (0,'. getEntity('').')';
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'expensereport_rules er';
+ $sql .= ' WHERE er.entity IN (0,'.getEntity('').')';
if (!empty($fk_c_type_fees))
{
- $sql.= ' AND er.fk_c_type_fees IN (-1, '.$fk_c_type_fees.')';
+ $sql .= ' AND er.fk_c_type_fees IN (-1, '.$fk_c_type_fees.')';
}
if (!empty($date))
{
$date = dol_print_date($date, '%Y-%m-%d');
- $sql.= ' AND er.dates <= \''.$date.'\'';
- $sql.= ' AND er.datee >= \''.$date.'\'';
+ $sql .= ' AND er.dates <= \''.$date.'\'';
+ $sql .= ' AND er.datee >= \''.$date.'\'';
}
if ($fk_user > 0)
{
- $sql.= ' AND (er.is_for_all = 1';
- $sql.= ' OR er.fk_user = '.$fk_user;
- $sql.= ' OR er.fk_usergroup IN (SELECT ugu.fk_usergroup FROM '.MAIN_DB_PREFIX.'usergroup_user ugu WHERE ugu.fk_user = '.$fk_user.') )';
+ $sql .= ' AND (er.is_for_all = 1';
+ $sql .= ' OR er.fk_user = '.$fk_user;
+ $sql .= ' OR er.fk_usergroup IN (SELECT ugu.fk_usergroup FROM '.MAIN_DB_PREFIX.'usergroup_user ugu WHERE ugu.fk_user = '.$fk_user.') )';
}
- $sql.= ' ORDER BY er.is_for_all, er.fk_usergroup, er.fk_user';
+ $sql .= ' ORDER BY er.is_for_all, er.fk_usergroup, er.fk_user';
dol_syslog("ExpenseReportRule::getAllRule sql=".$sql);
diff --git a/htdocs/expensereport/document.php b/htdocs/expensereport/document.php
index 48461eec8bf..25018653acb 100644
--- a/htdocs/expensereport/document.php
+++ b/htdocs/expensereport/document.php
@@ -50,7 +50,7 @@ $result = restrictedArea($user, 'expensereport', $id, 'expensereport');
// Get parameters
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php
index ec6f78d91f7..945c2387dc5 100644
--- a/htdocs/expensereport/index.php
+++ b/htdocs/expensereport/index.php
@@ -47,7 +47,7 @@ $result = restrictedArea($user, 'expensereport', '', '');
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
@@ -136,10 +136,10 @@ if ($conf->use_javascript_ajax)
$dolgraph->SetData($dataseries);
$dolgraph->setHeight(350);
$dolgraph->combine = empty($conf->global->MAIN_EXPENSEREPORT_COMBINE_GRAPH_STAT) ? 0.05 : $conf->global->MAIN_EXPENSEREPORT_COMBINE_GRAPH_STAT;
- $dolgraph->setShowLegend(1);
+ $dolgraph->setShowLegend(2);
$dolgraph->setShowPercent(1);
$dolgraph->SetType(array('pie'));
- $dolgraph->setWidth('100%');
+ $dolgraph->setHeight('200');
$dolgraph->draw('idgraphstatus');
print $dolgraph->show($totalnb ? 0 : 1);
diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php
index 5604ee77dc3..7689c5e172f 100644
--- a/htdocs/expensereport/list.php
+++ b/htdocs/expensereport/list.php
@@ -76,7 +76,7 @@ $diroutputmassaction = $conf->expensereport->dir_output.'/temp/massgeneration/'.
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/expensereport/payment/payment.php b/htdocs/expensereport/payment/payment.php
index 2f915b3f8e8..872bd5a0792 100644
--- a/htdocs/expensereport/payment/payment.php
+++ b/htdocs/expensereport/payment/payment.php
@@ -31,14 +31,14 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
// Load translation files required by the page
$langs->loadLangs(array('bills', 'banks', 'trips'));
-$id=GETPOST("id", 'int');
-$ref=GETPOST('ref', 'alpha');
-$action=GETPOST('action', 'aZ09');
+$id = GETPOST("id", 'int');
+$ref = GETPOST('ref', 'alpha');
+$action = GETPOST('action', 'aZ09');
$amounts = array();
-$accountid=GETPOST('accountid', 'int');
+$accountid = GETPOST('accountid', 'int');
// Security check
-$socid=0;
+$socid = 0;
if ($user->socid > 0)
{
$socid = $user->socid;
@@ -51,7 +51,7 @@ if ($user->socid > 0)
if ($action == 'add_payment')
{
- $error=0;
+ $error = 0;
if ($_POST["cancel"])
{
@@ -62,7 +62,7 @@ if ($action == 'add_payment')
$expensereport = new ExpenseReport($db);
$result = $expensereport->fetch($id, $ref);
- if (! $result)
+ if (!$result)
{
$error++;
setEventMessages($expensereport->error, $expensereport->errors, 'errors');
@@ -70,7 +70,7 @@ if ($action == 'add_payment')
$datepaid = dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]);
- if (! ($_POST["fk_typepayment"] > 0))
+ if (!($_POST["fk_typepayment"] > 0))
{
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("PaymentMode")), null, 'errors');
$error++;
@@ -80,13 +80,13 @@ if ($action == 'add_payment')
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Date")), null, 'errors');
$error++;
}
- if (! empty($conf->banque->enabled) && ! ($accountid > 0))
+ if (!empty($conf->banque->enabled) && !($accountid > 0))
{
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AccountToDebit")), null, 'errors');
$error++;
}
- if (! $error)
+ if (!$error)
{
$paymentid = 0;
$total = 0;
@@ -104,10 +104,10 @@ if ($action == 'add_payment')
if (count($amounts) <= 0)
{
$error++;
- $errmsg='ErrorNoPaymentDefined';
+ $errmsg = 'ErrorNoPaymentDefined';
}
- if (! $error)
+ if (!$error)
{
$db->begin();
@@ -115,13 +115,13 @@ if ($action == 'add_payment')
$payment = new PaymentExpenseReport($db);
$payment->fk_expensereport = $expensereport->id;
$payment->datepaid = $datepaid;
- $payment->amounts = $amounts; // Tableau de montant
+ $payment->amounts = $amounts; // Tableau de montant
$payment->total = $total;
$payment->fk_typepayment = GETPOST("fk_typepayment", 'int');
$payment->num_payment = GETPOST("num_payment", 'alphanothtml');
$payment->note_public = GETPOST("note_public", 'none');
- if (! $error)
+ if (!$error)
{
$paymentid = $payment->create($user);
if ($paymentid < 0)
@@ -131,10 +131,10 @@ if ($action == 'add_payment')
}
}
- if (! $error)
+ if (!$error)
{
- $result=$payment->addPaymentToBank($user, 'payment_expensereport', '(ExpenseReportPayment)', $accountid, '', '');
- if (! $result > 0)
+ $result = $payment->addPaymentToBank($user, 'payment_expensereport', '(ExpenseReportPayment)', $accountid, '', '');
+ if (!$result > 0)
{
setEventMessages($payment->error, $payment->errors, 'errors');
$error++;
@@ -152,7 +152,7 @@ if ($action == 'add_payment')
}
}
- if (! $error)
+ if (!$error)
{
$db->commit();
$loc = DOL_URL_ROOT.'/expensereport/card.php?id='.$id;
@@ -166,7 +166,7 @@ if ($action == 'add_payment')
}
}
- $action='create';
+ $action = 'create';
}
@@ -176,7 +176,7 @@ if ($action == 'add_payment')
llxHeader();
-$form=new Form($db);
+$form = new Form($db);
// Form to create expense report payment
@@ -188,7 +188,7 @@ if ($action == 'create' || empty($action))
$total = $expensereport->total_ttc;
// autofill remainder amount
- if (! empty($conf->use_javascript_ajax)) {
+ if (!empty($conf->use_javascript_ajax)) {
print "\n".'';
}
- print ' '.$langs->trans("AddThirdParty").' ';
+ print ' ';
}
print '';
@@ -1661,8 +1661,8 @@ if ($action == 'create')
$langs->load('projects');
print ''.$langs->trans('Project').' ';
- $formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1);
- print ' id).'">'.$langs->trans("AddProject").' ';
+ $formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth500');
+ print ' id).'"> ';
print ' ';
}
diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php
index eb9093888af..dd55bb36ffb 100644
--- a/htdocs/fourn/commande/dispatch.php
+++ b/htdocs/fourn/commande/dispatch.php
@@ -273,7 +273,7 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner)
if (empty($conf->multicurrency->enabled) && empty($conf->dynamicprices->enabled)) {
$dto = GETPOST("dto_".$reg[1].'_'.$reg[2]);
//update supplier price
- if (isset($_POST[$saveprice])) {
+ if (GETPOSTISSET($saveprice)) {
// TODO Use class
$sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price";
$sql .= " SET unitprice='".GETPOST($pu)."'";
diff --git a/htdocs/fourn/commande/document.php b/htdocs/fourn/commande/document.php
index 203ee0be5df..0d8924b8fc5 100644
--- a/htdocs/fourn/commande/document.php
+++ b/htdocs/fourn/commande/document.php
@@ -53,7 +53,7 @@ $result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'com
// Get parameters
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/fourn/commande/index.php b/htdocs/fourn/commande/index.php
index b09b67ba1d3..25c4868fd5e 100644
--- a/htdocs/fourn/commande/index.php
+++ b/htdocs/fourn/commande/index.php
@@ -137,10 +137,10 @@ if ($resql)
include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
$dolgraph = new DolGraph();
$dolgraph->SetData($dataseries);
- $dolgraph->setShowLegend(1);
+ $dolgraph->setShowLegend(2);
$dolgraph->setShowPercent(1);
$dolgraph->SetType(array('pie'));
- $dolgraph->setWidth('100%');
+ $dolgraph->setHeight('200');
$dolgraph->draw('idgraphstatus');
print $dolgraph->show($total ? 0 : 1);
@@ -159,17 +159,14 @@ else
/*
* Legends / Status
- *
- * Motivo: Mostrar todos os Status e dar a possibilidade de filtrar apenas um deles
- * Reason: Show all Status and give the possibility to filter only one
*/
-$sql = "SELECT count(cf.rowid), fk_statut";
+$sql = "SELECT count(cf.rowid) as nb, cf.fk_statut";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
$sql .= ", ".MAIN_DB_PREFIX."commande_fournisseur as cf";
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql .= " WHERE cf.fk_soc = s.rowid";
-$sql .= " AND s.entity = ".$conf->entity;
+$sql .= " AND cf.entity IN (".getEntity("supplier_order").")"; // Thirdparty sharing is mandatory with supplier order sharing
if ($user->socid) $sql .= ' AND cf.fk_soc = '.$user->socid;
if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
$sql .= " GROUP BY cf.fk_statut";
@@ -189,11 +186,11 @@ if ($resql)
while ($i < $num)
{
- $row = $db->fetch_row($resql);
+ $obj = $db->fetch_object($resql);
print '';
- print ''.$commandestatic->LibStatut($row[1]).' ';
- print ''.$row[0].' '.$commandestatic->LibStatut($row[1], 3).' ';
+ print ''.$commandestatic->LibStatut($obj->nb).' ';
+ print ''.$obj->nb.' '.$commandestatic->LibStatut($obj->fk_statut, 3).' ';
print " \n";
$i++;
@@ -218,7 +215,7 @@ if (!empty($conf->fournisseur->enabled))
$sql .= ", ".MAIN_DB_PREFIX."societe as s";
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql .= " WHERE c.fk_soc = s.rowid";
- $sql .= " AND c.entity = ".$conf->entity;
+ $sql .= " AND c.entity IN (".getEntity("supplier_order").")"; // Thirdparty sharing is mandatory with supplier order sharing
$sql .= " AND c.fk_statut = 0";
if (!empty($socid)) $sql .= " AND c.fk_soc = ".$socid;
if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
@@ -254,17 +251,25 @@ if (!empty($conf->fournisseur->enabled))
/*
* List of users allowed
*/
-$sql = "SELECT u.rowid, u.lastname, u.firstname, u.email";
-$sql .= " FROM ".MAIN_DB_PREFIX."user as u,";
-$sql .= " ".MAIN_DB_PREFIX."user_rights as ur";
-$sql .= ", ".MAIN_DB_PREFIX."rights_def as rd";
-$sql .= " WHERE u.rowid = ur.fk_user";
-$sql .= " AND (u.entity IN (0,".$conf->entity.")";
-$sql .= " AND rd.entity = ".$conf->entity.")";
-$sql .= " AND ur.fk_id = rd.id";
-$sql .= " AND module = 'fournisseur'";
-$sql .= " AND perms = 'commande'";
-$sql .= " AND subperms = 'approuver'";
+
+$sql = "SELECT";
+if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
+ $sql .= " DISTINCT";
+}
+$sql .= " u.rowid, u.lastname, u.firstname, u.email, u.statut";
+$sql .= " FROM ".MAIN_DB_PREFIX."user as u";
+if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
+{
+ $sql .= ",".MAIN_DB_PREFIX."usergroup_user as ug";
+ $sql .= " WHERE ((ug.fk_user = u.rowid";
+ $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
+ $sql .= " OR u.entity = 0)"; // Show always superadmin
+}
+else
+{
+ $sql .= " WHERE (u.entity IN (".getEntity('user').")";
+}
+$sql .= " AND u.fk_soc IS NULL"; // An external user can not approved
$resql = $db->query($sql);
if ($resql)
@@ -281,15 +286,23 @@ if ($resql)
{
$obj = $db->fetch_object($resql);
- print '';
- print '';
+ $userstatic = new User($db);
$userstatic->id = $obj->rowid;
- $userstatic->lastname = $obj->lastname;
- $userstatic->firstname = $obj->firstname;
- $userstatic->email = $obj->email;
- print $userstatic->getNomUrl(1);
- print ' ';
- print " \n";
+ $userstatic->getrights('fournisseur');
+
+ if (!empty($userstatic->rights->fournisseur->commande->approuver))
+ {
+ print '';
+ print '';
+ $userstatic->lastname = $obj->lastname;
+ $userstatic->firstname = $obj->firstname;
+ $userstatic->email = $obj->email;
+ $userstatic->statut = $obj->statut;
+ print $userstatic->getNomUrl(1);
+ print ' ';
+ print " \n";
+ }
+
$i++;
}
print "
";
diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php
index 71881d34103..d7836d47d86 100644
--- a/htdocs/fourn/commande/list.php
+++ b/htdocs/fourn/commande/list.php
@@ -80,6 +80,11 @@ $search_sale = GETPOST('search_sale', 'int');
$search_total_ht = GETPOST('search_total_ht', 'alpha');
$search_total_vat = GETPOST('search_total_vat', 'alpha');
$search_total_ttc = GETPOST('search_total_ttc', 'alpha');
+$search_multicurrency_code = GETPOST('search_multicurrency_code', 'alpha');
+$search_multicurrency_tx = GETPOST('search_multicurrency_tx', 'alpha');
+$search_multicurrency_montant_ht = GETPOST('search_multicurrency_montant_ht', 'alpha');
+$search_multicurrency_montant_vat = GETPOST('search_multicurrency_montant_vat', 'alpha');
+$search_multicurrency_montant_ttc = GETPOST('search_multicurrency_montant_ttc', 'alpha');
$optioncss = GETPOST('optioncss', 'alpha');
$search_billed = GETPOST('search_billed', 'int');
$search_project_ref = GETPOST('search_project_ref', 'alpha');
@@ -99,7 +104,7 @@ $diroutputmassaction = $conf->fournisseur->commande->dir_output.'/temp/massgener
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1 || !empty($search_btn) || !empty($search_remove_btn) || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
@@ -146,6 +151,11 @@ $arrayfields = array(
'cf.total_ht'=>array('label'=>$langs->trans("AmountHT"), 'checked'=>1),
'cf.total_vat'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>0),
'cf.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>0),
+ 'cf.multicurrency_code'=>array('label'=>'Currency', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'cf.multicurrency_tx'=>array('label'=>'CurrencyRate', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'cf.multicurrency_total_ht'=>array('label'=>'MulticurrencyAmountHT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'cf.multicurrency_total_vat'=>array('label'=>'MulticurrencyAmountVAT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'cf.multicurrency_total_ttc'=>array('label'=>'MulticurrencyAmountTTC', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
'cf.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
'cf.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
'cf.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
@@ -201,6 +211,11 @@ if (empty($reshook))
$search_total_ht = '';
$search_total_vat = '';
$search_total_ttc = '';
+ $search_multicurrency_code = '';
+ $search_multicurrency_tx = '';
+ $search_multicurrency_montant_ht = '';
+ $search_multicurrency_montant_vat = '';
+ $search_multicurrency_montant_ttc = '';
$search_project_ref = '';
$search_status = -1;
$search_orderyear = '';
@@ -421,14 +436,14 @@ if (empty($reshook))
// Fac builddoc
$donotredirect = 1;
$upload_dir = $conf->facture->dir_output;
- $permissiontoadd=$user->rights->facture->creer;
+ $permissiontoadd = $user->rights->facture->creer;
include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
}
$massaction = $action = 'confirm_createbills';
}
- if (! $error)
+ if (!$error)
{
$db->commit();
setEventMessages($langs->trans('BillCreated', $nb_bills_created), null, 'mesgs');
@@ -485,6 +500,7 @@ $sql .= ' s.rowid as socid, s.nom as name, s.town, s.zip, s.fk_pays, s.client, s
$sql .= " typent.code as typent_code,";
$sql .= " state.code_departement as state_code, state.nom as state_name,";
$sql .= " cf.rowid, cf.ref, cf.ref_supplier, cf.fk_statut, cf.billed, cf.total_ht, cf.tva as total_tva, cf.total_ttc, cf.fk_user_author, cf.date_commande as date_commande, cf.date_livraison as date_delivery,";
+$sql .= ' cf.fk_multicurrency, cf.multicurrency_code, cf.multicurrency_tx, cf.multicurrency_total_ht, cf.multicurrency_total_tva as multicurrency_total_vat, cf.multicurrency_total_ttc,';
$sql .= ' cf.date_creation as date_creation, cf.tms as date_update,';
$sql .= ' cf.note_public, cf.note_private,';
$sql .= " p.rowid as project_id, p.ref as project_ref, p.title as project_title,";
@@ -543,6 +559,11 @@ if ($search_user > 0) $sql .= " AND ec.fk_c_type_contact = tc.rowid AND tc.eleme
if ($search_total_ht != '') $sql .= natural_search('cf.total_ht', $search_total_ht, 1);
if ($search_total_vat != '') $sql .= natural_search('cf.tva', $search_total_vat, 1);
if ($search_total_ttc != '') $sql .= natural_search('cf.total_ttc', $search_total_ttc, 1);
+if ($search_multicurrency_code != '') $sql .= ' AND cf.multicurrency_code = "'.$db->escape($search_multicurrency_code).'"';
+if ($search_multicurrency_tx != '') $sql .= natural_search('cf.multicurrency_tx', $search_multicurrency_tx, 1);
+if ($search_multicurrency_montant_ht != '') $sql .= natural_search('cf.multicurrency_total_ht', $search_multicurrency_montant_ht, 1);
+if ($search_multicurrency_montant_vat != '') $sql .= natural_search('cf.multicurrency_total_tva', $search_multicurrency_montant_vat, 1);
+if ($search_multicurrency_montant_ttc != '') $sql .= natural_search('cf.multicurrency_total_ttc', $search_multicurrency_montant_ttc, 1);
if ($search_project_ref != '') $sql .= natural_search("p.ref", $search_project_ref);
// Add where from extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
@@ -613,6 +634,11 @@ if ($resql)
if ($search_sale > 0) $param .= '&search_sale='.$search_sale;
if ($search_total_ht != '') $param .= '&search_total_ht='.$search_total_ht;
if ($search_total_ttc != '') $param .= "&search_total_ttc=".$search_total_ttc;
+ if ($search_multicurrency_code != '') $param .= '&search_multicurrency_code='.urlencode($search_multicurrency_code);
+ if ($search_multicurrency_tx != '') $param .= '&search_multicurrency_tx='.urlencode($search_multicurrency_tx);
+ if ($search_multicurrency_montant_ht != '') $param .= '&search_multicurrency_montant_ht='.urlencode($search_multicurrency_montant_ht);
+ if ($search_multicurrency_montant_vat != '') $param .= '&search_multicurrency_montant_vat='.urlencode($search_multicurrency_montant_vat);
+ if ($search_multicurrency_montant_ttc != '') $param .= '&search_multicurrency_montant_ttc='.urlencode($search_multicurrency_montant_ttc);
if ($search_refsupp) $param .= "&search_refsupp=".$search_refsupp;
if ($search_status >= 0) $param .= "&search_status=".$search_status;
if ($search_project_ref >= 0) $param .= "&search_project_ref=".$search_project_ref;
@@ -844,6 +870,41 @@ if ($resql)
print ' ';
print '';
}
+ if (!empty($arrayfields['cf.multicurrency_code']['checked']))
+ {
+ // Currency
+ print '';
+ print $form->selectMultiCurrency($search_multicurrency_code, 'search_multicurrency_code', 1);
+ print ' ';
+ }
+ if (!empty($arrayfields['cf.multicurrency_tx']['checked']))
+ {
+ // Currency rate
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['cf.multicurrency_total_ht']['checked']))
+ {
+ // Amount
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['cf.multicurrency_total_vat']['checked']))
+ {
+ // Amount
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['cf.multicurrency_total_ttc']['checked']))
+ {
+ // Amount
+ print '';
+ print ' ';
+ print ' ';
+ }
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
@@ -902,6 +963,11 @@ if ($resql)
if (!empty($arrayfields['cf.total_ht']['checked'])) print_liste_field_titre($arrayfields['cf.total_ht']['label'], $_SERVER["PHP_SELF"], "cf.total_ht", "", $param, '', $sortfield, $sortorder, 'right ');
if (!empty($arrayfields['cf.total_vat']['checked'])) print_liste_field_titre($arrayfields['cf.total_vat']['label'], $_SERVER["PHP_SELF"], "cf.tva", "", $param, '', $sortfield, $sortorder, 'right ');
if (!empty($arrayfields['cf.total_ttc']['checked'])) print_liste_field_titre($arrayfields['cf.total_ttc']['label'], $_SERVER["PHP_SELF"], "cf.total_ttc", "", $param, '', $sortfield, $sortorder, 'right ');
+ if (!empty($arrayfields['cf.multicurrency_code']['checked'])) print_liste_field_titre($arrayfields['cf.multicurrency_code']['label'], $_SERVER['PHP_SELF'], 'cf.multicurrency_code', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['cf.multicurrency_tx']['checked'])) print_liste_field_titre($arrayfields['cf.multicurrency_tx']['label'], $_SERVER['PHP_SELF'], 'cf.multicurrency_tx', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['cf.multicurrency_total_ht']['checked'])) print_liste_field_titre($arrayfields['cf.multicurrency_total_ht']['label'], $_SERVER['PHP_SELF'], 'cf.multicurrency_total_ht', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['cf.multicurrency_total_vat']['checked'])) print_liste_field_titre($arrayfields['cf.multicurrency_total_vat']['label'], $_SERVER['PHP_SELF'], 'cf.multicurrency_total_tva', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['cf.multicurrency_total_ttc']['checked'])) print_liste_field_titre($arrayfields['cf.multicurrency_total_ttc']['label'], $_SERVER['PHP_SELF'], 'cf.multicurrency_total_ttc', '', $param, 'class="right"', $sortfield, $sortorder);
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
// Hook fields
@@ -998,139 +1064,173 @@ if ($resql)
$thirdpartytmp->email = $obj->email;
print $thirdpartytmp->getNomUrl(1, 'supplier');
print ''."\n";
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Town
- if (! empty($arrayfields['s.town']['checked']))
+ if (!empty($arrayfields['s.town']['checked']))
{
print '';
print $obj->town;
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Zip
- if (! empty($arrayfields['s.zip']['checked']))
+ if (!empty($arrayfields['s.zip']['checked']))
{
print '';
print $obj->zip;
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// State
- if (! empty($arrayfields['state.nom']['checked']))
+ if (!empty($arrayfields['state.nom']['checked']))
{
print "".$obj->state_name." \n";
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Country
- if (! empty($arrayfields['country.code_iso']['checked']))
+ if (!empty($arrayfields['country.code_iso']['checked']))
{
print '';
- $tmparray=getCountry($obj->fk_pays, 'all');
+ $tmparray = getCountry($obj->fk_pays, 'all');
print $tmparray['label'];
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Type ent
- if (! empty($arrayfields['typent.code']['checked']))
+ if (!empty($arrayfields['typent.code']['checked']))
{
print '';
- if (count($typenArray)==0) $typenArray = $formcompany->typent_array(1);
+ if (count($typenArray) == 0) $typenArray = $formcompany->typent_array(1);
print $typenArray[$obj->typent_code];
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Order date
- if (! empty($arrayfields['cf.date_commande']['checked']))
+ if (!empty($arrayfields['cf.date_commande']['checked']))
{
print '';
if ($obj->date_commande) print dol_print_date($db->jdate($obj->date_commande), 'day');
else print '';
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Plannned date of delivery
- if (! empty($arrayfields['cf.date_delivery']['checked']))
+ if (!empty($arrayfields['cf.date_delivery']['checked']))
{
print '';
print dol_print_date($db->jdate($obj->date_delivery), 'day');
- if ($objectstatic->hasDelay() && ! empty($objectstatic->date_delivery)) {
+ if ($objectstatic->hasDelay() && !empty($objectstatic->date_delivery)) {
print ' '.img_picto($langs->trans("Late").' : '.$objectstatic->showDelay(), "warning");
}
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Amount HT
- if (! empty($arrayfields['cf.total_ht']['checked']))
+ if (!empty($arrayfields['cf.total_ht']['checked']))
{
print ''.price($obj->total_ht)." \n";
- if (! $i) $totalarray['nbfield']++;
- if (! $i) $totalarray['pos'][$totalarray['nbfield']]='cf.total_ht';
+ if (!$i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'cf.total_ht';
$totalarray['val']['cf.total_ht'] += $obj->total_ht;
}
// Amount VAT
- if (! empty($arrayfields['cf.total_vat']['checked']))
+ if (!empty($arrayfields['cf.total_vat']['checked']))
{
print ''.price($obj->total_tva)." \n";
- if (! $i) $totalarray['nbfield']++;
- if (! $i) $totalarray['pos'][$totalarray['nbfield']]='cf.total_vat';
+ if (!$i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'cf.total_vat';
$totalarray['val']['cf.total_vat'] += $obj->total_tva;
}
// Amount TTC
- if (! empty($arrayfields['cf.total_ttc']['checked']))
+ if (!empty($arrayfields['cf.total_ttc']['checked']))
{
print ''.price($obj->total_ttc)." \n";
- if (! $i) $totalarray['nbfield']++;
- if (! $i) $totalarray['pos'][$totalarray['nbfield']]='cf.total_ttc';
+ if (!$i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'cf.total_ttc';
$totalarray['val']['cf.total_ttc'] += $obj->total_ttc;
}
+ // Currency
+ if (!empty($arrayfields['cf.multicurrency_code']['checked']))
+ {
+ print ''.$obj->multicurrency_code.' - '.$langs->trans('Currency'.$obj->multicurrency_code)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+
+ // Currency rate
+ if (!empty($arrayfields['cf.multicurrency_tx']['checked']))
+ {
+ print '';
+ $form->form_multicurrency_rate($_SERVER['PHP_SELF'].'?id='.$obj->rowid, $obj->multicurrency_tx, 'none', $obj->multicurrency_code);
+ print " \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount HT
+ if (!empty($arrayfields['cf.multicurrency_total_ht']['checked']))
+ {
+ print ''.price($obj->multicurrency_total_ht)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount VAT
+ if (!empty($arrayfields['cf.multicurrency_total_vat']['checked']))
+ {
+ print ''.price($obj->multicurrency_total_vat)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount TTC
+ if (!empty($arrayfields['cf.multicurrency_total_ttc']['checked']))
+ {
+ print ''.price($obj->multicurrency_total_ttc)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
// Fields from hook
- $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
- $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook
+ $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
+ $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
// Date creation
- if (! empty($arrayfields['cf.datec']['checked']))
+ if (!empty($arrayfields['cf.datec']['checked']))
{
print '';
print dol_print_date($db->jdate($obj->date_creation), 'dayhour', 'tzuser');
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Date modification
- if (! empty($arrayfields['cf.tms']['checked']))
+ if (!empty($arrayfields['cf.tms']['checked']))
{
print '';
print dol_print_date($db->jdate($obj->date_update), 'dayhour', 'tzuser');
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Status
- if (! empty($arrayfields['cf.fk_statut']['checked']))
+ if (!empty($arrayfields['cf.fk_statut']['checked']))
{
print ''.$objectstatic->LibStatut($obj->fk_statut, 5, $obj->billed).' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Billed
- if (! empty($arrayfields['cf.billed']['checked']))
+ if (!empty($arrayfields['cf.billed']['checked']))
{
print ''.yn($obj->billed).' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Action column
print '';
if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
{
- $selected=0;
- if (in_array($obj->rowid, $arrayofselected)) $selected=1;
- print ' ';
+ $selected = 0;
+ if (in_array($obj->rowid, $arrayofselected)) $selected = 1;
+ print ' ';
}
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
print "\n";
$i++;
diff --git a/htdocs/fourn/contact.php b/htdocs/fourn/contact.php
index 35d21ab04f3..06e7f09edd7 100644
--- a/htdocs/fourn/contact.php
+++ b/htdocs/fourn/contact.php
@@ -43,7 +43,7 @@ if ($user->socid > 0)
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php
index ffdfb07baa0..329ee266362 100644
--- a/htdocs/fourn/facture/card.php
+++ b/htdocs/fourn/facture/card.php
@@ -657,7 +657,7 @@ if (empty($reshook))
$_GET['socid'] = $_POST['socid'];
$error++;
}
- if (!($_POST['fac_replacement'] > 0)) {
+ if (! (GETPOST('fac_replacement', 'int') > 0)) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ReplaceInvoice")), null, 'errors');
}
@@ -870,7 +870,7 @@ if (empty($reshook))
if (!$error && $_POST['origin'] && $_POST['originid'])
{
// Parse element/subelement (ex: project_task)
- $element = $subelement = GETPOST('origin');
+ $element = $subelement = GETPOST('origin', 'alpha');
/*if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs))
{
$element = $regs[1];
@@ -894,8 +894,8 @@ if (empty($reshook))
{
$element = 'projet';
}
- $object->origin = GETPOST('origin');
- $object->origin_id = GETPOST('originid');
+ $object->origin = GETPOST('origin', 'alpha');
+ $object->origin_id = GETPOST('originid', 'int');
require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php';
@@ -917,6 +917,10 @@ if (empty($reshook))
}
}
}
+ elseif (!empty($object->origin) && !empty($object->origin_id))
+ {
+ $object->linkedObjectsIds[$object->origin] = $object->origin_id;
+ }
$id = $object->create($user);
@@ -1803,7 +1807,7 @@ if ($action == 'create')
});
';
}
- print ' '.$langs->trans("AddThirdParty").' ';
+ print ' ';
}
print '';
diff --git a/htdocs/fourn/facture/document.php b/htdocs/fourn/facture/document.php
index 2c409b08ea7..3a05c0bed97 100644
--- a/htdocs/fourn/facture/document.php
+++ b/htdocs/fourn/facture/document.php
@@ -52,7 +52,7 @@ $result = restrictedArea($user, 'fournisseur', $id, 'facture_fourn', 'facture');
// Get parameters
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/fourn/facture/impayees.php b/htdocs/fourn/facture/impayees.php
index 4d6e85006c3..cdcdcff23c3 100644
--- a/htdocs/fourn/facture/impayees.php
+++ b/htdocs/fourn/facture/impayees.php
@@ -54,7 +54,7 @@ $search_company = GETPOST('search_company', 'alpha');
$search_amount_no_tax = GETPOST('search_amount_no_tax', 'alpha');
$search_amount_all_tax = GETPOST('search_amount_all_tax', 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php
index 9b865cae3e6..7be2c5e9b26 100644
--- a/htdocs/fourn/facture/list.php
+++ b/htdocs/fourn/facture/list.php
@@ -84,6 +84,11 @@ $search_montant_vat = GETPOST('search_montant_vat', 'alpha');
$search_montant_localtax1 = GETPOST('search_montant_localtax1', 'alpha');
$search_montant_localtax2 = GETPOST('search_montant_localtax2', 'alpha');
$search_montant_ttc = GETPOST('search_montant_ttc', 'alpha');
+$search_multicurrency_code = GETPOST('search_multicurrency_code', 'alpha');
+$search_multicurrency_tx = GETPOST('search_multicurrency_tx', 'alpha');
+$search_multicurrency_montant_ht = GETPOST('search_multicurrency_montant_ht', 'alpha');
+$search_multicurrency_montant_vat = GETPOST('search_multicurrency_montant_vat', 'alpha');
+$search_multicurrency_montant_ttc = GETPOST('search_multicurrency_montant_ttc', 'alpha');
$search_status = GETPOST('search_status', 'int');
$search_paymentmode = GETPOST('search_paymentmode', 'int');
$search_town = GETPOST('search_town', 'alpha');
@@ -97,7 +102,7 @@ $day = GETPOST('day', 'int');
$month = GETPOST('month', 'int');
$year = GETPOST('year', 'int');
$day_lim = GETPOST('day_lim', 'int');
-$month_lim = GETPOST('month_lim', 'int');
+$month_lim = GETPOST('month_lim', 'int');
$year_lim = GETPOST('year_lim', 'int');
$toselect = GETPOST('toselect', 'array');
$search_btn = GETPOST('button_search', 'alpha');
@@ -112,7 +117,7 @@ $filter = GETPOST('filtre', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if ($page == -1 || $page == null || !empty($search_btn) || !empty($search_remove_btn) || (empty($toselect) && $massaction === '0')) { $page = 0; }
$offset = $limit * $page;
$pageprev = $page - 1;
@@ -167,6 +172,13 @@ $arrayfields = array(
'f.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>0),
'dynamount_payed'=>array('label'=>$langs->trans("Payed"), 'checked'=>0),
'rtp'=>array('label'=>$langs->trans("Rest"), 'checked'=>0),
+ 'f.multicurrency_code'=>array('label'=>'Currency', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'f.multicurrency_tx'=>array('label'=>'CurrencyRate', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'f.multicurrency_total_ht'=>array('label'=>'MulticurrencyAmountHT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'f.multicurrency_total_vat'=>array('label'=>'MulticurrencyAmountVAT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'f.multicurrency_total_ttc'=>array('label'=>'MulticurrencyAmountTTC', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'multicurrency_dynamount_payed'=>array('label'=>'MulticurrencyAlreadyPaid', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)),
+ 'multicurrency_rtp'=>array('label'=>'MulticurrencyRemainderToPay', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), // Not enabled by default because slow
'f.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
'f.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
'f.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
@@ -201,47 +213,52 @@ if (empty($reshook))
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', 'alpha')) // All tests must be present to be compatible with all browsers
{
- $search_all="";
- $search_user='';
- $search_sale='';
- $search_product_category='';
- $search_ref="";
- $search_refsupplier="";
- $search_type="";
- $search_label="";
- $search_project='';
- $search_company="";
- $search_amount_no_tax="";
- $search_amount_all_tax="";
- $search_montant_ht='';
- $search_montant_vat='';
- $search_montant_localtax1='';
- $search_montant_localtax2='';
- $search_montant_ttc='';
- $search_status='';
- $search_paymentmode='';
- $search_town='';
- $search_zip="";
- $search_state="";
- $search_type='';
- $search_country='';
- $search_type_thirdparty='';
- $year="";
- $month="";
- $day="";
- $year_lim="";
- $month_lim="";
- $day_lim="";
- $toselect='';
- $search_array_options=array();
- $filter='';
- $option='';
- $socid="";
+ $search_all = "";
+ $search_user = '';
+ $search_sale = '';
+ $search_product_category = '';
+ $search_ref = "";
+ $search_refsupplier = "";
+ $search_type = "";
+ $search_label = "";
+ $search_project = '';
+ $search_company = "";
+ $search_amount_no_tax = "";
+ $search_amount_all_tax = "";
+ $search_montant_ht = '';
+ $search_montant_vat = '';
+ $search_montant_localtax1 = '';
+ $search_montant_localtax2 = '';
+ $search_montant_ttc = '';
+ $search_multicurrency_code = '';
+ $search_multicurrency_tx = '';
+ $search_multicurrency_montant_ht = '';
+ $search_multicurrency_montant_vat = '';
+ $search_multicurrency_montant_ttc = '';
+ $search_status = '';
+ $search_paymentmode = '';
+ $search_town = '';
+ $search_zip = "";
+ $search_state = "";
+ $search_type = '';
+ $search_country = '';
+ $search_type_thirdparty = '';
+ $year = "";
+ $month = "";
+ $day = "";
+ $year_lim = "";
+ $month_lim = "";
+ $day_lim = "";
+ $toselect = '';
+ $search_array_options = array();
+ $filter = '';
+ $option = '';
+ $socid = "";
}
// Mass actions
- $objectclass='FactureFournisseur';
- $objectlabel='SupplierInvoices';
+ $objectclass = 'FactureFournisseur';
+ $objectlabel = 'SupplierInvoices';
$permissiontoread = $user->rights->fournisseur->facture->lire;
$permissiontoadd = $user->rights->fournisseur->facture->creer;
$permissiontodelete = $user->rights->fournisseur->facture->supprimer;
@@ -269,6 +286,7 @@ if ($search_all || $search_product_category > 0) $sql = 'SELECT DISTINCT';
$sql .= " f.rowid as facid, f.ref, f.ref_supplier, f.type, f.datef, f.date_lim_reglement as datelimite, f.fk_mode_reglement,";
$sql .= " f.total_ht, f.total_ttc, f.total_tva as total_vat, f.paye as paye, f.fk_statut as fk_statut, f.libelle as label, f.datec as date_creation, f.tms as date_update,";
$sql .= " f.localtax1 as total_localtax1, f.localtax2 as total_localtax2,";
+$sql .= ' f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva as multicurrency_total_vat, f.multicurrency_total_ttc,';
$sql .= " f.note_public, f.note_private,";
$sql .= " s.rowid as socid, s.nom as name, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta as code_compta_client, s.code_compta_fournisseur,";
$sql .= " typent.code as typent_code,";
@@ -336,6 +354,11 @@ if ($search_montant_vat != '') $sql .= natural_search('f.total_tva', $search_mon
if ($search_montant_localtax1 != '') $sql .= natural_search('f.localtax1', $search_montant_localtax1, 1);
if ($search_montant_localtax2 != '') $sql .= natural_search('f.localtax2', $search_montant_localtax2, 1);
if ($search_montant_ttc != '') $sql .= natural_search('f.total_ttc', $search_montant_ttc, 1);
+if ($search_multicurrency_code != '') $sql .= ' AND f.multicurrency_code = "'.$db->escape($search_multicurrency_code).'"';
+if ($search_multicurrency_tx != '') $sql .= natural_search('f.multicurrency_tx', $search_multicurrency_tx, 1);
+if ($search_multicurrency_montant_ht != '') $sql .= natural_search('f.multicurrency_total_ht', $search_multicurrency_montant_ht, 1);
+if ($search_multicurrency_montant_vat != '') $sql .= natural_search('f.multicurrency_total_tva', $search_multicurrency_montant_vat, 1);
+if ($search_multicurrency_montant_ttc != '') $sql .= natural_search('f.multicurrency_total_ttc', $search_multicurrency_montant_ttc, 1);
if ($search_status != '' && $search_status >= 0) $sql .= " AND f.fk_statut = ".$db->escape($search_status);
if ($search_paymentmode > 0) $sql .= " AND f.fk_mode_reglement = ".$search_paymentmode."";
$sql .= dolSqlDateFilter("f.datef", $day, $month, $year);
@@ -433,8 +456,8 @@ if ($resql)
}
$param = '&socid='.$socid;
- if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.$contextpage;
- if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.$limit;
+ if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage);
+ if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit);
if ($search_all) $param .= '&search_all='.urlencode($search_all);
if ($day) $param .= '&day='.urlencode($day);
if ($month) $param .= '&month='.urlencode($month);
@@ -452,12 +475,17 @@ if ($resql)
if ($search_montant_localtax1 != '') $param .= '&search_montant_localtax1='.urlencode($search_montant_localtax1);
if ($search_montant_localtax2 != '') $param .= '&search_montant_localtax2='.urlencode($search_montant_localtax2);
if ($search_montant_ttc != '') $param .= '&search_montant_ttc='.urlencode($search_montant_ttc);
+ if ($search_multicurrency_code != '') $param .= '&search_multicurrency_code='.urlencode($search_multicurrency_code);
+ if ($search_multicurrency_tx != '') $param .= '&search_multicurrency_tx='.urlencode($search_multicurrency_tx);
+ if ($search_multicurrency_montant_ht != '') $param .= '&search_multicurrency_montant_ht='.urlencode($search_multicurrency_montant_ht);
+ if ($search_multicurrency_montant_vat != '') $param .= '&search_multicurrency_montant_vat='.urlencode($search_multicurrency_montant_vat);
+ if ($search_multicurrency_montant_ttc != '') $param .= '&search_multicurrency_montant_ttc='.urlencode($search_multicurrency_montant_ttc);
if ($search_amount_no_tax) $param .= '&search_amount_no_tax='.urlencode($search_amount_no_tax);
if ($search_amount_all_tax) $param .= '&search_amount_all_tax='.urlencode($search_amount_all_tax);
if ($search_status >= 0) $param .= "&search_status=".urlencode($search_status);
- if ($show_files) $param .= '&show_files='.$show_files;
- if ($option) $param .= "&option=".$option;
- if ($optioncss != '') $param .= '&optioncss='.$optioncss;
+ if ($show_files) $param .= '&show_files='.urlencode($show_files);
+ if ($option) $param .= "&option=".urlencode($option);
+ if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss);
// Add $param from extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
@@ -741,6 +769,51 @@ if ($resql)
print '';
print ' ';
}
+ if (!empty($arrayfields['f.multicurrency_code']['checked']))
+ {
+ // Currency
+ print '';
+ print $form->selectMultiCurrency($search_multicurrency_code, 'search_multicurrency_code', 1);
+ print ' ';
+ }
+ if (!empty($arrayfields['f.multicurrency_tx']['checked']))
+ {
+ // Currency rate
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['f.multicurrency_total_ht']['checked']))
+ {
+ // Amount
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['f.multicurrency_total_vat']['checked']))
+ {
+ // Amount
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['f.multicurrency_total_ttc']['checked']))
+ {
+ // Amount
+ print '';
+ print ' ';
+ print ' ';
+ }
+ if (!empty($arrayfields['multicurrency_dynamount_payed']['checked']))
+ {
+ print '';
+ print ' ';
+ }
+ if (!empty($arrayfields['multicurrency_rtp']['checked']))
+ {
+ print '';
+ print ' ';
+ }
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
@@ -798,6 +871,13 @@ if ($resql)
if (!empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'], $_SERVER['PHP_SELF'], 'f.total_ttc', '', $param, '', $sortfield, $sortorder, 'right ');
if (!empty($arrayfields['dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['dynamount_payed']['label'], $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, 'right ');
if (!empty($arrayfields['rtp']['checked'])) print_liste_field_titre($arrayfields['rtp']['label'], $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, 'right ');
+ if (!empty($arrayfields['f.multicurrency_code']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_code']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_code', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.multicurrency_tx']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_tx']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_tx', '', $param, '', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.multicurrency_total_ht']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_total_ht']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_total_ht', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.multicurrency_total_vat']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_total_vat']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_total_tva', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['f.multicurrency_total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_total_ttc']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_total_ttc', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['multicurrency_dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['multicurrency_dynamount_payed']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder);
+ if (!empty($arrayfields['multicurrency_rtp']['checked'])) print_liste_field_titre($arrayfields['multicurrency_rtp']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder);
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
// Hook fields
@@ -831,6 +911,11 @@ if ($resql)
$facturestatic->statut = $obj->fk_statut;
$facturestatic->note_public = $obj->note_public;
$facturestatic->note_private = $obj->note_private;
+ $facturestatic->multicurrency_code = $obj->multicurrency_code;
+ $facturestatic->multicurrency_tx = $obj->multicurrency_tx;
+ $facturestatic->multicurrency_total_ht = $obj->multicurrency_total_ht;
+ $facturestatic->multicurrency_total_tva = $obj->multicurrency_total_vat;
+ $facturestatic->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
$thirdparty->id = $obj->socid;
$thirdparty->name = $obj->name;
@@ -848,6 +933,14 @@ if ($resql)
$totaldeposits = $facturestatic->getSumDepositsUsed();
$totalpay = $paiement + $totalcreditnotes + $totaldeposits;
$remaintopay = $obj->total_ttc - $totalpay;
+ $multicurrency_paiement = $facturestatic->getSommePaiement(1);
+ $multicurrency_totalcreditnotes = $facturestatic->getSumCreditNotesUsed(1);
+ $multicurrency_totaldeposits = $facturestatic->getSumDepositsUsed(1);
+ $multicurrency_totalpay = $multicurrency_paiement + $multicurrency_totalcreditnotes + $multicurrency_totaldeposits;
+ $multicurrency_remaintopay = price2num($facturestatic->multicurrency_total_ttc - $multicurrency_totalpay);
+
+ $facturestatic->alreadypaid = ($paiement ? $paiement : 0);
+
//If invoice has been converted and the conversion has been used, we dont have remain to pay on invoice
if ($facturestatic->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
@@ -879,7 +972,7 @@ if ($resql)
// Supplier ref
if (!empty($arrayfields['f.ref_supplier']['checked']))
{
- print '';
+ print ' ';
print $obj->ref_supplier;
print ' ';
if (!$i) $totalarray['nbfield']++;
@@ -921,139 +1014,187 @@ if ($resql)
print img_warning($langs->trans('Late'));
}
print '';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Project
- if (! empty($arrayfields['p.ref']['checked']))
+ if (!empty($arrayfields['p.ref']['checked']))
{
print '';
if ($obj->project_id > 0)
{
- $projectstatic->id=$obj->project_id;
- $projectstatic->ref=$obj->project_ref;
- $projectstatic->title=$obj->project_label;
+ $projectstatic->id = $obj->project_id;
+ $projectstatic->ref = $obj->project_ref;
+ $projectstatic->title = $obj->project_label;
print $projectstatic->getNomUrl(1);
}
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Third party
- if (! empty($arrayfields['s.nom']['checked']))
+ if (!empty($arrayfields['s.nom']['checked']))
{
print '';
print $thirdparty->getNomUrl(1, 'supplier');
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Town
- if (! empty($arrayfields['s.town']['checked']))
+ if (!empty($arrayfields['s.town']['checked']))
{
print '';
print $obj->town;
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Zip
- if (! empty($arrayfields['s.zip']['checked']))
+ if (!empty($arrayfields['s.zip']['checked']))
{
print '';
print $obj->zip;
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// State
- if (! empty($arrayfields['state.nom']['checked']))
+ if (!empty($arrayfields['state.nom']['checked']))
{
print "".$obj->state_name." \n";
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Country
- if (! empty($arrayfields['country.code_iso']['checked']))
+ if (!empty($arrayfields['country.code_iso']['checked']))
{
print '';
- $tmparray=getCountry($obj->fk_pays, 'all');
+ $tmparray = getCountry($obj->fk_pays, 'all');
print $tmparray['label'];
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Type ent
- if (! empty($arrayfields['typent.code']['checked']))
+ if (!empty($arrayfields['typent.code']['checked']))
{
print '';
- if (count($typenArray)==0) $typenArray = $formcompany->typent_array(1);
+ if (count($typenArray) == 0) $typenArray = $formcompany->typent_array(1);
print $typenArray[$obj->typent_code];
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Payment mode
- if (! empty($arrayfields['f.fk_mode_reglement']['checked']))
+ if (!empty($arrayfields['f.fk_mode_reglement']['checked']))
{
print '';
$form->form_modes_reglement($_SERVER['PHP_SELF'], $obj->fk_mode_reglement, 'none', '', -1);
print ' ';
- if (! $i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['nbfield']++;
}
// Amount HT
- if (! empty($arrayfields['f.total_ht']['checked']))
+ if (!empty($arrayfields['f.total_ht']['checked']))
{
print ''.price($obj->total_ht)." \n";
- if (! $i) $totalarray['nbfield']++;
- if (! $i) $totalarray['pos'][$totalarray['nbfield']]='f.total_ht';
+ if (!$i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'f.total_ht';
$totalarray['val']['f.total_ht'] += $obj->total_ht;
}
// Amount VAT
- if (! empty($arrayfields['f.total_vat']['checked']))
+ if (!empty($arrayfields['f.total_vat']['checked']))
{
print ''.price($obj->total_vat)." \n";
- if (! $i) $totalarray['nbfield']++;
- if (! $i) $totalarray['pos'][$totalarray['nbfield']]='f.total_vat';
+ if (!$i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'f.total_vat';
$totalarray['val']['f.total_vat'] += $obj->total_vat;
}
// Amount LocalTax1
- if (! empty($arrayfields['f.total_localtax1']['checked']))
+ if (!empty($arrayfields['f.total_localtax1']['checked']))
{
print ''.price($obj->total_localtax1)." \n";
- if (! $i) $totalarray['nbfield']++;
- if (! $i) $totalarray['pos'][$totalarray['nbfield']]='f.total_localtax1';
+ if (!$i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'f.total_localtax1';
$totalarray['val']['f.total_localtax1'] += $obj->total_localtax1;
}
// Amount LocalTax2
- if (! empty($arrayfields['f.total_localtax2']['checked']))
+ if (!empty($arrayfields['f.total_localtax2']['checked']))
{
print ''.price($obj->total_localtax2)." \n";
- if (! $i) $totalarray['nbfield']++;
- if (! $i) $totalarray['pos'][$totalarray['nbfield']]='f.total_localtax2';
+ if (!$i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'f.total_localtax2';
$totalarray['val']['f.total_localtax2'] += $obj->total_localtax2;
}
// Amount TTC
- if (! empty($arrayfields['f.total_ttc']['checked']))
+ if (!empty($arrayfields['f.total_ttc']['checked']))
{
print ''.price($obj->total_ttc)." \n";
- if (! $i) $totalarray['nbfield']++;
- if (! $i) $totalarray['pos'][$totalarray['nbfield']]='f.total_ttc';
+ if (!$i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'f.total_ttc';
$totalarray['val']['f.total_ttc'] += $obj->total_ttc;
}
- if (! empty($arrayfields['dynamount_payed']['checked']))
+ if (!empty($arrayfields['dynamount_payed']['checked']))
{
- print ''.(! empty($totalpay)?price($totalpay, 0, $langs):' ').' '; // TODO Use a denormalized field
- if (! $i) $totalarray['nbfield']++;
- if (! $i) $totalarray['pos'][$totalarray['nbfield']]='totalam';
+ print ''.(!empty($totalpay) ?price($totalpay, 0, $langs) : ' ').' '; // TODO Use a denormalized field
+ if (!$i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'totalam';
$totalarray['val']['totalam'] += $totalpay;
}
- if (! empty($arrayfields['rtp']['checked']))
+ if (!empty($arrayfields['rtp']['checked']))
{
- print ''.(! empty($remaintopay)?price($remaintopay, 0, $langs):' ').' '; // TODO Use a denormalized field
- if (! $i) $totalarray['nbfield']++;
- if (! $i) $totalarray['pos'][$totalarray['nbfield']]='rtp';
+ print ''.(!empty($remaintopay) ?price($remaintopay, 0, $langs) : ' ').' '; // TODO Use a denormalized field
+ if (!$i) $totalarray['nbfield']++;
+ if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'rtp';
$totalarray['val']['rtp'] += $remaintopay;
}
+ // Currency
+ if (!empty($arrayfields['f.multicurrency_code']['checked']))
+ {
+ print ''.$obj->multicurrency_code.' - '.$langs->trans('Currency'.$obj->multicurrency_code)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+
+ // Currency rate
+ if (!empty($arrayfields['f.multicurrency_tx']['checked']))
+ {
+ print '';
+ $form->form_multicurrency_rate($_SERVER['PHP_SELF'].'?id='.$obj->rowid, $obj->multicurrency_tx, 'none', $obj->multicurrency_code);
+ print " \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount HT
+ if (!empty($arrayfields['f.multicurrency_total_ht']['checked']))
+ {
+ print ''.price($obj->multicurrency_total_ht)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount VAT
+ if (!empty($arrayfields['f.multicurrency_total_vat']['checked']))
+ {
+ print ''.price($obj->multicurrency_total_vat)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ // Amount TTC
+ if (!empty($arrayfields['f.multicurrency_total_ttc']['checked']))
+ {
+ print ''.price($obj->multicurrency_total_ttc)." \n";
+ if (!$i) $totalarray['nbfield']++;
+ }
+ if (!empty($arrayfields['multicurrency_dynamount_payed']['checked']))
+ {
+ print ''.(!empty($multicurrency_totalpay) ?price($multicurrency_totalpay, 0, $langs) : ' ').' '; // TODO Use a denormalized field
+ if (!$i) $totalarray['nbfield']++;
+ }
+
+ // Pending amount
+ if (!empty($arrayfields['multicurrency_rtp']['checked']))
+ {
+ print '';
+ print (!empty($multicurrency_remaintopay) ? price($multicurrency_remaintopay, 0, $langs) : ' ');
+ print ' '; // TODO Use a denormalized field
+ if (!$i) $totalarray['nbfield']++;
+ }
+
// Extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
@@ -1081,7 +1222,6 @@ if ($resql)
if (!empty($arrayfields['f.fk_statut']['checked']))
{
print '';
- // TODO $paiement is not yet defined
print $facturestatic->LibStatut($obj->paye, $obj->fk_statut, 5, $paiement, $obj->type);
print " ";
if (!$i) $totalarray['nbfield']++;
diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php
index e0a679d1321..6c4f5ff95b1 100644
--- a/htdocs/fourn/facture/paiement.php
+++ b/htdocs/fourn/facture/paiement.php
@@ -62,7 +62,7 @@ $search_payment_num = GETPOST('search_payment_num', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
@@ -297,9 +297,13 @@ if (empty($reshook))
$paiement->datepaye = $datepaye;
$paiement->amounts = $amounts; // Array of amounts
$paiement->multicurrency_amounts = $multicurrency_amounts;
- $paiement->paiementid = $_POST['paiementid'];
- $paiement->num_paiement = $_POST['num_paiement'];
- $paiement->note = $_POST['comment'];
+ $paiement->paiementid = GETPOST('paiementid', 'int');
+
+ $paiement->num_payment = GETPOST('num_paiement', 'alpha');
+ $paiement->note_private = GETPOST('comment', 'alpha');
+ $paiement->num_paiement = $paiement->num_payment; // For bacward compatibility
+ $paiement->note = $paiement->note_private; // For bacward compatibility
+
if (!$error)
{
$paiement_id = $paiement->create($user, (GETPOST('closepaidinvoices') == 'on' ? 1 : 0), $thirdparty);
@@ -808,7 +812,7 @@ if (empty($action) || $action == 'list')
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
- $page = GETPOST("page", 'int');
+ $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; }
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/fourn/product/list.php b/htdocs/fourn/product/list.php
index 6f46e0823ca..5e83ae93923 100644
--- a/htdocs/fourn/product/list.php
+++ b/htdocs/fourn/product/list.php
@@ -45,7 +45,7 @@ $optioncss = GETPOST('optioncss', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/ftp/index.php b/htdocs/ftp/index.php
index a421926387d..2d8efadc472 100644
--- a/htdocs/ftp/index.php
+++ b/htdocs/ftp/index.php
@@ -49,7 +49,7 @@ $download_dir = $conf->ftp->dir_temp;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
-$page = GETPOST("page", 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php
index acd4be35b79..075ca5f5524 100644
--- a/htdocs/holiday/class/holiday.class.php
+++ b/htdocs/holiday/class/holiday.class.php
@@ -716,7 +716,7 @@ class Holiday extends CommonObject
{
$num = $this->ref;
}
- $this->newref = $num;
+ $this->newref = dol_sanitizeFileName($num);
// Update status
$sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
diff --git a/htdocs/holiday/define_holiday.php b/htdocs/holiday/define_holiday.php
index fc91e86fbb8..17c1bcd75b8 100644
--- a/htdocs/holiday/define_holiday.php
+++ b/htdocs/holiday/define_holiday.php
@@ -43,7 +43,7 @@ $search_supervisor=GETPOST('search_supervisor', 'int');
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/holiday/document.php b/htdocs/holiday/document.php
index 64dca56c290..4b8757bf9bf 100644
--- a/htdocs/holiday/document.php
+++ b/htdocs/holiday/document.php
@@ -51,7 +51,7 @@ $result = restrictedArea($user, 'holiday', $id, 'holiday');
// Get parameters
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php
index 2361edf8a27..4aad973d1e9 100644
--- a/htdocs/holiday/list.php
+++ b/htdocs/holiday/list.php
@@ -85,7 +85,7 @@ $diroutputmassaction = $conf->holiday->dir_output.'/temp/massgeneration/'.$user-
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/holiday/view_log.php b/htdocs/holiday/view_log.php
index 7c5ebb36d7c..59aac9e94d9 100644
--- a/htdocs/holiday/view_log.php
+++ b/htdocs/holiday/view_log.php
@@ -50,7 +50,7 @@ if (empty($year))
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
-$page = GETPOST('page', 'int');
+$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
$offset = $limit * $page;
$pageprev = $page - 1;
diff --git a/htdocs/hrm/establishment/card.php b/htdocs/hrm/establishment/card.php
index 11a08d400a3..b8af96ffb8e 100644
--- a/htdocs/hrm/establishment/card.php
+++ b/htdocs/hrm/establishment/card.php
@@ -225,7 +225,7 @@ if ($action == 'create')
print '';
print ''.$form->editfieldkey('Town', 'town', '', $object, 0).' ';
print '';
- print $formcompany->select_ziptown(GETPOST('town', 'alpha'), 'town', array (
+ print $formcompany->select_ziptown(GETPOSTISSET('town') ? GETPOST('town', 'alpha') : $object->town, 'town', array (
'zipcode',
'selectcountry_id'
));
@@ -236,7 +236,7 @@ if ($action == 'create')
print ' ';
print ''.$form->editfieldkey('Country', 'selectcountry_id', '', $object, 0).' ';
print '';
- print $form->select_country(GETPOST('country_id', 'int')>0?GETPOST('country_id', 'int'):$mysoc->country_id, 'country_id');
+ print $form->select_country(GETPOSTISSET('country_id') ? GETPOST('country_id', 'int') : ($object->country_id ? $object->country_id : $mysoc->country_id), 'country_id');
if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
print ' ';
print ' ';
@@ -245,7 +245,7 @@ if ($action == 'create')
print '';
print ''.$form->editfieldkey('Status', 'status', '', $object, 0, 'string', '', 1).' ';
print '';
- print $form->selectarray('status', $status2label, GETPOST('status', 'alpha'));
+ print $form->selectarray('status', $status2label, GETPOSTISSET('status') ? GETPOST('status', 'alpha') : 1);
print ' ';
print '
';
@@ -318,7 +318,7 @@ if (($id || $ref) && $action == 'edit')
// Country
print '
'.$form->editfieldkey('Country', 'selectcountry_id', '', $object, 0).' ';
print '';
- print $form->select_country($object->fk_country, 'country_id');
+ print $form->select_country($object->country_id, 'country_id');
if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
print ' ';
print '';
diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php
index 6f4a1092194..87696535d2f 100644
--- a/htdocs/imports/import.php
+++ b/htdocs/imports/import.php
@@ -522,6 +522,7 @@ if ($step == 3 && $datatoimport)
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', '');
+
print '
';
print '
';
print '
';
@@ -540,6 +541,13 @@ if ($step == 3 && $datatoimport)
dol_fiche_end();
+
+ if ($format == 'xlsx' && ! class_exists('XMLWriter')) {
+ $langs->load("install");
+ print info_admin($langs->trans("ErrorPHPDoesNotSupport", 'php-xml'), 0, 0, 1, 'error');
+ }
+
+
print ' ';
print '';
diff --git a/htdocs/includes/ace/ChangeLog.txt b/htdocs/includes/ace/ChangeLog.txt
index 237a2cdd66f..824f8750e12 100644
--- a/htdocs/includes/ace/ChangeLog.txt
+++ b/htdocs/includes/ace/ChangeLog.txt
@@ -1,3 +1,12 @@
+2020.01.14 Version 1.4.8
+* highlight both matched braces, and highlight unmatched brace in red
+* improve snippet manager
+* compatibility with webpack file-loader v5
+* improve vim mode
+
+2019.10.17 Version 1.4.7
+* add placeholder option
+
2019.09.08 Version 1.4.6
* restore native behavior of ctrl-p on mac (jumptomatching command is moved to cmd-\)
* improve snippet manager
diff --git a/htdocs/includes/ace/ace.d.ts b/htdocs/includes/ace/ace.d.ts
index 3d7ce109bb7..dd1a2952a06 100644
--- a/htdocs/includes/ace/ace.d.ts
+++ b/htdocs/includes/ace/ace.d.ts
@@ -214,6 +214,7 @@ export namespace Ace {
wrapBehavioursEnabled: boolean;
autoScrollEditorIntoView: boolean;
keyboardHandler: string;
+ placeholder: string;
value: string;
session: EditSession;
}
diff --git a/htdocs/includes/ace/kitchen-sink.html b/htdocs/includes/ace/kitchen-sink.html
index e4bab25a335..27014fa6004 100644
--- a/htdocs/includes/ace/kitchen-sink.html
+++ b/htdocs/includes/ace/kitchen-sink.html
@@ -8,7 +8,7 @@
diff --git a/htdocs/includes/ace/package.json b/htdocs/includes/ace/package.json
index 16587d65d90..a00dddeb40a 100644
--- a/htdocs/includes/ace/package.json
+++ b/htdocs/includes/ace/package.json
@@ -2,7 +2,7 @@
"name": "ace-builds",
"main": "./src-noconflict/ace.js",
"typings": "ace.d.ts",
- "version": "1.4.6",
+ "version": "1.4.8",
"description": "Ace (Ajax.org Cloud9 Editor)",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
diff --git a/htdocs/includes/ace/src/ace.js b/htdocs/includes/ace/src/ace.js
index 378ba7cf463..43d9931a3c4 100644
--- a/htdocs/includes/ace/src/ace.js
+++ b/htdocs/includes/ace/src/ace.js
@@ -880,10 +880,10 @@ if (!Date.now) {
return new Date().getTime();
};
}
-var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
+var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" +
"\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
"\u2029\uFEFF";
-if (!String.prototype.trim || ws.trim()) {
+if (!String.prototype.trim) {
ws = "[" + ws + "]";
var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
trimEndRegexp = new RegExp(ws + ws + "*$");
@@ -1404,26 +1404,30 @@ var useragent = require("./useragent");
var pressedKeys = null;
var ts = 0;
+var activeListenerOptions;
+function detectListenerOptionsSupport() {
+ activeListenerOptions = false;
+ try {
+ document.createComment("").addEventListener("test", function() {}, {
+ get passive() {
+ activeListenerOptions = {passive: false};
+ }
+ });
+ } catch(e) {}
+}
+
+function getListenerOptions() {
+ if (activeListenerOptions == undefined)
+ detectListenerOptionsSupport();
+ return activeListenerOptions;
+}
+
exports.addListener = function(elem, type, callback) {
- if (elem.addEventListener) {
- return elem.addEventListener(type, callback, false);
- }
- if (elem.attachEvent) {
- var wrapper = function() {
- callback.call(elem, window.event);
- };
- callback._wrapper = wrapper;
- elem.attachEvent("on" + type, wrapper);
- }
+ return elem.addEventListener(type, callback, getListenerOptions());
};
exports.removeListener = function(elem, type, callback) {
- if (elem.removeEventListener) {
- return elem.removeEventListener(type, callback, false);
- }
- if (elem.detachEvent) {
- elem.detachEvent("on" + type, callback._wrapper || callback);
- }
+ return elem.removeEventListener(type, callback, getListenerOptions());
};
exports.stopEvent = function(e) {
exports.stopPropagation(e);
@@ -1434,27 +1438,18 @@ exports.stopEvent = function(e) {
exports.stopPropagation = function(e) {
if (e.stopPropagation)
e.stopPropagation();
- else
- e.cancelBubble = true;
};
exports.preventDefault = function(e) {
if (e.preventDefault)
e.preventDefault();
- else
- e.returnValue = false;
};
exports.getButton = function(e) {
if (e.type == "dblclick")
return 0;
if (e.type == "contextmenu" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey)))
return 2;
- if (e.preventDefault) {
- return e.button;
- }
- else {
- return {1:0, 2:2, 4:1}[e.button];
- }
+ return e.button;
};
exports.capture = function(el, eventHandler, releaseCaptureHandler) {
@@ -1560,30 +1555,16 @@ exports.addMultiMouseDownListener = function(elements, timeouts, eventHandler, c
else if (clicks > 1)
return eventHandler[callbackName](eventNames[clicks], e);
}
- function onDblclick(e) {
- clicks = 2;
- if (timer)
- clearTimeout(timer);
- timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600);
- eventHandler[callbackName]("mousedown", e);
- eventHandler[callbackName](eventNames[clicks], e);
- }
if (!Array.isArray(elements))
elements = [elements];
elements.forEach(function(el) {
exports.addListener(el, "mousedown", onMousedown);
- if (useragent.isOldIE)
- exports.addListener(el, "dblclick", onDblclick);
});
};
-var getModifierHash = useragent.isMac && useragent.isOpera && !("KeyboardEvent" in window)
- ? function(e) {
- return 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0);
- }
- : function(e) {
- return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);
- };
+var getModifierHash = function(e) {
+ return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);
+};
exports.getModifierString = function(e) {
return keys.KEY_MODS[getModifierHash(e)];
@@ -2228,6 +2209,7 @@ var TextInput = function(parentNode, host) {
var lastValue = "";
var lastSelectionStart = 0;
var lastSelectionEnd = 0;
+ var lastRestoreEnd = 0;
try { var isFocused = document.activeElement === text; } catch(e) {}
event.addListener(text, "blur", function(e) {
@@ -2447,9 +2429,8 @@ var TextInput = function(parentNode, host) {
endIndex = 0;
}
inserted = inserted.slice(0, endIndex);
- if (!fromInput && restoreStart == inserted.length && !extendLeft && !extendRight && !restoreEnd)
+ if (!fromInput && !inserted && !restoreStart && !extendLeft && !extendRight && !restoreEnd)
return "";
-
sendingText = true;
if (inserted && !extendLeft && !extendRight && !restoreStart && !restoreEnd || commandMode) {
host.onTextInput(inserted);
@@ -2466,6 +2447,7 @@ var TextInput = function(parentNode, host) {
lastValue = value;
lastSelectionStart = selectionStart;
lastSelectionEnd = selectionEnd;
+ lastRestoreEnd = restoreEnd;
return inserted;
}
};
@@ -2628,7 +2610,7 @@ var TextInput = function(parentNode, host) {
= inComposition.context.compositionStartOffset;
}
inComposition.markerRange.end.column = inComposition.markerRange.start.column
- + lastSelectionEnd - inComposition.selectionStart;
+ + lastSelectionEnd - inComposition.selectionStart + lastRestoreEnd;
}
}
};
@@ -3786,10 +3768,11 @@ exports.DragdropHandler = DragdropHandler;
});
-define("ace/mouse/touch_handler",["require","exports","module","ace/mouse/mouse_event","ace/lib/dom"], function(require, exports, module) {
+define("ace/mouse/touch_handler",["require","exports","module","ace/mouse/mouse_event","ace/lib/event","ace/lib/dom"], function(require, exports, module) {
"use strict";
var MouseEvent = require("./mouse_event").MouseEvent;
+var event = require("../lib/event");
var dom = require("../lib/dom");
exports.addTouchListeners = function(el, editor) {
@@ -3916,12 +3899,12 @@ exports.addTouchListeners = function(el, editor) {
}
mode = "wait";
}
- el.addEventListener("contextmenu", function(e) {
+ event.addListener(el, "contextmenu", function(e) {
if (!pressed) return;
var textarea = editor.textInput.getElement();
textarea.focus();
});
- el.addEventListener("touchstart", function (e) {
+ event.addListener(el, "touchstart", function (e) {
var touches = e.touches;
if (longTouchTimer || touches.length > 1) {
clearTimeout(longTouchTimer);
@@ -3995,7 +3978,7 @@ exports.addTouchListeners = function(el, editor) {
touchStartT = t;
});
- el.addEventListener("touchend", function (e) {
+ event.addListener(el, "touchend", function (e) {
pressed = editor.$mouseHandler.isMousePressed = false;
if (animationTimer) clearInterval(animationTimer);
if (mode == "zoom") {
@@ -4015,7 +3998,7 @@ exports.addTouchListeners = function(el, editor) {
clearTimeout(longTouchTimer);
longTouchTimer = null;
});
- el.addEventListener("touchmove", function (e) {
+ event.addListener(el, "touchmove", function (e) {
if (longTouchTimer) {
clearTimeout(longTouchTimer);
longTouchTimer = null;
@@ -4577,7 +4560,7 @@ function deHyphenate(str) {
return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); });
}
-exports.version = "1.4.6";
+exports.version = "1.4.8";
});
@@ -5677,6 +5660,8 @@ var Selection = function(session) {
};
this.$setSelection = function(anchorRow, anchorColumn, cursorRow, cursorColumn) {
+ if (this.$silent)
+ return;
var wasEmpty = this.$isEmpty;
var wasMultiselect = this.inMultiSelectMode;
this.$silent = true;
@@ -6070,14 +6055,19 @@ var Selection = function(session) {
else
this.$desiredColumn = screenPos.column;
}
-
+
+ if (rows != 0 && this.session.lineWidgets && this.session.lineWidgets[this.lead.row]) {
+ var widget = this.session.lineWidgets[this.lead.row];
+ if (rows < 0)
+ rows -= widget.rowsAbove || 0;
+ else if (rows > 0)
+ rows += widget.rowCount - (widget.rowsAbove || 0);
+ }
+
var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column, offsetX);
if (rows !== 0 && chars === 0 && docPos.row === this.lead.row && docPos.column === this.lead.column) {
- if (this.session.lineWidgets && this.session.lineWidgets[docPos.row]) {
- if (docPos.row > 0 || rows > 0)
- docPos.row++;
- }
+
}
this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0);
};
@@ -9710,7 +9700,7 @@ function BracketMatch() {
var line = this.getLine(pos.row);
var before = true, range;
- var chr = line.charAt(pos.column-1);
+ var chr = line.charAt(pos.column - 1);
var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
if (!match) {
chr = line.charAt(pos.column);
@@ -9745,6 +9735,29 @@ function BracketMatch() {
return range;
};
+ this.getMatchingBracketRanges = function(pos) {
+ var line = this.getLine(pos.row);
+
+ var chr = line.charAt(pos.column - 1);
+ var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
+ if (!match) {
+ chr = line.charAt(pos.column);
+ pos = {row: pos.row, column: pos.column + 1};
+ match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
+ }
+
+ if (!match)
+ return null;
+
+ var startRange = new Range(pos.row, pos.column - 1, pos.row, pos.column);
+ var bracketPos = match[1] ? this.$findClosingBracket(match[1], pos)
+ : this.$findOpeningBracket(match[2], pos);
+ if (!bracketPos)
+ return [startRange];
+ var endRange = new Range(bracketPos.row, bracketPos.column, bracketPos.row, bracketPos.column + 1);
+
+ return [startRange, endRange];
+ };
this.$brackets = {
")": "(",
@@ -11147,15 +11160,14 @@ EditSession.$uid = 0;
this.lineWidgets = null;
this.getRowLength = function(row) {
+ var h = 1;
if (this.lineWidgets)
- var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;
- else
- h = 0;
- if (!this.$useWrapMode || !this.$wrapData[row]) {
- return 1 + h;
- } else {
- return this.$wrapData[row].length + 1 + h;
- }
+ h += this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;
+
+ if (!this.$useWrapMode || !this.$wrapData[row])
+ return h;
+ else
+ return this.$wrapData[row].length + h;
};
this.getRowLineCount = function(row) {
if (!this.$useWrapMode || !this.$wrapData[row]) {
@@ -11367,6 +11379,9 @@ EditSession.$uid = 0;
wrapIndent = screenRowOffset > 0 ? wrapRow.indent : 0;
}
}
+
+ if (this.lineWidgets && this.lineWidgets[row] && this.lineWidgets[row].rowsAbove)
+ screenRow += this.lineWidgets[row].rowsAbove;
return {
row: screenRow,
@@ -13034,6 +13049,26 @@ exports.commands = [{
},
readOnly: true,
scrollIntoView: "none"
+}, {
+ name: "addLineAfter",
+ exec: function(editor) {
+ editor.selection.clearSelection();
+ editor.navigateLineEnd();
+ editor.insert("\n");
+ },
+ multiSelectAction: "forEach",
+ scrollIntoView: "cursor"
+}, {
+ name: "addLineBefore",
+ exec: function(editor) {
+ editor.selection.clearSelection();
+ var cursor = editor.getCursorPosition();
+ editor.selection.moveTo(cursor.row - 1, Number.MAX_VALUE);
+ editor.insert("\n");
+ if (cursor.row === 0) editor.navigateUp();
+ },
+ multiSelectAction: "forEach",
+ scrollIntoView: "cursor"
}, {
name: "openCommandPallete",
description: "Open command pallete",
@@ -13419,28 +13454,46 @@ Editor.$uid = 0;
};
this.$highlightBrackets = function() {
- if (this.session.$bracketHighlight) {
- this.session.removeMarker(this.session.$bracketHighlight);
- this.session.$bracketHighlight = null;
- }
-
if (this.$highlightPending) {
return;
}
var self = this;
this.$highlightPending = true;
- setTimeout(function() {
+ setTimeout(function () {
self.$highlightPending = false;
var session = self.session;
if (!session || !session.bgTokenizer) return;
- var pos = session.findMatchingBracket(self.getCursorPosition());
- if (pos) {
- var range = new Range(pos.row, pos.column, pos.row, pos.column + 1);
- } else if (session.$mode.getMatching) {
- var range = session.$mode.getMatching(self.session);
+ if (session.$bracketHighlight) {
+ session.$bracketHighlight.markerIds.forEach(function(id) {
+ session.removeMarker(id);
+ });
+ session.$bracketHighlight = null;
}
- if (range)
- session.$bracketHighlight = session.addMarker(range, "ace_bracket", "text");
+ var ranges = session.getMatchingBracketRanges(self.getCursorPosition());
+ if (!ranges && session.$mode.getMatching)
+ ranges = session.$mode.getMatching(self.session);
+ if (!ranges)
+ return;
+
+ var markerType = "ace_bracket";
+ if (!Array.isArray(ranges)) {
+ ranges = [ranges];
+ } else if (ranges.length == 1) {
+ markerType = "ace_error_bracket";
+ }
+ if (ranges.length == 2) {
+ if (Range.comparePoints(ranges[0].end, ranges[1].start) == 0)
+ ranges = [Range.fromPoints(ranges[0].start, ranges[1].end)];
+ else if (Range.comparePoints(ranges[0].start, ranges[1].end) == 0)
+ ranges = [Range.fromPoints(ranges[1].start, ranges[0].end)];
+ }
+
+ session.$bracketHighlight = {
+ ranges: ranges,
+ markerIds: ranges.map(function(range) {
+ return session.addMarker(range, markerType, "text");
+ })
+ };
}, 50);
};
this.$highlightTags = function() {
@@ -14263,6 +14316,7 @@ Editor.$uid = 0;
["up", "down"],
["before", "after"],
["even", "odd"],
+ ["in", "out"],
["inside", "outside"],
["next", "previous"],
["increase", "decrease"],
@@ -14870,9 +14924,11 @@ Editor.$uid = 0;
this.destroy = function() {
this.renderer.destroy();
this._signal("destroy", this);
- if (this.session) {
+ if (this.session)
this.session.destroy();
- }
+ if (this._$emitInputEvent)
+ this._$emitInputEvent.cancel();
+ this.session = null;
};
this.setAutoScrollEditorIntoView = function(enable) {
if (!enable)
@@ -15028,6 +15084,31 @@ config.defineOptions(Editor.prototype, "editor", {
relativeNumberRenderer.detach(this);
}
},
+ placeholder: {
+ set: function(message) {
+ if (!this.$updatePlaceholder) {
+ this.$updatePlaceholder = function() {
+ var value = this.renderer.$composition || this.getValue();
+ if (value && this.renderer.placeholderNode) {
+ this.renderer.off("afterRender", this.$updatePlaceholder);
+ dom.removeCssClass(this.container, "ace_hasPlaceholder");
+ this.renderer.placeholderNode.remove();
+ this.renderer.placeholderNode = null;
+ } else if (!value && !this.renderer.placeholderNode) {
+ this.renderer.on("afterRender", this.$updatePlaceholder);
+ dom.addCssClass(this.container, "ace_hasPlaceholder");
+ var el = dom.createElement("div");
+ el.className = "ace_placeholder";
+ el.textContent = this.$placeholder || "";
+ this.renderer.placeholderNode = el;
+ this.renderer.content.appendChild(this.renderer.placeholderNode);
+ }
+ }.bind(this);
+ this.on("input", this.$updatePlaceholder);
+ }
+ this.$updatePlaceholder();
+ }
+ },
hScrollBarAlwaysVisible: "renderer",
vScrollBarAlwaysVisible: "renderer",
@@ -15118,6 +15199,7 @@ var UndoManager = function() {
this.add = function(delta, allowMerge, session) {
if (this.$fromUndo) return;
if (delta == this.$lastDelta) return;
+ if (!this.$keepRedoStack) this.$redoStack.length = 0;
if (allowMerge === false || !this.lastDeltas) {
this.lastDeltas = [];
this.$undoStack.push(this.lastDeltas);
@@ -15194,6 +15276,25 @@ var UndoManager = function() {
if (to == null) to = this.$rev + 1;
};
+
+ this.validateDeltaBoundaries = function(deltaSet, docLength, invertAction) {
+ if (!deltaSet) {
+ return false;
+ }
+ return deltaSet.every(function(delta) {
+ var action = delta.action;
+ if (invertAction && delta.action === "insert") action = "remove";
+ if (invertAction && delta.action === "remove") action = "insert";
+ switch(action) {
+ case "insert":
+ return delta.start.row <= docLength;
+ case "remove":
+ return delta.start.row < docLength && delta.end.row < docLength;
+ default:
+ return true;
+ }
+ });
+ };
this.undo = function(session, dontSelect) {
this.lastDeltas = null;
var stack = this.$undoStack;
@@ -15211,7 +15312,7 @@ var UndoManager = function() {
var deltaSet = stack.pop();
var undoSelectionRange = null;
- if (deltaSet && deltaSet.length) {
+ if (this.validateDeltaBoundaries(deltaSet, session.getLength(), true)) {
undoSelectionRange = session.undoChanges(deltaSet, dontSelect);
this.$redoStack.push(deltaSet);
this.$syncRev();
@@ -15239,7 +15340,7 @@ var UndoManager = function() {
var deltaSet = this.$redoStack.pop();
var redoSelectionRange = null;
- if (deltaSet) {
+ if (this.validateDeltaBoundaries(deltaSet, session.getLength(), false)) {
redoSelectionRange = session.redoChanges(deltaSet, dontSelect);
this.$undoStack.push(deltaSet);
this.$syncRev();
@@ -15618,7 +15719,7 @@ var Lines = function(element, canvasHeight) {
};
this.computeLineHeight = function(row, config, session) {
- return config.lineHeight * session.getRowLength(row);
+ return config.lineHeight * session.getRowLineCount(row);
};
this.getLength = function() {
@@ -15645,10 +15746,10 @@ var Lines = function(element, canvasHeight) {
fragment.appendChild(cell[i].element);
}
this.element.appendChild(fragment);
- } else {
+ } else {
this.cells.push(cell);
this.element.appendChild(cell.element);
- }
+ }
};
this.unshift = function(cell) {
@@ -15662,10 +15763,10 @@ var Lines = function(element, canvasHeight) {
this.element.insertBefore(fragment, this.element.firstChild);
else
this.element.appendChild(fragment);
- } else {
+ } else {
this.cells.unshift(cell);
this.element.insertAdjacentElement("afterbegin", cell.element);
- }
+ }
};
this.last = function() {
@@ -17633,6 +17734,7 @@ position: absolute;\
box-sizing: border-box;\
min-width: 100%;\
contain: style size layout;\
+font-variant-ligatures: no-common-ligatures;\
}\
.ace_dragging .ace_scroller:before{\
position: absolute;\
@@ -17764,7 +17866,6 @@ margin-top: 1px;\
[ace_nocontext=true] {\
transform: none!important;\
filter: none!important;\
-perspective: none!important;\
clip-path: none!important;\
mask : none!important;\
contain: none!important;\
@@ -17843,6 +17944,9 @@ border-bottom: 1px solid;\
.ace_hidden-cursors .ace_cursor {\
opacity: 0.2;\
}\
+.ace_hasPlaceholder .ace_hidden-cursors .ace_cursor {\
+opacity: 0;\
+}\
.ace_smooth-blinking .ace_cursor {\
transition: opacity 0.18s;\
}\
@@ -17879,6 +17983,11 @@ z-index: 5;\
position: absolute;\
z-index: 6;\
}\
+.ace_marker-layer .ace_error_bracket {\
+position: absolute;\
+border-bottom: 1px solid #DE5555;\
+border-radius: 0;\
+}\
.ace_marker-layer .ace_active-line {\
position: absolute;\
z-index: 2;\
@@ -18062,6 +18171,14 @@ opacity:1;\
}\
.ace_mobile-button:active {\
background-color: #ddd;\
+}\
+.ace_placeholder {\
+font-family: arial;\
+transform: scale(0.9);\
+transform-origin: left;\
+white-space: pre;\
+opacity: 0.7;\
+margin: 0 10px;\
}";
var useragent = require("./lib/useragent");
@@ -18522,7 +18639,6 @@ var VirtualRenderer = function(container, theme) {
if (composition.useTextareaForIME) {
var val = this.textarea.value;
w = this.characterWidth * (this.session.$getStringScreenWidth(val)[0]);
- h += 2;
}
else {
posTop += this.lineHeight + 2;
@@ -18649,7 +18765,7 @@ var VirtualRenderer = function(container, theme) {
this.$textLayer.checkForSizeChanges();
}
- this._signal("beforeRender");
+ this._signal("beforeRender", changes);
if (this.session && this.session.$bidiHandler)
this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics);
@@ -18697,7 +18813,7 @@ var VirtualRenderer = function(container, theme) {
this.$markerFront.update(config);
this.$cursorLayer.update(config);
this.$moveTextAreaToCursor();
- this._signal("afterRender");
+ this._signal("afterRender", changes);
return;
}
if (changes & this.CHANGE_SCROLL) {
@@ -18717,7 +18833,7 @@ var VirtualRenderer = function(container, theme) {
this.$markerFront.update(config);
this.$cursorLayer.update(config);
this.$moveTextAreaToCursor();
- this._signal("afterRender");
+ this._signal("afterRender", changes);
return;
}
@@ -18753,7 +18869,7 @@ var VirtualRenderer = function(container, theme) {
this.$markerBack.update(config);
}
- this._signal("afterRender");
+ this._signal("afterRender", changes);
};
@@ -19185,7 +19301,7 @@ var VirtualRenderer = function(container, theme) {
this.$moveTextAreaToCursor();
this.$cursorLayer.element.style.display = "none";
}
- else {
+ else {
composition.markerId = this.session.addMarker(composition.markerRange, "ace_composition_marker", "text");
}
};
@@ -20079,10 +20195,20 @@ exports.defaultCommands = [{
scrollIntoView: "cursor",
readOnly: true
}, {
- name: "splitIntoLines",
+ name: "toggleSplitSelectionIntoLines",
+ description: "Split into lines",
+ exec: function(editor) {
+ if (editor.multiSelect.rangeCount > 1)
+ editor.multiSelect.joinSelections();
+ else
+ editor.multiSelect.splitIntoLines();
+ },
+ bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"},
+ readOnly: true
+}, {
+ name: "splitSelectionIntoLines",
description: "Split into lines",
exec: function(editor) { editor.multiSelect.splitIntoLines(); },
- bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"},
readOnly: true
}, {
name: "alignCursors",
@@ -20177,7 +20303,6 @@ var EditSession = require("./edit_session").EditSession;
return $blockChangeEvents || this.fromOrientedRange(range);
};
-
this.toSingleRange = function(range) {
range = range || this.ranges[0];
var removed = this.rangeList.removeAll();
@@ -20242,45 +20367,36 @@ var EditSession = require("./edit_session").EditSession;
this.getAllRanges = function() {
return this.rangeCount ? this.rangeList.ranges.concat() : [this.getRange()];
};
-
this.splitIntoLines = function () {
- if (this.rangeCount > 1) {
- var ranges = this.rangeList.ranges;
- var lastRange = ranges[ranges.length - 1];
- var range = Range.fromPoints(ranges[0].start, lastRange.end);
-
- this.toSingleRange();
- this.setSelectionRange(range, lastRange.cursor == lastRange.start);
- } else {
- var range = this.getRange();
- var isBackwards = this.isBackwards();
- var startRow = range.start.row;
+ var ranges = this.ranges.length ? this.ranges : [this.getRange()];
+ var newRanges = [];
+ for (var i = 0; i < ranges.length; i++) {
+ var range = ranges[i];
+ var row = range.start.row;
var endRow = range.end.row;
- if (startRow == endRow) {
- if (isBackwards)
- var start = range.end, end = range.start;
- else
- var start = range.start, end = range.end;
-
- this.addRange(Range.fromPoints(end, end));
- this.addRange(Range.fromPoints(start, start));
- return;
+ if (row === endRow) {
+ newRanges.push(range.clone());
+ } else {
+ newRanges.push(new Range(row, range.start.column, row, this.session.getLine(row).length));
+ while (++row < endRow)
+ newRanges.push(this.getLineRange(row, true));
+ newRanges.push(new Range(endRow, 0, endRow, range.end.column));
}
-
- var rectSel = [];
- var r = this.getLineRange(startRow, true);
- r.start.column = range.start.column;
- rectSel.push(r);
-
- for (var i = startRow + 1; i < endRow; i++)
- rectSel.push(this.getLineRange(i, true));
-
- r = this.getLineRange(endRow, true);
- r.end.column = range.end.column;
- rectSel.push(r);
-
- rectSel.forEach(this.addRange, this);
+ if (i == 0 && !this.isBackwards())
+ newRanges = newRanges.reverse();
}
+ this.toSingleRange();
+ for (var i = newRanges.length; i--;)
+ this.addRange(newRanges[i]);
+ };
+
+ this.joinSelections = function () {
+ var ranges = this.rangeList.ranges;
+ var lastRange = ranges[ranges.length - 1];
+ var range = Range.fromPoints(ranges[0].start, lastRange.end);
+
+ this.toSingleRange();
+ this.setSelectionRange(range, lastRange.cursor == lastRange.start);
};
this.toggleBlockSelection = function () {
if (this.rangeCount > 1) {
@@ -21146,13 +21262,10 @@ var dom = require("../lib/dom");
dom.importCssString(exports.cssText, exports.cssClass);
});
-define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"], function(require, exports, module) {
+define("ace/line_widgets",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
"use strict";
-var oop = require("./lib/oop");
var dom = require("./lib/dom");
-var Range = require("./range").Range;
-
function LineWidgets(session) {
this.session = session;
@@ -21266,14 +21379,21 @@ function LineWidgets(session) {
var len = delta.end.row - startRow;
if (len === 0) {
- } else if (delta.action == 'remove') {
+ } else if (delta.action == "remove") {
var removed = lineWidgets.splice(startRow + 1, len);
+ if (!lineWidgets[startRow] && removed[removed.length - 1]) {
+ lineWidgets[startRow] = removed.pop();
+ }
removed.forEach(function(w) {
w && this.removeLineWidget(w);
}, this);
this.$updateRows();
} else {
var args = new Array(len);
+ if (lineWidgets[startRow] && lineWidgets[startRow].column != null) {
+ if (delta.start.column > lineWidgets[startRow].column)
+ startRow++;
+ }
args.unshift(startRow, 0);
lineWidgets.splice.apply(lineWidgets, args);
this.$updateRows();
@@ -21298,7 +21418,7 @@ function LineWidgets(session) {
this.session.lineWidgets = null;
};
- this.addLineWidget = function(w) {
+ this.$registerLineWidget = function(w) {
if (!this.session.lineWidgets)
this.session.lineWidgets = new Array(this.session.getLength());
@@ -21312,9 +21432,15 @@ function LineWidgets(session) {
}
this.session.lineWidgets[w.row] = w;
-
+ return w;
+ };
+
+ this.addLineWidget = function(w) {
+ this.$registerLineWidget(w);
w.session = this.session;
+ if (!this.editor) return w;
+
var renderer = this.editor.renderer;
if (w.html && !w.el) {
w.el = dom.createElement("div");
@@ -21326,13 +21452,13 @@ function LineWidgets(session) {
w.el.style.zIndex = 5;
renderer.container.appendChild(w.el);
w._inDocument = true;
- }
-
- if (!w.coverGutter) {
- w.el.style.zIndex = 3;
- }
- if (w.pixelHeight == null) {
- w.pixelHeight = w.el.offsetHeight;
+
+ if (!w.coverGutter) {
+ w.el.style.zIndex = 3;
+ }
+ if (w.pixelHeight == null) {
+ w.pixelHeight = w.el.offsetHeight;
+ }
}
if (w.rowCount == null) {
w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight;
diff --git a/htdocs/includes/ace/src/ext-code_lens.js b/htdocs/includes/ace/src/ext-code_lens.js
new file mode 100644
index 00000000000..4b7e4340f22
--- /dev/null
+++ b/htdocs/includes/ace/src/ext-code_lens.js
@@ -0,0 +1,234 @@
+define("ace/ext/code_lens",["require","exports","module","ace/line_widgets","ace/lib/lang","ace/lib/dom","ace/editor","ace/config"], function(require, exports, module) {
+"use strict";
+var LineWidgets = require("../line_widgets").LineWidgets;
+var lang = require("../lib/lang");
+var dom = require("../lib/dom");
+
+function clearLensElements(renderer) {
+ var textLayer = renderer.$textLayer;
+ var lensElements = textLayer.$lenses;
+ if (lensElements)
+ lensElements.forEach(function(el) {el.remove(); });
+ textLayer.$lenses = null;
+}
+
+function renderWidgets(changes, renderer) {
+ var changed = changes & renderer.CHANGE_LINES
+ || changes & renderer.CHANGE_FULL
+ || changes & renderer.CHANGE_SCROLL
+ || changes & renderer.CHANGE_TEXT;
+ if (!changed)
+ return;
+
+ var session = renderer.session;
+ var lineWidgets = renderer.session.lineWidgets;
+ var textLayer = renderer.$textLayer;
+ var lensElements = textLayer.$lenses;
+ if (!lineWidgets) {
+ if (lensElements)
+ clearLensElements(renderer);
+ return;
+ }
+
+ var textCells = renderer.$textLayer.$lines.cells;
+ var config = renderer.layerConfig;
+ var padding = renderer.$padding;
+
+ if (!lensElements)
+ lensElements = textLayer.$lenses = [];
+
+
+ var index = 0;
+ for (var i = 0; i < textCells.length; i++) {
+ var row = textCells[i].row;
+ var widget = lineWidgets[row];
+ var lenses = widget && widget.lenses;
+
+ if (!lenses || !lenses.length) continue;
+
+ var lensContainer = lensElements[index];
+ if (!lensContainer) {
+ lensContainer = lensElements[index]
+ = dom.buildDom(["div", {class: "ace_codeLens"}], renderer.container);
+ }
+ lensContainer.style.height = config.lineHeight + "px";
+ index++;
+
+ for (var j = 0; j < lenses.length; j++) {
+ var el = lensContainer.childNodes[2 * j];
+ if (!el) {
+ if (j != 0) lensContainer.appendChild(dom.createTextNode("\xa0|\xa0"));
+ el = dom.buildDom(["a"], lensContainer);
+ }
+ el.textContent = lenses[j].title;
+ el.lensCommand = lenses[j];
+ }
+ while (lensContainer.childNodes.length > 2 * j - 1)
+ lensContainer.lastChild.remove();
+
+ var top = renderer.$cursorLayer.getPixelPosition({
+ row: row,
+ column: 0
+ }, true).top - config.lineHeight * widget.rowsAbove - config.offset;
+ lensContainer.style.top = top + "px";
+
+ var left = renderer.gutterWidth;
+ var indent = session.getLine(row).search(/\S|$/);
+ if (indent == -1)
+ indent = 0;
+ left += indent * config.characterWidth;
+ left -= renderer.scrollLeft;
+ lensContainer.style.paddingLeft = padding + left + "px";
+ }
+ while (index < lensElements.length)
+ lensElements.pop().remove();
+}
+
+function clearCodeLensWidgets(session) {
+ if (!session.lineWidgets) return;
+ var widgetManager = session.widgetManager;
+ session.lineWidgets.forEach(function(widget) {
+ if (widget && widget.lenses)
+ widgetManager.removeLineWidget(widget);
+ });
+}
+
+exports.setLenses = function(session, lenses) {
+ var firstRow = Number.MAX_VALUE;
+
+ clearCodeLensWidgets(session);
+ lenses && lenses.forEach(function(lens) {
+ var row = lens.start.row;
+ var column = lens.start.column;
+ var widget = session.lineWidgets && session.lineWidgets[row];
+ if (!widget || !widget.lenses) {
+ widget = session.widgetManager.$registerLineWidget({
+ rowCount: 1,
+ rowsAbove: 1,
+ row: row,
+ column: column,
+ lenses: []
+ });
+ }
+ widget.lenses.push(lens.command);
+ if (row < firstRow)
+ firstRow = row;
+ });
+ session._emit("changeFold", {data: {start: {row: firstRow}}});
+};
+
+function attachToEditor(editor) {
+ editor.codeLensProviders = [];
+ editor.renderer.on("afterRender", renderWidgets);
+ editor.$codeLensClickHandler = function(e) {
+ var command = e.target.lensCommand;
+ if (command)
+ editor.execCommand(command.id, command.arguments);
+ };
+ editor.container.addEventListener("click", editor.$codeLensClickHandler);
+ editor.$updateLenses = function() {
+ var session = editor.session;
+ if (!session) return;
+
+ if (!session.widgetManager) {
+ session.widgetManager = new LineWidgets(session);
+ session.widgetManager.attach(editor);
+ }
+
+ var providersToWaitNum = editor.codeLensProviders.length;
+ var lenses = [];
+ editor.codeLensProviders.forEach(function(provider) {
+ provider.provideCodeLenses(session, function(currentLenses) {
+ currentLenses.forEach(function(lens) {
+ lenses.push(lens);
+ });
+ providersToWaitNum--;
+ if (providersToWaitNum == 0) {
+ applyLenses();
+ }
+ });
+ });
+
+ function applyLenses() {
+ var cursor = session.selection.cursor;
+ var oldRow = session.documentToScreenRow(cursor);
+ exports.setLenses(session, lenses);
+
+ var lastDelta = session.$undoManager && session.$undoManager.$lastDelta;
+ if (lastDelta && lastDelta.action == "remove" && lastDelta.lines.length > 1)
+ return;
+ var row = session.documentToScreenRow(cursor);
+ var lineHeight = editor.renderer.layerConfig.lineHeight;
+ var top = session.getScrollTop() + (row - oldRow) * lineHeight;
+ session.setScrollTop(top);
+ }
+ };
+ var updateLenses = lang.delayedCall(editor.$updateLenses);
+ editor.$updateLensesOnInput = function() {
+ updateLenses.delay(250);
+ };
+ editor.on("input", editor.$updateLensesOnInput);
+}
+
+function detachFromEditor(editor) {
+ editor.off("input", editor.$updateLensesOnInput);
+ editor.renderer.off("afterRender", renderWidgets);
+ if (editor.$codeLensClickHandler)
+ editor.container.removeEventListener("click", editor.$codeLensClickHandler);
+}
+
+exports.registerCodeLensProvider = function(editor, codeLensProvider) {
+ editor.setOption("enableCodeLens", true);
+ editor.codeLensProviders.push(codeLensProvider);
+ editor.$updateLensesOnInput();
+};
+
+exports.clear = function(session) {
+ exports.setLenses(session, null);
+};
+
+var Editor = require("../editor").Editor;
+require("../config").defineOptions(Editor.prototype, "editor", {
+ enableCodeLens: {
+ set: function(val) {
+ if (val) {
+ attachToEditor(this);
+ } else {
+ detachFromEditor(this);
+ }
+ }
+ }
+});
+
+dom.importCssString("\
+.ace_codeLens {\
+ position: absolute;\
+ color: #aaa;\
+ font-size: 88%;\
+ background: inherit;\
+ width: 100%;\
+ display: flex;\
+ align-items: flex-end;\
+ pointer-events: none;\
+}\
+.ace_codeLens > a {\
+ cursor: pointer;\
+ pointer-events: auto;\
+}\
+.ace_codeLens > a:hover {\
+ color: #0000ff;\
+ text-decoration: underline;\
+}\
+.ace_dark > .ace_codeLens > a:hover {\
+ color: #4e94ce;\
+}\
+", "");
+
+}); (function() {
+ window.require(["ace/ext/code_lens"], function(m) {
+ if (typeof module == "object" && typeof exports == "object" && module) {
+ module.exports = m;
+ }
+ });
+ })();
+
\ No newline at end of file
diff --git a/htdocs/includes/ace/src/ext-emmet.js b/htdocs/includes/ace/src/ext-emmet.js
index 30425a69273..3cb3818d1b5 100644
--- a/htdocs/includes/ace/src/ext-emmet.js
+++ b/htdocs/includes/ace/src/ext-emmet.js
@@ -747,15 +747,16 @@ var TabstopManager = function(editor) {
this.onChange = function(delta) {
var isRemove = delta.action[0] == "r";
- var parents = this.selectedTabstop && this.selectedTabstop.parents || {};
+ var selectedTabstop = this.selectedTabstop || {};
+ var parents = selectedTabstop.parents || {};
var tabstops = (this.tabstops || []).slice();
for (var i = 0; i < tabstops.length; i++) {
var ts = tabstops[i];
- var active = ts == this.selectedTabstop || parents[ts.index];
+ var active = ts == selectedTabstop || parents[ts.index];
ts.rangeList.$bias = active ? 0 : 1;
- if (delta.action == "remove" && ts !== this.selectedTabstop) {
- var parentActive = ts.parents && ts.parents[this.selectedTabstop.index];
+ if (delta.action == "remove" && ts !== selectedTabstop) {
+ var parentActive = ts.parents && ts.parents[selectedTabstop.index];
var startIndex = ts.rangeList.pointIndex(delta.start, parentActive);
startIndex = startIndex < 0 ? -startIndex - 1 : startIndex + 1;
var endIndex = ts.rangeList.pointIndex(delta.end, parentActive);
@@ -868,8 +869,6 @@ var TabstopManager = function(editor) {
var ranges = this.ranges;
tabstops.forEach(function(ts, index) {
var dest = this.$openTabstops[index] || ts;
- ts.rangeList = new RangeList();
- ts.rangeList.$bias = 0;
for (var i = 0; i < ts.length; i++) {
var p = ts[i];
@@ -879,7 +878,6 @@ var TabstopManager = function(editor) {
range.original = p;
range.tabstop = dest;
ranges.push(range);
- ts.rangeList.ranges.push(range);
if (dest != ts)
dest.unshift(range);
else
@@ -897,6 +895,9 @@ var TabstopManager = function(editor) {
this.$openTabstops[index] = dest;
}
this.addTabstopMarkers(dest);
+ dest.rangeList = dest.rangeList || new RangeList();
+ dest.rangeList.$bias = 0;
+ dest.rangeList.addList(dest);
}, this);
if (arg.length > 2) {
@@ -939,21 +940,18 @@ var TabstopManager = function(editor) {
this.keyboardHandler = new HashHandler();
this.keyboardHandler.bindKeys({
- "Tab": function(ed) {
- if (exports.snippetManager && exports.snippetManager.expandWithTab(ed)) {
+ "Tab": function(editor) {
+ if (exports.snippetManager && exports.snippetManager.expandWithTab(editor))
return;
- }
-
- ed.tabstopManager.tabNext(1);
+ editor.tabstopManager.tabNext(1);
+ editor.renderer.scrollCursorIntoView();
},
- "Shift-Tab": function(ed) {
- ed.tabstopManager.tabNext(-1);
+ "Shift-Tab": function(editor) {
+ editor.tabstopManager.tabNext(-1);
+ editor.renderer.scrollCursorIntoView();
},
- "Esc": function(ed) {
- ed.tabstopManager.detach();
- },
- "Return": function(ed) {
- return false;
+ "Esc": function(editor) {
+ editor.tabstopManager.detach();
}
});
}).call(TabstopManager.prototype);
diff --git a/htdocs/includes/ace/src/ext-keybinding_menu.js b/htdocs/includes/ace/src/ext-keybinding_menu.js
index 501c5f9ccad..4f980686e68 100644
--- a/htdocs/includes/ace/src/ext-keybinding_menu.js
+++ b/htdocs/includes/ace/src/ext-keybinding_menu.js
@@ -65,6 +65,7 @@ dom.importCssString(cssText);
module.exports.overlayPage = function overlayPage(editor, contentElement, callback) {
var closer = document.createElement('div');
+ var ignoreFocusOut = false;
function documentEscListener(e) {
if (e.keyCode === 27) {
@@ -76,17 +77,28 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba
if (!closer) return;
document.removeEventListener('keydown', documentEscListener);
closer.parentNode.removeChild(closer);
- editor.focus();
+ if (editor) {
+ editor.focus();
+ }
closer = null;
callback && callback();
}
+ function setIgnoreFocusOut(ignore) {
+ ignoreFocusOut = ignore;
+ if (ignore) {
+ closer.style.pointerEvents = "none";
+ contentElement.style.pointerEvents = "auto";
+ }
+ }
closer.style.cssText = 'margin: 0; padding: 0; ' +
'position: fixed; top:0; bottom:0; left:0; right:0;' +
'z-index: 9990; ' +
- 'background-color: rgba(0, 0, 0, 0.3);';
- closer.addEventListener('click', function() {
- close();
+ (editor ? 'background-color: rgba(0, 0, 0, 0.3);' : '');
+ closer.addEventListener('click', function(e) {
+ if (!ignoreFocusOut) {
+ close();
+ }
});
document.addEventListener('keydown', documentEscListener);
@@ -96,9 +108,12 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba
closer.appendChild(contentElement);
document.body.appendChild(closer);
- editor.blur();
+ if (editor) {
+ editor.blur();
+ }
return {
- close: close
+ close: close,
+ setIgnoreFocusOut: setIgnoreFocusOut
};
};
diff --git a/htdocs/includes/ace/src/ext-language_tools.js b/htdocs/includes/ace/src/ext-language_tools.js
index 80af02df566..7e6967e0d7a 100644
--- a/htdocs/includes/ace/src/ext-language_tools.js
+++ b/htdocs/includes/ace/src/ext-language_tools.js
@@ -747,15 +747,16 @@ var TabstopManager = function(editor) {
this.onChange = function(delta) {
var isRemove = delta.action[0] == "r";
- var parents = this.selectedTabstop && this.selectedTabstop.parents || {};
+ var selectedTabstop = this.selectedTabstop || {};
+ var parents = selectedTabstop.parents || {};
var tabstops = (this.tabstops || []).slice();
for (var i = 0; i < tabstops.length; i++) {
var ts = tabstops[i];
- var active = ts == this.selectedTabstop || parents[ts.index];
+ var active = ts == selectedTabstop || parents[ts.index];
ts.rangeList.$bias = active ? 0 : 1;
- if (delta.action == "remove" && ts !== this.selectedTabstop) {
- var parentActive = ts.parents && ts.parents[this.selectedTabstop.index];
+ if (delta.action == "remove" && ts !== selectedTabstop) {
+ var parentActive = ts.parents && ts.parents[selectedTabstop.index];
var startIndex = ts.rangeList.pointIndex(delta.start, parentActive);
startIndex = startIndex < 0 ? -startIndex - 1 : startIndex + 1;
var endIndex = ts.rangeList.pointIndex(delta.end, parentActive);
@@ -868,8 +869,6 @@ var TabstopManager = function(editor) {
var ranges = this.ranges;
tabstops.forEach(function(ts, index) {
var dest = this.$openTabstops[index] || ts;
- ts.rangeList = new RangeList();
- ts.rangeList.$bias = 0;
for (var i = 0; i < ts.length; i++) {
var p = ts[i];
@@ -879,7 +878,6 @@ var TabstopManager = function(editor) {
range.original = p;
range.tabstop = dest;
ranges.push(range);
- ts.rangeList.ranges.push(range);
if (dest != ts)
dest.unshift(range);
else
@@ -897,6 +895,9 @@ var TabstopManager = function(editor) {
this.$openTabstops[index] = dest;
}
this.addTabstopMarkers(dest);
+ dest.rangeList = dest.rangeList || new RangeList();
+ dest.rangeList.$bias = 0;
+ dest.rangeList.addList(dest);
}, this);
if (arg.length > 2) {
@@ -939,21 +940,18 @@ var TabstopManager = function(editor) {
this.keyboardHandler = new HashHandler();
this.keyboardHandler.bindKeys({
- "Tab": function(ed) {
- if (exports.snippetManager && exports.snippetManager.expandWithTab(ed)) {
+ "Tab": function(editor) {
+ if (exports.snippetManager && exports.snippetManager.expandWithTab(editor))
return;
- }
-
- ed.tabstopManager.tabNext(1);
+ editor.tabstopManager.tabNext(1);
+ editor.renderer.scrollCursorIntoView();
},
- "Shift-Tab": function(ed) {
- ed.tabstopManager.tabNext(-1);
+ "Shift-Tab": function(editor) {
+ editor.tabstopManager.tabNext(-1);
+ editor.renderer.scrollCursorIntoView();
},
- "Esc": function(ed) {
- ed.tabstopManager.detach();
- },
- "Return": function(ed) {
- return false;
+ "Esc": function(editor) {
+ editor.tabstopManager.detach();
}
});
}).call(TabstopManager.prototype);
@@ -1355,7 +1353,7 @@ exports.parForEach = function(array, fn, callback) {
}
};
-var ID_REGEX = /[a-zA-Z_0-9\$\-\u00A2-\uFFFF]/;
+var ID_REGEX = /[a-zA-Z_0-9\$\-\u00A2-\u2000\u2070-\uFFFF]/;
exports.retrievePrecedingIdentifier = function(text, pos, regex) {
regex = regex || ID_REGEX;
diff --git a/htdocs/includes/ace/src/ext-modelist.js b/htdocs/includes/ace/src/ext-modelist.js
index 0032ecd178f..8b771ffeb99 100644
--- a/htdocs/includes/ace/src/ext-modelist.js
+++ b/htdocs/includes/ace/src/ext-modelist.js
@@ -101,6 +101,7 @@ var supportedModes = {
Jade: ["jade|pug"],
Java: ["java"],
JavaScript: ["js|jsm|jsx"],
+ JSON5: ["json5"],
JSON: ["json"],
JSONiq: ["jq"],
JSP: ["jsp"],
@@ -131,6 +132,7 @@ var supportedModes = {
Nix: ["nix"],
Nim: ["nim"],
NSIS: ["nsi|nsh"],
+ Nunjucks: ["nunjucks|nunjs|nj|njk"],
ObjectiveC: ["m|mm"],
OCaml: ["ml|mli"],
Pascal: ["pas|p"],
diff --git a/htdocs/includes/ace/src/ext-options.js b/htdocs/includes/ace/src/ext-options.js
index e01961df4ed..d1d01cefa05 100644
--- a/htdocs/includes/ace/src/ext-options.js
+++ b/htdocs/includes/ace/src/ext-options.js
@@ -65,6 +65,7 @@ dom.importCssString(cssText);
module.exports.overlayPage = function overlayPage(editor, contentElement, callback) {
var closer = document.createElement('div');
+ var ignoreFocusOut = false;
function documentEscListener(e) {
if (e.keyCode === 27) {
@@ -76,17 +77,28 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba
if (!closer) return;
document.removeEventListener('keydown', documentEscListener);
closer.parentNode.removeChild(closer);
- editor.focus();
+ if (editor) {
+ editor.focus();
+ }
closer = null;
callback && callback();
}
+ function setIgnoreFocusOut(ignore) {
+ ignoreFocusOut = ignore;
+ if (ignore) {
+ closer.style.pointerEvents = "none";
+ contentElement.style.pointerEvents = "auto";
+ }
+ }
closer.style.cssText = 'margin: 0; padding: 0; ' +
'position: fixed; top:0; bottom:0; left:0; right:0;' +
'z-index: 9990; ' +
- 'background-color: rgba(0, 0, 0, 0.3);';
- closer.addEventListener('click', function() {
- close();
+ (editor ? 'background-color: rgba(0, 0, 0, 0.3);' : '');
+ closer.addEventListener('click', function(e) {
+ if (!ignoreFocusOut) {
+ close();
+ }
});
document.addEventListener('keydown', documentEscListener);
@@ -96,9 +108,12 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba
closer.appendChild(contentElement);
document.body.appendChild(closer);
- editor.blur();
+ if (editor) {
+ editor.blur();
+ }
return {
- close: close
+ close: close,
+ setIgnoreFocusOut: setIgnoreFocusOut
};
};
@@ -207,6 +222,7 @@ var supportedModes = {
Jade: ["jade|pug"],
Java: ["java"],
JavaScript: ["js|jsm|jsx"],
+ JSON5: ["json5"],
JSON: ["json"],
JSONiq: ["jq"],
JSP: ["jsp"],
@@ -237,6 +253,7 @@ var supportedModes = {
Nix: ["nix"],
Nim: ["nim"],
NSIS: ["nsi|nsh"],
+ Nunjucks: ["nunjucks|nunjs|nj|njk"],
ObjectiveC: ["m|mm"],
OCaml: ["ml|mli"],
Pascal: ["pas|p"],
@@ -396,9 +413,9 @@ exports.themes = themeData.map(function(data) {
define("ace/ext/options",["require","exports","module","ace/ext/menu_tools/overlay_page","ace/lib/dom","ace/lib/oop","ace/config","ace/lib/event_emitter","ace/ext/modelist","ace/ext/themelist"], function(require, exports, module) {
"use strict";
-var overlayPage = require('./menu_tools/overlay_page').overlayPage;
-
+require("./menu_tools/overlay_page");
+
var dom = require("../lib/dom");
var oop = require("../lib/oop");
var config = require("../config");
@@ -437,7 +454,8 @@ var optionGroups = {
{ caption : "Ace", value : null },
{ caption : "Vim", value : "ace/keyboard/vim" },
{ caption : "Emacs", value : "ace/keyboard/emacs" },
- { caption : "Sublime", value : "ace/keyboard/sublime" }
+ { caption : "Sublime", value : "ace/keyboard/sublime" },
+ { caption : "VSCode", value : "ace/keyboard/vscode" }
]
},
"Font Size": {
diff --git a/htdocs/includes/ace/src/ext-prompt.js b/htdocs/includes/ace/src/ext-prompt.js
index 815c7cda214..bcc99f70806 100644
--- a/htdocs/includes/ace/src/ext-prompt.js
+++ b/htdocs/includes/ace/src/ext-prompt.js
@@ -387,7 +387,7 @@ exports.parForEach = function(array, fn, callback) {
}
};
-var ID_REGEX = /[a-zA-Z_0-9\$\-\u00A2-\uFFFF]/;
+var ID_REGEX = /[a-zA-Z_0-9\$\-\u00A2-\u2000\u2070-\uFFFF]/;
exports.retrievePrecedingIdentifier = function(text, pos, regex) {
regex = regex || ID_REGEX;
@@ -1179,15 +1179,16 @@ var TabstopManager = function(editor) {
this.onChange = function(delta) {
var isRemove = delta.action[0] == "r";
- var parents = this.selectedTabstop && this.selectedTabstop.parents || {};
+ var selectedTabstop = this.selectedTabstop || {};
+ var parents = selectedTabstop.parents || {};
var tabstops = (this.tabstops || []).slice();
for (var i = 0; i < tabstops.length; i++) {
var ts = tabstops[i];
- var active = ts == this.selectedTabstop || parents[ts.index];
+ var active = ts == selectedTabstop || parents[ts.index];
ts.rangeList.$bias = active ? 0 : 1;
- if (delta.action == "remove" && ts !== this.selectedTabstop) {
- var parentActive = ts.parents && ts.parents[this.selectedTabstop.index];
+ if (delta.action == "remove" && ts !== selectedTabstop) {
+ var parentActive = ts.parents && ts.parents[selectedTabstop.index];
var startIndex = ts.rangeList.pointIndex(delta.start, parentActive);
startIndex = startIndex < 0 ? -startIndex - 1 : startIndex + 1;
var endIndex = ts.rangeList.pointIndex(delta.end, parentActive);
@@ -1300,8 +1301,6 @@ var TabstopManager = function(editor) {
var ranges = this.ranges;
tabstops.forEach(function(ts, index) {
var dest = this.$openTabstops[index] || ts;
- ts.rangeList = new RangeList();
- ts.rangeList.$bias = 0;
for (var i = 0; i < ts.length; i++) {
var p = ts[i];
@@ -1311,7 +1310,6 @@ var TabstopManager = function(editor) {
range.original = p;
range.tabstop = dest;
ranges.push(range);
- ts.rangeList.ranges.push(range);
if (dest != ts)
dest.unshift(range);
else
@@ -1329,6 +1327,9 @@ var TabstopManager = function(editor) {
this.$openTabstops[index] = dest;
}
this.addTabstopMarkers(dest);
+ dest.rangeList = dest.rangeList || new RangeList();
+ dest.rangeList.$bias = 0;
+ dest.rangeList.addList(dest);
}, this);
if (arg.length > 2) {
@@ -1371,21 +1372,18 @@ var TabstopManager = function(editor) {
this.keyboardHandler = new HashHandler();
this.keyboardHandler.bindKeys({
- "Tab": function(ed) {
- if (exports.snippetManager && exports.snippetManager.expandWithTab(ed)) {
+ "Tab": function(editor) {
+ if (exports.snippetManager && exports.snippetManager.expandWithTab(editor))
return;
- }
-
- ed.tabstopManager.tabNext(1);
+ editor.tabstopManager.tabNext(1);
+ editor.renderer.scrollCursorIntoView();
},
- "Shift-Tab": function(ed) {
- ed.tabstopManager.tabNext(-1);
+ "Shift-Tab": function(editor) {
+ editor.tabstopManager.tabNext(-1);
+ editor.renderer.scrollCursorIntoView();
},
- "Esc": function(ed) {
- ed.tabstopManager.detach();
- },
- "Return": function(ed) {
- return false;
+ "Esc": function(editor) {
+ editor.tabstopManager.detach();
}
});
}).call(TabstopManager.prototype);
@@ -2004,6 +2002,7 @@ dom.importCssString(cssText);
module.exports.overlayPage = function overlayPage(editor, contentElement, callback) {
var closer = document.createElement('div');
+ var ignoreFocusOut = false;
function documentEscListener(e) {
if (e.keyCode === 27) {
@@ -2015,17 +2014,28 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba
if (!closer) return;
document.removeEventListener('keydown', documentEscListener);
closer.parentNode.removeChild(closer);
- editor.focus();
+ if (editor) {
+ editor.focus();
+ }
closer = null;
callback && callback();
}
+ function setIgnoreFocusOut(ignore) {
+ ignoreFocusOut = ignore;
+ if (ignore) {
+ closer.style.pointerEvents = "none";
+ contentElement.style.pointerEvents = "auto";
+ }
+ }
closer.style.cssText = 'margin: 0; padding: 0; ' +
'position: fixed; top:0; bottom:0; left:0; right:0;' +
'z-index: 9990; ' +
- 'background-color: rgba(0, 0, 0, 0.3);';
- closer.addEventListener('click', function() {
- close();
+ (editor ? 'background-color: rgba(0, 0, 0, 0.3);' : '');
+ closer.addEventListener('click', function(e) {
+ if (!ignoreFocusOut) {
+ close();
+ }
});
document.addEventListener('keydown', documentEscListener);
@@ -2035,9 +2045,12 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba
closer.appendChild(contentElement);
document.body.appendChild(closer);
- editor.blur();
+ if (editor) {
+ editor.blur();
+ }
return {
- close: close
+ close: close,
+ setIgnoreFocusOut: setIgnoreFocusOut
};
};
@@ -2146,6 +2159,7 @@ var supportedModes = {
Jade: ["jade|pug"],
Java: ["java"],
JavaScript: ["js|jsm|jsx"],
+ JSON5: ["json5"],
JSON: ["json"],
JSONiq: ["jq"],
JSP: ["jsp"],
@@ -2176,6 +2190,7 @@ var supportedModes = {
Nix: ["nix"],
Nim: ["nim"],
NSIS: ["nsi|nsh"],
+ Nunjucks: ["nunjucks|nunjs|nj|njk"],
ObjectiveC: ["m|mm"],
OCaml: ["ml|mli"],
Pascal: ["pas|p"],
@@ -2305,14 +2320,18 @@ function prompt(editor, message, options, callback) {
var cmdLine = $singleLineEditor();
cmdLine.session.setUndoManager(new UndoManager());
- cmdLine.setOption("fontSize", editor.getOption("fontSize"));
- var el = dom.buildDom(["div", {class: "ace_prompt_container"}]);
+ var el = dom.buildDom(["div", {class: "ace_prompt_container" + (options.hasDescription ? " input-box-with-description" : "")}]);
var overlay = overlayPage(editor, el, done);
el.appendChild(cmdLine.container);
- editor.cmdLine = cmdLine;
- cmdLine.setValue(message, 1);
+ if (editor) {
+ editor.cmdLine = cmdLine;
+ cmdLine.setOption("fontSize", editor.getOption("fontSize"));
+ }
+ if (message) {
+ cmdLine.setValue(message, 1);
+ }
if (options.selection) {
cmdLine.selection.setRange({
start: cmdLine.session.doc.indexToPosition(options.selection[0]),
@@ -2348,14 +2367,26 @@ function prompt(editor, message, options, callback) {
cmdLine.session.bgTokenizer.setTokenizer(tokenizer);
}
+ if (options.placeholder) {
+ cmdLine.setOption("placeholder", options.placeholder);
+ }
+
+ if (options.hasDescription) {
+ var promptTextContainer = dom.buildDom(["div", {class: "ace_prompt_text_container"}]);
+ dom.buildDom(options.prompt || "Press 'Enter' to confirm or 'Escape' to cancel", promptTextContainer);
+ el.appendChild(promptTextContainer);
+ }
+
+ overlay.setIgnoreFocusOut(options.ignoreFocusOut);
+
function accept() {
var val;
- if (popup.getCursorPosition().row > 0) {
+ if (popup && popup.getCursorPosition().row > 0) {
val = valueFromRecentList();
} else {
val = cmdLine.getValue();
}
- var curData = popup.getData(popup.getRow());
+ var curData = popup ? popup.getData(popup.getRow()) : val;
if (curData && !curData.error) {
done();
options.onAccept && options.onAccept({
@@ -2365,22 +2396,29 @@ function prompt(editor, message, options, callback) {
}
}
- cmdLine.commands.bindKeys({
+ var keys = {
"Enter": accept,
"Esc|Shift-Esc": function() {
options.onCancel && options.onCancel(cmdLine.getValue(), cmdLine);
done();
- },
- "Up": function(editor) { popup.goTo("up"); valueFromRecentList();},
- "Down": function(editor) { popup.goTo("down"); valueFromRecentList();},
- "Ctrl-Up|Ctrl-Home": function(editor) { popup.goTo("start"); valueFromRecentList();},
- "Ctrl-Down|Ctrl-End": function(editor) { popup.goTo("end"); valueFromRecentList();},
- "Tab": function(editor) {
- popup.goTo("down"); valueFromRecentList();
- },
- "PageUp": function(editor) { popup.gotoPageUp(); valueFromRecentList();},
- "PageDown": function(editor) { popup.gotoPageDown(); valueFromRecentList();}
- });
+ }
+ };
+
+ if (popup) {
+ Object.assign(keys, {
+ "Up": function(editor) { popup.goTo("up"); valueFromRecentList();},
+ "Down": function(editor) { popup.goTo("down"); valueFromRecentList();},
+ "Ctrl-Up|Ctrl-Home": function(editor) { popup.goTo("start"); valueFromRecentList();},
+ "Ctrl-Down|Ctrl-End": function(editor) { popup.goTo("end"); valueFromRecentList();},
+ "Tab": function(editor) {
+ popup.goTo("down"); valueFromRecentList();
+ },
+ "PageUp": function(editor) { popup.gotoPageUp(); valueFromRecentList();},
+ "PageDown": function(editor) { popup.gotoPageDown(); valueFromRecentList();}
+ });
+ }
+
+ cmdLine.commands.bindKeys(keys);
function done() {
overlay.close();
@@ -2413,7 +2451,9 @@ function prompt(editor, message, options, callback) {
}
cmdLine.resize(true);
- popup.resize(true);
+ if (popup) {
+ popup.resize(true);
+ }
cmdLine.focus();
openPrompt = {
diff --git a/htdocs/includes/ace/src/ext-settings_menu.js b/htdocs/includes/ace/src/ext-settings_menu.js
index d10afac8f34..ebfa4108519 100644
--- a/htdocs/includes/ace/src/ext-settings_menu.js
+++ b/htdocs/includes/ace/src/ext-settings_menu.js
@@ -65,6 +65,7 @@ dom.importCssString(cssText);
module.exports.overlayPage = function overlayPage(editor, contentElement, callback) {
var closer = document.createElement('div');
+ var ignoreFocusOut = false;
function documentEscListener(e) {
if (e.keyCode === 27) {
@@ -76,17 +77,28 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba
if (!closer) return;
document.removeEventListener('keydown', documentEscListener);
closer.parentNode.removeChild(closer);
- editor.focus();
+ if (editor) {
+ editor.focus();
+ }
closer = null;
callback && callback();
}
+ function setIgnoreFocusOut(ignore) {
+ ignoreFocusOut = ignore;
+ if (ignore) {
+ closer.style.pointerEvents = "none";
+ contentElement.style.pointerEvents = "auto";
+ }
+ }
closer.style.cssText = 'margin: 0; padding: 0; ' +
'position: fixed; top:0; bottom:0; left:0; right:0;' +
'z-index: 9990; ' +
- 'background-color: rgba(0, 0, 0, 0.3);';
- closer.addEventListener('click', function() {
- close();
+ (editor ? 'background-color: rgba(0, 0, 0, 0.3);' : '');
+ closer.addEventListener('click', function(e) {
+ if (!ignoreFocusOut) {
+ close();
+ }
});
document.addEventListener('keydown', documentEscListener);
@@ -96,9 +108,12 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba
closer.appendChild(contentElement);
document.body.appendChild(closer);
- editor.blur();
+ if (editor) {
+ editor.blur();
+ }
return {
- close: close
+ close: close,
+ setIgnoreFocusOut: setIgnoreFocusOut
};
};
@@ -207,6 +222,7 @@ var supportedModes = {
Jade: ["jade|pug"],
Java: ["java"],
JavaScript: ["js|jsm|jsx"],
+ JSON5: ["json5"],
JSON: ["json"],
JSONiq: ["jq"],
JSP: ["jsp"],
@@ -237,6 +253,7 @@ var supportedModes = {
Nix: ["nix"],
Nim: ["nim"],
NSIS: ["nsi|nsh"],
+ Nunjucks: ["nunjucks|nunjs|nj|njk"],
ObjectiveC: ["m|mm"],
OCaml: ["ml|mli"],
Pascal: ["pas|p"],
@@ -396,9 +413,9 @@ exports.themes = themeData.map(function(data) {
define("ace/ext/options",["require","exports","module","ace/ext/menu_tools/overlay_page","ace/lib/dom","ace/lib/oop","ace/config","ace/lib/event_emitter","ace/ext/modelist","ace/ext/themelist"], function(require, exports, module) {
"use strict";
-var overlayPage = require('./menu_tools/overlay_page').overlayPage;
-
+require("./menu_tools/overlay_page");
+
var dom = require("../lib/dom");
var oop = require("../lib/oop");
var config = require("../config");
@@ -437,7 +454,8 @@ var optionGroups = {
{ caption : "Ace", value : null },
{ caption : "Vim", value : "ace/keyboard/vim" },
{ caption : "Emacs", value : "ace/keyboard/emacs" },
- { caption : "Sublime", value : "ace/keyboard/sublime" }
+ { caption : "Sublime", value : "ace/keyboard/sublime" },
+ { caption : "VSCode", value : "ace/keyboard/vscode" }
]
},
"Font Size": {
diff --git a/htdocs/includes/ace/src/ext-spellcheck.js b/htdocs/includes/ace/src/ext-spellcheck.js
index 6f5af5049d7..10d3901f49f 100644
--- a/htdocs/includes/ace/src/ext-spellcheck.js
+++ b/htdocs/includes/ace/src/ext-spellcheck.js
@@ -28,7 +28,6 @@ exports.contextMenuHandler = function(e){
});
host.textInput.setInputHandler(function(newVal) {
- console.log(newVal , value, text.selectionStart, text.selectionEnd);
if (newVal == value)
return '';
if (newVal.lastIndexOf(value, 0) === 0)
diff --git a/htdocs/includes/ace/src/keybinding-emacs.js b/htdocs/includes/ace/src/keybinding-emacs.js
index 960ff734b3d..58e79cd44fc 100644
--- a/htdocs/includes/ace/src/keybinding-emacs.js
+++ b/htdocs/includes/ace/src/keybinding-emacs.js
@@ -548,8 +548,6 @@ function objectToRegExp(obj) {
if (this.$editor.showCommandLine) {
this.$editor.showCommandLine(msg);
this.$editor.focus();
- } else {
- console.log(msg);
}
};
diff --git a/htdocs/includes/ace/src/keybinding-sublime.js b/htdocs/includes/ace/src/keybinding-sublime.js
index e34735b2ae0..21fcb3803c6 100644
--- a/htdocs/includes/ace/src/keybinding-sublime.js
+++ b/htdocs/includes/ace/src/keybinding-sublime.js
@@ -1,9 +1,6 @@
-define("ace/keyboard/sublime",["require","exports","module","ace/lib/keys","ace/lib/oop","ace/lib/useragent","ace/keyboard/hash_handler"], function(require, exports, module) {
+define("ace/keyboard/sublime",["require","exports","module","ace/keyboard/hash_handler"], function(require, exports, module) {
"use strict";
-var keyUtil = require("../lib/keys");
-var oop = require("../lib/oop");
-var useragent = require("../lib/useragent");
var HashHandler = require("../keyboard/hash_handler").HashHandler;
function moveBySubWords(editor, direction, extend) {
@@ -373,7 +370,7 @@ exports.handler.addCommands([{
},
{
bindKey: { mac: "cmd-shift-l", win: "ctrl-shift-l" },
- name: "splitIntoLines"
+ name: "splitSelectionIntoLines"
}, {
bindKey: { mac: "ctrl-cmd-down", win: "ctrl-shift-down" },
name: "movelinesdown"
diff --git a/htdocs/includes/ace/src/keybinding-vim.js b/htdocs/includes/ace/src/keybinding-vim.js
index 889c2269ac7..79761280e93 100644
--- a/htdocs/includes/ace/src/keybinding-vim.js
+++ b/htdocs/includes/ace/src/keybinding-vim.js
@@ -435,6 +435,7 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve
if (!e) e = s;
return this.ace.session.replace(new Range(s.line, s.ch, e.line, e.ch), text);
};
+ this.replaceSelection =
this.replaceSelections = function(p) {
var sel = this.ace.selection;
if (this.ace.inVirtualSelectionMode) {
@@ -846,6 +847,8 @@ dom.importCssString(".normal-mode .ace_cursor{\
{ keys: '', type: 'keyToKey', toKeys: '' },
{ keys: '', type: 'keyToKey', toKeys: '', context: 'insert' },
{ keys: '', type: 'keyToKey', toKeys: '', context: 'insert' },
+ { keys: '', type: 'keyToKey', toKeys: '' }, // ace_patch ipad keyboard sends C-Esc instead of C-[
+ { keys: '', type: 'keyToKey', toKeys: '', context: 'insert' },
{ keys: 's', type: 'keyToKey', toKeys: 'cl', context: 'normal' },
{ keys: 's', type: 'keyToKey', toKeys: 'c', context: 'visual'},
{ keys: 'S', type: 'keyToKey', toKeys: 'cc', context: 'normal' },
@@ -940,7 +943,9 @@ dom.importCssString(".normal-mode .ace_cursor{\
{ keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'eol' }, context: 'normal' },
{ keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'endOfSelectedArea' }, context: 'visual' },
{ keys: 'i', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'inplace' }, context: 'normal' },
+ { keys: 'gi', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'lastEdit' }, context: 'normal' },
{ keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'firstNonBlank'}, context: 'normal' },
+ { keys: 'gI', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'bol'}, context: 'normal' },
{ keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'startOfSelectedArea' }, context: 'visual' },
{ keys: 'o', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: true }, context: 'normal' },
{ keys: 'O', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: false }, context: 'normal' },
@@ -950,6 +955,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
{ keys: '', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }},
{ keys: 'gv', type: 'action', action: 'reselectLastSelection' },
{ keys: 'J', type: 'action', action: 'joinLines', isEdit: true },
+ { keys: 'gJ', type: 'action', action: 'joinLines', actionArgs: { keepSpaces: true }, isEdit: true },
{ keys: 'p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true }},
{ keys: 'P', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true }},
{ keys: 'r', type: 'action', action: 'replace', isEdit: true },
@@ -1026,7 +1032,6 @@ dom.importCssString(".normal-mode .ace_cursor{\
CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm));
cm.state.vim = null;
}
-
function detachVimMap(cm, next) {
if (this == CodeMirror.keyMap.vim)
CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor");
@@ -1296,9 +1301,16 @@ dom.importCssString(".normal-mode .ace_cursor{\
}
return mark;
}
+ function find(cm, offset) {
+ var oldPointer = pointer;
+ var mark = move(cm, offset);
+ pointer = oldPointer;
+ return mark && mark.find();
+ }
return {
cachedCursor: undefined, //used for # and * jumps
add: add,
+ find: find,
move: move
};
};
@@ -1943,6 +1955,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
});
}
function onPromptClose(query) {
+ cm.scrollTo(originalScrollPos.left, originalScrollPos.top);
handleQuery(query, true /** ignoreCase */, true /** smartCase */);
var macroModeState = vimGlobalState.macroModeState;
if (macroModeState.isRecording) {
@@ -2514,7 +2527,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
}
}
if (ch < lineText.length) {
- var re = /[<>]/.test(lineText[ch]) ? /[(){}[\]<>]/ : /[(){}[\]]/;
+ var re = /[<>]/.test(lineText[ch]) ? /[(){}[\]<>]/ : /[(){}[\]]/; //ace_patch?
var matched = cm.findMatchingBracket(Pos(line, ch+1), {bracketRegex: re});
return matched.to;
} else {
@@ -2643,8 +2656,8 @@ dom.importCssString(".normal-mode .ace_cursor{\
head.line--;
cm.setSelection(anchor, head)
text = cm.getSelection();
- cm.replaceSelections("");
- finalHead = anchor
+ cm.replaceSelection("");
+ finalHead = anchor;
} else {
text = cm.getSelection();
var replacement = fillArray('', ranges.length);
@@ -2864,6 +2877,8 @@ dom.importCssString(".normal-mode .ace_cursor{\
var height = cm.listSelections().length;
if (insertAt == 'eol') {
head = Pos(head.line, lineLength(cm, head.line));
+ } else if (insertAt == 'bol') {
+ head = Pos(head.line, 0);
} else if (insertAt == 'charAfter') {
head = offsetCursor(head, 0, 1);
} else if (insertAt == 'firstNonBlank') {
@@ -2902,6 +2917,8 @@ dom.importCssString(".normal-mode .ace_cursor{\
if (vim.visualMode){
return;
}
+ } else if (insertAt == 'lastEdit') {
+ head = getLastEditPos(cm) || head;
}
cm.setOption('disableInput', false);
if (actionArgs && actionArgs.replace) {
@@ -3001,7 +3018,9 @@ dom.importCssString(".normal-mode .ace_cursor{\
var tmp = Pos(curStart.line + 1,
lineLength(cm, curStart.line + 1));
var text = cm.getRange(curStart, tmp);
- text = text.replace(/\n\s*/g, ' ');
+ text = actionArgs.keepSpaces
+ ? text.replace(/\n\r?/g, '')
+ : text.replace(/\n\s*/g, ' ');
cm.replaceRange(text, curStart, tmp);
}
var curFinalPos = Pos(curStart.line, finalCh);
@@ -4583,11 +4602,22 @@ dom.importCssString(".normal-mode .ace_cursor{\
}
function getMarkPos(cm, vim, markName) {
+ if (markName == '\'' || markName == '`') {
+ return vimGlobalState.jumpList.find(cm, -1) || Pos(0, 0);
+ } else if (markName == '.') {
+ return getLastEditPos(cm);
+ }
var mark = vim.marks[markName];
return mark && mark.find();
}
+ function getLastEditPos(cm) {
+ var undoManager = cm.ace.session.$undoManager;
+ if (undoManager && undoManager.$lastDelta)
+ return toCmPos(undoManager.$lastDelta.end);
+ }
+
var ExCommandDispatcher = function() {
this.buildCommandMap_();
};
@@ -5068,6 +5098,9 @@ dom.importCssString(".normal-mode .ace_cursor{\
var global = false; // True to replace all instances on a line, false to replace only 1.
if (tokens.length) {
regexPart = tokens[0];
+ if (getOption('pcre') && regexPart !== '') {
+ regexPart = new RegExp(regexPart).source; //normalize not escaped characters
+ }
replacePart = tokens[1];
if (regexPart && regexPart[regexPart.length - 1] === '$') {
regexPart = regexPart.slice(0, regexPart.length - 1) + '\\n';
@@ -5075,7 +5108,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
}
if (replacePart !== undefined) {
if (getOption('pcre')) {
- replacePart = unescapeRegexReplace(replacePart);
+ replacePart = unescapeRegexReplace(replacePart.replace(/([^\\])&/g,"$1$$&"));
} else {
replacePart = translateRegexReplace(replacePart);
}
@@ -5101,7 +5134,11 @@ dom.importCssString(".normal-mode .ace_cursor{\
global = true;
flagsPart.replace('g', '');
}
- regexPart = regexPart.replace(/\//g, "\\/") + '/' + flagsPart;
+ if (getOption('pcre')) {
+ regexPart = regexPart + '/' + flagsPart;
+ } else {
+ regexPart = regexPart.replace(/\//g, "\\/") + '/' + flagsPart;
+ }
}
}
if (regexPart) {
diff --git a/htdocs/includes/ace/src/keybinding-vscode.js b/htdocs/includes/ace/src/keybinding-vscode.js
new file mode 100644
index 00000000000..45ac5cf03ff
--- /dev/null
+++ b/htdocs/includes/ace/src/keybinding-vscode.js
@@ -0,0 +1,262 @@
+define("ace/keyboard/vscode",["require","exports","module","ace/keyboard/hash_handler","ace/config"], function(require, exports, module) {
+"use strict";
+
+var HashHandler = require("../keyboard/hash_handler").HashHandler;
+var config = require("../config");
+
+exports.handler = new HashHandler();
+exports.handler.$id = "ace/keyboard/vscode";
+
+exports.handler.addCommands([{
+ name: "toggleWordWrap",
+ exec: function(editor) {
+ var wrapUsed = editor.session.getUseWrapMode();
+ editor.session.setUseWrapMode(!wrapUsed);
+ },
+ readOnly: true
+}, {
+ name: "navigateToLastEditLocation",
+ exec: function(editor) {
+ var lastDelta = editor.session.getUndoManager().$lastDelta;
+ var range = (lastDelta.action == "remove")? lastDelta.start: lastDelta.end;
+ editor.moveCursorTo(range.row, range.column);
+ editor.clearSelection();
+ }
+}, {
+ name: "replaceAll",
+ exec: function (editor) {
+ if (!editor.searchBox) {
+ config.loadModule("ace/ext/searchbox", function(e) {
+ e.Search(editor, true);
+ });
+ } else {
+ if (editor.searchBox.active === true && editor.searchBox.replaceOption.checked === true) {
+ editor.searchBox.replaceAll();
+ }
+ }
+ }
+}, {
+ name: "replaceOne",
+ exec: function (editor) {
+ if (!editor.searchBox) {
+ config.loadModule("ace/ext/searchbox", function(e) {
+ e.Search(editor, true);
+ });
+ } else {
+ if (editor.searchBox.active === true && editor.searchBox.replaceOption.checked === true) {
+ editor.searchBox.replace();
+ }
+ }
+ }
+}, {
+ name: "selectAllMatches",
+ exec: function (editor) {
+ if (!editor.searchBox) {
+ config.loadModule("ace/ext/searchbox", function(e) {
+ e.Search(editor, false);
+ });
+ } else {
+ if (editor.searchBox.active === true) {
+ editor.searchBox.findAll();
+ }
+ }
+ }
+}, {
+ name: "toggleFindCaseSensitive",
+ exec: function (editor) {
+ config.loadModule("ace/ext/searchbox", function(e) {
+ e.Search(editor, false);
+ var sb = editor.searchBox;
+ sb.caseSensitiveOption.checked = !sb.caseSensitiveOption.checked;
+ sb.$syncOptions();
+ });
+
+ }
+}, {
+ name: "toggleFindInSelection",
+ exec: function (editor) {
+ config.loadModule("ace/ext/searchbox", function(e) {
+ e.Search(editor, false);
+ var sb = editor.searchBox;
+ sb.searchOption.checked = !sb.searchRange;
+ sb.setSearchRange(sb.searchOption.checked && sb.editor.getSelectionRange());
+ sb.$syncOptions();
+ });
+ }
+}, {
+ name: "toggleFindRegex",
+ exec: function (editor) {
+ config.loadModule("ace/ext/searchbox", function(e) {
+ e.Search(editor, false);
+ var sb = editor.searchBox;
+ sb.regExpOption.checked = !sb.regExpOption.checked;
+ sb.$syncOptions();
+ });
+ }
+}, {
+ name: "toggleFindWholeWord",
+ exec: function (editor) {
+ config.loadModule("ace/ext/searchbox", function(e) {
+ e.Search(editor, false);
+ var sb = editor.searchBox;
+ sb.wholeWordOption.checked = !sb.wholeWordOption.checked;
+ sb.$syncOptions();
+ });
+ }
+}, {
+ name: "removeSecondaryCursors",
+ exec: function (editor) {
+ var ranges = editor.selection.ranges;
+ if (ranges && ranges.length > 1)
+ editor.selection.toSingleRange(ranges[ranges.length - 1]);
+ else
+ editor.selection.clearSelection();
+ }
+}]);
+
+
+[{
+ bindKey: {mac: "Control-G", win: "Ctrl-G"},
+ name: "gotoline"
+}, {
+ bindKey: {mac: "Command-Shift-L|Command-F2", win: "Ctrl-Shift-L|Ctrl-F2"},
+ name: "findAll"
+}, {
+ bindKey: {mac: "Shift-F8|Shift-Option-F8", win: "Shift-F8|Shift-Alt-F8"},
+ name: "goToPreviousError"
+}, {
+ bindKey: {mac: "F8|Option-F8", win: "F8|Alt-F8"},
+ name: "goToNextError"
+}, {
+ bindKey: {mac: "Command-Shift-P|F1", win: "Ctrl-Shift-P|F1"},
+ name: "openCommandPallete"
+}, {
+ bindKey: {mac: "Command-K|Command-S", win: "Ctrl-K|Ctrl-S"},
+ name: "showKeyboardShortcuts"
+}, {
+ bindKey: {mac: "Shift-Option-Up", win: "Alt-Shift-Up"},
+ name: "copylinesup"
+}, {
+ bindKey: {mac: "Shift-Option-Down", win: "Alt-Shift-Down"},
+ name: "copylinesdown"
+}, {
+ bindKey: {mac: "Command-Shift-K", win: "Ctrl-Shift-K"},
+ name: "removeline"
+}, {
+ bindKey: {mac: "Command-Enter", win: "Ctrl-Enter"},
+ name: "addLineAfter"
+}, {
+ bindKey: {mac: "Command-Shift-Enter", win: "Ctrl-Shift-Enter"},
+ name: "addLineBefore"
+}, {
+ bindKey: {mac: "Command-Shift-\\", win: "Ctrl-Shift-\\"},
+ name: "jumptomatching"
+}, {
+ bindKey: {mac: "Command-]", win: "Ctrl-]"},
+ name: "blockindent"
+}, {
+ bindKey: {mac: "Command-[", win: "Ctrl-["},
+ name: "blockoutdent"
+}, {
+ bindKey: {mac: "Control-PageDown", win: "Alt-PageDown"},
+ name: "pagedown"
+}, {
+ bindKey: {mac: "Control-PageUp", win: "Alt-PageUp"},
+ name: "pageup"
+}, {
+ bindKey: {mac: "Shift-Option-A", win: "Shift-Alt-A"},
+ name: "toggleBlockComment"
+}, {
+ bindKey: {mac: "Option-Z", win: "Alt-Z"},
+ name: "toggleWordWrap"
+}, {
+ bindKey: {mac: "Command-G", win: "F3|Ctrl-K Ctrl-D"},
+ name: "findnext"
+}, {
+ bindKey: {mac: "Command-Shift-G", win: "Shift-F3"},
+ name: "findprevious"
+}, {
+ bindKey: {mac: "Option-Enter", win: "Alt-Enter"},
+ name: "selectAllMatches"
+}, {
+ bindKey: {mac: "Command-D", win: "Ctrl-D"},
+ name: "selectMoreAfter"
+}, {
+ bindKey: {mac: "Command-K Command-D", win: "Ctrl-K Ctrl-D"},
+ name: "selectOrFindNext"
+}, {
+ bindKey: {mac: "Shift-Option-I", win: "Shift-Alt-I"},
+ name: "splitSelectionIntoLines"
+}, {
+ bindKey: {mac: "Command-K M", win: "Ctrl-K M"},
+ name: "modeSelect"
+}, {
+ bindKey: {mac: "Command-Option-[", win: "Ctrl-Shift-["},
+ name: "toggleFoldWidget"
+}, {
+ bindKey: {mac: "Command-Option-]", win: "Ctrl-Shift-]"},
+ name: "toggleFoldWidget"
+}, {
+ bindKey: {mac: "Command-K Command-0", win: "Ctrl-K Ctrl-0"},
+ name: "foldall"
+}, {
+ bindKey: {mac: "Command-K Command-J", win: "Ctrl-K Ctrl-J"},
+ name: "unfoldall"
+}, {
+ bindKey: { mac: "Command-K Command-1", win: "Ctrl-K Ctrl-1" },
+ name: "foldOther"
+}, {
+ bindKey: { mac: "Command-K Command-Q", win: "Ctrl-K Ctrl-Q" },
+ name: "navigateToLastEditLocation"
+}, {
+ bindKey: { mac: "Command-K Command-R|Command-K Command-S", win: "Ctrl-K Ctrl-R|Ctrl-K Ctrl-S" },
+ name: "showKeyboardShortcuts"
+}, {
+ bindKey: { mac: "Command-K Command-X", win: "Ctrl-K Ctrl-X" },
+ name: "trimTrailingSpace"
+}, {
+ bindKey: {mac: "Shift-Down|Command-Shift-Down", win: "Shift-Down|Ctrl-Shift-Down"},
+ name: "selectdown"
+}, {
+ bindKey: {mac: "Shift-Up|Command-Shift-Up", win: "Shift-Up|Ctrl-Shift-Up"},
+ name: "selectup"
+}, {
+ bindKey: {mac: "Command-Alt-Enter", win: "Ctrl-Alt-Enter"},
+ name: "replaceAll"
+}, {
+ bindKey: {mac: "Command-Shift-1", win: "Ctrl-Shift-1"},
+ name: "replaceOne"
+}, {
+ bindKey: {mac: "Option-C", win: "Alt-C"},
+ name: "toggleFindCaseSensitive"
+}, {
+ bindKey: {mac: "Option-L", win: "Alt-L"},
+ name: "toggleFindInSelection"
+}, {
+ bindKey: {mac: "Option-R", win: "Alt-R"},
+ name: "toggleFindRegex"
+}, {
+ bindKey: {mac: "Option-W", win: "Alt-W"},
+ name: "toggleFindWholeWord"
+}, {
+ bindKey: {mac: "Command-L", win: "Ctrl-L"},
+ name: "expandtoline"
+}, {
+ bindKey: {mac: "Shift-Esc", win: "Shift-Esc"},
+ name: "removeSecondaryCursors"
+}
+].forEach(function(binding) {
+ var command = exports.handler.commands[binding.name];
+ if (command)
+ command.bindKey = binding.bindKey;
+ exports.handler.bindKey(binding.bindKey, command || binding.name);
+});
+
+}); (function() {
+ window.require(["ace/keyboard/vscode"], function(m) {
+ if (typeof module == "object" && typeof exports == "object" && module) {
+ module.exports = m;
+ }
+ });
+ })();
+
\ No newline at end of file
diff --git a/htdocs/includes/ace/src/mode-csound_document.js b/htdocs/includes/ace/src/mode-csound_document.js
index b4495c6892f..ae92fce17e1 100644
--- a/htdocs/includes/ace/src/mode-csound_document.js
+++ b/htdocs/includes/ace/src/mode-csound_document.js
@@ -1146,6 +1146,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"ampdb",
"ampdbfs",
"ampmidi",
+ "ampmidicurve",
"ampmidid",
"areson",
"aresonk",
@@ -1194,7 +1195,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"ceps",
"cepsinv",
"chanctrl",
- "changed",
"changed2",
"chani",
"chano",
@@ -1363,6 +1363,17 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"flooper",
"flooper2",
"floor",
+ "fluidAllOut",
+ "fluidCCi",
+ "fluidCCk",
+ "fluidControl",
+ "fluidEngine",
+ "fluidInfo",
+ "fluidLoad",
+ "fluidNote",
+ "fluidOut",
+ "fluidProgramSelect",
+ "fluidSetInterpMethod",
"fmanal",
"fmax",
"fmb3",
@@ -1437,6 +1448,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"grain2",
"grain3",
"granule",
+ "gtf",
"guiro",
"harmon",
"harmon2",
@@ -1845,6 +1857,8 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"nsamp",
"nstance",
"nstrnum",
+ "nstrstr",
+ "ntof",
"ntom",
"ntrpol",
"nxtpow2",
@@ -1975,7 +1989,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"ptable",
"ptable3",
"ptablei",
- "ptableiw",
"ptablew",
"ptrack",
"puts",
@@ -2282,6 +2295,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"strget",
"strindex",
"strindexk",
+ "string2array",
"strlen",
"strlenk",
"strlower",
@@ -2325,7 +2339,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"tableigpw",
"tableikt",
"tableimix",
- "tableiw",
"tablekt",
"tablemix",
"tableng",
@@ -2533,6 +2546,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"array",
"bformdec",
"bformenc",
+ "changed",
"copy2ftab",
"copy2ttab",
"hrtfer",
@@ -2542,6 +2556,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"mintab",
"pop",
"pop_f",
+ "ptableiw",
"push",
"push_f",
"scalet",
@@ -2560,6 +2575,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"stack",
"sumtab",
"tabgen",
+ "tableiw",
"tabmap",
"tabmap_i",
"tabslice",
diff --git a/htdocs/includes/ace/src/mode-csound_orchestra.js b/htdocs/includes/ace/src/mode-csound_orchestra.js
index 7f1a60442aa..7cb3917c9f4 100644
--- a/htdocs/includes/ace/src/mode-csound_orchestra.js
+++ b/htdocs/includes/ace/src/mode-csound_orchestra.js
@@ -1146,6 +1146,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"ampdb",
"ampdbfs",
"ampmidi",
+ "ampmidicurve",
"ampmidid",
"areson",
"aresonk",
@@ -1194,7 +1195,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"ceps",
"cepsinv",
"chanctrl",
- "changed",
"changed2",
"chani",
"chano",
@@ -1363,6 +1363,17 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"flooper",
"flooper2",
"floor",
+ "fluidAllOut",
+ "fluidCCi",
+ "fluidCCk",
+ "fluidControl",
+ "fluidEngine",
+ "fluidInfo",
+ "fluidLoad",
+ "fluidNote",
+ "fluidOut",
+ "fluidProgramSelect",
+ "fluidSetInterpMethod",
"fmanal",
"fmax",
"fmb3",
@@ -1437,6 +1448,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"grain2",
"grain3",
"granule",
+ "gtf",
"guiro",
"harmon",
"harmon2",
@@ -1845,6 +1857,8 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"nsamp",
"nstance",
"nstrnum",
+ "nstrstr",
+ "ntof",
"ntom",
"ntrpol",
"nxtpow2",
@@ -1975,7 +1989,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"ptable",
"ptable3",
"ptablei",
- "ptableiw",
"ptablew",
"ptrack",
"puts",
@@ -2282,6 +2295,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"strget",
"strindex",
"strindexk",
+ "string2array",
"strlen",
"strlenk",
"strlower",
@@ -2325,7 +2339,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"tableigpw",
"tableikt",
"tableimix",
- "tableiw",
"tablekt",
"tablemix",
"tableng",
@@ -2533,6 +2546,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"array",
"bformdec",
"bformenc",
+ "changed",
"copy2ftab",
"copy2ttab",
"hrtfer",
@@ -2542,6 +2556,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"mintab",
"pop",
"pop_f",
+ "ptableiw",
"push",
"push_f",
"scalet",
@@ -2560,6 +2575,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) {
"stack",
"sumtab",
"tabgen",
+ "tableiw",
"tabmap",
"tabmap_i",
"tabslice",
diff --git a/htdocs/includes/ace/src/mode-jade.js b/htdocs/includes/ace/src/mode-jade.js
index 51c796d73f2..5c3488944ce 100644
--- a/htdocs/includes/ace/src/mode-jade.js
+++ b/htdocs/includes/ace/src/mode-jade.js
@@ -1083,7 +1083,7 @@ var MarkdownHighlightRules = function() {
next : "blockquote"
}, { // HR * - _
token : "constant",
- regex : "^ {0,2}(?:(?: ?\\* ?){3,}|(?: ?\\- ?){3,}|(?: ?\\_ ?){3,})\\s*$",
+ regex : "^ {0,3}(?:(?:\\* ?){3,}|(?:\\- ?){3,}|(?:\\_ ?){3,})\\s*$",
next: "allowBlock"
}, { // list
token : "markup.list",
diff --git a/htdocs/includes/ace/src/mode-json5.js b/htdocs/includes/ace/src/mode-json5.js
new file mode 100644
index 00000000000..539fd2f2160
--- /dev/null
+++ b/htdocs/includes/ace/src/mode-json5.js
@@ -0,0 +1,360 @@
+define("ace/mode/json_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
+
+var JsonHighlightRules = function() {
+ this.$rules = {
+ "start" : [
+ {
+ token : "variable", // single line
+ regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]\\s*(?=:)'
+ }, {
+ token : "string", // single line
+ regex : '"',
+ next : "string"
+ }, {
+ token : "constant.numeric", // hex
+ regex : "0[xX][0-9a-fA-F]+\\b"
+ }, {
+ token : "constant.numeric", // float
+ regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
+ }, {
+ token : "constant.language.boolean",
+ regex : "(?:true|false)\\b"
+ }, {
+ token : "text", // single quoted strings are not allowed
+ regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
+ }, {
+ token : "comment", // comments are not allowed, but who cares?
+ regex : "\\/\\/.*$"
+ }, {
+ token : "comment.start", // comments are not allowed, but who cares?
+ regex : "\\/\\*",
+ next : "comment"
+ }, {
+ token : "paren.lparen",
+ regex : "[[({]"
+ }, {
+ token : "paren.rparen",
+ regex : "[\\])}]"
+ }, {
+ token : "text",
+ regex : "\\s+"
+ }
+ ],
+ "string" : [
+ {
+ token : "constant.language.escape",
+ regex : /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\\\/bfnrt])/
+ }, {
+ token : "string",
+ regex : '"|$',
+ next : "start"
+ }, {
+ defaultToken : "string"
+ }
+ ],
+ "comment" : [
+ {
+ token : "comment.end", // comments are not allowed, but who cares?
+ regex : "\\*\\/",
+ next : "start"
+ }, {
+ defaultToken: "comment"
+ }
+ ]
+ };
+
+};
+
+oop.inherits(JsonHighlightRules, TextHighlightRules);
+
+exports.JsonHighlightRules = JsonHighlightRules;
+});
+
+define("ace/mode/json5_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/json_highlight_rules"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var JsonHighlightRules = require("./json_highlight_rules").JsonHighlightRules;
+
+var Json5HighlightRules = function() {
+ JsonHighlightRules.call(this);
+
+ var startRules = [{
+ token : "variable",
+ regex : /[a-zA-Z$_\u00a1-\uffff][\w$\u00a1-\uffff]*\s*(?=:)/
+ }, {
+ token : "variable",
+ regex : /['](?:(?:\\.)|(?:[^'\\]))*?[']\s*(?=:)/
+ }, {
+ token : "constant.language.boolean",
+ regex : /(?:null)\b/
+ }, {
+ token : "string",
+ regex : /'/,
+ next : [{
+ token : "constant.language.escape",
+ regex : /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\/bfnrt]|$)/,
+ consumeLineEnd : true
+ }, {
+ token : "string",
+ regex : /'|$/,
+ next : "start"
+ }, {
+ defaultToken : "string"
+ }]
+ }, {
+ token : "string",
+ regex : /"(?![^"]*":)/,
+ next : [{
+ token : "constant.language.escape",
+ regex : /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\/bfnrt]|$)/,
+ consumeLineEnd : true
+ }, {
+ token : "string",
+ regex : /"|$/,
+ next : "start"
+ }, {
+ defaultToken : "string"
+ }]
+ }, {
+ token : "constant.numeric",
+ regex : /[+-]?(?:Infinity|NaN)\b/
+ }];
+
+ for (var key in this.$rules)
+ this.$rules[key].unshift.apply(this.$rules[key], startRules);
+
+ this.normalizeRules();
+};
+
+oop.inherits(Json5HighlightRules, JsonHighlightRules);
+
+exports.Json5HighlightRules = Json5HighlightRules;
+});
+
+define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) {
+"use strict";
+
+var Range = require("../range").Range;
+
+var MatchingBraceOutdent = function() {};
+
+(function() {
+
+ this.checkOutdent = function(line, input) {
+ if (! /^\s+$/.test(line))
+ return false;
+
+ return /^\s*\}/.test(input);
+ };
+
+ this.autoOutdent = function(doc, row) {
+ var line = doc.getLine(row);
+ var match = line.match(/^(\s*\})/);
+
+ if (!match) return 0;
+
+ var column = match[1].length;
+ var openBracePos = doc.findMatchingBracket({row: row, column: column});
+
+ if (!openBracePos || openBracePos.row == row) return 0;
+
+ var indent = this.$getIndent(doc.getLine(openBracePos.row));
+ doc.replace(new Range(row, 0, row, column-1), indent);
+ };
+
+ this.$getIndent = function(line) {
+ return line.match(/^\s*/)[0];
+ };
+
+}).call(MatchingBraceOutdent.prototype);
+
+exports.MatchingBraceOutdent = MatchingBraceOutdent;
+});
+
+define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../../lib/oop");
+var Range = require("../../range").Range;
+var BaseFoldMode = require("./fold_mode").FoldMode;
+
+var FoldMode = exports.FoldMode = function(commentRegex) {
+ if (commentRegex) {
+ this.foldingStartMarker = new RegExp(
+ this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start)
+ );
+ this.foldingStopMarker = new RegExp(
+ this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end)
+ );
+ }
+};
+oop.inherits(FoldMode, BaseFoldMode);
+
+(function() {
+
+ this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/;
+ this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/;
+ this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/;
+ this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/;
+ this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/;
+ this._getFoldWidgetBase = this.getFoldWidget;
+ this.getFoldWidget = function(session, foldStyle, row) {
+ var line = session.getLine(row);
+
+ if (this.singleLineBlockCommentRe.test(line)) {
+ if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line))
+ return "";
+ }
+
+ var fw = this._getFoldWidgetBase(session, foldStyle, row);
+
+ if (!fw && this.startRegionRe.test(line))
+ return "start"; // lineCommentRegionStart
+
+ return fw;
+ };
+
+ this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) {
+ var line = session.getLine(row);
+
+ if (this.startRegionRe.test(line))
+ return this.getCommentRegionBlock(session, line, row);
+
+ var match = line.match(this.foldingStartMarker);
+ if (match) {
+ var i = match.index;
+
+ if (match[1])
+ return this.openingBracketBlock(session, match[1], row, i);
+
+ var range = session.getCommentFoldRange(row, i + match[0].length, 1);
+
+ if (range && !range.isMultiLine()) {
+ if (forceMultiline) {
+ range = this.getSectionRange(session, row);
+ } else if (foldStyle != "all")
+ range = null;
+ }
+
+ return range;
+ }
+
+ if (foldStyle === "markbegin")
+ return;
+
+ var match = line.match(this.foldingStopMarker);
+ if (match) {
+ var i = match.index + match[0].length;
+
+ if (match[1])
+ return this.closingBracketBlock(session, match[1], row, i);
+
+ return session.getCommentFoldRange(row, i, -1);
+ }
+ };
+
+ this.getSectionRange = function(session, row) {
+ var line = session.getLine(row);
+ var startIndent = line.search(/\S/);
+ var startRow = row;
+ var startColumn = line.length;
+ row = row + 1;
+ var endRow = row;
+ var maxRow = session.getLength();
+ while (++row < maxRow) {
+ line = session.getLine(row);
+ var indent = line.search(/\S/);
+ if (indent === -1)
+ continue;
+ if (startIndent > indent)
+ break;
+ var subRange = this.getFoldWidgetRange(session, "all", row);
+
+ if (subRange) {
+ if (subRange.start.row <= startRow) {
+ break;
+ } else if (subRange.isMultiLine()) {
+ row = subRange.end.row;
+ } else if (startIndent == indent) {
+ break;
+ }
+ }
+ endRow = row;
+ }
+
+ return new Range(startRow, startColumn, endRow, session.getLine(endRow).length);
+ };
+ this.getCommentRegionBlock = function(session, line, row) {
+ var startColumn = line.search(/\s*$/);
+ var maxRow = session.getLength();
+ var startRow = row;
+
+ var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/;
+ var depth = 1;
+ while (++row < maxRow) {
+ line = session.getLine(row);
+ var m = re.exec(line);
+ if (!m) continue;
+ if (m[1]) depth--;
+ else depth++;
+
+ if (!depth) break;
+ }
+
+ var endRow = row;
+ if (endRow > startRow) {
+ return new Range(startRow, startColumn, endRow, line.length);
+ }
+ };
+
+}).call(FoldMode.prototype);
+
+});
+
+define("ace/mode/json5",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/json5_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var TextMode = require("./text").Mode;
+var HighlightRules = require("./json5_highlight_rules").Json5HighlightRules;
+var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
+var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
+var CStyleFoldMode = require("./folding/cstyle").FoldMode;
+
+var Mode = function() {
+ this.HighlightRules = HighlightRules;
+ this.$outdent = new MatchingBraceOutdent();
+ this.$behaviour = new CstyleBehaviour();
+ this.foldingRules = new CStyleFoldMode();
+};
+oop.inherits(Mode, TextMode);
+
+(function() {
+ this.lineCommentStart = "//";
+ this.blockComment = {start: "/*", end: "*/"};
+
+ this.checkOutdent = function(state, line, input) {
+ return this.$outdent.checkOutdent(line, input);
+ };
+
+ this.autoOutdent = function(state, doc, row) {
+ this.$outdent.autoOutdent(doc, row);
+ };
+
+ this.$id = "ace/mode/json5";
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+}); (function() {
+ window.require(["ace/mode/json5"], function(m) {
+ if (typeof module == "object" && typeof exports == "object" && module) {
+ module.exports = m;
+ }
+ });
+ })();
+
\ No newline at end of file
diff --git a/htdocs/includes/ace/src/mode-markdown.js b/htdocs/includes/ace/src/mode-markdown.js
index 380fab69915..ac4072175ec 100644
--- a/htdocs/includes/ace/src/mode-markdown.js
+++ b/htdocs/includes/ace/src/mode-markdown.js
@@ -2625,7 +2625,7 @@ var MarkdownHighlightRules = function() {
next : "blockquote"
}, { // HR * - _
token : "constant",
- regex : "^ {0,2}(?:(?: ?\\* ?){3,}|(?: ?\\- ?){3,}|(?: ?\\_ ?){3,})\\s*$",
+ regex : "^ {0,3}(?:(?:\\* ?){3,}|(?:\\- ?){3,}|(?:\\_ ?){3,})\\s*$",
next: "allowBlock"
}, { // list
token : "markup.list",
diff --git a/htdocs/includes/ace/src/mode-mask.js b/htdocs/includes/ace/src/mode-mask.js
index 83cc5fe70b3..7a60ff04e9a 100644
--- a/htdocs/includes/ace/src/mode-mask.js
+++ b/htdocs/includes/ace/src/mode-mask.js
@@ -1083,7 +1083,7 @@ var MarkdownHighlightRules = function() {
next : "blockquote"
}, { // HR * - _
token : "constant",
- regex : "^ {0,2}(?:(?: ?\\* ?){3,}|(?: ?\\- ?){3,}|(?: ?\\_ ?){3,})\\s*$",
+ regex : "^ {0,3}(?:(?:\\* ?){3,}|(?:\\- ?){3,}|(?:\\_ ?){3,})\\s*$",
next: "allowBlock"
}, { // list
token : "markup.list",
diff --git a/htdocs/includes/ace/src/mode-nsis.js b/htdocs/includes/ace/src/mode-nsis.js
index 2b8b5061a6d..67c2abec063 100644
--- a/htdocs/includes/ace/src/mode-nsis.js
+++ b/htdocs/includes/ace/src/mode-nsis.js
@@ -13,7 +13,7 @@ var NSISHighlightRules = function() {
caseInsensitive: true
}, {
token: "keyword.command.nsis",
- regex: /^\s*(?:Abort|AddBrandingImage|AddSize|AllowRootDirInstall|AllowSkipFiles|AutoCloseWindow|BGFont|BGGradient|BrandingText|BringToFront|Call|CallInstDLL|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|CreateDirectory|CreateFont|CreateShortCut|Delete|DeleteINISec|DeleteINIStr|DeleteRegKey|DeleteRegValue|DetailPrint|DetailsButtonText|DirText|DirVar|DirVerify|EnableWindow|EnumRegKey|EnumRegValue|Exch|Exec|ExecShell|ExecShellWait|ExecWait|ExpandEnvStrings|File|FileBufSize|FileClose|FileErrorText|FileOpen|FileRead|FileReadByte|FileReadUTF16LE|FileReadWord|FileWriteUTF16LE|FileSeek|FileWrite|FileWriteByte|FileWriteWord|FindClose|FindFirst|FindNext|FindWindow|FlushINI|GetCurInstType|GetCurrentAddress|GetDlgItem|GetDLLVersion|GetDLLVersionLocal|GetErrorLevel|GetFileTime|GetFileTimeLocal|GetFullPathName|GetFunctionAddress|GetInstDirError|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|Int64Cmp|Int64CmpU|Int64Fmt|IntCmp|IntCmpU|IntFmt|IntOp|IntPtrCmp|IntPtrCmpU|IntPtrOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|PEDllCharacteristics|PESubsysVer|Pop|Push|Quit|ReadEnvStr|ReadINIStr|ReadRegDWORD|ReadRegStr|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|SectionGetFlags|SectionGetInstTypes|SectionGetSize|SectionGetText|SectionIn|SectionSetFlags|SectionSetInstTypes|SectionSetSize|SectionSetText|SendMessage|SetAutoClose|SetBrandingImage|SetCompress|SetCompressor|SetCompressorDictSize|SetCtlColors|SetCurInstType|SetDatablockOptimize|SetDateSave|SetDetailsPrint|SetDetailsView|SetErrorLevel|SetErrors|SetFileAttributes|SetFont|SetOutPath|SetOverwrite|SetRebootFlag|SetRegView|SetShellVarContext|SetSilent|ShowInstDetails|ShowUninstDetails|ShowWindow|SilentInstall|SilentUnInstall|Sleep|SpaceTexts|StrCmp|StrCmpS|StrCpy|StrLen|SubCaption|Unicode|UninstallButtonText|UninstallCaption|UninstallIcon|UninstallSubCaption|UninstallText|UninstPage|UnRegDLL|Var|VIAddVersionKey|VIFileVersion|VIProductVersion|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|WriteRegMultiStr|WriteRegNone|WriteRegStr|WriteUninstaller|XPStyle)\b/,
+ regex: /^\s*(?:Abort|AddBrandingImage|AddSize|AllowRootDirInstall|AllowSkipFiles|AutoCloseWindow|BGFont|BGGradient|BrandingText|BringToFront|Call|CallInstDLL|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|CreateDirectory|CreateFont|CreateShortCut|Delete|DeleteINISec|DeleteINIStr|DeleteRegKey|DeleteRegValue|DetailPrint|DetailsButtonText|DirText|DirVar|DirVerify|EnableWindow|EnumRegKey|EnumRegValue|Exch|Exec|ExecShell|ExecShellWait|ExecWait|ExpandEnvStrings|File|FileBufSize|FileClose|FileErrorText|FileOpen|FileRead|FileReadByte|FileReadUTF16LE|FileReadWord|FileWriteUTF16LE|FileSeek|FileWrite|FileWriteByte|FileWriteWord|FindClose|FindFirst|FindNext|FindWindow|FlushINI|GetCurInstType|GetCurrentAddress|GetDlgItem|GetDLLVersion|GetDLLVersionLocal|GetErrorLevel|GetFileTime|GetFileTimeLocal|GetFullPathName|GetFunctionAddress|GetInstDirError|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|Int64Cmp|Int64CmpU|Int64Fmt|IntCmp|IntCmpU|IntFmt|IntOp|IntPtrCmp|IntPtrCmpU|IntPtrOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadAndSetImage|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestLongPathAware|ManifestMaxVersionTested|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|PEAddResource|PEDllCharacteristics|PERemoveResource|PESubsysVer|Pop|Push|Quit|ReadEnvStr|ReadINIStr|ReadRegDWORD|ReadRegStr|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|SectionGetFlags|SectionGetInstTypes|SectionGetSize|SectionGetText|SectionIn|SectionSetFlags|SectionSetInstTypes|SectionSetSize|SectionSetText|SendMessage|SetAutoClose|SetBrandingImage|SetCompress|SetCompressor|SetCompressorDictSize|SetCtlColors|SetCurInstType|SetDatablockOptimize|SetDateSave|SetDetailsPrint|SetDetailsView|SetErrorLevel|SetErrors|SetFileAttributes|SetFont|SetOutPath|SetOverwrite|SetRebootFlag|SetRegView|SetShellVarContext|SetSilent|ShowInstDetails|ShowUninstDetails|ShowWindow|SilentInstall|SilentUnInstall|Sleep|SpaceTexts|StrCmp|StrCmpS|StrCpy|StrLen|SubCaption|Unicode|UninstallButtonText|UninstallCaption|UninstallIcon|UninstallSubCaption|UninstallText|UninstPage|UnRegDLL|Var|VIAddVersionKey|VIFileVersion|VIProductVersion|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|WriteRegMultiStr|WriteRegNone|WriteRegStr|WriteUninstaller|XPStyle)\b/,
caseInsensitive: true
}, {
token: "keyword.control.nsis",
diff --git a/htdocs/includes/ace/src/mode-nunjucks.js b/htdocs/includes/ace/src/mode-nunjucks.js
new file mode 100644
index 00000000000..57f1e9f32bb
--- /dev/null
+++ b/htdocs/includes/ace/src/mode-nunjucks.js
@@ -0,0 +1,2695 @@
+define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
+
+var DocCommentHighlightRules = function() {
+ this.$rules = {
+ "start" : [ {
+ token : "comment.doc.tag",
+ regex : "@[\\w\\d_]+" // TODO: fix email addresses
+ },
+ DocCommentHighlightRules.getTagRule(),
+ {
+ defaultToken : "comment.doc",
+ caseInsensitive: true
+ }]
+ };
+};
+
+oop.inherits(DocCommentHighlightRules, TextHighlightRules);
+
+DocCommentHighlightRules.getTagRule = function(start) {
+ return {
+ token : "comment.doc.tag.storage.type",
+ regex : "\\b(?:TODO|FIXME|XXX|HACK)\\b"
+ };
+};
+
+DocCommentHighlightRules.getStartRule = function(start) {
+ return {
+ token : "comment.doc", // doc comment
+ regex : "\\/\\*(?=\\*)",
+ next : start
+ };
+};
+
+DocCommentHighlightRules.getEndRule = function (start) {
+ return {
+ token : "comment.doc", // closing comment
+ regex : "\\*\\/",
+ next : start
+ };
+};
+
+
+exports.DocCommentHighlightRules = DocCommentHighlightRules;
+
+});
+
+define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
+var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
+var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*";
+
+var JavaScriptHighlightRules = function(options) {
+ var keywordMapper = this.createKeywordMapper({
+ "variable.language":
+ "Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|" + // Constructors
+ "Namespace|QName|XML|XMLList|" + // E4X
+ "ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|" +
+ "Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|" +
+ "Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|" + // Errors
+ "SyntaxError|TypeError|URIError|" +
+ "decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|" + // Non-constructor functions
+ "isNaN|parseFloat|parseInt|" +
+ "JSON|Math|" + // Other
+ "this|arguments|prototype|window|document" , // Pseudo
+ "keyword":
+ "const|yield|import|get|set|async|await|" +
+ "break|case|catch|continue|default|delete|do|else|finally|for|function|" +
+ "if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|" +
+ "__parent__|__count__|escape|unescape|with|__proto__|" +
+ "class|enum|extends|super|export|implements|private|public|interface|package|protected|static",
+ "storage.type":
+ "const|let|var|function",
+ "constant.language":
+ "null|Infinity|NaN|undefined",
+ "support.function":
+ "alert",
+ "constant.language.boolean": "true|false"
+ }, "identifier");
+ var kwBeforeRe = "case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void";
+
+ var escapedRe = "\\\\(?:x[0-9a-fA-F]{2}|" + // hex
+ "u[0-9a-fA-F]{4}|" + // unicode
+ "u{[0-9a-fA-F]{1,6}}|" + // es6 unicode
+ "[0-2][0-7]{0,2}|" + // oct
+ "3[0-7][0-7]?|" + // oct
+ "[4-7][0-7]?|" + //oct
+ ".)";
+
+ this.$rules = {
+ "no_regex" : [
+ DocCommentHighlightRules.getStartRule("doc-start"),
+ comments("no_regex"),
+ {
+ token : "string",
+ regex : "'(?=.)",
+ next : "qstring"
+ }, {
+ token : "string",
+ regex : '"(?=.)',
+ next : "qqstring"
+ }, {
+ token : "constant.numeric", // hexadecimal, octal and binary
+ regex : /0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/
+ }, {
+ token : "constant.numeric", // decimal integers and floats
+ regex : /(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/
+ }, {
+ token : [
+ "storage.type", "punctuation.operator", "support.function",
+ "punctuation.operator", "entity.name.function", "text","keyword.operator"
+ ],
+ regex : "(" + identifierRe + ")(\\.)(prototype)(\\.)(" + identifierRe +")(\\s*)(=)",
+ next: "function_arguments"
+ }, {
+ token : [
+ "storage.type", "punctuation.operator", "entity.name.function", "text",
+ "keyword.operator", "text", "storage.type", "text", "paren.lparen"
+ ],
+ regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",
+ next: "function_arguments"
+ }, {
+ token : [
+ "entity.name.function", "text", "keyword.operator", "text", "storage.type",
+ "text", "paren.lparen"
+ ],
+ regex : "(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",
+ next: "function_arguments"
+ }, {
+ token : [
+ "storage.type", "punctuation.operator", "entity.name.function", "text",
+ "keyword.operator", "text",
+ "storage.type", "text", "entity.name.function", "text", "paren.lparen"
+ ],
+ regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",
+ next: "function_arguments"
+ }, {
+ token : [
+ "storage.type", "text", "entity.name.function", "text", "paren.lparen"
+ ],
+ regex : "(function)(\\s+)(" + identifierRe + ")(\\s*)(\\()",
+ next: "function_arguments"
+ }, {
+ token : [
+ "entity.name.function", "text", "punctuation.operator",
+ "text", "storage.type", "text", "paren.lparen"
+ ],
+ regex : "(" + identifierRe + ")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",
+ next: "function_arguments"
+ }, {
+ token : [
+ "text", "text", "storage.type", "text", "paren.lparen"
+ ],
+ regex : "(:)(\\s*)(function)(\\s*)(\\()",
+ next: "function_arguments"
+ }, {
+ token : "keyword",
+ regex : "from(?=\\s*('|\"))"
+ }, {
+ token : "keyword",
+ regex : "(?:" + kwBeforeRe + ")\\b",
+ next : "start"
+ }, {
+ token : ["support.constant"],
+ regex : /that\b/
+ }, {
+ token : ["storage.type", "punctuation.operator", "support.function.firebug"],
+ regex : /(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/
+ }, {
+ token : keywordMapper,
+ regex : identifierRe
+ }, {
+ token : "punctuation.operator",
+ regex : /[.](?![.])/,
+ next : "property"
+ }, {
+ token : "storage.type",
+ regex : /=>/,
+ next : "start"
+ }, {
+ token : "keyword.operator",
+ regex : /--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,
+ next : "start"
+ }, {
+ token : "punctuation.operator",
+ regex : /[?:,;.]/,
+ next : "start"
+ }, {
+ token : "paren.lparen",
+ regex : /[\[({]/,
+ next : "start"
+ }, {
+ token : "paren.rparen",
+ regex : /[\])}]/
+ }, {
+ token: "comment",
+ regex: /^#!.*$/
+ }
+ ],
+ property: [{
+ token : "text",
+ regex : "\\s+"
+ }, {
+ token : [
+ "storage.type", "punctuation.operator", "entity.name.function", "text",
+ "keyword.operator", "text",
+ "storage.type", "text", "entity.name.function", "text", "paren.lparen"
+ ],
+ regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()",
+ next: "function_arguments"
+ }, {
+ token : "punctuation.operator",
+ regex : /[.](?![.])/
+ }, {
+ token : "support.function",
+ regex : /(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/
+ }, {
+ token : "support.function.dom",
+ regex : /(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/
+ }, {
+ token : "support.constant",
+ regex : /(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/
+ }, {
+ token : "identifier",
+ regex : identifierRe
+ }, {
+ regex: "",
+ token: "empty",
+ next: "no_regex"
+ }
+ ],
+ "start": [
+ DocCommentHighlightRules.getStartRule("doc-start"),
+ comments("start"),
+ {
+ token: "string.regexp",
+ regex: "\\/",
+ next: "regex"
+ }, {
+ token : "text",
+ regex : "\\s+|^$",
+ next : "start"
+ }, {
+ token: "empty",
+ regex: "",
+ next: "no_regex"
+ }
+ ],
+ "regex": [
+ {
+ token: "regexp.keyword.operator",
+ regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"
+ }, {
+ token: "string.regexp",
+ regex: "/[sxngimy]*",
+ next: "no_regex"
+ }, {
+ token : "invalid",
+ regex: /\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/
+ }, {
+ token : "constant.language.escape",
+ regex: /\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/
+ }, {
+ token : "constant.language.delimiter",
+ regex: /\|/
+ }, {
+ token: "constant.language.escape",
+ regex: /\[\^?/,
+ next: "regex_character_class"
+ }, {
+ token: "empty",
+ regex: "$",
+ next: "no_regex"
+ }, {
+ defaultToken: "string.regexp"
+ }
+ ],
+ "regex_character_class": [
+ {
+ token: "regexp.charclass.keyword.operator",
+ regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"
+ }, {
+ token: "constant.language.escape",
+ regex: "]",
+ next: "regex"
+ }, {
+ token: "constant.language.escape",
+ regex: "-"
+ }, {
+ token: "empty",
+ regex: "$",
+ next: "no_regex"
+ }, {
+ defaultToken: "string.regexp.charachterclass"
+ }
+ ],
+ "function_arguments": [
+ {
+ token: "variable.parameter",
+ regex: identifierRe
+ }, {
+ token: "punctuation.operator",
+ regex: "[, ]+"
+ }, {
+ token: "punctuation.operator",
+ regex: "$"
+ }, {
+ token: "empty",
+ regex: "",
+ next: "no_regex"
+ }
+ ],
+ "qqstring" : [
+ {
+ token : "constant.language.escape",
+ regex : escapedRe
+ }, {
+ token : "string",
+ regex : "\\\\$",
+ consumeLineEnd : true
+ }, {
+ token : "string",
+ regex : '"|$',
+ next : "no_regex"
+ }, {
+ defaultToken: "string"
+ }
+ ],
+ "qstring" : [
+ {
+ token : "constant.language.escape",
+ regex : escapedRe
+ }, {
+ token : "string",
+ regex : "\\\\$",
+ consumeLineEnd : true
+ }, {
+ token : "string",
+ regex : "'|$",
+ next : "no_regex"
+ }, {
+ defaultToken: "string"
+ }
+ ]
+ };
+
+
+ if (!options || !options.noES6) {
+ this.$rules.no_regex.unshift({
+ regex: "[{}]", onMatch: function(val, state, stack) {
+ this.next = val == "{" ? this.nextState : "";
+ if (val == "{" && stack.length) {
+ stack.unshift("start", state);
+ }
+ else if (val == "}" && stack.length) {
+ stack.shift();
+ this.next = stack.shift();
+ if (this.next.indexOf("string") != -1 || this.next.indexOf("jsx") != -1)
+ return "paren.quasi.end";
+ }
+ return val == "{" ? "paren.lparen" : "paren.rparen";
+ },
+ nextState: "start"
+ }, {
+ token : "string.quasi.start",
+ regex : /`/,
+ push : [{
+ token : "constant.language.escape",
+ regex : escapedRe
+ }, {
+ token : "paren.quasi.start",
+ regex : /\${/,
+ push : "start"
+ }, {
+ token : "string.quasi.end",
+ regex : /`/,
+ next : "pop"
+ }, {
+ defaultToken: "string.quasi"
+ }]
+ });
+
+ if (!options || options.jsx != false)
+ JSX.call(this);
+ }
+
+ this.embedRules(DocCommentHighlightRules, "doc-",
+ [ DocCommentHighlightRules.getEndRule("no_regex") ]);
+
+ this.normalizeRules();
+};
+
+oop.inherits(JavaScriptHighlightRules, TextHighlightRules);
+
+function JSX() {
+ var tagRegex = identifierRe.replace("\\d", "\\d\\-");
+ var jsxTag = {
+ onMatch : function(val, state, stack) {
+ var offset = val.charAt(1) == "/" ? 2 : 1;
+ if (offset == 1) {
+ if (state != this.nextState)
+ stack.unshift(this.next, this.nextState, 0);
+ else
+ stack.unshift(this.next);
+ stack[2]++;
+ } else if (offset == 2) {
+ if (state == this.nextState) {
+ stack[1]--;
+ if (!stack[1] || stack[1] < 0) {
+ stack.shift();
+ stack.shift();
+ }
+ }
+ }
+ return [{
+ type: "meta.tag.punctuation." + (offset == 1 ? "" : "end-") + "tag-open.xml",
+ value: val.slice(0, offset)
+ }, {
+ type: "meta.tag.tag-name.xml",
+ value: val.substr(offset)
+ }];
+ },
+ regex : "?" + tagRegex + "",
+ next: "jsxAttributes",
+ nextState: "jsx"
+ };
+ this.$rules.start.unshift(jsxTag);
+ var jsxJsRule = {
+ regex: "{",
+ token: "paren.quasi.start",
+ push: "start"
+ };
+ this.$rules.jsx = [
+ jsxJsRule,
+ jsxTag,
+ {include : "reference"},
+ {defaultToken: "string"}
+ ];
+ this.$rules.jsxAttributes = [{
+ token : "meta.tag.punctuation.tag-close.xml",
+ regex : "/?>",
+ onMatch : function(value, currentState, stack) {
+ if (currentState == stack[0])
+ stack.shift();
+ if (value.length == 2) {
+ if (stack[0] == this.nextState)
+ stack[1]--;
+ if (!stack[1] || stack[1] < 0) {
+ stack.splice(0, 2);
+ }
+ }
+ this.next = stack[0] || "start";
+ return [{type: this.token, value: value}];
+ },
+ nextState: "jsx"
+ },
+ jsxJsRule,
+ comments("jsxAttributes"),
+ {
+ token : "entity.other.attribute-name.xml",
+ regex : tagRegex
+ }, {
+ token : "keyword.operator.attribute-equals.xml",
+ regex : "="
+ }, {
+ token : "text.tag-whitespace.xml",
+ regex : "\\s+"
+ }, {
+ token : "string.attribute-value.xml",
+ regex : "'",
+ stateName : "jsx_attr_q",
+ push : [
+ {token : "string.attribute-value.xml", regex: "'", next: "pop"},
+ {include : "reference"},
+ {defaultToken : "string.attribute-value.xml"}
+ ]
+ }, {
+ token : "string.attribute-value.xml",
+ regex : '"',
+ stateName : "jsx_attr_qq",
+ push : [
+ {token : "string.attribute-value.xml", regex: '"', next: "pop"},
+ {include : "reference"},
+ {defaultToken : "string.attribute-value.xml"}
+ ]
+ },
+ jsxTag
+ ];
+ this.$rules.reference = [{
+ token : "constant.language.escape.reference.xml",
+ regex : "(?:[0-9]+;)|(?:[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"
+ }];
+}
+
+function comments(next) {
+ return [
+ {
+ token : "comment", // multi line comment
+ regex : /\/\*/,
+ next: [
+ DocCommentHighlightRules.getTagRule(),
+ {token : "comment", regex : "\\*\\/", next : next || "pop"},
+ {defaultToken : "comment", caseInsensitive: true}
+ ]
+ }, {
+ token : "comment",
+ regex : "\\/\\/",
+ next: [
+ DocCommentHighlightRules.getTagRule(),
+ {token : "comment", regex : "$|^", next : next || "pop"},
+ {defaultToken : "comment", caseInsensitive: true}
+ ]
+ }
+ ];
+}
+exports.JavaScriptHighlightRules = JavaScriptHighlightRules;
+});
+
+define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) {
+"use strict";
+
+var Range = require("../range").Range;
+
+var MatchingBraceOutdent = function() {};
+
+(function() {
+
+ this.checkOutdent = function(line, input) {
+ if (! /^\s+$/.test(line))
+ return false;
+
+ return /^\s*\}/.test(input);
+ };
+
+ this.autoOutdent = function(doc, row) {
+ var line = doc.getLine(row);
+ var match = line.match(/^(\s*\})/);
+
+ if (!match) return 0;
+
+ var column = match[1].length;
+ var openBracePos = doc.findMatchingBracket({row: row, column: column});
+
+ if (!openBracePos || openBracePos.row == row) return 0;
+
+ var indent = this.$getIndent(doc.getLine(openBracePos.row));
+ doc.replace(new Range(row, 0, row, column-1), indent);
+ };
+
+ this.$getIndent = function(line) {
+ return line.match(/^\s*/)[0];
+ };
+
+}).call(MatchingBraceOutdent.prototype);
+
+exports.MatchingBraceOutdent = MatchingBraceOutdent;
+});
+
+define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../../lib/oop");
+var Range = require("../../range").Range;
+var BaseFoldMode = require("./fold_mode").FoldMode;
+
+var FoldMode = exports.FoldMode = function(commentRegex) {
+ if (commentRegex) {
+ this.foldingStartMarker = new RegExp(
+ this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start)
+ );
+ this.foldingStopMarker = new RegExp(
+ this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end)
+ );
+ }
+};
+oop.inherits(FoldMode, BaseFoldMode);
+
+(function() {
+
+ this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/;
+ this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/;
+ this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/;
+ this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/;
+ this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/;
+ this._getFoldWidgetBase = this.getFoldWidget;
+ this.getFoldWidget = function(session, foldStyle, row) {
+ var line = session.getLine(row);
+
+ if (this.singleLineBlockCommentRe.test(line)) {
+ if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line))
+ return "";
+ }
+
+ var fw = this._getFoldWidgetBase(session, foldStyle, row);
+
+ if (!fw && this.startRegionRe.test(line))
+ return "start"; // lineCommentRegionStart
+
+ return fw;
+ };
+
+ this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) {
+ var line = session.getLine(row);
+
+ if (this.startRegionRe.test(line))
+ return this.getCommentRegionBlock(session, line, row);
+
+ var match = line.match(this.foldingStartMarker);
+ if (match) {
+ var i = match.index;
+
+ if (match[1])
+ return this.openingBracketBlock(session, match[1], row, i);
+
+ var range = session.getCommentFoldRange(row, i + match[0].length, 1);
+
+ if (range && !range.isMultiLine()) {
+ if (forceMultiline) {
+ range = this.getSectionRange(session, row);
+ } else if (foldStyle != "all")
+ range = null;
+ }
+
+ return range;
+ }
+
+ if (foldStyle === "markbegin")
+ return;
+
+ var match = line.match(this.foldingStopMarker);
+ if (match) {
+ var i = match.index + match[0].length;
+
+ if (match[1])
+ return this.closingBracketBlock(session, match[1], row, i);
+
+ return session.getCommentFoldRange(row, i, -1);
+ }
+ };
+
+ this.getSectionRange = function(session, row) {
+ var line = session.getLine(row);
+ var startIndent = line.search(/\S/);
+ var startRow = row;
+ var startColumn = line.length;
+ row = row + 1;
+ var endRow = row;
+ var maxRow = session.getLength();
+ while (++row < maxRow) {
+ line = session.getLine(row);
+ var indent = line.search(/\S/);
+ if (indent === -1)
+ continue;
+ if (startIndent > indent)
+ break;
+ var subRange = this.getFoldWidgetRange(session, "all", row);
+
+ if (subRange) {
+ if (subRange.start.row <= startRow) {
+ break;
+ } else if (subRange.isMultiLine()) {
+ row = subRange.end.row;
+ } else if (startIndent == indent) {
+ break;
+ }
+ }
+ endRow = row;
+ }
+
+ return new Range(startRow, startColumn, endRow, session.getLine(endRow).length);
+ };
+ this.getCommentRegionBlock = function(session, line, row) {
+ var startColumn = line.search(/\s*$/);
+ var maxRow = session.getLength();
+ var startRow = row;
+
+ var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/;
+ var depth = 1;
+ while (++row < maxRow) {
+ line = session.getLine(row);
+ var m = re.exec(line);
+ if (!m) continue;
+ if (m[1]) depth--;
+ else depth++;
+
+ if (!depth) break;
+ }
+
+ var endRow = row;
+ if (endRow > startRow) {
+ return new Range(startRow, startColumn, endRow, line.length);
+ }
+ };
+
+}).call(FoldMode.prototype);
+
+});
+
+define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var TextMode = require("./text").Mode;
+var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules;
+var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
+var WorkerClient = require("../worker/worker_client").WorkerClient;
+var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
+var CStyleFoldMode = require("./folding/cstyle").FoldMode;
+
+var Mode = function() {
+ this.HighlightRules = JavaScriptHighlightRules;
+
+ this.$outdent = new MatchingBraceOutdent();
+ this.$behaviour = new CstyleBehaviour();
+ this.foldingRules = new CStyleFoldMode();
+};
+oop.inherits(Mode, TextMode);
+
+(function() {
+
+ this.lineCommentStart = "//";
+ this.blockComment = {start: "/*", end: "*/"};
+ this.$quotes = {'"': '"', "'": "'", "`": "`"};
+
+ this.getNextLineIndent = function(state, line, tab) {
+ var indent = this.$getIndent(line);
+
+ var tokenizedLine = this.getTokenizer().getLineTokens(line, state);
+ var tokens = tokenizedLine.tokens;
+ var endState = tokenizedLine.state;
+
+ if (tokens.length && tokens[tokens.length-1].type == "comment") {
+ return indent;
+ }
+
+ if (state == "start" || state == "no_regex") {
+ var match = line.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/);
+ if (match) {
+ indent += tab;
+ }
+ } else if (state == "doc-start") {
+ if (endState == "start" || endState == "no_regex") {
+ return "";
+ }
+ var match = line.match(/^\s*(\/?)\*/);
+ if (match) {
+ if (match[1]) {
+ indent += " ";
+ }
+ indent += "* ";
+ }
+ }
+
+ return indent;
+ };
+
+ this.checkOutdent = function(state, line, input) {
+ return this.$outdent.checkOutdent(line, input);
+ };
+
+ this.autoOutdent = function(state, doc, row) {
+ this.$outdent.autoOutdent(doc, row);
+ };
+
+ this.createWorker = function(session) {
+ var worker = new WorkerClient(["ace"], "ace/mode/javascript_worker", "JavaScriptWorker");
+ worker.attachToDocument(session.getDocument());
+
+ worker.on("annotate", function(results) {
+ session.setAnnotations(results.data);
+ });
+
+ worker.on("terminate", function() {
+ session.clearAnnotations();
+ });
+
+ return worker;
+ };
+
+ this.$id = "ace/mode/javascript";
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+});
+
+define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var lang = require("../lib/lang");
+var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
+var supportType = exports.supportType = "align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index";
+var supportFunction = exports.supportFunction = "rgb|rgba|url|attr|counter|counters";
+var supportConstant = exports.supportConstant = "absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom";
+var supportConstantColor = exports.supportConstantColor = "aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen";
+var supportConstantFonts = exports.supportConstantFonts = "arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace";
+
+var numRe = exports.numRe = "\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))";
+var pseudoElements = exports.pseudoElements = "(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b";
+var pseudoClasses = exports.pseudoClasses = "(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b";
+
+var CssHighlightRules = function() {
+
+ var keywordMapper = this.createKeywordMapper({
+ "support.function": supportFunction,
+ "support.constant": supportConstant,
+ "support.type": supportType,
+ "support.constant.color": supportConstantColor,
+ "support.constant.fonts": supportConstantFonts
+ }, "text", true);
+
+ this.$rules = {
+ "start" : [{
+ include : ["strings", "url", "comments"]
+ }, {
+ token: "paren.lparen",
+ regex: "\\{",
+ next: "ruleset"
+ }, {
+ token: "paren.rparen",
+ regex: "\\}"
+ }, {
+ token: "string",
+ regex: "@(?!viewport)",
+ next: "media"
+ }, {
+ token: "keyword",
+ regex: "#[a-z0-9-_]+"
+ }, {
+ token: "keyword",
+ regex: "%"
+ }, {
+ token: "variable",
+ regex: "\\.[a-z0-9-_]+"
+ }, {
+ token: "string",
+ regex: ":[a-z0-9-_]+"
+ }, {
+ token : "constant.numeric",
+ regex : numRe
+ }, {
+ token: "constant",
+ regex: "[a-z0-9-_]+"
+ }, {
+ caseInsensitive: true
+ }],
+
+ "media": [{
+ include : ["strings", "url", "comments"]
+ }, {
+ token: "paren.lparen",
+ regex: "\\{",
+ next: "start"
+ }, {
+ token: "paren.rparen",
+ regex: "\\}",
+ next: "start"
+ }, {
+ token: "string",
+ regex: ";",
+ next: "start"
+ }, {
+ token: "keyword",
+ regex: "(?:media|supports|document|charset|import|namespace|media|supports|document"
+ + "|page|font|keyframes|viewport|counter-style|font-feature-values"
+ + "|swash|ornaments|annotation|stylistic|styleset|character-variant)"
+ }],
+
+ "comments" : [{
+ token: "comment", // multi line comment
+ regex: "\\/\\*",
+ push: [{
+ token : "comment",
+ regex : "\\*\\/",
+ next : "pop"
+ }, {
+ defaultToken : "comment"
+ }]
+ }],
+
+ "ruleset" : [{
+ regex : "-(webkit|ms|moz|o)-",
+ token : "text"
+ }, {
+ token : "punctuation.operator",
+ regex : "[:;]"
+ }, {
+ token : "paren.rparen",
+ regex : "\\}",
+ next : "start"
+ }, {
+ include : ["strings", "url", "comments"]
+ }, {
+ token : ["constant.numeric", "keyword"],
+ regex : "(" + numRe + ")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)"
+ }, {
+ token : "constant.numeric",
+ regex : numRe
+ }, {
+ token : "constant.numeric", // hex6 color
+ regex : "#[a-f0-9]{6}"
+ }, {
+ token : "constant.numeric", // hex3 color
+ regex : "#[a-f0-9]{3}"
+ }, {
+ token : ["punctuation", "entity.other.attribute-name.pseudo-element.css"],
+ regex : pseudoElements
+ }, {
+ token : ["punctuation", "entity.other.attribute-name.pseudo-class.css"],
+ regex : pseudoClasses
+ }, {
+ include: "url"
+ }, {
+ token : keywordMapper,
+ regex : "\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"
+ }, {
+ caseInsensitive: true
+ }],
+
+ url: [{
+ token : "support.function",
+ regex : "(?:url(:?-prefix)?|domain|regexp)\\(",
+ push: [{
+ token : "support.function",
+ regex : "\\)",
+ next : "pop"
+ }, {
+ defaultToken: "string"
+ }]
+ }],
+
+ strings: [{
+ token : "string.start",
+ regex : "'",
+ push : [{
+ token : "string.end",
+ regex : "'|$",
+ next: "pop"
+ }, {
+ include : "escapes"
+ }, {
+ token : "constant.language.escape",
+ regex : /\\$/,
+ consumeLineEnd: true
+ }, {
+ defaultToken: "string"
+ }]
+ }, {
+ token : "string.start",
+ regex : '"',
+ push : [{
+ token : "string.end",
+ regex : '"|$',
+ next: "pop"
+ }, {
+ include : "escapes"
+ }, {
+ token : "constant.language.escape",
+ regex : /\\$/,
+ consumeLineEnd: true
+ }, {
+ defaultToken: "string"
+ }]
+ }],
+ escapes: [{
+ token : "constant.language.escape",
+ regex : /\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/
+ }]
+
+ };
+
+ this.normalizeRules();
+};
+
+oop.inherits(CssHighlightRules, TextHighlightRules);
+
+exports.CssHighlightRules = CssHighlightRules;
+
+});
+
+define("ace/mode/css_completions",["require","exports","module"], function(require, exports, module) {
+"use strict";
+
+var propertyMap = {
+ "background": {"#$0": 1},
+ "background-color": {"#$0": 1, "transparent": 1, "fixed": 1},
+ "background-image": {"url('/$0')": 1},
+ "background-repeat": {"repeat": 1, "repeat-x": 1, "repeat-y": 1, "no-repeat": 1, "inherit": 1},
+ "background-position": {"bottom":2, "center":2, "left":2, "right":2, "top":2, "inherit":2},
+ "background-attachment": {"scroll": 1, "fixed": 1},
+ "background-size": {"cover": 1, "contain": 1},
+ "background-clip": {"border-box": 1, "padding-box": 1, "content-box": 1},
+ "background-origin": {"border-box": 1, "padding-box": 1, "content-box": 1},
+ "border": {"solid $0": 1, "dashed $0": 1, "dotted $0": 1, "#$0": 1},
+ "border-color": {"#$0": 1},
+ "border-style": {"solid":2, "dashed":2, "dotted":2, "double":2, "groove":2, "hidden":2, "inherit":2, "inset":2, "none":2, "outset":2, "ridged":2},
+ "border-collapse": {"collapse": 1, "separate": 1},
+ "bottom": {"px": 1, "em": 1, "%": 1},
+ "clear": {"left": 1, "right": 1, "both": 1, "none": 1},
+ "color": {"#$0": 1, "rgb(#$00,0,0)": 1},
+ "cursor": {"default": 1, "pointer": 1, "move": 1, "text": 1, "wait": 1, "help": 1, "progress": 1, "n-resize": 1, "ne-resize": 1, "e-resize": 1, "se-resize": 1, "s-resize": 1, "sw-resize": 1, "w-resize": 1, "nw-resize": 1},
+ "display": {"none": 1, "block": 1, "inline": 1, "inline-block": 1, "table-cell": 1},
+ "empty-cells": {"show": 1, "hide": 1},
+ "float": {"left": 1, "right": 1, "none": 1},
+ "font-family": {"Arial":2,"Comic Sans MS":2,"Consolas":2,"Courier New":2,"Courier":2,"Georgia":2,"Monospace":2,"Sans-Serif":2, "Segoe UI":2,"Tahoma":2,"Times New Roman":2,"Trebuchet MS":2,"Verdana": 1},
+ "font-size": {"px": 1, "em": 1, "%": 1},
+ "font-weight": {"bold": 1, "normal": 1},
+ "font-style": {"italic": 1, "normal": 1},
+ "font-variant": {"normal": 1, "small-caps": 1},
+ "height": {"px": 1, "em": 1, "%": 1},
+ "left": {"px": 1, "em": 1, "%": 1},
+ "letter-spacing": {"normal": 1},
+ "line-height": {"normal": 1},
+ "list-style-type": {"none": 1, "disc": 1, "circle": 1, "square": 1, "decimal": 1, "decimal-leading-zero": 1, "lower-roman": 1, "upper-roman": 1, "lower-greek": 1, "lower-latin": 1, "upper-latin": 1, "georgian": 1, "lower-alpha": 1, "upper-alpha": 1},
+ "margin": {"px": 1, "em": 1, "%": 1},
+ "margin-right": {"px": 1, "em": 1, "%": 1},
+ "margin-left": {"px": 1, "em": 1, "%": 1},
+ "margin-top": {"px": 1, "em": 1, "%": 1},
+ "margin-bottom": {"px": 1, "em": 1, "%": 1},
+ "max-height": {"px": 1, "em": 1, "%": 1},
+ "max-width": {"px": 1, "em": 1, "%": 1},
+ "min-height": {"px": 1, "em": 1, "%": 1},
+ "min-width": {"px": 1, "em": 1, "%": 1},
+ "overflow": {"hidden": 1, "visible": 1, "auto": 1, "scroll": 1},
+ "overflow-x": {"hidden": 1, "visible": 1, "auto": 1, "scroll": 1},
+ "overflow-y": {"hidden": 1, "visible": 1, "auto": 1, "scroll": 1},
+ "padding": {"px": 1, "em": 1, "%": 1},
+ "padding-top": {"px": 1, "em": 1, "%": 1},
+ "padding-right": {"px": 1, "em": 1, "%": 1},
+ "padding-bottom": {"px": 1, "em": 1, "%": 1},
+ "padding-left": {"px": 1, "em": 1, "%": 1},
+ "page-break-after": {"auto": 1, "always": 1, "avoid": 1, "left": 1, "right": 1},
+ "page-break-before": {"auto": 1, "always": 1, "avoid": 1, "left": 1, "right": 1},
+ "position": {"absolute": 1, "relative": 1, "fixed": 1, "static": 1},
+ "right": {"px": 1, "em": 1, "%": 1},
+ "table-layout": {"fixed": 1, "auto": 1},
+ "text-decoration": {"none": 1, "underline": 1, "line-through": 1, "blink": 1},
+ "text-align": {"left": 1, "right": 1, "center": 1, "justify": 1},
+ "text-transform": {"capitalize": 1, "uppercase": 1, "lowercase": 1, "none": 1},
+ "top": {"px": 1, "em": 1, "%": 1},
+ "vertical-align": {"top": 1, "bottom": 1},
+ "visibility": {"hidden": 1, "visible": 1},
+ "white-space": {"nowrap": 1, "normal": 1, "pre": 1, "pre-line": 1, "pre-wrap": 1},
+ "width": {"px": 1, "em": 1, "%": 1},
+ "word-spacing": {"normal": 1},
+ "filter": {"alpha(opacity=$0100)": 1},
+
+ "text-shadow": {"$02px 2px 2px #777": 1},
+ "text-overflow": {"ellipsis-word": 1, "clip": 1, "ellipsis": 1},
+ "-moz-border-radius": 1,
+ "-moz-border-radius-topright": 1,
+ "-moz-border-radius-bottomright": 1,
+ "-moz-border-radius-topleft": 1,
+ "-moz-border-radius-bottomleft": 1,
+ "-webkit-border-radius": 1,
+ "-webkit-border-top-right-radius": 1,
+ "-webkit-border-top-left-radius": 1,
+ "-webkit-border-bottom-right-radius": 1,
+ "-webkit-border-bottom-left-radius": 1,
+ "-moz-box-shadow": 1,
+ "-webkit-box-shadow": 1,
+ "transform": {"rotate($00deg)": 1, "skew($00deg)": 1},
+ "-moz-transform": {"rotate($00deg)": 1, "skew($00deg)": 1},
+ "-webkit-transform": {"rotate($00deg)": 1, "skew($00deg)": 1 }
+};
+
+var CssCompletions = function() {
+
+};
+
+(function() {
+
+ this.completionsDefined = false;
+
+ this.defineCompletions = function() {
+ if (document) {
+ var style = document.createElement('c').style;
+
+ for (var i in style) {
+ if (typeof style[i] !== 'string')
+ continue;
+
+ var name = i.replace(/[A-Z]/g, function(x) {
+ return '-' + x.toLowerCase();
+ });
+
+ if (!propertyMap.hasOwnProperty(name))
+ propertyMap[name] = 1;
+ }
+ }
+
+ this.completionsDefined = true;
+ };
+
+ this.getCompletions = function(state, session, pos, prefix) {
+ if (!this.completionsDefined) {
+ this.defineCompletions();
+ }
+
+ if (state==='ruleset' || session.$mode.$id == "ace/mode/scss") {
+ var line = session.getLine(pos.row).substr(0, pos.column);
+ if (/:[^;]+$/.test(line)) {
+ /([\w\-]+):[^:]*$/.test(line);
+
+ return this.getPropertyValueCompletions(state, session, pos, prefix);
+ } else {
+ return this.getPropertyCompletions(state, session, pos, prefix);
+ }
+ }
+
+ return [];
+ };
+
+ this.getPropertyCompletions = function(state, session, pos, prefix) {
+ var properties = Object.keys(propertyMap);
+ return properties.map(function(property){
+ return {
+ caption: property,
+ snippet: property + ': $0;',
+ meta: "property",
+ score: 1000000
+ };
+ });
+ };
+
+ this.getPropertyValueCompletions = function(state, session, pos, prefix) {
+ var line = session.getLine(pos.row).substr(0, pos.column);
+ var property = (/([\w\-]+):[^:]*$/.exec(line) || {})[1];
+
+ if (!property)
+ return [];
+ var values = [];
+ if (property in propertyMap && typeof propertyMap[property] === "object") {
+ values = Object.keys(propertyMap[property]);
+ }
+ return values.map(function(value){
+ return {
+ caption: value,
+ snippet: value,
+ meta: "property value",
+ score: 1000000
+ };
+ });
+ };
+
+}).call(CssCompletions.prototype);
+
+exports.CssCompletions = CssCompletions;
+});
+
+define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../../lib/oop");
+var Behaviour = require("../behaviour").Behaviour;
+var CstyleBehaviour = require("./cstyle").CstyleBehaviour;
+var TokenIterator = require("../../token_iterator").TokenIterator;
+
+var CssBehaviour = function () {
+
+ this.inherit(CstyleBehaviour);
+
+ this.add("colon", "insertion", function (state, action, editor, session, text) {
+ if (text === ':' && editor.selection.isEmpty()) {
+ var cursor = editor.getCursorPosition();
+ var iterator = new TokenIterator(session, cursor.row, cursor.column);
+ var token = iterator.getCurrentToken();
+ if (token && token.value.match(/\s+/)) {
+ token = iterator.stepBackward();
+ }
+ if (token && token.type === 'support.type') {
+ var line = session.doc.getLine(cursor.row);
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
+ if (rightChar === ':') {
+ return {
+ text: '',
+ selection: [1, 1]
+ };
+ }
+ if (/^(\s+[^;]|\s*$)/.test(line.substring(cursor.column))) {
+ return {
+ text: ':;',
+ selection: [1, 1]
+ };
+ }
+ }
+ }
+ });
+
+ this.add("colon", "deletion", function (state, action, editor, session, range) {
+ var selected = session.doc.getTextRange(range);
+ if (!range.isMultiLine() && selected === ':') {
+ var cursor = editor.getCursorPosition();
+ var iterator = new TokenIterator(session, cursor.row, cursor.column);
+ var token = iterator.getCurrentToken();
+ if (token && token.value.match(/\s+/)) {
+ token = iterator.stepBackward();
+ }
+ if (token && token.type === 'support.type') {
+ var line = session.doc.getLine(range.start.row);
+ var rightChar = line.substring(range.end.column, range.end.column + 1);
+ if (rightChar === ';') {
+ range.end.column ++;
+ return range;
+ }
+ }
+ }
+ });
+
+ this.add("semicolon", "insertion", function (state, action, editor, session, text) {
+ if (text === ';' && editor.selection.isEmpty()) {
+ var cursor = editor.getCursorPosition();
+ var line = session.doc.getLine(cursor.row);
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
+ if (rightChar === ';') {
+ return {
+ text: '',
+ selection: [1, 1]
+ };
+ }
+ }
+ });
+
+ this.add("!important", "insertion", function (state, action, editor, session, text) {
+ if (text === '!' && editor.selection.isEmpty()) {
+ var cursor = editor.getCursorPosition();
+ var line = session.doc.getLine(cursor.row);
+
+ if (/^\s*(;|}|$)/.test(line.substring(cursor.column))) {
+ return {
+ text: '!important',
+ selection: [10, 10]
+ };
+ }
+ }
+ });
+
+};
+oop.inherits(CssBehaviour, CstyleBehaviour);
+
+exports.CssBehaviour = CssBehaviour;
+});
+
+define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var TextMode = require("./text").Mode;
+var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules;
+var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
+var WorkerClient = require("../worker/worker_client").WorkerClient;
+var CssCompletions = require("./css_completions").CssCompletions;
+var CssBehaviour = require("./behaviour/css").CssBehaviour;
+var CStyleFoldMode = require("./folding/cstyle").FoldMode;
+
+var Mode = function() {
+ this.HighlightRules = CssHighlightRules;
+ this.$outdent = new MatchingBraceOutdent();
+ this.$behaviour = new CssBehaviour();
+ this.$completer = new CssCompletions();
+ this.foldingRules = new CStyleFoldMode();
+};
+oop.inherits(Mode, TextMode);
+
+(function() {
+
+ this.foldingRules = "cStyle";
+ this.blockComment = {start: "/*", end: "*/"};
+
+ this.getNextLineIndent = function(state, line, tab) {
+ var indent = this.$getIndent(line);
+ var tokens = this.getTokenizer().getLineTokens(line, state).tokens;
+ if (tokens.length && tokens[tokens.length-1].type == "comment") {
+ return indent;
+ }
+
+ var match = line.match(/^.*\{\s*$/);
+ if (match) {
+ indent += tab;
+ }
+
+ return indent;
+ };
+
+ this.checkOutdent = function(state, line, input) {
+ return this.$outdent.checkOutdent(line, input);
+ };
+
+ this.autoOutdent = function(state, doc, row) {
+ this.$outdent.autoOutdent(doc, row);
+ };
+
+ this.getCompletions = function(state, session, pos, prefix) {
+ return this.$completer.getCompletions(state, session, pos, prefix);
+ };
+
+ this.createWorker = function(session) {
+ var worker = new WorkerClient(["ace"], "ace/mode/css_worker", "Worker");
+ worker.attachToDocument(session.getDocument());
+
+ worker.on("annotate", function(e) {
+ session.setAnnotations(e.data);
+ });
+
+ worker.on("terminate", function() {
+ session.clearAnnotations();
+ });
+
+ return worker;
+ };
+
+ this.$id = "ace/mode/css";
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+
+});
+
+define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
+
+var XmlHighlightRules = function(normalize) {
+ var tagRegex = "[_:a-zA-Z\xc0-\uffff][-_:.a-zA-Z0-9\xc0-\uffff]*";
+
+ this.$rules = {
+ start : [
+ {token : "string.cdata.xml", regex : "<\\!\\[CDATA\\[", next : "cdata"},
+ {
+ token : ["punctuation.instruction.xml", "keyword.instruction.xml"],
+ regex : "(<\\?)(" + tagRegex + ")", next : "processing_instruction"
+ },
+ {token : "comment.start.xml", regex : "<\\!--", next : "comment"},
+ {
+ token : ["xml-pe.doctype.xml", "xml-pe.doctype.xml"],
+ regex : "(<\\!)(DOCTYPE)(?=[\\s])", next : "doctype", caseInsensitive: true
+ },
+ {include : "tag"},
+ {token : "text.end-tag-open.xml", regex: ""},
+ {token : "text.tag-open.xml", regex: "<"},
+ {include : "reference"},
+ {defaultToken : "text.xml"}
+ ],
+
+ processing_instruction : [{
+ token : "entity.other.attribute-name.decl-attribute-name.xml",
+ regex : tagRegex
+ }, {
+ token : "keyword.operator.decl-attribute-equals.xml",
+ regex : "="
+ }, {
+ include: "whitespace"
+ }, {
+ include: "string"
+ }, {
+ token : "punctuation.xml-decl.xml",
+ regex : "\\?>",
+ next : "start"
+ }],
+
+ doctype : [
+ {include : "whitespace"},
+ {include : "string"},
+ {token : "xml-pe.doctype.xml", regex : ">", next : "start"},
+ {token : "xml-pe.xml", regex : "[-_a-zA-Z0-9:]+"},
+ {token : "punctuation.int-subset", regex : "\\[", push : "int_subset"}
+ ],
+
+ int_subset : [{
+ token : "text.xml",
+ regex : "\\s+"
+ }, {
+ token: "punctuation.int-subset.xml",
+ regex: "]",
+ next: "pop"
+ }, {
+ token : ["punctuation.markup-decl.xml", "keyword.markup-decl.xml"],
+ regex : "(<\\!)(" + tagRegex + ")",
+ push : [{
+ token : "text",
+ regex : "\\s+"
+ },
+ {
+ token : "punctuation.markup-decl.xml",
+ regex : ">",
+ next : "pop"
+ },
+ {include : "string"}]
+ }],
+
+ cdata : [
+ {token : "string.cdata.xml", regex : "\\]\\]>", next : "start"},
+ {token : "text.xml", regex : "\\s+"},
+ {token : "text.xml", regex : "(?:[^\\]]|\\](?!\\]>))+"}
+ ],
+
+ comment : [
+ {token : "comment.end.xml", regex : "-->", next : "start"},
+ {defaultToken : "comment.xml"}
+ ],
+
+ reference : [{
+ token : "constant.language.escape.reference.xml",
+ regex : "(?:[0-9]+;)|(?:[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"
+ }],
+
+ attr_reference : [{
+ token : "constant.language.escape.reference.attribute-value.xml",
+ regex : "(?:[0-9]+;)|(?:[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"
+ }],
+
+ tag : [{
+ token : ["meta.tag.punctuation.tag-open.xml", "meta.tag.punctuation.end-tag-open.xml", "meta.tag.tag-name.xml"],
+ regex : "(?:(<)|())((?:" + tagRegex + ":)?" + tagRegex + ")",
+ next: [
+ {include : "attributes"},
+ {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next : "start"}
+ ]
+ }],
+
+ tag_whitespace : [
+ {token : "text.tag-whitespace.xml", regex : "\\s+"}
+ ],
+ whitespace : [
+ {token : "text.whitespace.xml", regex : "\\s+"}
+ ],
+ string: [{
+ token : "string.xml",
+ regex : "'",
+ push : [
+ {token : "string.xml", regex: "'", next: "pop"},
+ {defaultToken : "string.xml"}
+ ]
+ }, {
+ token : "string.xml",
+ regex : '"',
+ push : [
+ {token : "string.xml", regex: '"', next: "pop"},
+ {defaultToken : "string.xml"}
+ ]
+ }],
+
+ attributes: [{
+ token : "entity.other.attribute-name.xml",
+ regex : tagRegex
+ }, {
+ token : "keyword.operator.attribute-equals.xml",
+ regex : "="
+ }, {
+ include: "tag_whitespace"
+ }, {
+ include: "attribute_value"
+ }],
+
+ attribute_value: [{
+ token : "string.attribute-value.xml",
+ regex : "'",
+ push : [
+ {token : "string.attribute-value.xml", regex: "'", next: "pop"},
+ {include : "attr_reference"},
+ {defaultToken : "string.attribute-value.xml"}
+ ]
+ }, {
+ token : "string.attribute-value.xml",
+ regex : '"',
+ push : [
+ {token : "string.attribute-value.xml", regex: '"', next: "pop"},
+ {include : "attr_reference"},
+ {defaultToken : "string.attribute-value.xml"}
+ ]
+ }]
+ };
+
+ if (this.constructor === XmlHighlightRules)
+ this.normalizeRules();
+};
+
+
+(function() {
+
+ this.embedTagRules = function(HighlightRules, prefix, tag){
+ this.$rules.tag.unshift({
+ token : ["meta.tag.punctuation.tag-open.xml", "meta.tag." + tag + ".tag-name.xml"],
+ regex : "(<)(" + tag + "(?=\\s|>|$))",
+ next: [
+ {include : "attributes"},
+ {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next : prefix + "start"}
+ ]
+ });
+
+ this.$rules[tag + "-end"] = [
+ {include : "attributes"},
+ {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next: "start",
+ onMatch : function(value, currentState, stack) {
+ stack.splice(0);
+ return this.token;
+ }}
+ ];
+
+ this.embedRules(HighlightRules, prefix, [{
+ token: ["meta.tag.punctuation.end-tag-open.xml", "meta.tag." + tag + ".tag-name.xml"],
+ regex : "()(" + tag + "(?=\\s|>|$))",
+ next: tag + "-end"
+ }, {
+ token: "string.cdata.xml",
+ regex : "<\\!\\[CDATA\\["
+ }, {
+ token: "string.cdata.xml",
+ regex : "\\]\\]>"
+ }]);
+ };
+
+}).call(TextHighlightRules.prototype);
+
+oop.inherits(XmlHighlightRules, TextHighlightRules);
+
+exports.XmlHighlightRules = XmlHighlightRules;
+});
+
+define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var lang = require("../lib/lang");
+var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules;
+var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules;
+var XmlHighlightRules = require("./xml_highlight_rules").XmlHighlightRules;
+
+var tagMap = lang.createMap({
+ a : 'anchor',
+ button : 'form',
+ form : 'form',
+ img : 'image',
+ input : 'form',
+ label : 'form',
+ option : 'form',
+ script : 'script',
+ select : 'form',
+ textarea : 'form',
+ style : 'style',
+ table : 'table',
+ tbody : 'table',
+ td : 'table',
+ tfoot : 'table',
+ th : 'table',
+ tr : 'table'
+});
+
+var HtmlHighlightRules = function() {
+ XmlHighlightRules.call(this);
+
+ this.addRules({
+ attributes: [{
+ include : "tag_whitespace"
+ }, {
+ token : "entity.other.attribute-name.xml",
+ regex : "[-_a-zA-Z0-9:.]+"
+ }, {
+ token : "keyword.operator.attribute-equals.xml",
+ regex : "=",
+ push : [{
+ include: "tag_whitespace"
+ }, {
+ token : "string.unquoted.attribute-value.html",
+ regex : "[^<>='\"`\\s]+",
+ next : "pop"
+ }, {
+ token : "empty",
+ regex : "",
+ next : "pop"
+ }]
+ }, {
+ include : "attribute_value"
+ }],
+ tag: [{
+ token : function(start, tag) {
+ var group = tagMap[tag];
+ return ["meta.tag.punctuation." + (start == "<" ? "" : "end-") + "tag-open.xml",
+ "meta.tag" + (group ? "." + group : "") + ".tag-name.xml"];
+ },
+ regex : "(?)([-_a-zA-Z0-9:.]+)",
+ next: "tag_stuff"
+ }],
+ tag_stuff: [
+ {include : "attributes"},
+ {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next : "start"}
+ ]
+ });
+
+ this.embedTagRules(CssHighlightRules, "css-", "style");
+ this.embedTagRules(new JavaScriptHighlightRules({jsx: false}).getRules(), "js-", "script");
+
+ if (this.constructor === HtmlHighlightRules)
+ this.normalizeRules();
+};
+
+oop.inherits(HtmlHighlightRules, XmlHighlightRules);
+
+exports.HtmlHighlightRules = HtmlHighlightRules;
+});
+
+define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../../lib/oop");
+var Behaviour = require("../behaviour").Behaviour;
+var TokenIterator = require("../../token_iterator").TokenIterator;
+var lang = require("../../lib/lang");
+
+function is(token, type) {
+ return token && token.type.lastIndexOf(type + ".xml") > -1;
+}
+
+var XmlBehaviour = function () {
+
+ this.add("string_dquotes", "insertion", function (state, action, editor, session, text) {
+ if (text == '"' || text == "'") {
+ var quote = text;
+ var selected = session.doc.getTextRange(editor.getSelectionRange());
+ if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) {
+ return {
+ text: quote + selected + quote,
+ selection: false
+ };
+ }
+
+ var cursor = editor.getCursorPosition();
+ var line = session.doc.getLine(cursor.row);
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
+ var iterator = new TokenIterator(session, cursor.row, cursor.column);
+ var token = iterator.getCurrentToken();
+
+ if (rightChar == quote && (is(token, "attribute-value") || is(token, "string"))) {
+ return {
+ text: "",
+ selection: [1, 1]
+ };
+ }
+
+ if (!token)
+ token = iterator.stepBackward();
+
+ if (!token)
+ return;
+
+ while (is(token, "tag-whitespace") || is(token, "whitespace")) {
+ token = iterator.stepBackward();
+ }
+ var rightSpace = !rightChar || rightChar.match(/\s/);
+ if (is(token, "attribute-equals") && (rightSpace || rightChar == '>') || (is(token, "decl-attribute-equals") && (rightSpace || rightChar == '?'))) {
+ return {
+ text: quote + quote,
+ selection: [1, 1]
+ };
+ }
+ }
+ });
+
+ this.add("string_dquotes", "deletion", function(state, action, editor, session, range) {
+ var selected = session.doc.getTextRange(range);
+ if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
+ var line = session.doc.getLine(range.start.row);
+ var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
+ if (rightChar == selected) {
+ range.end.column++;
+ return range;
+ }
+ }
+ });
+
+ this.add("autoclosing", "insertion", function (state, action, editor, session, text) {
+ if (text == '>') {
+ var position = editor.getSelectionRange().start;
+ var iterator = new TokenIterator(session, position.row, position.column);
+ var token = iterator.getCurrentToken() || iterator.stepBackward();
+ if (!token || !(is(token, "tag-name") || is(token, "tag-whitespace") || is(token, "attribute-name") || is(token, "attribute-equals") || is(token, "attribute-value")))
+ return;
+ if (is(token, "reference.attribute-value"))
+ return;
+ if (is(token, "attribute-value")) {
+ var tokenEndColumn = iterator.getCurrentTokenColumn() + token.value.length;
+ if (position.column < tokenEndColumn)
+ return;
+ if (position.column == tokenEndColumn) {
+ var nextToken = iterator.stepForward();
+ if (nextToken && is(nextToken, "attribute-value"))
+ return;
+ iterator.stepBackward();
+ }
+ }
+
+ if (/^\s*>/.test(session.getLine(position.row).slice(position.column)))
+ return;
+ while (!is(token, "tag-name")) {
+ token = iterator.stepBackward();
+ if (token.value == "<") {
+ token = iterator.stepForward();
+ break;
+ }
+ }
+
+ var tokenRow = iterator.getCurrentTokenRow();
+ var tokenColumn = iterator.getCurrentTokenColumn();
+ if (is(iterator.stepBackward(), "end-tag-open"))
+ return;
+
+ var element = token.value;
+ if (tokenRow == position.row)
+ element = element.substring(0, position.column - tokenColumn);
+
+ if (this.voidElements.hasOwnProperty(element.toLowerCase()))
+ return;
+
+ return {
+ text: ">" + "" + element + ">",
+ selection: [1, 1]
+ };
+ }
+ });
+
+ this.add("autoindent", "insertion", function (state, action, editor, session, text) {
+ if (text == "\n") {
+ var cursor = editor.getCursorPosition();
+ var line = session.getLine(cursor.row);
+ var iterator = new TokenIterator(session, cursor.row, cursor.column);
+ var token = iterator.getCurrentToken();
+
+ if (token && token.type.indexOf("tag-close") !== -1) {
+ if (token.value == "/>")
+ return;
+ while (token && token.type.indexOf("tag-name") === -1) {
+ token = iterator.stepBackward();
+ }
+
+ if (!token) {
+ return;
+ }
+
+ var tag = token.value;
+ var row = iterator.getCurrentTokenRow();
+ token = iterator.stepBackward();
+ if (!token || token.type.indexOf("end-tag") !== -1) {
+ return;
+ }
+
+ if (this.voidElements && !this.voidElements[tag]) {
+ var nextToken = session.getTokenAt(cursor.row, cursor.column+1);
+ var line = session.getLine(row);
+ var nextIndent = this.$getIndent(line);
+ var indent = nextIndent + session.getTabString();
+
+ if (nextToken && nextToken.value === "") {
+ return {
+ text: "\n" + indent + "\n" + nextIndent,
+ selection: [1, indent.length, 1, indent.length]
+ };
+ } else {
+ return {
+ text: "\n" + indent
+ };
+ }
+ }
+ }
+ }
+ });
+
+};
+
+oop.inherits(XmlBehaviour, Behaviour);
+
+exports.XmlBehaviour = XmlBehaviour;
+});
+
+define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../../lib/oop");
+var BaseFoldMode = require("./fold_mode").FoldMode;
+
+var FoldMode = exports.FoldMode = function(defaultMode, subModes) {
+ this.defaultMode = defaultMode;
+ this.subModes = subModes;
+};
+oop.inherits(FoldMode, BaseFoldMode);
+
+(function() {
+
+
+ this.$getMode = function(state) {
+ if (typeof state != "string")
+ state = state[0];
+ for (var key in this.subModes) {
+ if (state.indexOf(key) === 0)
+ return this.subModes[key];
+ }
+ return null;
+ };
+
+ this.$tryMode = function(state, session, foldStyle, row) {
+ var mode = this.$getMode(state);
+ return (mode ? mode.getFoldWidget(session, foldStyle, row) : "");
+ };
+
+ this.getFoldWidget = function(session, foldStyle, row) {
+ return (
+ this.$tryMode(session.getState(row-1), session, foldStyle, row) ||
+ this.$tryMode(session.getState(row), session, foldStyle, row) ||
+ this.defaultMode.getFoldWidget(session, foldStyle, row)
+ );
+ };
+
+ this.getFoldWidgetRange = function(session, foldStyle, row) {
+ var mode = this.$getMode(session.getState(row-1));
+
+ if (!mode || !mode.getFoldWidget(session, foldStyle, row))
+ mode = this.$getMode(session.getState(row));
+
+ if (!mode || !mode.getFoldWidget(session, foldStyle, row))
+ mode = this.defaultMode;
+
+ return mode.getFoldWidgetRange(session, foldStyle, row);
+ };
+
+}).call(FoldMode.prototype);
+
+});
+
+define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../../lib/oop");
+var lang = require("../../lib/lang");
+var Range = require("../../range").Range;
+var BaseFoldMode = require("./fold_mode").FoldMode;
+var TokenIterator = require("../../token_iterator").TokenIterator;
+
+var FoldMode = exports.FoldMode = function(voidElements, optionalEndTags) {
+ BaseFoldMode.call(this);
+ this.voidElements = voidElements || {};
+ this.optionalEndTags = oop.mixin({}, this.voidElements);
+ if (optionalEndTags)
+ oop.mixin(this.optionalEndTags, optionalEndTags);
+
+};
+oop.inherits(FoldMode, BaseFoldMode);
+
+var Tag = function() {
+ this.tagName = "";
+ this.closing = false;
+ this.selfClosing = false;
+ this.start = {row: 0, column: 0};
+ this.end = {row: 0, column: 0};
+};
+
+function is(token, type) {
+ return token.type.lastIndexOf(type + ".xml") > -1;
+}
+
+(function() {
+
+ this.getFoldWidget = function(session, foldStyle, row) {
+ var tag = this._getFirstTagInLine(session, row);
+
+ if (!tag)
+ return this.getCommentFoldWidget(session, row);
+
+ if (tag.closing || (!tag.tagName && tag.selfClosing))
+ return foldStyle == "markbeginend" ? "end" : "";
+
+ if (!tag.tagName || tag.selfClosing || this.voidElements.hasOwnProperty(tag.tagName.toLowerCase()))
+ return "";
+
+ if (this._findEndTagInLine(session, row, tag.tagName, tag.end.column))
+ return "";
+
+ return "start";
+ };
+
+ this.getCommentFoldWidget = function(session, row) {
+ if (/comment/.test(session.getState(row)) && /';
+ break;
+ }
+ }
+ return tag;
+ } else if (is(token, "tag-close")) {
+ tag.selfClosing = token.value == '/>';
+ return tag;
+ }
+ tag.start.column += token.value.length;
+ }
+
+ return null;
+ };
+
+ this._findEndTagInLine = function(session, row, tagName, startColumn) {
+ var tokens = session.getTokens(row);
+ var column = 0;
+ for (var i = 0; i < tokens.length; i++) {
+ var token = tokens[i];
+ column += token.value.length;
+ if (column < startColumn)
+ continue;
+ if (is(token, "end-tag-open")) {
+ token = tokens[i + 1];
+ if (token && token.value == tagName)
+ return true;
+ }
+ }
+ return false;
+ };
+ this._readTagForward = function(iterator) {
+ var token = iterator.getCurrentToken();
+ if (!token)
+ return null;
+
+ var tag = new Tag();
+ do {
+ if (is(token, "tag-open")) {
+ tag.closing = is(token, "end-tag-open");
+ tag.start.row = iterator.getCurrentTokenRow();
+ tag.start.column = iterator.getCurrentTokenColumn();
+ } else if (is(token, "tag-name")) {
+ tag.tagName = token.value;
+ } else if (is(token, "tag-close")) {
+ tag.selfClosing = token.value == "/>";
+ tag.end.row = iterator.getCurrentTokenRow();
+ tag.end.column = iterator.getCurrentTokenColumn() + token.value.length;
+ iterator.stepForward();
+ return tag;
+ }
+ } while(token = iterator.stepForward());
+
+ return null;
+ };
+
+ this._readTagBackward = function(iterator) {
+ var token = iterator.getCurrentToken();
+ if (!token)
+ return null;
+
+ var tag = new Tag();
+ do {
+ if (is(token, "tag-open")) {
+ tag.closing = is(token, "end-tag-open");
+ tag.start.row = iterator.getCurrentTokenRow();
+ tag.start.column = iterator.getCurrentTokenColumn();
+ iterator.stepBackward();
+ return tag;
+ } else if (is(token, "tag-name")) {
+ tag.tagName = token.value;
+ } else if (is(token, "tag-close")) {
+ tag.selfClosing = token.value == "/>";
+ tag.end.row = iterator.getCurrentTokenRow();
+ tag.end.column = iterator.getCurrentTokenColumn() + token.value.length;
+ }
+ } while(token = iterator.stepBackward());
+
+ return null;
+ };
+
+ this._pop = function(stack, tag) {
+ while (stack.length) {
+
+ var top = stack[stack.length-1];
+ if (!tag || top.tagName == tag.tagName) {
+ return stack.pop();
+ }
+ else if (this.optionalEndTags.hasOwnProperty(top.tagName)) {
+ stack.pop();
+ continue;
+ } else {
+ return null;
+ }
+ }
+ };
+
+ this.getFoldWidgetRange = function(session, foldStyle, row) {
+ var firstTag = this._getFirstTagInLine(session, row);
+
+ if (!firstTag) {
+ return this.getCommentFoldWidget(session, row)
+ && session.getCommentFoldRange(row, session.getLine(row).length);
+ }
+
+ var isBackward = firstTag.closing || firstTag.selfClosing;
+ var stack = [];
+ var tag;
+
+ if (!isBackward) {
+ var iterator = new TokenIterator(session, row, firstTag.start.column);
+ var start = {
+ row: row,
+ column: firstTag.start.column + firstTag.tagName.length + 2
+ };
+ if (firstTag.start.row == firstTag.end.row)
+ start.column = firstTag.end.column;
+ while (tag = this._readTagForward(iterator)) {
+ if (tag.selfClosing) {
+ if (!stack.length) {
+ tag.start.column += tag.tagName.length + 2;
+ tag.end.column -= 2;
+ return Range.fromPoints(tag.start, tag.end);
+ } else
+ continue;
+ }
+
+ if (tag.closing) {
+ this._pop(stack, tag);
+ if (stack.length == 0)
+ return Range.fromPoints(start, tag.start);
+ }
+ else {
+ stack.push(tag);
+ }
+ }
+ }
+ else {
+ var iterator = new TokenIterator(session, row, firstTag.end.column);
+ var end = {
+ row: row,
+ column: firstTag.start.column
+ };
+
+ while (tag = this._readTagBackward(iterator)) {
+ if (tag.selfClosing) {
+ if (!stack.length) {
+ tag.start.column += tag.tagName.length + 2;
+ tag.end.column -= 2;
+ return Range.fromPoints(tag.start, tag.end);
+ } else
+ continue;
+ }
+
+ if (!tag.closing) {
+ this._pop(stack, tag);
+ if (stack.length == 0) {
+ tag.start.column += tag.tagName.length + 2;
+ if (tag.start.row == tag.end.row && tag.start.column < tag.end.column)
+ tag.start.column = tag.end.column;
+ return Range.fromPoints(tag.start, end);
+ }
+ }
+ else {
+ stack.push(tag);
+ }
+ }
+ }
+
+ };
+
+}).call(FoldMode.prototype);
+
+});
+
+define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../../lib/oop");
+var MixedFoldMode = require("./mixed").FoldMode;
+var XmlFoldMode = require("./xml").FoldMode;
+var CStyleFoldMode = require("./cstyle").FoldMode;
+
+var FoldMode = exports.FoldMode = function(voidElements, optionalTags) {
+ MixedFoldMode.call(this, new XmlFoldMode(voidElements, optionalTags), {
+ "js-": new CStyleFoldMode(),
+ "css-": new CStyleFoldMode()
+ });
+};
+
+oop.inherits(FoldMode, MixedFoldMode);
+
+});
+
+define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"], function(require, exports, module) {
+"use strict";
+
+var TokenIterator = require("../token_iterator").TokenIterator;
+
+var commonAttributes = [
+ "accesskey",
+ "class",
+ "contenteditable",
+ "contextmenu",
+ "dir",
+ "draggable",
+ "dropzone",
+ "hidden",
+ "id",
+ "inert",
+ "itemid",
+ "itemprop",
+ "itemref",
+ "itemscope",
+ "itemtype",
+ "lang",
+ "spellcheck",
+ "style",
+ "tabindex",
+ "title",
+ "translate"
+];
+
+var eventAttributes = [
+ "onabort",
+ "onblur",
+ "oncancel",
+ "oncanplay",
+ "oncanplaythrough",
+ "onchange",
+ "onclick",
+ "onclose",
+ "oncontextmenu",
+ "oncuechange",
+ "ondblclick",
+ "ondrag",
+ "ondragend",
+ "ondragenter",
+ "ondragleave",
+ "ondragover",
+ "ondragstart",
+ "ondrop",
+ "ondurationchange",
+ "onemptied",
+ "onended",
+ "onerror",
+ "onfocus",
+ "oninput",
+ "oninvalid",
+ "onkeydown",
+ "onkeypress",
+ "onkeyup",
+ "onload",
+ "onloadeddata",
+ "onloadedmetadata",
+ "onloadstart",
+ "onmousedown",
+ "onmousemove",
+ "onmouseout",
+ "onmouseover",
+ "onmouseup",
+ "onmousewheel",
+ "onpause",
+ "onplay",
+ "onplaying",
+ "onprogress",
+ "onratechange",
+ "onreset",
+ "onscroll",
+ "onseeked",
+ "onseeking",
+ "onselect",
+ "onshow",
+ "onstalled",
+ "onsubmit",
+ "onsuspend",
+ "ontimeupdate",
+ "onvolumechange",
+ "onwaiting"
+];
+
+var globalAttributes = commonAttributes.concat(eventAttributes);
+
+var attributeMap = {
+ "a": {"href": 1, "target": {"_blank": 1, "top": 1}, "ping": 1, "rel": {"nofollow": 1, "alternate": 1, "author": 1, "bookmark": 1, "help": 1, "license": 1, "next": 1, "noreferrer": 1, "prefetch": 1, "prev": 1, "search": 1, "tag": 1}, "media": 1, "hreflang": 1, "type": 1},
+ "abbr": {},
+ "address": {},
+ "area": {"shape": 1, "coords": 1, "href": 1, "hreflang": 1, "alt": 1, "target": 1, "media": 1, "rel": 1, "ping": 1, "type": 1},
+ "article": {"pubdate": 1},
+ "aside": {},
+ "audio": {"src": 1, "autobuffer": 1, "autoplay": {"autoplay": 1}, "loop": {"loop": 1}, "controls": {"controls": 1}, "muted": {"muted": 1}, "preload": {"auto": 1, "metadata": 1, "none": 1 }},
+ "b": {},
+ "base": {"href": 1, "target": 1},
+ "bdi": {},
+ "bdo": {},
+ "blockquote": {"cite": 1},
+ "body": {"onafterprint": 1, "onbeforeprint": 1, "onbeforeunload": 1, "onhashchange": 1, "onmessage": 1, "onoffline": 1, "onpopstate": 1, "onredo": 1, "onresize": 1, "onstorage": 1, "onundo": 1, "onunload": 1},
+ "br": {},
+ "button": {"autofocus": 1, "disabled": {"disabled": 1}, "form": 1, "formaction": 1, "formenctype": 1, "formmethod": 1, "formnovalidate": 1, "formtarget": 1, "name": 1, "value": 1, "type": {"button": 1, "submit": 1}},
+ "canvas": {"width": 1, "height": 1},
+ "caption": {},
+ "cite": {},
+ "code": {},
+ "col": {"span": 1},
+ "colgroup": {"span": 1},
+ "command": {"type": 1, "label": 1, "icon": 1, "disabled": 1, "checked": 1, "radiogroup": 1, "command": 1},
+ "data": {},
+ "datalist": {},
+ "dd": {},
+ "del": {"cite": 1, "datetime": 1},
+ "details": {"open": 1},
+ "dfn": {},
+ "dialog": {"open": 1},
+ "div": {},
+ "dl": {},
+ "dt": {},
+ "em": {},
+ "embed": {"src": 1, "height": 1, "width": 1, "type": 1},
+ "fieldset": {"disabled": 1, "form": 1, "name": 1},
+ "figcaption": {},
+ "figure": {},
+ "footer": {},
+ "form": {"accept-charset": 1, "action": 1, "autocomplete": 1, "enctype": {"multipart/form-data": 1, "application/x-www-form-urlencoded": 1}, "method": {"get": 1, "post": 1}, "name": 1, "novalidate": 1, "target": {"_blank": 1, "top": 1}},
+ "h1": {},
+ "h2": {},
+ "h3": {},
+ "h4": {},
+ "h5": {},
+ "h6": {},
+ "head": {},
+ "header": {},
+ "hr": {},
+ "html": {"manifest": 1},
+ "i": {},
+ "iframe": {"name": 1, "src": 1, "height": 1, "width": 1, "sandbox": {"allow-same-origin": 1, "allow-top-navigation": 1, "allow-forms": 1, "allow-scripts": 1}, "seamless": {"seamless": 1}},
+ "img": {"alt": 1, "src": 1, "height": 1, "width": 1, "usemap": 1, "ismap": 1},
+ "input": {
+ "type": {"text": 1, "password": 1, "hidden": 1, "checkbox": 1, "submit": 1, "radio": 1, "file": 1, "button": 1, "reset": 1, "image": 31, "color": 1, "date": 1, "datetime": 1, "datetime-local": 1, "email": 1, "month": 1, "number": 1, "range": 1, "search": 1, "tel": 1, "time": 1, "url": 1, "week": 1},
+ "accept": 1, "alt": 1, "autocomplete": {"on": 1, "off": 1}, "autofocus": {"autofocus": 1}, "checked": {"checked": 1}, "disabled": {"disabled": 1}, "form": 1, "formaction": 1, "formenctype": {"application/x-www-form-urlencoded": 1, "multipart/form-data": 1, "text/plain": 1}, "formmethod": {"get": 1, "post": 1}, "formnovalidate": {"formnovalidate": 1}, "formtarget": {"_blank": 1, "_self": 1, "_parent": 1, "_top": 1}, "height": 1, "list": 1, "max": 1, "maxlength": 1, "min": 1, "multiple": {"multiple": 1}, "name": 1, "pattern": 1, "placeholder": 1, "readonly": {"readonly": 1}, "required": {"required": 1}, "size": 1, "src": 1, "step": 1, "width": 1, "files": 1, "value": 1},
+ "ins": {"cite": 1, "datetime": 1},
+ "kbd": {},
+ "keygen": {"autofocus": 1, "challenge": {"challenge": 1}, "disabled": {"disabled": 1}, "form": 1, "keytype": {"rsa": 1, "dsa": 1, "ec": 1}, "name": 1},
+ "label": {"form": 1, "for": 1},
+ "legend": {},
+ "li": {"value": 1},
+ "link": {"href": 1, "hreflang": 1, "rel": {"stylesheet": 1, "icon": 1}, "media": {"all": 1, "screen": 1, "print": 1}, "type": {"text/css": 1, "image/png": 1, "image/jpeg": 1, "image/gif": 1}, "sizes": 1},
+ "main": {},
+ "map": {"name": 1},
+ "mark": {},
+ "math": {},
+ "menu": {"type": 1, "label": 1},
+ "meta": {"http-equiv": {"content-type": 1}, "name": {"description": 1, "keywords": 1}, "content": {"text/html; charset=UTF-8": 1}, "charset": 1},
+ "meter": {"value": 1, "min": 1, "max": 1, "low": 1, "high": 1, "optimum": 1},
+ "nav": {},
+ "noscript": {"href": 1},
+ "object": {"param": 1, "data": 1, "type": 1, "height" : 1, "width": 1, "usemap": 1, "name": 1, "form": 1, "classid": 1},
+ "ol": {"start": 1, "reversed": 1},
+ "optgroup": {"disabled": 1, "label": 1},
+ "option": {"disabled": 1, "selected": 1, "label": 1, "value": 1},
+ "output": {"for": 1, "form": 1, "name": 1},
+ "p": {},
+ "param": {"name": 1, "value": 1},
+ "pre": {},
+ "progress": {"value": 1, "max": 1},
+ "q": {"cite": 1},
+ "rp": {},
+ "rt": {},
+ "ruby": {},
+ "s": {},
+ "samp": {},
+ "script": {"charset": 1, "type": {"text/javascript": 1}, "src": 1, "defer": 1, "async": 1},
+ "select": {"autofocus": 1, "disabled": 1, "form": 1, "multiple": {"multiple": 1}, "name": 1, "size": 1, "readonly":{"readonly": 1}},
+ "small": {},
+ "source": {"src": 1, "type": 1, "media": 1},
+ "span": {},
+ "strong": {},
+ "style": {"type": 1, "media": {"all": 1, "screen": 1, "print": 1}, "scoped": 1},
+ "sub": {},
+ "sup": {},
+ "svg": {},
+ "table": {"summary": 1},
+ "tbody": {},
+ "td": {"headers": 1, "rowspan": 1, "colspan": 1},
+ "textarea": {"autofocus": {"autofocus": 1}, "disabled": {"disabled": 1}, "form": 1, "maxlength": 1, "name": 1, "placeholder": 1, "readonly": {"readonly": 1}, "required": {"required": 1}, "rows": 1, "cols": 1, "wrap": {"on": 1, "off": 1, "hard": 1, "soft": 1}},
+ "tfoot": {},
+ "th": {"headers": 1, "rowspan": 1, "colspan": 1, "scope": 1},
+ "thead": {},
+ "time": {"datetime": 1},
+ "title": {},
+ "tr": {},
+ "track": {"kind": 1, "src": 1, "srclang": 1, "label": 1, "default": 1},
+ "section": {},
+ "summary": {},
+ "u": {},
+ "ul": {},
+ "var": {},
+ "video": {"src": 1, "autobuffer": 1, "autoplay": {"autoplay": 1}, "loop": {"loop": 1}, "controls": {"controls": 1}, "width": 1, "height": 1, "poster": 1, "muted": {"muted": 1}, "preload": {"auto": 1, "metadata": 1, "none": 1}},
+ "wbr": {}
+};
+
+var elements = Object.keys(attributeMap);
+
+function is(token, type) {
+ return token.type.lastIndexOf(type + ".xml") > -1;
+}
+
+function findTagName(session, pos) {
+ var iterator = new TokenIterator(session, pos.row, pos.column);
+ var token = iterator.getCurrentToken();
+ while (token && !is(token, "tag-name")){
+ token = iterator.stepBackward();
+ }
+ if (token)
+ return token.value;
+}
+
+function findAttributeName(session, pos) {
+ var iterator = new TokenIterator(session, pos.row, pos.column);
+ var token = iterator.getCurrentToken();
+ while (token && !is(token, "attribute-name")){
+ token = iterator.stepBackward();
+ }
+ if (token)
+ return token.value;
+}
+
+var HtmlCompletions = function() {
+
+};
+
+(function() {
+
+ this.getCompletions = function(state, session, pos, prefix) {
+ var token = session.getTokenAt(pos.row, pos.column);
+
+ if (!token)
+ return [];
+ if (is(token, "tag-name") || is(token, "tag-open") || is(token, "end-tag-open"))
+ return this.getTagCompletions(state, session, pos, prefix);
+ if (is(token, "tag-whitespace") || is(token, "attribute-name"))
+ return this.getAttributeCompletions(state, session, pos, prefix);
+ if (is(token, "attribute-value"))
+ return this.getAttributeValueCompletions(state, session, pos, prefix);
+ var line = session.getLine(pos.row).substr(0, pos.column);
+ if (/&[a-z]*$/i.test(line))
+ return this.getHTMLEntityCompletions(state, session, pos, prefix);
+
+ return [];
+ };
+
+ this.getTagCompletions = function(state, session, pos, prefix) {
+ return elements.map(function(element){
+ return {
+ value: element,
+ meta: "tag",
+ score: 1000000
+ };
+ });
+ };
+
+ this.getAttributeCompletions = function(state, session, pos, prefix) {
+ var tagName = findTagName(session, pos);
+ if (!tagName)
+ return [];
+ var attributes = globalAttributes;
+ if (tagName in attributeMap) {
+ attributes = attributes.concat(Object.keys(attributeMap[tagName]));
+ }
+ return attributes.map(function(attribute){
+ return {
+ caption: attribute,
+ snippet: attribute + '="$0"',
+ meta: "attribute",
+ score: 1000000
+ };
+ });
+ };
+
+ this.getAttributeValueCompletions = function(state, session, pos, prefix) {
+ var tagName = findTagName(session, pos);
+ var attributeName = findAttributeName(session, pos);
+
+ if (!tagName)
+ return [];
+ var values = [];
+ if (tagName in attributeMap && attributeName in attributeMap[tagName] && typeof attributeMap[tagName][attributeName] === "object") {
+ values = Object.keys(attributeMap[tagName][attributeName]);
+ }
+ return values.map(function(value){
+ return {
+ caption: value,
+ snippet: value,
+ meta: "attribute value",
+ score: 1000000
+ };
+ });
+ };
+
+ this.getHTMLEntityCompletions = function(state, session, pos, prefix) {
+ var values = ['Aacute;', 'aacute;', 'Acirc;', 'acirc;', 'acute;', 'AElig;', 'aelig;', 'Agrave;', 'agrave;', 'alefsym;', 'Alpha;', 'alpha;', 'amp;', 'and;', 'ang;', 'Aring;', 'aring;', 'asymp;', 'Atilde;', 'atilde;', 'Auml;', 'auml;', 'bdquo;', 'Beta;', 'beta;', 'brvbar;', 'bull;', 'cap;', 'Ccedil;', 'ccedil;', 'cedil;', 'cent;', 'Chi;', 'chi;', 'circ;', 'clubs;', 'cong;', 'copy;', 'crarr;', 'cup;', 'curren;', 'Dagger;', 'dagger;', 'dArr;', 'darr;', 'deg;', 'Delta;', 'delta;', 'diams;', 'divide;', 'Eacute;', 'eacute;', 'Ecirc;', 'ecirc;', 'Egrave;', 'egrave;', 'empty;', 'emsp;', 'ensp;', 'Epsilon;', 'epsilon;', 'equiv;', 'Eta;', 'eta;', 'ETH;', 'eth;', 'Euml;', 'euml;', 'euro;', 'exist;', 'fnof;', 'forall;', 'frac12;', 'frac14;', 'frac34;', 'frasl;', 'Gamma;', 'gamma;', 'ge;', 'gt;', 'hArr;', 'harr;', 'hearts;', 'hellip;', 'Iacute;', 'iacute;', 'Icirc;', 'icirc;', 'iexcl;', 'Igrave;', 'igrave;', 'image;', 'infin;', 'int;', 'Iota;', 'iota;', 'iquest;', 'isin;', 'Iuml;', 'iuml;', 'Kappa;', 'kappa;', 'Lambda;', 'lambda;', 'lang;', 'laquo;', 'lArr;', 'larr;', 'lceil;', 'ldquo;', 'le;', 'lfloor;', 'lowast;', 'loz;', 'lrm;', 'lsaquo;', 'lsquo;', 'lt;', 'macr;', 'mdash;', 'micro;', 'middot;', 'minus;', 'Mu;', 'mu;', 'nabla;', 'nbsp;', 'ndash;', 'ne;', 'ni;', 'not;', 'notin;', 'nsub;', 'Ntilde;', 'ntilde;', 'Nu;', 'nu;', 'Oacute;', 'oacute;', 'Ocirc;', 'ocirc;', 'OElig;', 'oelig;', 'Ograve;', 'ograve;', 'oline;', 'Omega;', 'omega;', 'Omicron;', 'omicron;', 'oplus;', 'or;', 'ordf;', 'ordm;', 'Oslash;', 'oslash;', 'Otilde;', 'otilde;', 'otimes;', 'Ouml;', 'ouml;', 'para;', 'part;', 'permil;', 'perp;', 'Phi;', 'phi;', 'Pi;', 'pi;', 'piv;', 'plusmn;', 'pound;', 'Prime;', 'prime;', 'prod;', 'prop;', 'Psi;', 'psi;', 'quot;', 'radic;', 'rang;', 'raquo;', 'rArr;', 'rarr;', 'rceil;', 'rdquo;', 'real;', 'reg;', 'rfloor;', 'Rho;', 'rho;', 'rlm;', 'rsaquo;', 'rsquo;', 'sbquo;', 'Scaron;', 'scaron;', 'sdot;', 'sect;', 'shy;', 'Sigma;', 'sigma;', 'sigmaf;', 'sim;', 'spades;', 'sub;', 'sube;', 'sum;', 'sup;', 'sup1;', 'sup2;', 'sup3;', 'supe;', 'szlig;', 'Tau;', 'tau;', 'there4;', 'Theta;', 'theta;', 'thetasym;', 'thinsp;', 'THORN;', 'thorn;', 'tilde;', 'times;', 'trade;', 'Uacute;', 'uacute;', 'uArr;', 'uarr;', 'Ucirc;', 'ucirc;', 'Ugrave;', 'ugrave;', 'uml;', 'upsih;', 'Upsilon;', 'upsilon;', 'Uuml;', 'uuml;', 'weierp;', 'Xi;', 'xi;', 'Yacute;', 'yacute;', 'yen;', 'Yuml;', 'yuml;', 'Zeta;', 'zeta;', 'zwj;', 'zwnj;'];
+
+ return values.map(function(value){
+ return {
+ caption: value,
+ snippet: value,
+ meta: "html entity",
+ score: 1000000
+ };
+ });
+ };
+
+}).call(HtmlCompletions.prototype);
+
+exports.HtmlCompletions = HtmlCompletions;
+});
+
+define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var lang = require("../lib/lang");
+var TextMode = require("./text").Mode;
+var JavaScriptMode = require("./javascript").Mode;
+var CssMode = require("./css").Mode;
+var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules;
+var XmlBehaviour = require("./behaviour/xml").XmlBehaviour;
+var HtmlFoldMode = require("./folding/html").FoldMode;
+var HtmlCompletions = require("./html_completions").HtmlCompletions;
+var WorkerClient = require("../worker/worker_client").WorkerClient;
+var voidElements = ["area", "base", "br", "col", "embed", "hr", "img", "input", "keygen", "link", "meta", "menuitem", "param", "source", "track", "wbr"];
+var optionalEndTags = ["li", "dt", "dd", "p", "rt", "rp", "optgroup", "option", "colgroup", "td", "th"];
+
+var Mode = function(options) {
+ this.fragmentContext = options && options.fragmentContext;
+ this.HighlightRules = HtmlHighlightRules;
+ this.$behaviour = new XmlBehaviour();
+ this.$completer = new HtmlCompletions();
+
+ this.createModeDelegates({
+ "js-": JavaScriptMode,
+ "css-": CssMode
+ });
+
+ this.foldingRules = new HtmlFoldMode(this.voidElements, lang.arrayToMap(optionalEndTags));
+};
+oop.inherits(Mode, TextMode);
+
+(function() {
+
+ this.blockComment = {start: ""};
+
+ this.voidElements = lang.arrayToMap(voidElements);
+
+ this.getNextLineIndent = function(state, line, tab) {
+ return this.$getIndent(line);
+ };
+
+ this.checkOutdent = function(state, line, input) {
+ return false;
+ };
+
+ this.getCompletions = function(state, session, pos, prefix) {
+ return this.$completer.getCompletions(state, session, pos, prefix);
+ };
+
+ this.createWorker = function(session) {
+ if (this.constructor != Mode)
+ return;
+ var worker = new WorkerClient(["ace"], "ace/mode/html_worker", "Worker");
+ worker.attachToDocument(session.getDocument());
+
+ if (this.fragmentContext)
+ worker.call("setOptions", [{context: this.fragmentContext}]);
+
+ worker.on("error", function(e) {
+ session.setAnnotations(e.data);
+ });
+
+ worker.on("terminate", function() {
+ session.clearAnnotations();
+ });
+
+ return worker;
+ };
+
+ this.$id = "ace/mode/html";
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+});
+
+define("ace/mode/nunjucks_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules","ace/mode/html_highlight_rules"], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
+var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules;
+
+var NunjucksHighlightRules = function() {
+ HtmlHighlightRules.call(this);
+ this.$rules["start"].unshift({
+ token: "punctuation.begin",
+ regex: /{{-?/,
+ push: [{
+ token: "punctuation.end",
+ regex: /-?}}/,
+ next: "pop"
+ },
+ {include: "expression"}
+ ]
+ }, {
+ token: "punctuation.begin",
+ regex: /{%-?/,
+ push: [{
+ token: "punctuation.end",
+ regex: /-?%}/,
+ next: "pop"
+ }, {
+ token: "constant.language.escape",
+ regex: /\b(r\/.*\/[gimy]?)\b/
+ },
+ {include: "statement"}
+ ]
+ }, {
+ token: "comment.begin",
+ regex: /{#/,
+ push: [{
+ token: "comment.end",
+ regex: /#}/,
+ next: "pop"
+ },
+ {defaultToken: "comment"}
+ ]
+ });
+ this.addRules({
+ attribute_value: [{
+ token: "string.attribute-value.xml",
+ regex: "'",
+ push: [
+ {token: "string.attribute-value.xml", regex: "'", next: "pop"},
+ {
+ token: "punctuation.begin",
+ regex: /{{-?/,
+ push: [{
+ token: "punctuation.end",
+ regex: /-?}}/,
+ next: "pop"
+ },
+ {include: "expression"}
+ ]
+ },
+ {include: "attr_reference"},
+ {defaultToken: "string.attribute-value.xml"}
+ ]
+ }, {
+ token: "string.attribute-value.xml",
+ regex: '"',
+ push: [
+ {token: "string.attribute-value.xml", regex: '"', next: "pop"},
+ {
+ token: "punctuation.begin",
+ regex: /{{-?/,
+ push: [{
+ token: "punctuation.end",
+ regex: /-?}}/,
+ next: "pop"
+ },
+ {include: "expression"}
+ ]
+ },
+ {include: "attr_reference"},
+ {defaultToken: "string.attribute-value.xml"}
+ ]
+ }],
+ "statement": [{
+ token: "keyword.control",
+ regex: /\b(block|endblock|extends|endif|elif|for|endfor|asyncEach|endeach|include|asyncAll|endall|macro|endmacro|set|endset|ignore missing|as|from|raw|verbatim|filter|endfilter)\b/
+ },
+ {include: "expression"}
+ ],
+ "expression": [{
+ token: "constant.language",
+ regex: /\b(true|false|none)\b/
+ }, {
+ token: "string",
+ regex: /"/,
+ push: [{
+ token: "string",
+ regex: /"/,
+ next: "pop"
+ },
+ {include: "escapeStrings"},
+ {defaultToken: "string"}
+ ]
+ }, {
+ token: "string",
+ regex: /'/,
+ push: [{
+ token: "string",
+ regex: /'/,
+ next: "pop"
+ },
+ {include: "escapeStrings"},
+ {defaultToken: "string"}
+ ]
+ }, {
+ token: "constant.numeric", // hexadecimal, octal and binary
+ regex: /0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/
+ }, {
+ token: "constant.numeric", // decimal integers and floats
+ regex: /(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/
+ }, {
+ token: "keyword.operator",
+ regex: /\+|-|\/\/|\/|%|\*\*|\*|===|==|!==|!=|>=|>|<=|
+ }, {
+ token: "keyword.control",
+ regex: /\b(and|else|if|in|import|not|or)\b/
+ }, {
+ token: "support.function",
+ regex: /[a-zA-Z_]+(?=\()/
+ }, {
+ token: "paren.lpar",
+ regex: /[(\[{]/
+ }, {
+ token: "paren.rpar",
+ regex: /[)\]}]/
+ }, {
+ token: "punctuation",
+ regex: /[,]/
+ }, {
+ token: ["punctuation", "support.function"],
+ regex: /(\.)([a-zA-Z_][a-zA-Z0-9_]*)(?=\()/
+ }, {
+ token: ["punctuation", "variable.parameter"],
+ regex: /(\.)([a-zA-Z_][a-zA-Z0-9_]*)/
+ }, {
+ token: ["punctuation", "text", "support.other"],
+ regex: /(\|)(\s)*([a-zA-Z_][a-zA-Z0-9_]*)/
+ }, {
+ token: "variable",
+ regex: /[a-zA-Z_][a-zA-Z0-9_]*/
+ }
+ ],
+ "escapeStrings": [{
+ token: "constant.language.escape",
+ regex: /(\\\\n)|(\\\\)|(\\")|(\\')|(\\a)|(\\b)|(\\f)|(\\n)|(\\r)|(\\t)|(\\v)/
+ }, {
+ token: "constant.language.escape",
+ regex: /\\(?:x[0-9A-F]{2}|(?:U[0-9A-Fa-f]{8})|(?:u[0-9A-Fa-f]{4})|(?:N{[a-zA-Z ]+}))/
+ }]
+ });
+
+ this.normalizeRules();
+};
+
+oop.inherits(NunjucksHighlightRules, TextHighlightRules);
+
+exports.NunjucksHighlightRules = NunjucksHighlightRules;
+});
+
+define("ace/mode/nunjucks",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/nunjucks_highlight_rules"], function(require, exports, module) {
+ "use strict";
+
+var oop = require("../lib/oop");
+var HtmlMode = require("./html").Mode;
+var NunjucksHighlightRules = require("./nunjucks_highlight_rules").NunjucksHighlightRules;
+
+var Mode = function() {
+ this.HighlightRules = NunjucksHighlightRules;
+};
+
+oop.inherits(Mode, HtmlMode);
+
+(function() {
+ this.$id = "ace/mode/nunjucks";
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+}); (function() {
+ window.require(["ace/mode/nunjucks"], function(m) {
+ if (typeof module == "object" && typeof exports == "object" && module) {
+ module.exports = m;
+ }
+ });
+ })();
+
\ No newline at end of file
diff --git a/htdocs/includes/ace/src/mode-rust.js b/htdocs/includes/ace/src/mode-rust.js
index d10bdfce408..e24ed47a680 100644
--- a/htdocs/includes/ace/src/mode-rust.js
+++ b/htdocs/includes/ace/src/mode-rust.js
@@ -56,7 +56,7 @@ var RustHighlightRules = function() {
regex: '\\b(fn)(\\s+)((?:r#)?[a-zA-Z_][a-zA-Z0-9_]*)' },
{ token: 'support.constant', regex: '\\b[a-zA-Z_][\\w\\d]*::' },
{ token: 'keyword.source.rust',
- regex: '\\b(?:abstract|alignof|as|become|box|break|catch|continue|const|crate|default|do|dyn|else|enum|extern|for|final|if|impl|in|let|loop|macro|match|mod|move|mut|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\\b' },
+ regex: '\\b(?:abstract|alignof|as|async|await|become|box|break|catch|continue|const|crate|default|do|dyn|else|enum|extern|for|final|if|impl|in|let|loop|macro|match|mod|move|mut|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\\b' },
{ token: 'storage.type.source.rust',
regex: '\\b(?:Self|isize|usize|char|bool|u8|u16|u32|u64|u128|f16|f32|f64|i8|i16|i32|i64|i128|str|option|either|c_float|c_double|c_void|FILE|fpos_t|DIR|dirent|c_char|c_schar|c_uchar|c_short|c_ushort|c_int|c_uint|c_long|c_ulong|size_t|ptrdiff_t|clock_t|time_t|c_longlong|c_ulonglong|intptr_t|uintptr_t|off_t|dev_t|ino_t|pid_t|mode_t|ssize_t)\\b' },
{ token: 'variable.language.source.rust', regex: '\\bself\\b' },
diff --git a/htdocs/includes/ace/src/mode-slim.js b/htdocs/includes/ace/src/mode-slim.js
index 320e6a75b92..7f243bde705 100644
--- a/htdocs/includes/ace/src/mode-slim.js
+++ b/htdocs/includes/ace/src/mode-slim.js
@@ -2831,7 +2831,7 @@ var MarkdownHighlightRules = function() {
next : "blockquote"
}, { // HR * - _
token : "constant",
- regex : "^ {0,2}(?:(?: ?\\* ?){3,}|(?: ?\\- ?){3,}|(?: ?\\_ ?){3,})\\s*$",
+ regex : "^ {0,3}(?:(?:\\* ?){3,}|(?:\\- ?){3,}|(?:\\_ ?){3,})\\s*$",
next: "allowBlock"
}, { // list
token : "markup.list",
diff --git a/htdocs/includes/ace/src/mode-vhdl.js b/htdocs/includes/ace/src/mode-vhdl.js
index e6222383e60..75f22a1f512 100644
--- a/htdocs/includes/ace/src/mode-vhdl.js
+++ b/htdocs/includes/ace/src/mode-vhdl.js
@@ -12,15 +12,14 @@ var VHDLHighlightRules = function() {
"begin|block|buffer|bus|case|component|configuration|"+
"disconnect|downto|else|elsif|end|entity|file|for|function|"+
"generate|generic|guarded|if|impure|in|inertial|inout|is|"+
- "label|linkage|literal|loop|mapnew|next|of|on|open|"+
- "others|out|port|process|pure|range|record|reject|"+
- "report|return|select|shared|subtype|then|to|transport|"+
+ "label|linkage|literal|loop|mapnew|next|of|on|open|others|"+
+ "out|port|process|pure|range|record|reject|report|return|"+
+ "select|severity|shared|signal|subtype|then|to|transport|"+
"type|unaffected|united|until|wait|when|while|with";
var storageType = "bit|bit_vector|boolean|character|integer|line|natural|"+
- "positive|real|register|severity|signal|signed|"+
- "std_logic|std_logic_vector|string||text|time|unsigned|"+
- "variable";
+ "positive|real|register|signed|std_logic|"+
+ "std_logic_vector|string||text|time|unsigned|variable";
var storageModifiers = "array|constant";
diff --git a/htdocs/includes/ace/src/snippets/json5.js b/htdocs/includes/ace/src/snippets/json5.js
new file mode 100644
index 00000000000..8afbead737d
--- /dev/null
+++ b/htdocs/includes/ace/src/snippets/json5.js
@@ -0,0 +1,14 @@
+define("ace/snippets/json5",["require","exports","module"], function(require, exports, module) {
+"use strict";
+
+exports.snippetText =undefined;
+exports.scope = "json5";
+
+}); (function() {
+ window.require(["ace/snippets/json5"], function(m) {
+ if (typeof module == "object" && typeof exports == "object" && module) {
+ module.exports = m;
+ }
+ });
+ })();
+
\ No newline at end of file
diff --git a/htdocs/includes/ace/src/snippets/nunjucks.js b/htdocs/includes/ace/src/snippets/nunjucks.js
new file mode 100644
index 00000000000..961adec5778
--- /dev/null
+++ b/htdocs/includes/ace/src/snippets/nunjucks.js
@@ -0,0 +1,14 @@
+define("ace/snippets/nunjucks",["require","exports","module"], function(require, exports, module) {
+"use strict";
+
+exports.snippetText =undefined;
+exports.scope = "nunjucks";
+
+}); (function() {
+ window.require(["ace/snippets/nunjucks"], function(m) {
+ if (typeof module == "object" && typeof exports == "object" && module) {
+ module.exports = m;
+ }
+ });
+ })();
+
\ No newline at end of file
diff --git a/htdocs/includes/ace/src/worker-coffee.js b/htdocs/includes/ace/src/worker-coffee.js
index 38a3b4a12c6..e924c0c88a4 100644
--- a/htdocs/includes/ace/src/worker-coffee.js
+++ b/htdocs/includes/ace/src/worker-coffee.js
@@ -2092,10 +2092,10 @@ if (!Date.now) {
return new Date().getTime();
};
}
-var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
+var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" +
"\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
"\u2029\uFEFF";
-if (!String.prototype.trim || ws.trim()) {
+if (!String.prototype.trim) {
ws = "[" + ws + "]";
var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
trimEndRegexp = new RegExp(ws + ws + "*$");
diff --git a/htdocs/includes/ace/src/worker-css.js b/htdocs/includes/ace/src/worker-css.js
index 78d75c18028..a7d914e3397 100644
--- a/htdocs/includes/ace/src/worker-css.js
+++ b/htdocs/includes/ace/src/worker-css.js
@@ -8709,10 +8709,10 @@ if (!Date.now) {
return new Date().getTime();
};
}
-var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
+var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" +
"\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
"\u2029\uFEFF";
-if (!String.prototype.trim || ws.trim()) {
+if (!String.prototype.trim) {
ws = "[" + ws + "]";
var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
trimEndRegexp = new RegExp(ws + ws + "*$");
diff --git a/htdocs/includes/ace/src/worker-html.js b/htdocs/includes/ace/src/worker-html.js
index 6d60761b9a1..f52f5eeb204 100644
--- a/htdocs/includes/ace/src/worker-html.js
+++ b/htdocs/includes/ace/src/worker-html.js
@@ -11544,10 +11544,10 @@ if (!Date.now) {
return new Date().getTime();
};
}
-var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
+var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" +
"\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
"\u2029\uFEFF";
-if (!String.prototype.trim || ws.trim()) {
+if (!String.prototype.trim) {
ws = "[" + ws + "]";
var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
trimEndRegexp = new RegExp(ws + ws + "*$");
diff --git a/htdocs/includes/ace/src/worker-javascript.js b/htdocs/includes/ace/src/worker-javascript.js
index 19f5058d5c1..4d3d2a85e99 100644
--- a/htdocs/includes/ace/src/worker-javascript.js
+++ b/htdocs/includes/ace/src/worker-javascript.js
@@ -12467,10 +12467,10 @@ if (!Date.now) {
return new Date().getTime();
};
}
-var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
+var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" +
"\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
"\u2029\uFEFF";
-if (!String.prototype.trim || ws.trim()) {
+if (!String.prototype.trim) {
ws = "[" + ws + "]";
var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
trimEndRegexp = new RegExp(ws + ws + "*$");
diff --git a/htdocs/includes/ace/src/worker-json.js b/htdocs/includes/ace/src/worker-json.js
index 3f5abb5c5fe..0f7fa308c6f 100644
--- a/htdocs/includes/ace/src/worker-json.js
+++ b/htdocs/includes/ace/src/worker-json.js
@@ -2337,10 +2337,10 @@ if (!Date.now) {
return new Date().getTime();
};
}
-var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
+var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" +
"\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
"\u2029\uFEFF";
-if (!String.prototype.trim || ws.trim()) {
+if (!String.prototype.trim) {
ws = "[" + ws + "]";
var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
trimEndRegexp = new RegExp(ws + ws + "*$");
diff --git a/htdocs/includes/ace/src/worker-lua.js b/htdocs/includes/ace/src/worker-lua.js
index 6e1ebb68275..9884d2a8759 100644
--- a/htdocs/includes/ace/src/worker-lua.js
+++ b/htdocs/includes/ace/src/worker-lua.js
@@ -3572,10 +3572,10 @@ if (!Date.now) {
return new Date().getTime();
};
}
-var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
+var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" +
"\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
"\u2029\uFEFF";
-if (!String.prototype.trim || ws.trim()) {
+if (!String.prototype.trim) {
ws = "[" + ws + "]";
var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
trimEndRegexp = new RegExp(ws + ws + "*$");
diff --git a/htdocs/includes/ace/src/worker-php.js b/htdocs/includes/ace/src/worker-php.js
index 7d41f37cb50..9be61099005 100644
--- a/htdocs/includes/ace/src/worker-php.js
+++ b/htdocs/includes/ace/src/worker-php.js
@@ -2394,7 +2394,7 @@ PHP.Lexer = function(src, ini) {
};
-PHP.Parser = function ( preprocessedTokens, eval ) {
+PHP.Parser = function ( preprocessedTokens, evaluate ) {
var yybase = this.yybase,
yydefault = this.yydefault,
@@ -2516,7 +2516,7 @@ PHP.Parser = function ( preprocessedTokens, eval ) {
this.yyastk[ this.stackPos ] = this.yyval;
attributeStack[ this.stackPos ] = this.startAttributes;
} else {
- if (eval !== true) {
+ if (evaluate !== true) {
var expected = [];
@@ -4241,10 +4241,10 @@ if (!Date.now) {
return new Date().getTime();
};
}
-var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
+var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" +
"\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
"\u2029\uFEFF";
-if (!String.prototype.trim || ws.trim()) {
+if (!String.prototype.trim) {
ws = "[" + ws + "]";
var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
trimEndRegexp = new RegExp(ws + ws + "*$");
diff --git a/htdocs/includes/ace/src/worker-xml.js b/htdocs/includes/ace/src/worker-xml.js
index f6ea2cbf148..d661272a9d2 100644
--- a/htdocs/includes/ace/src/worker-xml.js
+++ b/htdocs/includes/ace/src/worker-xml.js
@@ -1824,10 +1824,15 @@ function parseDCC(source,start,domBuilder,errorHandler){//sure start with '',start+9);
- domBuilder.startCDATA();
- domBuilder.characters(source,start+9,end-start-9);
- domBuilder.endCDATA()
- return end+3;
+ if (end > start) {
+ domBuilder.startCDATA();
+ domBuilder.characters(source,start+9,end-start-9);
+ domBuilder.endCDATA()
+ return end+3;
+ } else {
+ errorHandler.error("Unclosed CDATA");
+ return -1;
+ }
}
var matchs = split(source,start);
var len = matchs.length;
@@ -3825,10 +3830,10 @@ if (!Date.now) {
return new Date().getTime();
};
}
-var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
+var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" +
"\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
"\u2029\uFEFF";
-if (!String.prototype.trim || ws.trim()) {
+if (!String.prototype.trim) {
ws = "[" + ws + "]";
var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
trimEndRegexp = new RegExp(ws + ws + "*$");
diff --git a/htdocs/includes/ace/src/worker-xquery.js b/htdocs/includes/ace/src/worker-xquery.js
index a20b76c2c28..6f0f68123d2 100644
--- a/htdocs/includes/ace/src/worker-xquery.js
+++ b/htdocs/includes/ace/src/worker-xquery.js
@@ -58290,10 +58290,10 @@ if (!Date.now) {
return new Date().getTime();
};
}
-var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
+var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" +
"\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
"\u2029\uFEFF";
-if (!String.prototype.trim || ws.trim()) {
+if (!String.prototype.trim) {
ws = "[" + ws + "]";
var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
trimEndRegexp = new RegExp(ws + ws + "*$");
diff --git a/htdocs/includes/ace/webpack-resolver.js b/htdocs/includes/ace/webpack-resolver.js
index 1d5de60d98a..6205871f242 100644
--- a/htdocs/includes/ace/webpack-resolver.js
+++ b/htdocs/includes/ace/webpack-resolver.js
@@ -1,403 +1,403 @@
-ace.config.setModuleUrl('ace/ext/beautify', require('file-loader!./src-noconflict/ext-beautify.js'))
-ace.config.setModuleUrl('ace/ext/elastic_tabstops_lite', require('file-loader!./src-noconflict/ext-elastic_tabstops_lite.js'))
-ace.config.setModuleUrl('ace/ext/emmet', require('file-loader!./src-noconflict/ext-emmet.js'))
-ace.config.setModuleUrl('ace/ext/error_marker', require('file-loader!./src-noconflict/ext-error_marker.js'))
-ace.config.setModuleUrl('ace/ext/keyboard_menu', require('file-loader!./src-noconflict/ext-keybinding_menu.js'))
-ace.config.setModuleUrl('ace/ext/language_tools', require('file-loader!./src-noconflict/ext-language_tools.js'))
-ace.config.setModuleUrl('ace/ext/linking', require('file-loader!./src-noconflict/ext-linking.js'))
-ace.config.setModuleUrl('ace/ext/modelist', require('file-loader!./src-noconflict/ext-modelist.js'))
-ace.config.setModuleUrl('ace/ext/options', require('file-loader!./src-noconflict/ext-options.js'))
-ace.config.setModuleUrl('ace/ext/prompt', require('file-loader!./src-noconflict/ext-prompt.js'))
-ace.config.setModuleUrl('ace/ext/rtl', require('file-loader!./src-noconflict/ext-rtl.js'))
-ace.config.setModuleUrl('ace/ext/searchbox', require('file-loader!./src-noconflict/ext-searchbox.js'))
-ace.config.setModuleUrl('ace/ext/settings_menu', require('file-loader!./src-noconflict/ext-settings_menu.js'))
-ace.config.setModuleUrl('ace/ext/spellcheck', require('file-loader!./src-noconflict/ext-spellcheck.js'))
-ace.config.setModuleUrl('ace/ext/split', require('file-loader!./src-noconflict/ext-split.js'))
-ace.config.setModuleUrl('ace/ext/static_highlight', require('file-loader!./src-noconflict/ext-static_highlight.js'))
-ace.config.setModuleUrl('ace/ext/statusbar', require('file-loader!./src-noconflict/ext-statusbar.js'))
-ace.config.setModuleUrl('ace/ext/textarea', require('file-loader!./src-noconflict/ext-textarea.js'))
-ace.config.setModuleUrl('ace/ext/themelist', require('file-loader!./src-noconflict/ext-themelist.js'))
-ace.config.setModuleUrl('ace/ext/whitespace', require('file-loader!./src-noconflict/ext-whitespace.js'))
-ace.config.setModuleUrl('ace/keyboard/emacs', require('file-loader!./src-noconflict/keybinding-emacs.js'))
-ace.config.setModuleUrl('ace/keyboard/sublime', require('file-loader!./src-noconflict/keybinding-sublime.js'))
-ace.config.setModuleUrl('ace/keyboard/vim', require('file-loader!./src-noconflict/keybinding-vim.js'))
-ace.config.setModuleUrl('ace/mode/abap', require('file-loader!./src-noconflict/mode-abap.js'))
-ace.config.setModuleUrl('ace/mode/abc', require('file-loader!./src-noconflict/mode-abc.js'))
-ace.config.setModuleUrl('ace/mode/actionscript', require('file-loader!./src-noconflict/mode-actionscript.js'))
-ace.config.setModuleUrl('ace/mode/ada', require('file-loader!./src-noconflict/mode-ada.js'))
-ace.config.setModuleUrl('ace/mode/apache_conf', require('file-loader!./src-noconflict/mode-apache_conf.js'))
-ace.config.setModuleUrl('ace/mode/apex', require('file-loader!./src-noconflict/mode-apex.js'))
-ace.config.setModuleUrl('ace/mode/applescript', require('file-loader!./src-noconflict/mode-applescript.js'))
-ace.config.setModuleUrl('ace/mode/aql', require('file-loader!./src-noconflict/mode-aql.js'))
-ace.config.setModuleUrl('ace/mode/asciidoc', require('file-loader!./src-noconflict/mode-asciidoc.js'))
-ace.config.setModuleUrl('ace/mode/asl', require('file-loader!./src-noconflict/mode-asl.js'))
-ace.config.setModuleUrl('ace/mode/assembly_x86', require('file-loader!./src-noconflict/mode-assembly_x86.js'))
-ace.config.setModuleUrl('ace/mode/autohotkey', require('file-loader!./src-noconflict/mode-autohotkey.js'))
-ace.config.setModuleUrl('ace/mode/batchfile', require('file-loader!./src-noconflict/mode-batchfile.js'))
-ace.config.setModuleUrl('ace/mode/bro', require('file-loader!./src-noconflict/mode-bro.js'))
-ace.config.setModuleUrl('ace/mode/c9search', require('file-loader!./src-noconflict/mode-c9search.js'))
-ace.config.setModuleUrl('ace/mode/cirru', require('file-loader!./src-noconflict/mode-cirru.js'))
-ace.config.setModuleUrl('ace/mode/clojure', require('file-loader!./src-noconflict/mode-clojure.js'))
-ace.config.setModuleUrl('ace/mode/cobol', require('file-loader!./src-noconflict/mode-cobol.js'))
-ace.config.setModuleUrl('ace/mode/coffee', require('file-loader!./src-noconflict/mode-coffee.js'))
-ace.config.setModuleUrl('ace/mode/coldfusion', require('file-loader!./src-noconflict/mode-coldfusion.js'))
-ace.config.setModuleUrl('ace/mode/crystal', require('file-loader!./src-noconflict/mode-crystal.js'))
-ace.config.setModuleUrl('ace/mode/csharp', require('file-loader!./src-noconflict/mode-csharp.js'))
-ace.config.setModuleUrl('ace/mode/csound_document', require('file-loader!./src-noconflict/mode-csound_document.js'))
-ace.config.setModuleUrl('ace/mode/csound_orchestra', require('file-loader!./src-noconflict/mode-csound_orchestra.js'))
-ace.config.setModuleUrl('ace/mode/csound_score', require('file-loader!./src-noconflict/mode-csound_score.js'))
-ace.config.setModuleUrl('ace/mode/csp', require('file-loader!./src-noconflict/mode-csp.js'))
-ace.config.setModuleUrl('ace/mode/css', require('file-loader!./src-noconflict/mode-css.js'))
-ace.config.setModuleUrl('ace/mode/curly', require('file-loader!./src-noconflict/mode-curly.js'))
-ace.config.setModuleUrl('ace/mode/c_cpp', require('file-loader!./src-noconflict/mode-c_cpp.js'))
-ace.config.setModuleUrl('ace/mode/d', require('file-loader!./src-noconflict/mode-d.js'))
-ace.config.setModuleUrl('ace/mode/dart', require('file-loader!./src-noconflict/mode-dart.js'))
-ace.config.setModuleUrl('ace/mode/diff', require('file-loader!./src-noconflict/mode-diff.js'))
-ace.config.setModuleUrl('ace/mode/django', require('file-loader!./src-noconflict/mode-django.js'))
-ace.config.setModuleUrl('ace/mode/dockerfile', require('file-loader!./src-noconflict/mode-dockerfile.js'))
-ace.config.setModuleUrl('ace/mode/dot', require('file-loader!./src-noconflict/mode-dot.js'))
-ace.config.setModuleUrl('ace/mode/drools', require('file-loader!./src-noconflict/mode-drools.js'))
-ace.config.setModuleUrl('ace/mode/edifact', require('file-loader!./src-noconflict/mode-edifact.js'))
-ace.config.setModuleUrl('ace/mode/eiffel', require('file-loader!./src-noconflict/mode-eiffel.js'))
-ace.config.setModuleUrl('ace/mode/ejs', require('file-loader!./src-noconflict/mode-ejs.js'))
-ace.config.setModuleUrl('ace/mode/elixir', require('file-loader!./src-noconflict/mode-elixir.js'))
-ace.config.setModuleUrl('ace/mode/elm', require('file-loader!./src-noconflict/mode-elm.js'))
-ace.config.setModuleUrl('ace/mode/erlang', require('file-loader!./src-noconflict/mode-erlang.js'))
-ace.config.setModuleUrl('ace/mode/forth', require('file-loader!./src-noconflict/mode-forth.js'))
-ace.config.setModuleUrl('ace/mode/fortran', require('file-loader!./src-noconflict/mode-fortran.js'))
-ace.config.setModuleUrl('ace/mode/fsharp', require('file-loader!./src-noconflict/mode-fsharp.js'))
-ace.config.setModuleUrl('ace/mode/fsl', require('file-loader!./src-noconflict/mode-fsl.js'))
-ace.config.setModuleUrl('ace/mode/ftl', require('file-loader!./src-noconflict/mode-ftl.js'))
-ace.config.setModuleUrl('ace/mode/gcode', require('file-loader!./src-noconflict/mode-gcode.js'))
-ace.config.setModuleUrl('ace/mode/gherkin', require('file-loader!./src-noconflict/mode-gherkin.js'))
-ace.config.setModuleUrl('ace/mode/gitignore', require('file-loader!./src-noconflict/mode-gitignore.js'))
-ace.config.setModuleUrl('ace/mode/glsl', require('file-loader!./src-noconflict/mode-glsl.js'))
-ace.config.setModuleUrl('ace/mode/gobstones', require('file-loader!./src-noconflict/mode-gobstones.js'))
-ace.config.setModuleUrl('ace/mode/golang', require('file-loader!./src-noconflict/mode-golang.js'))
-ace.config.setModuleUrl('ace/mode/graphqlschema', require('file-loader!./src-noconflict/mode-graphqlschema.js'))
-ace.config.setModuleUrl('ace/mode/groovy', require('file-loader!./src-noconflict/mode-groovy.js'))
-ace.config.setModuleUrl('ace/mode/haml', require('file-loader!./src-noconflict/mode-haml.js'))
-ace.config.setModuleUrl('ace/mode/handlebars', require('file-loader!./src-noconflict/mode-handlebars.js'))
-ace.config.setModuleUrl('ace/mode/haskell', require('file-loader!./src-noconflict/mode-haskell.js'))
-ace.config.setModuleUrl('ace/mode/haskell_cabal', require('file-loader!./src-noconflict/mode-haskell_cabal.js'))
-ace.config.setModuleUrl('ace/mode/haxe', require('file-loader!./src-noconflict/mode-haxe.js'))
-ace.config.setModuleUrl('ace/mode/hjson', require('file-loader!./src-noconflict/mode-hjson.js'))
-ace.config.setModuleUrl('ace/mode/html', require('file-loader!./src-noconflict/mode-html.js'))
-ace.config.setModuleUrl('ace/mode/html_elixir', require('file-loader!./src-noconflict/mode-html_elixir.js'))
-ace.config.setModuleUrl('ace/mode/html_ruby', require('file-loader!./src-noconflict/mode-html_ruby.js'))
-ace.config.setModuleUrl('ace/mode/ini', require('file-loader!./src-noconflict/mode-ini.js'))
-ace.config.setModuleUrl('ace/mode/io', require('file-loader!./src-noconflict/mode-io.js'))
-ace.config.setModuleUrl('ace/mode/jack', require('file-loader!./src-noconflict/mode-jack.js'))
-ace.config.setModuleUrl('ace/mode/jade', require('file-loader!./src-noconflict/mode-jade.js'))
-ace.config.setModuleUrl('ace/mode/java', require('file-loader!./src-noconflict/mode-java.js'))
-ace.config.setModuleUrl('ace/mode/javascript', require('file-loader!./src-noconflict/mode-javascript.js'))
-ace.config.setModuleUrl('ace/mode/json', require('file-loader!./src-noconflict/mode-json.js'))
-ace.config.setModuleUrl('ace/mode/jsoniq', require('file-loader!./src-noconflict/mode-jsoniq.js'))
-ace.config.setModuleUrl('ace/mode/jsp', require('file-loader!./src-noconflict/mode-jsp.js'))
-ace.config.setModuleUrl('ace/mode/jssm', require('file-loader!./src-noconflict/mode-jssm.js'))
-ace.config.setModuleUrl('ace/mode/jsx', require('file-loader!./src-noconflict/mode-jsx.js'))
-ace.config.setModuleUrl('ace/mode/julia', require('file-loader!./src-noconflict/mode-julia.js'))
-ace.config.setModuleUrl('ace/mode/kotlin', require('file-loader!./src-noconflict/mode-kotlin.js'))
-ace.config.setModuleUrl('ace/mode/latex', require('file-loader!./src-noconflict/mode-latex.js'))
-ace.config.setModuleUrl('ace/mode/less', require('file-loader!./src-noconflict/mode-less.js'))
-ace.config.setModuleUrl('ace/mode/liquid', require('file-loader!./src-noconflict/mode-liquid.js'))
-ace.config.setModuleUrl('ace/mode/lisp', require('file-loader!./src-noconflict/mode-lisp.js'))
-ace.config.setModuleUrl('ace/mode/livescript', require('file-loader!./src-noconflict/mode-livescript.js'))
-ace.config.setModuleUrl('ace/mode/logiql', require('file-loader!./src-noconflict/mode-logiql.js'))
-ace.config.setModuleUrl('ace/mode/logtalk', require('file-loader!./src-noconflict/mode-logtalk.js'))
-ace.config.setModuleUrl('ace/mode/lsl', require('file-loader!./src-noconflict/mode-lsl.js'))
-ace.config.setModuleUrl('ace/mode/lua', require('file-loader!./src-noconflict/mode-lua.js'))
-ace.config.setModuleUrl('ace/mode/luapage', require('file-loader!./src-noconflict/mode-luapage.js'))
-ace.config.setModuleUrl('ace/mode/lucene', require('file-loader!./src-noconflict/mode-lucene.js'))
-ace.config.setModuleUrl('ace/mode/makefile', require('file-loader!./src-noconflict/mode-makefile.js'))
-ace.config.setModuleUrl('ace/mode/markdown', require('file-loader!./src-noconflict/mode-markdown.js'))
-ace.config.setModuleUrl('ace/mode/mask', require('file-loader!./src-noconflict/mode-mask.js'))
-ace.config.setModuleUrl('ace/mode/matlab', require('file-loader!./src-noconflict/mode-matlab.js'))
-ace.config.setModuleUrl('ace/mode/maze', require('file-loader!./src-noconflict/mode-maze.js'))
-ace.config.setModuleUrl('ace/mode/mel', require('file-loader!./src-noconflict/mode-mel.js'))
-ace.config.setModuleUrl('ace/mode/mixal', require('file-loader!./src-noconflict/mode-mixal.js'))
-ace.config.setModuleUrl('ace/mode/mushcode', require('file-loader!./src-noconflict/mode-mushcode.js'))
-ace.config.setModuleUrl('ace/mode/mysql', require('file-loader!./src-noconflict/mode-mysql.js'))
-ace.config.setModuleUrl('ace/mode/nginx', require('file-loader!./src-noconflict/mode-nginx.js'))
-ace.config.setModuleUrl('ace/mode/nim', require('file-loader!./src-noconflict/mode-nim.js'))
-ace.config.setModuleUrl('ace/mode/nix', require('file-loader!./src-noconflict/mode-nix.js'))
-ace.config.setModuleUrl('ace/mode/nsis', require('file-loader!./src-noconflict/mode-nsis.js'))
-ace.config.setModuleUrl('ace/mode/objectivec', require('file-loader!./src-noconflict/mode-objectivec.js'))
-ace.config.setModuleUrl('ace/mode/ocaml', require('file-loader!./src-noconflict/mode-ocaml.js'))
-ace.config.setModuleUrl('ace/mode/pascal', require('file-loader!./src-noconflict/mode-pascal.js'))
-ace.config.setModuleUrl('ace/mode/perl', require('file-loader!./src-noconflict/mode-perl.js'))
-ace.config.setModuleUrl('ace/mode/perl6', require('file-loader!./src-noconflict/mode-perl6.js'))
-ace.config.setModuleUrl('ace/mode/pgsql', require('file-loader!./src-noconflict/mode-pgsql.js'))
-ace.config.setModuleUrl('ace/mode/php', require('file-loader!./src-noconflict/mode-php.js'))
-ace.config.setModuleUrl('ace/mode/php_laravel_blade', require('file-loader!./src-noconflict/mode-php_laravel_blade.js'))
-ace.config.setModuleUrl('ace/mode/pig', require('file-loader!./src-noconflict/mode-pig.js'))
-ace.config.setModuleUrl('ace/mode/plain_text', require('file-loader!./src-noconflict/mode-plain_text.js'))
-ace.config.setModuleUrl('ace/mode/powershell', require('file-loader!./src-noconflict/mode-powershell.js'))
-ace.config.setModuleUrl('ace/mode/praat', require('file-loader!./src-noconflict/mode-praat.js'))
-ace.config.setModuleUrl('ace/mode/prolog', require('file-loader!./src-noconflict/mode-prolog.js'))
-ace.config.setModuleUrl('ace/mode/properties', require('file-loader!./src-noconflict/mode-properties.js'))
-ace.config.setModuleUrl('ace/mode/protobuf', require('file-loader!./src-noconflict/mode-protobuf.js'))
-ace.config.setModuleUrl('ace/mode/puppet', require('file-loader!./src-noconflict/mode-puppet.js'))
-ace.config.setModuleUrl('ace/mode/python', require('file-loader!./src-noconflict/mode-python.js'))
-ace.config.setModuleUrl('ace/mode/r', require('file-loader!./src-noconflict/mode-r.js'))
-ace.config.setModuleUrl('ace/mode/razor', require('file-loader!./src-noconflict/mode-razor.js'))
-ace.config.setModuleUrl('ace/mode/rdoc', require('file-loader!./src-noconflict/mode-rdoc.js'))
-ace.config.setModuleUrl('ace/mode/red', require('file-loader!./src-noconflict/mode-red.js'))
-ace.config.setModuleUrl('ace/mode/redshift', require('file-loader!./src-noconflict/mode-redshift.js'))
-ace.config.setModuleUrl('ace/mode/rhtml', require('file-loader!./src-noconflict/mode-rhtml.js'))
-ace.config.setModuleUrl('ace/mode/rst', require('file-loader!./src-noconflict/mode-rst.js'))
-ace.config.setModuleUrl('ace/mode/ruby', require('file-loader!./src-noconflict/mode-ruby.js'))
-ace.config.setModuleUrl('ace/mode/rust', require('file-loader!./src-noconflict/mode-rust.js'))
-ace.config.setModuleUrl('ace/mode/sass', require('file-loader!./src-noconflict/mode-sass.js'))
-ace.config.setModuleUrl('ace/mode/scad', require('file-loader!./src-noconflict/mode-scad.js'))
-ace.config.setModuleUrl('ace/mode/scala', require('file-loader!./src-noconflict/mode-scala.js'))
-ace.config.setModuleUrl('ace/mode/scheme', require('file-loader!./src-noconflict/mode-scheme.js'))
-ace.config.setModuleUrl('ace/mode/scss', require('file-loader!./src-noconflict/mode-scss.js'))
-ace.config.setModuleUrl('ace/mode/sh', require('file-loader!./src-noconflict/mode-sh.js'))
-ace.config.setModuleUrl('ace/mode/sjs', require('file-loader!./src-noconflict/mode-sjs.js'))
-ace.config.setModuleUrl('ace/mode/slim', require('file-loader!./src-noconflict/mode-slim.js'))
-ace.config.setModuleUrl('ace/mode/smarty', require('file-loader!./src-noconflict/mode-smarty.js'))
-ace.config.setModuleUrl('ace/mode/snippets', require('file-loader!./src-noconflict/mode-snippets.js'))
-ace.config.setModuleUrl('ace/mode/soy_template', require('file-loader!./src-noconflict/mode-soy_template.js'))
-ace.config.setModuleUrl('ace/mode/space', require('file-loader!./src-noconflict/mode-space.js'))
-ace.config.setModuleUrl('ace/mode/sparql', require('file-loader!./src-noconflict/mode-sparql.js'))
-ace.config.setModuleUrl('ace/mode/sql', require('file-loader!./src-noconflict/mode-sql.js'))
-ace.config.setModuleUrl('ace/mode/sqlserver', require('file-loader!./src-noconflict/mode-sqlserver.js'))
-ace.config.setModuleUrl('ace/mode/stylus', require('file-loader!./src-noconflict/mode-stylus.js'))
-ace.config.setModuleUrl('ace/mode/svg', require('file-loader!./src-noconflict/mode-svg.js'))
-ace.config.setModuleUrl('ace/mode/swift', require('file-loader!./src-noconflict/mode-swift.js'))
-ace.config.setModuleUrl('ace/mode/tcl', require('file-loader!./src-noconflict/mode-tcl.js'))
-ace.config.setModuleUrl('ace/mode/terraform', require('file-loader!./src-noconflict/mode-terraform.js'))
-ace.config.setModuleUrl('ace/mode/tex', require('file-loader!./src-noconflict/mode-tex.js'))
-ace.config.setModuleUrl('ace/mode/text', require('file-loader!./src-noconflict/mode-text.js'))
-ace.config.setModuleUrl('ace/mode/textile', require('file-loader!./src-noconflict/mode-textile.js'))
-ace.config.setModuleUrl('ace/mode/toml', require('file-loader!./src-noconflict/mode-toml.js'))
-ace.config.setModuleUrl('ace/mode/tsx', require('file-loader!./src-noconflict/mode-tsx.js'))
-ace.config.setModuleUrl('ace/mode/turtle', require('file-loader!./src-noconflict/mode-turtle.js'))
-ace.config.setModuleUrl('ace/mode/twig', require('file-loader!./src-noconflict/mode-twig.js'))
-ace.config.setModuleUrl('ace/mode/typescript', require('file-loader!./src-noconflict/mode-typescript.js'))
-ace.config.setModuleUrl('ace/mode/vala', require('file-loader!./src-noconflict/mode-vala.js'))
-ace.config.setModuleUrl('ace/mode/vbscript', require('file-loader!./src-noconflict/mode-vbscript.js'))
-ace.config.setModuleUrl('ace/mode/velocity', require('file-loader!./src-noconflict/mode-velocity.js'))
-ace.config.setModuleUrl('ace/mode/verilog', require('file-loader!./src-noconflict/mode-verilog.js'))
-ace.config.setModuleUrl('ace/mode/vhdl', require('file-loader!./src-noconflict/mode-vhdl.js'))
-ace.config.setModuleUrl('ace/mode/visualforce', require('file-loader!./src-noconflict/mode-visualforce.js'))
-ace.config.setModuleUrl('ace/mode/wollok', require('file-loader!./src-noconflict/mode-wollok.js'))
-ace.config.setModuleUrl('ace/mode/xml', require('file-loader!./src-noconflict/mode-xml.js'))
-ace.config.setModuleUrl('ace/mode/xquery', require('file-loader!./src-noconflict/mode-xquery.js'))
-ace.config.setModuleUrl('ace/mode/yaml', require('file-loader!./src-noconflict/mode-yaml.js'))
-ace.config.setModuleUrl('ace/mode/zeek', require('file-loader!./src-noconflict/mode-zeek.js'))
+ace.config.setModuleUrl('ace/ext/beautify', require('file-loader?esModule=false!./src-noconflict/ext-beautify.js'))
+ace.config.setModuleUrl('ace/ext/elastic_tabstops_lite', require('file-loader?esModule=false!./src-noconflict/ext-elastic_tabstops_lite.js'))
+ace.config.setModuleUrl('ace/ext/emmet', require('file-loader?esModule=false!./src-noconflict/ext-emmet.js'))
+ace.config.setModuleUrl('ace/ext/error_marker', require('file-loader?esModule=false!./src-noconflict/ext-error_marker.js'))
+ace.config.setModuleUrl('ace/ext/keyboard_menu', require('file-loader?esModule=false!./src-noconflict/ext-keybinding_menu.js'))
+ace.config.setModuleUrl('ace/ext/language_tools', require('file-loader?esModule=false!./src-noconflict/ext-language_tools.js'))
+ace.config.setModuleUrl('ace/ext/linking', require('file-loader?esModule=false!./src-noconflict/ext-linking.js'))
+ace.config.setModuleUrl('ace/ext/modelist', require('file-loader?esModule=false!./src-noconflict/ext-modelist.js'))
+ace.config.setModuleUrl('ace/ext/options', require('file-loader?esModule=false!./src-noconflict/ext-options.js'))
+ace.config.setModuleUrl('ace/ext/prompt', require('file-loader?esModule=false!./src-noconflict/ext-prompt.js'))
+ace.config.setModuleUrl('ace/ext/rtl', require('file-loader?esModule=false!./src-noconflict/ext-rtl.js'))
+ace.config.setModuleUrl('ace/ext/searchbox', require('file-loader?esModule=false!./src-noconflict/ext-searchbox.js'))
+ace.config.setModuleUrl('ace/ext/settings_menu', require('file-loader?esModule=false!./src-noconflict/ext-settings_menu.js'))
+ace.config.setModuleUrl('ace/ext/spellcheck', require('file-loader?esModule=false!./src-noconflict/ext-spellcheck.js'))
+ace.config.setModuleUrl('ace/ext/split', require('file-loader?esModule=false!./src-noconflict/ext-split.js'))
+ace.config.setModuleUrl('ace/ext/static_highlight', require('file-loader?esModule=false!./src-noconflict/ext-static_highlight.js'))
+ace.config.setModuleUrl('ace/ext/statusbar', require('file-loader?esModule=false!./src-noconflict/ext-statusbar.js'))
+ace.config.setModuleUrl('ace/ext/textarea', require('file-loader?esModule=false!./src-noconflict/ext-textarea.js'))
+ace.config.setModuleUrl('ace/ext/themelist', require('file-loader?esModule=false!./src-noconflict/ext-themelist.js'))
+ace.config.setModuleUrl('ace/ext/whitespace', require('file-loader?esModule=false!./src-noconflict/ext-whitespace.js'))
+ace.config.setModuleUrl('ace/keyboard/emacs', require('file-loader?esModule=false!./src-noconflict/keybinding-emacs.js'))
+ace.config.setModuleUrl('ace/keyboard/sublime', require('file-loader?esModule=false!./src-noconflict/keybinding-sublime.js'))
+ace.config.setModuleUrl('ace/keyboard/vim', require('file-loader?esModule=false!./src-noconflict/keybinding-vim.js'))
+ace.config.setModuleUrl('ace/mode/abap', require('file-loader?esModule=false!./src-noconflict/mode-abap.js'))
+ace.config.setModuleUrl('ace/mode/abc', require('file-loader?esModule=false!./src-noconflict/mode-abc.js'))
+ace.config.setModuleUrl('ace/mode/actionscript', require('file-loader?esModule=false!./src-noconflict/mode-actionscript.js'))
+ace.config.setModuleUrl('ace/mode/ada', require('file-loader?esModule=false!./src-noconflict/mode-ada.js'))
+ace.config.setModuleUrl('ace/mode/apache_conf', require('file-loader?esModule=false!./src-noconflict/mode-apache_conf.js'))
+ace.config.setModuleUrl('ace/mode/apex', require('file-loader?esModule=false!./src-noconflict/mode-apex.js'))
+ace.config.setModuleUrl('ace/mode/applescript', require('file-loader?esModule=false!./src-noconflict/mode-applescript.js'))
+ace.config.setModuleUrl('ace/mode/aql', require('file-loader?esModule=false!./src-noconflict/mode-aql.js'))
+ace.config.setModuleUrl('ace/mode/asciidoc', require('file-loader?esModule=false!./src-noconflict/mode-asciidoc.js'))
+ace.config.setModuleUrl('ace/mode/asl', require('file-loader?esModule=false!./src-noconflict/mode-asl.js'))
+ace.config.setModuleUrl('ace/mode/assembly_x86', require('file-loader?esModule=false!./src-noconflict/mode-assembly_x86.js'))
+ace.config.setModuleUrl('ace/mode/autohotkey', require('file-loader?esModule=false!./src-noconflict/mode-autohotkey.js'))
+ace.config.setModuleUrl('ace/mode/batchfile', require('file-loader?esModule=false!./src-noconflict/mode-batchfile.js'))
+ace.config.setModuleUrl('ace/mode/bro', require('file-loader?esModule=false!./src-noconflict/mode-bro.js'))
+ace.config.setModuleUrl('ace/mode/c9search', require('file-loader?esModule=false!./src-noconflict/mode-c9search.js'))
+ace.config.setModuleUrl('ace/mode/cirru', require('file-loader?esModule=false!./src-noconflict/mode-cirru.js'))
+ace.config.setModuleUrl('ace/mode/clojure', require('file-loader?esModule=false!./src-noconflict/mode-clojure.js'))
+ace.config.setModuleUrl('ace/mode/cobol', require('file-loader?esModule=false!./src-noconflict/mode-cobol.js'))
+ace.config.setModuleUrl('ace/mode/coffee', require('file-loader?esModule=false!./src-noconflict/mode-coffee.js'))
+ace.config.setModuleUrl('ace/mode/coldfusion', require('file-loader?esModule=false!./src-noconflict/mode-coldfusion.js'))
+ace.config.setModuleUrl('ace/mode/crystal', require('file-loader?esModule=false!./src-noconflict/mode-crystal.js'))
+ace.config.setModuleUrl('ace/mode/csharp', require('file-loader?esModule=false!./src-noconflict/mode-csharp.js'))
+ace.config.setModuleUrl('ace/mode/csound_document', require('file-loader?esModule=false!./src-noconflict/mode-csound_document.js'))
+ace.config.setModuleUrl('ace/mode/csound_orchestra', require('file-loader?esModule=false!./src-noconflict/mode-csound_orchestra.js'))
+ace.config.setModuleUrl('ace/mode/csound_score', require('file-loader?esModule=false!./src-noconflict/mode-csound_score.js'))
+ace.config.setModuleUrl('ace/mode/csp', require('file-loader?esModule=false!./src-noconflict/mode-csp.js'))
+ace.config.setModuleUrl('ace/mode/css', require('file-loader?esModule=false!./src-noconflict/mode-css.js'))
+ace.config.setModuleUrl('ace/mode/curly', require('file-loader?esModule=false!./src-noconflict/mode-curly.js'))
+ace.config.setModuleUrl('ace/mode/c_cpp', require('file-loader?esModule=false!./src-noconflict/mode-c_cpp.js'))
+ace.config.setModuleUrl('ace/mode/d', require('file-loader?esModule=false!./src-noconflict/mode-d.js'))
+ace.config.setModuleUrl('ace/mode/dart', require('file-loader?esModule=false!./src-noconflict/mode-dart.js'))
+ace.config.setModuleUrl('ace/mode/diff', require('file-loader?esModule=false!./src-noconflict/mode-diff.js'))
+ace.config.setModuleUrl('ace/mode/django', require('file-loader?esModule=false!./src-noconflict/mode-django.js'))
+ace.config.setModuleUrl('ace/mode/dockerfile', require('file-loader?esModule=false!./src-noconflict/mode-dockerfile.js'))
+ace.config.setModuleUrl('ace/mode/dot', require('file-loader?esModule=false!./src-noconflict/mode-dot.js'))
+ace.config.setModuleUrl('ace/mode/drools', require('file-loader?esModule=false!./src-noconflict/mode-drools.js'))
+ace.config.setModuleUrl('ace/mode/edifact', require('file-loader?esModule=false!./src-noconflict/mode-edifact.js'))
+ace.config.setModuleUrl('ace/mode/eiffel', require('file-loader?esModule=false!./src-noconflict/mode-eiffel.js'))
+ace.config.setModuleUrl('ace/mode/ejs', require('file-loader?esModule=false!./src-noconflict/mode-ejs.js'))
+ace.config.setModuleUrl('ace/mode/elixir', require('file-loader?esModule=false!./src-noconflict/mode-elixir.js'))
+ace.config.setModuleUrl('ace/mode/elm', require('file-loader?esModule=false!./src-noconflict/mode-elm.js'))
+ace.config.setModuleUrl('ace/mode/erlang', require('file-loader?esModule=false!./src-noconflict/mode-erlang.js'))
+ace.config.setModuleUrl('ace/mode/forth', require('file-loader?esModule=false!./src-noconflict/mode-forth.js'))
+ace.config.setModuleUrl('ace/mode/fortran', require('file-loader?esModule=false!./src-noconflict/mode-fortran.js'))
+ace.config.setModuleUrl('ace/mode/fsharp', require('file-loader?esModule=false!./src-noconflict/mode-fsharp.js'))
+ace.config.setModuleUrl('ace/mode/fsl', require('file-loader?esModule=false!./src-noconflict/mode-fsl.js'))
+ace.config.setModuleUrl('ace/mode/ftl', require('file-loader?esModule=false!./src-noconflict/mode-ftl.js'))
+ace.config.setModuleUrl('ace/mode/gcode', require('file-loader?esModule=false!./src-noconflict/mode-gcode.js'))
+ace.config.setModuleUrl('ace/mode/gherkin', require('file-loader?esModule=false!./src-noconflict/mode-gherkin.js'))
+ace.config.setModuleUrl('ace/mode/gitignore', require('file-loader?esModule=false!./src-noconflict/mode-gitignore.js'))
+ace.config.setModuleUrl('ace/mode/glsl', require('file-loader?esModule=false!./src-noconflict/mode-glsl.js'))
+ace.config.setModuleUrl('ace/mode/gobstones', require('file-loader?esModule=false!./src-noconflict/mode-gobstones.js'))
+ace.config.setModuleUrl('ace/mode/golang', require('file-loader?esModule=false!./src-noconflict/mode-golang.js'))
+ace.config.setModuleUrl('ace/mode/graphqlschema', require('file-loader?esModule=false!./src-noconflict/mode-graphqlschema.js'))
+ace.config.setModuleUrl('ace/mode/groovy', require('file-loader?esModule=false!./src-noconflict/mode-groovy.js'))
+ace.config.setModuleUrl('ace/mode/haml', require('file-loader?esModule=false!./src-noconflict/mode-haml.js'))
+ace.config.setModuleUrl('ace/mode/handlebars', require('file-loader?esModule=false!./src-noconflict/mode-handlebars.js'))
+ace.config.setModuleUrl('ace/mode/haskell', require('file-loader?esModule=false!./src-noconflict/mode-haskell.js'))
+ace.config.setModuleUrl('ace/mode/haskell_cabal', require('file-loader?esModule=false!./src-noconflict/mode-haskell_cabal.js'))
+ace.config.setModuleUrl('ace/mode/haxe', require('file-loader?esModule=false!./src-noconflict/mode-haxe.js'))
+ace.config.setModuleUrl('ace/mode/hjson', require('file-loader?esModule=false!./src-noconflict/mode-hjson.js'))
+ace.config.setModuleUrl('ace/mode/html', require('file-loader?esModule=false!./src-noconflict/mode-html.js'))
+ace.config.setModuleUrl('ace/mode/html_elixir', require('file-loader?esModule=false!./src-noconflict/mode-html_elixir.js'))
+ace.config.setModuleUrl('ace/mode/html_ruby', require('file-loader?esModule=false!./src-noconflict/mode-html_ruby.js'))
+ace.config.setModuleUrl('ace/mode/ini', require('file-loader?esModule=false!./src-noconflict/mode-ini.js'))
+ace.config.setModuleUrl('ace/mode/io', require('file-loader?esModule=false!./src-noconflict/mode-io.js'))
+ace.config.setModuleUrl('ace/mode/jack', require('file-loader?esModule=false!./src-noconflict/mode-jack.js'))
+ace.config.setModuleUrl('ace/mode/jade', require('file-loader?esModule=false!./src-noconflict/mode-jade.js'))
+ace.config.setModuleUrl('ace/mode/java', require('file-loader?esModule=false!./src-noconflict/mode-java.js'))
+ace.config.setModuleUrl('ace/mode/javascript', require('file-loader?esModule=false!./src-noconflict/mode-javascript.js'))
+ace.config.setModuleUrl('ace/mode/json', require('file-loader?esModule=false!./src-noconflict/mode-json.js'))
+ace.config.setModuleUrl('ace/mode/jsoniq', require('file-loader?esModule=false!./src-noconflict/mode-jsoniq.js'))
+ace.config.setModuleUrl('ace/mode/jsp', require('file-loader?esModule=false!./src-noconflict/mode-jsp.js'))
+ace.config.setModuleUrl('ace/mode/jssm', require('file-loader?esModule=false!./src-noconflict/mode-jssm.js'))
+ace.config.setModuleUrl('ace/mode/jsx', require('file-loader?esModule=false!./src-noconflict/mode-jsx.js'))
+ace.config.setModuleUrl('ace/mode/julia', require('file-loader?esModule=false!./src-noconflict/mode-julia.js'))
+ace.config.setModuleUrl('ace/mode/kotlin', require('file-loader?esModule=false!./src-noconflict/mode-kotlin.js'))
+ace.config.setModuleUrl('ace/mode/latex', require('file-loader?esModule=false!./src-noconflict/mode-latex.js'))
+ace.config.setModuleUrl('ace/mode/less', require('file-loader?esModule=false!./src-noconflict/mode-less.js'))
+ace.config.setModuleUrl('ace/mode/liquid', require('file-loader?esModule=false!./src-noconflict/mode-liquid.js'))
+ace.config.setModuleUrl('ace/mode/lisp', require('file-loader?esModule=false!./src-noconflict/mode-lisp.js'))
+ace.config.setModuleUrl('ace/mode/livescript', require('file-loader?esModule=false!./src-noconflict/mode-livescript.js'))
+ace.config.setModuleUrl('ace/mode/logiql', require('file-loader?esModule=false!./src-noconflict/mode-logiql.js'))
+ace.config.setModuleUrl('ace/mode/logtalk', require('file-loader?esModule=false!./src-noconflict/mode-logtalk.js'))
+ace.config.setModuleUrl('ace/mode/lsl', require('file-loader?esModule=false!./src-noconflict/mode-lsl.js'))
+ace.config.setModuleUrl('ace/mode/lua', require('file-loader?esModule=false!./src-noconflict/mode-lua.js'))
+ace.config.setModuleUrl('ace/mode/luapage', require('file-loader?esModule=false!./src-noconflict/mode-luapage.js'))
+ace.config.setModuleUrl('ace/mode/lucene', require('file-loader?esModule=false!./src-noconflict/mode-lucene.js'))
+ace.config.setModuleUrl('ace/mode/makefile', require('file-loader?esModule=false!./src-noconflict/mode-makefile.js'))
+ace.config.setModuleUrl('ace/mode/markdown', require('file-loader?esModule=false!./src-noconflict/mode-markdown.js'))
+ace.config.setModuleUrl('ace/mode/mask', require('file-loader?esModule=false!./src-noconflict/mode-mask.js'))
+ace.config.setModuleUrl('ace/mode/matlab', require('file-loader?esModule=false!./src-noconflict/mode-matlab.js'))
+ace.config.setModuleUrl('ace/mode/maze', require('file-loader?esModule=false!./src-noconflict/mode-maze.js'))
+ace.config.setModuleUrl('ace/mode/mel', require('file-loader?esModule=false!./src-noconflict/mode-mel.js'))
+ace.config.setModuleUrl('ace/mode/mixal', require('file-loader?esModule=false!./src-noconflict/mode-mixal.js'))
+ace.config.setModuleUrl('ace/mode/mushcode', require('file-loader?esModule=false!./src-noconflict/mode-mushcode.js'))
+ace.config.setModuleUrl('ace/mode/mysql', require('file-loader?esModule=false!./src-noconflict/mode-mysql.js'))
+ace.config.setModuleUrl('ace/mode/nginx', require('file-loader?esModule=false!./src-noconflict/mode-nginx.js'))
+ace.config.setModuleUrl('ace/mode/nim', require('file-loader?esModule=false!./src-noconflict/mode-nim.js'))
+ace.config.setModuleUrl('ace/mode/nix', require('file-loader?esModule=false!./src-noconflict/mode-nix.js'))
+ace.config.setModuleUrl('ace/mode/nsis', require('file-loader?esModule=false!./src-noconflict/mode-nsis.js'))
+ace.config.setModuleUrl('ace/mode/objectivec', require('file-loader?esModule=false!./src-noconflict/mode-objectivec.js'))
+ace.config.setModuleUrl('ace/mode/ocaml', require('file-loader?esModule=false!./src-noconflict/mode-ocaml.js'))
+ace.config.setModuleUrl('ace/mode/pascal', require('file-loader?esModule=false!./src-noconflict/mode-pascal.js'))
+ace.config.setModuleUrl('ace/mode/perl', require('file-loader?esModule=false!./src-noconflict/mode-perl.js'))
+ace.config.setModuleUrl('ace/mode/perl6', require('file-loader?esModule=false!./src-noconflict/mode-perl6.js'))
+ace.config.setModuleUrl('ace/mode/pgsql', require('file-loader?esModule=false!./src-noconflict/mode-pgsql.js'))
+ace.config.setModuleUrl('ace/mode/php', require('file-loader?esModule=false!./src-noconflict/mode-php.js'))
+ace.config.setModuleUrl('ace/mode/php_laravel_blade', require('file-loader?esModule=false!./src-noconflict/mode-php_laravel_blade.js'))
+ace.config.setModuleUrl('ace/mode/pig', require('file-loader?esModule=false!./src-noconflict/mode-pig.js'))
+ace.config.setModuleUrl('ace/mode/plain_text', require('file-loader?esModule=false!./src-noconflict/mode-plain_text.js'))
+ace.config.setModuleUrl('ace/mode/powershell', require('file-loader?esModule=false!./src-noconflict/mode-powershell.js'))
+ace.config.setModuleUrl('ace/mode/praat', require('file-loader?esModule=false!./src-noconflict/mode-praat.js'))
+ace.config.setModuleUrl('ace/mode/prolog', require('file-loader?esModule=false!./src-noconflict/mode-prolog.js'))
+ace.config.setModuleUrl('ace/mode/properties', require('file-loader?esModule=false!./src-noconflict/mode-properties.js'))
+ace.config.setModuleUrl('ace/mode/protobuf', require('file-loader?esModule=false!./src-noconflict/mode-protobuf.js'))
+ace.config.setModuleUrl('ace/mode/puppet', require('file-loader?esModule=false!./src-noconflict/mode-puppet.js'))
+ace.config.setModuleUrl('ace/mode/python', require('file-loader?esModule=false!./src-noconflict/mode-python.js'))
+ace.config.setModuleUrl('ace/mode/r', require('file-loader?esModule=false!./src-noconflict/mode-r.js'))
+ace.config.setModuleUrl('ace/mode/razor', require('file-loader?esModule=false!./src-noconflict/mode-razor.js'))
+ace.config.setModuleUrl('ace/mode/rdoc', require('file-loader?esModule=false!./src-noconflict/mode-rdoc.js'))
+ace.config.setModuleUrl('ace/mode/red', require('file-loader?esModule=false!./src-noconflict/mode-red.js'))
+ace.config.setModuleUrl('ace/mode/redshift', require('file-loader?esModule=false!./src-noconflict/mode-redshift.js'))
+ace.config.setModuleUrl('ace/mode/rhtml', require('file-loader?esModule=false!./src-noconflict/mode-rhtml.js'))
+ace.config.setModuleUrl('ace/mode/rst', require('file-loader?esModule=false!./src-noconflict/mode-rst.js'))
+ace.config.setModuleUrl('ace/mode/ruby', require('file-loader?esModule=false!./src-noconflict/mode-ruby.js'))
+ace.config.setModuleUrl('ace/mode/rust', require('file-loader?esModule=false!./src-noconflict/mode-rust.js'))
+ace.config.setModuleUrl('ace/mode/sass', require('file-loader?esModule=false!./src-noconflict/mode-sass.js'))
+ace.config.setModuleUrl('ace/mode/scad', require('file-loader?esModule=false!./src-noconflict/mode-scad.js'))
+ace.config.setModuleUrl('ace/mode/scala', require('file-loader?esModule=false!./src-noconflict/mode-scala.js'))
+ace.config.setModuleUrl('ace/mode/scheme', require('file-loader?esModule=false!./src-noconflict/mode-scheme.js'))
+ace.config.setModuleUrl('ace/mode/scss', require('file-loader?esModule=false!./src-noconflict/mode-scss.js'))
+ace.config.setModuleUrl('ace/mode/sh', require('file-loader?esModule=false!./src-noconflict/mode-sh.js'))
+ace.config.setModuleUrl('ace/mode/sjs', require('file-loader?esModule=false!./src-noconflict/mode-sjs.js'))
+ace.config.setModuleUrl('ace/mode/slim', require('file-loader?esModule=false!./src-noconflict/mode-slim.js'))
+ace.config.setModuleUrl('ace/mode/smarty', require('file-loader?esModule=false!./src-noconflict/mode-smarty.js'))
+ace.config.setModuleUrl('ace/mode/snippets', require('file-loader?esModule=false!./src-noconflict/mode-snippets.js'))
+ace.config.setModuleUrl('ace/mode/soy_template', require('file-loader?esModule=false!./src-noconflict/mode-soy_template.js'))
+ace.config.setModuleUrl('ace/mode/space', require('file-loader?esModule=false!./src-noconflict/mode-space.js'))
+ace.config.setModuleUrl('ace/mode/sparql', require('file-loader?esModule=false!./src-noconflict/mode-sparql.js'))
+ace.config.setModuleUrl('ace/mode/sql', require('file-loader?esModule=false!./src-noconflict/mode-sql.js'))
+ace.config.setModuleUrl('ace/mode/sqlserver', require('file-loader?esModule=false!./src-noconflict/mode-sqlserver.js'))
+ace.config.setModuleUrl('ace/mode/stylus', require('file-loader?esModule=false!./src-noconflict/mode-stylus.js'))
+ace.config.setModuleUrl('ace/mode/svg', require('file-loader?esModule=false!./src-noconflict/mode-svg.js'))
+ace.config.setModuleUrl('ace/mode/swift', require('file-loader?esModule=false!./src-noconflict/mode-swift.js'))
+ace.config.setModuleUrl('ace/mode/tcl', require('file-loader?esModule=false!./src-noconflict/mode-tcl.js'))
+ace.config.setModuleUrl('ace/mode/terraform', require('file-loader?esModule=false!./src-noconflict/mode-terraform.js'))
+ace.config.setModuleUrl('ace/mode/tex', require('file-loader?esModule=false!./src-noconflict/mode-tex.js'))
+ace.config.setModuleUrl('ace/mode/text', require('file-loader?esModule=false!./src-noconflict/mode-text.js'))
+ace.config.setModuleUrl('ace/mode/textile', require('file-loader?esModule=false!./src-noconflict/mode-textile.js'))
+ace.config.setModuleUrl('ace/mode/toml', require('file-loader?esModule=false!./src-noconflict/mode-toml.js'))
+ace.config.setModuleUrl('ace/mode/tsx', require('file-loader?esModule=false!./src-noconflict/mode-tsx.js'))
+ace.config.setModuleUrl('ace/mode/turtle', require('file-loader?esModule=false!./src-noconflict/mode-turtle.js'))
+ace.config.setModuleUrl('ace/mode/twig', require('file-loader?esModule=false!./src-noconflict/mode-twig.js'))
+ace.config.setModuleUrl('ace/mode/typescript', require('file-loader?esModule=false!./src-noconflict/mode-typescript.js'))
+ace.config.setModuleUrl('ace/mode/vala', require('file-loader?esModule=false!./src-noconflict/mode-vala.js'))
+ace.config.setModuleUrl('ace/mode/vbscript', require('file-loader?esModule=false!./src-noconflict/mode-vbscript.js'))
+ace.config.setModuleUrl('ace/mode/velocity', require('file-loader?esModule=false!./src-noconflict/mode-velocity.js'))
+ace.config.setModuleUrl('ace/mode/verilog', require('file-loader?esModule=false!./src-noconflict/mode-verilog.js'))
+ace.config.setModuleUrl('ace/mode/vhdl', require('file-loader?esModule=false!./src-noconflict/mode-vhdl.js'))
+ace.config.setModuleUrl('ace/mode/visualforce', require('file-loader?esModule=false!./src-noconflict/mode-visualforce.js'))
+ace.config.setModuleUrl('ace/mode/wollok', require('file-loader?esModule=false!./src-noconflict/mode-wollok.js'))
+ace.config.setModuleUrl('ace/mode/xml', require('file-loader?esModule=false!./src-noconflict/mode-xml.js'))
+ace.config.setModuleUrl('ace/mode/xquery', require('file-loader?esModule=false!./src-noconflict/mode-xquery.js'))
+ace.config.setModuleUrl('ace/mode/yaml', require('file-loader?esModule=false!./src-noconflict/mode-yaml.js'))
+ace.config.setModuleUrl('ace/mode/zeek', require('file-loader?esModule=false!./src-noconflict/mode-zeek.js'))
-ace.config.setModuleUrl('ace/theme/ambiance', require('file-loader!./src-noconflict/theme-ambiance.js'))
-ace.config.setModuleUrl('ace/theme/chaos', require('file-loader!./src-noconflict/theme-chaos.js'))
-ace.config.setModuleUrl('ace/theme/chrome', require('file-loader!./src-noconflict/theme-chrome.js'))
-ace.config.setModuleUrl('ace/theme/clouds', require('file-loader!./src-noconflict/theme-clouds.js'))
-ace.config.setModuleUrl('ace/theme/clouds_midnight', require('file-loader!./src-noconflict/theme-clouds_midnight.js'))
-ace.config.setModuleUrl('ace/theme/cobalt', require('file-loader!./src-noconflict/theme-cobalt.js'))
-ace.config.setModuleUrl('ace/theme/crimson_editor', require('file-loader!./src-noconflict/theme-crimson_editor.js'))
-ace.config.setModuleUrl('ace/theme/dawn', require('file-loader!./src-noconflict/theme-dawn.js'))
-ace.config.setModuleUrl('ace/theme/dracula', require('file-loader!./src-noconflict/theme-dracula.js'))
-ace.config.setModuleUrl('ace/theme/dreamweaver', require('file-loader!./src-noconflict/theme-dreamweaver.js'))
-ace.config.setModuleUrl('ace/theme/eclipse', require('file-loader!./src-noconflict/theme-eclipse.js'))
-ace.config.setModuleUrl('ace/theme/github', require('file-loader!./src-noconflict/theme-github.js'))
-ace.config.setModuleUrl('ace/theme/gob', require('file-loader!./src-noconflict/theme-gob.js'))
-ace.config.setModuleUrl('ace/theme/gruvbox', require('file-loader!./src-noconflict/theme-gruvbox.js'))
-ace.config.setModuleUrl('ace/theme/idle_fingers', require('file-loader!./src-noconflict/theme-idle_fingers.js'))
-ace.config.setModuleUrl('ace/theme/iplastic', require('file-loader!./src-noconflict/theme-iplastic.js'))
-ace.config.setModuleUrl('ace/theme/katzenmilch', require('file-loader!./src-noconflict/theme-katzenmilch.js'))
-ace.config.setModuleUrl('ace/theme/kr_theme', require('file-loader!./src-noconflict/theme-kr_theme.js'))
-ace.config.setModuleUrl('ace/theme/kuroir', require('file-loader!./src-noconflict/theme-kuroir.js'))
-ace.config.setModuleUrl('ace/theme/merbivore', require('file-loader!./src-noconflict/theme-merbivore.js'))
-ace.config.setModuleUrl('ace/theme/merbivore_soft', require('file-loader!./src-noconflict/theme-merbivore_soft.js'))
-ace.config.setModuleUrl('ace/theme/monokai', require('file-loader!./src-noconflict/theme-monokai.js'))
-ace.config.setModuleUrl('ace/theme/mono_industrial', require('file-loader!./src-noconflict/theme-mono_industrial.js'))
-ace.config.setModuleUrl('ace/theme/pastel_on_dark', require('file-loader!./src-noconflict/theme-pastel_on_dark.js'))
-ace.config.setModuleUrl('ace/theme/solarized_dark', require('file-loader!./src-noconflict/theme-solarized_dark.js'))
-ace.config.setModuleUrl('ace/theme/solarized_light', require('file-loader!./src-noconflict/theme-solarized_light.js'))
-ace.config.setModuleUrl('ace/theme/sqlserver', require('file-loader!./src-noconflict/theme-sqlserver.js'))
-ace.config.setModuleUrl('ace/theme/terminal', require('file-loader!./src-noconflict/theme-terminal.js'))
-ace.config.setModuleUrl('ace/theme/textmate', require('file-loader!./src-noconflict/theme-textmate.js'))
-ace.config.setModuleUrl('ace/theme/tomorrow', require('file-loader!./src-noconflict/theme-tomorrow.js'))
-ace.config.setModuleUrl('ace/theme/tomorrow_night', require('file-loader!./src-noconflict/theme-tomorrow_night.js'))
-ace.config.setModuleUrl('ace/theme/tomorrow_night_blue', require('file-loader!./src-noconflict/theme-tomorrow_night_blue.js'))
-ace.config.setModuleUrl('ace/theme/tomorrow_night_bright', require('file-loader!./src-noconflict/theme-tomorrow_night_bright.js'))
-ace.config.setModuleUrl('ace/theme/tomorrow_night_eighties', require('file-loader!./src-noconflict/theme-tomorrow_night_eighties.js'))
-ace.config.setModuleUrl('ace/theme/twilight', require('file-loader!./src-noconflict/theme-twilight.js'))
-ace.config.setModuleUrl('ace/theme/vibrant_ink', require('file-loader!./src-noconflict/theme-vibrant_ink.js'))
-ace.config.setModuleUrl('ace/theme/xcode', require('file-loader!./src-noconflict/theme-xcode.js'))
-ace.config.setModuleUrl('ace/mode/coffee_worker', require('file-loader!./src-noconflict/worker-coffee.js'))
-ace.config.setModuleUrl('ace/mode/css_worker', require('file-loader!./src-noconflict/worker-css.js'))
-ace.config.setModuleUrl('ace/mode/html_worker', require('file-loader!./src-noconflict/worker-html.js'))
-ace.config.setModuleUrl('ace/mode/javascript_worker', require('file-loader!./src-noconflict/worker-javascript.js'))
-ace.config.setModuleUrl('ace/mode/json_worker', require('file-loader!./src-noconflict/worker-json.js'))
-ace.config.setModuleUrl('ace/mode/lua_worker', require('file-loader!./src-noconflict/worker-lua.js'))
-ace.config.setModuleUrl('ace/mode/php_worker', require('file-loader!./src-noconflict/worker-php.js'))
-ace.config.setModuleUrl('ace/mode/xml_worker', require('file-loader!./src-noconflict/worker-xml.js'))
-ace.config.setModuleUrl('ace/mode/xquery_worker', require('file-loader!./src-noconflict/worker-xquery.js'))
-ace.config.setModuleUrl('ace/snippets/abap', require('file-loader!./src-noconflict/snippets/abap.js'))
-ace.config.setModuleUrl('ace/snippets/abc', require('file-loader!./src-noconflict/snippets/abc.js'))
-ace.config.setModuleUrl('ace/snippets/actionscript', require('file-loader!./src-noconflict/snippets/actionscript.js'))
-ace.config.setModuleUrl('ace/snippets/ada', require('file-loader!./src-noconflict/snippets/ada.js'))
-ace.config.setModuleUrl('ace/snippets/apache_conf', require('file-loader!./src-noconflict/snippets/apache_conf.js'))
-ace.config.setModuleUrl('ace/snippets/apex', require('file-loader!./src-noconflict/snippets/apex.js'))
-ace.config.setModuleUrl('ace/snippets/applescript', require('file-loader!./src-noconflict/snippets/applescript.js'))
-ace.config.setModuleUrl('ace/snippets/aql', require('file-loader!./src-noconflict/snippets/aql.js'))
-ace.config.setModuleUrl('ace/snippets/asciidoc', require('file-loader!./src-noconflict/snippets/asciidoc.js'))
-ace.config.setModuleUrl('ace/snippets/asl', require('file-loader!./src-noconflict/snippets/asl.js'))
-ace.config.setModuleUrl('ace/snippets/assembly_x86', require('file-loader!./src-noconflict/snippets/assembly_x86.js'))
-ace.config.setModuleUrl('ace/snippets/autohotkey', require('file-loader!./src-noconflict/snippets/autohotkey.js'))
-ace.config.setModuleUrl('ace/snippets/batchfile', require('file-loader!./src-noconflict/snippets/batchfile.js'))
-ace.config.setModuleUrl('ace/snippets/bro', require('file-loader!./src-noconflict/snippets/bro.js'))
-ace.config.setModuleUrl('ace/snippets/c9search', require('file-loader!./src-noconflict/snippets/c9search.js'))
-ace.config.setModuleUrl('ace/snippets/cirru', require('file-loader!./src-noconflict/snippets/cirru.js'))
-ace.config.setModuleUrl('ace/snippets/clojure', require('file-loader!./src-noconflict/snippets/clojure.js'))
-ace.config.setModuleUrl('ace/snippets/cobol', require('file-loader!./src-noconflict/snippets/cobol.js'))
-ace.config.setModuleUrl('ace/snippets/coffee', require('file-loader!./src-noconflict/snippets/coffee.js'))
-ace.config.setModuleUrl('ace/snippets/coldfusion', require('file-loader!./src-noconflict/snippets/coldfusion.js'))
-ace.config.setModuleUrl('ace/snippets/crystal', require('file-loader!./src-noconflict/snippets/crystal.js'))
-ace.config.setModuleUrl('ace/snippets/csharp', require('file-loader!./src-noconflict/snippets/csharp.js'))
-ace.config.setModuleUrl('ace/snippets/csound_document', require('file-loader!./src-noconflict/snippets/csound_document.js'))
-ace.config.setModuleUrl('ace/snippets/csound_orchestra', require('file-loader!./src-noconflict/snippets/csound_orchestra.js'))
-ace.config.setModuleUrl('ace/snippets/csound_score', require('file-loader!./src-noconflict/snippets/csound_score.js'))
-ace.config.setModuleUrl('ace/snippets/csp', require('file-loader!./src-noconflict/snippets/csp.js'))
-ace.config.setModuleUrl('ace/snippets/css', require('file-loader!./src-noconflict/snippets/css.js'))
-ace.config.setModuleUrl('ace/snippets/curly', require('file-loader!./src-noconflict/snippets/curly.js'))
-ace.config.setModuleUrl('ace/snippets/c_cpp', require('file-loader!./src-noconflict/snippets/c_cpp.js'))
-ace.config.setModuleUrl('ace/snippets/d', require('file-loader!./src-noconflict/snippets/d.js'))
-ace.config.setModuleUrl('ace/snippets/dart', require('file-loader!./src-noconflict/snippets/dart.js'))
-ace.config.setModuleUrl('ace/snippets/diff', require('file-loader!./src-noconflict/snippets/diff.js'))
-ace.config.setModuleUrl('ace/snippets/django', require('file-loader!./src-noconflict/snippets/django.js'))
-ace.config.setModuleUrl('ace/snippets/dockerfile', require('file-loader!./src-noconflict/snippets/dockerfile.js'))
-ace.config.setModuleUrl('ace/snippets/dot', require('file-loader!./src-noconflict/snippets/dot.js'))
-ace.config.setModuleUrl('ace/snippets/drools', require('file-loader!./src-noconflict/snippets/drools.js'))
-ace.config.setModuleUrl('ace/snippets/edifact', require('file-loader!./src-noconflict/snippets/edifact.js'))
-ace.config.setModuleUrl('ace/snippets/eiffel', require('file-loader!./src-noconflict/snippets/eiffel.js'))
-ace.config.setModuleUrl('ace/snippets/ejs', require('file-loader!./src-noconflict/snippets/ejs.js'))
-ace.config.setModuleUrl('ace/snippets/elixir', require('file-loader!./src-noconflict/snippets/elixir.js'))
-ace.config.setModuleUrl('ace/snippets/elm', require('file-loader!./src-noconflict/snippets/elm.js'))
-ace.config.setModuleUrl('ace/snippets/erlang', require('file-loader!./src-noconflict/snippets/erlang.js'))
-ace.config.setModuleUrl('ace/snippets/forth', require('file-loader!./src-noconflict/snippets/forth.js'))
-ace.config.setModuleUrl('ace/snippets/fortran', require('file-loader!./src-noconflict/snippets/fortran.js'))
-ace.config.setModuleUrl('ace/snippets/fsharp', require('file-loader!./src-noconflict/snippets/fsharp.js'))
-ace.config.setModuleUrl('ace/snippets/fsl', require('file-loader!./src-noconflict/snippets/fsl.js'))
-ace.config.setModuleUrl('ace/snippets/ftl', require('file-loader!./src-noconflict/snippets/ftl.js'))
-ace.config.setModuleUrl('ace/snippets/gcode', require('file-loader!./src-noconflict/snippets/gcode.js'))
-ace.config.setModuleUrl('ace/snippets/gherkin', require('file-loader!./src-noconflict/snippets/gherkin.js'))
-ace.config.setModuleUrl('ace/snippets/gitignore', require('file-loader!./src-noconflict/snippets/gitignore.js'))
-ace.config.setModuleUrl('ace/snippets/glsl', require('file-loader!./src-noconflict/snippets/glsl.js'))
-ace.config.setModuleUrl('ace/snippets/gobstones', require('file-loader!./src-noconflict/snippets/gobstones.js'))
-ace.config.setModuleUrl('ace/snippets/golang', require('file-loader!./src-noconflict/snippets/golang.js'))
-ace.config.setModuleUrl('ace/snippets/graphqlschema', require('file-loader!./src-noconflict/snippets/graphqlschema.js'))
-ace.config.setModuleUrl('ace/snippets/groovy', require('file-loader!./src-noconflict/snippets/groovy.js'))
-ace.config.setModuleUrl('ace/snippets/haml', require('file-loader!./src-noconflict/snippets/haml.js'))
-ace.config.setModuleUrl('ace/snippets/handlebars', require('file-loader!./src-noconflict/snippets/handlebars.js'))
-ace.config.setModuleUrl('ace/snippets/haskell', require('file-loader!./src-noconflict/snippets/haskell.js'))
-ace.config.setModuleUrl('ace/snippets/haskell_cabal', require('file-loader!./src-noconflict/snippets/haskell_cabal.js'))
-ace.config.setModuleUrl('ace/snippets/haxe', require('file-loader!./src-noconflict/snippets/haxe.js'))
-ace.config.setModuleUrl('ace/snippets/hjson', require('file-loader!./src-noconflict/snippets/hjson.js'))
-ace.config.setModuleUrl('ace/snippets/html', require('file-loader!./src-noconflict/snippets/html.js'))
-ace.config.setModuleUrl('ace/snippets/html_elixir', require('file-loader!./src-noconflict/snippets/html_elixir.js'))
-ace.config.setModuleUrl('ace/snippets/html_ruby', require('file-loader!./src-noconflict/snippets/html_ruby.js'))
-ace.config.setModuleUrl('ace/snippets/ini', require('file-loader!./src-noconflict/snippets/ini.js'))
-ace.config.setModuleUrl('ace/snippets/io', require('file-loader!./src-noconflict/snippets/io.js'))
-ace.config.setModuleUrl('ace/snippets/jack', require('file-loader!./src-noconflict/snippets/jack.js'))
-ace.config.setModuleUrl('ace/snippets/jade', require('file-loader!./src-noconflict/snippets/jade.js'))
-ace.config.setModuleUrl('ace/snippets/java', require('file-loader!./src-noconflict/snippets/java.js'))
-ace.config.setModuleUrl('ace/snippets/javascript', require('file-loader!./src-noconflict/snippets/javascript.js'))
-ace.config.setModuleUrl('ace/snippets/json', require('file-loader!./src-noconflict/snippets/json.js'))
-ace.config.setModuleUrl('ace/snippets/jsoniq', require('file-loader!./src-noconflict/snippets/jsoniq.js'))
-ace.config.setModuleUrl('ace/snippets/jsp', require('file-loader!./src-noconflict/snippets/jsp.js'))
-ace.config.setModuleUrl('ace/snippets/jssm', require('file-loader!./src-noconflict/snippets/jssm.js'))
-ace.config.setModuleUrl('ace/snippets/jsx', require('file-loader!./src-noconflict/snippets/jsx.js'))
-ace.config.setModuleUrl('ace/snippets/julia', require('file-loader!./src-noconflict/snippets/julia.js'))
-ace.config.setModuleUrl('ace/snippets/kotlin', require('file-loader!./src-noconflict/snippets/kotlin.js'))
-ace.config.setModuleUrl('ace/snippets/latex', require('file-loader!./src-noconflict/snippets/latex.js'))
-ace.config.setModuleUrl('ace/snippets/less', require('file-loader!./src-noconflict/snippets/less.js'))
-ace.config.setModuleUrl('ace/snippets/liquid', require('file-loader!./src-noconflict/snippets/liquid.js'))
-ace.config.setModuleUrl('ace/snippets/lisp', require('file-loader!./src-noconflict/snippets/lisp.js'))
-ace.config.setModuleUrl('ace/snippets/livescript', require('file-loader!./src-noconflict/snippets/livescript.js'))
-ace.config.setModuleUrl('ace/snippets/logiql', require('file-loader!./src-noconflict/snippets/logiql.js'))
-ace.config.setModuleUrl('ace/snippets/logtalk', require('file-loader!./src-noconflict/snippets/logtalk.js'))
-ace.config.setModuleUrl('ace/snippets/lsl', require('file-loader!./src-noconflict/snippets/lsl.js'))
-ace.config.setModuleUrl('ace/snippets/lua', require('file-loader!./src-noconflict/snippets/lua.js'))
-ace.config.setModuleUrl('ace/snippets/luapage', require('file-loader!./src-noconflict/snippets/luapage.js'))
-ace.config.setModuleUrl('ace/snippets/lucene', require('file-loader!./src-noconflict/snippets/lucene.js'))
-ace.config.setModuleUrl('ace/snippets/makefile', require('file-loader!./src-noconflict/snippets/makefile.js'))
-ace.config.setModuleUrl('ace/snippets/markdown', require('file-loader!./src-noconflict/snippets/markdown.js'))
-ace.config.setModuleUrl('ace/snippets/mask', require('file-loader!./src-noconflict/snippets/mask.js'))
-ace.config.setModuleUrl('ace/snippets/matlab', require('file-loader!./src-noconflict/snippets/matlab.js'))
-ace.config.setModuleUrl('ace/snippets/maze', require('file-loader!./src-noconflict/snippets/maze.js'))
-ace.config.setModuleUrl('ace/snippets/mel', require('file-loader!./src-noconflict/snippets/mel.js'))
-ace.config.setModuleUrl('ace/snippets/mixal', require('file-loader!./src-noconflict/snippets/mixal.js'))
-ace.config.setModuleUrl('ace/snippets/mushcode', require('file-loader!./src-noconflict/snippets/mushcode.js'))
-ace.config.setModuleUrl('ace/snippets/mysql', require('file-loader!./src-noconflict/snippets/mysql.js'))
-ace.config.setModuleUrl('ace/snippets/nginx', require('file-loader!./src-noconflict/snippets/nginx.js'))
-ace.config.setModuleUrl('ace/snippets/nim', require('file-loader!./src-noconflict/snippets/nim.js'))
-ace.config.setModuleUrl('ace/snippets/nix', require('file-loader!./src-noconflict/snippets/nix.js'))
-ace.config.setModuleUrl('ace/snippets/nsis', require('file-loader!./src-noconflict/snippets/nsis.js'))
-ace.config.setModuleUrl('ace/snippets/objectivec', require('file-loader!./src-noconflict/snippets/objectivec.js'))
-ace.config.setModuleUrl('ace/snippets/ocaml', require('file-loader!./src-noconflict/snippets/ocaml.js'))
-ace.config.setModuleUrl('ace/snippets/pascal', require('file-loader!./src-noconflict/snippets/pascal.js'))
-ace.config.setModuleUrl('ace/snippets/perl', require('file-loader!./src-noconflict/snippets/perl.js'))
-ace.config.setModuleUrl('ace/snippets/perl6', require('file-loader!./src-noconflict/snippets/perl6.js'))
-ace.config.setModuleUrl('ace/snippets/pgsql', require('file-loader!./src-noconflict/snippets/pgsql.js'))
-ace.config.setModuleUrl('ace/snippets/php', require('file-loader!./src-noconflict/snippets/php.js'))
-ace.config.setModuleUrl('ace/snippets/php_laravel_blade', require('file-loader!./src-noconflict/snippets/php_laravel_blade.js'))
-ace.config.setModuleUrl('ace/snippets/pig', require('file-loader!./src-noconflict/snippets/pig.js'))
-ace.config.setModuleUrl('ace/snippets/plain_text', require('file-loader!./src-noconflict/snippets/plain_text.js'))
-ace.config.setModuleUrl('ace/snippets/powershell', require('file-loader!./src-noconflict/snippets/powershell.js'))
-ace.config.setModuleUrl('ace/snippets/praat', require('file-loader!./src-noconflict/snippets/praat.js'))
-ace.config.setModuleUrl('ace/snippets/prolog', require('file-loader!./src-noconflict/snippets/prolog.js'))
-ace.config.setModuleUrl('ace/snippets/properties', require('file-loader!./src-noconflict/snippets/properties.js'))
-ace.config.setModuleUrl('ace/snippets/protobuf', require('file-loader!./src-noconflict/snippets/protobuf.js'))
-ace.config.setModuleUrl('ace/snippets/puppet', require('file-loader!./src-noconflict/snippets/puppet.js'))
-ace.config.setModuleUrl('ace/snippets/python', require('file-loader!./src-noconflict/snippets/python.js'))
-ace.config.setModuleUrl('ace/snippets/r', require('file-loader!./src-noconflict/snippets/r.js'))
-ace.config.setModuleUrl('ace/snippets/razor', require('file-loader!./src-noconflict/snippets/razor.js'))
-ace.config.setModuleUrl('ace/snippets/rdoc', require('file-loader!./src-noconflict/snippets/rdoc.js'))
-ace.config.setModuleUrl('ace/snippets/red', require('file-loader!./src-noconflict/snippets/red.js'))
-ace.config.setModuleUrl('ace/snippets/redshift', require('file-loader!./src-noconflict/snippets/redshift.js'))
-ace.config.setModuleUrl('ace/snippets/rhtml', require('file-loader!./src-noconflict/snippets/rhtml.js'))
-ace.config.setModuleUrl('ace/snippets/rst', require('file-loader!./src-noconflict/snippets/rst.js'))
-ace.config.setModuleUrl('ace/snippets/ruby', require('file-loader!./src-noconflict/snippets/ruby.js'))
-ace.config.setModuleUrl('ace/snippets/rust', require('file-loader!./src-noconflict/snippets/rust.js'))
-ace.config.setModuleUrl('ace/snippets/sass', require('file-loader!./src-noconflict/snippets/sass.js'))
-ace.config.setModuleUrl('ace/snippets/scad', require('file-loader!./src-noconflict/snippets/scad.js'))
-ace.config.setModuleUrl('ace/snippets/scala', require('file-loader!./src-noconflict/snippets/scala.js'))
-ace.config.setModuleUrl('ace/snippets/scheme', require('file-loader!./src-noconflict/snippets/scheme.js'))
-ace.config.setModuleUrl('ace/snippets/scss', require('file-loader!./src-noconflict/snippets/scss.js'))
-ace.config.setModuleUrl('ace/snippets/sh', require('file-loader!./src-noconflict/snippets/sh.js'))
-ace.config.setModuleUrl('ace/snippets/sjs', require('file-loader!./src-noconflict/snippets/sjs.js'))
-ace.config.setModuleUrl('ace/snippets/slim', require('file-loader!./src-noconflict/snippets/slim.js'))
-ace.config.setModuleUrl('ace/snippets/smarty', require('file-loader!./src-noconflict/snippets/smarty.js'))
-ace.config.setModuleUrl('ace/snippets/snippets', require('file-loader!./src-noconflict/snippets/snippets.js'))
-ace.config.setModuleUrl('ace/snippets/soy_template', require('file-loader!./src-noconflict/snippets/soy_template.js'))
-ace.config.setModuleUrl('ace/snippets/space', require('file-loader!./src-noconflict/snippets/space.js'))
-ace.config.setModuleUrl('ace/snippets/sparql', require('file-loader!./src-noconflict/snippets/sparql.js'))
-ace.config.setModuleUrl('ace/snippets/sql', require('file-loader!./src-noconflict/snippets/sql.js'))
-ace.config.setModuleUrl('ace/snippets/sqlserver', require('file-loader!./src-noconflict/snippets/sqlserver.js'))
-ace.config.setModuleUrl('ace/snippets/stylus', require('file-loader!./src-noconflict/snippets/stylus.js'))
-ace.config.setModuleUrl('ace/snippets/svg', require('file-loader!./src-noconflict/snippets/svg.js'))
-ace.config.setModuleUrl('ace/snippets/swift', require('file-loader!./src-noconflict/snippets/swift.js'))
-ace.config.setModuleUrl('ace/snippets/tcl', require('file-loader!./src-noconflict/snippets/tcl.js'))
-ace.config.setModuleUrl('ace/snippets/terraform', require('file-loader!./src-noconflict/snippets/terraform.js'))
-ace.config.setModuleUrl('ace/snippets/tex', require('file-loader!./src-noconflict/snippets/tex.js'))
-ace.config.setModuleUrl('ace/snippets/text', require('file-loader!./src-noconflict/snippets/text.js'))
-ace.config.setModuleUrl('ace/snippets/textile', require('file-loader!./src-noconflict/snippets/textile.js'))
-ace.config.setModuleUrl('ace/snippets/toml', require('file-loader!./src-noconflict/snippets/toml.js'))
-ace.config.setModuleUrl('ace/snippets/tsx', require('file-loader!./src-noconflict/snippets/tsx.js'))
-ace.config.setModuleUrl('ace/snippets/turtle', require('file-loader!./src-noconflict/snippets/turtle.js'))
-ace.config.setModuleUrl('ace/snippets/twig', require('file-loader!./src-noconflict/snippets/twig.js'))
-ace.config.setModuleUrl('ace/snippets/typescript', require('file-loader!./src-noconflict/snippets/typescript.js'))
-ace.config.setModuleUrl('ace/snippets/vala', require('file-loader!./src-noconflict/snippets/vala.js'))
-ace.config.setModuleUrl('ace/snippets/vbscript', require('file-loader!./src-noconflict/snippets/vbscript.js'))
-ace.config.setModuleUrl('ace/snippets/velocity', require('file-loader!./src-noconflict/snippets/velocity.js'))
-ace.config.setModuleUrl('ace/snippets/verilog', require('file-loader!./src-noconflict/snippets/verilog.js'))
-ace.config.setModuleUrl('ace/snippets/vhdl', require('file-loader!./src-noconflict/snippets/vhdl.js'))
-ace.config.setModuleUrl('ace/snippets/visualforce', require('file-loader!./src-noconflict/snippets/visualforce.js'))
-ace.config.setModuleUrl('ace/snippets/wollok', require('file-loader!./src-noconflict/snippets/wollok.js'))
-ace.config.setModuleUrl('ace/snippets/xml', require('file-loader!./src-noconflict/snippets/xml.js'))
-ace.config.setModuleUrl('ace/snippets/xquery', require('file-loader!./src-noconflict/snippets/xquery.js'))
-ace.config.setModuleUrl('ace/snippets/yaml', require('file-loader!./src-noconflict/snippets/yaml.js'))
-ace.config.setModuleUrl('ace/snippets/zeek', require('file-loader!./src-noconflict/snippets/zeek.js'))
\ No newline at end of file
+ace.config.setModuleUrl('ace/theme/ambiance', require('file-loader?esModule=false!./src-noconflict/theme-ambiance.js'))
+ace.config.setModuleUrl('ace/theme/chaos', require('file-loader?esModule=false!./src-noconflict/theme-chaos.js'))
+ace.config.setModuleUrl('ace/theme/chrome', require('file-loader?esModule=false!./src-noconflict/theme-chrome.js'))
+ace.config.setModuleUrl('ace/theme/clouds', require('file-loader?esModule=false!./src-noconflict/theme-clouds.js'))
+ace.config.setModuleUrl('ace/theme/clouds_midnight', require('file-loader?esModule=false!./src-noconflict/theme-clouds_midnight.js'))
+ace.config.setModuleUrl('ace/theme/cobalt', require('file-loader?esModule=false!./src-noconflict/theme-cobalt.js'))
+ace.config.setModuleUrl('ace/theme/crimson_editor', require('file-loader?esModule=false!./src-noconflict/theme-crimson_editor.js'))
+ace.config.setModuleUrl('ace/theme/dawn', require('file-loader?esModule=false!./src-noconflict/theme-dawn.js'))
+ace.config.setModuleUrl('ace/theme/dracula', require('file-loader?esModule=false!./src-noconflict/theme-dracula.js'))
+ace.config.setModuleUrl('ace/theme/dreamweaver', require('file-loader?esModule=false!./src-noconflict/theme-dreamweaver.js'))
+ace.config.setModuleUrl('ace/theme/eclipse', require('file-loader?esModule=false!./src-noconflict/theme-eclipse.js'))
+ace.config.setModuleUrl('ace/theme/github', require('file-loader?esModule=false!./src-noconflict/theme-github.js'))
+ace.config.setModuleUrl('ace/theme/gob', require('file-loader?esModule=false!./src-noconflict/theme-gob.js'))
+ace.config.setModuleUrl('ace/theme/gruvbox', require('file-loader?esModule=false!./src-noconflict/theme-gruvbox.js'))
+ace.config.setModuleUrl('ace/theme/idle_fingers', require('file-loader?esModule=false!./src-noconflict/theme-idle_fingers.js'))
+ace.config.setModuleUrl('ace/theme/iplastic', require('file-loader?esModule=false!./src-noconflict/theme-iplastic.js'))
+ace.config.setModuleUrl('ace/theme/katzenmilch', require('file-loader?esModule=false!./src-noconflict/theme-katzenmilch.js'))
+ace.config.setModuleUrl('ace/theme/kr_theme', require('file-loader?esModule=false!./src-noconflict/theme-kr_theme.js'))
+ace.config.setModuleUrl('ace/theme/kuroir', require('file-loader?esModule=false!./src-noconflict/theme-kuroir.js'))
+ace.config.setModuleUrl('ace/theme/merbivore', require('file-loader?esModule=false!./src-noconflict/theme-merbivore.js'))
+ace.config.setModuleUrl('ace/theme/merbivore_soft', require('file-loader?esModule=false!./src-noconflict/theme-merbivore_soft.js'))
+ace.config.setModuleUrl('ace/theme/monokai', require('file-loader?esModule=false!./src-noconflict/theme-monokai.js'))
+ace.config.setModuleUrl('ace/theme/mono_industrial', require('file-loader?esModule=false!./src-noconflict/theme-mono_industrial.js'))
+ace.config.setModuleUrl('ace/theme/pastel_on_dark', require('file-loader?esModule=false!./src-noconflict/theme-pastel_on_dark.js'))
+ace.config.setModuleUrl('ace/theme/solarized_dark', require('file-loader?esModule=false!./src-noconflict/theme-solarized_dark.js'))
+ace.config.setModuleUrl('ace/theme/solarized_light', require('file-loader?esModule=false!./src-noconflict/theme-solarized_light.js'))
+ace.config.setModuleUrl('ace/theme/sqlserver', require('file-loader?esModule=false!./src-noconflict/theme-sqlserver.js'))
+ace.config.setModuleUrl('ace/theme/terminal', require('file-loader?esModule=false!./src-noconflict/theme-terminal.js'))
+ace.config.setModuleUrl('ace/theme/textmate', require('file-loader?esModule=false!./src-noconflict/theme-textmate.js'))
+ace.config.setModuleUrl('ace/theme/tomorrow', require('file-loader?esModule=false!./src-noconflict/theme-tomorrow.js'))
+ace.config.setModuleUrl('ace/theme/tomorrow_night', require('file-loader?esModule=false!./src-noconflict/theme-tomorrow_night.js'))
+ace.config.setModuleUrl('ace/theme/tomorrow_night_blue', require('file-loader?esModule=false!./src-noconflict/theme-tomorrow_night_blue.js'))
+ace.config.setModuleUrl('ace/theme/tomorrow_night_bright', require('file-loader?esModule=false!./src-noconflict/theme-tomorrow_night_bright.js'))
+ace.config.setModuleUrl('ace/theme/tomorrow_night_eighties', require('file-loader?esModule=false!./src-noconflict/theme-tomorrow_night_eighties.js'))
+ace.config.setModuleUrl('ace/theme/twilight', require('file-loader?esModule=false!./src-noconflict/theme-twilight.js'))
+ace.config.setModuleUrl('ace/theme/vibrant_ink', require('file-loader?esModule=false!./src-noconflict/theme-vibrant_ink.js'))
+ace.config.setModuleUrl('ace/theme/xcode', require('file-loader?esModule=false!./src-noconflict/theme-xcode.js'))
+ace.config.setModuleUrl('ace/mode/coffee_worker', require('file-loader?esModule=false!./src-noconflict/worker-coffee.js'))
+ace.config.setModuleUrl('ace/mode/css_worker', require('file-loader?esModule=false!./src-noconflict/worker-css.js'))
+ace.config.setModuleUrl('ace/mode/html_worker', require('file-loader?esModule=false!./src-noconflict/worker-html.js'))
+ace.config.setModuleUrl('ace/mode/javascript_worker', require('file-loader?esModule=false!./src-noconflict/worker-javascript.js'))
+ace.config.setModuleUrl('ace/mode/json_worker', require('file-loader?esModule=false!./src-noconflict/worker-json.js'))
+ace.config.setModuleUrl('ace/mode/lua_worker', require('file-loader?esModule=false!./src-noconflict/worker-lua.js'))
+ace.config.setModuleUrl('ace/mode/php_worker', require('file-loader?esModule=false!./src-noconflict/worker-php.js'))
+ace.config.setModuleUrl('ace/mode/xml_worker', require('file-loader?esModule=false!./src-noconflict/worker-xml.js'))
+ace.config.setModuleUrl('ace/mode/xquery_worker', require('file-loader?esModule=false!./src-noconflict/worker-xquery.js'))
+ace.config.setModuleUrl('ace/snippets/abap', require('file-loader?esModule=false!./src-noconflict/snippets/abap.js'))
+ace.config.setModuleUrl('ace/snippets/abc', require('file-loader?esModule=false!./src-noconflict/snippets/abc.js'))
+ace.config.setModuleUrl('ace/snippets/actionscript', require('file-loader?esModule=false!./src-noconflict/snippets/actionscript.js'))
+ace.config.setModuleUrl('ace/snippets/ada', require('file-loader?esModule=false!./src-noconflict/snippets/ada.js'))
+ace.config.setModuleUrl('ace/snippets/apache_conf', require('file-loader?esModule=false!./src-noconflict/snippets/apache_conf.js'))
+ace.config.setModuleUrl('ace/snippets/apex', require('file-loader?esModule=false!./src-noconflict/snippets/apex.js'))
+ace.config.setModuleUrl('ace/snippets/applescript', require('file-loader?esModule=false!./src-noconflict/snippets/applescript.js'))
+ace.config.setModuleUrl('ace/snippets/aql', require('file-loader?esModule=false!./src-noconflict/snippets/aql.js'))
+ace.config.setModuleUrl('ace/snippets/asciidoc', require('file-loader?esModule=false!./src-noconflict/snippets/asciidoc.js'))
+ace.config.setModuleUrl('ace/snippets/asl', require('file-loader?esModule=false!./src-noconflict/snippets/asl.js'))
+ace.config.setModuleUrl('ace/snippets/assembly_x86', require('file-loader?esModule=false!./src-noconflict/snippets/assembly_x86.js'))
+ace.config.setModuleUrl('ace/snippets/autohotkey', require('file-loader?esModule=false!./src-noconflict/snippets/autohotkey.js'))
+ace.config.setModuleUrl('ace/snippets/batchfile', require('file-loader?esModule=false!./src-noconflict/snippets/batchfile.js'))
+ace.config.setModuleUrl('ace/snippets/bro', require('file-loader?esModule=false!./src-noconflict/snippets/bro.js'))
+ace.config.setModuleUrl('ace/snippets/c9search', require('file-loader?esModule=false!./src-noconflict/snippets/c9search.js'))
+ace.config.setModuleUrl('ace/snippets/cirru', require('file-loader?esModule=false!./src-noconflict/snippets/cirru.js'))
+ace.config.setModuleUrl('ace/snippets/clojure', require('file-loader?esModule=false!./src-noconflict/snippets/clojure.js'))
+ace.config.setModuleUrl('ace/snippets/cobol', require('file-loader?esModule=false!./src-noconflict/snippets/cobol.js'))
+ace.config.setModuleUrl('ace/snippets/coffee', require('file-loader?esModule=false!./src-noconflict/snippets/coffee.js'))
+ace.config.setModuleUrl('ace/snippets/coldfusion', require('file-loader?esModule=false!./src-noconflict/snippets/coldfusion.js'))
+ace.config.setModuleUrl('ace/snippets/crystal', require('file-loader?esModule=false!./src-noconflict/snippets/crystal.js'))
+ace.config.setModuleUrl('ace/snippets/csharp', require('file-loader?esModule=false!./src-noconflict/snippets/csharp.js'))
+ace.config.setModuleUrl('ace/snippets/csound_document', require('file-loader?esModule=false!./src-noconflict/snippets/csound_document.js'))
+ace.config.setModuleUrl('ace/snippets/csound_orchestra', require('file-loader?esModule=false!./src-noconflict/snippets/csound_orchestra.js'))
+ace.config.setModuleUrl('ace/snippets/csound_score', require('file-loader?esModule=false!./src-noconflict/snippets/csound_score.js'))
+ace.config.setModuleUrl('ace/snippets/csp', require('file-loader?esModule=false!./src-noconflict/snippets/csp.js'))
+ace.config.setModuleUrl('ace/snippets/css', require('file-loader?esModule=false!./src-noconflict/snippets/css.js'))
+ace.config.setModuleUrl('ace/snippets/curly', require('file-loader?esModule=false!./src-noconflict/snippets/curly.js'))
+ace.config.setModuleUrl('ace/snippets/c_cpp', require('file-loader?esModule=false!./src-noconflict/snippets/c_cpp.js'))
+ace.config.setModuleUrl('ace/snippets/d', require('file-loader?esModule=false!./src-noconflict/snippets/d.js'))
+ace.config.setModuleUrl('ace/snippets/dart', require('file-loader?esModule=false!./src-noconflict/snippets/dart.js'))
+ace.config.setModuleUrl('ace/snippets/diff', require('file-loader?esModule=false!./src-noconflict/snippets/diff.js'))
+ace.config.setModuleUrl('ace/snippets/django', require('file-loader?esModule=false!./src-noconflict/snippets/django.js'))
+ace.config.setModuleUrl('ace/snippets/dockerfile', require('file-loader?esModule=false!./src-noconflict/snippets/dockerfile.js'))
+ace.config.setModuleUrl('ace/snippets/dot', require('file-loader?esModule=false!./src-noconflict/snippets/dot.js'))
+ace.config.setModuleUrl('ace/snippets/drools', require('file-loader?esModule=false!./src-noconflict/snippets/drools.js'))
+ace.config.setModuleUrl('ace/snippets/edifact', require('file-loader?esModule=false!./src-noconflict/snippets/edifact.js'))
+ace.config.setModuleUrl('ace/snippets/eiffel', require('file-loader?esModule=false!./src-noconflict/snippets/eiffel.js'))
+ace.config.setModuleUrl('ace/snippets/ejs', require('file-loader?esModule=false!./src-noconflict/snippets/ejs.js'))
+ace.config.setModuleUrl('ace/snippets/elixir', require('file-loader?esModule=false!./src-noconflict/snippets/elixir.js'))
+ace.config.setModuleUrl('ace/snippets/elm', require('file-loader?esModule=false!./src-noconflict/snippets/elm.js'))
+ace.config.setModuleUrl('ace/snippets/erlang', require('file-loader?esModule=false!./src-noconflict/snippets/erlang.js'))
+ace.config.setModuleUrl('ace/snippets/forth', require('file-loader?esModule=false!./src-noconflict/snippets/forth.js'))
+ace.config.setModuleUrl('ace/snippets/fortran', require('file-loader?esModule=false!./src-noconflict/snippets/fortran.js'))
+ace.config.setModuleUrl('ace/snippets/fsharp', require('file-loader?esModule=false!./src-noconflict/snippets/fsharp.js'))
+ace.config.setModuleUrl('ace/snippets/fsl', require('file-loader?esModule=false!./src-noconflict/snippets/fsl.js'))
+ace.config.setModuleUrl('ace/snippets/ftl', require('file-loader?esModule=false!./src-noconflict/snippets/ftl.js'))
+ace.config.setModuleUrl('ace/snippets/gcode', require('file-loader?esModule=false!./src-noconflict/snippets/gcode.js'))
+ace.config.setModuleUrl('ace/snippets/gherkin', require('file-loader?esModule=false!./src-noconflict/snippets/gherkin.js'))
+ace.config.setModuleUrl('ace/snippets/gitignore', require('file-loader?esModule=false!./src-noconflict/snippets/gitignore.js'))
+ace.config.setModuleUrl('ace/snippets/glsl', require('file-loader?esModule=false!./src-noconflict/snippets/glsl.js'))
+ace.config.setModuleUrl('ace/snippets/gobstones', require('file-loader?esModule=false!./src-noconflict/snippets/gobstones.js'))
+ace.config.setModuleUrl('ace/snippets/golang', require('file-loader?esModule=false!./src-noconflict/snippets/golang.js'))
+ace.config.setModuleUrl('ace/snippets/graphqlschema', require('file-loader?esModule=false!./src-noconflict/snippets/graphqlschema.js'))
+ace.config.setModuleUrl('ace/snippets/groovy', require('file-loader?esModule=false!./src-noconflict/snippets/groovy.js'))
+ace.config.setModuleUrl('ace/snippets/haml', require('file-loader?esModule=false!./src-noconflict/snippets/haml.js'))
+ace.config.setModuleUrl('ace/snippets/handlebars', require('file-loader?esModule=false!./src-noconflict/snippets/handlebars.js'))
+ace.config.setModuleUrl('ace/snippets/haskell', require('file-loader?esModule=false!./src-noconflict/snippets/haskell.js'))
+ace.config.setModuleUrl('ace/snippets/haskell_cabal', require('file-loader?esModule=false!./src-noconflict/snippets/haskell_cabal.js'))
+ace.config.setModuleUrl('ace/snippets/haxe', require('file-loader?esModule=false!./src-noconflict/snippets/haxe.js'))
+ace.config.setModuleUrl('ace/snippets/hjson', require('file-loader?esModule=false!./src-noconflict/snippets/hjson.js'))
+ace.config.setModuleUrl('ace/snippets/html', require('file-loader?esModule=false!./src-noconflict/snippets/html.js'))
+ace.config.setModuleUrl('ace/snippets/html_elixir', require('file-loader?esModule=false!./src-noconflict/snippets/html_elixir.js'))
+ace.config.setModuleUrl('ace/snippets/html_ruby', require('file-loader?esModule=false!./src-noconflict/snippets/html_ruby.js'))
+ace.config.setModuleUrl('ace/snippets/ini', require('file-loader?esModule=false!./src-noconflict/snippets/ini.js'))
+ace.config.setModuleUrl('ace/snippets/io', require('file-loader?esModule=false!./src-noconflict/snippets/io.js'))
+ace.config.setModuleUrl('ace/snippets/jack', require('file-loader?esModule=false!./src-noconflict/snippets/jack.js'))
+ace.config.setModuleUrl('ace/snippets/jade', require('file-loader?esModule=false!./src-noconflict/snippets/jade.js'))
+ace.config.setModuleUrl('ace/snippets/java', require('file-loader?esModule=false!./src-noconflict/snippets/java.js'))
+ace.config.setModuleUrl('ace/snippets/javascript', require('file-loader?esModule=false!./src-noconflict/snippets/javascript.js'))
+ace.config.setModuleUrl('ace/snippets/json', require('file-loader?esModule=false!./src-noconflict/snippets/json.js'))
+ace.config.setModuleUrl('ace/snippets/jsoniq', require('file-loader?esModule=false!./src-noconflict/snippets/jsoniq.js'))
+ace.config.setModuleUrl('ace/snippets/jsp', require('file-loader?esModule=false!./src-noconflict/snippets/jsp.js'))
+ace.config.setModuleUrl('ace/snippets/jssm', require('file-loader?esModule=false!./src-noconflict/snippets/jssm.js'))
+ace.config.setModuleUrl('ace/snippets/jsx', require('file-loader?esModule=false!./src-noconflict/snippets/jsx.js'))
+ace.config.setModuleUrl('ace/snippets/julia', require('file-loader?esModule=false!./src-noconflict/snippets/julia.js'))
+ace.config.setModuleUrl('ace/snippets/kotlin', require('file-loader?esModule=false!./src-noconflict/snippets/kotlin.js'))
+ace.config.setModuleUrl('ace/snippets/latex', require('file-loader?esModule=false!./src-noconflict/snippets/latex.js'))
+ace.config.setModuleUrl('ace/snippets/less', require('file-loader?esModule=false!./src-noconflict/snippets/less.js'))
+ace.config.setModuleUrl('ace/snippets/liquid', require('file-loader?esModule=false!./src-noconflict/snippets/liquid.js'))
+ace.config.setModuleUrl('ace/snippets/lisp', require('file-loader?esModule=false!./src-noconflict/snippets/lisp.js'))
+ace.config.setModuleUrl('ace/snippets/livescript', require('file-loader?esModule=false!./src-noconflict/snippets/livescript.js'))
+ace.config.setModuleUrl('ace/snippets/logiql', require('file-loader?esModule=false!./src-noconflict/snippets/logiql.js'))
+ace.config.setModuleUrl('ace/snippets/logtalk', require('file-loader?esModule=false!./src-noconflict/snippets/logtalk.js'))
+ace.config.setModuleUrl('ace/snippets/lsl', require('file-loader?esModule=false!./src-noconflict/snippets/lsl.js'))
+ace.config.setModuleUrl('ace/snippets/lua', require('file-loader?esModule=false!./src-noconflict/snippets/lua.js'))
+ace.config.setModuleUrl('ace/snippets/luapage', require('file-loader?esModule=false!./src-noconflict/snippets/luapage.js'))
+ace.config.setModuleUrl('ace/snippets/lucene', require('file-loader?esModule=false!./src-noconflict/snippets/lucene.js'))
+ace.config.setModuleUrl('ace/snippets/makefile', require('file-loader?esModule=false!./src-noconflict/snippets/makefile.js'))
+ace.config.setModuleUrl('ace/snippets/markdown', require('file-loader?esModule=false!./src-noconflict/snippets/markdown.js'))
+ace.config.setModuleUrl('ace/snippets/mask', require('file-loader?esModule=false!./src-noconflict/snippets/mask.js'))
+ace.config.setModuleUrl('ace/snippets/matlab', require('file-loader?esModule=false!./src-noconflict/snippets/matlab.js'))
+ace.config.setModuleUrl('ace/snippets/maze', require('file-loader?esModule=false!./src-noconflict/snippets/maze.js'))
+ace.config.setModuleUrl('ace/snippets/mel', require('file-loader?esModule=false!./src-noconflict/snippets/mel.js'))
+ace.config.setModuleUrl('ace/snippets/mixal', require('file-loader?esModule=false!./src-noconflict/snippets/mixal.js'))
+ace.config.setModuleUrl('ace/snippets/mushcode', require('file-loader?esModule=false!./src-noconflict/snippets/mushcode.js'))
+ace.config.setModuleUrl('ace/snippets/mysql', require('file-loader?esModule=false!./src-noconflict/snippets/mysql.js'))
+ace.config.setModuleUrl('ace/snippets/nginx', require('file-loader?esModule=false!./src-noconflict/snippets/nginx.js'))
+ace.config.setModuleUrl('ace/snippets/nim', require('file-loader?esModule=false!./src-noconflict/snippets/nim.js'))
+ace.config.setModuleUrl('ace/snippets/nix', require('file-loader?esModule=false!./src-noconflict/snippets/nix.js'))
+ace.config.setModuleUrl('ace/snippets/nsis', require('file-loader?esModule=false!./src-noconflict/snippets/nsis.js'))
+ace.config.setModuleUrl('ace/snippets/objectivec', require('file-loader?esModule=false!./src-noconflict/snippets/objectivec.js'))
+ace.config.setModuleUrl('ace/snippets/ocaml', require('file-loader?esModule=false!./src-noconflict/snippets/ocaml.js'))
+ace.config.setModuleUrl('ace/snippets/pascal', require('file-loader?esModule=false!./src-noconflict/snippets/pascal.js'))
+ace.config.setModuleUrl('ace/snippets/perl', require('file-loader?esModule=false!./src-noconflict/snippets/perl.js'))
+ace.config.setModuleUrl('ace/snippets/perl6', require('file-loader?esModule=false!./src-noconflict/snippets/perl6.js'))
+ace.config.setModuleUrl('ace/snippets/pgsql', require('file-loader?esModule=false!./src-noconflict/snippets/pgsql.js'))
+ace.config.setModuleUrl('ace/snippets/php', require('file-loader?esModule=false!./src-noconflict/snippets/php.js'))
+ace.config.setModuleUrl('ace/snippets/php_laravel_blade', require('file-loader?esModule=false!./src-noconflict/snippets/php_laravel_blade.js'))
+ace.config.setModuleUrl('ace/snippets/pig', require('file-loader?esModule=false!./src-noconflict/snippets/pig.js'))
+ace.config.setModuleUrl('ace/snippets/plain_text', require('file-loader?esModule=false!./src-noconflict/snippets/plain_text.js'))
+ace.config.setModuleUrl('ace/snippets/powershell', require('file-loader?esModule=false!./src-noconflict/snippets/powershell.js'))
+ace.config.setModuleUrl('ace/snippets/praat', require('file-loader?esModule=false!./src-noconflict/snippets/praat.js'))
+ace.config.setModuleUrl('ace/snippets/prolog', require('file-loader?esModule=false!./src-noconflict/snippets/prolog.js'))
+ace.config.setModuleUrl('ace/snippets/properties', require('file-loader?esModule=false!./src-noconflict/snippets/properties.js'))
+ace.config.setModuleUrl('ace/snippets/protobuf', require('file-loader?esModule=false!./src-noconflict/snippets/protobuf.js'))
+ace.config.setModuleUrl('ace/snippets/puppet', require('file-loader?esModule=false!./src-noconflict/snippets/puppet.js'))
+ace.config.setModuleUrl('ace/snippets/python', require('file-loader?esModule=false!./src-noconflict/snippets/python.js'))
+ace.config.setModuleUrl('ace/snippets/r', require('file-loader?esModule=false!./src-noconflict/snippets/r.js'))
+ace.config.setModuleUrl('ace/snippets/razor', require('file-loader?esModule=false!./src-noconflict/snippets/razor.js'))
+ace.config.setModuleUrl('ace/snippets/rdoc', require('file-loader?esModule=false!./src-noconflict/snippets/rdoc.js'))
+ace.config.setModuleUrl('ace/snippets/red', require('file-loader?esModule=false!./src-noconflict/snippets/red.js'))
+ace.config.setModuleUrl('ace/snippets/redshift', require('file-loader?esModule=false!./src-noconflict/snippets/redshift.js'))
+ace.config.setModuleUrl('ace/snippets/rhtml', require('file-loader?esModule=false!./src-noconflict/snippets/rhtml.js'))
+ace.config.setModuleUrl('ace/snippets/rst', require('file-loader?esModule=false!./src-noconflict/snippets/rst.js'))
+ace.config.setModuleUrl('ace/snippets/ruby', require('file-loader?esModule=false!./src-noconflict/snippets/ruby.js'))
+ace.config.setModuleUrl('ace/snippets/rust', require('file-loader?esModule=false!./src-noconflict/snippets/rust.js'))
+ace.config.setModuleUrl('ace/snippets/sass', require('file-loader?esModule=false!./src-noconflict/snippets/sass.js'))
+ace.config.setModuleUrl('ace/snippets/scad', require('file-loader?esModule=false!./src-noconflict/snippets/scad.js'))
+ace.config.setModuleUrl('ace/snippets/scala', require('file-loader?esModule=false!./src-noconflict/snippets/scala.js'))
+ace.config.setModuleUrl('ace/snippets/scheme', require('file-loader?esModule=false!./src-noconflict/snippets/scheme.js'))
+ace.config.setModuleUrl('ace/snippets/scss', require('file-loader?esModule=false!./src-noconflict/snippets/scss.js'))
+ace.config.setModuleUrl('ace/snippets/sh', require('file-loader?esModule=false!./src-noconflict/snippets/sh.js'))
+ace.config.setModuleUrl('ace/snippets/sjs', require('file-loader?esModule=false!./src-noconflict/snippets/sjs.js'))
+ace.config.setModuleUrl('ace/snippets/slim', require('file-loader?esModule=false!./src-noconflict/snippets/slim.js'))
+ace.config.setModuleUrl('ace/snippets/smarty', require('file-loader?esModule=false!./src-noconflict/snippets/smarty.js'))
+ace.config.setModuleUrl('ace/snippets/snippets', require('file-loader?esModule=false!./src-noconflict/snippets/snippets.js'))
+ace.config.setModuleUrl('ace/snippets/soy_template', require('file-loader?esModule=false!./src-noconflict/snippets/soy_template.js'))
+ace.config.setModuleUrl('ace/snippets/space', require('file-loader?esModule=false!./src-noconflict/snippets/space.js'))
+ace.config.setModuleUrl('ace/snippets/sparql', require('file-loader?esModule=false!./src-noconflict/snippets/sparql.js'))
+ace.config.setModuleUrl('ace/snippets/sql', require('file-loader?esModule=false!./src-noconflict/snippets/sql.js'))
+ace.config.setModuleUrl('ace/snippets/sqlserver', require('file-loader?esModule=false!./src-noconflict/snippets/sqlserver.js'))
+ace.config.setModuleUrl('ace/snippets/stylus', require('file-loader?esModule=false!./src-noconflict/snippets/stylus.js'))
+ace.config.setModuleUrl('ace/snippets/svg', require('file-loader?esModule=false!./src-noconflict/snippets/svg.js'))
+ace.config.setModuleUrl('ace/snippets/swift', require('file-loader?esModule=false!./src-noconflict/snippets/swift.js'))
+ace.config.setModuleUrl('ace/snippets/tcl', require('file-loader?esModule=false!./src-noconflict/snippets/tcl.js'))
+ace.config.setModuleUrl('ace/snippets/terraform', require('file-loader?esModule=false!./src-noconflict/snippets/terraform.js'))
+ace.config.setModuleUrl('ace/snippets/tex', require('file-loader?esModule=false!./src-noconflict/snippets/tex.js'))
+ace.config.setModuleUrl('ace/snippets/text', require('file-loader?esModule=false!./src-noconflict/snippets/text.js'))
+ace.config.setModuleUrl('ace/snippets/textile', require('file-loader?esModule=false!./src-noconflict/snippets/textile.js'))
+ace.config.setModuleUrl('ace/snippets/toml', require('file-loader?esModule=false!./src-noconflict/snippets/toml.js'))
+ace.config.setModuleUrl('ace/snippets/tsx', require('file-loader?esModule=false!./src-noconflict/snippets/tsx.js'))
+ace.config.setModuleUrl('ace/snippets/turtle', require('file-loader?esModule=false!./src-noconflict/snippets/turtle.js'))
+ace.config.setModuleUrl('ace/snippets/twig', require('file-loader?esModule=false!./src-noconflict/snippets/twig.js'))
+ace.config.setModuleUrl('ace/snippets/typescript', require('file-loader?esModule=false!./src-noconflict/snippets/typescript.js'))
+ace.config.setModuleUrl('ace/snippets/vala', require('file-loader?esModule=false!./src-noconflict/snippets/vala.js'))
+ace.config.setModuleUrl('ace/snippets/vbscript', require('file-loader?esModule=false!./src-noconflict/snippets/vbscript.js'))
+ace.config.setModuleUrl('ace/snippets/velocity', require('file-loader?esModule=false!./src-noconflict/snippets/velocity.js'))
+ace.config.setModuleUrl('ace/snippets/verilog', require('file-loader?esModule=false!./src-noconflict/snippets/verilog.js'))
+ace.config.setModuleUrl('ace/snippets/vhdl', require('file-loader?esModule=false!./src-noconflict/snippets/vhdl.js'))
+ace.config.setModuleUrl('ace/snippets/visualforce', require('file-loader?esModule=false!./src-noconflict/snippets/visualforce.js'))
+ace.config.setModuleUrl('ace/snippets/wollok', require('file-loader?esModule=false!./src-noconflict/snippets/wollok.js'))
+ace.config.setModuleUrl('ace/snippets/xml', require('file-loader?esModule=false!./src-noconflict/snippets/xml.js'))
+ace.config.setModuleUrl('ace/snippets/xquery', require('file-loader?esModule=false!./src-noconflict/snippets/xquery.js'))
+ace.config.setModuleUrl('ace/snippets/yaml', require('file-loader?esModule=false!./src-noconflict/snippets/yaml.js'))
+ace.config.setModuleUrl('ace/snippets/zeek', require('file-loader?esModule=false!./src-noconflict/snippets/zeek.js'))
\ No newline at end of file
diff --git a/htdocs/includes/evalmath/README.md b/htdocs/includes/evalmath/README.md
deleted file mode 100755
index 6011e3fb676..00000000000
--- a/htdocs/includes/evalmath/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-evalmath.class.php
-==================
-
-Version 1.0
-
-Taken from http://www.phpclasses.org/browse/file/11680.html, cred to Miles Kaufmann
-
-This repository is cloned for two reasons:
-
-1. To allow downloading the code without signing in to phpclasses.org.
-2. To add very small improvements to the code.
diff --git a/htdocs/includes/evalmath/evalmath.class.php b/htdocs/includes/evalmath/evalmath.class.php
deleted file mode 100644
index 9d970aed789..00000000000
--- a/htdocs/includes/evalmath/evalmath.class.php
+++ /dev/null
@@ -1,398 +0,0 @@
-
-
-================================================================================
-
-NAME
- EvalMath - safely evaluate math expressions
-
-SYNOPSIS
- include('evalmath.class.php');
- $m = new EvalMath;
- // basic evaluation:
- $result = $m->evaluate('2+2');
- // supports: order of operation; parentheses; negation; built-in functions
- $result = $m->evaluate('-8(5/2)^2*(1-sqrt(4))-8');
- // create your own variables
- $m->evaluate('a = e^(ln(pi))');
- // or functions
- $m->evaluate('f(x,y) = x^2 + y^2 - 2x*y + 1');
- // and then use them
- $result = $m->evaluate('3*f(42,a)');
-
-DESCRIPTION
- Use the EvalMath class when you want to evaluate mathematical expressions
- from untrusted sources. You can define your own variables and functions,
- which are stored in the object. Try it, it's fun!
-
-METHODS
- $m->evalute($expr)
- Evaluates the expression and returns the result. If an error occurs,
- prints a warning and returns false. If $expr is a function assignment,
- returns true on success.
-
- $m->e($expr)
- A synonym for $m->evaluate().
-
- $m->vars()
- Returns an associative array of all user-defined variables and values.
-
- $m->funcs()
- Returns an array of all user-defined functions.
-
-PARAMETERS
- $m->suppress_errors
- Set to true to turn off warnings when evaluating expressions
-
- $m->last_error
- If the last evaluation failed, contains a string describing the error.
- (Useful when suppress_errors is on).
-
- $m->last_error_code
- If the last evaluation failed, 2 element array with numeric code and extra info
-
-AUTHOR INFORMATION
- Copyright 2005, Miles Kaufmann.
-
-LICENSE
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- 1 Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-*/
-
-class EvalMath
-{
- var $suppress_errors = false;
- var $last_error = null;
- var $last_error_code = null;
-
- var $v = array('e'=>2.71,'pi'=>3.14159); // variables (and constants)
- var $f = array(); // user-defined functions
- var $vb = array('e', 'pi'); // constants
- var $fb = array( // built-in functions
- 'sin','sinh','arcsin','asin','arcsinh','asinh',
- 'cos','cosh','arccos','acos','arccosh','acosh',
- 'tan','tanh','arctan','atan','arctanh','atanh',
- 'sqrt','abs','ln','log','intval');
-
- /**
- * Constructor
- */
- function __construct() {
- // make the variables a little more accurate
- $this->v['pi'] = pi();
- $this->v['e'] = exp(1);
- }
-
- function e($expr) {
- return $this->evaluate($expr);
- }
-
- function evaluate($expr) {
- $this->last_error = null;
- $this->last_error_code = null;
- $expr = trim($expr);
- if (substr($expr, -1, 1) == ';') $expr = substr($expr, 0, strlen($expr)-1); // strip semicolons at the end
- //===============
- // is it a variable assignment?
- if (preg_match('/^\s*([a-z]\w*)\s*=\s*(.+)$/', $expr, $matches)) {
- if (in_array($matches[1], $this->vb)) { // make sure we're not assigning to a constant
- return $this->trigger(1, "cannot assign to constant '$matches[1]'", $matches[1]);
- }
- if (($tmp = $this->pfx($this->nfx($matches[2]))) === false) return false; // get the result and make sure it's good
- $this->v[$matches[1]] = $tmp; // if so, stick it in the variable array
- return $this->v[$matches[1]]; // and return the resulting value
- //===============
- // is it a function assignment?
- } elseif (preg_match('/^\s*([a-z]\w*)\s*\(\s*([a-z]\w*(?:\s*,\s*[a-z]\w*)*)\s*\)\s*=\s*(.+)$/', $expr, $matches)) {
- $fnn = $matches[1]; // get the function name
- if (in_array($matches[1], $this->fb)) { // make sure it isn't built in
- return $this->trigger(2, "cannot redefine built-in function '$matches[1]()'", $matches[1]);
- }
- $args = explode(",", preg_replace("/\s+/", "", $matches[2])); // get the arguments
- if (($stack = $this->nfx($matches[3])) === false) return false; // see if it can be converted to postfix
- $nbstack = count($stack);
- for ($i = 0; $i < $nbstack; $i++) { // freeze the state of the non-argument variables
- $token = $stack[$i];
- if (preg_match('/^[a-z]\w*$/', $token) and !in_array($token, $args)) {
- if (array_key_exists($token, $this->v)) {
- $stack[$i] = $this->v[$token];
- } else {
- return $this->trigger(3, "undefined variable '$token' in function definition", $token);
- }
- }
- }
- $this->f[$fnn] = array('args'=>$args, 'func'=>$stack);
- return true;
- //===============
- } else {
- return $this->pfx($this->nfx($expr)); // straight up evaluation, woo
- }
- }
-
- function vars() {
- $output = $this->v;
- unset($output['pi']);
- unset($output['e']);
- return $output;
- }
-
- function funcs() {
- $output = array();
- foreach ($this->f as $fnn=>$dat)
- $output[] = $fnn . '(' . implode(',', $dat['args']) . ')';
- return $output;
- }
-
- //===================== HERE BE INTERNAL METHODS ====================\\
-
- // Convert infix to postfix notation
- function nfx($expr) {
-
- $index = 0;
- $stack = new EvalMathStack();
- $output = array(); // postfix form of expression, to be passed to pfx()
- $expr = trim(strtolower($expr));
-
- $ops = array('+', '-', '*', '/', '^', '_');
- $ops_r = array('+'=>0,'-'=>0,'*'=>0,'/'=>0,'^'=>1); // right-associative operator?
- $ops_p = array('+'=>0,'-'=>0,'*'=>1,'/'=>1,'_'=>1,'^'=>2); // operator precedence
-
- $expecting_op = false; // we use this in syntax-checking the expression
- // and determining when a - is a negation
-
- if (preg_match("/[^\w\s+*^\/()\.,-]/", $expr, $matches)) { // make sure the characters are all good
- return $this->trigger(4, "illegal character '{$matches[0]}'", $matches[0]);
- }
-
- while(1) { // 1 Infinite Loop ;)
- $op = substr($expr, $index, 1); // get the first character at the current index
- // find out if we're currently at the beginning of a number/variable/function/parenthesis/operand
- $ex = preg_match('/^([a-z]\w*\(?|\d+(?:\.\d*)?|\.\d+|\()/', substr($expr, $index), $match);
- //===============
- if ($op == '-' and !$expecting_op) { // is it a negation instead of a minus?
- $stack->push('_'); // put a negation on the stack
- $index++;
- } elseif ($op == '_') { // we have to explicitly deny this, because it's legal on the stack
- return $this->trigger(4, "illegal character '_'", "_"); // but not in the input expression
- //===============
- } elseif ((in_array($op, $ops) or $ex) and $expecting_op) { // are we putting an operator on the stack?
- if ($ex) { // are we expecting an operator but have a number/variable/function/opening parethesis?
- $op = '*'; $index--; // it's an implicit multiplication
- }
- // heart of the algorithm:
- while($stack->count > 0 and ($o2 = $stack->last()) and in_array($o2, $ops) and ($ops_r[$op] ? $ops_p[$op] < $ops_p[$o2] : $ops_p[$op] <= $ops_p[$o2])) {
- $output[] = $stack->pop(); // pop stuff off the stack into the output
- }
- // many thanks: http://en.wikipedia.org/wiki/Reverse_Polish_notation#The_algorithm_in_detail
- $stack->push($op); // finally put OUR operator onto the stack
- $index++;
- $expecting_op = false;
- //===============
- } elseif ($op == ')' and $expecting_op) { // ready to close a parenthesis?
- while (($o2 = $stack->pop()) != '(') { // pop off the stack back to the last (
- if (is_null($o2)) return $this->trigger(5, "unexpected ')'", ")");
- else $output[] = $o2;
- }
- if (preg_match("/^([a-z]\w*)\($/", $stack->last(2), $matches)) { // did we just close a function?
- $fnn = $matches[1]; // get the function name
- $arg_count = $stack->pop(); // see how many arguments there were (cleverly stored on the stack, thank you)
- $output[] = $stack->pop(); // pop the function and push onto the output
- if (in_array($fnn, $this->fb)) { // check the argument count
- if($arg_count > 1)
- return $this->trigger(6, "wrong number of arguments ($arg_count given, 1 expected)", array($arg_count, 1));
- } elseif (array_key_exists($fnn, $this->f)) {
- if ($arg_count != count($this->f[$fnn]['args']))
- return $this->trigger(6, "wrong number of arguments ($arg_count given, " . count($this->f[$fnn]['args']) . " expected)", array($arg_count, count($this->f[$fnn]['args'])));
- } else { // did we somehow push a non-function on the stack? this should never happen
- return $this->trigger(7, "internal error");
- }
- }
- $index++;
- //===============
- } elseif ($op == ',' and $expecting_op) { // did we just finish a function argument?
- while (($o2 = $stack->pop()) != '(') {
- if (is_null($o2)) return $this->trigger(5, "unexpected ','", ","); // oops, never had a (
- else $output[] = $o2; // pop the argument expression stuff and push onto the output
- }
- // make sure there was a function
- if (!preg_match("/^([a-z]\w*)\($/", $stack->last(2), $matches))
- return $this->trigger(5, "unexpected ','", ",");
- $stack->push($stack->pop()+1); // increment the argument count
- $stack->push('('); // put the ( back on, we'll need to pop back to it again
- $index++;
- $expecting_op = false;
- //===============
- } elseif ($op == '(' and !$expecting_op) {
- $stack->push('('); // that was easy
- $index++;
- $allow_neg = true;
- //===============
- } elseif ($ex and !$expecting_op) { // do we now have a function/variable/number?
- $expecting_op = true;
- $val = $match[1];
- if (preg_match("/^([a-z]\w*)\($/", $val, $matches)) { // may be func, or variable w/ implicit multiplication against parentheses...
- if (in_array($matches[1], $this->fb) or array_key_exists($matches[1], $this->f)) { // it's a func
- $stack->push($val);
- $stack->push(1);
- $stack->push('(');
- $expecting_op = false;
- } else { // it's a var w/ implicit multiplication
- $val = $matches[1];
- $output[] = $val;
- }
- } else { // it's a plain old var or num
- $output[] = $val;
- }
- $index += strlen($val);
- //===============
- } elseif ($op == ')') { // miscellaneous error checking
- return $this->trigger(5, "unexpected ')'", ")");
- } elseif (in_array($op, $ops) and !$expecting_op) {
- return $this->trigger(8, "unexpected operator '$op'", $op);
- } else { // I don't even want to know what you did to get here
- return $this->trigger(9, "an unexpected error occured");
- }
- if ($index == strlen($expr)) {
- if (in_array($op, $ops)) { // did we end with an operator? bad.
- return $this->trigger(10, "operator '$op' lacks operand", $op);
- } else {
- break;
- }
- }
- while (substr($expr, $index, 1) == ' ') { // step the index past whitespace (pretty much turns whitespace
- $index++; // into implicit multiplication if no operator is there)
- }
-
- }
- while (!is_null($op = $stack->pop())) { // pop everything off the stack and push onto output
- if ($op == '(') return $this->trigger(11, "expecting ')'", ")"); // if there are (s on the stack, ()s were unbalanced
- $output[] = $op;
- }
- return $output;
- }
-
- // evaluate postfix notation
- function pfx($tokens, $vars = array()) {
-
- if ($tokens == false) return false;
-
- $stack = new EvalMathStack();
-
- foreach ($tokens as $token) { // nice and easy
- // if the token is a binary operator, pop two values off the stack, do the operation, and push the result back on
- if (in_array($token, array('+', '-', '*', '/', '^'))) {
- if (is_null($op2 = $stack->pop())) return $this->trigger(12, "internal error");
- if (is_null($op1 = $stack->pop())) return $this->trigger(13, "internal error");
- switch ($token) {
- case '+':
- $stack->push($op1+$op2); break;
- case '-':
- $stack->push($op1-$op2); break;
- case '*':
- $stack->push($op1*$op2); break;
- case '/':
- if ($op2 == 0) return $this->trigger(14, "division by zero");
- $stack->push($op1/$op2); break;
- case '^':
- $stack->push(pow($op1, $op2)); break;
- }
- // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on
- } elseif ($token == "_") {
- $stack->push(-1*$stack->pop());
- // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on
- } elseif (preg_match("/^([a-z]\w*)\($/", $token, $matches)) { // it's a function!
- $fnn = $matches[1];
- if (in_array($fnn, $this->fb)) { // built-in function:
- if (is_null($op1 = $stack->pop())) return $this->trigger(15, "internal error");
- $fnn = preg_replace("/^arc/", "a", $fnn); // for the 'arc' trig synonyms
- if ($fnn == 'ln') $fnn = 'log';
- eval('$stack->push(' . $fnn . '($op1));'); // perfectly safe eval()
- } elseif (array_key_exists($fnn, $this->f)) { // user function
- // get args
- $args = array();
- for ($i = count($this->f[$fnn]['args'])-1; $i >= 0; $i--) {
- if (is_null($args[$this->f[$fnn]['args'][$i]] = $stack->pop())) return $this->trigger(16, "internal error");
- }
- $stack->push($this->pfx($this->f[$fnn]['func'], $args)); // yay... recursion!!!!
- }
- // if the token is a number or variable, push it on the stack
- } else {
- if (is_numeric($token)) {
- $stack->push($token);
- } elseif (array_key_exists($token, $this->v)) {
- $stack->push($this->v[$token]);
- } elseif (array_key_exists($token, $vars)) {
- $stack->push($vars[$token]);
- } else {
- return $this->trigger(17, "undefined variable '$token'", $token);
- }
- }
- }
- // when we're out of tokens, the stack should have a single element, the final result
- if ($stack->count != 1) return $this->trigger(18, "internal error");
- return $stack->pop();
- }
-
- // trigger an error, but nicely, if need be
- function trigger($code, $msg, $info = null) {
- $this->last_error = $msg;
- $this->last_error_code = array($code, $info);
- if (!$this->suppress_errors) trigger_error($msg, E_USER_WARNING);
- return false;
- }
-}
-
-/**
- * Class for internal use
- */
-class EvalMathStack
-{
- var $stack = array();
- var $count = 0;
-
- function push($val) {
- $this->stack[$this->count] = $val;
- $this->count++;
- }
-
- function pop() {
- if ($this->count > 0) {
- $this->count--;
- return $this->stack[$this->count];
- }
- return null;
- }
-
- function last($n=1) {
- if (isset($this->stack[$this->count-$n])) {
- return $this->stack[$this->count-$n];
- }
- return;
- }
-}
diff --git a/htdocs/includes/jquery/plugins/select2/.editorconfig b/htdocs/includes/jquery/plugins/select2/.editorconfig
new file mode 100644
index 00000000000..54f4d3beedb
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/.editorconfig
@@ -0,0 +1,6 @@
+[*]
+indent_style = space
+end_of_line = lf
+
+[*.js]
+indent_size = 2
diff --git a/htdocs/includes/jquery/plugins/select2/.gitignore b/htdocs/includes/jquery/plugins/select2/.gitignore
new file mode 100644
index 00000000000..aa970da6518
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/.gitignore
@@ -0,0 +1,3 @@
+node_modules
+dist/js/i18n/build.txt
+.sass-cache
diff --git a/htdocs/includes/jquery/plugins/select2/.jshintignore b/htdocs/includes/jquery/plugins/select2/.jshintignore
new file mode 100644
index 00000000000..ba5a30f8c38
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/.jshintignore
@@ -0,0 +1,4 @@
+src/js/banner.*.js
+src/js/wrapper.*.js
+tests/vendor/*.js
+tests/helpers.js
diff --git a/htdocs/includes/jquery/plugins/select2/.jshintrc b/htdocs/includes/jquery/plugins/select2/.jshintrc
new file mode 100644
index 00000000000..94299268771
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/.jshintrc
@@ -0,0 +1,25 @@
+{
+ "bitwise": true,
+ "camelcase": true,
+ "curly": true,
+ "es3": true,
+ "eqnull": true,
+ "freeze": true,
+ "globals": {
+ "console": false,
+ "define": false,
+ "document": false,
+ "MockContainer": false,
+ "module": false,
+ "QUnit": false,
+ "require": false,
+ "test": false,
+ "window": false
+ },
+ "indent": 2,
+ "maxlen": 80,
+ "noarg": true,
+ "nonew": true,
+ "quotmark": "single",
+ "undef": true
+}
diff --git a/htdocs/includes/jquery/plugins/select2/CHANGELOG.md b/htdocs/includes/jquery/plugins/select2/CHANGELOG.md
index 3ae60aff255..d6b2a7587dd 100644
--- a/htdocs/includes/jquery/plugins/select2/CHANGELOG.md
+++ b/htdocs/includes/jquery/plugins/select2/CHANGELOG.md
@@ -1,5 +1,178 @@
# Change Log
+## 4.0.13
+
+### New features / improvements
+
+* Trigger `input` event before `change` events (#4649)
+* Feed back the keypress code that was responsible for the 'close' event (#5513)
+* Only trigger `selection:update` once on DOM change events (#5734)
+
+### Bug fixes
+
+* Prevent opening of disabled elements (#5751)
+
+### Documentation
+
+* Fix "edit this page" links in docs (#5689)
+
+### Miscellaneous
+
+* Registered Select2 on Open Collective (#5700, #5721, #5741)
+
+## 4.0.12
+
+### Bug fixes
+
+* Fixes incorrect offset when using the Shadow DOM and styling the `` element (#5682)
+
+### Miscellaneous
+
+* Replace cdnjs with jsDelivr in the documentation (#5687)
+* Fix incorrect provider for the automated NPM deployment (#5686)
+
+## 4.0.11
+
+### Bug fixes
+
+* Fixes jQuery migrate error when getting offset when dropdownParent not in document (#5584)
+
+### Miscellaneous
+
+* Enable GitHub actions for CI (#5591)
+* Documentation has been moved into and is deployed from the code repository (#5638)
+* Remove Travis CI integration (#5665)
+
+## 4.0.10
+
+### New features / improvements
+
+* Support passing in a selector for `dropdownParent` option (#5622)
+
+### Bug fixes
+
+* Fix bug where dropdowns pointing upwards were incorrectly positioned (#5621)
+
+## 4.0.9
+
+### New features / improvements
+
+* Mirror disabled state through aria-disabled on selection (#5579)
+* Select2 now clears the internal ID when it is destroyed (#5587)
+* Set the main ARIA 1.1 roles and properties for comboboxes (#5582)
+* The `language` option now has a clearly defined fallback chain (#5602)
+
+### Bug fixes
+
+* Do not propagate click when search box is not empty (#5580)
+* Fix `maximumSelectionLength` being ignored by `closeOnSelect` (#5581)
+* Fix generated options not receiving result IDs (#5586)
+* Remove selection title attribute if text is empty (#5589)
+* Reposition dropdown whenever items are selected (#5590)
+* Fix dropdown positioning when displayed above with messages (#5592)
+* Fix search box expanding width of container (#5595)
+* `allowClear` no longer shifts selections to a new line (#5603)
+
+### Translations
+
+* Fix error in German translations (#5604)
+
+### Miscellaneous
+
+* Updated development grunt version so it no longer shows as vulnerable (#5597)
+* Remove unused variables (#5554)
+
+## 4.0.8
+
+### New features / improvements
+
+* Test against and fix compatibility with jQuery 3.4.1 (#5531)
+* Results respect disabled state of `` (#5560)
+* Add `computedstyle` option for calculating the width (#5559)
+
+### Bug fixes
+
+* Fix tag creation being broken in 4.0.7 (#5558)
+* Fix infinite scroll when the scrollbar is not visible (#5575)
+* Revert change to focusing behaviour in 4.0.6 (#5576)
+
+### Translations
+
+* Fix wording in French translations (#5521)
+
+### Miscellaneous
+
+* Update grunt-contrib-qunit to latest version (#5530)
+* Removed unused `.select2-selection__placeholder` CSS definitions for multiple selects (#5508)
+* Remove deprecated jQuery shorthand (#5564)
+
+## 4.0.7
+
+### New features/improvements
+- Do not close on select if Ctrl or Meta (Cmd) keys being held (#5222)
+
+### Bug fixes
+- Fixed issue where single select boxes would automatically reopen when they were closed (#5490, #5492)
+
+### Miscellaneous
+- Move almost and jquery-mousewheel to devDependencies (#5489)
+
+## 4.0.6
+
+### New features/improvements
+- Add style property to package.json (#5019)
+- Implement `clear` and `clearing` events (#5058)
+- Add `scrollAfterSelect` option (#5150)
+- Add missing diacritics (#4118, #4337, #5464)
+
+### Bug fixes
+- Fix up arrow error when there are no options in dropdown (#5127)
+- Add `;` before beginning of factory wrapper (#5089)
+- Fix IE11 issue with select losing focus after selecting an item (#4860)
+- Clear tooltip from `select2-selection__rendered` when selection is cleared (#4640, #4746)
+- Fix keyboard not closing when closing dropdown on iOS 10 (#4680)
+- User-defined types not normalized properly when passed in as data (#4632)
+- Perform deep merge for `Defaults.set()` (#4364)
+- Fix "the results could not be loaded" displaying during AJAX request (#4356)
+- Cache objects in `Utils.__cache` instead of using `$.data` (#4346, #5486)
+- Removing the double event binding registration of `selection:update` (#4306)
+
+#### Accessibility
+- Improve `.select2-hidden-accessible` (#4908)
+- Add role and aria-readonly attributes to single selection dropdown value (#4881)
+
+### Translations
+- Add Turkmen translations (`tk`) (#5125)
+- Fix error in French translations (#5122)
+- Add Albanian translation (`sq`) (#5199)
+- Add Georgian translation (`ka`) (#5179)
+- Add Nepali translation (`ne`) (#5295)
+- Add Bangla translation (`bn`) (#5248)
+- Add `removeAllItems` translation for clear "x" title (#5291)
+- Fix wording in Vietnamese translations (#5387)
+- Fix error in Russian translation (#5401)
+
+### Miscellaneous
+- Remove duplicate CSS selector in classic theme (#5115)
+
+## 4.0.5
+
+### Bug fixes
+- Replace `autocapitalize=off` with `autocapitalize=none` (#4994)
+
+### Translations
+- Vietnamese: remove an unnecessary quote mark (#5059)
+- Czech: Add missing commas and periods (#5052)
+- Spanish: Update the 'errorLoading' message (#5032)
+- Fix typo in Romanian (#5005)
+- Improve French translation (#4988)
+- Add Pashto translation (`ps`) (#4960)
+- Add translations for lower and upper Sorbian (`dsb` and `hsb`) (#4949)
+- Updates to Slovak (#4915)
+- Fixed Norwegian `inputTooShort` message (#4817, 4896)
+- Add Afrikaans translation (`af`) (#4850)
+- Add Bosnian translation (`bs`) (#4504)
+
## 4.0.4
### New features / Improvements
diff --git a/htdocs/includes/jquery/plugins/select2/Gruntfile.js b/htdocs/includes/jquery/plugins/select2/Gruntfile.js
index bf0f38d4303..23ef3d9cf50 100644
--- a/htdocs/includes/jquery/plugins/select2/Gruntfile.js
+++ b/htdocs/includes/jquery/plugins/select2/Gruntfile.js
@@ -1,3 +1,5 @@
+const sass = require('node-sass');
+
module.exports = function (grunt) {
// Full list of files that must be included by RequireJS
includes = [
@@ -62,10 +64,6 @@ module.exports = function (grunt) {
grunt.initConfig({
package: grunt.file.readJSON('package.json'),
- clean: {
- docs: ['docs/_site']
- },
-
concat: {
'dist': {
options: {
@@ -124,81 +122,10 @@ module.exports = function (grunt) {
}
},
- 'saucelabs-qunit': {
- all: {
- options: {
- build: testBuildNumber,
- tags: ['tests', 'qunit'],
- urls: testUrls,
- testname: 'QUnit test for Select2',
- browsers: [
- {
- browserName: 'internet explorer',
- version: '8'
- },
- {
- browserName: 'internet explorer',
- version: '9'
- },
- {
- browserName: 'internet explorer',
- version: '10'
- },
- {
- browserName: 'internet explorer',
- version: '11'
- },
-
- {
- browserName: 'firefox',
- platform: 'linux'
- },
-
- {
- browserName: 'chrome'
- },
-
- {
- browserName: 'opera',
- version: '12',
- platform: 'linux'
- }
- ]
- }
- }
- },
-
- 'gh-pages': {
- options: {
- base: 'docs',
- branch: 'master',
- clone: 'node_modules/grunt-gh-pages/repo',
- message: 'Updated docs with master',
- push: true,
- repo: 'git@github.com:select2/select2.github.io.git'
- },
- src: '**'
- },
-
- jekyll: {
- options: {
- src: 'docs',
- dest: 'docs/_site'
- },
- build: {
- d: null
- },
- serve: {
- options: {
- serve: true,
- watch: true
- }
- }
- },
-
jshint: {
options: {
- jshintrc: true
+ jshintrc: true,
+ reporterOutput: ''
},
code: {
src: ['src/js/**/*.js']
@@ -211,6 +138,7 @@ module.exports = function (grunt) {
sass: {
dist: {
options: {
+ implementation: sass,
outputStyle: 'compressed'
},
files: {
@@ -222,6 +150,7 @@ module.exports = function (grunt) {
},
dev: {
options: {
+ implementation: sass,
outputStyle: 'nested'
},
files: {
@@ -233,19 +162,6 @@ module.exports = function (grunt) {
}
},
- symlink: {
- docs: {
- cwd: 'dist',
- expand: true,
- overwrite: false,
- src: [
- '*'
- ],
- dest: 'docs/dist',
- filter: 'isDirectory'
- }
- },
-
requirejs: {
'dist': {
options: {
@@ -324,22 +240,17 @@ module.exports = function (grunt) {
}
});
- grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-requirejs');
- grunt.loadNpmTasks('grunt-contrib-symlink');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
- grunt.loadNpmTasks('grunt-gh-pages');
- grunt.loadNpmTasks('grunt-jekyll');
- grunt.loadNpmTasks('grunt-saucelabs');
grunt.loadNpmTasks('grunt-sass');
- grunt.registerTask('default', ['compile', 'test', 'minify']);
+ grunt.registerTask('default', ['compile', 'test', 'lint', 'minify']);
grunt.registerTask('compile', [
'requirejs:dist', 'requirejs:dist.full', 'requirejs:i18n',
@@ -347,24 +258,6 @@ module.exports = function (grunt) {
'sass:dev'
]);
grunt.registerTask('minify', ['uglify', 'sass:dist']);
- grunt.registerTask('test', ['connect:tests', 'qunit', 'jshint']);
-
- var ciTasks = [];
-
- ciTasks.push('compile');
- ciTasks.push('connect:tests');
-
- // Can't run Sauce Labs tests in pull requests
- if (process.env.TRAVIS_PULL_REQUEST == 'false') {
- ciTasks.push('saucelabs-qunit');
- }
-
- ciTasks.push('qunit');
- ciTasks.push('jshint');
-
- grunt.registerTask('ci', ciTasks);
-
- grunt.registerTask('docs', ['symlink:docs', 'jekyll:serve']);
-
- grunt.registerTask('docs-release', ['default', 'clean:docs', 'gh-pages']);
+ grunt.registerTask('lint', ['jshint']);
+ grunt.registerTask('test', ['connect:tests', 'qunit']);
};
diff --git a/htdocs/includes/jquery/plugins/select2/README.md b/htdocs/includes/jquery/plugins/select2/README.md
index 6ee975d6ee0..a27484fa40c 100644
--- a/htdocs/includes/jquery/plugins/select2/README.md
+++ b/htdocs/includes/jquery/plugins/select2/README.md
@@ -1,6 +1,8 @@
Select2
=======
-[![Build Status][travis-ci-image]][travis-ci-status]
+![Build Status][github-actions-image]
+[](https://opencollective.com/select2) [][cdnjs]
+[][jsdelivr]
Select2 is a jQuery-based replacement for select boxes. It supports searching,
remote data sets, and pagination of results.
@@ -31,14 +33,10 @@ Browser compatibility
* Safari 3+
* Opera 10.6+
-Select2 is automatically tested on the following browsers.
-
-[![Sauce Labs Test Status][saucelabs-matrix]][saucelabs-status]
-
Usage
-----
-You can source Select2 directly from a CDN like [JSDliver][jsdelivr] or
-[CDNJS][cdnjs], [download it from this GitHub repo][releases], or use one of
+You can source Select2 directly from a CDN like [jsDelivr][jsdelivr] or
+[cdnjs][cdnjs], [download it from this GitHub repo][releases], or use one of
the integrations below.
Integrations
@@ -51,14 +49,17 @@ Plugins
- [django-autocomplete-light]
- [django-easy-select2]
- [django-select2]
+* [Drupal] - [drupal-select2]
* [Meteor] - [meteor-select2]
* [Ruby on Rails][ruby-on-rails] - [select2-rails]
* [Wicket] - [wicketstuff-select2]
* [Yii 2][yii2] - [yii2-widget-select2]
+* [Angularjs][angularjs] - [mdr-angular-select2]
Themes
- [Bootstrap 3][bootstrap3] - [select2-bootstrap-theme]
+- [Bootstrap 4][bootstrap4] - [select2-bootstrap4-theme]
- [Flat UI][flat-ui] - [select2-flat-theme]
- [Metro UI][metro-ui] - [select2-metro]
@@ -76,8 +77,8 @@ make a pull request back to Select2 here on GitHub.
Documentation
-------------
The documentation for Select2 is available
-[through GitHub Pages][documentation] and is located within this repository
-in the [`docs` folder][documentation-folder].
+[online at the documentation website][documentation] and is located within the
+[`docs` directory of this repository][documentation-directory].
Community
---------
@@ -91,28 +92,31 @@ The license is available within the repository in the [LICENSE][license] file.
[cdnjs]: http://www.cdnjs.com/libraries/select2
[community]: https://select2.org/getting-help
[documentation]: https://select2.org
-[documentation-folder]: https://github.com/select2/select2/tree/master/docs
+[documentation-directory]: https://github.com/select2/select2/tree/develop/docs
[freenode]: https://freenode.net/
-[jsdelivr]: http://www.jsdelivr.com/#!select2
+[github-actions-image]: https://github.com/select2/select2/workflows/CI/badge.svg
+[jsdelivr]: https://www.jsdelivr.com/package/npm/select2
[license]: LICENSE.md
[releases]: https://github.com/select2/select2/releases
-[saucelabs-matrix]: https://saucelabs.com/browser-matrix/select2.svg
-[saucelabs-status]: https://saucelabs.com/u/select2
-[travis-ci-image]: https://img.shields.io/travis/select2/select2/master.svg
-[travis-ci-status]: https://travis-ci.org/select2/select2
+[angularjs]: https://angularjs.org/
[bootstrap3]: https://getbootstrap.com/
+[bootstrap4]: https://getbootstrap.com/
[django]: https://www.djangoproject.com/
[django-autocomplete-light]: https://github.com/yourlabs/django-autocomplete-light
[django-easy-select2]: https://github.com/asyncee/django-easy-select2
[django-select2]: https://github.com/applegrew/django-select2
+[drupal]: https://www.drupal.org/
+[drupal-select2]: https://www.drupal.org/project/select2
[flat-ui]: http://designmodo.github.io/Flat-UI/
+[mdr-angular-select2]: https://github.com/modulr/mdr-angular-select2
[meteor]: https://www.meteor.com/
[meteor-select2]: https://github.com/nate-strauser/meteor-select2
[metro-ui]: http://metroui.org.ua/
[select2-metro]: http://metroui.org.ua/select2.html
[ruby-on-rails]: http://rubyonrails.org/
[select2-bootstrap-theme]: https://github.com/select2/select2-bootstrap-theme
+[select2-bootstrap4-theme]: https://github.com/ttskch/select2-bootstrap4-theme
[select2-flat-theme]: https://github.com/techhysahil/select2-Flat_Theme
[select2-rails]: https://github.com/argerim/select2-rails
[vue.js]: http://vuejs.org/
@@ -121,3 +125,33 @@ The license is available within the repository in the [LICENSE][license] file.
[wicketstuff-select2]: https://github.com/wicketstuff/core/tree/master/select2-parent
[yii2]: http://www.yiiframework.com/
[yii2-widget-select2]: https://github.com/kartik-v/yii2-widget-select2
+
+## Contributors
+
+### Code Contributors
+
+This project exists thanks to all the people who contribute. [[Contribute](.github/CONTRIBUTING.md)].
+
+
+### Financial Contributors
+
+Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/select2/contribute)]
+
+#### Individuals
+
+
+
+#### Organizations
+
+Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/select2/contribute)]
+
+
+
+
+
+
+
+
+
+
+
diff --git a/htdocs/includes/jquery/plugins/select2/component.json b/htdocs/includes/jquery/plugins/select2/component.json
index 078338b59d3..a8e74c52499 100644
--- a/htdocs/includes/jquery/plugins/select2/component.json
+++ b/htdocs/includes/jquery/plugins/select2/component.json
@@ -2,7 +2,7 @@
"name": "select2",
"repo": "select/select2",
"description": "Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.",
- "version": "4.0.4",
+ "version": "4.0.13",
"demo": "https://select2.org/",
"keywords": [
"jquery"
diff --git a/htdocs/includes/jquery/plugins/select2/composer.json b/htdocs/includes/jquery/plugins/select2/composer.json
index 141f4e14155..5ef2db2b1db 100644
--- a/htdocs/includes/jquery/plugins/select2/composer.json
+++ b/htdocs/includes/jquery/plugins/select2/composer.json
@@ -4,9 +4,6 @@
"type": "component",
"homepage": "https://select2.org/",
"license": "MIT",
- "require": {
- "robloach/component-installer": "*"
- },
"extra": {
"component": {
"scripts": [
diff --git a/htdocs/includes/jquery/plugins/select2/dist/css/select2.css b/htdocs/includes/jquery/plugins/select2/dist/css/select2.css
index 447b2b86cc0..750b3207aeb 100644
--- a/htdocs/includes/jquery/plugins/select2/dist/css/select2.css
+++ b/htdocs/includes/jquery/plugins/select2/dist/css/select2.css
@@ -118,12 +118,14 @@
.select2-hidden-accessible {
border: 0 !important;
clip: rect(0 0 0 0) !important;
+ -webkit-clip-path: inset(50%) !important;
+ clip-path: inset(50%) !important;
height: 1px !important;
- margin: -1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
- width: 1px !important; }
+ width: 1px !important;
+ white-space: nowrap !important; }
.select2-container--default .select2-selection--single {
background-color: #fff;
@@ -186,16 +188,13 @@
width: 100%; }
.select2-container--default .select2-selection--multiple .select2-selection__rendered li {
list-style: none; }
- .select2-container--default .select2-selection--multiple .select2-selection__placeholder {
- color: #999;
- margin-top: 5px;
- float: left; }
.select2-container--default .select2-selection--multiple .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
margin-top: 5px;
- margin-right: 10px; }
+ margin-right: 10px;
+ padding: 1px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
@@ -214,7 +213,7 @@
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #333; }
-.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
+.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
float: right; }
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
@@ -420,9 +419,7 @@
color: #555; }
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
- float: right; }
-
-.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
+ float: right;
margin-left: 5px;
margin-right: auto; }
diff --git a/htdocs/includes/jquery/plugins/select2/dist/css/select2.min.css b/htdocs/includes/jquery/plugins/select2/dist/css/select2.min.css
index 76de04d9233..7c18ad59dfc 100644
--- a/htdocs/includes/jquery/plugins/select2/dist/css/select2.min.css
+++ b/htdocs/includes/jquery/plugins/select2/dist/css/select2.min.css
@@ -1 +1 @@
-.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}
+.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px;padding:1px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/af.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/af.js
new file mode 100644
index 00000000000..32e5ac7de89
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/af.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/af",[],function(){return{errorLoading:function(){return"Die resultate kon nie gelaai word nie."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Verwyders asseblief "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Voer asseblief "+(e.minimum-e.input.length)+" of meer karakters"},loadingMore:function(){return"Meer resultate word gelaai…"},maximumSelected:function(e){var n="Kies asseblief net "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"Geen resultate gevind"},searching:function(){return"Besig…"},removeAllItems:function(){return"Verwyder alle items"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ar.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ar.js
new file mode 100644
index 00000000000..64e1caad34d
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ar.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ar",[],function(){return{errorLoading:function(){return"لا يمكن تحميل النتائج"},inputTooLong:function(n){return"الرجاء حذف "+(n.input.length-n.maximum)+" عناصر"},inputTooShort:function(n){return"الرجاء إضافة "+(n.minimum-n.input.length)+" عناصر"},loadingMore:function(){return"جاري تحميل نتائج إضافية..."},maximumSelected:function(n){return"تستطيع إختيار "+n.maximum+" بنود فقط"},noResults:function(){return"لم يتم العثور على أي نتائج"},searching:function(){return"جاري البحث…"},removeAllItems:function(){return"قم بإزالة كل العناصر"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/az.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/az.js
new file mode 100644
index 00000000000..1d52c260f29
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/az.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/az",[],function(){return{inputTooLong:function(n){return n.input.length-n.maximum+" simvol silin"},inputTooShort:function(n){return n.minimum-n.input.length+" simvol daxil edin"},loadingMore:function(){return"Daha çox nəticə yüklənir…"},maximumSelected:function(n){return"Sadəcə "+n.maximum+" element seçə bilərsiniz"},noResults:function(){return"Nəticə tapılmadı"},searching:function(){return"Axtarılır…"},removeAllItems:function(){return"Bütün elementləri sil"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/bg.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/bg.js
new file mode 100644
index 00000000000..73b730a705a
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/bg.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bg",[],function(){return{inputTooLong:function(n){var e=n.input.length-n.maximum,u="Моля въведете с "+e+" по-малко символ";return e>1&&(u+="a"),u},inputTooShort:function(n){var e=n.minimum-n.input.length,u="Моля въведете още "+e+" символ";return e>1&&(u+="a"),u},loadingMore:function(){return"Зареждат се още…"},maximumSelected:function(n){var e="Можете да направите до "+n.maximum+" ";return n.maximum>1?e+="избора":e+="избор",e},noResults:function(){return"Няма намерени съвпадения"},searching:function(){return"Търсене…"},removeAllItems:function(){return"Премахнете всички елементи"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/bn.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/bn.js
new file mode 100644
index 00000000000..2d17b9d8e05
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/bn.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bn",[],function(){return{errorLoading:function(){return"ফলাফলগুলি লোড করা যায়নি।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।";return 1!=e&&(u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।"),u},inputTooShort:function(n){return n.minimum-n.input.length+" টি অক্ষর অথবা অধিক অক্ষর লিখুন।"},loadingMore:function(){return"আরো ফলাফল লোড হচ্ছে ..."},maximumSelected:function(n){var e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।";return 1!=n.maximum&&(e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।"),e},noResults:function(){return"কোন ফলাফল পাওয়া যায়নি।"},searching:function(){return"অনুসন্ধান করা হচ্ছে ..."}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/bs.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/bs.js
new file mode 100644
index 00000000000..46b084d7583
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/bs.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/bs",[],function(){function e(e,n,r,t){return e%10==1&&e%100!=11?n:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspijelo."},inputTooLong:function(n){var r=n.input.length-n.maximum,t="Obrišite "+r+" simbol";return t+=e(r,"","a","a")},inputTooShort:function(n){var r=n.minimum-n.input.length,t="Ukucajte bar još "+r+" simbol";return t+=e(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(n){var r="Možete izabrati samo "+n.maximum+" stavk";return r+=e(n.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Uklonite sve stavke"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ca.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ca.js
new file mode 100644
index 00000000000..82dbbb7a212
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ca.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ca",[],function(){return{errorLoading:function(){return"La càrrega ha fallat"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Si us plau, elimina "+n+" car";return r+=1==n?"àcter":"àcters"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Si us plau, introdueix "+n+" car";return r+=1==n?"àcter":"àcters"},loadingMore:function(){return"Carregant més resultats…"},maximumSelected:function(e){var n="Només es pot seleccionar "+e.maximum+" element";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No s'han trobat resultats"},searching:function(){return"Cercant…"},removeAllItems:function(){return"Treu tots els elements"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/cs.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/cs.js
new file mode 100644
index 00000000000..7116d6c1dfd
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/cs.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/cs",[],function(){function e(e,n){switch(e){case 2:return n?"dva":"dvě";case 3:return"tři";case 4:return"čtyři"}return""}return{errorLoading:function(){return"Výsledky nemohly být načteny."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadejte o jeden znak méně.":t<=4?"Prosím, zadejte o "+e(t,!0)+" znaky méně.":"Prosím, zadejte o "+t+" znaků méně."},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadejte ještě jeden znak.":t<=4?"Prosím, zadejte ještě další "+e(t,!0)+" znaky.":"Prosím, zadejte ještě dalších "+t+" znaků."},loadingMore:function(){return"Načítají se další výsledky…"},maximumSelected:function(n){var t=n.maximum;return 1==t?"Můžete zvolit jen jednu položku.":t<=4?"Můžete zvolit maximálně "+e(t,!1)+" položky.":"Můžete zvolit maximálně "+t+" položek."},noResults:function(){return"Nenalezeny žádné položky."},searching:function(){return"Vyhledávání…"},removeAllItems:function(){return"Odstraňte všechny položky"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/da.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/da.js
new file mode 100644
index 00000000000..cda32c34aaa
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/da.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/da",[],function(){return{errorLoading:function(){return"Resultaterne kunne ikke indlæses."},inputTooLong:function(e){return"Angiv venligst "+(e.input.length-e.maximum)+" tegn mindre"},inputTooShort:function(e){return"Angiv venligst "+(e.minimum-e.input.length)+" tegn mere"},loadingMore:function(){return"Indlæser flere resultater…"},maximumSelected:function(e){var n="Du kan kun vælge "+e.maximum+" emne";return 1!=e.maximum&&(n+="r"),n},noResults:function(){return"Ingen resultater fundet"},searching:function(){return"Søger…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/de.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/de.js
new file mode 100644
index 00000000000..c2e61e5800b
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/de.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/de",[],function(){return{errorLoading:function(){return"Die Ergebnisse konnten nicht geladen werden."},inputTooLong:function(e){return"Bitte "+(e.input.length-e.maximum)+" Zeichen weniger eingeben"},inputTooShort:function(e){return"Bitte "+(e.minimum-e.input.length)+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var n="Sie können nur "+e.maximum+" Element";return 1!=e.maximum&&(n+="e"),n+=" auswählen"},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"},removeAllItems:function(){return"Entferne alle Elemente"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/dsb.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/dsb.js
new file mode 100644
index 00000000000..02f283abada
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/dsb.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/dsb",[],function(){var n=["znamuško","znamušce","znamuška","znamuškow"],e=["zapisk","zapiska","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njejsu se dali zacytaś."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Pšosym lašuj "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Pšosym zapódaj nanejmjenjej "+a+" "+u(a,n)},loadingMore:function(){return"Dalšne wuslědki se zacytaju…"},maximumSelected:function(n){return"Móžoš jano "+n.maximum+" "+u(n.maximum,e)+"wubraś."},noResults:function(){return"Žedne wuslědki namakane"},searching:function(){return"Pyta se…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/el.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/el.js
new file mode 100644
index 00000000000..d4922a1df5b
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/el.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(n){var e=n.input.length-n.maximum,u="Παρακαλώ διαγράψτε "+e+" χαρακτήρ";return 1==e&&(u+="α"),1!=e&&(u+="ες"),u},inputTooShort:function(n){return"Παρακαλώ συμπληρώστε "+(n.minimum-n.input.length)+" ή περισσότερους χαρακτήρες"},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(n){var e="Μπορείτε να επιλέξετε μόνο "+n.maximum+" επιλογ";return 1==n.maximum&&(e+="ή"),1!=n.maximum&&(e+="ές"),e},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"},removeAllItems:function(){return"Καταργήστε όλα τα στοιχεία"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/en.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/en.js
new file mode 100644
index 00000000000..3b192857342
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/en.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Please delete "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Please enter "+(e.minimum-e.input.length)+" or more characters"},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var n="You can only select "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No results found"},searching:function(){return"Searching…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/es.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/es.js
new file mode 100644
index 00000000000..68afd6d2592
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/es.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/es",[],function(){return{errorLoading:function(){return"No se pudieron cargar los resultados"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Por favor, elimine "+n+" car";return r+=1==n?"ácter":"acteres"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Por favor, introduzca "+n+" car";return r+=1==n?"ácter":"acteres"},loadingMore:function(){return"Cargando más resultados…"},maximumSelected:function(e){var n="Sólo puede seleccionar "+e.maximum+" elemento";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No se encontraron resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Eliminar todos los elementos"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/et.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/et.js
new file mode 100644
index 00000000000..070b61a26dd
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/et.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/et",[],function(){return{inputTooLong:function(e){var n=e.input.length-e.maximum,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" vähem"},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" rohkem"},loadingMore:function(){return"Laen tulemusi…"},maximumSelected:function(e){var n="Saad vaid "+e.maximum+" tulemus";return 1==e.maximum?n+="e":n+="t",n+=" valida"},noResults:function(){return"Tulemused puuduvad"},searching:function(){return"Otsin…"},removeAllItems:function(){return"Eemalda kõik esemed"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/eu.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/eu.js
new file mode 100644
index 00000000000..90d5e73f8a8
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/eu.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/eu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gutxiago"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gehiago"},loadingMore:function(){return"Emaitza gehiago kargatzen…"},maximumSelected:function(e){return 1===e.maximum?"Elementu bakarra hauta dezakezu":e.maximum+" elementu hauta ditzakezu soilik"},noResults:function(){return"Ez da bat datorrenik aurkitu"},searching:function(){return"Bilatzen…"},removeAllItems:function(){return"Kendu elementu guztiak"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/fa.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/fa.js
new file mode 100644
index 00000000000..e1ffdbed0d8
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/fa.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fa",[],function(){return{errorLoading:function(){return"امکان بارگذاری نتایج وجود ندارد."},inputTooLong:function(n){return"لطفاً "+(n.input.length-n.maximum)+" کاراکتر را حذف نمایید"},inputTooShort:function(n){return"لطفاً تعداد "+(n.minimum-n.input.length)+" کاراکتر یا بیشتر وارد نمایید"},loadingMore:function(){return"در حال بارگذاری نتایج بیشتر..."},maximumSelected:function(n){return"شما تنها میتوانید "+n.maximum+" آیتم را انتخاب نمایید"},noResults:function(){return"هیچ نتیجهای یافت نشد"},searching:function(){return"در حال جستجو..."},removeAllItems:function(){return"همه موارد را حذف کنید"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/fi.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/fi.js
new file mode 100644
index 00000000000..ffed1247dd0
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/fi.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fi",[],function(){return{errorLoading:function(){return"Tuloksia ei saatu ladattua."},inputTooLong:function(n){return"Ole hyvä ja anna "+(n.input.length-n.maximum)+" merkkiä vähemmän"},inputTooShort:function(n){return"Ole hyvä ja anna "+(n.minimum-n.input.length)+" merkkiä lisää"},loadingMore:function(){return"Ladataan lisää tuloksia…"},maximumSelected:function(n){return"Voit valita ainoastaan "+n.maximum+" kpl"},noResults:function(){return"Ei tuloksia"},searching:function(){return"Haetaan…"},removeAllItems:function(){return"Poista kaikki kohteet"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/fr.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/fr.js
new file mode 100644
index 00000000000..dd02f973ffa
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/fr.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/fr",[],function(){return{errorLoading:function(){return"Les résultats ne peuvent pas être chargés."},inputTooLong:function(e){var n=e.input.length-e.maximum;return"Supprimez "+n+" caractère"+(n>1?"s":"")},inputTooShort:function(e){var n=e.minimum-e.input.length;return"Saisissez au moins "+n+" caractère"+(n>1?"s":"")},loadingMore:function(){return"Chargement de résultats supplémentaires…"},maximumSelected:function(e){return"Vous pouvez seulement sélectionner "+e.maximum+" élément"+(e.maximum>1?"s":"")},noResults:function(){return"Aucun résultat trouvé"},searching:function(){return"Recherche en cours…"},removeAllItems:function(){return"Supprimer tous les éléments"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/gl.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/gl.js
new file mode 100644
index 00000000000..208a0057057
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/gl.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/gl",[],function(){return{errorLoading:function(){return"Non foi posíbel cargar os resultados."},inputTooLong:function(e){var n=e.input.length-e.maximum;return 1===n?"Elimine un carácter":"Elimine "+n+" caracteres"},inputTooShort:function(e){var n=e.minimum-e.input.length;return 1===n?"Engada un carácter":"Engada "+n+" caracteres"},loadingMore:function(){return"Cargando máis resultados…"},maximumSelected:function(e){return 1===e.maximum?"Só pode seleccionar un elemento":"Só pode seleccionar "+e.maximum+" elementos"},noResults:function(){return"Non se atoparon resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Elimina todos os elementos"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/he.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/he.js
new file mode 100644
index 00000000000..25a8805aa02
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/he.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/he",[],function(){return{errorLoading:function(){return"שגיאה בטעינת התוצאות"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="נא למחוק ";return r+=1===e?"תו אחד":e+" תווים"},inputTooShort:function(n){var e=n.minimum-n.input.length,r="נא להכניס ";return r+=1===e?"תו אחד":e+" תווים",r+=" או יותר"},loadingMore:function(){return"טוען תוצאות נוספות…"},maximumSelected:function(n){var e="באפשרותך לבחור עד ";return 1===n.maximum?e+="פריט אחד":e+=n.maximum+" פריטים",e},noResults:function(){return"לא נמצאו תוצאות"},searching:function(){return"מחפש…"},removeAllItems:function(){return"הסר את כל הפריטים"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hi.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hi.js
new file mode 100644
index 00000000000..f3ed798434b
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hi.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hi",[],function(){return{errorLoading:function(){return"परिणामों को लोड नहीं किया जा सका।"},inputTooLong:function(n){var e=n.input.length-n.maximum,r=e+" अक्षर को हटा दें";return e>1&&(r=e+" अक्षरों को हटा दें "),r},inputTooShort:function(n){return"कृपया "+(n.minimum-n.input.length)+" या अधिक अक्षर दर्ज करें"},loadingMore:function(){return"अधिक परिणाम लोड हो रहे है..."},maximumSelected:function(n){return"आप केवल "+n.maximum+" आइटम का चयन कर सकते हैं"},noResults:function(){return"कोई परिणाम नहीं मिला"},searching:function(){return"खोज रहा है..."},removeAllItems:function(){return"सभी वस्तुओं को हटा दें"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hr.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hr.js
new file mode 100644
index 00000000000..cb3268db161
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hr.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hr",[],function(){function n(n){var e=" "+n+" znak";return n%10<5&&n%10>0&&(n%100<5||n%100>19)?n%10>1&&(e+="a"):e+="ova",e}return{errorLoading:function(){return"Preuzimanje nije uspjelo."},inputTooLong:function(e){return"Unesite "+n(e.input.length-e.maximum)},inputTooShort:function(e){return"Unesite još "+n(e.minimum-e.input.length)},loadingMore:function(){return"Učitavanje rezultata…"},maximumSelected:function(n){return"Maksimalan broj odabranih stavki je "+n.maximum},noResults:function(){return"Nema rezultata"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Ukloni sve stavke"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hsb.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hsb.js
new file mode 100644
index 00000000000..3d5bf09dbd5
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hsb.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hsb",[],function(){var n=["znamješko","znamješce","znamješka","znamješkow"],e=["zapisk","zapiskaj","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njedachu so začitać."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Prošu zhašej "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Prošu zapodaj znajmjeńša "+a+" "+u(a,n)},loadingMore:function(){return"Dalše wuslědki so začitaja…"},maximumSelected:function(n){return"Móžeš jenož "+n.maximum+" "+u(n.maximum,e)+"wubrać"},noResults:function(){return"Žane wuslědki namakane"},searching:function(){return"Pyta so…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hu.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hu.js
new file mode 100644
index 00000000000..4893aa2f70d
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hu.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/hu",[],function(){return{errorLoading:function(){return"Az eredmények betöltése nem sikerült."},inputTooLong:function(e){return"Túl hosszú. "+(e.input.length-e.maximum)+" karakterrel több, mint kellene."},inputTooShort:function(e){return"Túl rövid. Még "+(e.minimum-e.input.length)+" karakter hiányzik."},loadingMore:function(){return"Töltés…"},maximumSelected:function(e){return"Csak "+e.maximum+" elemet lehet kiválasztani."},noResults:function(){return"Nincs találat."},searching:function(){return"Keresés…"},removeAllItems:function(){return"Távolítson el minden elemet"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hy.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hy.js
new file mode 100644
index 00000000000..8230007141a
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/hy.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hy",[],function(){return{errorLoading:function(){return"Արդյունքները հնարավոր չէ բեռնել։"},inputTooLong:function(n){return"Խնդրում ենք հեռացնել "+(n.input.length-n.maximum)+" նշան"},inputTooShort:function(n){return"Խնդրում ենք մուտքագրել "+(n.minimum-n.input.length)+" կամ ավել նշաններ"},loadingMore:function(){return"Բեռնվում են նոր արդյունքներ․․․"},maximumSelected:function(n){return"Դուք կարող եք ընտրել առավելագույնը "+n.maximum+" կետ"},noResults:function(){return"Արդյունքներ չեն գտնվել"},searching:function(){return"Որոնում․․․"},removeAllItems:function(){return"Հեռացնել բոլոր տարրերը"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/id.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/id.js
new file mode 100644
index 00000000000..4a0b3bf009d
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/id.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/id",[],function(){return{errorLoading:function(){return"Data tidak boleh diambil."},inputTooLong:function(n){return"Hapuskan "+(n.input.length-n.maximum)+" huruf"},inputTooShort:function(n){return"Masukkan "+(n.minimum-n.input.length)+" huruf lagi"},loadingMore:function(){return"Mengambil data…"},maximumSelected:function(n){return"Anda hanya dapat memilih "+n.maximum+" pilihan"},noResults:function(){return"Tidak ada data yang sesuai"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Hapus semua item"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/is.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/is.js
new file mode 100644
index 00000000000..cca5bbecf02
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/is.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/is",[],function(){return{inputTooLong:function(n){var t=n.input.length-n.maximum,e="Vinsamlegast styttið texta um "+t+" staf";return t<=1?e:e+"i"},inputTooShort:function(n){var t=n.minimum-n.input.length,e="Vinsamlegast skrifið "+t+" staf";return t>1&&(e+="i"),e+=" í viðbót"},loadingMore:function(){return"Sæki fleiri niðurstöður…"},maximumSelected:function(n){return"Þú getur aðeins valið "+n.maximum+" atriði"},noResults:function(){return"Ekkert fannst"},searching:function(){return"Leita…"},removeAllItems:function(){return"Fjarlægðu öll atriði"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/it.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/it.js
new file mode 100644
index 00000000000..507c7d9f293
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/it.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/it",[],function(){return{errorLoading:function(){return"I risultati non possono essere caricati."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Per favore cancella "+n+" caratter";return t+=1!==n?"i":"e"},inputTooShort:function(e){return"Per favore inserisci "+(e.minimum-e.input.length)+" o più caratteri"},loadingMore:function(){return"Caricando più risultati…"},maximumSelected:function(e){var n="Puoi selezionare solo "+e.maximum+" element";return 1!==e.maximum?n+="i":n+="o",n},noResults:function(){return"Nessun risultato trovato"},searching:function(){return"Sto cercando…"},removeAllItems:function(){return"Rimuovi tutti gli oggetti"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ja.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ja.js
new file mode 100644
index 00000000000..451025e2c7d
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ja.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ja",[],function(){return{errorLoading:function(){return"結果が読み込まれませんでした"},inputTooLong:function(n){return n.input.length-n.maximum+" 文字を削除してください"},inputTooShort:function(n){return"少なくとも "+(n.minimum-n.input.length)+" 文字を入力してください"},loadingMore:function(){return"読み込み中…"},maximumSelected:function(n){return n.maximum+" 件しか選択できません"},noResults:function(){return"対象が見つかりません"},searching:function(){return"検索しています…"},removeAllItems:function(){return"すべてのアイテムを削除"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ka.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ka.js
new file mode 100644
index 00000000000..60c593b705d
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ka.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ka",[],function(){return{errorLoading:function(){return"მონაცემების ჩატვირთვა შეუძლებელია."},inputTooLong:function(n){return"გთხოვთ აკრიფეთ "+(n.input.length-n.maximum)+" სიმბოლოთი ნაკლები"},inputTooShort:function(n){return"გთხოვთ აკრიფეთ "+(n.minimum-n.input.length)+" სიმბოლო ან მეტი"},loadingMore:function(){return"მონაცემების ჩატვირთვა…"},maximumSelected:function(n){return"თქვენ შეგიძლიათ აირჩიოთ არაუმეტეს "+n.maximum+" ელემენტი"},noResults:function(){return"რეზულტატი არ მოიძებნა"},searching:function(){return"ძიება…"},removeAllItems:function(){return"ამოიღე ყველა ელემენტი"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/km.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/km.js
new file mode 100644
index 00000000000..4dca94f414e
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/km.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/km",[],function(){return{errorLoading:function(){return"មិនអាចទាញយកទិន្នន័យ"},inputTooLong:function(n){return"សូមលុបចេញ "+(n.input.length-n.maximum)+" អក្សរ"},inputTooShort:function(n){return"សូមបញ្ចូល"+(n.minimum-n.input.length)+" អក្សរ រឺ ច្រើនជាងនេះ"},loadingMore:function(){return"កំពុងទាញយកទិន្នន័យបន្ថែម..."},maximumSelected:function(n){return"អ្នកអាចជ្រើសរើសបានតែ "+n.maximum+" ជម្រើសប៉ុណ្ណោះ"},noResults:function(){return"មិនមានលទ្ធផល"},searching:function(){return"កំពុងស្វែងរក..."},removeAllItems:function(){return"លុបធាតុទាំងអស់"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ko.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ko.js
new file mode 100644
index 00000000000..f2880fb0043
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ko.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ko",[],function(){return{errorLoading:function(){return"결과를 불러올 수 없습니다."},inputTooLong:function(n){return"너무 깁니다. "+(n.input.length-n.maximum)+" 글자 지워주세요."},inputTooShort:function(n){return"너무 짧습니다. "+(n.minimum-n.input.length)+" 글자 더 입력해주세요."},loadingMore:function(){return"불러오는 중…"},maximumSelected:function(n){return"최대 "+n.maximum+"개까지만 선택 가능합니다."},noResults:function(){return"결과가 없습니다."},searching:function(){return"검색 중…"},removeAllItems:function(){return"모든 항목 삭제"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/lt.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/lt.js
new file mode 100644
index 00000000000..f6a42155ad8
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/lt.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/lt",[],function(){function n(n,e,i,t){return n%10==1&&(n%100<11||n%100>19)?e:n%10>=2&&n%10<=9&&(n%100<11||n%100>19)?i:t}return{inputTooLong:function(e){var i=e.input.length-e.maximum,t="Pašalinkite "+i+" simbol";return t+=n(i,"į","ius","ių")},inputTooShort:function(e){var i=e.minimum-e.input.length,t="Įrašykite dar "+i+" simbol";return t+=n(i,"į","ius","ių")},loadingMore:function(){return"Kraunama daugiau rezultatų…"},maximumSelected:function(e){var i="Jūs galite pasirinkti tik "+e.maximum+" element";return i+=n(e.maximum,"ą","us","ų")},noResults:function(){return"Atitikmenų nerasta"},searching:function(){return"Ieškoma…"},removeAllItems:function(){return"Pašalinti visus elementus"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/lv.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/lv.js
new file mode 100644
index 00000000000..806dc5c4339
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/lv.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/lv",[],function(){function e(e,n,u,i){return 11===e?n:e%10==1?u:i}return{inputTooLong:function(n){var u=n.input.length-n.maximum,i="Lūdzu ievadiet par "+u;return(i+=" simbol"+e(u,"iem","u","iem"))+" mazāk"},inputTooShort:function(n){var u=n.minimum-n.input.length,i="Lūdzu ievadiet vēl "+u;return i+=" simbol"+e(u,"us","u","us")},loadingMore:function(){return"Datu ielāde…"},maximumSelected:function(n){var u="Jūs varat izvēlēties ne vairāk kā "+n.maximum;return u+=" element"+e(n.maximum,"us","u","us")},noResults:function(){return"Sakritību nav"},searching:function(){return"Meklēšana…"},removeAllItems:function(){return"Noņemt visus vienumus"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/mk.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/mk.js
new file mode 100644
index 00000000000..cb7b84a2634
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/mk.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/mk",[],function(){return{inputTooLong:function(n){var e=(n.input.length,n.maximum,"Ве молиме внесете "+n.maximum+" помалку карактер");return 1!==n.maximum&&(e+="и"),e},inputTooShort:function(n){var e=(n.minimum,n.input.length,"Ве молиме внесете уште "+n.maximum+" карактер");return 1!==n.maximum&&(e+="и"),e},loadingMore:function(){return"Вчитување резултати…"},maximumSelected:function(n){var e="Можете да изберете само "+n.maximum+" ставк";return 1===n.maximum?e+="а":e+="и",e},noResults:function(){return"Нема пронајдено совпаѓања"},searching:function(){return"Пребарување…"},removeAllItems:function(){return"Отстрани ги сите предмети"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ms.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ms.js
new file mode 100644
index 00000000000..6bd7eaa3e02
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ms.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ms",[],function(){return{errorLoading:function(){return"Keputusan tidak berjaya dimuatkan."},inputTooLong:function(n){return"Sila hapuskan "+(n.input.length-n.maximum)+" aksara"},inputTooShort:function(n){return"Sila masukkan "+(n.minimum-n.input.length)+" atau lebih aksara"},loadingMore:function(){return"Sedang memuatkan keputusan…"},maximumSelected:function(n){return"Anda hanya boleh memilih "+n.maximum+" pilihan"},noResults:function(){return"Tiada padanan yang ditemui"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Keluarkan semua item"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/nb.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/nb.js
new file mode 100644
index 00000000000..25d89c68704
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/nb.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nb",[],function(){return{errorLoading:function(){return"Kunne ikke hente resultater."},inputTooLong:function(e){return"Vennligst fjern "+(e.input.length-e.maximum)+" tegn"},inputTooShort:function(e){return"Vennligst skriv inn "+(e.minimum-e.input.length)+" tegn til"},loadingMore:function(){return"Laster flere resultater…"},maximumSelected:function(e){return"Du kan velge maks "+e.maximum+" elementer"},noResults:function(){return"Ingen treff"},searching:function(){return"Søker…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ne.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ne.js
new file mode 100644
index 00000000000..1c39f672103
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ne.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ne",[],function(){return{errorLoading:function(){return"नतिजाहरु देखाउन सकिएन।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="कृपया "+e+" अक्षर मेटाउनुहोस्।";return 1!=e&&(u+="कृपया "+e+" अक्षरहरु मेटाउनुहोस्।"),u},inputTooShort:function(n){return"कृपया बाँकी रहेका "+(n.minimum-n.input.length)+" वा अरु धेरै अक्षरहरु भर्नुहोस्।"},loadingMore:function(){return"अरु नतिजाहरु भरिँदैछन् …"},maximumSelected:function(n){var e="तँपाई "+n.maximum+" वस्तु मात्र छान्न पाउँनुहुन्छ।";return 1!=n.maximum&&(e="तँपाई "+n.maximum+" वस्तुहरु मात्र छान्न पाउँनुहुन्छ।"),e},noResults:function(){return"कुनै पनि नतिजा भेटिएन।"},searching:function(){return"खोजि हुँदैछ…"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/nl.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/nl.js
new file mode 100644
index 00000000000..2b74058d237
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/nl.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nl",[],function(){return{errorLoading:function(){return"De resultaten konden niet worden geladen."},inputTooLong:function(e){return"Gelieve "+(e.input.length-e.maximum)+" karakters te verwijderen"},inputTooShort:function(e){return"Gelieve "+(e.minimum-e.input.length)+" of meer karakters in te voeren"},loadingMore:function(){return"Meer resultaten laden…"},maximumSelected:function(e){var n=1==e.maximum?"kan":"kunnen",r="Er "+n+" maar "+e.maximum+" item";return 1!=e.maximum&&(r+="s"),r+=" worden geselecteerd"},noResults:function(){return"Geen resultaten gevonden…"},searching:function(){return"Zoeken…"},removeAllItems:function(){return"Verwijder alle items"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/pl.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/pl.js
new file mode 100644
index 00000000000..4ca5748c386
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/pl.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/pl",[],function(){var n=["znak","znaki","znaków"],e=["element","elementy","elementów"],r=function(n,e){return 1===n?e[0]:n>1&&n<=4?e[1]:n>=5?e[2]:void 0};return{errorLoading:function(){return"Nie można załadować wyników."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Usuń "+t+" "+r(t,n)},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Podaj przynajmniej "+t+" "+r(t,n)},loadingMore:function(){return"Trwa ładowanie…"},maximumSelected:function(n){return"Możesz zaznaczyć tylko "+n.maximum+" "+r(n.maximum,e)},noResults:function(){return"Brak wyników"},searching:function(){return"Trwa wyszukiwanie…"},removeAllItems:function(){return"Usuń wszystkie przedmioty"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ps.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ps.js
new file mode 100644
index 00000000000..9b008e4c145
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ps.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ps",[],function(){return{errorLoading:function(){return"پايلي نه سي ترلاسه کېدای"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="د مهربانۍ لمخي "+e+" توری ړنګ کړئ";return 1!=e&&(r=r.replace("توری","توري")),r},inputTooShort:function(n){return"لږ تر لږه "+(n.minimum-n.input.length)+" يا ډېر توري وليکئ"},loadingMore:function(){return"نوري پايلي ترلاسه کيږي..."},maximumSelected:function(n){var e="تاسو يوازي "+n.maximum+" قلم په نښه کولای سی";return 1!=n.maximum&&(e=e.replace("قلم","قلمونه")),e},noResults:function(){return"پايلي و نه موندل سوې"},searching:function(){return"لټول کيږي..."},removeAllItems:function(){return"ټول توکي لرې کړئ"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/pt-BR.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/pt-BR.js
new file mode 100644
index 00000000000..c991e2550ae
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/pt-BR.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt-BR",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Apague "+n+" caracter";return 1!=n&&(r+="es"),r},inputTooShort:function(e){return"Digite "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"Carregando mais resultados…"},maximumSelected:function(e){var n="Você só pode selecionar "+e.maximum+" ite";return 1==e.maximum?n+="m":n+="ns",n},noResults:function(){return"Nenhum resultado encontrado"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/pt.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/pt.js
new file mode 100644
index 00000000000..b5da1a6b496
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/pt.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var r=e.input.length-e.maximum,n="Por favor apague "+r+" ";return n+=1!=r?"caracteres":"caractere"},inputTooShort:function(e){return"Introduza "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"A carregar mais resultados…"},maximumSelected:function(e){var r="Apenas pode seleccionar "+e.maximum+" ";return r+=1!=e.maximum?"itens":"item"},noResults:function(){return"Sem resultados"},searching:function(){return"A procurar…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ro.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ro.js
new file mode 100644
index 00000000000..1ba7b40bef7
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ro.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ro",[],function(){return{errorLoading:function(){return"Rezultatele nu au putut fi incărcate."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vă rugăm să ștergeți"+t+" caracter";return 1!==t&&(n+="e"),n},inputTooShort:function(e){return"Vă rugăm să introduceți "+(e.minimum-e.input.length)+" sau mai multe caractere"},loadingMore:function(){return"Se încarcă mai multe rezultate…"},maximumSelected:function(e){var t="Aveți voie să selectați cel mult "+e.maximum;return t+=" element",1!==e.maximum&&(t+="e"),t},noResults:function(){return"Nu au fost găsite rezultate"},searching:function(){return"Căutare…"},removeAllItems:function(){return"Eliminați toate elementele"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ru.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ru.js
new file mode 100644
index 00000000000..63a7d66c3b4
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/ru.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ru",[],function(){function n(n,e,r,u){return n%10<5&&n%10>0&&n%100<5||n%100>20?n%10>1?r:e:u}return{errorLoading:function(){return"Невозможно загрузить результаты"},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Пожалуйста, введите на "+r+" символ";return u+=n(r,"","a","ов"),u+=" меньше"},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Пожалуйста, введите ещё хотя бы "+r+" символ";return u+=n(r,"","a","ов")},loadingMore:function(){return"Загрузка данных…"},maximumSelected:function(e){var r="Вы можете выбрать не более "+e.maximum+" элемент";return r+=n(e.maximum,"","a","ов")},noResults:function(){return"Совпадений не найдено"},searching:function(){return"Поиск…"},removeAllItems:function(){return"Удалить все элементы"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sk.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sk.js
new file mode 100644
index 00000000000..5049528ad0d
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sk.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sk",[],function(){var e={2:function(e){return e?"dva":"dve"},3:function(){return"tri"},4:function(){return"štyri"}};return{errorLoading:function(){return"Výsledky sa nepodarilo načítať."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadajte o jeden znak menej":t>=2&&t<=4?"Prosím, zadajte o "+e[t](!0)+" znaky menej":"Prosím, zadajte o "+t+" znakov menej"},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadajte ešte jeden znak":t<=4?"Prosím, zadajte ešte ďalšie "+e[t](!0)+" znaky":"Prosím, zadajte ešte ďalších "+t+" znakov"},loadingMore:function(){return"Načítanie ďalších výsledkov…"},maximumSelected:function(n){return 1==n.maximum?"Môžete zvoliť len jednu položku":n.maximum>=2&&n.maximum<=4?"Môžete zvoliť najviac "+e[n.maximum](!1)+" položky":"Môžete zvoliť najviac "+n.maximum+" položiek"},noResults:function(){return"Nenašli sa žiadne položky"},searching:function(){return"Vyhľadávanie…"},removeAllItems:function(){return"Odstráňte všetky položky"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sl.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sl.js
new file mode 100644
index 00000000000..4d0b7d3e345
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sl.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sl",[],function(){return{errorLoading:function(){return"Zadetkov iskanja ni bilo mogoče naložiti."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Prosim zbrišite "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Prosim vpišite še "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},loadingMore:function(){return"Nalagam več zadetkov…"},maximumSelected:function(e){var n="Označite lahko največ "+e.maximum+" predmet";return 2==e.maximum?n+="a":1!=e.maximum&&(n+="e"),n},noResults:function(){return"Ni zadetkov."},searching:function(){return"Iščem…"},removeAllItems:function(){return"Odstranite vse elemente"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sq.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sq.js
new file mode 100644
index 00000000000..59162024ed3
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sq.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sq",[],function(){return{errorLoading:function(){return"Rezultatet nuk mund të ngarkoheshin."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Të lutem fshi "+n+" karakter";return 1!=n&&(t+="e"),t},inputTooShort:function(e){return"Të lutem shkruaj "+(e.minimum-e.input.length)+" ose më shumë karaktere"},loadingMore:function(){return"Duke ngarkuar më shumë rezultate…"},maximumSelected:function(e){var n="Mund të zgjedhësh vetëm "+e.maximum+" element";return 1!=e.maximum&&(n+="e"),n},noResults:function(){return"Nuk u gjet asnjë rezultat"},searching:function(){return"Duke kërkuar…"},removeAllItems:function(){return"Hiq të gjitha sendet"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sr-Cyrl.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sr-Cyrl.js
new file mode 100644
index 00000000000..ce13ce8f9a1
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sr-Cyrl.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sr-Cyrl",[],function(){function n(n,e,r,u){return n%10==1&&n%100!=11?e:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?r:u}return{errorLoading:function(){return"Преузимање није успело."},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Обришите "+r+" симбол";return u+=n(r,"","а","а")},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Укуцајте бар још "+r+" симбол";return u+=n(r,"","а","а")},loadingMore:function(){return"Преузимање још резултата…"},maximumSelected:function(e){var r="Можете изабрати само "+e.maximum+" ставк";return r+=n(e.maximum,"у","е","и")},noResults:function(){return"Ништа није пронађено"},searching:function(){return"Претрага…"},removeAllItems:function(){return"Уклоните све ставке"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sr.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sr.js
new file mode 100644
index 00000000000..dd407a06dc4
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sr.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sr",[],function(){function n(n,e,r,t){return n%10==1&&n%100!=11?e:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspelo."},inputTooLong:function(e){var r=e.input.length-e.maximum,t="Obrišite "+r+" simbol";return t+=n(r,"","a","a")},inputTooShort:function(e){var r=e.minimum-e.input.length,t="Ukucajte bar još "+r+" simbol";return t+=n(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(e){var r="Možete izabrati samo "+e.maximum+" stavk";return r+=n(e.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Уклоните све ставке"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sv.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sv.js
new file mode 100644
index 00000000000..1bc8724a79a
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/sv.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sv",[],function(){return{errorLoading:function(){return"Resultat kunde inte laddas."},inputTooLong:function(n){return"Vänligen sudda ut "+(n.input.length-n.maximum)+" tecken"},inputTooShort:function(n){return"Vänligen skriv in "+(n.minimum-n.input.length)+" eller fler tecken"},loadingMore:function(){return"Laddar fler resultat…"},maximumSelected:function(n){return"Du kan max välja "+n.maximum+" element"},noResults:function(){return"Inga träffar"},searching:function(){return"Söker…"},removeAllItems:function(){return"Ta bort alla objekt"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/th.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/th.js
new file mode 100644
index 00000000000..63eab7114b0
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/th.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/th",[],function(){return{errorLoading:function(){return"ไม่สามารถค้นข้อมูลได้"},inputTooLong:function(n){return"โปรดลบออก "+(n.input.length-n.maximum)+" ตัวอักษร"},inputTooShort:function(n){return"โปรดพิมพ์เพิ่มอีก "+(n.minimum-n.input.length)+" ตัวอักษร"},loadingMore:function(){return"กำลังค้นข้อมูลเพิ่ม…"},maximumSelected:function(n){return"คุณสามารถเลือกได้ไม่เกิน "+n.maximum+" รายการ"},noResults:function(){return"ไม่พบข้อมูล"},searching:function(){return"กำลังค้นข้อมูล…"},removeAllItems:function(){return"ลบรายการทั้งหมด"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/tk.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/tk.js
new file mode 100644
index 00000000000..30255ff3777
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/tk.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/tk",[],function(){return{errorLoading:function(){return"Netije ýüklenmedi."},inputTooLong:function(e){return e.input.length-e.maximum+" harp bozuň."},inputTooShort:function(e){return"Ýene-de iň az "+(e.minimum-e.input.length)+" harp ýazyň."},loadingMore:function(){return"Köpräk netije görkezilýär…"},maximumSelected:function(e){return"Diňe "+e.maximum+" sanysyny saýlaň."},noResults:function(){return"Netije tapylmady."},searching:function(){return"Gözlenýär…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/tr.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/tr.js
new file mode 100644
index 00000000000..fc4c0bf0512
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/tr.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/tr",[],function(){return{errorLoading:function(){return"Sonuç yüklenemedi"},inputTooLong:function(n){return n.input.length-n.maximum+" karakter daha girmelisiniz"},inputTooShort:function(n){return"En az "+(n.minimum-n.input.length)+" karakter daha girmelisiniz"},loadingMore:function(){return"Daha fazla…"},maximumSelected:function(n){return"Sadece "+n.maximum+" seçim yapabilirsiniz"},noResults:function(){return"Sonuç bulunamadı"},searching:function(){return"Aranıyor…"},removeAllItems:function(){return"Tüm öğeleri kaldır"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/uk.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/uk.js
new file mode 100644
index 00000000000..63697e38849
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/uk.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/uk",[],function(){function n(n,e,u,r){return n%100>10&&n%100<15?r:n%10==1?e:n%10>1&&n%10<5?u:r}return{errorLoading:function(){return"Неможливо завантажити результати"},inputTooLong:function(e){return"Будь ласка, видаліть "+(e.input.length-e.maximum)+" "+n(e.maximum,"літеру","літери","літер")},inputTooShort:function(n){return"Будь ласка, введіть "+(n.minimum-n.input.length)+" або більше літер"},loadingMore:function(){return"Завантаження інших результатів…"},maximumSelected:function(e){return"Ви можете вибрати лише "+e.maximum+" "+n(e.maximum,"пункт","пункти","пунктів")},noResults:function(){return"Нічого не знайдено"},searching:function(){return"Пошук…"},removeAllItems:function(){return"Видалити всі елементи"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/vi.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/vi.js
new file mode 100644
index 00000000000..24f3bc2d61a
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/vi.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/vi",[],function(){return{inputTooLong:function(n){return"Vui lòng xóa bớt "+(n.input.length-n.maximum)+" ký tự"},inputTooShort:function(n){return"Vui lòng nhập thêm từ "+(n.minimum-n.input.length)+" ký tự trở lên"},loadingMore:function(){return"Đang lấy thêm kết quả…"},maximumSelected:function(n){return"Chỉ có thể chọn được "+n.maximum+" lựa chọn"},noResults:function(){return"Không tìm thấy kết quả"},searching:function(){return"Đang tìm…"},removeAllItems:function(){return"Xóa tất cả các mục"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/zh-CN.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/zh-CN.js
new file mode 100644
index 00000000000..2c5649d3108
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/zh-CN.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(n){return"请删除"+(n.input.length-n.maximum)+"个字符"},inputTooShort:function(n){return"请再输入至少"+(n.minimum-n.input.length)+"个字符"},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(n){return"最多只能选择"+n.maximum+"个项目"},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"},removeAllItems:function(){return"删除所有项目"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/i18n/zh-TW.js b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/zh-TW.js
new file mode 100644
index 00000000000..570a5669374
--- /dev/null
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/i18n/zh-TW.js
@@ -0,0 +1,3 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+
+!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/zh-TW",[],function(){return{inputTooLong:function(n){return"請刪掉"+(n.input.length-n.maximum)+"個字元"},inputTooShort:function(n){return"請再輸入"+(n.minimum-n.input.length)+"個字元"},loadingMore:function(){return"載入中…"},maximumSelected:function(n){return"你只能選擇最多"+n.maximum+"項"},noResults:function(){return"沒有找到相符的項目"},searching:function(){return"搜尋中…"},removeAllItems:function(){return"刪除所有項目"}}}),n.define,n.require}();
\ No newline at end of file
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/select2.full.js b/htdocs/includes/jquery/plugins/select2/dist/js/select2.full.js
index 608642bf64e..358572a6576 100644
--- a/htdocs/includes/jquery/plugins/select2/dist/js/select2.full.js
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/select2.full.js
@@ -1,11 +1,11 @@
/*!
- * Select2 4.0.5
+ * Select2 4.0.13
* https://select2.github.io
*
* Released under the MIT license
* https://github.com/select2/select2/blob/master/LICENSE.md
*/
-(function (factory) {
+;(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
@@ -574,10 +574,10 @@ S2.define('select2/utils',[
DecoratedClass.prototype = new ctr();
for (var m = 0; m < superMethods.length; m++) {
- var superMethod = superMethods[m];
+ var superMethod = superMethods[m];
- DecoratedClass.prototype[superMethod] =
- SuperClass.prototype[superMethod];
+ DecoratedClass.prototype[superMethod] =
+ SuperClass.prototype[superMethod];
}
var calledMethod = function (methodName) {
@@ -772,6 +772,70 @@ S2.define('select2/utils',[
$element.append($nodes);
};
+ // Cache objects in Utils.__cache instead of $.data (see #4346)
+ Utils.__cache = {};
+
+ var id = 0;
+ Utils.GetUniqueElementId = function (element) {
+ // Get a unique element Id. If element has no id,
+ // creates a new unique number, stores it in the id
+ // attribute and returns the new id.
+ // If an id already exists, it simply returns it.
+
+ var select2Id = element.getAttribute('data-select2-id');
+ if (select2Id == null) {
+ // If element has id, use it.
+ if (element.id) {
+ select2Id = element.id;
+ element.setAttribute('data-select2-id', select2Id);
+ } else {
+ element.setAttribute('data-select2-id', ++id);
+ select2Id = id.toString();
+ }
+ }
+ return select2Id;
+ };
+
+ Utils.StoreData = function (element, name, value) {
+ // Stores an item in the cache for a specified element.
+ // name is the cache key.
+ var id = Utils.GetUniqueElementId(element);
+ if (!Utils.__cache[id]) {
+ Utils.__cache[id] = {};
+ }
+
+ Utils.__cache[id][name] = value;
+ };
+
+ Utils.GetData = function (element, name) {
+ // Retrieves a value from the cache by its key (name)
+ // name is optional. If no name specified, return
+ // all cache items for the specified element.
+ // and for a specified element.
+ var id = Utils.GetUniqueElementId(element);
+ if (name) {
+ if (Utils.__cache[id]) {
+ if (Utils.__cache[id][name] != null) {
+ return Utils.__cache[id][name];
+ }
+ return $(element).data(name); // Fallback to HTML5 data attribs.
+ }
+ return $(element).data(name); // Fallback to HTML5 data attribs.
+ } else {
+ return Utils.__cache[id];
+ }
+ };
+
+ Utils.RemoveData = function (element) {
+ // Removes all cached items for a specified element.
+ var id = Utils.GetUniqueElementId(element);
+ if (Utils.__cache[id] != null) {
+ delete Utils.__cache[id];
+ }
+
+ element.removeAttribute('data-select2-id');
+ };
+
return Utils;
});
@@ -791,7 +855,7 @@ S2.define('select2/results',[
Results.prototype.render = function () {
var $results = $(
- ''
+ ''
);
if (this.options.get('multiple')) {
@@ -814,7 +878,7 @@ S2.define('select2/results',[
this.hideLoading();
var $message = $(
- ' '
);
@@ -907,7 +971,7 @@ S2.define('select2/results',[
$options.each(function () {
var $option = $(this);
- var item = $.data(this, 'data');
+ var item = Utils.GetData(this, 'data');
// id needs to be converted to a string when comparing
var id = '' + item.id;
@@ -948,11 +1012,16 @@ S2.define('select2/results',[
option.className = 'select2-results__option';
var attrs = {
- 'role': 'treeitem',
+ 'role': 'option',
'aria-selected': 'false'
};
- if (data.disabled) {
+ var matches = window.Element.prototype.matches ||
+ window.Element.prototype.msMatchesSelector ||
+ window.Element.prototype.webkitMatchesSelector;
+
+ if ((data.element != null && matches.call(data.element, ':disabled')) ||
+ (data.element == null && data.disabled)) {
delete attrs['aria-selected'];
attrs['aria-disabled'] = 'true';
}
@@ -1012,7 +1081,7 @@ S2.define('select2/results',[
this.template(data, option);
}
- $.data(option, 'data', data);
+ Utils.StoreData(option, 'data', data);
return option;
};
@@ -1053,7 +1122,10 @@ S2.define('select2/results',[
}
self.setClasses();
- self.highlightFirstItem();
+
+ if (self.options.get('scrollAfterSelect')) {
+ self.highlightFirstItem();
+ }
});
container.on('unselect', function () {
@@ -1062,7 +1134,10 @@ S2.define('select2/results',[
}
self.setClasses();
- self.highlightFirstItem();
+
+ if (self.options.get('scrollAfterSelect')) {
+ self.highlightFirstItem();
+ }
});
container.on('open', function () {
@@ -1098,7 +1173,7 @@ S2.define('select2/results',[
return;
}
- var data = $highlighted.data('data');
+ var data = Utils.GetData($highlighted[0], 'data');
if ($highlighted.attr('aria-selected') == 'true') {
self.trigger('close', {});
@@ -1116,8 +1191,9 @@ S2.define('select2/results',[
var currentIndex = $options.index($highlighted);
- // If we are already at te top, don't move further
- if (currentIndex === 0) {
+ // If we are already at the top, don't move further
+ // If no options, currentIndex will be -1
+ if (currentIndex <= 0) {
return;
}
@@ -1210,7 +1286,7 @@ S2.define('select2/results',[
function (evt) {
var $this = $(this);
- var data = $this.data('data');
+ var data = Utils.GetData(this, 'data');
if ($this.attr('aria-selected') === 'true') {
if (self.options.get('multiple')) {
@@ -1233,7 +1309,7 @@ S2.define('select2/results',[
this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
function (evt) {
- var data = $(this).data('data');
+ var data = Utils.GetData(this, 'data');
self.getHighlightedResults()
.removeClass('select2-results__option--highlighted');
@@ -1348,14 +1424,15 @@ S2.define('select2/selection/base',[
this._tabindex = 0;
- if (this.$element.data('old-tabindex') != null) {
- this._tabindex = this.$element.data('old-tabindex');
+ if (Utils.GetData(this.$element[0], 'old-tabindex') != null) {
+ this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex');
} else if (this.$element.attr('tabindex') != null) {
this._tabindex = this.$element.attr('tabindex');
}
$selection.attr('title', this.$element.attr('title'));
$selection.attr('tabindex', this._tabindex);
+ $selection.attr('aria-disabled', 'false');
this.$selection = $selection;
@@ -1365,7 +1442,6 @@ S2.define('select2/selection/base',[
BaseSelection.prototype.bind = function (container, $container) {
var self = this;
- var id = container.id + '-container';
var resultsId = container.id + '-results';
this.container = container;
@@ -1408,17 +1484,19 @@ S2.define('select2/selection/base',[
self.$selection.removeAttr('aria-activedescendant');
self.$selection.removeAttr('aria-owns');
- self.$selection.focus();
+ self.$selection.trigger('focus');
self._detachCloseHandler(container);
});
container.on('enable', function () {
self.$selection.attr('tabindex', self._tabindex);
+ self.$selection.attr('aria-disabled', 'false');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
+ self.$selection.attr('aria-disabled', 'true');
});
};
@@ -1441,7 +1519,6 @@ S2.define('select2/selection/base',[
};
BaseSelection.prototype._attachCloseHandler = function (container) {
- var self = this;
$(document.body).on('mousedown.select2.' + container.id, function (e) {
var $target = $(e.target);
@@ -1451,13 +1528,11 @@ S2.define('select2/selection/base',[
var $all = $('.select2.select2-container--open');
$all.each(function () {
- var $this = $(this);
-
if (this == $select[0]) {
return;
}
- var $element = $this.data('element');
+ var $element = Utils.GetData(this, 'element');
$element.select2('close');
});
@@ -1481,6 +1556,27 @@ S2.define('select2/selection/base',[
throw new Error('The `update` method must be defined in child classes.');
};
+ /**
+ * Helper method to abstract the "enabled" (not "disabled") state of this
+ * object.
+ *
+ * @return {true} if the instance is not disabled.
+ * @return {false} if the instance is disabled.
+ */
+ BaseSelection.prototype.isEnabled = function () {
+ return !this.isDisabled();
+ };
+
+ /**
+ * Helper method to abstract the "disabled" state of this object.
+ *
+ * @return {true} if the disabled option is true.
+ * @return {false} if the disabled option is false.
+ */
+ BaseSelection.prototype.isDisabled = function () {
+ return this.options.get('disabled');
+ };
+
return BaseSelection;
});
@@ -1518,7 +1614,10 @@ S2.define('select2/selection/single',[
var id = container.id + '-container';
- this.$selection.find('.select2-selection__rendered').attr('id', id);
+ this.$selection.find('.select2-selection__rendered')
+ .attr('id', id)
+ .attr('role', 'textbox')
+ .attr('aria-readonly', 'true');
this.$selection.attr('aria-labelledby', id);
this.$selection.on('mousedown', function (evt) {
@@ -1542,17 +1641,15 @@ S2.define('select2/selection/single',[
container.on('focus', function (evt) {
if (!container.isOpen()) {
- self.$selection.focus();
+ self.$selection.trigger('focus');
}
});
-
- container.on('selection:update', function (params) {
- self.update(params.data);
- });
};
SingleSelection.prototype.clear = function () {
- this.$selection.find('.select2-selection__rendered').empty();
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+ $rendered.empty();
+ $rendered.removeAttr('title'); // clear tooltip on empty
};
SingleSelection.prototype.display = function (data, container) {
@@ -1578,7 +1675,14 @@ S2.define('select2/selection/single',[
var formatted = this.display(selection, $rendered);
$rendered.empty().append(formatted);
- $rendered.prop('title', selection.title || selection.text);
+
+ var title = selection.title || selection.text;
+
+ if (title) {
+ $rendered.attr('title', title);
+ } else {
+ $rendered.removeAttr('title');
+ }
};
return SingleSelection;
@@ -1623,14 +1727,14 @@ S2.define('select2/selection/multiple',[
'.select2-selection__choice__remove',
function (evt) {
// Ignore the event if it is disabled
- if (self.options.get('disabled')) {
+ if (self.isDisabled()) {
return;
}
var $remove = $(this);
var $selection = $remove.parent();
- var data = $selection.data('data');
+ var data = Utils.GetData($selection[0], 'data');
self.trigger('unselect', {
originalEvent: evt,
@@ -1641,7 +1745,9 @@ S2.define('select2/selection/multiple',[
};
MultipleSelection.prototype.clear = function () {
- this.$selection.find('.select2-selection__rendered').empty();
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+ $rendered.empty();
+ $rendered.removeAttr('title');
};
MultipleSelection.prototype.display = function (data, container) {
@@ -1679,9 +1785,14 @@ S2.define('select2/selection/multiple',[
var formatted = this.display(selection, $selection);
$selection.append(formatted);
- $selection.prop('title', selection.title || selection.text);
- $selection.data('data', selection);
+ var title = selection.title || selection.text;
+
+ if (title) {
+ $selection.attr('title', title);
+ }
+
+ Utils.StoreData($selection[0], 'data', selection);
$selections.push($selection);
}
@@ -1746,8 +1857,9 @@ S2.define('select2/selection/placeholder',[
S2.define('select2/selection/allowClear',[
'jquery',
- '../keys'
-], function ($, KEYS) {
+ '../keys',
+ '../utils'
+], function ($, KEYS, Utils) {
function AllowClear () { }
AllowClear.prototype.bind = function (decorated, container, $container) {
@@ -1776,7 +1888,7 @@ S2.define('select2/selection/allowClear',[
AllowClear.prototype._handleClear = function (_, evt) {
// Ignore the event if it is disabled
- if (this.options.get('disabled')) {
+ if (this.isDisabled()) {
return;
}
@@ -1789,10 +1901,22 @@ S2.define('select2/selection/allowClear',[
evt.stopPropagation();
- var data = $clear.data('data');
+ var data = Utils.GetData($clear[0], 'data');
+
+ var previousVal = this.$element.val();
+ this.$element.val(this.placeholder.id);
+
+ var unselectData = {
+ data: data
+ };
+ this.trigger('clear', unselectData);
+ if (unselectData.prevented) {
+ this.$element.val(previousVal);
+ return;
+ }
for (var d = 0; d < data.length; d++) {
- var unselectData = {
+ unselectData = {
data: data[d]
};
@@ -1802,11 +1926,12 @@ S2.define('select2/selection/allowClear',[
// If the event was prevented, don't clear it out.
if (unselectData.prevented) {
+ this.$element.val(previousVal);
return;
}
}
- this.$element.val(this.placeholder.id).trigger('change');
+ this.$element.trigger('input').trigger('change');
this.trigger('toggle', {});
};
@@ -1829,12 +1954,14 @@ S2.define('select2/selection/allowClear',[
return;
}
+ var removeAll = this.options.get('translations').get('removeAllItems');
+
var $remove = $(
- '' +
+ '' +
'×' +
' '
);
- $remove.data('data', data);
+ Utils.StoreData($remove[0], 'data', data);
this.$selection.find('.select2-selection__rendered').prepend($remove);
};
@@ -1856,7 +1983,7 @@ S2.define('select2/selection/search',[
'' +
' ' +
+ ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
' '
);
@@ -1873,14 +2000,18 @@ S2.define('select2/selection/search',[
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
+ var resultsId = container.id + '-results';
+
decorated.call(this, container, $container);
container.on('open', function () {
+ self.$search.attr('aria-controls', resultsId);
self.$search.trigger('focus');
});
container.on('close', function () {
self.$search.val('');
+ self.$search.removeAttr('aria-controls');
self.$search.removeAttr('aria-activedescendant');
self.$search.trigger('focus');
});
@@ -1900,7 +2031,11 @@ S2.define('select2/selection/search',[
});
container.on('results:focus', function (params) {
- self.$search.attr('aria-activedescendant', params.id);
+ if (params.data._resultId) {
+ self.$search.attr('aria-activedescendant', params.data._resultId);
+ } else {
+ self.$search.removeAttr('aria-activedescendant');
+ }
});
this.$selection.on('focusin', '.select2-search--inline', function (evt) {
@@ -1925,7 +2060,7 @@ S2.define('select2/selection/search',[
.prev('.select2-selection__choice');
if ($previousChoice.length > 0) {
- var item = $previousChoice.data('data');
+ var item = Utils.GetData($previousChoice[0], 'data');
self.searchRemoveChoice(item);
@@ -1934,6 +2069,12 @@ S2.define('select2/selection/search',[
}
});
+ this.$selection.on('click', '.select2-search--inline', function (evt) {
+ if (self.$search.val()) {
+ evt.stopPropagation();
+ }
+ });
+
// Try to detect the IE version should the `documentMode` property that
// is stored on the document. This is only implemented in IE and is
// slightly cleaner than doing a user agent check.
@@ -2019,7 +2160,7 @@ S2.define('select2/selection/search',[
this.resizeSearch();
if (searchHadFocus) {
- this.$search.focus();
+ this.$search.trigger('focus');
}
};
@@ -2052,7 +2193,7 @@ S2.define('select2/selection/search',[
var width = '';
if (this.$search.attr('placeholder') !== '') {
- width = this.$selection.find('.select2-selection__rendered').innerWidth();
+ width = this.$selection.find('.select2-selection__rendered').width();
} else {
var minimumWidth = this.$search.val().length + 1;
@@ -2076,10 +2217,13 @@ S2.define('select2/selection/eventRelay',[
'open', 'opening',
'close', 'closing',
'select', 'selecting',
- 'unselect', 'unselecting'
+ 'unselect', 'unselecting',
+ 'clear', 'clearing'
];
- var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];
+ var preventableEvents = [
+ 'opening', 'closing', 'selecting', 'unselecting', 'clearing'
+ ];
decorated.call(this, container, $container);
@@ -2412,6 +2556,7 @@ S2.define('select2/diacritics',[
'\u019F': 'O',
'\uA74A': 'O',
'\uA74C': 'O',
+ '\u0152': 'OE',
'\u01A2': 'OI',
'\uA74E': 'OO',
'\u0222': 'OU',
@@ -2821,6 +2966,7 @@ S2.define('select2/diacritics',[
'\uA74B': 'o',
'\uA74D': 'o',
'\u0275': 'o',
+ '\u0153': 'oe',
'\u01A3': 'oi',
'\u0223': 'ou',
'\uA74F': 'oo',
@@ -2989,8 +3135,9 @@ S2.define('select2/diacritics',[
'\u03CD': '\u03C5',
'\u03CB': '\u03C5',
'\u03B0': '\u03C5',
- '\u03C9': '\u03C9',
- '\u03C2': '\u03C3'
+ '\u03CE': '\u03C9',
+ '\u03C2': '\u03C3',
+ '\u2019': '\''
};
return diacritics;
@@ -3075,7 +3222,7 @@ S2.define('select2/data/select',[
if ($(data.element).is('option')) {
data.element.selected = true;
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
return;
}
@@ -3096,13 +3243,13 @@ S2.define('select2/data/select',[
}
self.$element.val(val);
- self.$element.trigger('change');
+ self.$element.trigger('input').trigger('change');
});
} else {
var val = data.id;
this.$element.val(val);
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
}
};
@@ -3118,7 +3265,7 @@ S2.define('select2/data/select',[
if ($(data.element).is('option')) {
data.element.selected = false;
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
return;
}
@@ -3136,7 +3283,7 @@ S2.define('select2/data/select',[
self.$element.val(val);
- self.$element.trigger('change');
+ self.$element.trigger('input').trigger('change');
});
};
@@ -3158,7 +3305,7 @@ S2.define('select2/data/select',[
// Remove anything added to child elements
this.$element.find('*').each(function () {
// Remove any custom data set by Select2
- $.removeData(this, 'data');
+ Utils.RemoveData(this);
});
};
@@ -3231,7 +3378,7 @@ S2.define('select2/data/select',[
normalizedData.element = option;
// Override the option's data with the combined data
- $.data(option, 'data', normalizedData);
+ Utils.StoreData(option, 'data', normalizedData);
return $option;
};
@@ -3239,7 +3386,7 @@ S2.define('select2/data/select',[
SelectAdapter.prototype.item = function ($option) {
var data = {};
- data = $.data($option[0], 'data');
+ data = Utils.GetData($option[0], 'data');
if (data != null) {
return data;
@@ -3277,13 +3424,13 @@ S2.define('select2/data/select',[
data = this._normalizeItem(data);
data.element = $option[0];
- $.data($option[0], 'data', data);
+ Utils.StoreData($option[0], 'data', data);
return data;
};
SelectAdapter.prototype._normalizeItem = function (item) {
- if (!$.isPlainObject(item)) {
+ if (item !== Object(item)) {
item = {
id: item,
text: item
@@ -3329,15 +3476,19 @@ S2.define('select2/data/array',[
'jquery'
], function (SelectAdapter, Utils, $) {
function ArrayAdapter ($element, options) {
- var data = options.get('data') || [];
+ this._dataToConvert = options.get('data') || [];
ArrayAdapter.__super__.constructor.call(this, $element, options);
-
- this.addOptions(this.convertToOptions(data));
}
Utils.Extend(ArrayAdapter, SelectAdapter);
+ ArrayAdapter.prototype.bind = function (container, $container) {
+ ArrayAdapter.__super__.bind.call(this, container, $container);
+
+ this.addOptions(this.convertToOptions(this._dataToConvert));
+ };
+
ArrayAdapter.prototype.select = function (data) {
var $option = this.$element.find('option').filter(function (i, elm) {
return elm.value == data.id.toString();
@@ -3487,7 +3638,8 @@ S2.define('select2/data/ajax',[
}, function () {
// Attempt to detect if a request was aborted
// Only works if the transport exposes a status property
- if ($request.status && $request.status === '0') {
+ if ('status' in $request &&
+ ($request.status === 0 || $request.status === '0')) {
return;
}
@@ -3626,8 +3778,6 @@ S2.define('select2/data/tags',[
};
Tags.prototype._removeOldTags = function (_) {
- var tag = this._lastTag;
-
var $options = this.$element.find('option[data-select2-tag]');
$options.each(function () {
@@ -3702,7 +3852,7 @@ S2.define('select2/data/tokenizer',[
// Replace the search term if we have the search box
if (this.$search.length) {
this.$search.val(tokenData.term);
- this.$search.focus();
+ this.$search.trigger('focus');
}
params.term = tokenData.term;
@@ -3831,10 +3981,30 @@ S2.define('select2/data/maximumSelectionLength',[
decorated.call(this, $e, options);
}
+ MaximumSelectionLength.prototype.bind =
+ function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ container.on('select', function () {
+ self._checkIfMaximumSelected();
+ });
+ };
+
MaximumSelectionLength.prototype.query =
function (decorated, params, callback) {
var self = this;
+ this._checkIfMaximumSelected(function () {
+ decorated.call(self, params, callback);
+ });
+ };
+
+ MaximumSelectionLength.prototype._checkIfMaximumSelected =
+ function (_, successCallback) {
+ var self = this;
+
this.current(function (currentData) {
var count = currentData != null ? currentData.length : 0;
if (self.maximumSelectionLength > 0 &&
@@ -3847,7 +4017,10 @@ S2.define('select2/data/maximumSelectionLength',[
});
return;
}
- decorated.call(self, params, callback);
+
+ if (successCallback) {
+ successCallback();
+ }
});
};
@@ -3886,7 +4059,7 @@ S2.define('select2/dropdown',[
};
Dropdown.prototype.position = function ($dropdown, $container) {
- // Should be implmented in subclasses
+ // Should be implemented in subclasses
};
Dropdown.prototype.destroy = function () {
@@ -3910,7 +4083,7 @@ S2.define('select2/dropdown/search',[
'' +
' ' +
+ ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
' '
);
@@ -3925,6 +4098,8 @@ S2.define('select2/dropdown/search',[
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
+ var resultsId = container.id + '-results';
+
decorated.call(this, container, $container);
this.$search.on('keydown', function (evt) {
@@ -3947,23 +4122,27 @@ S2.define('select2/dropdown/search',[
container.on('open', function () {
self.$search.attr('tabindex', 0);
+ self.$search.attr('aria-controls', resultsId);
- self.$search.focus();
+ self.$search.trigger('focus');
window.setTimeout(function () {
- self.$search.focus();
+ self.$search.trigger('focus');
}, 0);
});
container.on('close', function () {
self.$search.attr('tabindex', -1);
+ self.$search.removeAttr('aria-controls');
+ self.$search.removeAttr('aria-activedescendant');
self.$search.val('');
+ self.$search.trigger('blur');
});
container.on('focus', function () {
if (!container.isOpen()) {
- self.$search.focus();
+ self.$search.trigger('focus');
}
});
@@ -3978,6 +4157,14 @@ S2.define('select2/dropdown/search',[
}
}
});
+
+ container.on('results:focus', function (params) {
+ if (params.data._resultId) {
+ self.$search.attr('aria-activedescendant', params.data._resultId);
+ } else {
+ self.$search.removeAttr('aria-activedescendant');
+ }
+ });
};
Search.prototype.handleSearch = function (evt) {
@@ -4062,6 +4249,7 @@ S2.define('select2/dropdown/infiniteScroll',[
if (this.showLoadingMore(data)) {
this.$results.append(this.$loadingMore);
+ this.loadMoreIfNeeded();
}
};
@@ -4080,25 +4268,27 @@ S2.define('select2/dropdown/infiniteScroll',[
self.loading = true;
});
- this.$results.on('scroll', function () {
- var isLoadMoreVisible = $.contains(
- document.documentElement,
- self.$loadingMore[0]
- );
+ this.$results.on('scroll', this.loadMoreIfNeeded.bind(this));
+ };
- if (self.loading || !isLoadMoreVisible) {
- return;
- }
+ InfiniteScroll.prototype.loadMoreIfNeeded = function () {
+ var isLoadMoreVisible = $.contains(
+ document.documentElement,
+ this.$loadingMore[0]
+ );
- var currentOffset = self.$results.offset().top +
- self.$results.outerHeight(false);
- var loadingMoreOffset = self.$loadingMore.offset().top +
- self.$loadingMore.outerHeight(false);
+ if (this.loading || !isLoadMoreVisible) {
+ return;
+ }
- if (currentOffset + 50 >= loadingMoreOffset) {
- self.loadMore();
- }
- });
+ var currentOffset = this.$results.offset().top +
+ this.$results.outerHeight(false);
+ var loadingMoreOffset = this.$loadingMore.offset().top +
+ this.$loadingMore.outerHeight(false);
+
+ if (currentOffset + 50 >= loadingMoreOffset) {
+ this.loadMore();
+ }
};
InfiniteScroll.prototype.loadMore = function () {
@@ -4119,7 +4309,7 @@ S2.define('select2/dropdown/infiniteScroll',[
var $option = $(
' '
+ 'role="option" aria-disabled="true">'
);
var message = this.options.get('translations').get('loadingMore');
@@ -4137,7 +4327,7 @@ S2.define('select2/dropdown/attachBody',[
'../utils'
], function ($, Utils) {
function AttachBody (decorated, $element, options) {
- this.$dropdownParent = options.get('dropdownParent') || $(document.body);
+ this.$dropdownParent = $(options.get('dropdownParent') || document.body);
decorated.call(this, $element, options);
}
@@ -4145,27 +4335,14 @@ S2.define('select2/dropdown/attachBody',[
AttachBody.prototype.bind = function (decorated, container, $container) {
var self = this;
- var setupResultsEvents = false;
-
decorated.call(this, container, $container);
container.on('open', function () {
self._showDropdown();
self._attachPositioningHandler(container);
- if (!setupResultsEvents) {
- setupResultsEvents = true;
-
- container.on('results:all', function () {
- self._positionDropdown();
- self._resizeDropdown();
- });
-
- container.on('results:append', function () {
- self._positionDropdown();
- self._resizeDropdown();
- });
- }
+ // Must bind after the results handlers to ensure correct sizing
+ self._bindContainerResultHandlers(container);
});
container.on('close', function () {
@@ -4214,6 +4391,44 @@ S2.define('select2/dropdown/attachBody',[
this.$dropdownContainer.detach();
};
+ AttachBody.prototype._bindContainerResultHandlers =
+ function (decorated, container) {
+
+ // These should only be bound once
+ if (this._containerResultsHandlersBound) {
+ return;
+ }
+
+ var self = this;
+
+ container.on('results:all', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('results:append', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('results:message', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('select', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('unselect', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ this._containerResultsHandlersBound = true;
+ };
+
AttachBody.prototype._attachPositioningHandler =
function (decorated, container) {
var self = this;
@@ -4224,14 +4439,14 @@ S2.define('select2/dropdown/attachBody',[
var $watchers = this.$container.parents().filter(Utils.hasScroll);
$watchers.each(function () {
- $(this).data('select2-scroll-position', {
+ Utils.StoreData(this, 'select2-scroll-position', {
x: $(this).scrollLeft(),
y: $(this).scrollTop()
});
});
$watchers.on(scrollEvent, function (ev) {
- var position = $(this).data('select2-scroll-position');
+ var position = Utils.GetData(this, 'select2-scroll-position');
$(this).scrollTop(position.y);
});
@@ -4290,16 +4505,26 @@ S2.define('select2/dropdown/attachBody',[
top: container.bottom
};
- // Determine what the parent element is to use for calciulating the offset
+ // Determine what the parent element is to use for calculating the offset
var $offsetParent = this.$dropdownParent;
- // For statically positoned elements, we need to get the element
+ // For statically positioned elements, we need to get the element
// that is determining the offset
if ($offsetParent.css('position') === 'static') {
$offsetParent = $offsetParent.offsetParent();
}
- var parentOffset = $offsetParent.offset();
+ var parentOffset = {
+ top: 0,
+ left: 0
+ };
+
+ if (
+ $.contains(document.body, $offsetParent[0]) ||
+ $offsetParent[0].isConnected
+ ) {
+ parentOffset = $offsetParent.offset();
+ }
css.top -= parentOffset.top;
css.left -= parentOffset.left;
@@ -4396,8 +4621,8 @@ S2.define('select2/dropdown/minimumResultsForSearch',[
});
S2.define('select2/dropdown/selectOnClose',[
-
-], function () {
+ '../utils'
+], function (Utils) {
function SelectOnClose () { }
SelectOnClose.prototype.bind = function (decorated, container, $container) {
@@ -4428,7 +4653,7 @@ S2.define('select2/dropdown/selectOnClose',[
return;
}
- var data = $highlightedResults.data('data');
+ var data = Utils.GetData($highlightedResults[0], 'data');
// Don't re-select already selected resulte
if (
@@ -4469,7 +4694,7 @@ S2.define('select2/dropdown/closeOnSelect',[
var originalEvent = evt.originalEvent;
// Don't close if the control key is being held
- if (originalEvent && originalEvent.ctrlKey) {
+ if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) {
return;
}
@@ -4523,6 +4748,9 @@ S2.define('select2/i18n/en',[],function () {
},
searching: function () {
return 'Searching…';
+ },
+ removeAllItems: function () {
+ return 'Remove all items';
}
};
});
@@ -4761,66 +4989,29 @@ S2.define('select2/defaults',[
);
}
- if (typeof options.language === 'string') {
- // Check if the language is specified with a region
- if (options.language.indexOf('-') > 0) {
- // Extract the region information if it is included
- var languageParts = options.language.split('-');
- var baseLanguage = languageParts[0];
+ // If the defaults were not previously applied from an element, it is
+ // possible for the language option to have not been resolved
+ options.language = this._resolveLanguage(options.language);
- options.language = [options.language, baseLanguage];
- } else {
- options.language = [options.language];
+ // Always fall back to English since it will always be complete
+ options.language.push('en');
+
+ var uniqueLanguages = [];
+
+ for (var l = 0; l < options.language.length; l++) {
+ var language = options.language[l];
+
+ if (uniqueLanguages.indexOf(language) === -1) {
+ uniqueLanguages.push(language);
}
}
- if ($.isArray(options.language)) {
- var languages = new Translation();
- options.language.push('en');
+ options.language = uniqueLanguages;
- var languageNames = options.language;
-
- for (var l = 0; l < languageNames.length; l++) {
- var name = languageNames[l];
- var language = {};
-
- try {
- // Try to load it with the original name
- language = Translation.loadPath(name);
- } catch (e) {
- try {
- // If we couldn't load it, check if it wasn't the full path
- name = this.defaults.amdLanguageBase + name;
- language = Translation.loadPath(name);
- } catch (ex) {
- // The translation could not be loaded at all. Sometimes this is
- // because of a configuration problem, other times this can be
- // because of how Select2 helps load all possible translation files.
- if (options.debug && window.console && console.warn) {
- console.warn(
- 'Select2: The language file for "' + name + '" could not be ' +
- 'automatically loaded. A fallback will be used instead.'
- );
- }
-
- continue;
- }
- }
-
- languages.extend(language);
- }
-
- options.translations = languages;
- } else {
- var baseTranslation = Translation.loadPath(
- this.defaults.amdLanguageBase + 'en'
- );
- var customTranslation = new Translation(options.language);
-
- customTranslation.extend(baseTranslation);
-
- options.translations = customTranslation;
- }
+ options.translations = this._processTranslations(
+ options.language,
+ options.debug
+ );
return options;
};
@@ -4887,13 +5078,14 @@ S2.define('select2/defaults',[
debug: false,
dropdownAutoWidth: false,
escapeMarkup: Utils.escapeMarkup,
- language: EnglishTranslation,
+ language: {},
matcher: matcher,
minimumInputLength: 0,
maximumInputLength: 0,
maximumSelectionLength: 0,
minimumResultsForSearch: 0,
selectOnClose: false,
+ scrollAfterSelect: false,
sorter: function (data) {
return data;
},
@@ -4908,6 +5100,103 @@ S2.define('select2/defaults',[
};
};
+ Defaults.prototype.applyFromElement = function (options, $element) {
+ var optionLanguage = options.language;
+ var defaultLanguage = this.defaults.language;
+ var elementLanguage = $element.prop('lang');
+ var parentLanguage = $element.closest('[lang]').prop('lang');
+
+ var languages = Array.prototype.concat.call(
+ this._resolveLanguage(elementLanguage),
+ this._resolveLanguage(optionLanguage),
+ this._resolveLanguage(defaultLanguage),
+ this._resolveLanguage(parentLanguage)
+ );
+
+ options.language = languages;
+
+ return options;
+ };
+
+ Defaults.prototype._resolveLanguage = function (language) {
+ if (!language) {
+ return [];
+ }
+
+ if ($.isEmptyObject(language)) {
+ return [];
+ }
+
+ if ($.isPlainObject(language)) {
+ return [language];
+ }
+
+ var languages;
+
+ if (!$.isArray(language)) {
+ languages = [language];
+ } else {
+ languages = language;
+ }
+
+ var resolvedLanguages = [];
+
+ for (var l = 0; l < languages.length; l++) {
+ resolvedLanguages.push(languages[l]);
+
+ if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) {
+ // Extract the region information if it is included
+ var languageParts = languages[l].split('-');
+ var baseLanguage = languageParts[0];
+
+ resolvedLanguages.push(baseLanguage);
+ }
+ }
+
+ return resolvedLanguages;
+ };
+
+ Defaults.prototype._processTranslations = function (languages, debug) {
+ var translations = new Translation();
+
+ for (var l = 0; l < languages.length; l++) {
+ var languageData = new Translation();
+
+ var language = languages[l];
+
+ if (typeof language === 'string') {
+ try {
+ // Try to load it with the original name
+ languageData = Translation.loadPath(language);
+ } catch (e) {
+ try {
+ // If we couldn't load it, check if it wasn't the full path
+ language = this.defaults.amdLanguageBase + language;
+ languageData = Translation.loadPath(language);
+ } catch (ex) {
+ // The translation could not be loaded at all. Sometimes this is
+ // because of a configuration problem, other times this can be
+ // because of how Select2 helps load all possible translation files
+ if (debug && window.console && console.warn) {
+ console.warn(
+ 'Select2: The language file for "' + language + '" could ' +
+ 'not be automatically loaded. A fallback will be used instead.'
+ );
+ }
+ }
+ }
+ } else if ($.isPlainObject(language)) {
+ languageData = new Translation(language);
+ } else {
+ languageData = language;
+ }
+
+ translations.extend(languageData);
+ }
+
+ return translations;
+ };
+
Defaults.prototype.set = function (key, value) {
var camelKey = $.camelCase(key);
@@ -4916,7 +5205,7 @@ S2.define('select2/defaults',[
var convertedData = Utils._convertData(data);
- $.extend(this.defaults, convertedData);
+ $.extend(true, this.defaults, convertedData);
};
var defaults = new Defaults();
@@ -4937,6 +5226,10 @@ S2.define('select2/options',[
this.fromElement($element);
}
+ if ($element != null) {
+ this.options = Defaults.applyFromElement(this.options, $element);
+ }
+
this.options = Defaults.apply(this.options);
if ($element && $element.is('input')) {
@@ -4960,14 +5253,6 @@ S2.define('select2/options',[
this.options.disabled = $e.prop('disabled');
}
- if (this.options.language == null) {
- if ($e.prop('lang')) {
- this.options.language = $e.prop('lang').toLowerCase();
- } else if ($e.closest('[lang]').prop('lang')) {
- this.options.language = $e.closest('[lang]').prop('lang');
- }
- }
-
if (this.options.dir == null) {
if ($e.prop('dir')) {
this.options.dir = $e.prop('dir');
@@ -4981,7 +5266,7 @@ S2.define('select2/options',[
$e.prop('disabled', this.options.disabled);
$e.prop('multiple', this.options.multiple);
- if ($e.data('select2Tags')) {
+ if (Utils.GetData($e[0], 'select2Tags')) {
if (this.options.debug && window.console && console.warn) {
console.warn(
'Select2: The `data-select2-tags` attribute has been changed to ' +
@@ -4990,11 +5275,11 @@ S2.define('select2/options',[
);
}
- $e.data('data', $e.data('select2Tags'));
- $e.data('tags', true);
+ Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags'));
+ Utils.StoreData($e[0], 'tags', true);
}
- if ($e.data('ajaxUrl')) {
+ if (Utils.GetData($e[0], 'ajaxUrl')) {
if (this.options.debug && window.console && console.warn) {
console.warn(
'Select2: The `data-ajax-url` attribute has been changed to ' +
@@ -5003,21 +5288,45 @@ S2.define('select2/options',[
);
}
- $e.attr('ajax--url', $e.data('ajaxUrl'));
- $e.data('ajax--url', $e.data('ajaxUrl'));
+ $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl'));
+ Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl'));
}
var dataset = {};
+ function upperCaseLetter(_, letter) {
+ return letter.toUpperCase();
+ }
+
+ // Pre-load all of the attributes which are prefixed with `data-`
+ for (var attr = 0; attr < $e[0].attributes.length; attr++) {
+ var attributeName = $e[0].attributes[attr].name;
+ var prefix = 'data-';
+
+ if (attributeName.substr(0, prefix.length) == prefix) {
+ // Get the contents of the attribute after `data-`
+ var dataName = attributeName.substring(prefix.length);
+
+ // Get the data contents from the consistent source
+ // This is more than likely the jQuery data helper
+ var dataValue = Utils.GetData($e[0], dataName);
+
+ // camelCase the attribute name to match the spec
+ var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter);
+
+ // Store the data attribute contents into the dataset since
+ dataset[camelDataName] = dataValue;
+ }
+ }
+
// Prefer the element's `dataset` attribute if it exists
// jQuery 1.x does not correctly handle data attributes with multiple dashes
if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
- dataset = $.extend(true, {}, $e[0].dataset, $e.data());
- } else {
- dataset = $e.data();
+ dataset = $.extend(true, {}, $e[0].dataset, dataset);
}
- var data = $.extend(true, {}, dataset);
+ // Prefer our internal data cache if it exists
+ var data = $.extend(true, {}, Utils.GetData($e[0]), dataset);
data = Utils._convertData(data);
@@ -5054,8 +5363,8 @@ S2.define('select2/core',[
'./keys'
], function ($, Options, Utils, KEYS) {
var Select2 = function ($element, options) {
- if ($element.data('select2') != null) {
- $element.data('select2').destroy();
+ if (Utils.GetData($element[0], 'select2') != null) {
+ Utils.GetData($element[0], 'select2').destroy();
}
this.$element = $element;
@@ -5071,7 +5380,7 @@ S2.define('select2/core',[
// Set up the tabindex
var tabindex = $element.attr('tabindex') || 0;
- $element.data('old-tabindex', tabindex);
+ Utils.StoreData($element[0], 'old-tabindex', tabindex);
$element.attr('tabindex', '-1');
// Set up containers and adapters
@@ -5132,6 +5441,9 @@ S2.define('select2/core',[
// Synchronize any monitored attributes
this._syncAttributes();
+ Utils.StoreData($element[0], 'select2', this);
+
+ // Ensure backwards compatibility with $element.data('select2').
$element.data('select2', this);
};
@@ -5208,6 +5520,12 @@ S2.define('select2/core',[
return null;
}
+ if (method == 'computedstyle') {
+ var computedStyle = window.getComputedStyle($element[0]);
+
+ return computedStyle.width;
+ }
+
return method;
};
@@ -5248,8 +5566,8 @@ S2.define('select2/core',[
if (observer != null) {
this._observer = new observer(function (mutations) {
- $.each(mutations, self._syncA);
- $.each(mutations, self._syncS);
+ self._syncA();
+ self._syncS(null, mutations);
});
this._observer.observe(this.$element[0], {
attributes: true,
@@ -5371,7 +5689,7 @@ S2.define('select2/core',[
if (self.isOpen()) {
if (key === KEYS.ESC || key === KEYS.TAB ||
(key === KEYS.UP && evt.altKey)) {
- self.close();
+ self.close(evt);
evt.preventDefault();
} else if (key === KEYS.ENTER) {
@@ -5405,7 +5723,7 @@ S2.define('select2/core',[
Select2.prototype._syncAttributes = function () {
this.options.set('disabled', this.$element.prop('disabled'));
- if (this.options.get('disabled')) {
+ if (this.isDisabled()) {
if (this.isOpen()) {
this.close();
}
@@ -5416,7 +5734,7 @@ S2.define('select2/core',[
}
};
- Select2.prototype._syncSubtree = function (evt, mutations) {
+ Select2.prototype._isChangeMutation = function (evt, mutations) {
var changed = false;
var self = this;
@@ -5444,7 +5762,22 @@ S2.define('select2/core',[
}
} else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
changed = true;
+ } else if ($.isArray(mutations)) {
+ $.each(mutations, function(evt, mutation) {
+ if (self._isChangeMutation(evt, mutation)) {
+ // We've found a change mutation.
+ // Let's escape from the loop and continue
+ changed = true;
+ return false;
+ }
+ });
}
+ return changed;
+ };
+
+ Select2.prototype._syncSubtree = function (evt, mutations) {
+ var changed = this._isChangeMutation(evt, mutations);
+ var self = this;
// Only re-pull the data if we think there is a change
if (changed) {
@@ -5466,7 +5799,8 @@ S2.define('select2/core',[
'open': 'opening',
'close': 'closing',
'select': 'selecting',
- 'unselect': 'unselecting'
+ 'unselect': 'unselecting',
+ 'clear': 'clearing'
};
if (args === undefined) {
@@ -5494,7 +5828,7 @@ S2.define('select2/core',[
};
Select2.prototype.toggleDropdown = function () {
- if (this.options.get('disabled')) {
+ if (this.isDisabled()) {
return;
}
@@ -5510,15 +5844,40 @@ S2.define('select2/core',[
return;
}
+ if (this.isDisabled()) {
+ return;
+ }
+
this.trigger('query', {});
};
- Select2.prototype.close = function () {
+ Select2.prototype.close = function (evt) {
if (!this.isOpen()) {
return;
}
- this.trigger('close', {});
+ this.trigger('close', { originalEvent : evt });
+ };
+
+ /**
+ * Helper method to abstract the "enabled" (not "disabled") state of this
+ * object.
+ *
+ * @return {true} if the instance is not disabled.
+ * @return {false} if the instance is disabled.
+ */
+ Select2.prototype.isEnabled = function () {
+ return !this.isDisabled();
+ };
+
+ /**
+ * Helper method to abstract the "disabled" state of this object.
+ *
+ * @return {true} if the disabled option is true.
+ * @return {false} if the disabled option is false.
+ */
+ Select2.prototype.isDisabled = function () {
+ return this.options.get('disabled');
};
Select2.prototype.isOpen = function () {
@@ -5595,7 +5954,7 @@ S2.define('select2/core',[
});
}
- this.$element.val(newVal).trigger('change');
+ this.$element.val(newVal).trigger('input').trigger('change');
};
Select2.prototype.destroy = function () {
@@ -5621,10 +5980,12 @@ S2.define('select2/core',[
this._syncS = null;
this.$element.off('.select2');
- this.$element.attr('tabindex', this.$element.data('old-tabindex'));
+ this.$element.attr('tabindex',
+ Utils.GetData(this.$element[0], 'old-tabindex'));
this.$element.removeClass('select2-hidden-accessible');
this.$element.attr('aria-hidden', 'false');
+ Utils.RemoveData(this.$element[0]);
this.$element.removeData('select2');
this.dataAdapter.destroy();
@@ -5652,7 +6013,7 @@ S2.define('select2/core',[
this.$container.addClass('select2-container--' + this.options.get('theme'));
- $container.data('element', this.$element);
+ Utils.StoreData($container[0], 'element', this.$element);
return $container;
};
@@ -5862,8 +6223,9 @@ S2.define('select2/compat/initSelection',[
});
S2.define('select2/compat/inputData',[
- 'jquery'
-], function ($) {
+ 'jquery',
+ '../utils'
+], function ($, Utils) {
function InputData (decorated, $element, options) {
this._currentData = [];
this._valueSeparator = options.get('valueSeparator') || ',';
@@ -5927,13 +6289,13 @@ S2.define('select2/compat/inputData',[
});
this.$element.val(data.id);
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
} else {
var value = this.$element.val();
value += this._valueSeparator + data.id;
this.$element.val(value);
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
}
};
@@ -5956,7 +6318,7 @@ S2.define('select2/compat/inputData',[
}
self.$element.val(values.join(self._valueSeparator));
- self.$element.trigger('change');
+ self.$element.trigger('input').trigger('change');
});
};
@@ -5980,7 +6342,7 @@ S2.define('select2/compat/inputData',[
InputData.prototype.addOptions = function (_, $options) {
var options = $.map($options, function ($option) {
- return $.data($option[0], 'data');
+ return Utils.GetData($option[0], 'data');
});
this._currentData.push.apply(this._currentData, options);
@@ -6383,8 +6745,9 @@ S2.define('jquery.select2',[
'jquery-mousewheel',
'./select2/core',
- './select2/defaults'
-], function ($, _, Select2, Defaults) {
+ './select2/defaults',
+ './select2/utils'
+], function ($, _, Select2, Defaults, Utils) {
if ($.fn.select2 == null) {
// All methods that should return the element
var thisMethods = ['open', 'close', 'destroy'];
@@ -6405,7 +6768,7 @@ S2.define('jquery.select2',[
var args = Array.prototype.slice.call(arguments, 1);
this.each(function () {
- var instance = $(this).data('select2');
+ var instance = Utils.GetData(this, 'select2');
if (instance == null && window.console && console.error) {
console.error(
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/select2.full.min.js b/htdocs/includes/jquery/plugins/select2/dist/js/select2.full.min.js
index 96ba80cd81b..fa781916e8b 100644
--- a/htdocs/includes/jquery/plugins/select2/dist/js/select2.full.min.js
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/select2.full.min.js
@@ -1 +1,2 @@
-/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=function(b,c){return void 0===c&&(c="undefined"!=typeof window?require("jquery"):require("jquery")(b)),a(c),c}:a(jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return v.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o=b&&b.split("/"),p=t.map,q=p&&p["*"]||{};if(a){for(a=a.split("/"),g=a.length-1,t.nodeIdCompat&&x.test(a[g])&&(a[g]=a[g].replace(x,"")),"."===a[0].charAt(0)&&o&&(n=o.slice(0,o.length-1),a=n.concat(a)),k=0;k0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}if((o||q)&&p){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),o)for(l=o.length;l>0;l-=1)if((e=p[o.slice(0,l).join("/")])&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&q&&q[d]&&(i=q[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){var d=w.call(arguments,0);return"string"!=typeof d[0]&&1===d.length&&d.push(null),o.apply(b,d.concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){r[a]=b}}function j(a){if(e(s,a)){var c=s[a];delete s[a],u[a]=!0,n.apply(b,c)}if(!e(r,a)&&!e(u,a))throw new Error("No "+a);return r[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return a?k(a):[]}function m(a){return function(){return t&&t.config&&t.config[a]||{}}}var n,o,p,q,r={},s={},t={},u={},v=Object.prototype.hasOwnProperty,w=[].slice,x=/\.js$/;p=function(a,b){var c,d=k(a),e=d[0],g=b[1];return a=d[1],e&&(e=f(e,g),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(g)):f(a,g):(a=f(a,g),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},q={require:function(a){return g(a)},exports:function(a){var b=r[a];return void 0!==b?b:r[a]={}},module:function(a){return{id:a,uri:"",exports:r[a],config:m(a)}}},n=function(a,c,d,f){var h,k,m,n,o,t,v,w=[],x=typeof d;if(f=f||a,t=l(f),"undefined"===x||"function"===x){for(c=!c.length&&d.length?["require","exports","module"]:c,o=0;o0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h":">",'"':""","'":"'","/":"/"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a(' '),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),d[0].className+=" select2-results__message",this.$results.append(d)},c.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c0?b.first().trigger("mouseenter"):a.first().trigger("mouseenter"),this.ensureHighlightVisible()},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()});b.$results.find(".select2-results__option[aria-selected]").each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("aria-selected","true"):b.attr("aria-selected","false")})})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"treeitem","aria-selected":"false"};b.disabled&&(delete d["aria-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["aria-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d.role="group",d["aria-label"]=b.text,delete d["aria-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";a(h);this.template(b,h);for(var i=[],j=0;j",{class:"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b,c){var d=this,e=b.id+"-results";this.$results.attr("id",e),b.on("results:all",function(a){d.clear(),d.append(a.data),b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("results:append",function(a){d.append(a.data),b.isOpen()&&d.setClasses()}),b.on("query",function(a){d.hideMessages(),d.showLoading(a)}),b.on("select",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("unselect",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("open",function(){d.$results.attr("aria-expanded","true"),d.$results.attr("aria-hidden","false"),d.setClasses(),d.ensureHighlightVisible()}),b.on("close",function(){d.$results.attr("aria-expanded","false"),d.$results.attr("aria-hidden","true"),d.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=d.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=d.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("aria-selected")?d.trigger("close",{}):d.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a);if(0!==c){var e=c-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top,h=f.offset().top,i=d.$results.scrollTop()+(h-g);0===e?d.$results.scrollTop(0):h-g<0&&d.$results.scrollTop(i)}}),b.on("results:next",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a),e=c+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top+d.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=d.$results.scrollTop()+h-g;0===e?d.$results.scrollTop(0):h>g&&d.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),b.on("results:message",function(a){d.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=d.$results.scrollTop(),c=d.$results.get(0).scrollHeight-b+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&c<=d.$results.height();e?(d.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(d.$results.scrollTop(d.$results.get(0).scrollHeight-d.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(b){var c=a(this),e=c.data("data");if("true"===c.attr("aria-selected"))return void(d.options.get("multiple")?d.trigger("unselect",{originalEvent:b,data:e}):d.trigger("close",{}));d.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(b){var c=a(this).data("data");d.getHighlightedResults().removeClass("select2-results__option--highlighted"),d.trigger("results:focus",{data:c,element:a(this)})})},c.prototype.getHighlightedResults=function(){return this.$results.find(".select2-results__option--highlighted")},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),c<=2?this.$results.scrollTop(0):(g>this.$results.outerHeight()||g<0)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a(' ');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a,b){var d=this,e=(a.id,a.id+"-results");this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),d.$selection.focus(),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2");a(".select2.select2-container--open").each(function(){var b=a(this);this!=d[0]&&b.data("element").select2("close")})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){b.find(".selection").append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html(' '),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d),this.$selection.attr("aria-labelledby",d),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()}),a.on("selection:update",function(a){c.update(a.data)})},e.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},e.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},e.prototype.selectionContainer=function(){return a(" ")},e.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.prop("title",b.title||b.text)},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html(''),a},d.prototype.bind=function(b,c){var e=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){e.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!e.options.get("disabled")){var c=a(this),d=c.parent(),f=d.data("data");e.trigger("unselect",{originalEvent:b,data:f})}})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},d.prototype.selectionContainer=function(){return a('× ')},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d1||c)return a.call(this,b);this.clear();var d=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(d)},b}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e0||0===c.length)){var d=a('× ');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a(' ');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.trigger("focus")}),b.on("close",function(){e.$search.val(""),e.$search.removeAttr("aria-activedescendant"),e.$search.trigger("focus")}),b.on("enable",function(){e.$search.prop("disabled",!1),e._transferTabIndex()}),b.on("disable",function(){e.$search.prop("disabled",!0)}),b.on("focus",function(a){e.$search.trigger("focus")}),b.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.id)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){if(a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented(),a.which===c.BACKSPACE&&""===e.$search.val()){var b=e.$searchContainer.prev(".select2-selection__choice");if(b.length>0){var d=b.data("data");e.searchRemoveChoice(d),a.preventDefault()}}});var f=document.documentMode,g=f&&f<=11;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){if(g)return void e.$selection.off("input.search input.searchcheck");e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(g&&"input"===a.type)return void e.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&e.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c&&this.$search.focus()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{a=.75*(this.$search.val().length+1)+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){return{"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"}}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),null!=c.id?d+="-"+c.id.toString():d+="-"+a.generateChars(4),d},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){d.status&&"0"===d.status||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h0&&b.term.length>this.maximumInputLength)return void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}});a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;if(d.maximumSelectionLength>0&&f>=d.maximumSelectionLength)return void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}});a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a(' ');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a(' ');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("focus",function(){c.isOpen()||e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){e.showSearch(a)?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){e.$results.offset().top+e.$results.outerHeight(!1)+50>=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1)&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a(' '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(" "),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(b){var c=a(this).data("select2-scroll-position");a(this).scrollTop(c.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id;this.$container.parents().filter(b.hasScroll).off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.topf.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),null==l.tokenSeparators&&null==l.tokenizer||(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){null==c(d,e.children[g])&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var h=b(e.text).toUpperCase(),i=b(d.term).toUpperCase();return h.indexOf(i)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)},new D}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return e<=0?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;h=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),null!=a&&0!==a.length||(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a(' ');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("select2/compat/utils",["jquery"],function(a){function b(b,c,d){var e,f,g=[];e=a.trim(b.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0===this.indexOf("select2-")&&g.push(this)})),e=a.trim(c.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&null!=(f=d(this))&&g.push(f)})),b.attr("class",g.join(" "))}return{syncCssClasses:b}}),b.define("select2/compat/containerCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("containerCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptContainerCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("containerCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/dropdownCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("dropdownCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptDropdownCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("dropdownCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/initSelection",["jquery"],function(a){function b(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=c.get("initSelection"),this._isInitialized=!1,a.call(this,b,c)}return b.prototype.current=function(b,c){var d=this;if(this._isInitialized)return void b.call(this,c);this.initSelection.call(null,this.$element,function(b){d._isInitialized=!0,a.isArray(b)||(b=[b]),c(b)})},b}),b.define("select2/compat/inputData",["jquery"],function(a){function b(a,b,c){this._currentData=[],this._valueSeparator=c.get("valueSeparator")||",","hidden"===b.prop("type")&&c.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `` element instead."),a.call(this,b,c)}return b.prototype.current=function(b,c){function d(b,c){var e=[];return b.selected||-1!==a.inArray(b.id,c)?(b.selected=!0,e.push(b)):b.selected=!1,b.children&&e.push.apply(e,d(b.children,c)),e}for(var e=[],f=0;f=0;f--){var g=d.children[f];b(c.term,g.text,g)||e.children.splice(f,1)}if(e.children.length>0)return e}return b(c.term,d.text,d)?e:null}return c}return b}),b.define("select2/compat/query",[],function(){function a(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `query` option has been deprecated in favor of a custom data adapter that overrides the `query` method. Support will be removed for the `query` option in future versions of Select2."),a.call(this,b,c)}return a.prototype.query=function(a,b,c){b.callback=c,this.options.get("query").call(null,b)},a}),b.define("select2/dropdown/attachContainer",[],function(){function a(a,b,c){a.call(this,b,c)}return a.prototype.position=function(a,b,c){c.find(".dropdown-wrapper").append(b),b.addClass("select2-dropdown--below"),c.addClass("select2-container--below")},a}),b.define("select2/dropdown/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$dropdown.on(d.join(" "),function(a){a.stopPropagation()})},a}),b.define("select2/selection/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$selection.on(d.join(" "),function(a){a.stopPropagation()})},a}),function(c){"function"==typeof b.define&&b.define.amd?b.define("jquery-mousewheel",["jquery"],c):"object"==typeof exports?module.exports=c:c(a)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||n=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120==0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})}),b.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults"],function(a,b,c,d){if(null==a.fn.select2){var e=["open","close","destroy"];a.fn.select2=function(b){if("object"==typeof(b=b||{}))return this.each(function(){var d=a.extend(!0,{},b);new c(a(this),d)}),this;if("string"==typeof b){var d,f=Array.prototype.slice.call(arguments,1);return this.each(function(){var c=a(this).data("select2");null==c&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2."),d=c[b].apply(c,f)}),a.inArray(b,e)>-1?this:d}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c});
\ No newline at end of file
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+!function(n){"function"==typeof define&&define.amd?define(["jquery"],n):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),n(t),t}:n(jQuery)}(function(d){var e=function(){if(d&&d.fn&&d.fn.select2&&d.fn.select2.amd)var e=d.fn.select2.amd;var t,n,i,h,o,s,f,g,m,v,y,_,r,a,w,l;function b(e,t){return r.call(e,t)}function c(e,t){var n,i,r,o,s,a,l,c,u,d,p,h=t&&t.split("/"),f=y.map,g=f&&f["*"]||{};if(e){for(s=(e=e.split("/")).length-1,y.nodeIdCompat&&w.test(e[s])&&(e[s]=e[s].replace(w,"")),"."===e[0].charAt(0)&&h&&(e=h.slice(0,h.length-1).concat(e)),u=0;u":">",'"':""","'":"'","/":"/"};return"string"!=typeof e?e:String(e).replace(/[&<>"'\/\\]/g,function(e){return t[e]})},r.appendMany=function(e,t){if("1.7"===o.fn.jquery.substr(0,3)){var n=o();o.map(t,function(e){n=n.add(e)}),t=n}e.append(t)},r.__cache={};var n=0;return r.GetUniqueElementId=function(e){var t=e.getAttribute("data-select2-id");return null==t&&(e.id?(t=e.id,e.setAttribute("data-select2-id",t)):(e.setAttribute("data-select2-id",++n),t=n.toString())),t},r.StoreData=function(e,t,n){var i=r.GetUniqueElementId(e);r.__cache[i]||(r.__cache[i]={}),r.__cache[i][t]=n},r.GetData=function(e,t){var n=r.GetUniqueElementId(e);return t?r.__cache[n]&&null!=r.__cache[n][t]?r.__cache[n][t]:o(e).data(t):r.__cache[n]},r.RemoveData=function(e){var t=r.GetUniqueElementId(e);null!=r.__cache[t]&&delete r.__cache[t],e.removeAttribute("data-select2-id")},r}),e.define("select2/results",["jquery","./utils"],function(h,f){function i(e,t,n){this.$element=e,this.data=n,this.options=t,i.__super__.constructor.call(this)}return f.Extend(i,f.Observable),i.prototype.render=function(){var e=h('');return this.options.get("multiple")&&e.attr("aria-multiselectable","true"),this.$results=e},i.prototype.clear=function(){this.$results.empty()},i.prototype.displayMessage=function(e){var t=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var n=h(' '),i=this.options.get("translations").get(e.message);n.append(t(i(e.args))),n[0].className+=" select2-results__message",this.$results.append(n)},i.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},i.prototype.append=function(e){this.hideLoading();var t=[];if(null!=e.results&&0!==e.results.length){e.results=this.sort(e.results);for(var n=0;n",{class:"select2-results__options select2-results__options--nested"});p.append(l),s.append(a),s.append(p)}else this.template(e,t);return f.StoreData(t,"data",e),t},i.prototype.bind=function(t,e){var l=this,n=t.id+"-results";this.$results.attr("id",n),t.on("results:all",function(e){l.clear(),l.append(e.data),t.isOpen()&&(l.setClasses(),l.highlightFirstItem())}),t.on("results:append",function(e){l.append(e.data),t.isOpen()&&l.setClasses()}),t.on("query",function(e){l.hideMessages(),l.showLoading(e)}),t.on("select",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("unselect",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("open",function(){l.$results.attr("aria-expanded","true"),l.$results.attr("aria-hidden","false"),l.setClasses(),l.ensureHighlightVisible()}),t.on("close",function(){l.$results.attr("aria-expanded","false"),l.$results.attr("aria-hidden","true"),l.$results.removeAttr("aria-activedescendant")}),t.on("results:toggle",function(){var e=l.getHighlightedResults();0!==e.length&&e.trigger("mouseup")}),t.on("results:select",function(){var e=l.getHighlightedResults();if(0!==e.length){var t=f.GetData(e[0],"data");"true"==e.attr("aria-selected")?l.trigger("close",{}):l.trigger("select",{data:t})}}),t.on("results:previous",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e);if(!(n<=0)){var i=n-1;0===e.length&&(i=0);var r=t.eq(i);r.trigger("mouseenter");var o=l.$results.offset().top,s=r.offset().top,a=l.$results.scrollTop()+(s-o);0===i?l.$results.scrollTop(0):s-o<0&&l.$results.scrollTop(a)}}),t.on("results:next",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e)+1;if(!(n>=t.length)){var i=t.eq(n);i.trigger("mouseenter");var r=l.$results.offset().top+l.$results.outerHeight(!1),o=i.offset().top+i.outerHeight(!1),s=l.$results.scrollTop()+o-r;0===n?l.$results.scrollTop(0):rthis.$results.outerHeight()||o<0)&&this.$results.scrollTop(r)}},i.prototype.template=function(e,t){var n=this.options.get("templateResult"),i=this.options.get("escapeMarkup"),r=n(e,t);null==r?t.style.display="none":"string"==typeof r?t.innerHTML=i(r):h(t).append(r)},i}),e.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),e.define("select2/selection/base",["jquery","../utils","../keys"],function(n,i,r){function o(e,t){this.$element=e,this.options=t,o.__super__.constructor.call(this)}return i.Extend(o,i.Observable),o.prototype.render=function(){var e=n(' ');return this._tabindex=0,null!=i.GetData(this.$element[0],"old-tabindex")?this._tabindex=i.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),e.attr("title",this.$element.attr("title")),e.attr("tabindex",this._tabindex),e.attr("aria-disabled","false"),this.$selection=e},o.prototype.bind=function(e,t){var n=this,i=e.id+"-results";this.container=e,this.$selection.on("focus",function(e){n.trigger("focus",e)}),this.$selection.on("blur",function(e){n._handleBlur(e)}),this.$selection.on("keydown",function(e){n.trigger("keypress",e),e.which===r.SPACE&&e.preventDefault()}),e.on("results:focus",function(e){n.$selection.attr("aria-activedescendant",e.data._resultId)}),e.on("selection:update",function(e){n.update(e.data)}),e.on("open",function(){n.$selection.attr("aria-expanded","true"),n.$selection.attr("aria-owns",i),n._attachCloseHandler(e)}),e.on("close",function(){n.$selection.attr("aria-expanded","false"),n.$selection.removeAttr("aria-activedescendant"),n.$selection.removeAttr("aria-owns"),n.$selection.trigger("focus"),n._detachCloseHandler(e)}),e.on("enable",function(){n.$selection.attr("tabindex",n._tabindex),n.$selection.attr("aria-disabled","false")}),e.on("disable",function(){n.$selection.attr("tabindex","-1"),n.$selection.attr("aria-disabled","true")})},o.prototype._handleBlur=function(e){var t=this;window.setTimeout(function(){document.activeElement==t.$selection[0]||n.contains(t.$selection[0],document.activeElement)||t.trigger("blur",e)},1)},o.prototype._attachCloseHandler=function(e){n(document.body).on("mousedown.select2."+e.id,function(e){var t=n(e.target).closest(".select2");n(".select2.select2-container--open").each(function(){this!=t[0]&&i.GetData(this,"element").select2("close")})})},o.prototype._detachCloseHandler=function(e){n(document.body).off("mousedown.select2."+e.id)},o.prototype.position=function(e,t){t.find(".selection").append(e)},o.prototype.destroy=function(){this._detachCloseHandler(this.container)},o.prototype.update=function(e){throw new Error("The `update` method must be defined in child classes.")},o.prototype.isEnabled=function(){return!this.isDisabled()},o.prototype.isDisabled=function(){return this.options.get("disabled")},o}),e.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(e,t,n,i){function r(){r.__super__.constructor.apply(this,arguments)}return n.Extend(r,t),r.prototype.render=function(){var e=r.__super__.render.call(this);return e.addClass("select2-selection--single"),e.html(' '),e},r.prototype.bind=function(t,e){var n=this;r.__super__.bind.apply(this,arguments);var i=t.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",i).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",i),this.$selection.on("mousedown",function(e){1===e.which&&n.trigger("toggle",{originalEvent:e})}),this.$selection.on("focus",function(e){}),this.$selection.on("blur",function(e){}),t.on("focus",function(e){t.isOpen()||n.$selection.trigger("focus")})},r.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},r.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},r.prototype.selectionContainer=function(){return e(" ")},r.prototype.update=function(e){if(0!==e.length){var t=e[0],n=this.$selection.find(".select2-selection__rendered"),i=this.display(t,n);n.empty().append(i);var r=t.title||t.text;r?n.attr("title",r):n.removeAttr("title")}else this.clear()},r}),e.define("select2/selection/multiple",["jquery","./base","../utils"],function(r,e,l){function n(e,t){n.__super__.constructor.apply(this,arguments)}return l.Extend(n,e),n.prototype.render=function(){var e=n.__super__.render.call(this);return e.addClass("select2-selection--multiple"),e.html(''),e},n.prototype.bind=function(e,t){var i=this;n.__super__.bind.apply(this,arguments),this.$selection.on("click",function(e){i.trigger("toggle",{originalEvent:e})}),this.$selection.on("click",".select2-selection__choice__remove",function(e){if(!i.isDisabled()){var t=r(this).parent(),n=l.GetData(t[0],"data");i.trigger("unselect",{originalEvent:e,data:n})}})},n.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},n.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},n.prototype.selectionContainer=function(){return r('× ')},n.prototype.update=function(e){if(this.clear(),0!==e.length){for(var t=[],n=0;n× ');a.StoreData(i[0],"data",t),this.$selection.find(".select2-selection__rendered").prepend(i)}},e}),e.define("select2/selection/search",["jquery","../utils","../keys"],function(i,a,l){function e(e,t,n){e.call(this,t,n)}return e.prototype.render=function(e){var t=i(' ');this.$searchContainer=t,this.$search=t.find("input");var n=e.call(this);return this._transferTabIndex(),n},e.prototype.bind=function(e,t,n){var i=this,r=t.id+"-results";e.call(this,t,n),t.on("open",function(){i.$search.attr("aria-controls",r),i.$search.trigger("focus")}),t.on("close",function(){i.$search.val(""),i.$search.removeAttr("aria-controls"),i.$search.removeAttr("aria-activedescendant"),i.$search.trigger("focus")}),t.on("enable",function(){i.$search.prop("disabled",!1),i._transferTabIndex()}),t.on("disable",function(){i.$search.prop("disabled",!0)}),t.on("focus",function(e){i.$search.trigger("focus")}),t.on("results:focus",function(e){e.data._resultId?i.$search.attr("aria-activedescendant",e.data._resultId):i.$search.removeAttr("aria-activedescendant")}),this.$selection.on("focusin",".select2-search--inline",function(e){i.trigger("focus",e)}),this.$selection.on("focusout",".select2-search--inline",function(e){i._handleBlur(e)}),this.$selection.on("keydown",".select2-search--inline",function(e){if(e.stopPropagation(),i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented(),e.which===l.BACKSPACE&&""===i.$search.val()){var t=i.$searchContainer.prev(".select2-selection__choice");if(0this.maximumInputLength?this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e}),e.define("select2/data/maximumSelectionLength",[],function(){function e(e,t,n){this.maximumSelectionLength=n.get("maximumSelectionLength"),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("select",function(){i._checkIfMaximumSelected()})},e.prototype.query=function(e,t,n){var i=this;this._checkIfMaximumSelected(function(){e.call(i,t,n)})},e.prototype._checkIfMaximumSelected=function(e,n){var i=this;this.current(function(e){var t=null!=e?e.length:0;0=i.maximumSelectionLength?i.trigger("results:message",{message:"maximumSelected",args:{maximum:i.maximumSelectionLength}}):n&&n()})},e}),e.define("select2/dropdown",["jquery","./utils"],function(t,e){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return e.Extend(n,e.Observable),n.prototype.render=function(){var e=t(' ');return e.attr("dir",this.options.get("dir")),this.$dropdown=e},n.prototype.bind=function(){},n.prototype.position=function(e,t){},n.prototype.destroy=function(){this.$dropdown.remove()},n}),e.define("select2/dropdown/search",["jquery","../utils"],function(o,e){function t(){}return t.prototype.render=function(e){var t=e.call(this),n=o(' ');return this.$searchContainer=n,this.$search=n.find("input"),t.prepend(n),t},t.prototype.bind=function(e,t,n){var i=this,r=t.id+"-results";e.call(this,t,n),this.$search.on("keydown",function(e){i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented()}),this.$search.on("input",function(e){o(this).off("keyup")}),this.$search.on("keyup input",function(e){i.handleSearch(e)}),t.on("open",function(){i.$search.attr("tabindex",0),i.$search.attr("aria-controls",r),i.$search.trigger("focus"),window.setTimeout(function(){i.$search.trigger("focus")},0)}),t.on("close",function(){i.$search.attr("tabindex",-1),i.$search.removeAttr("aria-controls"),i.$search.removeAttr("aria-activedescendant"),i.$search.val(""),i.$search.trigger("blur")}),t.on("focus",function(){t.isOpen()||i.$search.trigger("focus")}),t.on("results:all",function(e){null!=e.query.term&&""!==e.query.term||(i.showSearch(e)?i.$searchContainer.removeClass("select2-search--hide"):i.$searchContainer.addClass("select2-search--hide"))}),t.on("results:focus",function(e){e.data._resultId?i.$search.attr("aria-activedescendant",e.data._resultId):i.$search.removeAttr("aria-activedescendant")})},t.prototype.handleSearch=function(e){if(!this._keyUpPrevented){var t=this.$search.val();this.trigger("query",{term:t})}this._keyUpPrevented=!1},t.prototype.showSearch=function(e,t){return!0},t}),e.define("select2/dropdown/hidePlaceholder",[],function(){function e(e,t,n,i){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n,i)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return"string"==typeof t&&(t={id:"",text:t}),t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),i=t.length-1;0<=i;i--){var r=t[i];this.placeholder.id===r.id&&n.splice(i,1)}return n},e}),e.define("select2/dropdown/infiniteScroll",["jquery"],function(n){function e(e,t,n,i){this.lastParams={},e.call(this,t,n,i),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return e.prototype.append=function(e,t){this.$loadingMore.remove(),this.loading=!1,e.call(this,t),this.showLoadingMore(t)&&(this.$results.append(this.$loadingMore),this.loadMoreIfNeeded())},e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("query",function(e){i.lastParams=e,i.loading=!0}),t.on("query:append",function(e){i.lastParams=e,i.loading=!0}),this.$results.on("scroll",this.loadMoreIfNeeded.bind(this))},e.prototype.loadMoreIfNeeded=function(){var e=n.contains(document.documentElement,this.$loadingMore[0]);if(!this.loading&&e){var t=this.$results.offset().top+this.$results.outerHeight(!1);this.$loadingMore.offset().top+this.$loadingMore.outerHeight(!1)<=t+50&&this.loadMore()}},e.prototype.loadMore=function(){this.loading=!0;var e=n.extend({},{page:1},this.lastParams);e.page++,this.trigger("query:append",e)},e.prototype.showLoadingMore=function(e,t){return t.pagination&&t.pagination.more},e.prototype.createLoadingMore=function(){var e=n(' '),t=this.options.get("translations").get("loadingMore");return e.html(t(this.lastParams)),e},e}),e.define("select2/dropdown/attachBody",["jquery","../utils"],function(f,a){function e(e,t,n){this.$dropdownParent=f(n.get("dropdownParent")||document.body),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("open",function(){i._showDropdown(),i._attachPositioningHandler(t),i._bindContainerResultHandlers(t)}),t.on("close",function(){i._hideDropdown(),i._detachPositioningHandler(t)}),this.$dropdownContainer.on("mousedown",function(e){e.stopPropagation()})},e.prototype.destroy=function(e){e.call(this),this.$dropdownContainer.remove()},e.prototype.position=function(e,t,n){t.attr("class",n.attr("class")),t.removeClass("select2"),t.addClass("select2-container--open"),t.css({position:"absolute",top:-999999}),this.$container=n},e.prototype.render=function(e){var t=f(" "),n=e.call(this);return t.append(n),this.$dropdownContainer=t},e.prototype._hideDropdown=function(e){this.$dropdownContainer.detach()},e.prototype._bindContainerResultHandlers=function(e,t){if(!this._containerResultsHandlersBound){var n=this;t.on("results:all",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:append",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:message",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("select",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("unselect",function(){n._positionDropdown(),n._resizeDropdown()}),this._containerResultsHandlersBound=!0}},e.prototype._attachPositioningHandler=function(e,t){var n=this,i="scroll.select2."+t.id,r="resize.select2."+t.id,o="orientationchange.select2."+t.id,s=this.$container.parents().filter(a.hasScroll);s.each(function(){a.StoreData(this,"select2-scroll-position",{x:f(this).scrollLeft(),y:f(this).scrollTop()})}),s.on(i,function(e){var t=a.GetData(this,"select2-scroll-position");f(this).scrollTop(t.y)}),f(window).on(i+" "+r+" "+o,function(e){n._positionDropdown(),n._resizeDropdown()})},e.prototype._detachPositioningHandler=function(e,t){var n="scroll.select2."+t.id,i="resize.select2."+t.id,r="orientationchange.select2."+t.id;this.$container.parents().filter(a.hasScroll).off(n),f(window).off(n+" "+i+" "+r)},e.prototype._positionDropdown=function(){var e=f(window),t=this.$dropdown.hasClass("select2-dropdown--above"),n=this.$dropdown.hasClass("select2-dropdown--below"),i=null,r=this.$container.offset();r.bottom=r.top+this.$container.outerHeight(!1);var o={height:this.$container.outerHeight(!1)};o.top=r.top,o.bottom=r.top+o.height;var s=this.$dropdown.outerHeight(!1),a=e.scrollTop(),l=e.scrollTop()+e.height(),c=ar.bottom+s,d={left:r.left,top:o.bottom},p=this.$dropdownParent;"static"===p.css("position")&&(p=p.offsetParent());var h={top:0,left:0};(f.contains(document.body,p[0])||p[0].isConnected)&&(h=p.offset()),d.top-=h.top,d.left-=h.left,t||n||(i="below"),u||!c||t?!c&&u&&t&&(i="below"):i="above",("above"==i||t&&"below"!==i)&&(d.top=o.top-h.top-s),null!=i&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+i),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+i)),this.$dropdownContainer.css(d)},e.prototype._resizeDropdown=function(){var e={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(e.minWidth=e.width,e.position="relative",e.width="auto"),this.$dropdown.css(e)},e.prototype._showDropdown=function(e){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},e}),e.define("select2/dropdown/minimumResultsForSearch",[],function(){function e(e,t,n,i){this.minimumResultsForSearch=n.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),e.call(this,t,n,i)}return e.prototype.showSearch=function(e,t){return!(function e(t){for(var n=0,i=0;i ');return e.attr("dir",this.options.get("dir")),this.$container=e,this.$container.addClass("select2-container--"+this.options.get("theme")),u.StoreData(e[0],"element",this.$element),e},d}),e.define("select2/compat/utils",["jquery"],function(s){return{syncCssClasses:function(e,t,n){var i,r,o=[];(i=s.trim(e.attr("class")))&&s((i=""+i).split(/\s+/)).each(function(){0===this.indexOf("select2-")&&o.push(this)}),(i=s.trim(t.attr("class")))&&s((i=""+i).split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&null!=(r=n(this))&&o.push(r)}),e.attr("class",o.join(" "))}}}),e.define("select2/compat/containerCss",["jquery","./utils"],function(s,a){function l(e){return null}function e(){}return e.prototype.render=function(e){var t=e.call(this),n=this.options.get("containerCssClass")||"";s.isFunction(n)&&(n=n(this.$element));var i=this.options.get("adaptContainerCssClass");if(i=i||l,-1!==n.indexOf(":all:")){n=n.replace(":all:","");var r=i;i=function(e){var t=r(e);return null!=t?t+" "+e:e}}var o=this.options.get("containerCss")||{};return s.isFunction(o)&&(o=o(this.$element)),a.syncCssClasses(t,this.$element,i),t.css(o),t.addClass(n),t},e}),e.define("select2/compat/dropdownCss",["jquery","./utils"],function(s,a){function l(e){return null}function e(){}return e.prototype.render=function(e){var t=e.call(this),n=this.options.get("dropdownCssClass")||"";s.isFunction(n)&&(n=n(this.$element));var i=this.options.get("adaptDropdownCssClass");if(i=i||l,-1!==n.indexOf(":all:")){n=n.replace(":all:","");var r=i;i=function(e){var t=r(e);return null!=t?t+" "+e:e}}var o=this.options.get("dropdownCss")||{};return s.isFunction(o)&&(o=o(this.$element)),a.syncCssClasses(t,this.$element,i),t.css(o),t.addClass(n),t},e}),e.define("select2/compat/initSelection",["jquery"],function(i){function e(e,t,n){n.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=n.get("initSelection"),this._isInitialized=!1,e.call(this,t,n)}return e.prototype.current=function(e,t){var n=this;this._isInitialized?e.call(this,t):this.initSelection.call(null,this.$element,function(e){n._isInitialized=!0,i.isArray(e)||(e=[e]),t(e)})},e}),e.define("select2/compat/inputData",["jquery","../utils"],function(s,i){function e(e,t,n){this._currentData=[],this._valueSeparator=n.get("valueSeparator")||",","hidden"===t.prop("type")&&n.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `` element instead."),e.call(this,t,n)}return e.prototype.current=function(e,t){function i(e,t){var n=[];return e.selected||-1!==s.inArray(e.id,t)?(e.selected=!0,n.push(e)):e.selected=!1,e.children&&n.push.apply(n,i(e.children,t)),n}for(var n=[],r=0;r'
+ ''
);
if (this.options.get('multiple')) {
@@ -814,7 +878,7 @@ S2.define('select2/results',[
this.hideLoading();
var $message = $(
- ' '
);
@@ -907,7 +971,7 @@ S2.define('select2/results',[
$options.each(function () {
var $option = $(this);
- var item = $.data(this, 'data');
+ var item = Utils.GetData(this, 'data');
// id needs to be converted to a string when comparing
var id = '' + item.id;
@@ -948,11 +1012,16 @@ S2.define('select2/results',[
option.className = 'select2-results__option';
var attrs = {
- 'role': 'treeitem',
+ 'role': 'option',
'aria-selected': 'false'
};
- if (data.disabled) {
+ var matches = window.Element.prototype.matches ||
+ window.Element.prototype.msMatchesSelector ||
+ window.Element.prototype.webkitMatchesSelector;
+
+ if ((data.element != null && matches.call(data.element, ':disabled')) ||
+ (data.element == null && data.disabled)) {
delete attrs['aria-selected'];
attrs['aria-disabled'] = 'true';
}
@@ -1012,7 +1081,7 @@ S2.define('select2/results',[
this.template(data, option);
}
- $.data(option, 'data', data);
+ Utils.StoreData(option, 'data', data);
return option;
};
@@ -1053,7 +1122,10 @@ S2.define('select2/results',[
}
self.setClasses();
- self.highlightFirstItem();
+
+ if (self.options.get('scrollAfterSelect')) {
+ self.highlightFirstItem();
+ }
});
container.on('unselect', function () {
@@ -1062,7 +1134,10 @@ S2.define('select2/results',[
}
self.setClasses();
- self.highlightFirstItem();
+
+ if (self.options.get('scrollAfterSelect')) {
+ self.highlightFirstItem();
+ }
});
container.on('open', function () {
@@ -1098,7 +1173,7 @@ S2.define('select2/results',[
return;
}
- var data = $highlighted.data('data');
+ var data = Utils.GetData($highlighted[0], 'data');
if ($highlighted.attr('aria-selected') == 'true') {
self.trigger('close', {});
@@ -1116,8 +1191,9 @@ S2.define('select2/results',[
var currentIndex = $options.index($highlighted);
- // If we are already at te top, don't move further
- if (currentIndex === 0) {
+ // If we are already at the top, don't move further
+ // If no options, currentIndex will be -1
+ if (currentIndex <= 0) {
return;
}
@@ -1210,7 +1286,7 @@ S2.define('select2/results',[
function (evt) {
var $this = $(this);
- var data = $this.data('data');
+ var data = Utils.GetData(this, 'data');
if ($this.attr('aria-selected') === 'true') {
if (self.options.get('multiple')) {
@@ -1233,7 +1309,7 @@ S2.define('select2/results',[
this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
function (evt) {
- var data = $(this).data('data');
+ var data = Utils.GetData(this, 'data');
self.getHighlightedResults()
.removeClass('select2-results__option--highlighted');
@@ -1348,14 +1424,15 @@ S2.define('select2/selection/base',[
this._tabindex = 0;
- if (this.$element.data('old-tabindex') != null) {
- this._tabindex = this.$element.data('old-tabindex');
+ if (Utils.GetData(this.$element[0], 'old-tabindex') != null) {
+ this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex');
} else if (this.$element.attr('tabindex') != null) {
this._tabindex = this.$element.attr('tabindex');
}
$selection.attr('title', this.$element.attr('title'));
$selection.attr('tabindex', this._tabindex);
+ $selection.attr('aria-disabled', 'false');
this.$selection = $selection;
@@ -1365,7 +1442,6 @@ S2.define('select2/selection/base',[
BaseSelection.prototype.bind = function (container, $container) {
var self = this;
- var id = container.id + '-container';
var resultsId = container.id + '-results';
this.container = container;
@@ -1408,17 +1484,19 @@ S2.define('select2/selection/base',[
self.$selection.removeAttr('aria-activedescendant');
self.$selection.removeAttr('aria-owns');
- self.$selection.focus();
+ self.$selection.trigger('focus');
self._detachCloseHandler(container);
});
container.on('enable', function () {
self.$selection.attr('tabindex', self._tabindex);
+ self.$selection.attr('aria-disabled', 'false');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
+ self.$selection.attr('aria-disabled', 'true');
});
};
@@ -1441,7 +1519,6 @@ S2.define('select2/selection/base',[
};
BaseSelection.prototype._attachCloseHandler = function (container) {
- var self = this;
$(document.body).on('mousedown.select2.' + container.id, function (e) {
var $target = $(e.target);
@@ -1451,13 +1528,11 @@ S2.define('select2/selection/base',[
var $all = $('.select2.select2-container--open');
$all.each(function () {
- var $this = $(this);
-
if (this == $select[0]) {
return;
}
- var $element = $this.data('element');
+ var $element = Utils.GetData(this, 'element');
$element.select2('close');
});
@@ -1481,6 +1556,27 @@ S2.define('select2/selection/base',[
throw new Error('The `update` method must be defined in child classes.');
};
+ /**
+ * Helper method to abstract the "enabled" (not "disabled") state of this
+ * object.
+ *
+ * @return {true} if the instance is not disabled.
+ * @return {false} if the instance is disabled.
+ */
+ BaseSelection.prototype.isEnabled = function () {
+ return !this.isDisabled();
+ };
+
+ /**
+ * Helper method to abstract the "disabled" state of this object.
+ *
+ * @return {true} if the disabled option is true.
+ * @return {false} if the disabled option is false.
+ */
+ BaseSelection.prototype.isDisabled = function () {
+ return this.options.get('disabled');
+ };
+
return BaseSelection;
});
@@ -1518,7 +1614,10 @@ S2.define('select2/selection/single',[
var id = container.id + '-container';
- this.$selection.find('.select2-selection__rendered').attr('id', id);
+ this.$selection.find('.select2-selection__rendered')
+ .attr('id', id)
+ .attr('role', 'textbox')
+ .attr('aria-readonly', 'true');
this.$selection.attr('aria-labelledby', id);
this.$selection.on('mousedown', function (evt) {
@@ -1542,17 +1641,15 @@ S2.define('select2/selection/single',[
container.on('focus', function (evt) {
if (!container.isOpen()) {
- self.$selection.focus();
+ self.$selection.trigger('focus');
}
});
-
- container.on('selection:update', function (params) {
- self.update(params.data);
- });
};
SingleSelection.prototype.clear = function () {
- this.$selection.find('.select2-selection__rendered').empty();
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+ $rendered.empty();
+ $rendered.removeAttr('title'); // clear tooltip on empty
};
SingleSelection.prototype.display = function (data, container) {
@@ -1578,7 +1675,14 @@ S2.define('select2/selection/single',[
var formatted = this.display(selection, $rendered);
$rendered.empty().append(formatted);
- $rendered.prop('title', selection.title || selection.text);
+
+ var title = selection.title || selection.text;
+
+ if (title) {
+ $rendered.attr('title', title);
+ } else {
+ $rendered.removeAttr('title');
+ }
};
return SingleSelection;
@@ -1623,14 +1727,14 @@ S2.define('select2/selection/multiple',[
'.select2-selection__choice__remove',
function (evt) {
// Ignore the event if it is disabled
- if (self.options.get('disabled')) {
+ if (self.isDisabled()) {
return;
}
var $remove = $(this);
var $selection = $remove.parent();
- var data = $selection.data('data');
+ var data = Utils.GetData($selection[0], 'data');
self.trigger('unselect', {
originalEvent: evt,
@@ -1641,7 +1745,9 @@ S2.define('select2/selection/multiple',[
};
MultipleSelection.prototype.clear = function () {
- this.$selection.find('.select2-selection__rendered').empty();
+ var $rendered = this.$selection.find('.select2-selection__rendered');
+ $rendered.empty();
+ $rendered.removeAttr('title');
};
MultipleSelection.prototype.display = function (data, container) {
@@ -1679,9 +1785,14 @@ S2.define('select2/selection/multiple',[
var formatted = this.display(selection, $selection);
$selection.append(formatted);
- $selection.prop('title', selection.title || selection.text);
- $selection.data('data', selection);
+ var title = selection.title || selection.text;
+
+ if (title) {
+ $selection.attr('title', title);
+ }
+
+ Utils.StoreData($selection[0], 'data', selection);
$selections.push($selection);
}
@@ -1746,8 +1857,9 @@ S2.define('select2/selection/placeholder',[
S2.define('select2/selection/allowClear',[
'jquery',
- '../keys'
-], function ($, KEYS) {
+ '../keys',
+ '../utils'
+], function ($, KEYS, Utils) {
function AllowClear () { }
AllowClear.prototype.bind = function (decorated, container, $container) {
@@ -1776,7 +1888,7 @@ S2.define('select2/selection/allowClear',[
AllowClear.prototype._handleClear = function (_, evt) {
// Ignore the event if it is disabled
- if (this.options.get('disabled')) {
+ if (this.isDisabled()) {
return;
}
@@ -1789,10 +1901,22 @@ S2.define('select2/selection/allowClear',[
evt.stopPropagation();
- var data = $clear.data('data');
+ var data = Utils.GetData($clear[0], 'data');
+
+ var previousVal = this.$element.val();
+ this.$element.val(this.placeholder.id);
+
+ var unselectData = {
+ data: data
+ };
+ this.trigger('clear', unselectData);
+ if (unselectData.prevented) {
+ this.$element.val(previousVal);
+ return;
+ }
for (var d = 0; d < data.length; d++) {
- var unselectData = {
+ unselectData = {
data: data[d]
};
@@ -1802,11 +1926,12 @@ S2.define('select2/selection/allowClear',[
// If the event was prevented, don't clear it out.
if (unselectData.prevented) {
+ this.$element.val(previousVal);
return;
}
}
- this.$element.val(this.placeholder.id).trigger('change');
+ this.$element.trigger('input').trigger('change');
this.trigger('toggle', {});
};
@@ -1829,12 +1954,14 @@ S2.define('select2/selection/allowClear',[
return;
}
+ var removeAll = this.options.get('translations').get('removeAllItems');
+
var $remove = $(
- '' +
+ '' +
'×' +
' '
);
- $remove.data('data', data);
+ Utils.StoreData($remove[0], 'data', data);
this.$selection.find('.select2-selection__rendered').prepend($remove);
};
@@ -1856,7 +1983,7 @@ S2.define('select2/selection/search',[
'' +
' ' +
+ ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
' '
);
@@ -1873,14 +2000,18 @@ S2.define('select2/selection/search',[
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
+ var resultsId = container.id + '-results';
+
decorated.call(this, container, $container);
container.on('open', function () {
+ self.$search.attr('aria-controls', resultsId);
self.$search.trigger('focus');
});
container.on('close', function () {
self.$search.val('');
+ self.$search.removeAttr('aria-controls');
self.$search.removeAttr('aria-activedescendant');
self.$search.trigger('focus');
});
@@ -1900,7 +2031,11 @@ S2.define('select2/selection/search',[
});
container.on('results:focus', function (params) {
- self.$search.attr('aria-activedescendant', params.id);
+ if (params.data._resultId) {
+ self.$search.attr('aria-activedescendant', params.data._resultId);
+ } else {
+ self.$search.removeAttr('aria-activedescendant');
+ }
});
this.$selection.on('focusin', '.select2-search--inline', function (evt) {
@@ -1925,7 +2060,7 @@ S2.define('select2/selection/search',[
.prev('.select2-selection__choice');
if ($previousChoice.length > 0) {
- var item = $previousChoice.data('data');
+ var item = Utils.GetData($previousChoice[0], 'data');
self.searchRemoveChoice(item);
@@ -1934,6 +2069,12 @@ S2.define('select2/selection/search',[
}
});
+ this.$selection.on('click', '.select2-search--inline', function (evt) {
+ if (self.$search.val()) {
+ evt.stopPropagation();
+ }
+ });
+
// Try to detect the IE version should the `documentMode` property that
// is stored on the document. This is only implemented in IE and is
// slightly cleaner than doing a user agent check.
@@ -2019,7 +2160,7 @@ S2.define('select2/selection/search',[
this.resizeSearch();
if (searchHadFocus) {
- this.$search.focus();
+ this.$search.trigger('focus');
}
};
@@ -2052,7 +2193,7 @@ S2.define('select2/selection/search',[
var width = '';
if (this.$search.attr('placeholder') !== '') {
- width = this.$selection.find('.select2-selection__rendered').innerWidth();
+ width = this.$selection.find('.select2-selection__rendered').width();
} else {
var minimumWidth = this.$search.val().length + 1;
@@ -2076,10 +2217,13 @@ S2.define('select2/selection/eventRelay',[
'open', 'opening',
'close', 'closing',
'select', 'selecting',
- 'unselect', 'unselecting'
+ 'unselect', 'unselecting',
+ 'clear', 'clearing'
];
- var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];
+ var preventableEvents = [
+ 'opening', 'closing', 'selecting', 'unselecting', 'clearing'
+ ];
decorated.call(this, container, $container);
@@ -2412,6 +2556,7 @@ S2.define('select2/diacritics',[
'\u019F': 'O',
'\uA74A': 'O',
'\uA74C': 'O',
+ '\u0152': 'OE',
'\u01A2': 'OI',
'\uA74E': 'OO',
'\u0222': 'OU',
@@ -2821,6 +2966,7 @@ S2.define('select2/diacritics',[
'\uA74B': 'o',
'\uA74D': 'o',
'\u0275': 'o',
+ '\u0153': 'oe',
'\u01A3': 'oi',
'\u0223': 'ou',
'\uA74F': 'oo',
@@ -2989,8 +3135,9 @@ S2.define('select2/diacritics',[
'\u03CD': '\u03C5',
'\u03CB': '\u03C5',
'\u03B0': '\u03C5',
- '\u03C9': '\u03C9',
- '\u03C2': '\u03C3'
+ '\u03CE': '\u03C9',
+ '\u03C2': '\u03C3',
+ '\u2019': '\''
};
return diacritics;
@@ -3075,7 +3222,7 @@ S2.define('select2/data/select',[
if ($(data.element).is('option')) {
data.element.selected = true;
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
return;
}
@@ -3096,13 +3243,13 @@ S2.define('select2/data/select',[
}
self.$element.val(val);
- self.$element.trigger('change');
+ self.$element.trigger('input').trigger('change');
});
} else {
var val = data.id;
this.$element.val(val);
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
}
};
@@ -3118,7 +3265,7 @@ S2.define('select2/data/select',[
if ($(data.element).is('option')) {
data.element.selected = false;
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
return;
}
@@ -3136,7 +3283,7 @@ S2.define('select2/data/select',[
self.$element.val(val);
- self.$element.trigger('change');
+ self.$element.trigger('input').trigger('change');
});
};
@@ -3158,7 +3305,7 @@ S2.define('select2/data/select',[
// Remove anything added to child elements
this.$element.find('*').each(function () {
// Remove any custom data set by Select2
- $.removeData(this, 'data');
+ Utils.RemoveData(this);
});
};
@@ -3231,7 +3378,7 @@ S2.define('select2/data/select',[
normalizedData.element = option;
// Override the option's data with the combined data
- $.data(option, 'data', normalizedData);
+ Utils.StoreData(option, 'data', normalizedData);
return $option;
};
@@ -3239,7 +3386,7 @@ S2.define('select2/data/select',[
SelectAdapter.prototype.item = function ($option) {
var data = {};
- data = $.data($option[0], 'data');
+ data = Utils.GetData($option[0], 'data');
if (data != null) {
return data;
@@ -3277,13 +3424,13 @@ S2.define('select2/data/select',[
data = this._normalizeItem(data);
data.element = $option[0];
- $.data($option[0], 'data', data);
+ Utils.StoreData($option[0], 'data', data);
return data;
};
SelectAdapter.prototype._normalizeItem = function (item) {
- if (!$.isPlainObject(item)) {
+ if (item !== Object(item)) {
item = {
id: item,
text: item
@@ -3329,15 +3476,19 @@ S2.define('select2/data/array',[
'jquery'
], function (SelectAdapter, Utils, $) {
function ArrayAdapter ($element, options) {
- var data = options.get('data') || [];
+ this._dataToConvert = options.get('data') || [];
ArrayAdapter.__super__.constructor.call(this, $element, options);
-
- this.addOptions(this.convertToOptions(data));
}
Utils.Extend(ArrayAdapter, SelectAdapter);
+ ArrayAdapter.prototype.bind = function (container, $container) {
+ ArrayAdapter.__super__.bind.call(this, container, $container);
+
+ this.addOptions(this.convertToOptions(this._dataToConvert));
+ };
+
ArrayAdapter.prototype.select = function (data) {
var $option = this.$element.find('option').filter(function (i, elm) {
return elm.value == data.id.toString();
@@ -3487,7 +3638,8 @@ S2.define('select2/data/ajax',[
}, function () {
// Attempt to detect if a request was aborted
// Only works if the transport exposes a status property
- if ($request.status && $request.status === '0') {
+ if ('status' in $request &&
+ ($request.status === 0 || $request.status === '0')) {
return;
}
@@ -3626,8 +3778,6 @@ S2.define('select2/data/tags',[
};
Tags.prototype._removeOldTags = function (_) {
- var tag = this._lastTag;
-
var $options = this.$element.find('option[data-select2-tag]');
$options.each(function () {
@@ -3702,7 +3852,7 @@ S2.define('select2/data/tokenizer',[
// Replace the search term if we have the search box
if (this.$search.length) {
this.$search.val(tokenData.term);
- this.$search.focus();
+ this.$search.trigger('focus');
}
params.term = tokenData.term;
@@ -3831,10 +3981,30 @@ S2.define('select2/data/maximumSelectionLength',[
decorated.call(this, $e, options);
}
+ MaximumSelectionLength.prototype.bind =
+ function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ container.on('select', function () {
+ self._checkIfMaximumSelected();
+ });
+ };
+
MaximumSelectionLength.prototype.query =
function (decorated, params, callback) {
var self = this;
+ this._checkIfMaximumSelected(function () {
+ decorated.call(self, params, callback);
+ });
+ };
+
+ MaximumSelectionLength.prototype._checkIfMaximumSelected =
+ function (_, successCallback) {
+ var self = this;
+
this.current(function (currentData) {
var count = currentData != null ? currentData.length : 0;
if (self.maximumSelectionLength > 0 &&
@@ -3847,7 +4017,10 @@ S2.define('select2/data/maximumSelectionLength',[
});
return;
}
- decorated.call(self, params, callback);
+
+ if (successCallback) {
+ successCallback();
+ }
});
};
@@ -3886,7 +4059,7 @@ S2.define('select2/dropdown',[
};
Dropdown.prototype.position = function ($dropdown, $container) {
- // Should be implmented in subclasses
+ // Should be implemented in subclasses
};
Dropdown.prototype.destroy = function () {
@@ -3910,7 +4083,7 @@ S2.define('select2/dropdown/search',[
'' +
' ' +
+ ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
' '
);
@@ -3925,6 +4098,8 @@ S2.define('select2/dropdown/search',[
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
+ var resultsId = container.id + '-results';
+
decorated.call(this, container, $container);
this.$search.on('keydown', function (evt) {
@@ -3947,23 +4122,27 @@ S2.define('select2/dropdown/search',[
container.on('open', function () {
self.$search.attr('tabindex', 0);
+ self.$search.attr('aria-controls', resultsId);
- self.$search.focus();
+ self.$search.trigger('focus');
window.setTimeout(function () {
- self.$search.focus();
+ self.$search.trigger('focus');
}, 0);
});
container.on('close', function () {
self.$search.attr('tabindex', -1);
+ self.$search.removeAttr('aria-controls');
+ self.$search.removeAttr('aria-activedescendant');
self.$search.val('');
+ self.$search.trigger('blur');
});
container.on('focus', function () {
if (!container.isOpen()) {
- self.$search.focus();
+ self.$search.trigger('focus');
}
});
@@ -3978,6 +4157,14 @@ S2.define('select2/dropdown/search',[
}
}
});
+
+ container.on('results:focus', function (params) {
+ if (params.data._resultId) {
+ self.$search.attr('aria-activedescendant', params.data._resultId);
+ } else {
+ self.$search.removeAttr('aria-activedescendant');
+ }
+ });
};
Search.prototype.handleSearch = function (evt) {
@@ -4062,6 +4249,7 @@ S2.define('select2/dropdown/infiniteScroll',[
if (this.showLoadingMore(data)) {
this.$results.append(this.$loadingMore);
+ this.loadMoreIfNeeded();
}
};
@@ -4080,25 +4268,27 @@ S2.define('select2/dropdown/infiniteScroll',[
self.loading = true;
});
- this.$results.on('scroll', function () {
- var isLoadMoreVisible = $.contains(
- document.documentElement,
- self.$loadingMore[0]
- );
+ this.$results.on('scroll', this.loadMoreIfNeeded.bind(this));
+ };
- if (self.loading || !isLoadMoreVisible) {
- return;
- }
+ InfiniteScroll.prototype.loadMoreIfNeeded = function () {
+ var isLoadMoreVisible = $.contains(
+ document.documentElement,
+ this.$loadingMore[0]
+ );
- var currentOffset = self.$results.offset().top +
- self.$results.outerHeight(false);
- var loadingMoreOffset = self.$loadingMore.offset().top +
- self.$loadingMore.outerHeight(false);
+ if (this.loading || !isLoadMoreVisible) {
+ return;
+ }
- if (currentOffset + 50 >= loadingMoreOffset) {
- self.loadMore();
- }
- });
+ var currentOffset = this.$results.offset().top +
+ this.$results.outerHeight(false);
+ var loadingMoreOffset = this.$loadingMore.offset().top +
+ this.$loadingMore.outerHeight(false);
+
+ if (currentOffset + 50 >= loadingMoreOffset) {
+ this.loadMore();
+ }
};
InfiniteScroll.prototype.loadMore = function () {
@@ -4119,7 +4309,7 @@ S2.define('select2/dropdown/infiniteScroll',[
var $option = $(
' '
+ 'role="option" aria-disabled="true">'
);
var message = this.options.get('translations').get('loadingMore');
@@ -4137,7 +4327,7 @@ S2.define('select2/dropdown/attachBody',[
'../utils'
], function ($, Utils) {
function AttachBody (decorated, $element, options) {
- this.$dropdownParent = options.get('dropdownParent') || $(document.body);
+ this.$dropdownParent = $(options.get('dropdownParent') || document.body);
decorated.call(this, $element, options);
}
@@ -4145,27 +4335,14 @@ S2.define('select2/dropdown/attachBody',[
AttachBody.prototype.bind = function (decorated, container, $container) {
var self = this;
- var setupResultsEvents = false;
-
decorated.call(this, container, $container);
container.on('open', function () {
self._showDropdown();
self._attachPositioningHandler(container);
- if (!setupResultsEvents) {
- setupResultsEvents = true;
-
- container.on('results:all', function () {
- self._positionDropdown();
- self._resizeDropdown();
- });
-
- container.on('results:append', function () {
- self._positionDropdown();
- self._resizeDropdown();
- });
- }
+ // Must bind after the results handlers to ensure correct sizing
+ self._bindContainerResultHandlers(container);
});
container.on('close', function () {
@@ -4214,6 +4391,44 @@ S2.define('select2/dropdown/attachBody',[
this.$dropdownContainer.detach();
};
+ AttachBody.prototype._bindContainerResultHandlers =
+ function (decorated, container) {
+
+ // These should only be bound once
+ if (this._containerResultsHandlersBound) {
+ return;
+ }
+
+ var self = this;
+
+ container.on('results:all', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('results:append', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('results:message', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('select', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('unselect', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ this._containerResultsHandlersBound = true;
+ };
+
AttachBody.prototype._attachPositioningHandler =
function (decorated, container) {
var self = this;
@@ -4224,14 +4439,14 @@ S2.define('select2/dropdown/attachBody',[
var $watchers = this.$container.parents().filter(Utils.hasScroll);
$watchers.each(function () {
- $(this).data('select2-scroll-position', {
+ Utils.StoreData(this, 'select2-scroll-position', {
x: $(this).scrollLeft(),
y: $(this).scrollTop()
});
});
$watchers.on(scrollEvent, function (ev) {
- var position = $(this).data('select2-scroll-position');
+ var position = Utils.GetData(this, 'select2-scroll-position');
$(this).scrollTop(position.y);
});
@@ -4290,16 +4505,26 @@ S2.define('select2/dropdown/attachBody',[
top: container.bottom
};
- // Determine what the parent element is to use for calciulating the offset
+ // Determine what the parent element is to use for calculating the offset
var $offsetParent = this.$dropdownParent;
- // For statically positoned elements, we need to get the element
+ // For statically positioned elements, we need to get the element
// that is determining the offset
if ($offsetParent.css('position') === 'static') {
$offsetParent = $offsetParent.offsetParent();
}
- var parentOffset = $offsetParent.offset();
+ var parentOffset = {
+ top: 0,
+ left: 0
+ };
+
+ if (
+ $.contains(document.body, $offsetParent[0]) ||
+ $offsetParent[0].isConnected
+ ) {
+ parentOffset = $offsetParent.offset();
+ }
css.top -= parentOffset.top;
css.left -= parentOffset.left;
@@ -4396,8 +4621,8 @@ S2.define('select2/dropdown/minimumResultsForSearch',[
});
S2.define('select2/dropdown/selectOnClose',[
-
-], function () {
+ '../utils'
+], function (Utils) {
function SelectOnClose () { }
SelectOnClose.prototype.bind = function (decorated, container, $container) {
@@ -4428,7 +4653,7 @@ S2.define('select2/dropdown/selectOnClose',[
return;
}
- var data = $highlightedResults.data('data');
+ var data = Utils.GetData($highlightedResults[0], 'data');
// Don't re-select already selected resulte
if (
@@ -4469,7 +4694,7 @@ S2.define('select2/dropdown/closeOnSelect',[
var originalEvent = evt.originalEvent;
// Don't close if the control key is being held
- if (originalEvent && originalEvent.ctrlKey) {
+ if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) {
return;
}
@@ -4523,6 +4748,9 @@ S2.define('select2/i18n/en',[],function () {
},
searching: function () {
return 'Searching…';
+ },
+ removeAllItems: function () {
+ return 'Remove all items';
}
};
});
@@ -4761,66 +4989,29 @@ S2.define('select2/defaults',[
);
}
- if (typeof options.language === 'string') {
- // Check if the language is specified with a region
- if (options.language.indexOf('-') > 0) {
- // Extract the region information if it is included
- var languageParts = options.language.split('-');
- var baseLanguage = languageParts[0];
+ // If the defaults were not previously applied from an element, it is
+ // possible for the language option to have not been resolved
+ options.language = this._resolveLanguage(options.language);
- options.language = [options.language, baseLanguage];
- } else {
- options.language = [options.language];
+ // Always fall back to English since it will always be complete
+ options.language.push('en');
+
+ var uniqueLanguages = [];
+
+ for (var l = 0; l < options.language.length; l++) {
+ var language = options.language[l];
+
+ if (uniqueLanguages.indexOf(language) === -1) {
+ uniqueLanguages.push(language);
}
}
- if ($.isArray(options.language)) {
- var languages = new Translation();
- options.language.push('en');
+ options.language = uniqueLanguages;
- var languageNames = options.language;
-
- for (var l = 0; l < languageNames.length; l++) {
- var name = languageNames[l];
- var language = {};
-
- try {
- // Try to load it with the original name
- language = Translation.loadPath(name);
- } catch (e) {
- try {
- // If we couldn't load it, check if it wasn't the full path
- name = this.defaults.amdLanguageBase + name;
- language = Translation.loadPath(name);
- } catch (ex) {
- // The translation could not be loaded at all. Sometimes this is
- // because of a configuration problem, other times this can be
- // because of how Select2 helps load all possible translation files.
- if (options.debug && window.console && console.warn) {
- console.warn(
- 'Select2: The language file for "' + name + '" could not be ' +
- 'automatically loaded. A fallback will be used instead.'
- );
- }
-
- continue;
- }
- }
-
- languages.extend(language);
- }
-
- options.translations = languages;
- } else {
- var baseTranslation = Translation.loadPath(
- this.defaults.amdLanguageBase + 'en'
- );
- var customTranslation = new Translation(options.language);
-
- customTranslation.extend(baseTranslation);
-
- options.translations = customTranslation;
- }
+ options.translations = this._processTranslations(
+ options.language,
+ options.debug
+ );
return options;
};
@@ -4887,13 +5078,14 @@ S2.define('select2/defaults',[
debug: false,
dropdownAutoWidth: false,
escapeMarkup: Utils.escapeMarkup,
- language: EnglishTranslation,
+ language: {},
matcher: matcher,
minimumInputLength: 0,
maximumInputLength: 0,
maximumSelectionLength: 0,
minimumResultsForSearch: 0,
selectOnClose: false,
+ scrollAfterSelect: false,
sorter: function (data) {
return data;
},
@@ -4908,6 +5100,103 @@ S2.define('select2/defaults',[
};
};
+ Defaults.prototype.applyFromElement = function (options, $element) {
+ var optionLanguage = options.language;
+ var defaultLanguage = this.defaults.language;
+ var elementLanguage = $element.prop('lang');
+ var parentLanguage = $element.closest('[lang]').prop('lang');
+
+ var languages = Array.prototype.concat.call(
+ this._resolveLanguage(elementLanguage),
+ this._resolveLanguage(optionLanguage),
+ this._resolveLanguage(defaultLanguage),
+ this._resolveLanguage(parentLanguage)
+ );
+
+ options.language = languages;
+
+ return options;
+ };
+
+ Defaults.prototype._resolveLanguage = function (language) {
+ if (!language) {
+ return [];
+ }
+
+ if ($.isEmptyObject(language)) {
+ return [];
+ }
+
+ if ($.isPlainObject(language)) {
+ return [language];
+ }
+
+ var languages;
+
+ if (!$.isArray(language)) {
+ languages = [language];
+ } else {
+ languages = language;
+ }
+
+ var resolvedLanguages = [];
+
+ for (var l = 0; l < languages.length; l++) {
+ resolvedLanguages.push(languages[l]);
+
+ if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) {
+ // Extract the region information if it is included
+ var languageParts = languages[l].split('-');
+ var baseLanguage = languageParts[0];
+
+ resolvedLanguages.push(baseLanguage);
+ }
+ }
+
+ return resolvedLanguages;
+ };
+
+ Defaults.prototype._processTranslations = function (languages, debug) {
+ var translations = new Translation();
+
+ for (var l = 0; l < languages.length; l++) {
+ var languageData = new Translation();
+
+ var language = languages[l];
+
+ if (typeof language === 'string') {
+ try {
+ // Try to load it with the original name
+ languageData = Translation.loadPath(language);
+ } catch (e) {
+ try {
+ // If we couldn't load it, check if it wasn't the full path
+ language = this.defaults.amdLanguageBase + language;
+ languageData = Translation.loadPath(language);
+ } catch (ex) {
+ // The translation could not be loaded at all. Sometimes this is
+ // because of a configuration problem, other times this can be
+ // because of how Select2 helps load all possible translation files
+ if (debug && window.console && console.warn) {
+ console.warn(
+ 'Select2: The language file for "' + language + '" could ' +
+ 'not be automatically loaded. A fallback will be used instead.'
+ );
+ }
+ }
+ }
+ } else if ($.isPlainObject(language)) {
+ languageData = new Translation(language);
+ } else {
+ languageData = language;
+ }
+
+ translations.extend(languageData);
+ }
+
+ return translations;
+ };
+
Defaults.prototype.set = function (key, value) {
var camelKey = $.camelCase(key);
@@ -4916,7 +5205,7 @@ S2.define('select2/defaults',[
var convertedData = Utils._convertData(data);
- $.extend(this.defaults, convertedData);
+ $.extend(true, this.defaults, convertedData);
};
var defaults = new Defaults();
@@ -4937,6 +5226,10 @@ S2.define('select2/options',[
this.fromElement($element);
}
+ if ($element != null) {
+ this.options = Defaults.applyFromElement(this.options, $element);
+ }
+
this.options = Defaults.apply(this.options);
if ($element && $element.is('input')) {
@@ -4960,14 +5253,6 @@ S2.define('select2/options',[
this.options.disabled = $e.prop('disabled');
}
- if (this.options.language == null) {
- if ($e.prop('lang')) {
- this.options.language = $e.prop('lang').toLowerCase();
- } else if ($e.closest('[lang]').prop('lang')) {
- this.options.language = $e.closest('[lang]').prop('lang');
- }
- }
-
if (this.options.dir == null) {
if ($e.prop('dir')) {
this.options.dir = $e.prop('dir');
@@ -4981,7 +5266,7 @@ S2.define('select2/options',[
$e.prop('disabled', this.options.disabled);
$e.prop('multiple', this.options.multiple);
- if ($e.data('select2Tags')) {
+ if (Utils.GetData($e[0], 'select2Tags')) {
if (this.options.debug && window.console && console.warn) {
console.warn(
'Select2: The `data-select2-tags` attribute has been changed to ' +
@@ -4990,11 +5275,11 @@ S2.define('select2/options',[
);
}
- $e.data('data', $e.data('select2Tags'));
- $e.data('tags', true);
+ Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags'));
+ Utils.StoreData($e[0], 'tags', true);
}
- if ($e.data('ajaxUrl')) {
+ if (Utils.GetData($e[0], 'ajaxUrl')) {
if (this.options.debug && window.console && console.warn) {
console.warn(
'Select2: The `data-ajax-url` attribute has been changed to ' +
@@ -5003,21 +5288,45 @@ S2.define('select2/options',[
);
}
- $e.attr('ajax--url', $e.data('ajaxUrl'));
- $e.data('ajax--url', $e.data('ajaxUrl'));
+ $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl'));
+ Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl'));
}
var dataset = {};
+ function upperCaseLetter(_, letter) {
+ return letter.toUpperCase();
+ }
+
+ // Pre-load all of the attributes which are prefixed with `data-`
+ for (var attr = 0; attr < $e[0].attributes.length; attr++) {
+ var attributeName = $e[0].attributes[attr].name;
+ var prefix = 'data-';
+
+ if (attributeName.substr(0, prefix.length) == prefix) {
+ // Get the contents of the attribute after `data-`
+ var dataName = attributeName.substring(prefix.length);
+
+ // Get the data contents from the consistent source
+ // This is more than likely the jQuery data helper
+ var dataValue = Utils.GetData($e[0], dataName);
+
+ // camelCase the attribute name to match the spec
+ var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter);
+
+ // Store the data attribute contents into the dataset since
+ dataset[camelDataName] = dataValue;
+ }
+ }
+
// Prefer the element's `dataset` attribute if it exists
// jQuery 1.x does not correctly handle data attributes with multiple dashes
if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
- dataset = $.extend(true, {}, $e[0].dataset, $e.data());
- } else {
- dataset = $e.data();
+ dataset = $.extend(true, {}, $e[0].dataset, dataset);
}
- var data = $.extend(true, {}, dataset);
+ // Prefer our internal data cache if it exists
+ var data = $.extend(true, {}, Utils.GetData($e[0]), dataset);
data = Utils._convertData(data);
@@ -5054,8 +5363,8 @@ S2.define('select2/core',[
'./keys'
], function ($, Options, Utils, KEYS) {
var Select2 = function ($element, options) {
- if ($element.data('select2') != null) {
- $element.data('select2').destroy();
+ if (Utils.GetData($element[0], 'select2') != null) {
+ Utils.GetData($element[0], 'select2').destroy();
}
this.$element = $element;
@@ -5071,7 +5380,7 @@ S2.define('select2/core',[
// Set up the tabindex
var tabindex = $element.attr('tabindex') || 0;
- $element.data('old-tabindex', tabindex);
+ Utils.StoreData($element[0], 'old-tabindex', tabindex);
$element.attr('tabindex', '-1');
// Set up containers and adapters
@@ -5132,6 +5441,9 @@ S2.define('select2/core',[
// Synchronize any monitored attributes
this._syncAttributes();
+ Utils.StoreData($element[0], 'select2', this);
+
+ // Ensure backwards compatibility with $element.data('select2').
$element.data('select2', this);
};
@@ -5208,6 +5520,12 @@ S2.define('select2/core',[
return null;
}
+ if (method == 'computedstyle') {
+ var computedStyle = window.getComputedStyle($element[0]);
+
+ return computedStyle.width;
+ }
+
return method;
};
@@ -5248,8 +5566,8 @@ S2.define('select2/core',[
if (observer != null) {
this._observer = new observer(function (mutations) {
- $.each(mutations, self._syncA);
- $.each(mutations, self._syncS);
+ self._syncA();
+ self._syncS(null, mutations);
});
this._observer.observe(this.$element[0], {
attributes: true,
@@ -5371,7 +5689,7 @@ S2.define('select2/core',[
if (self.isOpen()) {
if (key === KEYS.ESC || key === KEYS.TAB ||
(key === KEYS.UP && evt.altKey)) {
- self.close();
+ self.close(evt);
evt.preventDefault();
} else if (key === KEYS.ENTER) {
@@ -5405,7 +5723,7 @@ S2.define('select2/core',[
Select2.prototype._syncAttributes = function () {
this.options.set('disabled', this.$element.prop('disabled'));
- if (this.options.get('disabled')) {
+ if (this.isDisabled()) {
if (this.isOpen()) {
this.close();
}
@@ -5416,7 +5734,7 @@ S2.define('select2/core',[
}
};
- Select2.prototype._syncSubtree = function (evt, mutations) {
+ Select2.prototype._isChangeMutation = function (evt, mutations) {
var changed = false;
var self = this;
@@ -5444,7 +5762,22 @@ S2.define('select2/core',[
}
} else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
changed = true;
+ } else if ($.isArray(mutations)) {
+ $.each(mutations, function(evt, mutation) {
+ if (self._isChangeMutation(evt, mutation)) {
+ // We've found a change mutation.
+ // Let's escape from the loop and continue
+ changed = true;
+ return false;
+ }
+ });
}
+ return changed;
+ };
+
+ Select2.prototype._syncSubtree = function (evt, mutations) {
+ var changed = this._isChangeMutation(evt, mutations);
+ var self = this;
// Only re-pull the data if we think there is a change
if (changed) {
@@ -5466,7 +5799,8 @@ S2.define('select2/core',[
'open': 'opening',
'close': 'closing',
'select': 'selecting',
- 'unselect': 'unselecting'
+ 'unselect': 'unselecting',
+ 'clear': 'clearing'
};
if (args === undefined) {
@@ -5494,7 +5828,7 @@ S2.define('select2/core',[
};
Select2.prototype.toggleDropdown = function () {
- if (this.options.get('disabled')) {
+ if (this.isDisabled()) {
return;
}
@@ -5510,15 +5844,40 @@ S2.define('select2/core',[
return;
}
+ if (this.isDisabled()) {
+ return;
+ }
+
this.trigger('query', {});
};
- Select2.prototype.close = function () {
+ Select2.prototype.close = function (evt) {
if (!this.isOpen()) {
return;
}
- this.trigger('close', {});
+ this.trigger('close', { originalEvent : evt });
+ };
+
+ /**
+ * Helper method to abstract the "enabled" (not "disabled") state of this
+ * object.
+ *
+ * @return {true} if the instance is not disabled.
+ * @return {false} if the instance is disabled.
+ */
+ Select2.prototype.isEnabled = function () {
+ return !this.isDisabled();
+ };
+
+ /**
+ * Helper method to abstract the "disabled" state of this object.
+ *
+ * @return {true} if the disabled option is true.
+ * @return {false} if the disabled option is false.
+ */
+ Select2.prototype.isDisabled = function () {
+ return this.options.get('disabled');
};
Select2.prototype.isOpen = function () {
@@ -5595,7 +5954,7 @@ S2.define('select2/core',[
});
}
- this.$element.val(newVal).trigger('change');
+ this.$element.val(newVal).trigger('input').trigger('change');
};
Select2.prototype.destroy = function () {
@@ -5621,10 +5980,12 @@ S2.define('select2/core',[
this._syncS = null;
this.$element.off('.select2');
- this.$element.attr('tabindex', this.$element.data('old-tabindex'));
+ this.$element.attr('tabindex',
+ Utils.GetData(this.$element[0], 'old-tabindex'));
this.$element.removeClass('select2-hidden-accessible');
this.$element.attr('aria-hidden', 'false');
+ Utils.RemoveData(this.$element[0]);
this.$element.removeData('select2');
this.dataAdapter.destroy();
@@ -5652,7 +6013,7 @@ S2.define('select2/core',[
this.$container.addClass('select2-container--' + this.options.get('theme'));
- $container.data('element', this.$element);
+ Utils.StoreData($container[0], 'element', this.$element);
return $container;
};
@@ -5672,8 +6033,9 @@ S2.define('jquery.select2',[
'jquery-mousewheel',
'./select2/core',
- './select2/defaults'
-], function ($, _, Select2, Defaults) {
+ './select2/defaults',
+ './select2/utils'
+], function ($, _, Select2, Defaults, Utils) {
if ($.fn.select2 == null) {
// All methods that should return the element
var thisMethods = ['open', 'close', 'destroy'];
@@ -5694,7 +6056,7 @@ S2.define('jquery.select2',[
var args = Array.prototype.slice.call(arguments, 1);
this.each(function () {
- var instance = $(this).data('select2');
+ var instance = Utils.GetData(this, 'select2');
if (instance == null && window.console && console.error) {
console.error(
diff --git a/htdocs/includes/jquery/plugins/select2/dist/js/select2.min.js b/htdocs/includes/jquery/plugins/select2/dist/js/select2.min.js
index 7ef2fda809e..e4214264342 100644
--- a/htdocs/includes/jquery/plugins/select2/dist/js/select2.min.js
+++ b/htdocs/includes/jquery/plugins/select2/dist/js/select2.min.js
@@ -1 +1,2 @@
-/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=function(b,c){return void 0===c&&(c="undefined"!=typeof window?require("jquery"):require("jquery")(b)),a(c),c}:a(jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return v.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o=b&&b.split("/"),p=t.map,q=p&&p["*"]||{};if(a){for(a=a.split("/"),g=a.length-1,t.nodeIdCompat&&x.test(a[g])&&(a[g]=a[g].replace(x,"")),"."===a[0].charAt(0)&&o&&(n=o.slice(0,o.length-1),a=n.concat(a)),k=0;k0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}if((o||q)&&p){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),o)for(l=o.length;l>0;l-=1)if((e=p[o.slice(0,l).join("/")])&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&q&&q[d]&&(i=q[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){var d=w.call(arguments,0);return"string"!=typeof d[0]&&1===d.length&&d.push(null),o.apply(b,d.concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){r[a]=b}}function j(a){if(e(s,a)){var c=s[a];delete s[a],u[a]=!0,n.apply(b,c)}if(!e(r,a)&&!e(u,a))throw new Error("No "+a);return r[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return a?k(a):[]}function m(a){return function(){return t&&t.config&&t.config[a]||{}}}var n,o,p,q,r={},s={},t={},u={},v=Object.prototype.hasOwnProperty,w=[].slice,x=/\.js$/;p=function(a,b){var c,d=k(a),e=d[0],g=b[1];return a=d[1],e&&(e=f(e,g),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(g)):f(a,g):(a=f(a,g),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},q={require:function(a){return g(a)},exports:function(a){var b=r[a];return void 0!==b?b:r[a]={}},module:function(a){return{id:a,uri:"",exports:r[a],config:m(a)}}},n=function(a,c,d,f){var h,k,m,n,o,t,v,w=[],x=typeof d;if(f=f||a,t=l(f),"undefined"===x||"function"===x){for(c=!c.length&&d.length?["require","exports","module"]:c,o=0;o0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h":">",'"':""","'":"'","/":"/"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a(' '),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),d[0].className+=" select2-results__message",this.$results.append(d)},c.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c0?b.first().trigger("mouseenter"):a.first().trigger("mouseenter"),this.ensureHighlightVisible()},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()});b.$results.find(".select2-results__option[aria-selected]").each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("aria-selected","true"):b.attr("aria-selected","false")})})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"treeitem","aria-selected":"false"};b.disabled&&(delete d["aria-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["aria-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d.role="group",d["aria-label"]=b.text,delete d["aria-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";a(h);this.template(b,h);for(var i=[],j=0;j",{class:"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b,c){var d=this,e=b.id+"-results";this.$results.attr("id",e),b.on("results:all",function(a){d.clear(),d.append(a.data),b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("results:append",function(a){d.append(a.data),b.isOpen()&&d.setClasses()}),b.on("query",function(a){d.hideMessages(),d.showLoading(a)}),b.on("select",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("unselect",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("open",function(){d.$results.attr("aria-expanded","true"),d.$results.attr("aria-hidden","false"),d.setClasses(),d.ensureHighlightVisible()}),b.on("close",function(){d.$results.attr("aria-expanded","false"),d.$results.attr("aria-hidden","true"),d.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=d.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=d.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("aria-selected")?d.trigger("close",{}):d.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a);if(0!==c){var e=c-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top,h=f.offset().top,i=d.$results.scrollTop()+(h-g);0===e?d.$results.scrollTop(0):h-g<0&&d.$results.scrollTop(i)}}),b.on("results:next",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a),e=c+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top+d.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=d.$results.scrollTop()+h-g;0===e?d.$results.scrollTop(0):h>g&&d.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),b.on("results:message",function(a){d.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=d.$results.scrollTop(),c=d.$results.get(0).scrollHeight-b+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&c<=d.$results.height();e?(d.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(d.$results.scrollTop(d.$results.get(0).scrollHeight-d.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(b){var c=a(this),e=c.data("data");if("true"===c.attr("aria-selected"))return void(d.options.get("multiple")?d.trigger("unselect",{originalEvent:b,data:e}):d.trigger("close",{}));d.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(b){var c=a(this).data("data");d.getHighlightedResults().removeClass("select2-results__option--highlighted"),d.trigger("results:focus",{data:c,element:a(this)})})},c.prototype.getHighlightedResults=function(){return this.$results.find(".select2-results__option--highlighted")},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),c<=2?this.$results.scrollTop(0):(g>this.$results.outerHeight()||g<0)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a(' ');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a,b){var d=this,e=(a.id,a.id+"-results");this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),d.$selection.focus(),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2");a(".select2.select2-container--open").each(function(){var b=a(this);this!=d[0]&&b.data("element").select2("close")})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){b.find(".selection").append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html(' '),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d),this.$selection.attr("aria-labelledby",d),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()}),a.on("selection:update",function(a){c.update(a.data)})},e.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},e.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},e.prototype.selectionContainer=function(){return a(" ")},e.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.prop("title",b.title||b.text)},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html(''),a},d.prototype.bind=function(b,c){var e=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){e.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!e.options.get("disabled")){var c=a(this),d=c.parent(),f=d.data("data");e.trigger("unselect",{originalEvent:b,data:f})}})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},d.prototype.selectionContainer=function(){return a('× ')},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d1||c)return a.call(this,b);this.clear();var d=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(d)},b}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e0||0===c.length)){var d=a('× ');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a(' ');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.trigger("focus")}),b.on("close",function(){e.$search.val(""),e.$search.removeAttr("aria-activedescendant"),e.$search.trigger("focus")}),b.on("enable",function(){e.$search.prop("disabled",!1),e._transferTabIndex()}),b.on("disable",function(){e.$search.prop("disabled",!0)}),b.on("focus",function(a){e.$search.trigger("focus")}),b.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.id)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){if(a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented(),a.which===c.BACKSPACE&&""===e.$search.val()){var b=e.$searchContainer.prev(".select2-selection__choice");if(b.length>0){var d=b.data("data");e.searchRemoveChoice(d),a.preventDefault()}}});var f=document.documentMode,g=f&&f<=11;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){if(g)return void e.$selection.off("input.search input.searchcheck");e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(g&&"input"===a.type)return void e.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&e.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c&&this.$search.focus()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{a=.75*(this.$search.val().length+1)+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){return{"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"}}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),null!=c.id?d+="-"+c.id.toString():d+="-"+a.generateChars(4),d},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){d.status&&"0"===d.status||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h0&&b.term.length>this.maximumInputLength)return void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}});a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;if(d.maximumSelectionLength>0&&f>=d.maximumSelectionLength)return void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}});a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a(' ');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a(' ');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("focus",function(){c.isOpen()||e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){e.showSearch(a)?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){e.$results.offset().top+e.$results.outerHeight(!1)+50>=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1)&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a(' '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(" "),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(b){var c=a(this).data("select2-scroll-position");a(this).scrollTop(c.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id;this.$container.parents().filter(b.hasScroll).off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.topf.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),null==l.tokenSeparators&&null==l.tokenizer||(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){null==c(d,e.children[g])&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var h=b(e.text).toUpperCase(),i=b(d.term).toUpperCase();return h.indexOf(i)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)},new D}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return e<=0?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;h=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),null!=a&&0!==a.length||(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a(' ');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("jquery-mousewheel",["jquery"],function(a){return a}),b.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults"],function(a,b,c,d){if(null==a.fn.select2){var e=["open","close","destroy"];a.fn.select2=function(b){if("object"==typeof(b=b||{}))return this.each(function(){var d=a.extend(!0,{},b);new c(a(this),d)}),this;if("string"==typeof b){var d,f=Array.prototype.slice.call(arguments,1);return this.each(function(){var c=a(this).data("select2");null==c&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2."),d=c[b].apply(c,f)}),a.inArray(b,e)>-1?this:d}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c});
\ No newline at end of file
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+!function(n){"function"==typeof define&&define.amd?define(["jquery"],n):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),n(t),t}:n(jQuery)}(function(u){var e=function(){if(u&&u.fn&&u.fn.select2&&u.fn.select2.amd)var e=u.fn.select2.amd;var t,n,r,h,o,s,f,g,m,v,y,_,i,a,b;function w(e,t){return i.call(e,t)}function l(e,t){var n,r,i,o,s,a,l,c,u,d,p,h=t&&t.split("/"),f=y.map,g=f&&f["*"]||{};if(e){for(s=(e=e.split("/")).length-1,y.nodeIdCompat&&b.test(e[s])&&(e[s]=e[s].replace(b,"")),"."===e[0].charAt(0)&&h&&(e=h.slice(0,h.length-1).concat(e)),u=0;u":">",'"':""","'":"'","/":"/"};return"string"!=typeof e?e:String(e).replace(/[&<>"'\/\\]/g,function(e){return t[e]})},i.appendMany=function(e,t){if("1.7"===o.fn.jquery.substr(0,3)){var n=o();o.map(t,function(e){n=n.add(e)}),t=n}e.append(t)},i.__cache={};var n=0;return i.GetUniqueElementId=function(e){var t=e.getAttribute("data-select2-id");return null==t&&(e.id?(t=e.id,e.setAttribute("data-select2-id",t)):(e.setAttribute("data-select2-id",++n),t=n.toString())),t},i.StoreData=function(e,t,n){var r=i.GetUniqueElementId(e);i.__cache[r]||(i.__cache[r]={}),i.__cache[r][t]=n},i.GetData=function(e,t){var n=i.GetUniqueElementId(e);return t?i.__cache[n]&&null!=i.__cache[n][t]?i.__cache[n][t]:o(e).data(t):i.__cache[n]},i.RemoveData=function(e){var t=i.GetUniqueElementId(e);null!=i.__cache[t]&&delete i.__cache[t],e.removeAttribute("data-select2-id")},i}),e.define("select2/results",["jquery","./utils"],function(h,f){function r(e,t,n){this.$element=e,this.data=n,this.options=t,r.__super__.constructor.call(this)}return f.Extend(r,f.Observable),r.prototype.render=function(){var e=h('');return this.options.get("multiple")&&e.attr("aria-multiselectable","true"),this.$results=e},r.prototype.clear=function(){this.$results.empty()},r.prototype.displayMessage=function(e){var t=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var n=h(' '),r=this.options.get("translations").get(e.message);n.append(t(r(e.args))),n[0].className+=" select2-results__message",this.$results.append(n)},r.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},r.prototype.append=function(e){this.hideLoading();var t=[];if(null!=e.results&&0!==e.results.length){e.results=this.sort(e.results);for(var n=0;n",{class:"select2-results__options select2-results__options--nested"});p.append(l),s.append(a),s.append(p)}else this.template(e,t);return f.StoreData(t,"data",e),t},r.prototype.bind=function(t,e){var l=this,n=t.id+"-results";this.$results.attr("id",n),t.on("results:all",function(e){l.clear(),l.append(e.data),t.isOpen()&&(l.setClasses(),l.highlightFirstItem())}),t.on("results:append",function(e){l.append(e.data),t.isOpen()&&l.setClasses()}),t.on("query",function(e){l.hideMessages(),l.showLoading(e)}),t.on("select",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("unselect",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("open",function(){l.$results.attr("aria-expanded","true"),l.$results.attr("aria-hidden","false"),l.setClasses(),l.ensureHighlightVisible()}),t.on("close",function(){l.$results.attr("aria-expanded","false"),l.$results.attr("aria-hidden","true"),l.$results.removeAttr("aria-activedescendant")}),t.on("results:toggle",function(){var e=l.getHighlightedResults();0!==e.length&&e.trigger("mouseup")}),t.on("results:select",function(){var e=l.getHighlightedResults();if(0!==e.length){var t=f.GetData(e[0],"data");"true"==e.attr("aria-selected")?l.trigger("close",{}):l.trigger("select",{data:t})}}),t.on("results:previous",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e);if(!(n<=0)){var r=n-1;0===e.length&&(r=0);var i=t.eq(r);i.trigger("mouseenter");var o=l.$results.offset().top,s=i.offset().top,a=l.$results.scrollTop()+(s-o);0===r?l.$results.scrollTop(0):s-o<0&&l.$results.scrollTop(a)}}),t.on("results:next",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e)+1;if(!(n>=t.length)){var r=t.eq(n);r.trigger("mouseenter");var i=l.$results.offset().top+l.$results.outerHeight(!1),o=r.offset().top+r.outerHeight(!1),s=l.$results.scrollTop()+o-i;0===n?l.$results.scrollTop(0):ithis.$results.outerHeight()||o<0)&&this.$results.scrollTop(i)}},r.prototype.template=function(e,t){var n=this.options.get("templateResult"),r=this.options.get("escapeMarkup"),i=n(e,t);null==i?t.style.display="none":"string"==typeof i?t.innerHTML=r(i):h(t).append(i)},r}),e.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),e.define("select2/selection/base",["jquery","../utils","../keys"],function(n,r,i){function o(e,t){this.$element=e,this.options=t,o.__super__.constructor.call(this)}return r.Extend(o,r.Observable),o.prototype.render=function(){var e=n(' ');return this._tabindex=0,null!=r.GetData(this.$element[0],"old-tabindex")?this._tabindex=r.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),e.attr("title",this.$element.attr("title")),e.attr("tabindex",this._tabindex),e.attr("aria-disabled","false"),this.$selection=e},o.prototype.bind=function(e,t){var n=this,r=e.id+"-results";this.container=e,this.$selection.on("focus",function(e){n.trigger("focus",e)}),this.$selection.on("blur",function(e){n._handleBlur(e)}),this.$selection.on("keydown",function(e){n.trigger("keypress",e),e.which===i.SPACE&&e.preventDefault()}),e.on("results:focus",function(e){n.$selection.attr("aria-activedescendant",e.data._resultId)}),e.on("selection:update",function(e){n.update(e.data)}),e.on("open",function(){n.$selection.attr("aria-expanded","true"),n.$selection.attr("aria-owns",r),n._attachCloseHandler(e)}),e.on("close",function(){n.$selection.attr("aria-expanded","false"),n.$selection.removeAttr("aria-activedescendant"),n.$selection.removeAttr("aria-owns"),n.$selection.trigger("focus"),n._detachCloseHandler(e)}),e.on("enable",function(){n.$selection.attr("tabindex",n._tabindex),n.$selection.attr("aria-disabled","false")}),e.on("disable",function(){n.$selection.attr("tabindex","-1"),n.$selection.attr("aria-disabled","true")})},o.prototype._handleBlur=function(e){var t=this;window.setTimeout(function(){document.activeElement==t.$selection[0]||n.contains(t.$selection[0],document.activeElement)||t.trigger("blur",e)},1)},o.prototype._attachCloseHandler=function(e){n(document.body).on("mousedown.select2."+e.id,function(e){var t=n(e.target).closest(".select2");n(".select2.select2-container--open").each(function(){this!=t[0]&&r.GetData(this,"element").select2("close")})})},o.prototype._detachCloseHandler=function(e){n(document.body).off("mousedown.select2."+e.id)},o.prototype.position=function(e,t){t.find(".selection").append(e)},o.prototype.destroy=function(){this._detachCloseHandler(this.container)},o.prototype.update=function(e){throw new Error("The `update` method must be defined in child classes.")},o.prototype.isEnabled=function(){return!this.isDisabled()},o.prototype.isDisabled=function(){return this.options.get("disabled")},o}),e.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(e,t,n,r){function i(){i.__super__.constructor.apply(this,arguments)}return n.Extend(i,t),i.prototype.render=function(){var e=i.__super__.render.call(this);return e.addClass("select2-selection--single"),e.html(' '),e},i.prototype.bind=function(t,e){var n=this;i.__super__.bind.apply(this,arguments);var r=t.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",r).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",r),this.$selection.on("mousedown",function(e){1===e.which&&n.trigger("toggle",{originalEvent:e})}),this.$selection.on("focus",function(e){}),this.$selection.on("blur",function(e){}),t.on("focus",function(e){t.isOpen()||n.$selection.trigger("focus")})},i.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},i.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},i.prototype.selectionContainer=function(){return e(" ")},i.prototype.update=function(e){if(0!==e.length){var t=e[0],n=this.$selection.find(".select2-selection__rendered"),r=this.display(t,n);n.empty().append(r);var i=t.title||t.text;i?n.attr("title",i):n.removeAttr("title")}else this.clear()},i}),e.define("select2/selection/multiple",["jquery","./base","../utils"],function(i,e,l){function n(e,t){n.__super__.constructor.apply(this,arguments)}return l.Extend(n,e),n.prototype.render=function(){var e=n.__super__.render.call(this);return e.addClass("select2-selection--multiple"),e.html(''),e},n.prototype.bind=function(e,t){var r=this;n.__super__.bind.apply(this,arguments),this.$selection.on("click",function(e){r.trigger("toggle",{originalEvent:e})}),this.$selection.on("click",".select2-selection__choice__remove",function(e){if(!r.isDisabled()){var t=i(this).parent(),n=l.GetData(t[0],"data");r.trigger("unselect",{originalEvent:e,data:n})}})},n.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},n.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},n.prototype.selectionContainer=function(){return i('× ')},n.prototype.update=function(e){if(this.clear(),0!==e.length){for(var t=[],n=0;n× ');a.StoreData(r[0],"data",t),this.$selection.find(".select2-selection__rendered").prepend(r)}},e}),e.define("select2/selection/search",["jquery","../utils","../keys"],function(r,a,l){function e(e,t,n){e.call(this,t,n)}return e.prototype.render=function(e){var t=r(' ');this.$searchContainer=t,this.$search=t.find("input");var n=e.call(this);return this._transferTabIndex(),n},e.prototype.bind=function(e,t,n){var r=this,i=t.id+"-results";e.call(this,t,n),t.on("open",function(){r.$search.attr("aria-controls",i),r.$search.trigger("focus")}),t.on("close",function(){r.$search.val(""),r.$search.removeAttr("aria-controls"),r.$search.removeAttr("aria-activedescendant"),r.$search.trigger("focus")}),t.on("enable",function(){r.$search.prop("disabled",!1),r._transferTabIndex()}),t.on("disable",function(){r.$search.prop("disabled",!0)}),t.on("focus",function(e){r.$search.trigger("focus")}),t.on("results:focus",function(e){e.data._resultId?r.$search.attr("aria-activedescendant",e.data._resultId):r.$search.removeAttr("aria-activedescendant")}),this.$selection.on("focusin",".select2-search--inline",function(e){r.trigger("focus",e)}),this.$selection.on("focusout",".select2-search--inline",function(e){r._handleBlur(e)}),this.$selection.on("keydown",".select2-search--inline",function(e){if(e.stopPropagation(),r.trigger("keypress",e),r._keyUpPrevented=e.isDefaultPrevented(),e.which===l.BACKSPACE&&""===r.$search.val()){var t=r.$searchContainer.prev(".select2-selection__choice");if(0this.maximumInputLength?this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e}),e.define("select2/data/maximumSelectionLength",[],function(){function e(e,t,n){this.maximumSelectionLength=n.get("maximumSelectionLength"),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var r=this;e.call(this,t,n),t.on("select",function(){r._checkIfMaximumSelected()})},e.prototype.query=function(e,t,n){var r=this;this._checkIfMaximumSelected(function(){e.call(r,t,n)})},e.prototype._checkIfMaximumSelected=function(e,n){var r=this;this.current(function(e){var t=null!=e?e.length:0;0=r.maximumSelectionLength?r.trigger("results:message",{message:"maximumSelected",args:{maximum:r.maximumSelectionLength}}):n&&n()})},e}),e.define("select2/dropdown",["jquery","./utils"],function(t,e){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return e.Extend(n,e.Observable),n.prototype.render=function(){var e=t(' ');return e.attr("dir",this.options.get("dir")),this.$dropdown=e},n.prototype.bind=function(){},n.prototype.position=function(e,t){},n.prototype.destroy=function(){this.$dropdown.remove()},n}),e.define("select2/dropdown/search",["jquery","../utils"],function(o,e){function t(){}return t.prototype.render=function(e){var t=e.call(this),n=o(' ');return this.$searchContainer=n,this.$search=n.find("input"),t.prepend(n),t},t.prototype.bind=function(e,t,n){var r=this,i=t.id+"-results";e.call(this,t,n),this.$search.on("keydown",function(e){r.trigger("keypress",e),r._keyUpPrevented=e.isDefaultPrevented()}),this.$search.on("input",function(e){o(this).off("keyup")}),this.$search.on("keyup input",function(e){r.handleSearch(e)}),t.on("open",function(){r.$search.attr("tabindex",0),r.$search.attr("aria-controls",i),r.$search.trigger("focus"),window.setTimeout(function(){r.$search.trigger("focus")},0)}),t.on("close",function(){r.$search.attr("tabindex",-1),r.$search.removeAttr("aria-controls"),r.$search.removeAttr("aria-activedescendant"),r.$search.val(""),r.$search.trigger("blur")}),t.on("focus",function(){t.isOpen()||r.$search.trigger("focus")}),t.on("results:all",function(e){null!=e.query.term&&""!==e.query.term||(r.showSearch(e)?r.$searchContainer.removeClass("select2-search--hide"):r.$searchContainer.addClass("select2-search--hide"))}),t.on("results:focus",function(e){e.data._resultId?r.$search.attr("aria-activedescendant",e.data._resultId):r.$search.removeAttr("aria-activedescendant")})},t.prototype.handleSearch=function(e){if(!this._keyUpPrevented){var t=this.$search.val();this.trigger("query",{term:t})}this._keyUpPrevented=!1},t.prototype.showSearch=function(e,t){return!0},t}),e.define("select2/dropdown/hidePlaceholder",[],function(){function e(e,t,n,r){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n,r)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return"string"==typeof t&&(t={id:"",text:t}),t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),r=t.length-1;0<=r;r--){var i=t[r];this.placeholder.id===i.id&&n.splice(r,1)}return n},e}),e.define("select2/dropdown/infiniteScroll",["jquery"],function(n){function e(e,t,n,r){this.lastParams={},e.call(this,t,n,r),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return e.prototype.append=function(e,t){this.$loadingMore.remove(),this.loading=!1,e.call(this,t),this.showLoadingMore(t)&&(this.$results.append(this.$loadingMore),this.loadMoreIfNeeded())},e.prototype.bind=function(e,t,n){var r=this;e.call(this,t,n),t.on("query",function(e){r.lastParams=e,r.loading=!0}),t.on("query:append",function(e){r.lastParams=e,r.loading=!0}),this.$results.on("scroll",this.loadMoreIfNeeded.bind(this))},e.prototype.loadMoreIfNeeded=function(){var e=n.contains(document.documentElement,this.$loadingMore[0]);if(!this.loading&&e){var t=this.$results.offset().top+this.$results.outerHeight(!1);this.$loadingMore.offset().top+this.$loadingMore.outerHeight(!1)<=t+50&&this.loadMore()}},e.prototype.loadMore=function(){this.loading=!0;var e=n.extend({},{page:1},this.lastParams);e.page++,this.trigger("query:append",e)},e.prototype.showLoadingMore=function(e,t){return t.pagination&&t.pagination.more},e.prototype.createLoadingMore=function(){var e=n(' '),t=this.options.get("translations").get("loadingMore");return e.html(t(this.lastParams)),e},e}),e.define("select2/dropdown/attachBody",["jquery","../utils"],function(f,a){function e(e,t,n){this.$dropdownParent=f(n.get("dropdownParent")||document.body),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var r=this;e.call(this,t,n),t.on("open",function(){r._showDropdown(),r._attachPositioningHandler(t),r._bindContainerResultHandlers(t)}),t.on("close",function(){r._hideDropdown(),r._detachPositioningHandler(t)}),this.$dropdownContainer.on("mousedown",function(e){e.stopPropagation()})},e.prototype.destroy=function(e){e.call(this),this.$dropdownContainer.remove()},e.prototype.position=function(e,t,n){t.attr("class",n.attr("class")),t.removeClass("select2"),t.addClass("select2-container--open"),t.css({position:"absolute",top:-999999}),this.$container=n},e.prototype.render=function(e){var t=f(" "),n=e.call(this);return t.append(n),this.$dropdownContainer=t},e.prototype._hideDropdown=function(e){this.$dropdownContainer.detach()},e.prototype._bindContainerResultHandlers=function(e,t){if(!this._containerResultsHandlersBound){var n=this;t.on("results:all",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:append",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:message",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("select",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("unselect",function(){n._positionDropdown(),n._resizeDropdown()}),this._containerResultsHandlersBound=!0}},e.prototype._attachPositioningHandler=function(e,t){var n=this,r="scroll.select2."+t.id,i="resize.select2."+t.id,o="orientationchange.select2."+t.id,s=this.$container.parents().filter(a.hasScroll);s.each(function(){a.StoreData(this,"select2-scroll-position",{x:f(this).scrollLeft(),y:f(this).scrollTop()})}),s.on(r,function(e){var t=a.GetData(this,"select2-scroll-position");f(this).scrollTop(t.y)}),f(window).on(r+" "+i+" "+o,function(e){n._positionDropdown(),n._resizeDropdown()})},e.prototype._detachPositioningHandler=function(e,t){var n="scroll.select2."+t.id,r="resize.select2."+t.id,i="orientationchange.select2."+t.id;this.$container.parents().filter(a.hasScroll).off(n),f(window).off(n+" "+r+" "+i)},e.prototype._positionDropdown=function(){var e=f(window),t=this.$dropdown.hasClass("select2-dropdown--above"),n=this.$dropdown.hasClass("select2-dropdown--below"),r=null,i=this.$container.offset();i.bottom=i.top+this.$container.outerHeight(!1);var o={height:this.$container.outerHeight(!1)};o.top=i.top,o.bottom=i.top+o.height;var s=this.$dropdown.outerHeight(!1),a=e.scrollTop(),l=e.scrollTop()+e.height(),c=ai.bottom+s,d={left:i.left,top:o.bottom},p=this.$dropdownParent;"static"===p.css("position")&&(p=p.offsetParent());var h={top:0,left:0};(f.contains(document.body,p[0])||p[0].isConnected)&&(h=p.offset()),d.top-=h.top,d.left-=h.left,t||n||(r="below"),u||!c||t?!c&&u&&t&&(r="below"):r="above",("above"==r||t&&"below"!==r)&&(d.top=o.top-h.top-s),null!=r&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+r),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+r)),this.$dropdownContainer.css(d)},e.prototype._resizeDropdown=function(){var e={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(e.minWidth=e.width,e.position="relative",e.width="auto"),this.$dropdown.css(e)},e.prototype._showDropdown=function(e){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},e}),e.define("select2/dropdown/minimumResultsForSearch",[],function(){function e(e,t,n,r){this.minimumResultsForSearch=n.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),e.call(this,t,n,r)}return e.prototype.showSearch=function(e,t){return!(function e(t){for(var n=0,r=0;r ');return e.attr("dir",this.options.get("dir")),this.$container=e,this.$container.addClass("select2-container--"+this.options.get("theme")),u.StoreData(e[0],"element",this.$element),e},d}),e.define("jquery-mousewheel",["jquery"],function(e){return e}),e.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults","./select2/utils"],function(i,e,o,t,s){if(null==i.fn.select2){var a=["open","close","destroy"];i.fn.select2=function(t){if("object"==typeof(t=t||{}))return this.each(function(){var e=i.extend(!0,{},t);new o(i(this),e)}),this;if("string"!=typeof t)throw new Error("Invalid arguments for Select2: "+t);var n,r=Array.prototype.slice.call(arguments,1);return this.each(function(){var e=s.GetData(this,"select2");null==e&&window.console&&console.error&&console.error("The select2('"+t+"') method was called on an element that is not using Select2."),n=e[t].apply(e,r)}),-1
* Original author: Victor Stanciu
*
- * @version 2.8.33
+ * @version 2.8.34
*/
class Mobile_Detect
{
@@ -61,7 +61,7 @@ class Mobile_Detect
/**
* Stores the version number of the current release.
*/
- const VERSION = '2.8.33';
+ const VERSION = '2.8.34';
/**
* A type for the version() method indicating a string return value.
@@ -164,14 +164,14 @@ class Mobile_Detect
*/
protected static $phoneDevices = array(
'iPhone' => '\biPhone\b|\biPod\b', // |\biTunes
- 'BlackBerry' => 'BlackBerry|\bBB10\b|rim[0-9]+',
+ 'BlackBerry' => 'BlackBerry|\bBB10\b|rim[0-9]+|\b(BBA100|BBB100|BBD100|BBE100|BBF100|STH100)\b-[0-9]+',
'HTC' => 'HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\bEVO\b|T-Mobile G1|Z520m|Android [0-9.]+; Pixel',
'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 6',
// @todo: Is 'Dell Streak' a tablet or a phone? ;)
'Dell' => 'Dell[;]? (Streak|Aero|Venue|Venue Pro|Flash|Smoke|Mini 3iX)|XCD28|XCD35|\b001DL\b|\b101DL\b|\bGS01\b',
'Motorola' => 'Motorola|DROIDX|DROID BIONIC|\bDroid\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\bMoto E\b|XT1068|XT1092|XT1052',
'Samsung' => '\bSamsung\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F|SM-J330F',
- 'LG' => '\bLG\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323|M257)',
+ 'LG' => '\bLG\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323|M257)|LM-G710',
'Sony' => 'SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533',
'Asus' => 'Asus.*Galaxy|PadFone.*Mobile',
'NokiaLumia' => 'Lumia [0-9]{3,4}',
@@ -201,6 +201,7 @@ class Mobile_Detect
'Amoi' => 'Amoi',
// http://en.wikipedia.org/wiki/INQ
'INQ' => 'INQ',
+ 'OnePlus' => 'ONEPLUS',
// @Tapatalk is a mobile app; http://support.tapatalk.com/threads/smf-2-0-2-os-and-browser-detection-plugin-and-tapatalk.15565/#post-79039
'GenericPhone' => 'Tapatalk|PDA;|SAGEM|\bmmp\b|pocket|\bpsp\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\bwap\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser',
);
@@ -219,7 +220,7 @@ class Mobile_Detect
'NexusTablet' => 'Android.*Nexus[\s]+(7|9|10)',
// https://en.wikipedia.org/wiki/Pixel_C
'GoogleTablet' => 'Android.*Pixel C',
- 'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y|SM-T585|SM-T285|SM-T825|SM-W708|SM-T835', // SCH-P709|SCH-P729|SM-T2558|GT-I9205 - Samsung Mega - treat them like a regular phone.
+ 'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y|SM-T585|SM-T285|SM-T825|SM-W708|SM-T835|SM-T830|SM-T837V|SM-T720|SM-T510|SM-T387V', // SCH-P709|SCH-P729|SM-T2558|GT-I9205 - Samsung Mega - treat them like a regular phone.
// http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html
'Kindle' => 'Kindle|Silk.*Accelerated|Android.*\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\b|Android.*Silk/[0-9.]+ like Chrome/[0-9.]+ (?!Mobile)',
// Only the Surface tablets with Windows RT are considered mobile.
@@ -251,7 +252,7 @@ class Mobile_Detect
// Prestigio Tablets http://www.prestigio.com/support
'PrestigioTablet' => 'PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002',
// http://support.lenovo.com/en_GB/downloads/default.page?#
- 'LenovoTablet' => 'Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304F|TB-X304L|TB-8703F|Tab2A7-10F|TB2-X30L',
+ 'LenovoTablet' => 'Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304X|TB-X304F|TB-X304L|TB-X505F|TB-X505L|TB-X505X|TB-X605F|TB-X605L|TB-8703F|TB-8703X|TB-8703N|TB-8704N|TB-8704F|TB-8704X|TB-8704V|TB-7304F|TB-7304I|TB-7304X|Tab2A7-10F|Tab2A7-20F|TB2-X30L|YT3-X50L|YT3-X50F|YT3-X50M|YT-X705F|YT-X703F|YT-X703L|YT-X705L|YT-X705X|TB2-X30F|TB2-X30L|TB2-X30M|A2107A-F|A2107A-H|TB3-730F|TB3-730M|TB3-730X|TB-7504F|TB-7504X',
// http://www.dell.com/support/home/us/en/04/Products/tab_mob/tablets
'DellTablet' => 'Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7',
// http://www.yarvik.com/en/matrix/tablets/
@@ -301,10 +302,10 @@ class Mobile_Detect
// http://www.fly-phone.com/devices/tablets/ ; http://www.fly-phone.com/service/
'FlyTablet' => 'IQ310|Fly Vision',
// http://www.bqreaders.com/gb/tablets-prices-sale.html
- 'bqTablet' => 'Android.*(bq)?.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))|Maxwell.*Lite|Maxwell.*Plus',
+ 'bqTablet' => 'Android.*(bq)?.*\b(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))\b|Maxwell.*Lite|Maxwell.*Plus',
// http://www.huaweidevice.com/worldwide/productFamily.do?method=index&directoryId=5011&treeId=3290
// http://www.huaweidevice.com/worldwide/downloadCenter.do?method=index&directoryId=3372&treeId=0&tb=1&type=software (including legacy tablets)
- 'HuaweiTablet' => 'MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L|BAH-L09|BAH-W09',
+ 'HuaweiTablet' => 'MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L|BAH-L09|BAH-W09|AGS-L09|CMR-AL19',
// Nec or Medias Tab
'NecTablet' => '\bN-06D|\bN-08D',
// Pantech Tablets: http://www.pantechusa.com/phones/
@@ -314,7 +315,7 @@ class Mobile_Detect
// http://versusuk.com/support.html
'VersusTablet' => 'TOUCHPAD.*[78910]|\bTOUCHTAB\b',
// http://www.zync.in/index.php/our-products/tablet-phablets
- 'ZyncTablet' => 'z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900',
+ 'ZyncTablet' => 'z1000|Z99 2G|z930|z990|z909|Z919|z900', // Removed "z999" because of https://github.com/serbanghita/Mobile-Detect/issues/717
// http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/
'PositivoTablet' => 'TB07STA|TB10STA|TB07FTA|TB10FTA',
// https://www.nabitablet.com/
@@ -377,7 +378,7 @@ class Mobile_Detect
'GoCleverTablet' => 'GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042',
// Modecom Tablets - http://www.modecom.eu/tablets/portal/
'ModecomTablet' => 'FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003',
- // Vonino Tablets - http://www.vonino.eu/tablets
+ // Vonino Tablets
'VoninoTablet' => '\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\bQ8\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\b',
// ECS Tablets - http://www.ecs.com.tw/ECSWebSite/Product/Product_Tablet_List.aspx?CategoryID=14&MenuID=107&childid=M_107&LanID=0
'ECSTablet' => 'V07OT2|TM105A|S10OT1|TR10CS1',
@@ -385,7 +386,7 @@ class Mobile_Detect
// @note: no need to add all the tablet codes since they are guided by the first regex.
'StorexTablet' => 'eZee[_\']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab',
// Generic Vodafone tablets.
- 'VodafoneTablet' => 'SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497',
+ 'VodafoneTablet' => 'SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497|VFD 1400',
// French tablets - Essentiel B http://www.boulanger.fr/tablette_tactile_e-book/tablette_tactile_essentiel_b/cl_68908.htm?multiChoiceToDelete=brand&mc_brand=essentielb
// Aka: http://www.essentielb.fr/
'EssentielBTablet' => 'Smart[ \']?TAB[ ]+?[0-9]+|Family[ \']?TAB2',
@@ -484,7 +485,7 @@ class Mobile_Detect
'PalmOS' => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino',
'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\bS60\b',
// @reference: http://en.wikipedia.org/wiki/Windows_Mobile
- 'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;',
+ 'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Windows Mobile|Windows Phone [0-9.]+|WCE;',
// @reference: http://en.wikipedia.org/wiki/Windows_Phone
// http://wifeng.cn/?r=blog&a=view&id=106
// http://nicksnettravels.builttoroam.com/post/2011/01/10/Bogus-Windows-Phone-7-User-Agent-String.aspx
@@ -492,6 +493,8 @@ class Mobile_Detect
// https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx
'WindowsPhoneOS' => 'Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;',
'iOS' => '\biPhone.*Mobile|\biPod|\biPad|AppleCoreMedia',
+ // https://en.wikipedia.org/wiki/IPadOS
+ 'iPadOS' => 'CPU OS 13',
// http://en.wikipedia.org/wiki/MeeGo
// @todo: research MeeGo in UAs
'MeeGoOS' => 'MeeGo',
@@ -539,7 +542,8 @@ class Mobile_Detect
// https://github.com/serbanghita/Mobile-Detect/issues/7
'DiigoBrowser' => 'DiigoBrowser',
// http://www.puffinbrowser.com/index.php
- 'Puffin' => 'Puffin',
+ // https://github.com/serbanghita/Mobile-Detect/issues/752
+ // 'Puffin' => 'Puffin',
// http://mercury-browser.com/index.html
'Mercury' => '\bMercury\b',
// http://en.wikipedia.org/wiki/Obigo_Browser
@@ -563,7 +567,7 @@ class Mobile_Detect
// http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/
// https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011
// https://developers.facebook.com/docs/sharing/best-practices
- 'Bot' => 'Googlebot|facebookexternalhit|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom',
+ 'Bot' => 'Googlebot|facebookexternalhit|Google-AMPHTML|s~amp-validator|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom|contentkingapp',
'MobileBot' => 'Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker/M1A1-R2D2',
'DesktopMode' => 'WPDesktop',
'TV' => 'SonyDTV|HbbTV', // experimental
diff --git a/htdocs/includes/mobiledetect/mobiledetectlib/README.md b/htdocs/includes/mobiledetect/mobiledetectlib/README.md
index 310d9f3661d..d73757b728f 100644
--- a/htdocs/includes/mobiledetect/mobiledetectlib/README.md
+++ b/htdocs/includes/mobiledetect/mobiledetectlib/README.md
@@ -68,13 +68,13 @@ or include the dependency in the `composer.json` file:
#### Demo
-* [:iphone: Live demo!](http://is.gd/mobiletest)
+* [:iphone: Live demo!](http://demo.mobiledetect.net)
* [Code examples](../../wiki/Code-examples)
#### Contribute
*Submit a PR*
-> Submit a pull request but before make sure you read [how to contribute](../../docs/CONTRIBUTING.md) guide.
+> Submit a pull request but before make sure you read [how to contribute](docs/CONTRIBUTING.md) guide.
*Donate*
@@ -92,7 +92,7 @@ Special thanks to the community :+1: for donations, JetBrains team for the conti
> [Submit new module, plugin, port](../../issues/new?title=New%203rd%20party%20module&body=Name,%20Link%20and%20Description%20of%20the%20module.)
:point_right: Keep `Mobile_Detect.php` class in a separate `module` and do NOT include it in your script core because of the high frequency of updates.
-:point_right: When including the class into you `web application` or `module` always use `include_once '../path/to/Mobile_Detect.php` to prevent conflicts.
+:point_right: When including the class into your `web application` or `module` always use `include_once '../path/to/Mobile_Detect.php` to prevent conflicts.
**JavaScript**
diff --git a/htdocs/includes/mobiledetect/mobiledetectlib/composer.json b/htdocs/includes/mobiledetect/mobiledetectlib/composer.json
index 25cd99a375f..738f8f8831f 100644
--- a/htdocs/includes/mobiledetect/mobiledetectlib/composer.json
+++ b/htdocs/includes/mobiledetect/mobiledetectlib/composer.json
@@ -1,31 +1,42 @@
{
- "name": "mobiledetect/mobiledetectlib",
- "type": "library",
- "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.",
- "keywords": ["mobile", "mobile detect", "mobile detector", "php mobile detect", "detect mobile devices"],
- "homepage": "https://github.com/serbanghita/Mobile-Detect",
- "license": "MIT",
- "authors": [
- {
- "name": "Serban Ghita",
- "email": "serbanghita@gmail.com",
- "homepage": "http://mobiledetect.net",
- "role": "Developer"
- }
- ],
- "require": {
- "php": ">=5.0.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.8.35||~5.7"
- },
- "autoload": {
- "classmap": ["Mobile_Detect.php"],
- "psr-0": {
- "Detection": "namespaced/"
- }
- },
- "archive": {
- "exclude": ["docs", "examples", "export"]
- }
-}
+ "name" : "mobiledetect/mobiledetectlib",
+ "type" : "library",
+ "description" : "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.",
+ "keywords" : [
+ "mobile",
+ "mobile detect",
+ "mobile detector",
+ "php mobile detect",
+ "detect mobile devices"
+ ],
+ "homepage" : "https://github.com/serbanghita/Mobile-Detect",
+ "license" : "MIT",
+ "authors" : [{
+ "name" : "Serban Ghita",
+ "email" : "serbanghita@gmail.com",
+ "homepage" : "http://mobiledetect.net",
+ "role" : "Developer"
+ }
+ ],
+ "require" : {
+ "php" : ">=5.0.0"
+ },
+ "require-dev" : {
+ "phpunit/phpunit" : "~4.8.35||~5.7"
+ },
+ "autoload" : {
+ "classmap" : [
+ "Mobile_Detect.php"
+ ],
+ "psr-0" : {
+ "Detection" : "namespaced/"
+ }
+ },
+ "archive" : {
+ "exclude" : [
+ "docs",
+ "examples",
+ "export"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/htdocs/includes/mobiledetect/mobiledetectlib/docker-compose.yml b/htdocs/includes/mobiledetect/mobiledetectlib/docker-compose.yml
new file mode 100644
index 00000000000..58ce75e879c
--- /dev/null
+++ b/htdocs/includes/mobiledetect/mobiledetectlib/docker-compose.yml
@@ -0,0 +1,16 @@
+app:
+ restart: 'on-failure'
+ image: php:7
+ working_dir: /app
+ command: vendor/bin/phpunit -v -c tests/phpunit.xml --coverage-text --strict-coverage --stop-on-risky
+ ports:
+ - "8000:8000"
+ volumes:
+ - .:/app
+
+composer:
+ restart: 'no'
+ image: composer/composer:php7
+ command: install
+ volumes:
+ - .:/app
\ No newline at end of file
diff --git a/htdocs/includes/mobiledetect/mobiledetectlib/docs/KNOWN_LIMITATIONS.md b/htdocs/includes/mobiledetect/mobiledetectlib/docs/KNOWN_LIMITATIONS.md
index 8b5d461fe38..5887092f1f8 100644
--- a/htdocs/includes/mobiledetect/mobiledetectlib/docs/KNOWN_LIMITATIONS.md
+++ b/htdocs/includes/mobiledetect/mobiledetectlib/docs/KNOWN_LIMITATIONS.md
@@ -3,7 +3,8 @@
* Mobile Detect script was designed to detect `mobile` devices. Implicitly other devices are considered to be `desktop`.
* User-Agent and HTTP headers sniffing is a non reliable method of detecting a mobile device.
* If the mobile browser is set on `Desktop mode`, the Mobile Detect script has no way of knowing that the device is `mobile`.
-* Some touchscreen devices (eg. Microsoft Surface) are tough to detect as mobile since they can be used in a laptop mode.
+* Some touchscreen devices (eg. Microsoft Surface) are tough to detect as mobile since they can be used in a laptop mode. See: [#32](https://github.com/serbanghita/Mobile-Detect/issues/32), [#461](https://github.com/serbanghita/Mobile-Detect/issues/461), [#667](https://github.com/serbanghita/Mobile-Detect/issues/667)
+* Some mobile devices (eg. IPadOS, Google Pixel Slate). See: [#795](https://github.com/serbanghita/Mobile-Detect/issues/795), [#788](https://github.com/serbanghita/Mobile-Detect/issues/788)
* Detecting the device brand (eg. Apple, Samsung, HTC) is not 100% reliable.
* We don't monitor the quality of the 3rd party tools based on Mobile Detect script.
We cannot guarantee that they are using the class properly or if they provide the latest version.
diff --git a/htdocs/includes/nnnick/chartjs/.codeclimate.yml b/htdocs/includes/nnnick/chartjs/.codeclimate.yml
new file mode 100644
index 00000000000..0b8340feb58
--- /dev/null
+++ b/htdocs/includes/nnnick/chartjs/.codeclimate.yml
@@ -0,0 +1,19 @@
+version: "2"
+plugins:
+ duplication:
+ enabled: true
+ config:
+ languages:
+ - javascript
+ fixme:
+ enabled: true
+exclude_patterns:
+ - "dist/"
+ - "docs/"
+ - "samples/"
+ - "scripts/"
+ - "test/"
+ - "*.js"
+ - "*.json"
+ - "*.md"
+ - ".*"
diff --git a/htdocs/includes/nnnick/chartjs/.editorconfig b/htdocs/includes/nnnick/chartjs/.editorconfig
new file mode 100644
index 00000000000..922810ad734
--- /dev/null
+++ b/htdocs/includes/nnnick/chartjs/.editorconfig
@@ -0,0 +1,18 @@
+# https://editorconfig.org
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[gulpfile.js]
+indent_style = space
+indent_size = 2
+
+[*.yml]
+indent_style = space
+indent_size = 2
diff --git a/htdocs/includes/nnnick/chartjs/.eslintignore b/htdocs/includes/nnnick/chartjs/.eslintignore
new file mode 100644
index 00000000000..96212a3593b
--- /dev/null
+++ b/htdocs/includes/nnnick/chartjs/.eslintignore
@@ -0,0 +1 @@
+**/*{.,-}min.js
diff --git a/htdocs/includes/nnnick/chartjs/.eslintrc.yml b/htdocs/includes/nnnick/chartjs/.eslintrc.yml
new file mode 100644
index 00000000000..b0d9d5695a9
--- /dev/null
+++ b/htdocs/includes/nnnick/chartjs/.eslintrc.yml
@@ -0,0 +1,7 @@
+extends: chartjs
+
+env:
+ browser: true
+ node: true
+
+plugins: ['html']
diff --git a/htdocs/includes/nnnick/chartjs/.gitignore b/htdocs/includes/nnnick/chartjs/.gitignore
new file mode 100644
index 00000000000..c4998047b01
--- /dev/null
+++ b/htdocs/includes/nnnick/chartjs/.gitignore
@@ -0,0 +1,16 @@
+/_book
+/coverage
+/custom
+/docs/index.md
+/gh-pages
+/jsdoc
+/node_modules
+.DS_Store
+.idea
+.project
+.settings
+.vscode
+bower.json
+*.log
+*.swp
+*.stackdump
diff --git a/htdocs/includes/nnnick/chartjs/.htmllintrc b/htdocs/includes/nnnick/chartjs/.htmllintrc
new file mode 100644
index 00000000000..1ab933490de
--- /dev/null
+++ b/htdocs/includes/nnnick/chartjs/.htmllintrc
@@ -0,0 +1,19 @@
+{
+ "indent-style": "tabs",
+ "line-end-style": false,
+ "attr-quote-style": "double",
+ "spec-char-escape": false,
+ "attr-bans": [
+ "align",
+ "background",
+ "bgcolor",
+ "border",
+ "frameborder",
+ "longdesc",
+ "marginwidth",
+ "marginheight",
+ "scrolling"
+ ],
+ "tag-bans": [ "b", "i" ],
+ "id-class-style": false
+}
diff --git a/htdocs/includes/nnnick/chartjs/.travis.yml b/htdocs/includes/nnnick/chartjs/.travis.yml
new file mode 100644
index 00000000000..beb8789b46b
--- /dev/null
+++ b/htdocs/includes/nnnick/chartjs/.travis.yml
@@ -0,0 +1,55 @@
+language: node_js
+node_js:
+ - lts/*
+
+before_install:
+ - "export CHROME_BIN=/usr/bin/google-chrome"
+ - "export DISPLAY=:99.0"
+ - "sh -e /etc/init.d/xvfb start"
+
+script:
+ - gulp build
+ - gulp test --coverage
+ - gulp docs
+ - gulp package
+ - gulp bower
+ - cat ./coverage/lcov.info | ./node_modules/.bin/coveralls || true
+
+sudo: required
+dist: trusty
+
+addons:
+ chrome: stable
+ firefox: latest
+
+# IMPORTANT: scripts require GITHUB_AUTH_TOKEN and GITHUB_AUTH_EMAIL environment variables
+# IMPORTANT: scripts has to be set executables in the Git repository (error 127)
+# https://github.com/travis-ci/travis-ci/issues/5538#issuecomment-225025939
+
+deploy:
+- provider: script
+ script: ./scripts/deploy.sh
+ skip_cleanup: true
+ on:
+ all_branches: true
+- provider: script
+ script: ./scripts/release.sh
+ skip_cleanup: true
+ on:
+ branch: release
+- provider: releases
+ api_key: $GITHUB_AUTH_TOKEN
+ skip_cleanup: true
+ file_glob: true
+ file:
+ - ./dist/*.css
+ - ./dist/*.js
+ - ./dist/*.zip
+ on:
+ tags: true
+- provider: npm
+ email: $NPM_AUTH_EMAIL
+ api_key: $NPM_AUTH_TOKEN
+ skip_cleanup: true
+ on:
+ tags: true
diff --git a/htdocs/includes/nnnick/chartjs/LICENSE.md b/htdocs/includes/nnnick/chartjs/LICENSE.md
new file mode 100644
index 00000000000..29c941dcccf
--- /dev/null
+++ b/htdocs/includes/nnnick/chartjs/LICENSE.md
@@ -0,0 +1,9 @@
+The MIT License (MIT)
+
+Copyright (c) 2018 Chart.js Contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/htdocs/includes/nnnick/chartjs/MAINTAINING.md b/htdocs/includes/nnnick/chartjs/MAINTAINING.md
new file mode 100644
index 00000000000..288b03945ff
--- /dev/null
+++ b/htdocs/includes/nnnick/chartjs/MAINTAINING.md
@@ -0,0 +1,36 @@
+# Maintaining
+## Release Process
+Chart.js relies on [Travis CI](https://travis-ci.org/) to automate the library [releases](https://github.com/chartjs/Chart.js/releases).
+
+### Releasing a New Version
+
+1. draft release notes on [GitHub](https://github.com/chartjs/Chart.js/releases/new) for the upcoming tag
+1. update `master` `package.json` version using [semver](https://semver.org/) semantic
+1. merge `master` into the `release` branch
+1. follow the build process on [Travis CI](https://travis-ci.org/chartjs/Chart.js)
+
+> **Note:** if `master` is merged in `release` with a `package.json` version that already exists, the tag
+creation fails and the release process is aborted.
+
+### Automated Tasks
+Merging into the `release` branch kicks off the automated release process:
+
+* build of the `dist/*.js` files
+* `bower.json` is generated from `package.json`
+* `dist/*.js` and `bower.json` are added to a detached branch
+* a tag is created from the `package.json` version
+* tag (with dist files) is pushed to GitHub
+
+Creation of this tag triggers a new build:
+
+* `Chart.js.zip` package is generated, containing dist files and examples
+* `dist/*.js` and `Chart.js.zip` are attached to the GitHub release (downloads)
+* a new npm package is published on [npmjs](https://www.npmjs.com/package/chart.js)
+
+Finally, [cdnjs](https://cdnjs.com/libraries/Chart.js) is automatically updated from the npm release.
+
+### Further Reading
+
+* [Travis GitHub releases](https://github.com/chartjs/Chart.js/pull/2555)
+* [Bower support and dist/* files](https://github.com/chartjs/Chart.js/issues/3033)
+* [cdnjs npm auto update](https://github.com/cdnjs/cdnjs/pull/8401)
diff --git a/htdocs/includes/nnnick/chartjs/README.md b/htdocs/includes/nnnick/chartjs/README.md
new file mode 100644
index 00000000000..5a522a5e915
--- /dev/null
+++ b/htdocs/includes/nnnick/chartjs/README.md
@@ -0,0 +1,32 @@
+
+
+ Simple yet flexible JavaScript charting for designers & developers
+
+
+
+
+
+
+
+
+
+
+## Documentation
+
+- [Introduction](https://www.chartjs.org/docs/latest/)
+- [Getting Started](https://www.chartjs.org/docs/latest/getting-started/)
+- [General](https://www.chartjs.org/docs/latest/general/)
+- [Configuration](https://www.chartjs.org/docs/latest/configuration/)
+- [Charts](https://www.chartjs.org/docs/latest/charts/)
+- [Axes](https://www.chartjs.org/docs/latest/axes/)
+- [Developers](https://www.chartjs.org/docs/latest/developers/)
+- [Popular Extensions](https://github.com/chartjs/awesome)
+- [Samples](https://www.chartjs.org/samples/)
+
+## Contributing
+
+Instructions on building and testing Chart.js can be found in [the documentation](https://github.com/chartjs/Chart.js/blob/master/docs/developers/contributing.md#building-and-testing). Before submitting an issue or a pull request, please take a moment to look over the [contributing guidelines](https://github.com/chartjs/Chart.js/blob/master/docs/developers/contributing.md) first. For support, please post questions on [Stack Overflow](https://stackoverflow.com/questions/tagged/chartjs) with the `chartjs` tag.
+
+## License
+
+Chart.js is available under the [MIT license](https://opensource.org/licenses/MIT).
diff --git a/htdocs/includes/nnnick/chartjs/book.json b/htdocs/includes/nnnick/chartjs/book.json
new file mode 100644
index 00000000000..22acbde968c
--- /dev/null
+++ b/htdocs/includes/nnnick/chartjs/book.json
@@ -0,0 +1,32 @@
+{
+ "root": "./docs",
+ "title": "Chart.js documentation",
+ "author": "chartjs",
+ "gitbook": "3.2.2",
+ "plugins": [
+ "-lunr",
+ "-search",
+ "search-plus",
+ "anchorjs",
+ "chartjs",
+ "ga",
+ "redirect"
+ ],
+ "pluginsConfig": {
+ "anchorjs": {
+ "icon": "#",
+ "placement": "left",
+ "visible": "always"
+ },
+ "ga": {
+ "token": "UA-28909194-3",
+ "configuration": "auto"
+ },
+ "theme-default": {
+ "showLevel": false,
+ "styles": {
+ "website": "style.css"
+ }
+ }
+ }
+}
diff --git a/htdocs/includes/nnnick/chartjs/composer.json b/htdocs/includes/nnnick/chartjs/composer.json
new file mode 100644
index 00000000000..b332bb0f595
--- /dev/null
+++ b/htdocs/includes/nnnick/chartjs/composer.json
@@ -0,0 +1,26 @@
+{
+ "name": "nnnick/chartjs",
+ "type": "library",
+ "description": "Simple HTML5 charts using the canvas element.",
+ "keywords": [
+ "chart",
+ "js"
+ ],
+ "homepage": "https://www.chartjs.org/",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "NICK DOWNIE",
+ "email": "hello@nickdownie.com"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "minimum-stability": "stable",
+ "extra": {
+ "branch-alias": {
+ "release/2.0": "v2.0-dev"
+ }
+ }
+}
diff --git a/htdocs/includes/nnnick/chartjs/dist/Chart.bundle.js b/htdocs/includes/nnnick/chartjs/dist/Chart.bundle.js
new file mode 100644
index 00000000000..204156a8fc7
--- /dev/null
+++ b/htdocs/includes/nnnick/chartjs/dist/Chart.bundle.js
@@ -0,0 +1,20755 @@
+/*!
+ * Chart.js v2.9.3
+ * https://www.chartjs.org
+ * (c) 2019 Chart.js Contributors
+ * Released under the MIT License
+ */
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+typeof define === 'function' && define.amd ? define(factory) :
+(global = global || self, global.Chart = factory());
+}(this, (function () { 'use strict';
+
+var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+
+function commonjsRequire () {
+ throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
+}
+
+function createCommonjsModule(fn, module) {
+ return module = { exports: {} }, fn(module, module.exports), module.exports;
+}
+
+function getCjsExportFromNamespace (n) {
+ return n && n['default'] || n;
+}
+
+var colorName = {
+ "aliceblue": [240, 248, 255],
+ "antiquewhite": [250, 235, 215],
+ "aqua": [0, 255, 255],
+ "aquamarine": [127, 255, 212],
+ "azure": [240, 255, 255],
+ "beige": [245, 245, 220],
+ "bisque": [255, 228, 196],
+ "black": [0, 0, 0],
+ "blanchedalmond": [255, 235, 205],
+ "blue": [0, 0, 255],
+ "blueviolet": [138, 43, 226],
+ "brown": [165, 42, 42],
+ "burlywood": [222, 184, 135],
+ "cadetblue": [95, 158, 160],
+ "chartreuse": [127, 255, 0],
+ "chocolate": [210, 105, 30],
+ "coral": [255, 127, 80],
+ "cornflowerblue": [100, 149, 237],
+ "cornsilk": [255, 248, 220],
+ "crimson": [220, 20, 60],
+ "cyan": [0, 255, 255],
+ "darkblue": [0, 0, 139],
+ "darkcyan": [0, 139, 139],
+ "darkgoldenrod": [184, 134, 11],
+ "darkgray": [169, 169, 169],
+ "darkgreen": [0, 100, 0],
+ "darkgrey": [169, 169, 169],
+ "darkkhaki": [189, 183, 107],
+ "darkmagenta": [139, 0, 139],
+ "darkolivegreen": [85, 107, 47],
+ "darkorange": [255, 140, 0],
+ "darkorchid": [153, 50, 204],
+ "darkred": [139, 0, 0],
+ "darksalmon": [233, 150, 122],
+ "darkseagreen": [143, 188, 143],
+ "darkslateblue": [72, 61, 139],
+ "darkslategray": [47, 79, 79],
+ "darkslategrey": [47, 79, 79],
+ "darkturquoise": [0, 206, 209],
+ "darkviolet": [148, 0, 211],
+ "deeppink": [255, 20, 147],
+ "deepskyblue": [0, 191, 255],
+ "dimgray": [105, 105, 105],
+ "dimgrey": [105, 105, 105],
+ "dodgerblue": [30, 144, 255],
+ "firebrick": [178, 34, 34],
+ "floralwhite": [255, 250, 240],
+ "forestgreen": [34, 139, 34],
+ "fuchsia": [255, 0, 255],
+ "gainsboro": [220, 220, 220],
+ "ghostwhite": [248, 248, 255],
+ "gold": [255, 215, 0],
+ "goldenrod": [218, 165, 32],
+ "gray": [128, 128, 128],
+ "green": [0, 128, 0],
+ "greenyellow": [173, 255, 47],
+ "grey": [128, 128, 128],
+ "honeydew": [240, 255, 240],
+ "hotpink": [255, 105, 180],
+ "indianred": [205, 92, 92],
+ "indigo": [75, 0, 130],
+ "ivory": [255, 255, 240],
+ "khaki": [240, 230, 140],
+ "lavender": [230, 230, 250],
+ "lavenderblush": [255, 240, 245],
+ "lawngreen": [124, 252, 0],
+ "lemonchiffon": [255, 250, 205],
+ "lightblue": [173, 216, 230],
+ "lightcoral": [240, 128, 128],
+ "lightcyan": [224, 255, 255],
+ "lightgoldenrodyellow": [250, 250, 210],
+ "lightgray": [211, 211, 211],
+ "lightgreen": [144, 238, 144],
+ "lightgrey": [211, 211, 211],
+ "lightpink": [255, 182, 193],
+ "lightsalmon": [255, 160, 122],
+ "lightseagreen": [32, 178, 170],
+ "lightskyblue": [135, 206, 250],
+ "lightslategray": [119, 136, 153],
+ "lightslategrey": [119, 136, 153],
+ "lightsteelblue": [176, 196, 222],
+ "lightyellow": [255, 255, 224],
+ "lime": [0, 255, 0],
+ "limegreen": [50, 205, 50],
+ "linen": [250, 240, 230],
+ "magenta": [255, 0, 255],
+ "maroon": [128, 0, 0],
+ "mediumaquamarine": [102, 205, 170],
+ "mediumblue": [0, 0, 205],
+ "mediumorchid": [186, 85, 211],
+ "mediumpurple": [147, 112, 219],
+ "mediumseagreen": [60, 179, 113],
+ "mediumslateblue": [123, 104, 238],
+ "mediumspringgreen": [0, 250, 154],
+ "mediumturquoise": [72, 209, 204],
+ "mediumvioletred": [199, 21, 133],
+ "midnightblue": [25, 25, 112],
+ "mintcream": [245, 255, 250],
+ "mistyrose": [255, 228, 225],
+ "moccasin": [255, 228, 181],
+ "navajowhite": [255, 222, 173],
+ "navy": [0, 0, 128],
+ "oldlace": [253, 245, 230],
+ "olive": [128, 128, 0],
+ "olivedrab": [107, 142, 35],
+ "orange": [255, 165, 0],
+ "orangered": [255, 69, 0],
+ "orchid": [218, 112, 214],
+ "palegoldenrod": [238, 232, 170],
+ "palegreen": [152, 251, 152],
+ "paleturquoise": [175, 238, 238],
+ "palevioletred": [219, 112, 147],
+ "papayawhip": [255, 239, 213],
+ "peachpuff": [255, 218, 185],
+ "peru": [205, 133, 63],
+ "pink": [255, 192, 203],
+ "plum": [221, 160, 221],
+ "powderblue": [176, 224, 230],
+ "purple": [128, 0, 128],
+ "rebeccapurple": [102, 51, 153],
+ "red": [255, 0, 0],
+ "rosybrown": [188, 143, 143],
+ "royalblue": [65, 105, 225],
+ "saddlebrown": [139, 69, 19],
+ "salmon": [250, 128, 114],
+ "sandybrown": [244, 164, 96],
+ "seagreen": [46, 139, 87],
+ "seashell": [255, 245, 238],
+ "sienna": [160, 82, 45],
+ "silver": [192, 192, 192],
+ "skyblue": [135, 206, 235],
+ "slateblue": [106, 90, 205],
+ "slategray": [112, 128, 144],
+ "slategrey": [112, 128, 144],
+ "snow": [255, 250, 250],
+ "springgreen": [0, 255, 127],
+ "steelblue": [70, 130, 180],
+ "tan": [210, 180, 140],
+ "teal": [0, 128, 128],
+ "thistle": [216, 191, 216],
+ "tomato": [255, 99, 71],
+ "turquoise": [64, 224, 208],
+ "violet": [238, 130, 238],
+ "wheat": [245, 222, 179],
+ "white": [255, 255, 255],
+ "whitesmoke": [245, 245, 245],
+ "yellow": [255, 255, 0],
+ "yellowgreen": [154, 205, 50]
+};
+
+var conversions = createCommonjsModule(function (module) {
+/* MIT license */
+
+
+// NOTE: conversions should only return primitive values (i.e. arrays, or
+// values that give correct `typeof` results).
+// do not use box values types (i.e. Number(), String(), etc.)
+
+var reverseKeywords = {};
+for (var key in colorName) {
+ if (colorName.hasOwnProperty(key)) {
+ reverseKeywords[colorName[key]] = key;
+ }
+}
+
+var convert = module.exports = {
+ rgb: {channels: 3, labels: 'rgb'},
+ hsl: {channels: 3, labels: 'hsl'},
+ hsv: {channels: 3, labels: 'hsv'},
+ hwb: {channels: 3, labels: 'hwb'},
+ cmyk: {channels: 4, labels: 'cmyk'},
+ xyz: {channels: 3, labels: 'xyz'},
+ lab: {channels: 3, labels: 'lab'},
+ lch: {channels: 3, labels: 'lch'},
+ hex: {channels: 1, labels: ['hex']},
+ keyword: {channels: 1, labels: ['keyword']},
+ ansi16: {channels: 1, labels: ['ansi16']},
+ ansi256: {channels: 1, labels: ['ansi256']},
+ hcg: {channels: 3, labels: ['h', 'c', 'g']},
+ apple: {channels: 3, labels: ['r16', 'g16', 'b16']},
+ gray: {channels: 1, labels: ['gray']}
+};
+
+// hide .channels and .labels properties
+for (var model in convert) {
+ if (convert.hasOwnProperty(model)) {
+ if (!('channels' in convert[model])) {
+ throw new Error('missing channels property: ' + model);
+ }
+
+ if (!('labels' in convert[model])) {
+ throw new Error('missing channel labels property: ' + model);
+ }
+
+ if (convert[model].labels.length !== convert[model].channels) {
+ throw new Error('channel and label counts mismatch: ' + model);
+ }
+
+ var channels = convert[model].channels;
+ var labels = convert[model].labels;
+ delete convert[model].channels;
+ delete convert[model].labels;
+ Object.defineProperty(convert[model], 'channels', {value: channels});
+ Object.defineProperty(convert[model], 'labels', {value: labels});
+ }
+}
+
+convert.rgb.hsl = function (rgb) {
+ var r = rgb[0] / 255;
+ var g = rgb[1] / 255;
+ var b = rgb[2] / 255;
+ var min = Math.min(r, g, b);
+ var max = Math.max(r, g, b);
+ var delta = max - min;
+ var h;
+ var s;
+ var l;
+
+ if (max === min) {
+ h = 0;
+ } else if (r === max) {
+ h = (g - b) / delta;
+ } else if (g === max) {
+ h = 2 + (b - r) / delta;
+ } else if (b === max) {
+ h = 4 + (r - g) / delta;
+ }
+
+ h = Math.min(h * 60, 360);
+
+ if (h < 0) {
+ h += 360;
+ }
+
+ l = (min + max) / 2;
+
+ if (max === min) {
+ s = 0;
+ } else if (l <= 0.5) {
+ s = delta / (max + min);
+ } else {
+ s = delta / (2 - max - min);
+ }
+
+ return [h, s * 100, l * 100];
+};
+
+convert.rgb.hsv = function (rgb) {
+ var rdif;
+ var gdif;
+ var bdif;
+ var h;
+ var s;
+
+ var r = rgb[0] / 255;
+ var g = rgb[1] / 255;
+ var b = rgb[2] / 255;
+ var v = Math.max(r, g, b);
+ var diff = v - Math.min(r, g, b);
+ var diffc = function (c) {
+ return (v - c) / 6 / diff + 1 / 2;
+ };
+
+ if (diff === 0) {
+ h = s = 0;
+ } else {
+ s = diff / v;
+ rdif = diffc(r);
+ gdif = diffc(g);
+ bdif = diffc(b);
+
+ if (r === v) {
+ h = bdif - gdif;
+ } else if (g === v) {
+ h = (1 / 3) + rdif - bdif;
+ } else if (b === v) {
+ h = (2 / 3) + gdif - rdif;
+ }
+ if (h < 0) {
+ h += 1;
+ } else if (h > 1) {
+ h -= 1;
+ }
+ }
+
+ return [
+ h * 360,
+ s * 100,
+ v * 100
+ ];
+};
+
+convert.rgb.hwb = function (rgb) {
+ var r = rgb[0];
+ var g = rgb[1];
+ var b = rgb[2];
+ var h = convert.rgb.hsl(rgb)[0];
+ var w = 1 / 255 * Math.min(r, Math.min(g, b));
+
+ b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
+
+ return [h, w * 100, b * 100];
+};
+
+convert.rgb.cmyk = function (rgb) {
+ var r = rgb[0] / 255;
+ var g = rgb[1] / 255;
+ var b = rgb[2] / 255;
+ var c;
+ var m;
+ var y;
+ var k;
+
+ k = Math.min(1 - r, 1 - g, 1 - b);
+ c = (1 - r - k) / (1 - k) || 0;
+ m = (1 - g - k) / (1 - k) || 0;
+ y = (1 - b - k) / (1 - k) || 0;
+
+ return [c * 100, m * 100, y * 100, k * 100];
+};
+
+/**
+ * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance
+ * */
+function comparativeDistance(x, y) {
+ return (
+ Math.pow(x[0] - y[0], 2) +
+ Math.pow(x[1] - y[1], 2) +
+ Math.pow(x[2] - y[2], 2)
+ );
+}
+
+convert.rgb.keyword = function (rgb) {
+ var reversed = reverseKeywords[rgb];
+ if (reversed) {
+ return reversed;
+ }
+
+ var currentClosestDistance = Infinity;
+ var currentClosestKeyword;
+
+ for (var keyword in colorName) {
+ if (colorName.hasOwnProperty(keyword)) {
+ var value = colorName[keyword];
+
+ // Compute comparative distance
+ var distance = comparativeDistance(rgb, value);
+
+ // Check if its less, if so set as closest
+ if (distance < currentClosestDistance) {
+ currentClosestDistance = distance;
+ currentClosestKeyword = keyword;
+ }
+ }
+ }
+
+ return currentClosestKeyword;
+};
+
+convert.keyword.rgb = function (keyword) {
+ return colorName[keyword];
+};
+
+convert.rgb.xyz = function (rgb) {
+ var r = rgb[0] / 255;
+ var g = rgb[1] / 255;
+ var b = rgb[2] / 255;
+
+ // assume sRGB
+ r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
+ g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
+ b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
+
+ var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
+ var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
+ var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
+
+ return [x * 100, y * 100, z * 100];
+};
+
+convert.rgb.lab = function (rgb) {
+ var xyz = convert.rgb.xyz(rgb);
+ var x = xyz[0];
+ var y = xyz[1];
+ var z = xyz[2];
+ var l;
+ var a;
+ var b;
+
+ x /= 95.047;
+ y /= 100;
+ z /= 108.883;
+
+ x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
+ y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
+ z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
+
+ l = (116 * y) - 16;
+ a = 500 * (x - y);
+ b = 200 * (y - z);
+
+ return [l, a, b];
+};
+
+convert.hsl.rgb = function (hsl) {
+ var h = hsl[0] / 360;
+ var s = hsl[1] / 100;
+ var l = hsl[2] / 100;
+ var t1;
+ var t2;
+ var t3;
+ var rgb;
+ var val;
+
+ if (s === 0) {
+ val = l * 255;
+ return [val, val, val];
+ }
+
+ if (l < 0.5) {
+ t2 = l * (1 + s);
+ } else {
+ t2 = l + s - l * s;
+ }
+
+ t1 = 2 * l - t2;
+
+ rgb = [0, 0, 0];
+ for (var i = 0; i < 3; i++) {
+ t3 = h + 1 / 3 * -(i - 1);
+ if (t3 < 0) {
+ t3++;
+ }
+ if (t3 > 1) {
+ t3--;
+ }
+
+ if (6 * t3 < 1) {
+ val = t1 + (t2 - t1) * 6 * t3;
+ } else if (2 * t3 < 1) {
+ val = t2;
+ } else if (3 * t3 < 2) {
+ val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
+ } else {
+ val = t1;
+ }
+
+ rgb[i] = val * 255;
+ }
+
+ return rgb;
+};
+
+convert.hsl.hsv = function (hsl) {
+ var h = hsl[0];
+ var s = hsl[1] / 100;
+ var l = hsl[2] / 100;
+ var smin = s;
+ var lmin = Math.max(l, 0.01);
+ var sv;
+ var v;
+
+ l *= 2;
+ s *= (l <= 1) ? l : 2 - l;
+ smin *= lmin <= 1 ? lmin : 2 - lmin;
+ v = (l + s) / 2;
+ sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);
+
+ return [h, sv * 100, v * 100];
+};
+
+convert.hsv.rgb = function (hsv) {
+ var h = hsv[0] / 60;
+ var s = hsv[1] / 100;
+ var v = hsv[2] / 100;
+ var hi = Math.floor(h) % 6;
+
+ var f = h - Math.floor(h);
+ var p = 255 * v * (1 - s);
+ var q = 255 * v * (1 - (s * f));
+ var t = 255 * v * (1 - (s * (1 - f)));
+ v *= 255;
+
+ switch (hi) {
+ case 0:
+ return [v, t, p];
+ case 1:
+ return [q, v, p];
+ case 2:
+ return [p, v, t];
+ case 3:
+ return [p, q, v];
+ case 4:
+ return [t, p, v];
+ case 5:
+ return [v, p, q];
+ }
+};
+
+convert.hsv.hsl = function (hsv) {
+ var h = hsv[0];
+ var s = hsv[1] / 100;
+ var v = hsv[2] / 100;
+ var vmin = Math.max(v, 0.01);
+ var lmin;
+ var sl;
+ var l;
+
+ l = (2 - s) * v;
+ lmin = (2 - s) * vmin;
+ sl = s * vmin;
+ sl /= (lmin <= 1) ? lmin : 2 - lmin;
+ sl = sl || 0;
+ l /= 2;
+
+ return [h, sl * 100, l * 100];
+};
+
+// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
+convert.hwb.rgb = function (hwb) {
+ var h = hwb[0] / 360;
+ var wh = hwb[1] / 100;
+ var bl = hwb[2] / 100;
+ var ratio = wh + bl;
+ var i;
+ var v;
+ var f;
+ var n;
+
+ // wh + bl cant be > 1
+ if (ratio > 1) {
+ wh /= ratio;
+ bl /= ratio;
+ }
+
+ i = Math.floor(6 * h);
+ v = 1 - bl;
+ f = 6 * h - i;
+
+ if ((i & 0x01) !== 0) {
+ f = 1 - f;
+ }
+
+ n = wh + f * (v - wh); // linear interpolation
+
+ var r;
+ var g;
+ var b;
+ switch (i) {
+ default:
+ case 6:
+ case 0: r = v; g = n; b = wh; break;
+ case 1: r = n; g = v; b = wh; break;
+ case 2: r = wh; g = v; b = n; break;
+ case 3: r = wh; g = n; b = v; break;
+ case 4: r = n; g = wh; b = v; break;
+ case 5: r = v; g = wh; b = n; break;
+ }
+
+ return [r * 255, g * 255, b * 255];
+};
+
+convert.cmyk.rgb = function (cmyk) {
+ var c = cmyk[0] / 100;
+ var m = cmyk[1] / 100;
+ var y = cmyk[2] / 100;
+ var k = cmyk[3] / 100;
+ var r;
+ var g;
+ var b;
+
+ r = 1 - Math.min(1, c * (1 - k) + k);
+ g = 1 - Math.min(1, m * (1 - k) + k);
+ b = 1 - Math.min(1, y * (1 - k) + k);
+
+ return [r * 255, g * 255, b * 255];
+};
+
+convert.xyz.rgb = function (xyz) {
+ var x = xyz[0] / 100;
+ var y = xyz[1] / 100;
+ var z = xyz[2] / 100;
+ var r;
+ var g;
+ var b;
+
+ r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
+ g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
+ b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
+
+ // assume sRGB
+ r = r > 0.0031308
+ ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
+ : r * 12.92;
+
+ g = g > 0.0031308
+ ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
+ : g * 12.92;
+
+ b = b > 0.0031308
+ ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
+ : b * 12.92;
+
+ r = Math.min(Math.max(0, r), 1);
+ g = Math.min(Math.max(0, g), 1);
+ b = Math.min(Math.max(0, b), 1);
+
+ return [r * 255, g * 255, b * 255];
+};
+
+convert.xyz.lab = function (xyz) {
+ var x = xyz[0];
+ var y = xyz[1];
+ var z = xyz[2];
+ var l;
+ var a;
+ var b;
+
+ x /= 95.047;
+ y /= 100;
+ z /= 108.883;
+
+ x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
+ y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
+ z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
+
+ l = (116 * y) - 16;
+ a = 500 * (x - y);
+ b = 200 * (y - z);
+
+ return [l, a, b];
+};
+
+convert.lab.xyz = function (lab) {
+ var l = lab[0];
+ var a = lab[1];
+ var b = lab[2];
+ var x;
+ var y;
+ var z;
+
+ y = (l + 16) / 116;
+ x = a / 500 + y;
+ z = y - b / 200;
+
+ var y2 = Math.pow(y, 3);
+ var x2 = Math.pow(x, 3);
+ var z2 = Math.pow(z, 3);
+ y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;
+ x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;
+ z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;
+
+ x *= 95.047;
+ y *= 100;
+ z *= 108.883;
+
+ return [x, y, z];
+};
+
+convert.lab.lch = function (lab) {
+ var l = lab[0];
+ var a = lab[1];
+ var b = lab[2];
+ var hr;
+ var h;
+ var c;
+
+ hr = Math.atan2(b, a);
+ h = hr * 360 / 2 / Math.PI;
+
+ if (h < 0) {
+ h += 360;
+ }
+
+ c = Math.sqrt(a * a + b * b);
+
+ return [l, c, h];
+};
+
+convert.lch.lab = function (lch) {
+ var l = lch[0];
+ var c = lch[1];
+ var h = lch[2];
+ var a;
+ var b;
+ var hr;
+
+ hr = h / 360 * 2 * Math.PI;
+ a = c * Math.cos(hr);
+ b = c * Math.sin(hr);
+
+ return [l, a, b];
+};
+
+convert.rgb.ansi16 = function (args) {
+ var r = args[0];
+ var g = args[1];
+ var b = args[2];
+ var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization
+
+ value = Math.round(value / 50);
+
+ if (value === 0) {
+ return 30;
+ }
+
+ var ansi = 30
+ + ((Math.round(b / 255) << 2)
+ | (Math.round(g / 255) << 1)
+ | Math.round(r / 255));
+
+ if (value === 2) {
+ ansi += 60;
+ }
+
+ return ansi;
+};
+
+convert.hsv.ansi16 = function (args) {
+ // optimization here; we already know the value and don't need to get
+ // it converted for us.
+ return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);
+};
+
+convert.rgb.ansi256 = function (args) {
+ var r = args[0];
+ var g = args[1];
+ var b = args[2];
+
+ // we use the extended greyscale palette here, with the exception of
+ // black and white. normal palette only has 4 greyscale shades.
+ if (r === g && g === b) {
+ if (r < 8) {
+ return 16;
+ }
+
+ if (r > 248) {
+ return 231;
+ }
+
+ return Math.round(((r - 8) / 247) * 24) + 232;
+ }
+
+ var ansi = 16
+ + (36 * Math.round(r / 255 * 5))
+ + (6 * Math.round(g / 255 * 5))
+ + Math.round(b / 255 * 5);
+
+ return ansi;
+};
+
+convert.ansi16.rgb = function (args) {
+ var color = args % 10;
+
+ // handle greyscale
+ if (color === 0 || color === 7) {
+ if (args > 50) {
+ color += 3.5;
+ }
+
+ color = color / 10.5 * 255;
+
+ return [color, color, color];
+ }
+
+ var mult = (~~(args > 50) + 1) * 0.5;
+ var r = ((color & 1) * mult) * 255;
+ var g = (((color >> 1) & 1) * mult) * 255;
+ var b = (((color >> 2) & 1) * mult) * 255;
+
+ return [r, g, b];
+};
+
+convert.ansi256.rgb = function (args) {
+ // handle greyscale
+ if (args >= 232) {
+ var c = (args - 232) * 10 + 8;
+ return [c, c, c];
+ }
+
+ args -= 16;
+
+ var rem;
+ var r = Math.floor(args / 36) / 5 * 255;
+ var g = Math.floor((rem = args % 36) / 6) / 5 * 255;
+ var b = (rem % 6) / 5 * 255;
+
+ return [r, g, b];
+};
+
+convert.rgb.hex = function (args) {
+ var integer = ((Math.round(args[0]) & 0xFF) << 16)
+ + ((Math.round(args[1]) & 0xFF) << 8)
+ + (Math.round(args[2]) & 0xFF);
+
+ var string = integer.toString(16).toUpperCase();
+ return '000000'.substring(string.length) + string;
+};
+
+convert.hex.rgb = function (args) {
+ var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
+ if (!match) {
+ return [0, 0, 0];
+ }
+
+ var colorString = match[0];
+
+ if (match[0].length === 3) {
+ colorString = colorString.split('').map(function (char) {
+ return char + char;
+ }).join('');
+ }
+
+ var integer = parseInt(colorString, 16);
+ var r = (integer >> 16) & 0xFF;
+ var g = (integer >> 8) & 0xFF;
+ var b = integer & 0xFF;
+
+ return [r, g, b];
+};
+
+convert.rgb.hcg = function (rgb) {
+ var r = rgb[0] / 255;
+ var g = rgb[1] / 255;
+ var b = rgb[2] / 255;
+ var max = Math.max(Math.max(r, g), b);
+ var min = Math.min(Math.min(r, g), b);
+ var chroma = (max - min);
+ var grayscale;
+ var hue;
+
+ if (chroma < 1) {
+ grayscale = min / (1 - chroma);
+ } else {
+ grayscale = 0;
+ }
+
+ if (chroma <= 0) {
+ hue = 0;
+ } else
+ if (max === r) {
+ hue = ((g - b) / chroma) % 6;
+ } else
+ if (max === g) {
+ hue = 2 + (b - r) / chroma;
+ } else {
+ hue = 4 + (r - g) / chroma + 4;
+ }
+
+ hue /= 6;
+ hue %= 1;
+
+ return [hue * 360, chroma * 100, grayscale * 100];
+};
+
+convert.hsl.hcg = function (hsl) {
+ var s = hsl[1] / 100;
+ var l = hsl[2] / 100;
+ var c = 1;
+ var f = 0;
+
+ if (l < 0.5) {
+ c = 2.0 * s * l;
+ } else {
+ c = 2.0 * s * (1.0 - l);
+ }
+
+ if (c < 1.0) {
+ f = (l - 0.5 * c) / (1.0 - c);
+ }
+
+ return [hsl[0], c * 100, f * 100];
+};
+
+convert.hsv.hcg = function (hsv) {
+ var s = hsv[1] / 100;
+ var v = hsv[2] / 100;
+
+ var c = s * v;
+ var f = 0;
+
+ if (c < 1.0) {
+ f = (v - c) / (1 - c);
+ }
+
+ return [hsv[0], c * 100, f * 100];
+};
+
+convert.hcg.rgb = function (hcg) {
+ var h = hcg[0] / 360;
+ var c = hcg[1] / 100;
+ var g = hcg[2] / 100;
+
+ if (c === 0.0) {
+ return [g * 255, g * 255, g * 255];
+ }
+
+ var pure = [0, 0, 0];
+ var hi = (h % 1) * 6;
+ var v = hi % 1;
+ var w = 1 - v;
+ var mg = 0;
+
+ switch (Math.floor(hi)) {
+ case 0:
+ pure[0] = 1; pure[1] = v; pure[2] = 0; break;
+ case 1:
+ pure[0] = w; pure[1] = 1; pure[2] = 0; break;
+ case 2:
+ pure[0] = 0; pure[1] = 1; pure[2] = v; break;
+ case 3:
+ pure[0] = 0; pure[1] = w; pure[2] = 1; break;
+ case 4:
+ pure[0] = v; pure[1] = 0; pure[2] = 1; break;
+ default:
+ pure[0] = 1; pure[1] = 0; pure[2] = w;
+ }
+
+ mg = (1.0 - c) * g;
+
+ return [
+ (c * pure[0] + mg) * 255,
+ (c * pure[1] + mg) * 255,
+ (c * pure[2] + mg) * 255
+ ];
+};
+
+convert.hcg.hsv = function (hcg) {
+ var c = hcg[1] / 100;
+ var g = hcg[2] / 100;
+
+ var v = c + g * (1.0 - c);
+ var f = 0;
+
+ if (v > 0.0) {
+ f = c / v;
+ }
+
+ return [hcg[0], f * 100, v * 100];
+};
+
+convert.hcg.hsl = function (hcg) {
+ var c = hcg[1] / 100;
+ var g = hcg[2] / 100;
+
+ var l = g * (1.0 - c) + 0.5 * c;
+ var s = 0;
+
+ if (l > 0.0 && l < 0.5) {
+ s = c / (2 * l);
+ } else
+ if (l >= 0.5 && l < 1.0) {
+ s = c / (2 * (1 - l));
+ }
+
+ return [hcg[0], s * 100, l * 100];
+};
+
+convert.hcg.hwb = function (hcg) {
+ var c = hcg[1] / 100;
+ var g = hcg[2] / 100;
+ var v = c + g * (1.0 - c);
+ return [hcg[0], (v - c) * 100, (1 - v) * 100];
+};
+
+convert.hwb.hcg = function (hwb) {
+ var w = hwb[1] / 100;
+ var b = hwb[2] / 100;
+ var v = 1 - b;
+ var c = v - w;
+ var g = 0;
+
+ if (c < 1) {
+ g = (v - c) / (1 - c);
+ }
+
+ return [hwb[0], c * 100, g * 100];
+};
+
+convert.apple.rgb = function (apple) {
+ return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];
+};
+
+convert.rgb.apple = function (rgb) {
+ return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];
+};
+
+convert.gray.rgb = function (args) {
+ return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];
+};
+
+convert.gray.hsl = convert.gray.hsv = function (args) {
+ return [0, 0, args[0]];
+};
+
+convert.gray.hwb = function (gray) {
+ return [0, 100, gray[0]];
+};
+
+convert.gray.cmyk = function (gray) {
+ return [0, 0, 0, gray[0]];
+};
+
+convert.gray.lab = function (gray) {
+ return [gray[0], 0, 0];
+};
+
+convert.gray.hex = function (gray) {
+ var val = Math.round(gray[0] / 100 * 255) & 0xFF;
+ var integer = (val << 16) + (val << 8) + val;
+
+ var string = integer.toString(16).toUpperCase();
+ return '000000'.substring(string.length) + string;
+};
+
+convert.rgb.gray = function (rgb) {
+ var val = (rgb[0] + rgb[1] + rgb[2]) / 3;
+ return [val / 255 * 100];
+};
+});
+var conversions_1 = conversions.rgb;
+var conversions_2 = conversions.hsl;
+var conversions_3 = conversions.hsv;
+var conversions_4 = conversions.hwb;
+var conversions_5 = conversions.cmyk;
+var conversions_6 = conversions.xyz;
+var conversions_7 = conversions.lab;
+var conversions_8 = conversions.lch;
+var conversions_9 = conversions.hex;
+var conversions_10 = conversions.keyword;
+var conversions_11 = conversions.ansi16;
+var conversions_12 = conversions.ansi256;
+var conversions_13 = conversions.hcg;
+var conversions_14 = conversions.apple;
+var conversions_15 = conversions.gray;
+
+/*
+ this function routes a model to all other models.
+
+ all functions that are routed have a property `.conversion` attached
+ to the returned synthetic function. This property is an array
+ of strings, each with the steps in between the 'from' and 'to'
+ color models (inclusive).
+
+ conversions that are not possible simply are not included.
+*/
+
+function buildGraph() {
+ var graph = {};
+ // https://jsperf.com/object-keys-vs-for-in-with-closure/3
+ var models = Object.keys(conversions);
+
+ for (var len = models.length, i = 0; i < len; i++) {
+ graph[models[i]] = {
+ // http://jsperf.com/1-vs-infinity
+ // micro-opt, but this is simple.
+ distance: -1,
+ parent: null
+ };
+ }
+
+ return graph;
+}
+
+// https://en.wikipedia.org/wiki/Breadth-first_search
+function deriveBFS(fromModel) {
+ var graph = buildGraph();
+ var queue = [fromModel]; // unshift -> queue -> pop
+
+ graph[fromModel].distance = 0;
+
+ while (queue.length) {
+ var current = queue.pop();
+ var adjacents = Object.keys(conversions[current]);
+
+ for (var len = adjacents.length, i = 0; i < len; i++) {
+ var adjacent = adjacents[i];
+ var node = graph[adjacent];
+
+ if (node.distance === -1) {
+ node.distance = graph[current].distance + 1;
+ node.parent = current;
+ queue.unshift(adjacent);
+ }
+ }
+ }
+
+ return graph;
+}
+
+function link(from, to) {
+ return function (args) {
+ return to(from(args));
+ };
+}
+
+function wrapConversion(toModel, graph) {
+ var path = [graph[toModel].parent, toModel];
+ var fn = conversions[graph[toModel].parent][toModel];
+
+ var cur = graph[toModel].parent;
+ while (graph[cur].parent) {
+ path.unshift(graph[cur].parent);
+ fn = link(conversions[graph[cur].parent][cur], fn);
+ cur = graph[cur].parent;
+ }
+
+ fn.conversion = path;
+ return fn;
+}
+
+var route = function (fromModel) {
+ var graph = deriveBFS(fromModel);
+ var conversion = {};
+
+ var models = Object.keys(graph);
+ for (var len = models.length, i = 0; i < len; i++) {
+ var toModel = models[i];
+ var node = graph[toModel];
+
+ if (node.parent === null) {
+ // no possible conversion, or this node is the source model.
+ continue;
+ }
+
+ conversion[toModel] = wrapConversion(toModel, graph);
+ }
+
+ return conversion;
+};
+
+var convert = {};
+
+var models = Object.keys(conversions);
+
+function wrapRaw(fn) {
+ var wrappedFn = function (args) {
+ if (args === undefined || args === null) {
+ return args;
+ }
+
+ if (arguments.length > 1) {
+ args = Array.prototype.slice.call(arguments);
+ }
+
+ return fn(args);
+ };
+
+ // preserve .conversion property if there is one
+ if ('conversion' in fn) {
+ wrappedFn.conversion = fn.conversion;
+ }
+
+ return wrappedFn;
+}
+
+function wrapRounded(fn) {
+ var wrappedFn = function (args) {
+ if (args === undefined || args === null) {
+ return args;
+ }
+
+ if (arguments.length > 1) {
+ args = Array.prototype.slice.call(arguments);
+ }
+
+ var result = fn(args);
+
+ // we're assuming the result is an array here.
+ // see notice in conversions.js; don't use box types
+ // in conversion functions.
+ if (typeof result === 'object') {
+ for (var len = result.length, i = 0; i < len; i++) {
+ result[i] = Math.round(result[i]);
+ }
+ }
+
+ return result;
+ };
+
+ // preserve .conversion property if there is one
+ if ('conversion' in fn) {
+ wrappedFn.conversion = fn.conversion;
+ }
+
+ return wrappedFn;
+}
+
+models.forEach(function (fromModel) {
+ convert[fromModel] = {};
+
+ Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels});
+ Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels});
+
+ var routes = route(fromModel);
+ var routeModels = Object.keys(routes);
+
+ routeModels.forEach(function (toModel) {
+ var fn = routes[toModel];
+
+ convert[fromModel][toModel] = wrapRounded(fn);
+ convert[fromModel][toModel].raw = wrapRaw(fn);
+ });
+});
+
+var colorConvert = convert;
+
+var colorName$1 = {
+ "aliceblue": [240, 248, 255],
+ "antiquewhite": [250, 235, 215],
+ "aqua": [0, 255, 255],
+ "aquamarine": [127, 255, 212],
+ "azure": [240, 255, 255],
+ "beige": [245, 245, 220],
+ "bisque": [255, 228, 196],
+ "black": [0, 0, 0],
+ "blanchedalmond": [255, 235, 205],
+ "blue": [0, 0, 255],
+ "blueviolet": [138, 43, 226],
+ "brown": [165, 42, 42],
+ "burlywood": [222, 184, 135],
+ "cadetblue": [95, 158, 160],
+ "chartreuse": [127, 255, 0],
+ "chocolate": [210, 105, 30],
+ "coral": [255, 127, 80],
+ "cornflowerblue": [100, 149, 237],
+ "cornsilk": [255, 248, 220],
+ "crimson": [220, 20, 60],
+ "cyan": [0, 255, 255],
+ "darkblue": [0, 0, 139],
+ "darkcyan": [0, 139, 139],
+ "darkgoldenrod": [184, 134, 11],
+ "darkgray": [169, 169, 169],
+ "darkgreen": [0, 100, 0],
+ "darkgrey": [169, 169, 169],
+ "darkkhaki": [189, 183, 107],
+ "darkmagenta": [139, 0, 139],
+ "darkolivegreen": [85, 107, 47],
+ "darkorange": [255, 140, 0],
+ "darkorchid": [153, 50, 204],
+ "darkred": [139, 0, 0],
+ "darksalmon": [233, 150, 122],
+ "darkseagreen": [143, 188, 143],
+ "darkslateblue": [72, 61, 139],
+ "darkslategray": [47, 79, 79],
+ "darkslategrey": [47, 79, 79],
+ "darkturquoise": [0, 206, 209],
+ "darkviolet": [148, 0, 211],
+ "deeppink": [255, 20, 147],
+ "deepskyblue": [0, 191, 255],
+ "dimgray": [105, 105, 105],
+ "dimgrey": [105, 105, 105],
+ "dodgerblue": [30, 144, 255],
+ "firebrick": [178, 34, 34],
+ "floralwhite": [255, 250, 240],
+ "forestgreen": [34, 139, 34],
+ "fuchsia": [255, 0, 255],
+ "gainsboro": [220, 220, 220],
+ "ghostwhite": [248, 248, 255],
+ "gold": [255, 215, 0],
+ "goldenrod": [218, 165, 32],
+ "gray": [128, 128, 128],
+ "green": [0, 128, 0],
+ "greenyellow": [173, 255, 47],
+ "grey": [128, 128, 128],
+ "honeydew": [240, 255, 240],
+ "hotpink": [255, 105, 180],
+ "indianred": [205, 92, 92],
+ "indigo": [75, 0, 130],
+ "ivory": [255, 255, 240],
+ "khaki": [240, 230, 140],
+ "lavender": [230, 230, 250],
+ "lavenderblush": [255, 240, 245],
+ "lawngreen": [124, 252, 0],
+ "lemonchiffon": [255, 250, 205],
+ "lightblue": [173, 216, 230],
+ "lightcoral": [240, 128, 128],
+ "lightcyan": [224, 255, 255],
+ "lightgoldenrodyellow": [250, 250, 210],
+ "lightgray": [211, 211, 211],
+ "lightgreen": [144, 238, 144],
+ "lightgrey": [211, 211, 211],
+ "lightpink": [255, 182, 193],
+ "lightsalmon": [255, 160, 122],
+ "lightseagreen": [32, 178, 170],
+ "lightskyblue": [135, 206, 250],
+ "lightslategray": [119, 136, 153],
+ "lightslategrey": [119, 136, 153],
+ "lightsteelblue": [176, 196, 222],
+ "lightyellow": [255, 255, 224],
+ "lime": [0, 255, 0],
+ "limegreen": [50, 205, 50],
+ "linen": [250, 240, 230],
+ "magenta": [255, 0, 255],
+ "maroon": [128, 0, 0],
+ "mediumaquamarine": [102, 205, 170],
+ "mediumblue": [0, 0, 205],
+ "mediumorchid": [186, 85, 211],
+ "mediumpurple": [147, 112, 219],
+ "mediumseagreen": [60, 179, 113],
+ "mediumslateblue": [123, 104, 238],
+ "mediumspringgreen": [0, 250, 154],
+ "mediumturquoise": [72, 209, 204],
+ "mediumvioletred": [199, 21, 133],
+ "midnightblue": [25, 25, 112],
+ "mintcream": [245, 255, 250],
+ "mistyrose": [255, 228, 225],
+ "moccasin": [255, 228, 181],
+ "navajowhite": [255, 222, 173],
+ "navy": [0, 0, 128],
+ "oldlace": [253, 245, 230],
+ "olive": [128, 128, 0],
+ "olivedrab": [107, 142, 35],
+ "orange": [255, 165, 0],
+ "orangered": [255, 69, 0],
+ "orchid": [218, 112, 214],
+ "palegoldenrod": [238, 232, 170],
+ "palegreen": [152, 251, 152],
+ "paleturquoise": [175, 238, 238],
+ "palevioletred": [219, 112, 147],
+ "papayawhip": [255, 239, 213],
+ "peachpuff": [255, 218, 185],
+ "peru": [205, 133, 63],
+ "pink": [255, 192, 203],
+ "plum": [221, 160, 221],
+ "powderblue": [176, 224, 230],
+ "purple": [128, 0, 128],
+ "rebeccapurple": [102, 51, 153],
+ "red": [255, 0, 0],
+ "rosybrown": [188, 143, 143],
+ "royalblue": [65, 105, 225],
+ "saddlebrown": [139, 69, 19],
+ "salmon": [250, 128, 114],
+ "sandybrown": [244, 164, 96],
+ "seagreen": [46, 139, 87],
+ "seashell": [255, 245, 238],
+ "sienna": [160, 82, 45],
+ "silver": [192, 192, 192],
+ "skyblue": [135, 206, 235],
+ "slateblue": [106, 90, 205],
+ "slategray": [112, 128, 144],
+ "slategrey": [112, 128, 144],
+ "snow": [255, 250, 250],
+ "springgreen": [0, 255, 127],
+ "steelblue": [70, 130, 180],
+ "tan": [210, 180, 140],
+ "teal": [0, 128, 128],
+ "thistle": [216, 191, 216],
+ "tomato": [255, 99, 71],
+ "turquoise": [64, 224, 208],
+ "violet": [238, 130, 238],
+ "wheat": [245, 222, 179],
+ "white": [255, 255, 255],
+ "whitesmoke": [245, 245, 245],
+ "yellow": [255, 255, 0],
+ "yellowgreen": [154, 205, 50]
+};
+
+/* MIT license */
+
+
+var colorString = {
+ getRgba: getRgba,
+ getHsla: getHsla,
+ getRgb: getRgb,
+ getHsl: getHsl,
+ getHwb: getHwb,
+ getAlpha: getAlpha,
+
+ hexString: hexString,
+ rgbString: rgbString,
+ rgbaString: rgbaString,
+ percentString: percentString,
+ percentaString: percentaString,
+ hslString: hslString,
+ hslaString: hslaString,
+ hwbString: hwbString,
+ keyword: keyword
+};
+
+function getRgba(string) {
+ if (!string) {
+ return;
+ }
+ var abbr = /^#([a-fA-F0-9]{3,4})$/i,
+ hex = /^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i,
+ rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,
+ per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,
+ keyword = /(\w+)/;
+
+ var rgb = [0, 0, 0],
+ a = 1,
+ match = string.match(abbr),
+ hexAlpha = "";
+ if (match) {
+ match = match[1];
+ hexAlpha = match[3];
+ for (var i = 0; i < rgb.length; i++) {
+ rgb[i] = parseInt(match[i] + match[i], 16);
+ }
+ if (hexAlpha) {
+ a = Math.round((parseInt(hexAlpha + hexAlpha, 16) / 255) * 100) / 100;
+ }
+ }
+ else if (match = string.match(hex)) {
+ hexAlpha = match[2];
+ match = match[1];
+ for (var i = 0; i < rgb.length; i++) {
+ rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);
+ }
+ if (hexAlpha) {
+ a = Math.round((parseInt(hexAlpha, 16) / 255) * 100) / 100;
+ }
+ }
+ else if (match = string.match(rgba)) {
+ for (var i = 0; i < rgb.length; i++) {
+ rgb[i] = parseInt(match[i + 1]);
+ }
+ a = parseFloat(match[4]);
+ }
+ else if (match = string.match(per)) {
+ for (var i = 0; i < rgb.length; i++) {
+ rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);
+ }
+ a = parseFloat(match[4]);
+ }
+ else if (match = string.match(keyword)) {
+ if (match[1] == "transparent") {
+ return [0, 0, 0, 0];
+ }
+ rgb = colorName$1[match[1]];
+ if (!rgb) {
+ return;
+ }
+ }
+
+ for (var i = 0; i < rgb.length; i++) {
+ rgb[i] = scale(rgb[i], 0, 255);
+ }
+ if (!a && a != 0) {
+ a = 1;
+ }
+ else {
+ a = scale(a, 0, 1);
+ }
+ rgb[3] = a;
+ return rgb;
+}
+
+function getHsla(string) {
+ if (!string) {
+ return;
+ }
+ var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;
+ var match = string.match(hsl);
+ if (match) {
+ var alpha = parseFloat(match[4]);
+ var h = scale(parseInt(match[1]), 0, 360),
+ s = scale(parseFloat(match[2]), 0, 100),
+ l = scale(parseFloat(match[3]), 0, 100),
+ a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);
+ return [h, s, l, a];
+ }
+}
+
+function getHwb(string) {
+ if (!string) {
+ return;
+ }
+ var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;
+ var match = string.match(hwb);
+ if (match) {
+ var alpha = parseFloat(match[4]);
+ var h = scale(parseInt(match[1]), 0, 360),
+ w = scale(parseFloat(match[2]), 0, 100),
+ b = scale(parseFloat(match[3]), 0, 100),
+ a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);
+ return [h, w, b, a];
+ }
+}
+
+function getRgb(string) {
+ var rgba = getRgba(string);
+ return rgba && rgba.slice(0, 3);
+}
+
+function getHsl(string) {
+ var hsla = getHsla(string);
+ return hsla && hsla.slice(0, 3);
+}
+
+function getAlpha(string) {
+ var vals = getRgba(string);
+ if (vals) {
+ return vals[3];
+ }
+ else if (vals = getHsla(string)) {
+ return vals[3];
+ }
+ else if (vals = getHwb(string)) {
+ return vals[3];
+ }
+}
+
+// generators
+function hexString(rgba, a) {
+ var a = (a !== undefined && rgba.length === 3) ? a : rgba[3];
+ return "#" + hexDouble(rgba[0])
+ + hexDouble(rgba[1])
+ + hexDouble(rgba[2])
+ + (
+ (a >= 0 && a < 1)
+ ? hexDouble(Math.round(a * 255))
+ : ""
+ );
+}
+
+function rgbString(rgba, alpha) {
+ if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {
+ return rgbaString(rgba, alpha);
+ }
+ return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")";
+}
+
+function rgbaString(rgba, alpha) {
+ if (alpha === undefined) {
+ alpha = (rgba[3] !== undefined ? rgba[3] : 1);
+ }
+ return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2]
+ + ", " + alpha + ")";
+}
+
+function percentString(rgba, alpha) {
+ if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {
+ return percentaString(rgba, alpha);
+ }
+ var r = Math.round(rgba[0]/255 * 100),
+ g = Math.round(rgba[1]/255 * 100),
+ b = Math.round(rgba[2]/255 * 100);
+
+ return "rgb(" + r + "%, " + g + "%, " + b + "%)";
+}
+
+function percentaString(rgba, alpha) {
+ var r = Math.round(rgba[0]/255 * 100),
+ g = Math.round(rgba[1]/255 * 100),
+ b = Math.round(rgba[2]/255 * 100);
+ return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")";
+}
+
+function hslString(hsla, alpha) {
+ if (alpha < 1 || (hsla[3] && hsla[3] < 1)) {
+ return hslaString(hsla, alpha);
+ }
+ return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)";
+}
+
+function hslaString(hsla, alpha) {
+ if (alpha === undefined) {
+ alpha = (hsla[3] !== undefined ? hsla[3] : 1);
+ }
+ return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, "
+ + alpha + ")";
+}
+
+// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax
+// (hwb have alpha optional & 1 is default value)
+function hwbString(hwb, alpha) {
+ if (alpha === undefined) {
+ alpha = (hwb[3] !== undefined ? hwb[3] : 1);
+ }
+ return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%"
+ + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")";
+}
+
+function keyword(rgb) {
+ return reverseNames[rgb.slice(0, 3)];
+}
+
+// helpers
+function scale(num, min, max) {
+ return Math.min(Math.max(min, num), max);
+}
+
+function hexDouble(num) {
+ var str = num.toString(16).toUpperCase();
+ return (str.length < 2) ? "0" + str : str;
+}
+
+
+//create a list of reverse color names
+var reverseNames = {};
+for (var name in colorName$1) {
+ reverseNames[colorName$1[name]] = name;
+}
+
+/* MIT license */
+
+
+
+var Color = function (obj) {
+ if (obj instanceof Color) {
+ return obj;
+ }
+ if (!(this instanceof Color)) {
+ return new Color(obj);
+ }
+
+ this.valid = false;
+ this.values = {
+ rgb: [0, 0, 0],
+ hsl: [0, 0, 0],
+ hsv: [0, 0, 0],
+ hwb: [0, 0, 0],
+ cmyk: [0, 0, 0, 0],
+ alpha: 1
+ };
+
+ // parse Color() argument
+ var vals;
+ if (typeof obj === 'string') {
+ vals = colorString.getRgba(obj);
+ if (vals) {
+ this.setValues('rgb', vals);
+ } else if (vals = colorString.getHsla(obj)) {
+ this.setValues('hsl', vals);
+ } else if (vals = colorString.getHwb(obj)) {
+ this.setValues('hwb', vals);
+ }
+ } else if (typeof obj === 'object') {
+ vals = obj;
+ if (vals.r !== undefined || vals.red !== undefined) {
+ this.setValues('rgb', vals);
+ } else if (vals.l !== undefined || vals.lightness !== undefined) {
+ this.setValues('hsl', vals);
+ } else if (vals.v !== undefined || vals.value !== undefined) {
+ this.setValues('hsv', vals);
+ } else if (vals.w !== undefined || vals.whiteness !== undefined) {
+ this.setValues('hwb', vals);
+ } else if (vals.c !== undefined || vals.cyan !== undefined) {
+ this.setValues('cmyk', vals);
+ }
+ }
+};
+
+Color.prototype = {
+ isValid: function () {
+ return this.valid;
+ },
+ rgb: function () {
+ return this.setSpace('rgb', arguments);
+ },
+ hsl: function () {
+ return this.setSpace('hsl', arguments);
+ },
+ hsv: function () {
+ return this.setSpace('hsv', arguments);
+ },
+ hwb: function () {
+ return this.setSpace('hwb', arguments);
+ },
+ cmyk: function () {
+ return this.setSpace('cmyk', arguments);
+ },
+
+ rgbArray: function () {
+ return this.values.rgb;
+ },
+ hslArray: function () {
+ return this.values.hsl;
+ },
+ hsvArray: function () {
+ return this.values.hsv;
+ },
+ hwbArray: function () {
+ var values = this.values;
+ if (values.alpha !== 1) {
+ return values.hwb.concat([values.alpha]);
+ }
+ return values.hwb;
+ },
+ cmykArray: function () {
+ return this.values.cmyk;
+ },
+ rgbaArray: function () {
+ var values = this.values;
+ return values.rgb.concat([values.alpha]);
+ },
+ hslaArray: function () {
+ var values = this.values;
+ return values.hsl.concat([values.alpha]);
+ },
+ alpha: function (val) {
+ if (val === undefined) {
+ return this.values.alpha;
+ }
+ this.setValues('alpha', val);
+ return this;
+ },
+
+ red: function (val) {
+ return this.setChannel('rgb', 0, val);
+ },
+ green: function (val) {
+ return this.setChannel('rgb', 1, val);
+ },
+ blue: function (val) {
+ return this.setChannel('rgb', 2, val);
+ },
+ hue: function (val) {
+ if (val) {
+ val %= 360;
+ val = val < 0 ? 360 + val : val;
+ }
+ return this.setChannel('hsl', 0, val);
+ },
+ saturation: function (val) {
+ return this.setChannel('hsl', 1, val);
+ },
+ lightness: function (val) {
+ return this.setChannel('hsl', 2, val);
+ },
+ saturationv: function (val) {
+ return this.setChannel('hsv', 1, val);
+ },
+ whiteness: function (val) {
+ return this.setChannel('hwb', 1, val);
+ },
+ blackness: function (val) {
+ return this.setChannel('hwb', 2, val);
+ },
+ value: function (val) {
+ return this.setChannel('hsv', 2, val);
+ },
+ cyan: function (val) {
+ return this.setChannel('cmyk', 0, val);
+ },
+ magenta: function (val) {
+ return this.setChannel('cmyk', 1, val);
+ },
+ yellow: function (val) {
+ return this.setChannel('cmyk', 2, val);
+ },
+ black: function (val) {
+ return this.setChannel('cmyk', 3, val);
+ },
+
+ hexString: function () {
+ return colorString.hexString(this.values.rgb);
+ },
+ rgbString: function () {
+ return colorString.rgbString(this.values.rgb, this.values.alpha);
+ },
+ rgbaString: function () {
+ return colorString.rgbaString(this.values.rgb, this.values.alpha);
+ },
+ percentString: function () {
+ return colorString.percentString(this.values.rgb, this.values.alpha);
+ },
+ hslString: function () {
+ return colorString.hslString(this.values.hsl, this.values.alpha);
+ },
+ hslaString: function () {
+ return colorString.hslaString(this.values.hsl, this.values.alpha);
+ },
+ hwbString: function () {
+ return colorString.hwbString(this.values.hwb, this.values.alpha);
+ },
+ keyword: function () {
+ return colorString.keyword(this.values.rgb, this.values.alpha);
+ },
+
+ rgbNumber: function () {
+ var rgb = this.values.rgb;
+ return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
+ },
+
+ luminosity: function () {
+ // http://www.w3.org/TR/WCAG20/#relativeluminancedef
+ var rgb = this.values.rgb;
+ var lum = [];
+ for (var i = 0; i < rgb.length; i++) {
+ var chan = rgb[i] / 255;
+ lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);
+ }
+ return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];
+ },
+
+ contrast: function (color2) {
+ // http://www.w3.org/TR/WCAG20/#contrast-ratiodef
+ var lum1 = this.luminosity();
+ var lum2 = color2.luminosity();
+ if (lum1 > lum2) {
+ return (lum1 + 0.05) / (lum2 + 0.05);
+ }
+ return (lum2 + 0.05) / (lum1 + 0.05);
+ },
+
+ level: function (color2) {
+ var contrastRatio = this.contrast(color2);
+ if (contrastRatio >= 7.1) {
+ return 'AAA';
+ }
+
+ return (contrastRatio >= 4.5) ? 'AA' : '';
+ },
+
+ dark: function () {
+ // YIQ equation from http://24ways.org/2010/calculating-color-contrast
+ var rgb = this.values.rgb;
+ var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;
+ return yiq < 128;
+ },
+
+ light: function () {
+ return !this.dark();
+ },
+
+ negate: function () {
+ var rgb = [];
+ for (var i = 0; i < 3; i++) {
+ rgb[i] = 255 - this.values.rgb[i];
+ }
+ this.setValues('rgb', rgb);
+ return this;
+ },
+
+ lighten: function (ratio) {
+ var hsl = this.values.hsl;
+ hsl[2] += hsl[2] * ratio;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ darken: function (ratio) {
+ var hsl = this.values.hsl;
+ hsl[2] -= hsl[2] * ratio;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ saturate: function (ratio) {
+ var hsl = this.values.hsl;
+ hsl[1] += hsl[1] * ratio;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ desaturate: function (ratio) {
+ var hsl = this.values.hsl;
+ hsl[1] -= hsl[1] * ratio;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ whiten: function (ratio) {
+ var hwb = this.values.hwb;
+ hwb[1] += hwb[1] * ratio;
+ this.setValues('hwb', hwb);
+ return this;
+ },
+
+ blacken: function (ratio) {
+ var hwb = this.values.hwb;
+ hwb[2] += hwb[2] * ratio;
+ this.setValues('hwb', hwb);
+ return this;
+ },
+
+ greyscale: function () {
+ var rgb = this.values.rgb;
+ // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
+ var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;
+ this.setValues('rgb', [val, val, val]);
+ return this;
+ },
+
+ clearer: function (ratio) {
+ var alpha = this.values.alpha;
+ this.setValues('alpha', alpha - (alpha * ratio));
+ return this;
+ },
+
+ opaquer: function (ratio) {
+ var alpha = this.values.alpha;
+ this.setValues('alpha', alpha + (alpha * ratio));
+ return this;
+ },
+
+ rotate: function (degrees) {
+ var hsl = this.values.hsl;
+ var hue = (hsl[0] + degrees) % 360;
+ hsl[0] = hue < 0 ? 360 + hue : hue;
+ this.setValues('hsl', hsl);
+ return this;
+ },
+
+ /**
+ * Ported from sass implementation in C
+ * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209
+ */
+ mix: function (mixinColor, weight) {
+ var color1 = this;
+ var color2 = mixinColor;
+ var p = weight === undefined ? 0.5 : weight;
+
+ var w = 2 * p - 1;
+ var a = color1.alpha() - color2.alpha();
+
+ var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+ var w2 = 1 - w1;
+
+ return this
+ .rgb(
+ w1 * color1.red() + w2 * color2.red(),
+ w1 * color1.green() + w2 * color2.green(),
+ w1 * color1.blue() + w2 * color2.blue()
+ )
+ .alpha(color1.alpha() * p + color2.alpha() * (1 - p));
+ },
+
+ toJSON: function () {
+ return this.rgb();
+ },
+
+ clone: function () {
+ // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,
+ // making the final build way to big to embed in Chart.js. So let's do it manually,
+ // assuming that values to clone are 1 dimension arrays containing only numbers,
+ // except 'alpha' which is a number.
+ var result = new Color();
+ var source = this.values;
+ var target = result.values;
+ var value, type;
+
+ for (var prop in source) {
+ if (source.hasOwnProperty(prop)) {
+ value = source[prop];
+ type = ({}).toString.call(value);
+ if (type === '[object Array]') {
+ target[prop] = value.slice(0);
+ } else if (type === '[object Number]') {
+ target[prop] = value;
+ } else {
+ console.error('unexpected color value:', value);
+ }
+ }
+ }
+
+ return result;
+ }
+};
+
+Color.prototype.spaces = {
+ rgb: ['red', 'green', 'blue'],
+ hsl: ['hue', 'saturation', 'lightness'],
+ hsv: ['hue', 'saturation', 'value'],
+ hwb: ['hue', 'whiteness', 'blackness'],
+ cmyk: ['cyan', 'magenta', 'yellow', 'black']
+};
+
+Color.prototype.maxes = {
+ rgb: [255, 255, 255],
+ hsl: [360, 100, 100],
+ hsv: [360, 100, 100],
+ hwb: [360, 100, 100],
+ cmyk: [100, 100, 100, 100]
+};
+
+Color.prototype.getValues = function (space) {
+ var values = this.values;
+ var vals = {};
+
+ for (var i = 0; i < space.length; i++) {
+ vals[space.charAt(i)] = values[space][i];
+ }
+
+ if (values.alpha !== 1) {
+ vals.a = values.alpha;
+ }
+
+ // {r: 255, g: 255, b: 255, a: 0.4}
+ return vals;
+};
+
+Color.prototype.setValues = function (space, vals) {
+ var values = this.values;
+ var spaces = this.spaces;
+ var maxes = this.maxes;
+ var alpha = 1;
+ var i;
+
+ this.valid = true;
+
+ if (space === 'alpha') {
+ alpha = vals;
+ } else if (vals.length) {
+ // [10, 10, 10]
+ values[space] = vals.slice(0, space.length);
+ alpha = vals[space.length];
+ } else if (vals[space.charAt(0)] !== undefined) {
+ // {r: 10, g: 10, b: 10}
+ for (i = 0; i < space.length; i++) {
+ values[space][i] = vals[space.charAt(i)];
+ }
+
+ alpha = vals.a;
+ } else if (vals[spaces[space][0]] !== undefined) {
+ // {red: 10, green: 10, blue: 10}
+ var chans = spaces[space];
+
+ for (i = 0; i < space.length; i++) {
+ values[space][i] = vals[chans[i]];
+ }
+
+ alpha = vals.alpha;
+ }
+
+ values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));
+
+ if (space === 'alpha') {
+ return false;
+ }
+
+ var capped;
+
+ // cap values of the space prior converting all values
+ for (i = 0; i < space.length; i++) {
+ capped = Math.max(0, Math.min(maxes[space][i], values[space][i]));
+ values[space][i] = Math.round(capped);
+ }
+
+ // convert to all the other color spaces
+ for (var sname in spaces) {
+ if (sname !== space) {
+ values[sname] = colorConvert[space][sname](values[space]);
+ }
+ }
+
+ return true;
+};
+
+Color.prototype.setSpace = function (space, args) {
+ var vals = args[0];
+
+ if (vals === undefined) {
+ // color.rgb()
+ return this.getValues(space);
+ }
+
+ // color.rgb(10, 10, 10)
+ if (typeof vals === 'number') {
+ vals = Array.prototype.slice.call(args);
+ }
+
+ this.setValues(space, vals);
+ return this;
+};
+
+Color.prototype.setChannel = function (space, index, val) {
+ var svalues = this.values[space];
+ if (val === undefined) {
+ // color.red()
+ return svalues[index];
+ } else if (val === svalues[index]) {
+ // color.red(color.red())
+ return this;
+ }
+
+ // color.red(100)
+ svalues[index] = val;
+ this.setValues(space, svalues);
+
+ return this;
+};
+
+if (typeof window !== 'undefined') {
+ window.Color = Color;
+}
+
+var chartjsColor = Color;
+
+/**
+ * @namespace Chart.helpers
+ */
+var helpers = {
+ /**
+ * An empty function that can be used, for example, for optional callback.
+ */
+ noop: function() {},
+
+ /**
+ * Returns a unique id, sequentially generated from a global variable.
+ * @returns {number}
+ * @function
+ */
+ uid: (function() {
+ var id = 0;
+ return function() {
+ return id++;
+ };
+ }()),
+
+ /**
+ * Returns true if `value` is neither null nor undefined, else returns false.
+ * @param {*} value - The value to test.
+ * @returns {boolean}
+ * @since 2.7.0
+ */
+ isNullOrUndef: function(value) {
+ return value === null || typeof value === 'undefined';
+ },
+
+ /**
+ * Returns true if `value` is an array (including typed arrays), else returns false.
+ * @param {*} value - The value to test.
+ * @returns {boolean}
+ * @function
+ */
+ isArray: function(value) {
+ if (Array.isArray && Array.isArray(value)) {
+ return true;
+ }
+ var type = Object.prototype.toString.call(value);
+ if (type.substr(0, 7) === '[object' && type.substr(-6) === 'Array]') {
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Returns true if `value` is an object (excluding null), else returns false.
+ * @param {*} value - The value to test.
+ * @returns {boolean}
+ * @since 2.7.0
+ */
+ isObject: function(value) {
+ return value !== null && Object.prototype.toString.call(value) === '[object Object]';
+ },
+
+ /**
+ * Returns true if `value` is a finite number, else returns false
+ * @param {*} value - The value to test.
+ * @returns {boolean}
+ */
+ isFinite: function(value) {
+ return (typeof value === 'number' || value instanceof Number) && isFinite(value);
+ },
+
+ /**
+ * Returns `value` if defined, else returns `defaultValue`.
+ * @param {*} value - The value to return if defined.
+ * @param {*} defaultValue - The value to return if `value` is undefined.
+ * @returns {*}
+ */
+ valueOrDefault: function(value, defaultValue) {
+ return typeof value === 'undefined' ? defaultValue : value;
+ },
+
+ /**
+ * Returns value at the given `index` in array if defined, else returns `defaultValue`.
+ * @param {Array} value - The array to lookup for value at `index`.
+ * @param {number} index - The index in `value` to lookup for value.
+ * @param {*} defaultValue - The value to return if `value[index]` is undefined.
+ * @returns {*}
+ */
+ valueAtIndexOrDefault: function(value, index, defaultValue) {
+ return helpers.valueOrDefault(helpers.isArray(value) ? value[index] : value, defaultValue);
+ },
+
+ /**
+ * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the
+ * value returned by `fn`. If `fn` is not a function, this method returns undefined.
+ * @param {function} fn - The function to call.
+ * @param {Array|undefined|null} args - The arguments with which `fn` should be called.
+ * @param {object} [thisArg] - The value of `this` provided for the call to `fn`.
+ * @returns {*}
+ */
+ callback: function(fn, args, thisArg) {
+ if (fn && typeof fn.call === 'function') {
+ return fn.apply(thisArg, args);
+ }
+ },
+
+ /**
+ * Note(SB) for performance sake, this method should only be used when loopable type
+ * is unknown or in none intensive code (not called often and small loopable). Else
+ * it's preferable to use a regular for() loop and save extra function calls.
+ * @param {object|Array} loopable - The object or array to be iterated.
+ * @param {function} fn - The function to call for each item.
+ * @param {object} [thisArg] - The value of `this` provided for the call to `fn`.
+ * @param {boolean} [reverse] - If true, iterates backward on the loopable.
+ */
+ each: function(loopable, fn, thisArg, reverse) {
+ var i, len, keys;
+ if (helpers.isArray(loopable)) {
+ len = loopable.length;
+ if (reverse) {
+ for (i = len - 1; i >= 0; i--) {
+ fn.call(thisArg, loopable[i], i);
+ }
+ } else {
+ for (i = 0; i < len; i++) {
+ fn.call(thisArg, loopable[i], i);
+ }
+ }
+ } else if (helpers.isObject(loopable)) {
+ keys = Object.keys(loopable);
+ len = keys.length;
+ for (i = 0; i < len; i++) {
+ fn.call(thisArg, loopable[keys[i]], keys[i]);
+ }
+ }
+ },
+
+ /**
+ * Returns true if the `a0` and `a1` arrays have the same content, else returns false.
+ * @see https://stackoverflow.com/a/14853974
+ * @param {Array} a0 - The array to compare
+ * @param {Array} a1 - The array to compare
+ * @returns {boolean}
+ */
+ arrayEquals: function(a0, a1) {
+ var i, ilen, v0, v1;
+
+ if (!a0 || !a1 || a0.length !== a1.length) {
+ return false;
+ }
+
+ for (i = 0, ilen = a0.length; i < ilen; ++i) {
+ v0 = a0[i];
+ v1 = a1[i];
+
+ if (v0 instanceof Array && v1 instanceof Array) {
+ if (!helpers.arrayEquals(v0, v1)) {
+ return false;
+ }
+ } else if (v0 !== v1) {
+ // NOTE: two different object instances will never be equal: {x:20} != {x:20}
+ return false;
+ }
+ }
+
+ return true;
+ },
+
+ /**
+ * Returns a deep copy of `source` without keeping references on objects and arrays.
+ * @param {*} source - The value to clone.
+ * @returns {*}
+ */
+ clone: function(source) {
+ if (helpers.isArray(source)) {
+ return source.map(helpers.clone);
+ }
+
+ if (helpers.isObject(source)) {
+ var target = {};
+ var keys = Object.keys(source);
+ var klen = keys.length;
+ var k = 0;
+
+ for (; k < klen; ++k) {
+ target[keys[k]] = helpers.clone(source[keys[k]]);
+ }
+
+ return target;
+ }
+
+ return source;
+ },
+
+ /**
+ * The default merger when Chart.helpers.merge is called without merger option.
+ * Note(SB): also used by mergeConfig and mergeScaleConfig as fallback.
+ * @private
+ */
+ _merger: function(key, target, source, options) {
+ var tval = target[key];
+ var sval = source[key];
+
+ if (helpers.isObject(tval) && helpers.isObject(sval)) {
+ helpers.merge(tval, sval, options);
+ } else {
+ target[key] = helpers.clone(sval);
+ }
+ },
+
+ /**
+ * Merges source[key] in target[key] only if target[key] is undefined.
+ * @private
+ */
+ _mergerIf: function(key, target, source) {
+ var tval = target[key];
+ var sval = source[key];
+
+ if (helpers.isObject(tval) && helpers.isObject(sval)) {
+ helpers.mergeIf(tval, sval);
+ } else if (!target.hasOwnProperty(key)) {
+ target[key] = helpers.clone(sval);
+ }
+ },
+
+ /**
+ * Recursively deep copies `source` properties into `target` with the given `options`.
+ * IMPORTANT: `target` is not cloned and will be updated with `source` properties.
+ * @param {object} target - The target object in which all sources are merged into.
+ * @param {object|object[]} source - Object(s) to merge into `target`.
+ * @param {object} [options] - Merging options:
+ * @param {function} [options.merger] - The merge method (key, target, source, options)
+ * @returns {object} The `target` object.
+ */
+ merge: function(target, source, options) {
+ var sources = helpers.isArray(source) ? source : [source];
+ var ilen = sources.length;
+ var merge, i, keys, klen, k;
+
+ if (!helpers.isObject(target)) {
+ return target;
+ }
+
+ options = options || {};
+ merge = options.merger || helpers._merger;
+
+ for (i = 0; i < ilen; ++i) {
+ source = sources[i];
+ if (!helpers.isObject(source)) {
+ continue;
+ }
+
+ keys = Object.keys(source);
+ for (k = 0, klen = keys.length; k < klen; ++k) {
+ merge(keys[k], target, source, options);
+ }
+ }
+
+ return target;
+ },
+
+ /**
+ * Recursively deep copies `source` properties into `target` *only* if not defined in target.
+ * IMPORTANT: `target` is not cloned and will be updated with `source` properties.
+ * @param {object} target - The target object in which all sources are merged into.
+ * @param {object|object[]} source - Object(s) to merge into `target`.
+ * @returns {object} The `target` object.
+ */
+ mergeIf: function(target, source) {
+ return helpers.merge(target, source, {merger: helpers._mergerIf});
+ },
+
+ /**
+ * Applies the contents of two or more objects together into the first object.
+ * @param {object} target - The target object in which all objects are merged into.
+ * @param {object} arg1 - Object containing additional properties to merge in target.
+ * @param {object} argN - Additional objects containing properties to merge in target.
+ * @returns {object} The `target` object.
+ */
+ extend: Object.assign || function(target) {
+ return helpers.merge(target, [].slice.call(arguments, 1), {
+ merger: function(key, dst, src) {
+ dst[key] = src[key];
+ }
+ });
+ },
+
+ /**
+ * Basic javascript inheritance based on the model created in Backbone.js
+ */
+ inherits: function(extensions) {
+ var me = this;
+ var ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() {
+ return me.apply(this, arguments);
+ };
+
+ var Surrogate = function() {
+ this.constructor = ChartElement;
+ };
+
+ Surrogate.prototype = me.prototype;
+ ChartElement.prototype = new Surrogate();
+ ChartElement.extend = helpers.inherits;
+
+ if (extensions) {
+ helpers.extend(ChartElement.prototype, extensions);
+ }
+
+ ChartElement.__super__ = me.prototype;
+ return ChartElement;
+ },
+
+ _deprecated: function(scope, value, previous, current) {
+ if (value !== undefined) {
+ console.warn(scope + ': "' + previous +
+ '" is deprecated. Please use "' + current + '" instead');
+ }
+ }
+};
+
+var helpers_core = helpers;
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.callback instead.
+ * @function Chart.helpers.callCallback
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.callCallback = helpers.callback;
+
+/**
+ * Provided for backward compatibility, use Array.prototype.indexOf instead.
+ * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+
+ * @function Chart.helpers.indexOf
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.indexOf = function(array, item, fromIndex) {
+ return Array.prototype.indexOf.call(array, item, fromIndex);
+};
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead.
+ * @function Chart.helpers.getValueOrDefault
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.getValueOrDefault = helpers.valueOrDefault;
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead.
+ * @function Chart.helpers.getValueAtIndexOrDefault
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
+
+/**
+ * Easing functions adapted from Robert Penner's easing equations.
+ * @namespace Chart.helpers.easingEffects
+ * @see http://www.robertpenner.com/easing/
+ */
+var effects = {
+ linear: function(t) {
+ return t;
+ },
+
+ easeInQuad: function(t) {
+ return t * t;
+ },
+
+ easeOutQuad: function(t) {
+ return -t * (t - 2);
+ },
+
+ easeInOutQuad: function(t) {
+ if ((t /= 0.5) < 1) {
+ return 0.5 * t * t;
+ }
+ return -0.5 * ((--t) * (t - 2) - 1);
+ },
+
+ easeInCubic: function(t) {
+ return t * t * t;
+ },
+
+ easeOutCubic: function(t) {
+ return (t = t - 1) * t * t + 1;
+ },
+
+ easeInOutCubic: function(t) {
+ if ((t /= 0.5) < 1) {
+ return 0.5 * t * t * t;
+ }
+ return 0.5 * ((t -= 2) * t * t + 2);
+ },
+
+ easeInQuart: function(t) {
+ return t * t * t * t;
+ },
+
+ easeOutQuart: function(t) {
+ return -((t = t - 1) * t * t * t - 1);
+ },
+
+ easeInOutQuart: function(t) {
+ if ((t /= 0.5) < 1) {
+ return 0.5 * t * t * t * t;
+ }
+ return -0.5 * ((t -= 2) * t * t * t - 2);
+ },
+
+ easeInQuint: function(t) {
+ return t * t * t * t * t;
+ },
+
+ easeOutQuint: function(t) {
+ return (t = t - 1) * t * t * t * t + 1;
+ },
+
+ easeInOutQuint: function(t) {
+ if ((t /= 0.5) < 1) {
+ return 0.5 * t * t * t * t * t;
+ }
+ return 0.5 * ((t -= 2) * t * t * t * t + 2);
+ },
+
+ easeInSine: function(t) {
+ return -Math.cos(t * (Math.PI / 2)) + 1;
+ },
+
+ easeOutSine: function(t) {
+ return Math.sin(t * (Math.PI / 2));
+ },
+
+ easeInOutSine: function(t) {
+ return -0.5 * (Math.cos(Math.PI * t) - 1);
+ },
+
+ easeInExpo: function(t) {
+ return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1));
+ },
+
+ easeOutExpo: function(t) {
+ return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1;
+ },
+
+ easeInOutExpo: function(t) {
+ if (t === 0) {
+ return 0;
+ }
+ if (t === 1) {
+ return 1;
+ }
+ if ((t /= 0.5) < 1) {
+ return 0.5 * Math.pow(2, 10 * (t - 1));
+ }
+ return 0.5 * (-Math.pow(2, -10 * --t) + 2);
+ },
+
+ easeInCirc: function(t) {
+ if (t >= 1) {
+ return t;
+ }
+ return -(Math.sqrt(1 - t * t) - 1);
+ },
+
+ easeOutCirc: function(t) {
+ return Math.sqrt(1 - (t = t - 1) * t);
+ },
+
+ easeInOutCirc: function(t) {
+ if ((t /= 0.5) < 1) {
+ return -0.5 * (Math.sqrt(1 - t * t) - 1);
+ }
+ return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1);
+ },
+
+ easeInElastic: function(t) {
+ var s = 1.70158;
+ var p = 0;
+ var a = 1;
+ if (t === 0) {
+ return 0;
+ }
+ if (t === 1) {
+ return 1;
+ }
+ if (!p) {
+ p = 0.3;
+ }
+ if (a < 1) {
+ a = 1;
+ s = p / 4;
+ } else {
+ s = p / (2 * Math.PI) * Math.asin(1 / a);
+ }
+ return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));
+ },
+
+ easeOutElastic: function(t) {
+ var s = 1.70158;
+ var p = 0;
+ var a = 1;
+ if (t === 0) {
+ return 0;
+ }
+ if (t === 1) {
+ return 1;
+ }
+ if (!p) {
+ p = 0.3;
+ }
+ if (a < 1) {
+ a = 1;
+ s = p / 4;
+ } else {
+ s = p / (2 * Math.PI) * Math.asin(1 / a);
+ }
+ return a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1;
+ },
+
+ easeInOutElastic: function(t) {
+ var s = 1.70158;
+ var p = 0;
+ var a = 1;
+ if (t === 0) {
+ return 0;
+ }
+ if ((t /= 0.5) === 2) {
+ return 1;
+ }
+ if (!p) {
+ p = 0.45;
+ }
+ if (a < 1) {
+ a = 1;
+ s = p / 4;
+ } else {
+ s = p / (2 * Math.PI) * Math.asin(1 / a);
+ }
+ if (t < 1) {
+ return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));
+ }
+ return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1;
+ },
+ easeInBack: function(t) {
+ var s = 1.70158;
+ return t * t * ((s + 1) * t - s);
+ },
+
+ easeOutBack: function(t) {
+ var s = 1.70158;
+ return (t = t - 1) * t * ((s + 1) * t + s) + 1;
+ },
+
+ easeInOutBack: function(t) {
+ var s = 1.70158;
+ if ((t /= 0.5) < 1) {
+ return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s));
+ }
+ return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
+ },
+
+ easeInBounce: function(t) {
+ return 1 - effects.easeOutBounce(1 - t);
+ },
+
+ easeOutBounce: function(t) {
+ if (t < (1 / 2.75)) {
+ return 7.5625 * t * t;
+ }
+ if (t < (2 / 2.75)) {
+ return 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75;
+ }
+ if (t < (2.5 / 2.75)) {
+ return 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375;
+ }
+ return 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375;
+ },
+
+ easeInOutBounce: function(t) {
+ if (t < 0.5) {
+ return effects.easeInBounce(t * 2) * 0.5;
+ }
+ return effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5;
+ }
+};
+
+var helpers_easing = {
+ effects: effects
+};
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.easing.effects instead.
+ * @function Chart.helpers.easingEffects
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers_core.easingEffects = effects;
+
+var PI = Math.PI;
+var RAD_PER_DEG = PI / 180;
+var DOUBLE_PI = PI * 2;
+var HALF_PI = PI / 2;
+var QUARTER_PI = PI / 4;
+var TWO_THIRDS_PI = PI * 2 / 3;
+
+/**
+ * @namespace Chart.helpers.canvas
+ */
+var exports$1 = {
+ /**
+ * Clears the entire canvas associated to the given `chart`.
+ * @param {Chart} chart - The chart for which to clear the canvas.
+ */
+ clear: function(chart) {
+ chart.ctx.clearRect(0, 0, chart.width, chart.height);
+ },
+
+ /**
+ * Creates a "path" for a rectangle with rounded corners at position (x, y) with a
+ * given size (width, height) and the same `radius` for all corners.
+ * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context.
+ * @param {number} x - The x axis of the coordinate for the rectangle starting point.
+ * @param {number} y - The y axis of the coordinate for the rectangle starting point.
+ * @param {number} width - The rectangle's width.
+ * @param {number} height - The rectangle's height.
+ * @param {number} radius - The rounded amount (in pixels) for the four corners.
+ * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object?
+ */
+ roundedRect: function(ctx, x, y, width, height, radius) {
+ if (radius) {
+ var r = Math.min(radius, height / 2, width / 2);
+ var left = x + r;
+ var top = y + r;
+ var right = x + width - r;
+ var bottom = y + height - r;
+
+ ctx.moveTo(x, top);
+ if (left < right && top < bottom) {
+ ctx.arc(left, top, r, -PI, -HALF_PI);
+ ctx.arc(right, top, r, -HALF_PI, 0);
+ ctx.arc(right, bottom, r, 0, HALF_PI);
+ ctx.arc(left, bottom, r, HALF_PI, PI);
+ } else if (left < right) {
+ ctx.moveTo(left, y);
+ ctx.arc(right, top, r, -HALF_PI, HALF_PI);
+ ctx.arc(left, top, r, HALF_PI, PI + HALF_PI);
+ } else if (top < bottom) {
+ ctx.arc(left, top, r, -PI, 0);
+ ctx.arc(left, bottom, r, 0, PI);
+ } else {
+ ctx.arc(left, top, r, -PI, PI);
+ }
+ ctx.closePath();
+ ctx.moveTo(x, y);
+ } else {
+ ctx.rect(x, y, width, height);
+ }
+ },
+
+ drawPoint: function(ctx, style, radius, x, y, rotation) {
+ var type, xOffset, yOffset, size, cornerRadius;
+ var rad = (rotation || 0) * RAD_PER_DEG;
+
+ if (style && typeof style === 'object') {
+ type = style.toString();
+ if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
+ ctx.save();
+ ctx.translate(x, y);
+ ctx.rotate(rad);
+ ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height);
+ ctx.restore();
+ return;
+ }
+ }
+
+ if (isNaN(radius) || radius <= 0) {
+ return;
+ }
+
+ ctx.beginPath();
+
+ switch (style) {
+ // Default includes circle
+ default:
+ ctx.arc(x, y, radius, 0, DOUBLE_PI);
+ ctx.closePath();
+ break;
+ case 'triangle':
+ ctx.moveTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);
+ rad += TWO_THIRDS_PI;
+ ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);
+ rad += TWO_THIRDS_PI;
+ ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);
+ ctx.closePath();
+ break;
+ case 'rectRounded':
+ // NOTE: the rounded rect implementation changed to use `arc` instead of
+ // `quadraticCurveTo` since it generates better results when rect is
+ // almost a circle. 0.516 (instead of 0.5) produces results with visually
+ // closer proportion to the previous impl and it is inscribed in the
+ // circle with `radius`. For more details, see the following PRs:
+ // https://github.com/chartjs/Chart.js/issues/5597
+ // https://github.com/chartjs/Chart.js/issues/5858
+ cornerRadius = radius * 0.516;
+ size = radius - cornerRadius;
+ xOffset = Math.cos(rad + QUARTER_PI) * size;
+ yOffset = Math.sin(rad + QUARTER_PI) * size;
+ ctx.arc(x - xOffset, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI);
+ ctx.arc(x + yOffset, y - xOffset, cornerRadius, rad - HALF_PI, rad);
+ ctx.arc(x + xOffset, y + yOffset, cornerRadius, rad, rad + HALF_PI);
+ ctx.arc(x - yOffset, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI);
+ ctx.closePath();
+ break;
+ case 'rect':
+ if (!rotation) {
+ size = Math.SQRT1_2 * radius;
+ ctx.rect(x - size, y - size, 2 * size, 2 * size);
+ break;
+ }
+ rad += QUARTER_PI;
+ /* falls through */
+ case 'rectRot':
+ xOffset = Math.cos(rad) * radius;
+ yOffset = Math.sin(rad) * radius;
+ ctx.moveTo(x - xOffset, y - yOffset);
+ ctx.lineTo(x + yOffset, y - xOffset);
+ ctx.lineTo(x + xOffset, y + yOffset);
+ ctx.lineTo(x - yOffset, y + xOffset);
+ ctx.closePath();
+ break;
+ case 'crossRot':
+ rad += QUARTER_PI;
+ /* falls through */
+ case 'cross':
+ xOffset = Math.cos(rad) * radius;
+ yOffset = Math.sin(rad) * radius;
+ ctx.moveTo(x - xOffset, y - yOffset);
+ ctx.lineTo(x + xOffset, y + yOffset);
+ ctx.moveTo(x + yOffset, y - xOffset);
+ ctx.lineTo(x - yOffset, y + xOffset);
+ break;
+ case 'star':
+ xOffset = Math.cos(rad) * radius;
+ yOffset = Math.sin(rad) * radius;
+ ctx.moveTo(x - xOffset, y - yOffset);
+ ctx.lineTo(x + xOffset, y + yOffset);
+ ctx.moveTo(x + yOffset, y - xOffset);
+ ctx.lineTo(x - yOffset, y + xOffset);
+ rad += QUARTER_PI;
+ xOffset = Math.cos(rad) * radius;
+ yOffset = Math.sin(rad) * radius;
+ ctx.moveTo(x - xOffset, y - yOffset);
+ ctx.lineTo(x + xOffset, y + yOffset);
+ ctx.moveTo(x + yOffset, y - xOffset);
+ ctx.lineTo(x - yOffset, y + xOffset);
+ break;
+ case 'line':
+ xOffset = Math.cos(rad) * radius;
+ yOffset = Math.sin(rad) * radius;
+ ctx.moveTo(x - xOffset, y - yOffset);
+ ctx.lineTo(x + xOffset, y + yOffset);
+ break;
+ case 'dash':
+ ctx.moveTo(x, y);
+ ctx.lineTo(x + Math.cos(rad) * radius, y + Math.sin(rad) * radius);
+ break;
+ }
+
+ ctx.fill();
+ ctx.stroke();
+ },
+
+ /**
+ * Returns true if the point is inside the rectangle
+ * @param {object} point - The point to test
+ * @param {object} area - The rectangle
+ * @returns {boolean}
+ * @private
+ */
+ _isPointInArea: function(point, area) {
+ var epsilon = 1e-6; // 1e-6 is margin in pixels for accumulated error.
+
+ return point.x > area.left - epsilon && point.x < area.right + epsilon &&
+ point.y > area.top - epsilon && point.y < area.bottom + epsilon;
+ },
+
+ clipArea: function(ctx, area) {
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);
+ ctx.clip();
+ },
+
+ unclipArea: function(ctx) {
+ ctx.restore();
+ },
+
+ lineTo: function(ctx, previous, target, flip) {
+ var stepped = target.steppedLine;
+ if (stepped) {
+ if (stepped === 'middle') {
+ var midpoint = (previous.x + target.x) / 2.0;
+ ctx.lineTo(midpoint, flip ? target.y : previous.y);
+ ctx.lineTo(midpoint, flip ? previous.y : target.y);
+ } else if ((stepped === 'after' && !flip) || (stepped !== 'after' && flip)) {
+ ctx.lineTo(previous.x, target.y);
+ } else {
+ ctx.lineTo(target.x, previous.y);
+ }
+ ctx.lineTo(target.x, target.y);
+ return;
+ }
+
+ if (!target.tension) {
+ ctx.lineTo(target.x, target.y);
+ return;
+ }
+
+ ctx.bezierCurveTo(
+ flip ? previous.controlPointPreviousX : previous.controlPointNextX,
+ flip ? previous.controlPointPreviousY : previous.controlPointNextY,
+ flip ? target.controlPointNextX : target.controlPointPreviousX,
+ flip ? target.controlPointNextY : target.controlPointPreviousY,
+ target.x,
+ target.y);
+ }
+};
+
+var helpers_canvas = exports$1;
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.canvas.clear instead.
+ * @namespace Chart.helpers.clear
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers_core.clear = exports$1.clear;
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead.
+ * @namespace Chart.helpers.drawRoundedRectangle
+ * @deprecated since version 2.7.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers_core.drawRoundedRectangle = function(ctx) {
+ ctx.beginPath();
+ exports$1.roundedRect.apply(exports$1, arguments);
+};
+
+var defaults = {
+ /**
+ * @private
+ */
+ _set: function(scope, values) {
+ return helpers_core.merge(this[scope] || (this[scope] = {}), values);
+ }
+};
+
+// TODO(v3): remove 'global' from namespace. all default are global and
+// there's inconsistency around which options are under 'global'
+defaults._set('global', {
+ defaultColor: 'rgba(0,0,0,0.1)',
+ defaultFontColor: '#666',
+ defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
+ defaultFontSize: 12,
+ defaultFontStyle: 'normal',
+ defaultLineHeight: 1.2,
+ showLines: true
+});
+
+var core_defaults = defaults;
+
+var valueOrDefault = helpers_core.valueOrDefault;
+
+/**
+ * Converts the given font object into a CSS font string.
+ * @param {object} font - A font object.
+ * @return {string} The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font
+ * @private
+ */
+function toFontString(font) {
+ if (!font || helpers_core.isNullOrUndef(font.size) || helpers_core.isNullOrUndef(font.family)) {
+ return null;
+ }
+
+ return (font.style ? font.style + ' ' : '')
+ + (font.weight ? font.weight + ' ' : '')
+ + font.size + 'px '
+ + font.family;
+}
+
+/**
+ * @alias Chart.helpers.options
+ * @namespace
+ */
+var helpers_options = {
+ /**
+ * Converts the given line height `value` in pixels for a specific font `size`.
+ * @param {number|string} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em').
+ * @param {number} size - The font size (in pixels) used to resolve relative `value`.
+ * @returns {number} The effective line height in pixels (size * 1.2 if value is invalid).
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height
+ * @since 2.7.0
+ */
+ toLineHeight: function(value, size) {
+ var matches = ('' + value).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);
+ if (!matches || matches[1] === 'normal') {
+ return size * 1.2;
+ }
+
+ value = +matches[2];
+
+ switch (matches[3]) {
+ case 'px':
+ return value;
+ case '%':
+ value /= 100;
+ break;
+ }
+
+ return size * value;
+ },
+
+ /**
+ * Converts the given value into a padding object with pre-computed width/height.
+ * @param {number|object} value - If a number, set the value to all TRBL component,
+ * else, if and object, use defined properties and sets undefined ones to 0.
+ * @returns {object} The padding values (top, right, bottom, left, width, height)
+ * @since 2.7.0
+ */
+ toPadding: function(value) {
+ var t, r, b, l;
+
+ if (helpers_core.isObject(value)) {
+ t = +value.top || 0;
+ r = +value.right || 0;
+ b = +value.bottom || 0;
+ l = +value.left || 0;
+ } else {
+ t = r = b = l = +value || 0;
+ }
+
+ return {
+ top: t,
+ right: r,
+ bottom: b,
+ left: l,
+ height: t + b,
+ width: l + r
+ };
+ },
+
+ /**
+ * Parses font options and returns the font object.
+ * @param {object} options - A object that contains font options to be parsed.
+ * @return {object} The font object.
+ * @todo Support font.* options and renamed to toFont().
+ * @private
+ */
+ _parseFont: function(options) {
+ var globalDefaults = core_defaults.global;
+ var size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize);
+ var font = {
+ family: valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily),
+ lineHeight: helpers_core.options.toLineHeight(valueOrDefault(options.lineHeight, globalDefaults.defaultLineHeight), size),
+ size: size,
+ style: valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle),
+ weight: null,
+ string: ''
+ };
+
+ font.string = toFontString(font);
+ return font;
+ },
+
+ /**
+ * Evaluates the given `inputs` sequentially and returns the first defined value.
+ * @param {Array} inputs - An array of values, falling back to the last value.
+ * @param {object} [context] - If defined and the current value is a function, the value
+ * is called with `context` as first argument and the result becomes the new input.
+ * @param {number} [index] - If defined and the current value is an array, the value
+ * at `index` become the new input.
+ * @param {object} [info] - object to return information about resolution in
+ * @param {boolean} [info.cacheable] - Will be set to `false` if option is not cacheable.
+ * @since 2.7.0
+ */
+ resolve: function(inputs, context, index, info) {
+ var cacheable = true;
+ var i, ilen, value;
+
+ for (i = 0, ilen = inputs.length; i < ilen; ++i) {
+ value = inputs[i];
+ if (value === undefined) {
+ continue;
+ }
+ if (context !== undefined && typeof value === 'function') {
+ value = value(context);
+ cacheable = false;
+ }
+ if (index !== undefined && helpers_core.isArray(value)) {
+ value = value[index];
+ cacheable = false;
+ }
+ if (value !== undefined) {
+ if (info && !cacheable) {
+ info.cacheable = false;
+ }
+ return value;
+ }
+ }
+ }
+};
+
+/**
+ * @alias Chart.helpers.math
+ * @namespace
+ */
+var exports$2 = {
+ /**
+ * Returns an array of factors sorted from 1 to sqrt(value)
+ * @private
+ */
+ _factorize: function(value) {
+ var result = [];
+ var sqrt = Math.sqrt(value);
+ var i;
+
+ for (i = 1; i < sqrt; i++) {
+ if (value % i === 0) {
+ result.push(i);
+ result.push(value / i);
+ }
+ }
+ if (sqrt === (sqrt | 0)) { // if value is a square number
+ result.push(sqrt);
+ }
+
+ result.sort(function(a, b) {
+ return a - b;
+ }).pop();
+ return result;
+ },
+
+ log10: Math.log10 || function(x) {
+ var exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10.
+ // Check for whole powers of 10,
+ // which due to floating point rounding error should be corrected.
+ var powerOf10 = Math.round(exponent);
+ var isPowerOf10 = x === Math.pow(10, powerOf10);
+
+ return isPowerOf10 ? powerOf10 : exponent;
+ }
+};
+
+var helpers_math = exports$2;
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.helpers.math.log10 instead.
+ * @namespace Chart.helpers.log10
+ * @deprecated since version 2.9.0
+ * @todo remove at version 3
+ * @private
+ */
+helpers_core.log10 = exports$2.log10;
+
+var getRtlAdapter = function(rectX, width) {
+ return {
+ x: function(x) {
+ return rectX + rectX + width - x;
+ },
+ setWidth: function(w) {
+ width = w;
+ },
+ textAlign: function(align) {
+ if (align === 'center') {
+ return align;
+ }
+ return align === 'right' ? 'left' : 'right';
+ },
+ xPlus: function(x, value) {
+ return x - value;
+ },
+ leftForLtr: function(x, itemWidth) {
+ return x - itemWidth;
+ },
+ };
+};
+
+var getLtrAdapter = function() {
+ return {
+ x: function(x) {
+ return x;
+ },
+ setWidth: function(w) { // eslint-disable-line no-unused-vars
+ },
+ textAlign: function(align) {
+ return align;
+ },
+ xPlus: function(x, value) {
+ return x + value;
+ },
+ leftForLtr: function(x, _itemWidth) { // eslint-disable-line no-unused-vars
+ return x;
+ },
+ };
+};
+
+var getAdapter = function(rtl, rectX, width) {
+ return rtl ? getRtlAdapter(rectX, width) : getLtrAdapter();
+};
+
+var overrideTextDirection = function(ctx, direction) {
+ var style, original;
+ if (direction === 'ltr' || direction === 'rtl') {
+ style = ctx.canvas.style;
+ original = [
+ style.getPropertyValue('direction'),
+ style.getPropertyPriority('direction'),
+ ];
+
+ style.setProperty('direction', direction, 'important');
+ ctx.prevTextDirection = original;
+ }
+};
+
+var restoreTextDirection = function(ctx) {
+ var original = ctx.prevTextDirection;
+ if (original !== undefined) {
+ delete ctx.prevTextDirection;
+ ctx.canvas.style.setProperty('direction', original[0], original[1]);
+ }
+};
+
+var helpers_rtl = {
+ getRtlAdapter: getAdapter,
+ overrideTextDirection: overrideTextDirection,
+ restoreTextDirection: restoreTextDirection,
+};
+
+var helpers$1 = helpers_core;
+var easing = helpers_easing;
+var canvas = helpers_canvas;
+var options = helpers_options;
+var math = helpers_math;
+var rtl = helpers_rtl;
+helpers$1.easing = easing;
+helpers$1.canvas = canvas;
+helpers$1.options = options;
+helpers$1.math = math;
+helpers$1.rtl = rtl;
+
+function interpolate(start, view, model, ease) {
+ var keys = Object.keys(model);
+ var i, ilen, key, actual, origin, target, type, c0, c1;
+
+ for (i = 0, ilen = keys.length; i < ilen; ++i) {
+ key = keys[i];
+
+ target = model[key];
+
+ // if a value is added to the model after pivot() has been called, the view
+ // doesn't contain it, so let's initialize the view to the target value.
+ if (!view.hasOwnProperty(key)) {
+ view[key] = target;
+ }
+
+ actual = view[key];
+
+ if (actual === target || key[0] === '_') {
+ continue;
+ }
+
+ if (!start.hasOwnProperty(key)) {
+ start[key] = actual;
+ }
+
+ origin = start[key];
+
+ type = typeof target;
+
+ if (type === typeof origin) {
+ if (type === 'string') {
+ c0 = chartjsColor(origin);
+ if (c0.valid) {
+ c1 = chartjsColor(target);
+ if (c1.valid) {
+ view[key] = c1.mix(c0, ease).rgbString();
+ continue;
+ }
+ }
+ } else if (helpers$1.isFinite(origin) && helpers$1.isFinite(target)) {
+ view[key] = origin + (target - origin) * ease;
+ continue;
+ }
+ }
+
+ view[key] = target;
+ }
+}
+
+var Element = function(configuration) {
+ helpers$1.extend(this, configuration);
+ this.initialize.apply(this, arguments);
+};
+
+helpers$1.extend(Element.prototype, {
+ _type: undefined,
+
+ initialize: function() {
+ this.hidden = false;
+ },
+
+ pivot: function() {
+ var me = this;
+ if (!me._view) {
+ me._view = helpers$1.extend({}, me._model);
+ }
+ me._start = {};
+ return me;
+ },
+
+ transition: function(ease) {
+ var me = this;
+ var model = me._model;
+ var start = me._start;
+ var view = me._view;
+
+ // No animation -> No Transition
+ if (!model || ease === 1) {
+ me._view = helpers$1.extend({}, model);
+ me._start = null;
+ return me;
+ }
+
+ if (!view) {
+ view = me._view = {};
+ }
+
+ if (!start) {
+ start = me._start = {};
+ }
+
+ interpolate(start, view, model, ease);
+
+ return me;
+ },
+
+ tooltipPosition: function() {
+ return {
+ x: this._model.x,
+ y: this._model.y
+ };
+ },
+
+ hasValue: function() {
+ return helpers$1.isNumber(this._model.x) && helpers$1.isNumber(this._model.y);
+ }
+});
+
+Element.extend = helpers$1.inherits;
+
+var core_element = Element;
+
+var exports$3 = core_element.extend({
+ chart: null, // the animation associated chart instance
+ currentStep: 0, // the current animation step
+ numSteps: 60, // default number of steps
+ easing: '', // the easing to use for this animation
+ render: null, // render function used by the animation service
+
+ onAnimationProgress: null, // user specified callback to fire on each step of the animation
+ onAnimationComplete: null, // user specified callback to fire when the animation finishes
+});
+
+var core_animation = exports$3;
+
+// DEPRECATIONS
+
+/**
+ * Provided for backward compatibility, use Chart.Animation instead
+ * @prop Chart.Animation#animationObject
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ */
+Object.defineProperty(exports$3.prototype, 'animationObject', {
+ get: function() {
+ return this;
+ }
+});
+
+/**
+ * Provided for backward compatibility, use Chart.Animation#chart instead
+ * @prop Chart.Animation#chartInstance
+ * @deprecated since version 2.6.0
+ * @todo remove at version 3
+ */
+Object.defineProperty(exports$3.prototype, 'chartInstance', {
+ get: function() {
+ return this.chart;
+ },
+ set: function(value) {
+ this.chart = value;
+ }
+});
+
+core_defaults._set('global', {
+ animation: {
+ duration: 1000,
+ easing: 'easeOutQuart',
+ onProgress: helpers$1.noop,
+ onComplete: helpers$1.noop
+ }
+});
+
+var core_animations = {
+ animations: [],
+ request: null,
+
+ /**
+ * @param {Chart} chart - The chart to animate.
+ * @param {Chart.Animation} animation - The animation that we will animate.
+ * @param {number} duration - The animation duration in ms.
+ * @param {boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions
+ */
+ addAnimation: function(chart, animation, duration, lazy) {
+ var animations = this.animations;
+ var i, ilen;
+
+ animation.chart = chart;
+ animation.startTime = Date.now();
+ animation.duration = duration;
+
+ if (!lazy) {
+ chart.animating = true;
+ }
+
+ for (i = 0, ilen = animations.length; i < ilen; ++i) {
+ if (animations[i].chart === chart) {
+ animations[i] = animation;
+ return;
+ }
+ }
+
+ animations.push(animation);
+
+ // If there are no animations queued, manually kickstart a digest, for lack of a better word
+ if (animations.length === 1) {
+ this.requestAnimationFrame();
+ }
+ },
+
+ cancelAnimation: function(chart) {
+ var index = helpers$1.findIndex(this.animations, function(animation) {
+ return animation.chart === chart;
+ });
+
+ if (index !== -1) {
+ this.animations.splice(index, 1);
+ chart.animating = false;
+ }
+ },
+
+ requestAnimationFrame: function() {
+ var me = this;
+ if (me.request === null) {
+ // Skip animation frame requests until the active one is executed.
+ // This can happen when processing mouse events, e.g. 'mousemove'
+ // and 'mouseout' events will trigger multiple renders.
+ me.request = helpers$1.requestAnimFrame.call(window, function() {
+ me.request = null;
+ me.startDigest();
+ });
+ }
+ },
+
+ /**
+ * @private
+ */
+ startDigest: function() {
+ var me = this;
+
+ me.advance();
+
+ // Do we have more stuff to animate?
+ if (me.animations.length > 0) {
+ me.requestAnimationFrame();
+ }
+ },
+
+ /**
+ * @private
+ */
+ advance: function() {
+ var animations = this.animations;
+ var animation, chart, numSteps, nextStep;
+ var i = 0;
+
+ // 1 animation per chart, so we are looping charts here
+ while (i < animations.length) {
+ animation = animations[i];
+ chart = animation.chart;
+ numSteps = animation.numSteps;
+
+ // Make sure that currentStep starts at 1
+ // https://github.com/chartjs/Chart.js/issues/6104
+ nextStep = Math.floor((Date.now() - animation.startTime) / animation.duration * numSteps) + 1;
+ animation.currentStep = Math.min(nextStep, numSteps);
+
+ helpers$1.callback(animation.render, [chart, animation], chart);
+ helpers$1.callback(animation.onAnimationProgress, [animation], chart);
+
+ if (animation.currentStep >= numSteps) {
+ helpers$1.callback(animation.onAnimationComplete, [animation], chart);
+ chart.animating = false;
+ animations.splice(i, 1);
+ } else {
+ ++i;
+ }
+ }
+ }
+};
+
+var resolve = helpers$1.options.resolve;
+
+var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
+
+/**
+ * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',
+ * 'unshift') and notify the listener AFTER the array has been altered. Listeners are
+ * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.
+ */
+function listenArrayEvents(array, listener) {
+ if (array._chartjs) {
+ array._chartjs.listeners.push(listener);
+ return;
+ }
+
+ Object.defineProperty(array, '_chartjs', {
+ configurable: true,
+ enumerable: false,
+ value: {
+ listeners: [listener]
+ }
+ });
+
+ arrayEvents.forEach(function(key) {
+ var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);
+ var base = array[key];
+
+ Object.defineProperty(array, key, {
+ configurable: true,
+ enumerable: false,
+ value: function() {
+ var args = Array.prototype.slice.call(arguments);
+ var res = base.apply(this, args);
+
+ helpers$1.each(array._chartjs.listeners, function(object) {
+ if (typeof object[method] === 'function') {
+ object[method].apply(object, args);
+ }
+ });
+
+ return res;
+ }
+ });
+ });
+}
+
+/**
+ * Removes the given array event listener and cleanup extra attached properties (such as
+ * the _chartjs stub and overridden methods) if array doesn't have any more listeners.
+ */
+function unlistenArrayEvents(array, listener) {
+ var stub = array._chartjs;
+ if (!stub) {
+ return;
+ }
+
+ var listeners = stub.listeners;
+ var index = listeners.indexOf(listener);
+ if (index !== -1) {
+ listeners.splice(index, 1);
+ }
+
+ if (listeners.length > 0) {
+ return;
+ }
+
+ arrayEvents.forEach(function(key) {
+ delete array[key];
+ });
+
+ delete array._chartjs;
+}
+
+// Base class for all dataset controllers (line, bar, etc)
+var DatasetController = function(chart, datasetIndex) {
+ this.initialize(chart, datasetIndex);
+};
+
+helpers$1.extend(DatasetController.prototype, {
+
+ /**
+ * Element type used to generate a meta dataset (e.g. Chart.element.Line).
+ * @type {Chart.core.element}
+ */
+ datasetElementType: null,
+
+ /**
+ * Element type used to generate a meta data (e.g. Chart.element.Point).
+ * @type {Chart.core.element}
+ */
+ dataElementType: null,
+
+ /**
+ * Dataset element option keys to be resolved in _resolveDatasetElementOptions.
+ * A derived controller may override this to resolve controller-specific options.
+ * The keys defined here are for backward compatibility for legend styles.
+ * @private
+ */
+ _datasetElementOptions: [
+ 'backgroundColor',
+ 'borderCapStyle',
+ 'borderColor',
+ 'borderDash',
+ 'borderDashOffset',
+ 'borderJoinStyle',
+ 'borderWidth'
+ ],
+
+ /**
+ * Data element option keys to be resolved in _resolveDataElementOptions.
+ * A derived controller may override this to resolve controller-specific options.
+ * The keys defined here are for backward compatibility for legend styles.
+ * @private
+ */
+ _dataElementOptions: [
+ 'backgroundColor',
+ 'borderColor',
+ 'borderWidth',
+ 'pointStyle'
+ ],
+
+ initialize: function(chart, datasetIndex) {
+ var me = this;
+ me.chart = chart;
+ me.index = datasetIndex;
+ me.linkScales();
+ me.addElements();
+ me._type = me.getMeta().type;
+ },
+
+ updateIndex: function(datasetIndex) {
+ this.index = datasetIndex;
+ },
+
+ linkScales: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var chart = me.chart;
+ var scales = chart.scales;
+ var dataset = me.getDataset();
+ var scalesOpts = chart.options.scales;
+
+ if (meta.xAxisID === null || !(meta.xAxisID in scales) || dataset.xAxisID) {
+ meta.xAxisID = dataset.xAxisID || scalesOpts.xAxes[0].id;
+ }
+ if (meta.yAxisID === null || !(meta.yAxisID in scales) || dataset.yAxisID) {
+ meta.yAxisID = dataset.yAxisID || scalesOpts.yAxes[0].id;
+ }
+ },
+
+ getDataset: function() {
+ return this.chart.data.datasets[this.index];
+ },
+
+ getMeta: function() {
+ return this.chart.getDatasetMeta(this.index);
+ },
+
+ getScaleForId: function(scaleID) {
+ return this.chart.scales[scaleID];
+ },
+
+ /**
+ * @private
+ */
+ _getValueScaleId: function() {
+ return this.getMeta().yAxisID;
+ },
+
+ /**
+ * @private
+ */
+ _getIndexScaleId: function() {
+ return this.getMeta().xAxisID;
+ },
+
+ /**
+ * @private
+ */
+ _getValueScale: function() {
+ return this.getScaleForId(this._getValueScaleId());
+ },
+
+ /**
+ * @private
+ */
+ _getIndexScale: function() {
+ return this.getScaleForId(this._getIndexScaleId());
+ },
+
+ reset: function() {
+ this._update(true);
+ },
+
+ /**
+ * @private
+ */
+ destroy: function() {
+ if (this._data) {
+ unlistenArrayEvents(this._data, this);
+ }
+ },
+
+ createMetaDataset: function() {
+ var me = this;
+ var type = me.datasetElementType;
+ return type && new type({
+ _chart: me.chart,
+ _datasetIndex: me.index
+ });
+ },
+
+ createMetaData: function(index) {
+ var me = this;
+ var type = me.dataElementType;
+ return type && new type({
+ _chart: me.chart,
+ _datasetIndex: me.index,
+ _index: index
+ });
+ },
+
+ addElements: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var data = me.getDataset().data || [];
+ var metaData = meta.data;
+ var i, ilen;
+
+ for (i = 0, ilen = data.length; i < ilen; ++i) {
+ metaData[i] = metaData[i] || me.createMetaData(i);
+ }
+
+ meta.dataset = meta.dataset || me.createMetaDataset();
+ },
+
+ addElementAndReset: function(index) {
+ var element = this.createMetaData(index);
+ this.getMeta().data.splice(index, 0, element);
+ this.updateElement(element, index, true);
+ },
+
+ buildOrUpdateElements: function() {
+ var me = this;
+ var dataset = me.getDataset();
+ var data = dataset.data || (dataset.data = []);
+
+ // In order to correctly handle data addition/deletion animation (an thus simulate
+ // real-time charts), we need to monitor these data modifications and synchronize
+ // the internal meta data accordingly.
+ if (me._data !== data) {
+ if (me._data) {
+ // This case happens when the user replaced the data array instance.
+ unlistenArrayEvents(me._data, me);
+ }
+
+ if (data && Object.isExtensible(data)) {
+ listenArrayEvents(data, me);
+ }
+ me._data = data;
+ }
+
+ // Re-sync meta data in case the user replaced the data array or if we missed
+ // any updates and so make sure that we handle number of datapoints changing.
+ me.resyncElements();
+ },
+
+ /**
+ * Returns the merged user-supplied and default dataset-level options
+ * @private
+ */
+ _configure: function() {
+ var me = this;
+ me._config = helpers$1.merge({}, [
+ me.chart.options.datasets[me._type],
+ me.getDataset(),
+ ], {
+ merger: function(key, target, source) {
+ if (key !== '_meta' && key !== 'data') {
+ helpers$1._merger(key, target, source);
+ }
+ }
+ });
+ },
+
+ _update: function(reset) {
+ var me = this;
+ me._configure();
+ me._cachedDataOpts = null;
+ me.update(reset);
+ },
+
+ update: helpers$1.noop,
+
+ transition: function(easingValue) {
+ var meta = this.getMeta();
+ var elements = meta.data || [];
+ var ilen = elements.length;
+ var i = 0;
+
+ for (; i < ilen; ++i) {
+ elements[i].transition(easingValue);
+ }
+
+ if (meta.dataset) {
+ meta.dataset.transition(easingValue);
+ }
+ },
+
+ draw: function() {
+ var meta = this.getMeta();
+ var elements = meta.data || [];
+ var ilen = elements.length;
+ var i = 0;
+
+ if (meta.dataset) {
+ meta.dataset.draw();
+ }
+
+ for (; i < ilen; ++i) {
+ elements[i].draw();
+ }
+ },
+
+ /**
+ * Returns a set of predefined style properties that should be used to represent the dataset
+ * or the data if the index is specified
+ * @param {number} index - data index
+ * @return {IStyleInterface} style object
+ */
+ getStyle: function(index) {
+ var me = this;
+ var meta = me.getMeta();
+ var dataset = meta.dataset;
+ var style;
+
+ me._configure();
+ if (dataset && index === undefined) {
+ style = me._resolveDatasetElementOptions(dataset || {});
+ } else {
+ index = index || 0;
+ style = me._resolveDataElementOptions(meta.data[index] || {}, index);
+ }
+
+ if (style.fill === false || style.fill === null) {
+ style.backgroundColor = style.borderColor;
+ }
+
+ return style;
+ },
+
+ /**
+ * @private
+ */
+ _resolveDatasetElementOptions: function(element, hover) {
+ var me = this;
+ var chart = me.chart;
+ var datasetOpts = me._config;
+ var custom = element.custom || {};
+ var options = chart.options.elements[me.datasetElementType.prototype._type] || {};
+ var elementOptions = me._datasetElementOptions;
+ var values = {};
+ var i, ilen, key, readKey;
+
+ // Scriptable options
+ var context = {
+ chart: chart,
+ dataset: me.getDataset(),
+ datasetIndex: me.index,
+ hover: hover
+ };
+
+ for (i = 0, ilen = elementOptions.length; i < ilen; ++i) {
+ key = elementOptions[i];
+ readKey = hover ? 'hover' + key.charAt(0).toUpperCase() + key.slice(1) : key;
+ values[key] = resolve([
+ custom[readKey],
+ datasetOpts[readKey],
+ options[readKey]
+ ], context);
+ }
+
+ return values;
+ },
+
+ /**
+ * @private
+ */
+ _resolveDataElementOptions: function(element, index) {
+ var me = this;
+ var custom = element && element.custom;
+ var cached = me._cachedDataOpts;
+ if (cached && !custom) {
+ return cached;
+ }
+ var chart = me.chart;
+ var datasetOpts = me._config;
+ var options = chart.options.elements[me.dataElementType.prototype._type] || {};
+ var elementOptions = me._dataElementOptions;
+ var values = {};
+
+ // Scriptable options
+ var context = {
+ chart: chart,
+ dataIndex: index,
+ dataset: me.getDataset(),
+ datasetIndex: me.index
+ };
+
+ // `resolve` sets cacheable to `false` if any option is indexed or scripted
+ var info = {cacheable: !custom};
+
+ var keys, i, ilen, key;
+
+ custom = custom || {};
+
+ if (helpers$1.isArray(elementOptions)) {
+ for (i = 0, ilen = elementOptions.length; i < ilen; ++i) {
+ key = elementOptions[i];
+ values[key] = resolve([
+ custom[key],
+ datasetOpts[key],
+ options[key]
+ ], context, index, info);
+ }
+ } else {
+ keys = Object.keys(elementOptions);
+ for (i = 0, ilen = keys.length; i < ilen; ++i) {
+ key = keys[i];
+ values[key] = resolve([
+ custom[key],
+ datasetOpts[elementOptions[key]],
+ datasetOpts[key],
+ options[key]
+ ], context, index, info);
+ }
+ }
+
+ if (info.cacheable) {
+ me._cachedDataOpts = Object.freeze(values);
+ }
+
+ return values;
+ },
+
+ removeHoverStyle: function(element) {
+ helpers$1.merge(element._model, element.$previousStyle || {});
+ delete element.$previousStyle;
+ },
+
+ setHoverStyle: function(element) {
+ var dataset = this.chart.data.datasets[element._datasetIndex];
+ var index = element._index;
+ var custom = element.custom || {};
+ var model = element._model;
+ var getHoverColor = helpers$1.getHoverColor;
+
+ element.$previousStyle = {
+ backgroundColor: model.backgroundColor,
+ borderColor: model.borderColor,
+ borderWidth: model.borderWidth
+ };
+
+ model.backgroundColor = resolve([custom.hoverBackgroundColor, dataset.hoverBackgroundColor, getHoverColor(model.backgroundColor)], undefined, index);
+ model.borderColor = resolve([custom.hoverBorderColor, dataset.hoverBorderColor, getHoverColor(model.borderColor)], undefined, index);
+ model.borderWidth = resolve([custom.hoverBorderWidth, dataset.hoverBorderWidth, model.borderWidth], undefined, index);
+ },
+
+ /**
+ * @private
+ */
+ _removeDatasetHoverStyle: function() {
+ var element = this.getMeta().dataset;
+
+ if (element) {
+ this.removeHoverStyle(element);
+ }
+ },
+
+ /**
+ * @private
+ */
+ _setDatasetHoverStyle: function() {
+ var element = this.getMeta().dataset;
+ var prev = {};
+ var i, ilen, key, keys, hoverOptions, model;
+
+ if (!element) {
+ return;
+ }
+
+ model = element._model;
+ hoverOptions = this._resolveDatasetElementOptions(element, true);
+
+ keys = Object.keys(hoverOptions);
+ for (i = 0, ilen = keys.length; i < ilen; ++i) {
+ key = keys[i];
+ prev[key] = model[key];
+ model[key] = hoverOptions[key];
+ }
+
+ element.$previousStyle = prev;
+ },
+
+ /**
+ * @private
+ */
+ resyncElements: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var data = me.getDataset().data;
+ var numMeta = meta.data.length;
+ var numData = data.length;
+
+ if (numData < numMeta) {
+ meta.data.splice(numData, numMeta - numData);
+ } else if (numData > numMeta) {
+ me.insertElements(numMeta, numData - numMeta);
+ }
+ },
+
+ /**
+ * @private
+ */
+ insertElements: function(start, count) {
+ for (var i = 0; i < count; ++i) {
+ this.addElementAndReset(start + i);
+ }
+ },
+
+ /**
+ * @private
+ */
+ onDataPush: function() {
+ var count = arguments.length;
+ this.insertElements(this.getDataset().data.length - count, count);
+ },
+
+ /**
+ * @private
+ */
+ onDataPop: function() {
+ this.getMeta().data.pop();
+ },
+
+ /**
+ * @private
+ */
+ onDataShift: function() {
+ this.getMeta().data.shift();
+ },
+
+ /**
+ * @private
+ */
+ onDataSplice: function(start, count) {
+ this.getMeta().data.splice(start, count);
+ this.insertElements(start, arguments.length - 2);
+ },
+
+ /**
+ * @private
+ */
+ onDataUnshift: function() {
+ this.insertElements(0, arguments.length);
+ }
+});
+
+DatasetController.extend = helpers$1.inherits;
+
+var core_datasetController = DatasetController;
+
+var TAU = Math.PI * 2;
+
+core_defaults._set('global', {
+ elements: {
+ arc: {
+ backgroundColor: core_defaults.global.defaultColor,
+ borderColor: '#fff',
+ borderWidth: 2,
+ borderAlign: 'center'
+ }
+ }
+});
+
+function clipArc(ctx, arc) {
+ var startAngle = arc.startAngle;
+ var endAngle = arc.endAngle;
+ var pixelMargin = arc.pixelMargin;
+ var angleMargin = pixelMargin / arc.outerRadius;
+ var x = arc.x;
+ var y = arc.y;
+
+ // Draw an inner border by cliping the arc and drawing a double-width border
+ // Enlarge the clipping arc by 0.33 pixels to eliminate glitches between borders
+ ctx.beginPath();
+ ctx.arc(x, y, arc.outerRadius, startAngle - angleMargin, endAngle + angleMargin);
+ if (arc.innerRadius > pixelMargin) {
+ angleMargin = pixelMargin / arc.innerRadius;
+ ctx.arc(x, y, arc.innerRadius - pixelMargin, endAngle + angleMargin, startAngle - angleMargin, true);
+ } else {
+ ctx.arc(x, y, pixelMargin, endAngle + Math.PI / 2, startAngle - Math.PI / 2);
+ }
+ ctx.closePath();
+ ctx.clip();
+}
+
+function drawFullCircleBorders(ctx, vm, arc, inner) {
+ var endAngle = arc.endAngle;
+ var i;
+
+ if (inner) {
+ arc.endAngle = arc.startAngle + TAU;
+ clipArc(ctx, arc);
+ arc.endAngle = endAngle;
+ if (arc.endAngle === arc.startAngle && arc.fullCircles) {
+ arc.endAngle += TAU;
+ arc.fullCircles--;
+ }
+ }
+
+ ctx.beginPath();
+ ctx.arc(arc.x, arc.y, arc.innerRadius, arc.startAngle + TAU, arc.startAngle, true);
+ for (i = 0; i < arc.fullCircles; ++i) {
+ ctx.stroke();
+ }
+
+ ctx.beginPath();
+ ctx.arc(arc.x, arc.y, vm.outerRadius, arc.startAngle, arc.startAngle + TAU);
+ for (i = 0; i < arc.fullCircles; ++i) {
+ ctx.stroke();
+ }
+}
+
+function drawBorder(ctx, vm, arc) {
+ var inner = vm.borderAlign === 'inner';
+
+ if (inner) {
+ ctx.lineWidth = vm.borderWidth * 2;
+ ctx.lineJoin = 'round';
+ } else {
+ ctx.lineWidth = vm.borderWidth;
+ ctx.lineJoin = 'bevel';
+ }
+
+ if (arc.fullCircles) {
+ drawFullCircleBorders(ctx, vm, arc, inner);
+ }
+
+ if (inner) {
+ clipArc(ctx, arc);
+ }
+
+ ctx.beginPath();
+ ctx.arc(arc.x, arc.y, vm.outerRadius, arc.startAngle, arc.endAngle);
+ ctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true);
+ ctx.closePath();
+ ctx.stroke();
+}
+
+var element_arc = core_element.extend({
+ _type: 'arc',
+
+ inLabelRange: function(mouseX) {
+ var vm = this._view;
+
+ if (vm) {
+ return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));
+ }
+ return false;
+ },
+
+ inRange: function(chartX, chartY) {
+ var vm = this._view;
+
+ if (vm) {
+ var pointRelativePosition = helpers$1.getAngleFromPoint(vm, {x: chartX, y: chartY});
+ var angle = pointRelativePosition.angle;
+ var distance = pointRelativePosition.distance;
+
+ // Sanitise angle range
+ var startAngle = vm.startAngle;
+ var endAngle = vm.endAngle;
+ while (endAngle < startAngle) {
+ endAngle += TAU;
+ }
+ while (angle > endAngle) {
+ angle -= TAU;
+ }
+ while (angle < startAngle) {
+ angle += TAU;
+ }
+
+ // Check if within the range of the open/close angle
+ var betweenAngles = (angle >= startAngle && angle <= endAngle);
+ var withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);
+
+ return (betweenAngles && withinRadius);
+ }
+ return false;
+ },
+
+ getCenterPoint: function() {
+ var vm = this._view;
+ var halfAngle = (vm.startAngle + vm.endAngle) / 2;
+ var halfRadius = (vm.innerRadius + vm.outerRadius) / 2;
+ return {
+ x: vm.x + Math.cos(halfAngle) * halfRadius,
+ y: vm.y + Math.sin(halfAngle) * halfRadius
+ };
+ },
+
+ getArea: function() {
+ var vm = this._view;
+ return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2));
+ },
+
+ tooltipPosition: function() {
+ var vm = this._view;
+ var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2);
+ var rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;
+
+ return {
+ x: vm.x + (Math.cos(centreAngle) * rangeFromCentre),
+ y: vm.y + (Math.sin(centreAngle) * rangeFromCentre)
+ };
+ },
+
+ draw: function() {
+ var ctx = this._chart.ctx;
+ var vm = this._view;
+ var pixelMargin = (vm.borderAlign === 'inner') ? 0.33 : 0;
+ var arc = {
+ x: vm.x,
+ y: vm.y,
+ innerRadius: vm.innerRadius,
+ outerRadius: Math.max(vm.outerRadius - pixelMargin, 0),
+ pixelMargin: pixelMargin,
+ startAngle: vm.startAngle,
+ endAngle: vm.endAngle,
+ fullCircles: Math.floor(vm.circumference / TAU)
+ };
+ var i;
+
+ ctx.save();
+
+ ctx.fillStyle = vm.backgroundColor;
+ ctx.strokeStyle = vm.borderColor;
+
+ if (arc.fullCircles) {
+ arc.endAngle = arc.startAngle + TAU;
+ ctx.beginPath();
+ ctx.arc(arc.x, arc.y, arc.outerRadius, arc.startAngle, arc.endAngle);
+ ctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true);
+ ctx.closePath();
+ for (i = 0; i < arc.fullCircles; ++i) {
+ ctx.fill();
+ }
+ arc.endAngle = arc.startAngle + vm.circumference % TAU;
+ }
+
+ ctx.beginPath();
+ ctx.arc(arc.x, arc.y, arc.outerRadius, arc.startAngle, arc.endAngle);
+ ctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true);
+ ctx.closePath();
+ ctx.fill();
+
+ if (vm.borderWidth) {
+ drawBorder(ctx, vm, arc);
+ }
+
+ ctx.restore();
+ }
+});
+
+var valueOrDefault$1 = helpers$1.valueOrDefault;
+
+var defaultColor = core_defaults.global.defaultColor;
+
+core_defaults._set('global', {
+ elements: {
+ line: {
+ tension: 0.4,
+ backgroundColor: defaultColor,
+ borderWidth: 3,
+ borderColor: defaultColor,
+ borderCapStyle: 'butt',
+ borderDash: [],
+ borderDashOffset: 0.0,
+ borderJoinStyle: 'miter',
+ capBezierPoints: true,
+ fill: true, // do we fill in the area between the line and its base axis
+ }
+ }
+});
+
+var element_line = core_element.extend({
+ _type: 'line',
+
+ draw: function() {
+ var me = this;
+ var vm = me._view;
+ var ctx = me._chart.ctx;
+ var spanGaps = vm.spanGaps;
+ var points = me._children.slice(); // clone array
+ var globalDefaults = core_defaults.global;
+ var globalOptionLineElements = globalDefaults.elements.line;
+ var lastDrawnIndex = -1;
+ var closePath = me._loop;
+ var index, previous, currentVM;
+
+ if (!points.length) {
+ return;
+ }
+
+ if (me._loop) {
+ for (index = 0; index < points.length; ++index) {
+ previous = helpers$1.previousItem(points, index);
+ // If the line has an open path, shift the point array
+ if (!points[index]._view.skip && previous._view.skip) {
+ points = points.slice(index).concat(points.slice(0, index));
+ closePath = spanGaps;
+ break;
+ }
+ }
+ // If the line has a close path, add the first point again
+ if (closePath) {
+ points.push(points[0]);
+ }
+ }
+
+ ctx.save();
+
+ // Stroke Line Options
+ ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;
+
+ // IE 9 and 10 do not support line dash
+ if (ctx.setLineDash) {
+ ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);
+ }
+
+ ctx.lineDashOffset = valueOrDefault$1(vm.borderDashOffset, globalOptionLineElements.borderDashOffset);
+ ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;
+ ctx.lineWidth = valueOrDefault$1(vm.borderWidth, globalOptionLineElements.borderWidth);
+ ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;
+
+ // Stroke Line
+ ctx.beginPath();
+
+ // First point moves to it's starting position no matter what
+ currentVM = points[0]._view;
+ if (!currentVM.skip) {
+ ctx.moveTo(currentVM.x, currentVM.y);
+ lastDrawnIndex = 0;
+ }
+
+ for (index = 1; index < points.length; ++index) {
+ currentVM = points[index]._view;
+ previous = lastDrawnIndex === -1 ? helpers$1.previousItem(points, index) : points[lastDrawnIndex];
+
+ if (!currentVM.skip) {
+ if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {
+ // There was a gap and this is the first point after the gap
+ ctx.moveTo(currentVM.x, currentVM.y);
+ } else {
+ // Line to next point
+ helpers$1.canvas.lineTo(ctx, previous._view, currentVM);
+ }
+ lastDrawnIndex = index;
+ }
+ }
+
+ if (closePath) {
+ ctx.closePath();
+ }
+
+ ctx.stroke();
+ ctx.restore();
+ }
+});
+
+var valueOrDefault$2 = helpers$1.valueOrDefault;
+
+var defaultColor$1 = core_defaults.global.defaultColor;
+
+core_defaults._set('global', {
+ elements: {
+ point: {
+ radius: 3,
+ pointStyle: 'circle',
+ backgroundColor: defaultColor$1,
+ borderColor: defaultColor$1,
+ borderWidth: 1,
+ // Hover
+ hitRadius: 1,
+ hoverRadius: 4,
+ hoverBorderWidth: 1
+ }
+ }
+});
+
+function xRange(mouseX) {
+ var vm = this._view;
+ return vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false;
+}
+
+function yRange(mouseY) {
+ var vm = this._view;
+ return vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false;
+}
+
+var element_point = core_element.extend({
+ _type: 'point',
+
+ inRange: function(mouseX, mouseY) {
+ var vm = this._view;
+ return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;
+ },
+
+ inLabelRange: xRange,
+ inXRange: xRange,
+ inYRange: yRange,
+
+ getCenterPoint: function() {
+ var vm = this._view;
+ return {
+ x: vm.x,
+ y: vm.y
+ };
+ },
+
+ getArea: function() {
+ return Math.PI * Math.pow(this._view.radius, 2);
+ },
+
+ tooltipPosition: function() {
+ var vm = this._view;
+ return {
+ x: vm.x,
+ y: vm.y,
+ padding: vm.radius + vm.borderWidth
+ };
+ },
+
+ draw: function(chartArea) {
+ var vm = this._view;
+ var ctx = this._chart.ctx;
+ var pointStyle = vm.pointStyle;
+ var rotation = vm.rotation;
+ var radius = vm.radius;
+ var x = vm.x;
+ var y = vm.y;
+ var globalDefaults = core_defaults.global;
+ var defaultColor = globalDefaults.defaultColor; // eslint-disable-line no-shadow
+
+ if (vm.skip) {
+ return;
+ }
+
+ // Clipping for Points.
+ if (chartArea === undefined || helpers$1.canvas._isPointInArea(vm, chartArea)) {
+ ctx.strokeStyle = vm.borderColor || defaultColor;
+ ctx.lineWidth = valueOrDefault$2(vm.borderWidth, globalDefaults.elements.point.borderWidth);
+ ctx.fillStyle = vm.backgroundColor || defaultColor;
+ helpers$1.canvas.drawPoint(ctx, pointStyle, radius, x, y, rotation);
+ }
+ }
+});
+
+var defaultColor$2 = core_defaults.global.defaultColor;
+
+core_defaults._set('global', {
+ elements: {
+ rectangle: {
+ backgroundColor: defaultColor$2,
+ borderColor: defaultColor$2,
+ borderSkipped: 'bottom',
+ borderWidth: 0
+ }
+ }
+});
+
+function isVertical(vm) {
+ return vm && vm.width !== undefined;
+}
+
+/**
+ * Helper function to get the bounds of the bar regardless of the orientation
+ * @param bar {Chart.Element.Rectangle} the bar
+ * @return {Bounds} bounds of the bar
+ * @private
+ */
+function getBarBounds(vm) {
+ var x1, x2, y1, y2, half;
+
+ if (isVertical(vm)) {
+ half = vm.width / 2;
+ x1 = vm.x - half;
+ x2 = vm.x + half;
+ y1 = Math.min(vm.y, vm.base);
+ y2 = Math.max(vm.y, vm.base);
+ } else {
+ half = vm.height / 2;
+ x1 = Math.min(vm.x, vm.base);
+ x2 = Math.max(vm.x, vm.base);
+ y1 = vm.y - half;
+ y2 = vm.y + half;
+ }
+
+ return {
+ left: x1,
+ top: y1,
+ right: x2,
+ bottom: y2
+ };
+}
+
+function swap(orig, v1, v2) {
+ return orig === v1 ? v2 : orig === v2 ? v1 : orig;
+}
+
+function parseBorderSkipped(vm) {
+ var edge = vm.borderSkipped;
+ var res = {};
+
+ if (!edge) {
+ return res;
+ }
+
+ if (vm.horizontal) {
+ if (vm.base > vm.x) {
+ edge = swap(edge, 'left', 'right');
+ }
+ } else if (vm.base < vm.y) {
+ edge = swap(edge, 'bottom', 'top');
+ }
+
+ res[edge] = true;
+ return res;
+}
+
+function parseBorderWidth(vm, maxW, maxH) {
+ var value = vm.borderWidth;
+ var skip = parseBorderSkipped(vm);
+ var t, r, b, l;
+
+ if (helpers$1.isObject(value)) {
+ t = +value.top || 0;
+ r = +value.right || 0;
+ b = +value.bottom || 0;
+ l = +value.left || 0;
+ } else {
+ t = r = b = l = +value || 0;
+ }
+
+ return {
+ t: skip.top || (t < 0) ? 0 : t > maxH ? maxH : t,
+ r: skip.right || (r < 0) ? 0 : r > maxW ? maxW : r,
+ b: skip.bottom || (b < 0) ? 0 : b > maxH ? maxH : b,
+ l: skip.left || (l < 0) ? 0 : l > maxW ? maxW : l
+ };
+}
+
+function boundingRects(vm) {
+ var bounds = getBarBounds(vm);
+ var width = bounds.right - bounds.left;
+ var height = bounds.bottom - bounds.top;
+ var border = parseBorderWidth(vm, width / 2, height / 2);
+
+ return {
+ outer: {
+ x: bounds.left,
+ y: bounds.top,
+ w: width,
+ h: height
+ },
+ inner: {
+ x: bounds.left + border.l,
+ y: bounds.top + border.t,
+ w: width - border.l - border.r,
+ h: height - border.t - border.b
+ }
+ };
+}
+
+function inRange(vm, x, y) {
+ var skipX = x === null;
+ var skipY = y === null;
+ var bounds = !vm || (skipX && skipY) ? false : getBarBounds(vm);
+
+ return bounds
+ && (skipX || x >= bounds.left && x <= bounds.right)
+ && (skipY || y >= bounds.top && y <= bounds.bottom);
+}
+
+var element_rectangle = core_element.extend({
+ _type: 'rectangle',
+
+ draw: function() {
+ var ctx = this._chart.ctx;
+ var vm = this._view;
+ var rects = boundingRects(vm);
+ var outer = rects.outer;
+ var inner = rects.inner;
+
+ ctx.fillStyle = vm.backgroundColor;
+ ctx.fillRect(outer.x, outer.y, outer.w, outer.h);
+
+ if (outer.w === inner.w && outer.h === inner.h) {
+ return;
+ }
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(outer.x, outer.y, outer.w, outer.h);
+ ctx.clip();
+ ctx.fillStyle = vm.borderColor;
+ ctx.rect(inner.x, inner.y, inner.w, inner.h);
+ ctx.fill('evenodd');
+ ctx.restore();
+ },
+
+ height: function() {
+ var vm = this._view;
+ return vm.base - vm.y;
+ },
+
+ inRange: function(mouseX, mouseY) {
+ return inRange(this._view, mouseX, mouseY);
+ },
+
+ inLabelRange: function(mouseX, mouseY) {
+ var vm = this._view;
+ return isVertical(vm)
+ ? inRange(vm, mouseX, null)
+ : inRange(vm, null, mouseY);
+ },
+
+ inXRange: function(mouseX) {
+ return inRange(this._view, mouseX, null);
+ },
+
+ inYRange: function(mouseY) {
+ return inRange(this._view, null, mouseY);
+ },
+
+ getCenterPoint: function() {
+ var vm = this._view;
+ var x, y;
+ if (isVertical(vm)) {
+ x = vm.x;
+ y = (vm.y + vm.base) / 2;
+ } else {
+ x = (vm.x + vm.base) / 2;
+ y = vm.y;
+ }
+
+ return {x: x, y: y};
+ },
+
+ getArea: function() {
+ var vm = this._view;
+
+ return isVertical(vm)
+ ? vm.width * Math.abs(vm.y - vm.base)
+ : vm.height * Math.abs(vm.x - vm.base);
+ },
+
+ tooltipPosition: function() {
+ var vm = this._view;
+ return {
+ x: vm.x,
+ y: vm.y
+ };
+ }
+});
+
+var elements = {};
+var Arc = element_arc;
+var Line = element_line;
+var Point = element_point;
+var Rectangle = element_rectangle;
+elements.Arc = Arc;
+elements.Line = Line;
+elements.Point = Point;
+elements.Rectangle = Rectangle;
+
+var deprecated = helpers$1._deprecated;
+var valueOrDefault$3 = helpers$1.valueOrDefault;
+
+core_defaults._set('bar', {
+ hover: {
+ mode: 'label'
+ },
+
+ scales: {
+ xAxes: [{
+ type: 'category',
+ offset: true,
+ gridLines: {
+ offsetGridLines: true
+ }
+ }],
+
+ yAxes: [{
+ type: 'linear'
+ }]
+ }
+});
+
+core_defaults._set('global', {
+ datasets: {
+ bar: {
+ categoryPercentage: 0.8,
+ barPercentage: 0.9
+ }
+ }
+});
+
+/**
+ * Computes the "optimal" sample size to maintain bars equally sized while preventing overlap.
+ * @private
+ */
+function computeMinSampleSize(scale, pixels) {
+ var min = scale._length;
+ var prev, curr, i, ilen;
+
+ for (i = 1, ilen = pixels.length; i < ilen; ++i) {
+ min = Math.min(min, Math.abs(pixels[i] - pixels[i - 1]));
+ }
+
+ for (i = 0, ilen = scale.getTicks().length; i < ilen; ++i) {
+ curr = scale.getPixelForTick(i);
+ min = i > 0 ? Math.min(min, Math.abs(curr - prev)) : min;
+ prev = curr;
+ }
+
+ return min;
+}
+
+/**
+ * Computes an "ideal" category based on the absolute bar thickness or, if undefined or null,
+ * uses the smallest interval (see computeMinSampleSize) that prevents bar overlapping. This
+ * mode currently always generates bars equally sized (until we introduce scriptable options?).
+ * @private
+ */
+function computeFitCategoryTraits(index, ruler, options) {
+ var thickness = options.barThickness;
+ var count = ruler.stackCount;
+ var curr = ruler.pixels[index];
+ var min = helpers$1.isNullOrUndef(thickness)
+ ? computeMinSampleSize(ruler.scale, ruler.pixels)
+ : -1;
+ var size, ratio;
+
+ if (helpers$1.isNullOrUndef(thickness)) {
+ size = min * options.categoryPercentage;
+ ratio = options.barPercentage;
+ } else {
+ // When bar thickness is enforced, category and bar percentages are ignored.
+ // Note(SB): we could add support for relative bar thickness (e.g. barThickness: '50%')
+ // and deprecate barPercentage since this value is ignored when thickness is absolute.
+ size = thickness * count;
+ ratio = 1;
+ }
+
+ return {
+ chunk: size / count,
+ ratio: ratio,
+ start: curr - (size / 2)
+ };
+}
+
+/**
+ * Computes an "optimal" category that globally arranges bars side by side (no gap when
+ * percentage options are 1), based on the previous and following categories. This mode
+ * generates bars with different widths when data are not evenly spaced.
+ * @private
+ */
+function computeFlexCategoryTraits(index, ruler, options) {
+ var pixels = ruler.pixels;
+ var curr = pixels[index];
+ var prev = index > 0 ? pixels[index - 1] : null;
+ var next = index < pixels.length - 1 ? pixels[index + 1] : null;
+ var percent = options.categoryPercentage;
+ var start, size;
+
+ if (prev === null) {
+ // first data: its size is double based on the next point or,
+ // if it's also the last data, we use the scale size.
+ prev = curr - (next === null ? ruler.end - ruler.start : next - curr);
+ }
+
+ if (next === null) {
+ // last data: its size is also double based on the previous point.
+ next = curr + curr - prev;
+ }
+
+ start = curr - (curr - Math.min(prev, next)) / 2 * percent;
+ size = Math.abs(next - prev) / 2 * percent;
+
+ return {
+ chunk: size / ruler.stackCount,
+ ratio: options.barPercentage,
+ start: start
+ };
+}
+
+var controller_bar = core_datasetController.extend({
+
+ dataElementType: elements.Rectangle,
+
+ /**
+ * @private
+ */
+ _dataElementOptions: [
+ 'backgroundColor',
+ 'borderColor',
+ 'borderSkipped',
+ 'borderWidth',
+ 'barPercentage',
+ 'barThickness',
+ 'categoryPercentage',
+ 'maxBarThickness',
+ 'minBarLength'
+ ],
+
+ initialize: function() {
+ var me = this;
+ var meta, scaleOpts;
+
+ core_datasetController.prototype.initialize.apply(me, arguments);
+
+ meta = me.getMeta();
+ meta.stack = me.getDataset().stack;
+ meta.bar = true;
+
+ scaleOpts = me._getIndexScale().options;
+ deprecated('bar chart', scaleOpts.barPercentage, 'scales.[x/y]Axes.barPercentage', 'dataset.barPercentage');
+ deprecated('bar chart', scaleOpts.barThickness, 'scales.[x/y]Axes.barThickness', 'dataset.barThickness');
+ deprecated('bar chart', scaleOpts.categoryPercentage, 'scales.[x/y]Axes.categoryPercentage', 'dataset.categoryPercentage');
+ deprecated('bar chart', me._getValueScale().options.minBarLength, 'scales.[x/y]Axes.minBarLength', 'dataset.minBarLength');
+ deprecated('bar chart', scaleOpts.maxBarThickness, 'scales.[x/y]Axes.maxBarThickness', 'dataset.maxBarThickness');
+ },
+
+ update: function(reset) {
+ var me = this;
+ var rects = me.getMeta().data;
+ var i, ilen;
+
+ me._ruler = me.getRuler();
+
+ for (i = 0, ilen = rects.length; i < ilen; ++i) {
+ me.updateElement(rects[i], i, reset);
+ }
+ },
+
+ updateElement: function(rectangle, index, reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var dataset = me.getDataset();
+ var options = me._resolveDataElementOptions(rectangle, index);
+
+ rectangle._xScale = me.getScaleForId(meta.xAxisID);
+ rectangle._yScale = me.getScaleForId(meta.yAxisID);
+ rectangle._datasetIndex = me.index;
+ rectangle._index = index;
+ rectangle._model = {
+ backgroundColor: options.backgroundColor,
+ borderColor: options.borderColor,
+ borderSkipped: options.borderSkipped,
+ borderWidth: options.borderWidth,
+ datasetLabel: dataset.label,
+ label: me.chart.data.labels[index]
+ };
+
+ if (helpers$1.isArray(dataset.data[index])) {
+ rectangle._model.borderSkipped = null;
+ }
+
+ me._updateElementGeometry(rectangle, index, reset, options);
+
+ rectangle.pivot();
+ },
+
+ /**
+ * @private
+ */
+ _updateElementGeometry: function(rectangle, index, reset, options) {
+ var me = this;
+ var model = rectangle._model;
+ var vscale = me._getValueScale();
+ var base = vscale.getBasePixel();
+ var horizontal = vscale.isHorizontal();
+ var ruler = me._ruler || me.getRuler();
+ var vpixels = me.calculateBarValuePixels(me.index, index, options);
+ var ipixels = me.calculateBarIndexPixels(me.index, index, ruler, options);
+
+ model.horizontal = horizontal;
+ model.base = reset ? base : vpixels.base;
+ model.x = horizontal ? reset ? base : vpixels.head : ipixels.center;
+ model.y = horizontal ? ipixels.center : reset ? base : vpixels.head;
+ model.height = horizontal ? ipixels.size : undefined;
+ model.width = horizontal ? undefined : ipixels.size;
+ },
+
+ /**
+ * Returns the stacks based on groups and bar visibility.
+ * @param {number} [last] - The dataset index
+ * @returns {string[]} The list of stack IDs
+ * @private
+ */
+ _getStacks: function(last) {
+ var me = this;
+ var scale = me._getIndexScale();
+ var metasets = scale._getMatchingVisibleMetas(me._type);
+ var stacked = scale.options.stacked;
+ var ilen = metasets.length;
+ var stacks = [];
+ var i, meta;
+
+ for (i = 0; i < ilen; ++i) {
+ meta = metasets[i];
+ // stacked | meta.stack
+ // | found | not found | undefined
+ // false | x | x | x
+ // true | | x |
+ // undefined | | x | x
+ if (stacked === false || stacks.indexOf(meta.stack) === -1 ||
+ (stacked === undefined && meta.stack === undefined)) {
+ stacks.push(meta.stack);
+ }
+ if (meta.index === last) {
+ break;
+ }
+ }
+
+ return stacks;
+ },
+
+ /**
+ * Returns the effective number of stacks based on groups and bar visibility.
+ * @private
+ */
+ getStackCount: function() {
+ return this._getStacks().length;
+ },
+
+ /**
+ * Returns the stack index for the given dataset based on groups and bar visibility.
+ * @param {number} [datasetIndex] - The dataset index
+ * @param {string} [name] - The stack name to find
+ * @returns {number} The stack index
+ * @private
+ */
+ getStackIndex: function(datasetIndex, name) {
+ var stacks = this._getStacks(datasetIndex);
+ var index = (name !== undefined)
+ ? stacks.indexOf(name)
+ : -1; // indexOf returns -1 if element is not present
+
+ return (index === -1)
+ ? stacks.length - 1
+ : index;
+ },
+
+ /**
+ * @private
+ */
+ getRuler: function() {
+ var me = this;
+ var scale = me._getIndexScale();
+ var pixels = [];
+ var i, ilen;
+
+ for (i = 0, ilen = me.getMeta().data.length; i < ilen; ++i) {
+ pixels.push(scale.getPixelForValue(null, i, me.index));
+ }
+
+ return {
+ pixels: pixels,
+ start: scale._startPixel,
+ end: scale._endPixel,
+ stackCount: me.getStackCount(),
+ scale: scale
+ };
+ },
+
+ /**
+ * Note: pixel values are not clamped to the scale area.
+ * @private
+ */
+ calculateBarValuePixels: function(datasetIndex, index, options) {
+ var me = this;
+ var chart = me.chart;
+ var scale = me._getValueScale();
+ var isHorizontal = scale.isHorizontal();
+ var datasets = chart.data.datasets;
+ var metasets = scale._getMatchingVisibleMetas(me._type);
+ var value = scale._parseValue(datasets[datasetIndex].data[index]);
+ var minBarLength = options.minBarLength;
+ var stacked = scale.options.stacked;
+ var stack = me.getMeta().stack;
+ var start = value.start === undefined ? 0 : value.max >= 0 && value.min >= 0 ? value.min : value.max;
+ var length = value.start === undefined ? value.end : value.max >= 0 && value.min >= 0 ? value.max - value.min : value.min - value.max;
+ var ilen = metasets.length;
+ var i, imeta, ivalue, base, head, size, stackLength;
+
+ if (stacked || (stacked === undefined && stack !== undefined)) {
+ for (i = 0; i < ilen; ++i) {
+ imeta = metasets[i];
+
+ if (imeta.index === datasetIndex) {
+ break;
+ }
+
+ if (imeta.stack === stack) {
+ stackLength = scale._parseValue(datasets[imeta.index].data[index]);
+ ivalue = stackLength.start === undefined ? stackLength.end : stackLength.min >= 0 && stackLength.max >= 0 ? stackLength.max : stackLength.min;
+
+ if ((value.min < 0 && ivalue < 0) || (value.max >= 0 && ivalue > 0)) {
+ start += ivalue;
+ }
+ }
+ }
+ }
+
+ base = scale.getPixelForValue(start);
+ head = scale.getPixelForValue(start + length);
+ size = head - base;
+
+ if (minBarLength !== undefined && Math.abs(size) < minBarLength) {
+ size = minBarLength;
+ if (length >= 0 && !isHorizontal || length < 0 && isHorizontal) {
+ head = base - minBarLength;
+ } else {
+ head = base + minBarLength;
+ }
+ }
+
+ return {
+ size: size,
+ base: base,
+ head: head,
+ center: head + size / 2
+ };
+ },
+
+ /**
+ * @private
+ */
+ calculateBarIndexPixels: function(datasetIndex, index, ruler, options) {
+ var me = this;
+ var range = options.barThickness === 'flex'
+ ? computeFlexCategoryTraits(index, ruler, options)
+ : computeFitCategoryTraits(index, ruler, options);
+
+ var stackIndex = me.getStackIndex(datasetIndex, me.getMeta().stack);
+ var center = range.start + (range.chunk * stackIndex) + (range.chunk / 2);
+ var size = Math.min(
+ valueOrDefault$3(options.maxBarThickness, Infinity),
+ range.chunk * range.ratio);
+
+ return {
+ base: center - size / 2,
+ head: center + size / 2,
+ center: center,
+ size: size
+ };
+ },
+
+ draw: function() {
+ var me = this;
+ var chart = me.chart;
+ var scale = me._getValueScale();
+ var rects = me.getMeta().data;
+ var dataset = me.getDataset();
+ var ilen = rects.length;
+ var i = 0;
+
+ helpers$1.canvas.clipArea(chart.ctx, chart.chartArea);
+
+ for (; i < ilen; ++i) {
+ var val = scale._parseValue(dataset.data[i]);
+ if (!isNaN(val.min) && !isNaN(val.max)) {
+ rects[i].draw();
+ }
+ }
+
+ helpers$1.canvas.unclipArea(chart.ctx);
+ },
+
+ /**
+ * @private
+ */
+ _resolveDataElementOptions: function() {
+ var me = this;
+ var values = helpers$1.extend({}, core_datasetController.prototype._resolveDataElementOptions.apply(me, arguments));
+ var indexOpts = me._getIndexScale().options;
+ var valueOpts = me._getValueScale().options;
+
+ values.barPercentage = valueOrDefault$3(indexOpts.barPercentage, values.barPercentage);
+ values.barThickness = valueOrDefault$3(indexOpts.barThickness, values.barThickness);
+ values.categoryPercentage = valueOrDefault$3(indexOpts.categoryPercentage, values.categoryPercentage);
+ values.maxBarThickness = valueOrDefault$3(indexOpts.maxBarThickness, values.maxBarThickness);
+ values.minBarLength = valueOrDefault$3(valueOpts.minBarLength, values.minBarLength);
+
+ return values;
+ }
+
+});
+
+var valueOrDefault$4 = helpers$1.valueOrDefault;
+var resolve$1 = helpers$1.options.resolve;
+
+core_defaults._set('bubble', {
+ hover: {
+ mode: 'single'
+ },
+
+ scales: {
+ xAxes: [{
+ type: 'linear', // bubble should probably use a linear scale by default
+ position: 'bottom',
+ id: 'x-axis-0' // need an ID so datasets can reference the scale
+ }],
+ yAxes: [{
+ type: 'linear',
+ position: 'left',
+ id: 'y-axis-0'
+ }]
+ },
+
+ tooltips: {
+ callbacks: {
+ title: function() {
+ // Title doesn't make sense for scatter since we format the data as a point
+ return '';
+ },
+ label: function(item, data) {
+ var datasetLabel = data.datasets[item.datasetIndex].label || '';
+ var dataPoint = data.datasets[item.datasetIndex].data[item.index];
+ return datasetLabel + ': (' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.r + ')';
+ }
+ }
+ }
+});
+
+var controller_bubble = core_datasetController.extend({
+ /**
+ * @protected
+ */
+ dataElementType: elements.Point,
+
+ /**
+ * @private
+ */
+ _dataElementOptions: [
+ 'backgroundColor',
+ 'borderColor',
+ 'borderWidth',
+ 'hoverBackgroundColor',
+ 'hoverBorderColor',
+ 'hoverBorderWidth',
+ 'hoverRadius',
+ 'hitRadius',
+ 'pointStyle',
+ 'rotation'
+ ],
+
+ /**
+ * @protected
+ */
+ update: function(reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var points = meta.data;
+
+ // Update Points
+ helpers$1.each(points, function(point, index) {
+ me.updateElement(point, index, reset);
+ });
+ },
+
+ /**
+ * @protected
+ */
+ updateElement: function(point, index, reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var custom = point.custom || {};
+ var xScale = me.getScaleForId(meta.xAxisID);
+ var yScale = me.getScaleForId(meta.yAxisID);
+ var options = me._resolveDataElementOptions(point, index);
+ var data = me.getDataset().data[index];
+ var dsIndex = me.index;
+
+ var x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex);
+ var y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex);
+
+ point._xScale = xScale;
+ point._yScale = yScale;
+ point._options = options;
+ point._datasetIndex = dsIndex;
+ point._index = index;
+ point._model = {
+ backgroundColor: options.backgroundColor,
+ borderColor: options.borderColor,
+ borderWidth: options.borderWidth,
+ hitRadius: options.hitRadius,
+ pointStyle: options.pointStyle,
+ rotation: options.rotation,
+ radius: reset ? 0 : options.radius,
+ skip: custom.skip || isNaN(x) || isNaN(y),
+ x: x,
+ y: y,
+ };
+
+ point.pivot();
+ },
+
+ /**
+ * @protected
+ */
+ setHoverStyle: function(point) {
+ var model = point._model;
+ var options = point._options;
+ var getHoverColor = helpers$1.getHoverColor;
+
+ point.$previousStyle = {
+ backgroundColor: model.backgroundColor,
+ borderColor: model.borderColor,
+ borderWidth: model.borderWidth,
+ radius: model.radius
+ };
+
+ model.backgroundColor = valueOrDefault$4(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));
+ model.borderColor = valueOrDefault$4(options.hoverBorderColor, getHoverColor(options.borderColor));
+ model.borderWidth = valueOrDefault$4(options.hoverBorderWidth, options.borderWidth);
+ model.radius = options.radius + options.hoverRadius;
+ },
+
+ /**
+ * @private
+ */
+ _resolveDataElementOptions: function(point, index) {
+ var me = this;
+ var chart = me.chart;
+ var dataset = me.getDataset();
+ var custom = point.custom || {};
+ var data = dataset.data[index] || {};
+ var values = core_datasetController.prototype._resolveDataElementOptions.apply(me, arguments);
+
+ // Scriptable options
+ var context = {
+ chart: chart,
+ dataIndex: index,
+ dataset: dataset,
+ datasetIndex: me.index
+ };
+
+ // In case values were cached (and thus frozen), we need to clone the values
+ if (me._cachedDataOpts === values) {
+ values = helpers$1.extend({}, values);
+ }
+
+ // Custom radius resolution
+ values.radius = resolve$1([
+ custom.radius,
+ data.r,
+ me._config.radius,
+ chart.options.elements.point.radius
+ ], context, index);
+
+ return values;
+ }
+});
+
+var valueOrDefault$5 = helpers$1.valueOrDefault;
+
+var PI$1 = Math.PI;
+var DOUBLE_PI$1 = PI$1 * 2;
+var HALF_PI$1 = PI$1 / 2;
+
+core_defaults._set('doughnut', {
+ animation: {
+ // Boolean - Whether we animate the rotation of the Doughnut
+ animateRotate: true,
+ // Boolean - Whether we animate scaling the Doughnut from the centre
+ animateScale: false
+ },
+ hover: {
+ mode: 'single'
+ },
+ legendCallback: function(chart) {
+ var list = document.createElement('ul');
+ var data = chart.data;
+ var datasets = data.datasets;
+ var labels = data.labels;
+ var i, ilen, listItem, listItemSpan;
+
+ list.setAttribute('class', chart.id + '-legend');
+ if (datasets.length) {
+ for (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) {
+ listItem = list.appendChild(document.createElement('li'));
+ listItemSpan = listItem.appendChild(document.createElement('span'));
+ listItemSpan.style.backgroundColor = datasets[0].backgroundColor[i];
+ if (labels[i]) {
+ listItem.appendChild(document.createTextNode(labels[i]));
+ }
+ }
+ }
+
+ return list.outerHTML;
+ },
+ legend: {
+ labels: {
+ generateLabels: function(chart) {
+ var data = chart.data;
+ if (data.labels.length && data.datasets.length) {
+ return data.labels.map(function(label, i) {
+ var meta = chart.getDatasetMeta(0);
+ var style = meta.controller.getStyle(i);
+
+ return {
+ text: label,
+ fillStyle: style.backgroundColor,
+ strokeStyle: style.borderColor,
+ lineWidth: style.borderWidth,
+ hidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden,
+
+ // Extra data used for toggling the correct item
+ index: i
+ };
+ });
+ }
+ return [];
+ }
+ },
+
+ onClick: function(e, legendItem) {
+ var index = legendItem.index;
+ var chart = this.chart;
+ var i, ilen, meta;
+
+ for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
+ meta = chart.getDatasetMeta(i);
+ // toggle visibility of index if exists
+ if (meta.data[index]) {
+ meta.data[index].hidden = !meta.data[index].hidden;
+ }
+ }
+
+ chart.update();
+ }
+ },
+
+ // The percentage of the chart that we cut out of the middle.
+ cutoutPercentage: 50,
+
+ // The rotation of the chart, where the first data arc begins.
+ rotation: -HALF_PI$1,
+
+ // The total circumference of the chart.
+ circumference: DOUBLE_PI$1,
+
+ // Need to override these to give a nice default
+ tooltips: {
+ callbacks: {
+ title: function() {
+ return '';
+ },
+ label: function(tooltipItem, data) {
+ var dataLabel = data.labels[tooltipItem.index];
+ var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
+
+ if (helpers$1.isArray(dataLabel)) {
+ // show value on first line of multiline label
+ // need to clone because we are changing the value
+ dataLabel = dataLabel.slice();
+ dataLabel[0] += value;
+ } else {
+ dataLabel += value;
+ }
+
+ return dataLabel;
+ }
+ }
+ }
+});
+
+var controller_doughnut = core_datasetController.extend({
+
+ dataElementType: elements.Arc,
+
+ linkScales: helpers$1.noop,
+
+ /**
+ * @private
+ */
+ _dataElementOptions: [
+ 'backgroundColor',
+ 'borderColor',
+ 'borderWidth',
+ 'borderAlign',
+ 'hoverBackgroundColor',
+ 'hoverBorderColor',
+ 'hoverBorderWidth',
+ ],
+
+ // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly
+ getRingIndex: function(datasetIndex) {
+ var ringIndex = 0;
+
+ for (var j = 0; j < datasetIndex; ++j) {
+ if (this.chart.isDatasetVisible(j)) {
+ ++ringIndex;
+ }
+ }
+
+ return ringIndex;
+ },
+
+ update: function(reset) {
+ var me = this;
+ var chart = me.chart;
+ var chartArea = chart.chartArea;
+ var opts = chart.options;
+ var ratioX = 1;
+ var ratioY = 1;
+ var offsetX = 0;
+ var offsetY = 0;
+ var meta = me.getMeta();
+ var arcs = meta.data;
+ var cutout = opts.cutoutPercentage / 100 || 0;
+ var circumference = opts.circumference;
+ var chartWeight = me._getRingWeight(me.index);
+ var maxWidth, maxHeight, i, ilen;
+
+ // If the chart's circumference isn't a full circle, calculate size as a ratio of the width/height of the arc
+ if (circumference < DOUBLE_PI$1) {
+ var startAngle = opts.rotation % DOUBLE_PI$1;
+ startAngle += startAngle >= PI$1 ? -DOUBLE_PI$1 : startAngle < -PI$1 ? DOUBLE_PI$1 : 0;
+ var endAngle = startAngle + circumference;
+ var startX = Math.cos(startAngle);
+ var startY = Math.sin(startAngle);
+ var endX = Math.cos(endAngle);
+ var endY = Math.sin(endAngle);
+ var contains0 = (startAngle <= 0 && endAngle >= 0) || endAngle >= DOUBLE_PI$1;
+ var contains90 = (startAngle <= HALF_PI$1 && endAngle >= HALF_PI$1) || endAngle >= DOUBLE_PI$1 + HALF_PI$1;
+ var contains180 = startAngle === -PI$1 || endAngle >= PI$1;
+ var contains270 = (startAngle <= -HALF_PI$1 && endAngle >= -HALF_PI$1) || endAngle >= PI$1 + HALF_PI$1;
+ var minX = contains180 ? -1 : Math.min(startX, startX * cutout, endX, endX * cutout);
+ var minY = contains270 ? -1 : Math.min(startY, startY * cutout, endY, endY * cutout);
+ var maxX = contains0 ? 1 : Math.max(startX, startX * cutout, endX, endX * cutout);
+ var maxY = contains90 ? 1 : Math.max(startY, startY * cutout, endY, endY * cutout);
+ ratioX = (maxX - minX) / 2;
+ ratioY = (maxY - minY) / 2;
+ offsetX = -(maxX + minX) / 2;
+ offsetY = -(maxY + minY) / 2;
+ }
+
+ for (i = 0, ilen = arcs.length; i < ilen; ++i) {
+ arcs[i]._options = me._resolveDataElementOptions(arcs[i], i);
+ }
+
+ chart.borderWidth = me.getMaxBorderWidth();
+ maxWidth = (chartArea.right - chartArea.left - chart.borderWidth) / ratioX;
+ maxHeight = (chartArea.bottom - chartArea.top - chart.borderWidth) / ratioY;
+ chart.outerRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0);
+ chart.innerRadius = Math.max(chart.outerRadius * cutout, 0);
+ chart.radiusLength = (chart.outerRadius - chart.innerRadius) / (me._getVisibleDatasetWeightTotal() || 1);
+ chart.offsetX = offsetX * chart.outerRadius;
+ chart.offsetY = offsetY * chart.outerRadius;
+
+ meta.total = me.calculateTotal();
+
+ me.outerRadius = chart.outerRadius - chart.radiusLength * me._getRingWeightOffset(me.index);
+ me.innerRadius = Math.max(me.outerRadius - chart.radiusLength * chartWeight, 0);
+
+ for (i = 0, ilen = arcs.length; i < ilen; ++i) {
+ me.updateElement(arcs[i], i, reset);
+ }
+ },
+
+ updateElement: function(arc, index, reset) {
+ var me = this;
+ var chart = me.chart;
+ var chartArea = chart.chartArea;
+ var opts = chart.options;
+ var animationOpts = opts.animation;
+ var centerX = (chartArea.left + chartArea.right) / 2;
+ var centerY = (chartArea.top + chartArea.bottom) / 2;
+ var startAngle = opts.rotation; // non reset case handled later
+ var endAngle = opts.rotation; // non reset case handled later
+ var dataset = me.getDataset();
+ var circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / DOUBLE_PI$1);
+ var innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius;
+ var outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius;
+ var options = arc._options || {};
+
+ helpers$1.extend(arc, {
+ // Utility
+ _datasetIndex: me.index,
+ _index: index,
+
+ // Desired view properties
+ _model: {
+ backgroundColor: options.backgroundColor,
+ borderColor: options.borderColor,
+ borderWidth: options.borderWidth,
+ borderAlign: options.borderAlign,
+ x: centerX + chart.offsetX,
+ y: centerY + chart.offsetY,
+ startAngle: startAngle,
+ endAngle: endAngle,
+ circumference: circumference,
+ outerRadius: outerRadius,
+ innerRadius: innerRadius,
+ label: helpers$1.valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])
+ }
+ });
+
+ var model = arc._model;
+
+ // Set correct angles if not resetting
+ if (!reset || !animationOpts.animateRotate) {
+ if (index === 0) {
+ model.startAngle = opts.rotation;
+ } else {
+ model.startAngle = me.getMeta().data[index - 1]._model.endAngle;
+ }
+
+ model.endAngle = model.startAngle + model.circumference;
+ }
+
+ arc.pivot();
+ },
+
+ calculateTotal: function() {
+ var dataset = this.getDataset();
+ var meta = this.getMeta();
+ var total = 0;
+ var value;
+
+ helpers$1.each(meta.data, function(element, index) {
+ value = dataset.data[index];
+ if (!isNaN(value) && !element.hidden) {
+ total += Math.abs(value);
+ }
+ });
+
+ /* if (total === 0) {
+ total = NaN;
+ }*/
+
+ return total;
+ },
+
+ calculateCircumference: function(value) {
+ var total = this.getMeta().total;
+ if (total > 0 && !isNaN(value)) {
+ return DOUBLE_PI$1 * (Math.abs(value) / total);
+ }
+ return 0;
+ },
+
+ // gets the max border or hover width to properly scale pie charts
+ getMaxBorderWidth: function(arcs) {
+ var me = this;
+ var max = 0;
+ var chart = me.chart;
+ var i, ilen, meta, arc, controller, options, borderWidth, hoverWidth;
+
+ if (!arcs) {
+ // Find the outmost visible dataset
+ for (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) {
+ if (chart.isDatasetVisible(i)) {
+ meta = chart.getDatasetMeta(i);
+ arcs = meta.data;
+ if (i !== me.index) {
+ controller = meta.controller;
+ }
+ break;
+ }
+ }
+ }
+
+ if (!arcs) {
+ return 0;
+ }
+
+ for (i = 0, ilen = arcs.length; i < ilen; ++i) {
+ arc = arcs[i];
+ if (controller) {
+ controller._configure();
+ options = controller._resolveDataElementOptions(arc, i);
+ } else {
+ options = arc._options;
+ }
+ if (options.borderAlign !== 'inner') {
+ borderWidth = options.borderWidth;
+ hoverWidth = options.hoverBorderWidth;
+
+ max = borderWidth > max ? borderWidth : max;
+ max = hoverWidth > max ? hoverWidth : max;
+ }
+ }
+ return max;
+ },
+
+ /**
+ * @protected
+ */
+ setHoverStyle: function(arc) {
+ var model = arc._model;
+ var options = arc._options;
+ var getHoverColor = helpers$1.getHoverColor;
+
+ arc.$previousStyle = {
+ backgroundColor: model.backgroundColor,
+ borderColor: model.borderColor,
+ borderWidth: model.borderWidth,
+ };
+
+ model.backgroundColor = valueOrDefault$5(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));
+ model.borderColor = valueOrDefault$5(options.hoverBorderColor, getHoverColor(options.borderColor));
+ model.borderWidth = valueOrDefault$5(options.hoverBorderWidth, options.borderWidth);
+ },
+
+ /**
+ * Get radius length offset of the dataset in relation to the visible datasets weights. This allows determining the inner and outer radius correctly
+ * @private
+ */
+ _getRingWeightOffset: function(datasetIndex) {
+ var ringWeightOffset = 0;
+
+ for (var i = 0; i < datasetIndex; ++i) {
+ if (this.chart.isDatasetVisible(i)) {
+ ringWeightOffset += this._getRingWeight(i);
+ }
+ }
+
+ return ringWeightOffset;
+ },
+
+ /**
+ * @private
+ */
+ _getRingWeight: function(dataSetIndex) {
+ return Math.max(valueOrDefault$5(this.chart.data.datasets[dataSetIndex].weight, 1), 0);
+ },
+
+ /**
+ * Returns the sum of all visibile data set weights. This value can be 0.
+ * @private
+ */
+ _getVisibleDatasetWeightTotal: function() {
+ return this._getRingWeightOffset(this.chart.data.datasets.length);
+ }
+});
+
+core_defaults._set('horizontalBar', {
+ hover: {
+ mode: 'index',
+ axis: 'y'
+ },
+
+ scales: {
+ xAxes: [{
+ type: 'linear',
+ position: 'bottom'
+ }],
+
+ yAxes: [{
+ type: 'category',
+ position: 'left',
+ offset: true,
+ gridLines: {
+ offsetGridLines: true
+ }
+ }]
+ },
+
+ elements: {
+ rectangle: {
+ borderSkipped: 'left'
+ }
+ },
+
+ tooltips: {
+ mode: 'index',
+ axis: 'y'
+ }
+});
+
+core_defaults._set('global', {
+ datasets: {
+ horizontalBar: {
+ categoryPercentage: 0.8,
+ barPercentage: 0.9
+ }
+ }
+});
+
+var controller_horizontalBar = controller_bar.extend({
+ /**
+ * @private
+ */
+ _getValueScaleId: function() {
+ return this.getMeta().xAxisID;
+ },
+
+ /**
+ * @private
+ */
+ _getIndexScaleId: function() {
+ return this.getMeta().yAxisID;
+ }
+});
+
+var valueOrDefault$6 = helpers$1.valueOrDefault;
+var resolve$2 = helpers$1.options.resolve;
+var isPointInArea = helpers$1.canvas._isPointInArea;
+
+core_defaults._set('line', {
+ showLines: true,
+ spanGaps: false,
+
+ hover: {
+ mode: 'label'
+ },
+
+ scales: {
+ xAxes: [{
+ type: 'category',
+ id: 'x-axis-0'
+ }],
+ yAxes: [{
+ type: 'linear',
+ id: 'y-axis-0'
+ }]
+ }
+});
+
+function scaleClip(scale, halfBorderWidth) {
+ var tickOpts = scale && scale.options.ticks || {};
+ var reverse = tickOpts.reverse;
+ var min = tickOpts.min === undefined ? halfBorderWidth : 0;
+ var max = tickOpts.max === undefined ? halfBorderWidth : 0;
+ return {
+ start: reverse ? max : min,
+ end: reverse ? min : max
+ };
+}
+
+function defaultClip(xScale, yScale, borderWidth) {
+ var halfBorderWidth = borderWidth / 2;
+ var x = scaleClip(xScale, halfBorderWidth);
+ var y = scaleClip(yScale, halfBorderWidth);
+
+ return {
+ top: y.end,
+ right: x.end,
+ bottom: y.start,
+ left: x.start
+ };
+}
+
+function toClip(value) {
+ var t, r, b, l;
+
+ if (helpers$1.isObject(value)) {
+ t = value.top;
+ r = value.right;
+ b = value.bottom;
+ l = value.left;
+ } else {
+ t = r = b = l = value;
+ }
+
+ return {
+ top: t,
+ right: r,
+ bottom: b,
+ left: l
+ };
+}
+
+
+var controller_line = core_datasetController.extend({
+
+ datasetElementType: elements.Line,
+
+ dataElementType: elements.Point,
+
+ /**
+ * @private
+ */
+ _datasetElementOptions: [
+ 'backgroundColor',
+ 'borderCapStyle',
+ 'borderColor',
+ 'borderDash',
+ 'borderDashOffset',
+ 'borderJoinStyle',
+ 'borderWidth',
+ 'cubicInterpolationMode',
+ 'fill'
+ ],
+
+ /**
+ * @private
+ */
+ _dataElementOptions: {
+ backgroundColor: 'pointBackgroundColor',
+ borderColor: 'pointBorderColor',
+ borderWidth: 'pointBorderWidth',
+ hitRadius: 'pointHitRadius',
+ hoverBackgroundColor: 'pointHoverBackgroundColor',
+ hoverBorderColor: 'pointHoverBorderColor',
+ hoverBorderWidth: 'pointHoverBorderWidth',
+ hoverRadius: 'pointHoverRadius',
+ pointStyle: 'pointStyle',
+ radius: 'pointRadius',
+ rotation: 'pointRotation'
+ },
+
+ update: function(reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var line = meta.dataset;
+ var points = meta.data || [];
+ var options = me.chart.options;
+ var config = me._config;
+ var showLine = me._showLine = valueOrDefault$6(config.showLine, options.showLines);
+ var i, ilen;
+
+ me._xScale = me.getScaleForId(meta.xAxisID);
+ me._yScale = me.getScaleForId(meta.yAxisID);
+
+ // Update Line
+ if (showLine) {
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if (config.tension !== undefined && config.lineTension === undefined) {
+ config.lineTension = config.tension;
+ }
+
+ // Utility
+ line._scale = me._yScale;
+ line._datasetIndex = me.index;
+ // Data
+ line._children = points;
+ // Model
+ line._model = me._resolveDatasetElementOptions(line);
+
+ line.pivot();
+ }
+
+ // Update Points
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ me.updateElement(points[i], i, reset);
+ }
+
+ if (showLine && line._model.tension !== 0) {
+ me.updateBezierControlPoints();
+ }
+
+ // Now pivot the point for animation
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ points[i].pivot();
+ }
+ },
+
+ updateElement: function(point, index, reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var custom = point.custom || {};
+ var dataset = me.getDataset();
+ var datasetIndex = me.index;
+ var value = dataset.data[index];
+ var xScale = me._xScale;
+ var yScale = me._yScale;
+ var lineModel = meta.dataset._model;
+ var x, y;
+
+ var options = me._resolveDataElementOptions(point, index);
+
+ x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex);
+ y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);
+
+ // Utility
+ point._xScale = xScale;
+ point._yScale = yScale;
+ point._options = options;
+ point._datasetIndex = datasetIndex;
+ point._index = index;
+
+ // Desired view properties
+ point._model = {
+ x: x,
+ y: y,
+ skip: custom.skip || isNaN(x) || isNaN(y),
+ // Appearance
+ radius: options.radius,
+ pointStyle: options.pointStyle,
+ rotation: options.rotation,
+ backgroundColor: options.backgroundColor,
+ borderColor: options.borderColor,
+ borderWidth: options.borderWidth,
+ tension: valueOrDefault$6(custom.tension, lineModel ? lineModel.tension : 0),
+ steppedLine: lineModel ? lineModel.steppedLine : false,
+ // Tooltip
+ hitRadius: options.hitRadius
+ };
+ },
+
+ /**
+ * @private
+ */
+ _resolveDatasetElementOptions: function(element) {
+ var me = this;
+ var config = me._config;
+ var custom = element.custom || {};
+ var options = me.chart.options;
+ var lineOptions = options.elements.line;
+ var values = core_datasetController.prototype._resolveDatasetElementOptions.apply(me, arguments);
+
+ // The default behavior of lines is to break at null values, according
+ // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158
+ // This option gives lines the ability to span gaps
+ values.spanGaps = valueOrDefault$6(config.spanGaps, options.spanGaps);
+ values.tension = valueOrDefault$6(config.lineTension, lineOptions.tension);
+ values.steppedLine = resolve$2([custom.steppedLine, config.steppedLine, lineOptions.stepped]);
+ values.clip = toClip(valueOrDefault$6(config.clip, defaultClip(me._xScale, me._yScale, values.borderWidth)));
+
+ return values;
+ },
+
+ calculatePointY: function(value, index, datasetIndex) {
+ var me = this;
+ var chart = me.chart;
+ var yScale = me._yScale;
+ var sumPos = 0;
+ var sumNeg = 0;
+ var i, ds, dsMeta, stackedRightValue, rightValue, metasets, ilen;
+
+ if (yScale.options.stacked) {
+ rightValue = +yScale.getRightValue(value);
+ metasets = chart._getSortedVisibleDatasetMetas();
+ ilen = metasets.length;
+
+ for (i = 0; i < ilen; ++i) {
+ dsMeta = metasets[i];
+ if (dsMeta.index === datasetIndex) {
+ break;
+ }
+
+ ds = chart.data.datasets[dsMeta.index];
+ if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id) {
+ stackedRightValue = +yScale.getRightValue(ds.data[index]);
+ if (stackedRightValue < 0) {
+ sumNeg += stackedRightValue || 0;
+ } else {
+ sumPos += stackedRightValue || 0;
+ }
+ }
+ }
+
+ if (rightValue < 0) {
+ return yScale.getPixelForValue(sumNeg + rightValue);
+ }
+ return yScale.getPixelForValue(sumPos + rightValue);
+ }
+ return yScale.getPixelForValue(value);
+ },
+
+ updateBezierControlPoints: function() {
+ var me = this;
+ var chart = me.chart;
+ var meta = me.getMeta();
+ var lineModel = meta.dataset._model;
+ var area = chart.chartArea;
+ var points = meta.data || [];
+ var i, ilen, model, controlPoints;
+
+ // Only consider points that are drawn in case the spanGaps option is used
+ if (lineModel.spanGaps) {
+ points = points.filter(function(pt) {
+ return !pt._model.skip;
+ });
+ }
+
+ function capControlPoint(pt, min, max) {
+ return Math.max(Math.min(pt, max), min);
+ }
+
+ if (lineModel.cubicInterpolationMode === 'monotone') {
+ helpers$1.splineCurveMonotone(points);
+ } else {
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ model = points[i]._model;
+ controlPoints = helpers$1.splineCurve(
+ helpers$1.previousItem(points, i)._model,
+ model,
+ helpers$1.nextItem(points, i)._model,
+ lineModel.tension
+ );
+ model.controlPointPreviousX = controlPoints.previous.x;
+ model.controlPointPreviousY = controlPoints.previous.y;
+ model.controlPointNextX = controlPoints.next.x;
+ model.controlPointNextY = controlPoints.next.y;
+ }
+ }
+
+ if (chart.options.elements.line.capBezierPoints) {
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ model = points[i]._model;
+ if (isPointInArea(model, area)) {
+ if (i > 0 && isPointInArea(points[i - 1]._model, area)) {
+ model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);
+ model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);
+ }
+ if (i < points.length - 1 && isPointInArea(points[i + 1]._model, area)) {
+ model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);
+ model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);
+ }
+ }
+ }
+ }
+ },
+
+ draw: function() {
+ var me = this;
+ var chart = me.chart;
+ var meta = me.getMeta();
+ var points = meta.data || [];
+ var area = chart.chartArea;
+ var canvas = chart.canvas;
+ var i = 0;
+ var ilen = points.length;
+ var clip;
+
+ if (me._showLine) {
+ clip = meta.dataset._model.clip;
+
+ helpers$1.canvas.clipArea(chart.ctx, {
+ left: clip.left === false ? 0 : area.left - clip.left,
+ right: clip.right === false ? canvas.width : area.right + clip.right,
+ top: clip.top === false ? 0 : area.top - clip.top,
+ bottom: clip.bottom === false ? canvas.height : area.bottom + clip.bottom
+ });
+
+ meta.dataset.draw();
+
+ helpers$1.canvas.unclipArea(chart.ctx);
+ }
+
+ // Draw the points
+ for (; i < ilen; ++i) {
+ points[i].draw(area);
+ }
+ },
+
+ /**
+ * @protected
+ */
+ setHoverStyle: function(point) {
+ var model = point._model;
+ var options = point._options;
+ var getHoverColor = helpers$1.getHoverColor;
+
+ point.$previousStyle = {
+ backgroundColor: model.backgroundColor,
+ borderColor: model.borderColor,
+ borderWidth: model.borderWidth,
+ radius: model.radius
+ };
+
+ model.backgroundColor = valueOrDefault$6(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));
+ model.borderColor = valueOrDefault$6(options.hoverBorderColor, getHoverColor(options.borderColor));
+ model.borderWidth = valueOrDefault$6(options.hoverBorderWidth, options.borderWidth);
+ model.radius = valueOrDefault$6(options.hoverRadius, options.radius);
+ },
+});
+
+var resolve$3 = helpers$1.options.resolve;
+
+core_defaults._set('polarArea', {
+ scale: {
+ type: 'radialLinear',
+ angleLines: {
+ display: false
+ },
+ gridLines: {
+ circular: true
+ },
+ pointLabels: {
+ display: false
+ },
+ ticks: {
+ beginAtZero: true
+ }
+ },
+
+ // Boolean - Whether to animate the rotation of the chart
+ animation: {
+ animateRotate: true,
+ animateScale: true
+ },
+
+ startAngle: -0.5 * Math.PI,
+ legendCallback: function(chart) {
+ var list = document.createElement('ul');
+ var data = chart.data;
+ var datasets = data.datasets;
+ var labels = data.labels;
+ var i, ilen, listItem, listItemSpan;
+
+ list.setAttribute('class', chart.id + '-legend');
+ if (datasets.length) {
+ for (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) {
+ listItem = list.appendChild(document.createElement('li'));
+ listItemSpan = listItem.appendChild(document.createElement('span'));
+ listItemSpan.style.backgroundColor = datasets[0].backgroundColor[i];
+ if (labels[i]) {
+ listItem.appendChild(document.createTextNode(labels[i]));
+ }
+ }
+ }
+
+ return list.outerHTML;
+ },
+ legend: {
+ labels: {
+ generateLabels: function(chart) {
+ var data = chart.data;
+ if (data.labels.length && data.datasets.length) {
+ return data.labels.map(function(label, i) {
+ var meta = chart.getDatasetMeta(0);
+ var style = meta.controller.getStyle(i);
+
+ return {
+ text: label,
+ fillStyle: style.backgroundColor,
+ strokeStyle: style.borderColor,
+ lineWidth: style.borderWidth,
+ hidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden,
+
+ // Extra data used for toggling the correct item
+ index: i
+ };
+ });
+ }
+ return [];
+ }
+ },
+
+ onClick: function(e, legendItem) {
+ var index = legendItem.index;
+ var chart = this.chart;
+ var i, ilen, meta;
+
+ for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
+ meta = chart.getDatasetMeta(i);
+ meta.data[index].hidden = !meta.data[index].hidden;
+ }
+
+ chart.update();
+ }
+ },
+
+ // Need to override these to give a nice default
+ tooltips: {
+ callbacks: {
+ title: function() {
+ return '';
+ },
+ label: function(item, data) {
+ return data.labels[item.index] + ': ' + item.yLabel;
+ }
+ }
+ }
+});
+
+var controller_polarArea = core_datasetController.extend({
+
+ dataElementType: elements.Arc,
+
+ linkScales: helpers$1.noop,
+
+ /**
+ * @private
+ */
+ _dataElementOptions: [
+ 'backgroundColor',
+ 'borderColor',
+ 'borderWidth',
+ 'borderAlign',
+ 'hoverBackgroundColor',
+ 'hoverBorderColor',
+ 'hoverBorderWidth',
+ ],
+
+ /**
+ * @private
+ */
+ _getIndexScaleId: function() {
+ return this.chart.scale.id;
+ },
+
+ /**
+ * @private
+ */
+ _getValueScaleId: function() {
+ return this.chart.scale.id;
+ },
+
+ update: function(reset) {
+ var me = this;
+ var dataset = me.getDataset();
+ var meta = me.getMeta();
+ var start = me.chart.options.startAngle || 0;
+ var starts = me._starts = [];
+ var angles = me._angles = [];
+ var arcs = meta.data;
+ var i, ilen, angle;
+
+ me._updateRadius();
+
+ meta.count = me.countVisibleElements();
+
+ for (i = 0, ilen = dataset.data.length; i < ilen; i++) {
+ starts[i] = start;
+ angle = me._computeAngle(i);
+ angles[i] = angle;
+ start += angle;
+ }
+
+ for (i = 0, ilen = arcs.length; i < ilen; ++i) {
+ arcs[i]._options = me._resolveDataElementOptions(arcs[i], i);
+ me.updateElement(arcs[i], i, reset);
+ }
+ },
+
+ /**
+ * @private
+ */
+ _updateRadius: function() {
+ var me = this;
+ var chart = me.chart;
+ var chartArea = chart.chartArea;
+ var opts = chart.options;
+ var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
+
+ chart.outerRadius = Math.max(minSize / 2, 0);
+ chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);
+ chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
+
+ me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);
+ me.innerRadius = me.outerRadius - chart.radiusLength;
+ },
+
+ updateElement: function(arc, index, reset) {
+ var me = this;
+ var chart = me.chart;
+ var dataset = me.getDataset();
+ var opts = chart.options;
+ var animationOpts = opts.animation;
+ var scale = chart.scale;
+ var labels = chart.data.labels;
+
+ var centerX = scale.xCenter;
+ var centerY = scale.yCenter;
+
+ // var negHalfPI = -0.5 * Math.PI;
+ var datasetStartAngle = opts.startAngle;
+ var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
+ var startAngle = me._starts[index];
+ var endAngle = startAngle + (arc.hidden ? 0 : me._angles[index]);
+
+ var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
+ var options = arc._options || {};
+
+ helpers$1.extend(arc, {
+ // Utility
+ _datasetIndex: me.index,
+ _index: index,
+ _scale: scale,
+
+ // Desired view properties
+ _model: {
+ backgroundColor: options.backgroundColor,
+ borderColor: options.borderColor,
+ borderWidth: options.borderWidth,
+ borderAlign: options.borderAlign,
+ x: centerX,
+ y: centerY,
+ innerRadius: 0,
+ outerRadius: reset ? resetRadius : distance,
+ startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,
+ endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,
+ label: helpers$1.valueAtIndexOrDefault(labels, index, labels[index])
+ }
+ });
+
+ arc.pivot();
+ },
+
+ countVisibleElements: function() {
+ var dataset = this.getDataset();
+ var meta = this.getMeta();
+ var count = 0;
+
+ helpers$1.each(meta.data, function(element, index) {
+ if (!isNaN(dataset.data[index]) && !element.hidden) {
+ count++;
+ }
+ });
+
+ return count;
+ },
+
+ /**
+ * @protected
+ */
+ setHoverStyle: function(arc) {
+ var model = arc._model;
+ var options = arc._options;
+ var getHoverColor = helpers$1.getHoverColor;
+ var valueOrDefault = helpers$1.valueOrDefault;
+
+ arc.$previousStyle = {
+ backgroundColor: model.backgroundColor,
+ borderColor: model.borderColor,
+ borderWidth: model.borderWidth,
+ };
+
+ model.backgroundColor = valueOrDefault(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));
+ model.borderColor = valueOrDefault(options.hoverBorderColor, getHoverColor(options.borderColor));
+ model.borderWidth = valueOrDefault(options.hoverBorderWidth, options.borderWidth);
+ },
+
+ /**
+ * @private
+ */
+ _computeAngle: function(index) {
+ var me = this;
+ var count = this.getMeta().count;
+ var dataset = me.getDataset();
+ var meta = me.getMeta();
+
+ if (isNaN(dataset.data[index]) || meta.data[index].hidden) {
+ return 0;
+ }
+
+ // Scriptable options
+ var context = {
+ chart: me.chart,
+ dataIndex: index,
+ dataset: dataset,
+ datasetIndex: me.index
+ };
+
+ return resolve$3([
+ me.chart.options.elements.arc.angle,
+ (2 * Math.PI) / count
+ ], context, index);
+ }
+});
+
+core_defaults._set('pie', helpers$1.clone(core_defaults.doughnut));
+core_defaults._set('pie', {
+ cutoutPercentage: 0
+});
+
+// Pie charts are Doughnut chart with different defaults
+var controller_pie = controller_doughnut;
+
+var valueOrDefault$7 = helpers$1.valueOrDefault;
+
+core_defaults._set('radar', {
+ spanGaps: false,
+ scale: {
+ type: 'radialLinear'
+ },
+ elements: {
+ line: {
+ fill: 'start',
+ tension: 0 // no bezier in radar
+ }
+ }
+});
+
+var controller_radar = core_datasetController.extend({
+ datasetElementType: elements.Line,
+
+ dataElementType: elements.Point,
+
+ linkScales: helpers$1.noop,
+
+ /**
+ * @private
+ */
+ _datasetElementOptions: [
+ 'backgroundColor',
+ 'borderWidth',
+ 'borderColor',
+ 'borderCapStyle',
+ 'borderDash',
+ 'borderDashOffset',
+ 'borderJoinStyle',
+ 'fill'
+ ],
+
+ /**
+ * @private
+ */
+ _dataElementOptions: {
+ backgroundColor: 'pointBackgroundColor',
+ borderColor: 'pointBorderColor',
+ borderWidth: 'pointBorderWidth',
+ hitRadius: 'pointHitRadius',
+ hoverBackgroundColor: 'pointHoverBackgroundColor',
+ hoverBorderColor: 'pointHoverBorderColor',
+ hoverBorderWidth: 'pointHoverBorderWidth',
+ hoverRadius: 'pointHoverRadius',
+ pointStyle: 'pointStyle',
+ radius: 'pointRadius',
+ rotation: 'pointRotation'
+ },
+
+ /**
+ * @private
+ */
+ _getIndexScaleId: function() {
+ return this.chart.scale.id;
+ },
+
+ /**
+ * @private
+ */
+ _getValueScaleId: function() {
+ return this.chart.scale.id;
+ },
+
+ update: function(reset) {
+ var me = this;
+ var meta = me.getMeta();
+ var line = meta.dataset;
+ var points = meta.data || [];
+ var scale = me.chart.scale;
+ var config = me._config;
+ var i, ilen;
+
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if (config.tension !== undefined && config.lineTension === undefined) {
+ config.lineTension = config.tension;
+ }
+
+ // Utility
+ line._scale = scale;
+ line._datasetIndex = me.index;
+ // Data
+ line._children = points;
+ line._loop = true;
+ // Model
+ line._model = me._resolveDatasetElementOptions(line);
+
+ line.pivot();
+
+ // Update Points
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ me.updateElement(points[i], i, reset);
+ }
+
+ // Update bezier control points
+ me.updateBezierControlPoints();
+
+ // Now pivot the point for animation
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ points[i].pivot();
+ }
+ },
+
+ updateElement: function(point, index, reset) {
+ var me = this;
+ var custom = point.custom || {};
+ var dataset = me.getDataset();
+ var scale = me.chart.scale;
+ var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);
+ var options = me._resolveDataElementOptions(point, index);
+ var lineModel = me.getMeta().dataset._model;
+ var x = reset ? scale.xCenter : pointPosition.x;
+ var y = reset ? scale.yCenter : pointPosition.y;
+
+ // Utility
+ point._scale = scale;
+ point._options = options;
+ point._datasetIndex = me.index;
+ point._index = index;
+
+ // Desired view properties
+ point._model = {
+ x: x, // value not used in dataset scale, but we want a consistent API between scales
+ y: y,
+ skip: custom.skip || isNaN(x) || isNaN(y),
+ // Appearance
+ radius: options.radius,
+ pointStyle: options.pointStyle,
+ rotation: options.rotation,
+ backgroundColor: options.backgroundColor,
+ borderColor: options.borderColor,
+ borderWidth: options.borderWidth,
+ tension: valueOrDefault$7(custom.tension, lineModel ? lineModel.tension : 0),
+
+ // Tooltip
+ hitRadius: options.hitRadius
+ };
+ },
+
+ /**
+ * @private
+ */
+ _resolveDatasetElementOptions: function() {
+ var me = this;
+ var config = me._config;
+ var options = me.chart.options;
+ var values = core_datasetController.prototype._resolveDatasetElementOptions.apply(me, arguments);
+
+ values.spanGaps = valueOrDefault$7(config.spanGaps, options.spanGaps);
+ values.tension = valueOrDefault$7(config.lineTension, options.elements.line.tension);
+
+ return values;
+ },
+
+ updateBezierControlPoints: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var area = me.chart.chartArea;
+ var points = meta.data || [];
+ var i, ilen, model, controlPoints;
+
+ // Only consider points that are drawn in case the spanGaps option is used
+ if (meta.dataset._model.spanGaps) {
+ points = points.filter(function(pt) {
+ return !pt._model.skip;
+ });
+ }
+
+ function capControlPoint(pt, min, max) {
+ return Math.max(Math.min(pt, max), min);
+ }
+
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
+ model = points[i]._model;
+ controlPoints = helpers$1.splineCurve(
+ helpers$1.previousItem(points, i, true)._model,
+ model,
+ helpers$1.nextItem(points, i, true)._model,
+ model.tension
+ );
+
+ // Prevent the bezier going outside of the bounds of the graph
+ model.controlPointPreviousX = capControlPoint(controlPoints.previous.x, area.left, area.right);
+ model.controlPointPreviousY = capControlPoint(controlPoints.previous.y, area.top, area.bottom);
+ model.controlPointNextX = capControlPoint(controlPoints.next.x, area.left, area.right);
+ model.controlPointNextY = capControlPoint(controlPoints.next.y, area.top, area.bottom);
+ }
+ },
+
+ setHoverStyle: function(point) {
+ var model = point._model;
+ var options = point._options;
+ var getHoverColor = helpers$1.getHoverColor;
+
+ point.$previousStyle = {
+ backgroundColor: model.backgroundColor,
+ borderColor: model.borderColor,
+ borderWidth: model.borderWidth,
+ radius: model.radius
+ };
+
+ model.backgroundColor = valueOrDefault$7(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));
+ model.borderColor = valueOrDefault$7(options.hoverBorderColor, getHoverColor(options.borderColor));
+ model.borderWidth = valueOrDefault$7(options.hoverBorderWidth, options.borderWidth);
+ model.radius = valueOrDefault$7(options.hoverRadius, options.radius);
+ }
+});
+
+core_defaults._set('scatter', {
+ hover: {
+ mode: 'single'
+ },
+
+ scales: {
+ xAxes: [{
+ id: 'x-axis-1', // need an ID so datasets can reference the scale
+ type: 'linear', // scatter should not use a category axis
+ position: 'bottom'
+ }],
+ yAxes: [{
+ id: 'y-axis-1',
+ type: 'linear',
+ position: 'left'
+ }]
+ },
+
+ tooltips: {
+ callbacks: {
+ title: function() {
+ return ''; // doesn't make sense for scatter since data are formatted as a point
+ },
+ label: function(item) {
+ return '(' + item.xLabel + ', ' + item.yLabel + ')';
+ }
+ }
+ }
+});
+
+core_defaults._set('global', {
+ datasets: {
+ scatter: {
+ showLine: false
+ }
+ }
+});
+
+// Scatter charts use line controllers
+var controller_scatter = controller_line;
+
+// NOTE export a map in which the key represents the controller type, not
+// the class, and so must be CamelCase in order to be correctly retrieved
+// by the controller in core.controller.js (`controllers[meta.type]`).
+
+var controllers = {
+ bar: controller_bar,
+ bubble: controller_bubble,
+ doughnut: controller_doughnut,
+ horizontalBar: controller_horizontalBar,
+ line: controller_line,
+ polarArea: controller_polarArea,
+ pie: controller_pie,
+ radar: controller_radar,
+ scatter: controller_scatter
+};
+
+/**
+ * Helper function to get relative position for an event
+ * @param {Event|IEvent} event - The event to get the position for
+ * @param {Chart} chart - The chart
+ * @returns {object} the event position
+ */
+function getRelativePosition(e, chart) {
+ if (e.native) {
+ return {
+ x: e.x,
+ y: e.y
+ };
+ }
+
+ return helpers$1.getRelativePosition(e, chart);
+}
+
+/**
+ * Helper function to traverse all of the visible elements in the chart
+ * @param {Chart} chart - the chart
+ * @param {function} handler - the callback to execute for each visible item
+ */
+function parseVisibleItems(chart, handler) {
+ var metasets = chart._getSortedVisibleDatasetMetas();
+ var metadata, i, j, ilen, jlen, element;
+
+ for (i = 0, ilen = metasets.length; i < ilen; ++i) {
+ metadata = metasets[i].data;
+ for (j = 0, jlen = metadata.length; j < jlen; ++j) {
+ element = metadata[j];
+ if (!element._view.skip) {
+ handler(element);
+ }
+ }
+ }
+}
+
+/**
+ * Helper function to get the items that intersect the event position
+ * @param {ChartElement[]} items - elements to filter
+ * @param {object} position - the point to be nearest to
+ * @return {ChartElement[]} the nearest items
+ */
+function getIntersectItems(chart, position) {
+ var elements = [];
+
+ parseVisibleItems(chart, function(element) {
+ if (element.inRange(position.x, position.y)) {
+ elements.push(element);
+ }
+ });
+
+ return elements;
+}
+
+/**
+ * Helper function to get the items nearest to the event position considering all visible items in teh chart
+ * @param {Chart} chart - the chart to look at elements from
+ * @param {object} position - the point to be nearest to
+ * @param {boolean} intersect - if true, only consider items that intersect the position
+ * @param {function} distanceMetric - function to provide the distance between points
+ * @return {ChartElement[]} the nearest items
+ */
+function getNearestItems(chart, position, intersect, distanceMetric) {
+ var minDistance = Number.POSITIVE_INFINITY;
+ var nearestItems = [];
+
+ parseVisibleItems(chart, function(element) {
+ if (intersect && !element.inRange(position.x, position.y)) {
+ return;
+ }
+
+ var center = element.getCenterPoint();
+ var distance = distanceMetric(position, center);
+ if (distance < minDistance) {
+ nearestItems = [element];
+ minDistance = distance;
+ } else if (distance === minDistance) {
+ // Can have multiple items at the same distance in which case we sort by size
+ nearestItems.push(element);
+ }
+ });
+
+ return nearestItems;
+}
+
+/**
+ * Get a distance metric function for two points based on the
+ * axis mode setting
+ * @param {string} axis - the axis mode. x|y|xy
+ */
+function getDistanceMetricForAxis(axis) {
+ var useX = axis.indexOf('x') !== -1;
+ var useY = axis.indexOf('y') !== -1;
+
+ return function(pt1, pt2) {
+ var deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0;
+ var deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0;
+ return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
+ };
+}
+
+function indexMode(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ // Default axis for index mode is 'x' to match old behaviour
+ options.axis = options.axis || 'x';
+ var distanceMetric = getDistanceMetricForAxis(options.axis);
+ var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);
+ var elements = [];
+
+ if (!items.length) {
+ return [];
+ }
+
+ chart._getSortedVisibleDatasetMetas().forEach(function(meta) {
+ var element = meta.data[items[0]._index];
+
+ // don't count items that are skipped (null data)
+ if (element && !element._view.skip) {
+ elements.push(element);
+ }
+ });
+
+ return elements;
+}
+
+/**
+ * @interface IInteractionOptions
+ */
+/**
+ * If true, only consider items that intersect the point
+ * @name IInterfaceOptions#boolean
+ * @type Boolean
+ */
+
+/**
+ * Contains interaction related functions
+ * @namespace Chart.Interaction
+ */
+var core_interaction = {
+ // Helper function for different modes
+ modes: {
+ single: function(chart, e) {
+ var position = getRelativePosition(e, chart);
+ var elements = [];
+
+ parseVisibleItems(chart, function(element) {
+ if (element.inRange(position.x, position.y)) {
+ elements.push(element);
+ return elements;
+ }
+ });
+
+ return elements.slice(0, 1);
+ },
+
+ /**
+ * @function Chart.Interaction.modes.label
+ * @deprecated since version 2.4.0
+ * @todo remove at version 3
+ * @private
+ */
+ label: indexMode,
+
+ /**
+ * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something
+ * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item
+ * @function Chart.Interaction.modes.index
+ * @since v2.4.0
+ * @param {Chart} chart - the chart we are returning items from
+ * @param {Event} e - the event we are find things at
+ * @param {IInteractionOptions} options - options to use during interaction
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ index: indexMode,
+
+ /**
+ * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something
+ * If the options.intersect is false, we find the nearest item and return the items in that dataset
+ * @function Chart.Interaction.modes.dataset
+ * @param {Chart} chart - the chart we are returning items from
+ * @param {Event} e - the event we are find things at
+ * @param {IInteractionOptions} options - options to use during interaction
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ dataset: function(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ options.axis = options.axis || 'xy';
+ var distanceMetric = getDistanceMetricForAxis(options.axis);
+ var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);
+
+ if (items.length > 0) {
+ items = chart.getDatasetMeta(items[0]._datasetIndex).data;
+ }
+
+ return items;
+ },
+
+ /**
+ * @function Chart.Interaction.modes.x-axis
+ * @deprecated since version 2.4.0. Use index mode and intersect == true
+ * @todo remove at version 3
+ * @private
+ */
+ 'x-axis': function(chart, e) {
+ return indexMode(chart, e, {intersect: false});
+ },
+
+ /**
+ * Point mode returns all elements that hit test based on the event position
+ * of the event
+ * @function Chart.Interaction.modes.intersect
+ * @param {Chart} chart - the chart we are returning items from
+ * @param {Event} e - the event we are find things at
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ point: function(chart, e) {
+ var position = getRelativePosition(e, chart);
+ return getIntersectItems(chart, position);
+ },
+
+ /**
+ * nearest mode returns the element closest to the point
+ * @function Chart.Interaction.modes.intersect
+ * @param {Chart} chart - the chart we are returning items from
+ * @param {Event} e - the event we are find things at
+ * @param {IInteractionOptions} options - options to use
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ nearest: function(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ options.axis = options.axis || 'xy';
+ var distanceMetric = getDistanceMetricForAxis(options.axis);
+ return getNearestItems(chart, position, options.intersect, distanceMetric);
+ },
+
+ /**
+ * x mode returns the elements that hit-test at the current x coordinate
+ * @function Chart.Interaction.modes.x
+ * @param {Chart} chart - the chart we are returning items from
+ * @param {Event} e - the event we are find things at
+ * @param {IInteractionOptions} options - options to use
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ x: function(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ var items = [];
+ var intersectsItem = false;
+
+ parseVisibleItems(chart, function(element) {
+ if (element.inXRange(position.x)) {
+ items.push(element);
+ }
+
+ if (element.inRange(position.x, position.y)) {
+ intersectsItem = true;
+ }
+ });
+
+ // If we want to trigger on an intersect and we don't have any items
+ // that intersect the position, return nothing
+ if (options.intersect && !intersectsItem) {
+ items = [];
+ }
+ return items;
+ },
+
+ /**
+ * y mode returns the elements that hit-test at the current y coordinate
+ * @function Chart.Interaction.modes.y
+ * @param {Chart} chart - the chart we are returning items from
+ * @param {Event} e - the event we are find things at
+ * @param {IInteractionOptions} options - options to use
+ * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+ */
+ y: function(chart, e, options) {
+ var position = getRelativePosition(e, chart);
+ var items = [];
+ var intersectsItem = false;
+
+ parseVisibleItems(chart, function(element) {
+ if (element.inYRange(position.y)) {
+ items.push(element);
+ }
+
+ if (element.inRange(position.x, position.y)) {
+ intersectsItem = true;
+ }
+ });
+
+ // If we want to trigger on an intersect and we don't have any items
+ // that intersect the position, return nothing
+ if (options.intersect && !intersectsItem) {
+ items = [];
+ }
+ return items;
+ }
+ }
+};
+
+var extend = helpers$1.extend;
+
+function filterByPosition(array, position) {
+ return helpers$1.where(array, function(v) {
+ return v.pos === position;
+ });
+}
+
+function sortByWeight(array, reverse) {
+ return array.sort(function(a, b) {
+ var v0 = reverse ? b : a;
+ var v1 = reverse ? a : b;
+ return v0.weight === v1.weight ?
+ v0.index - v1.index :
+ v0.weight - v1.weight;
+ });
+}
+
+function wrapBoxes(boxes) {
+ var layoutBoxes = [];
+ var i, ilen, box;
+
+ for (i = 0, ilen = (boxes || []).length; i < ilen; ++i) {
+ box = boxes[i];
+ layoutBoxes.push({
+ index: i,
+ box: box,
+ pos: box.position,
+ horizontal: box.isHorizontal(),
+ weight: box.weight
+ });
+ }
+ return layoutBoxes;
+}
+
+function setLayoutDims(layouts, params) {
+ var i, ilen, layout;
+ for (i = 0, ilen = layouts.length; i < ilen; ++i) {
+ layout = layouts[i];
+ // store width used instead of chartArea.w in fitBoxes
+ layout.width = layout.horizontal
+ ? layout.box.fullWidth && params.availableWidth
+ : params.vBoxMaxWidth;
+ // store height used instead of chartArea.h in fitBoxes
+ layout.height = layout.horizontal && params.hBoxMaxHeight;
+ }
+}
+
+function buildLayoutBoxes(boxes) {
+ var layoutBoxes = wrapBoxes(boxes);
+ var left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true);
+ var right = sortByWeight(filterByPosition(layoutBoxes, 'right'));
+ var top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true);
+ var bottom = sortByWeight(filterByPosition(layoutBoxes, 'bottom'));
+
+ return {
+ leftAndTop: left.concat(top),
+ rightAndBottom: right.concat(bottom),
+ chartArea: filterByPosition(layoutBoxes, 'chartArea'),
+ vertical: left.concat(right),
+ horizontal: top.concat(bottom)
+ };
+}
+
+function getCombinedMax(maxPadding, chartArea, a, b) {
+ return Math.max(maxPadding[a], chartArea[a]) + Math.max(maxPadding[b], chartArea[b]);
+}
+
+function updateDims(chartArea, params, layout) {
+ var box = layout.box;
+ var maxPadding = chartArea.maxPadding;
+ var newWidth, newHeight;
+
+ if (layout.size) {
+ // this layout was already counted for, lets first reduce old size
+ chartArea[layout.pos] -= layout.size;
+ }
+ layout.size = layout.horizontal ? box.height : box.width;
+ chartArea[layout.pos] += layout.size;
+
+ if (box.getPadding) {
+ var boxPadding = box.getPadding();
+ maxPadding.top = Math.max(maxPadding.top, boxPadding.top);
+ maxPadding.left = Math.max(maxPadding.left, boxPadding.left);
+ maxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom);
+ maxPadding.right = Math.max(maxPadding.right, boxPadding.right);
+ }
+
+ newWidth = params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right');
+ newHeight = params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom');
+
+ if (newWidth !== chartArea.w || newHeight !== chartArea.h) {
+ chartArea.w = newWidth;
+ chartArea.h = newHeight;
+
+ // return true if chart area changed in layout's direction
+ return layout.horizontal ? newWidth !== chartArea.w : newHeight !== chartArea.h;
+ }
+}
+
+function handleMaxPadding(chartArea) {
+ var maxPadding = chartArea.maxPadding;
+
+ function updatePos(pos) {
+ var change = Math.max(maxPadding[pos] - chartArea[pos], 0);
+ chartArea[pos] += change;
+ return change;
+ }
+ chartArea.y += updatePos('top');
+ chartArea.x += updatePos('left');
+ updatePos('right');
+ updatePos('bottom');
+}
+
+function getMargins(horizontal, chartArea) {
+ var maxPadding = chartArea.maxPadding;
+
+ function marginForPositions(positions) {
+ var margin = {left: 0, top: 0, right: 0, bottom: 0};
+ positions.forEach(function(pos) {
+ margin[pos] = Math.max(chartArea[pos], maxPadding[pos]);
+ });
+ return margin;
+ }
+
+ return horizontal
+ ? marginForPositions(['left', 'right'])
+ : marginForPositions(['top', 'bottom']);
+}
+
+function fitBoxes(boxes, chartArea, params) {
+ var refitBoxes = [];
+ var i, ilen, layout, box, refit, changed;
+
+ for (i = 0, ilen = boxes.length; i < ilen; ++i) {
+ layout = boxes[i];
+ box = layout.box;
+
+ box.update(
+ layout.width || chartArea.w,
+ layout.height || chartArea.h,
+ getMargins(layout.horizontal, chartArea)
+ );
+ if (updateDims(chartArea, params, layout)) {
+ changed = true;
+ if (refitBoxes.length) {
+ // Dimensions changed and there were non full width boxes before this
+ // -> we have to refit those
+ refit = true;
+ }
+ }
+ if (!box.fullWidth) { // fullWidth boxes don't need to be re-fitted in any case
+ refitBoxes.push(layout);
+ }
+ }
+
+ return refit ? fitBoxes(refitBoxes, chartArea, params) || changed : changed;
+}
+
+function placeBoxes(boxes, chartArea, params) {
+ var userPadding = params.padding;
+ var x = chartArea.x;
+ var y = chartArea.y;
+ var i, ilen, layout, box;
+
+ for (i = 0, ilen = boxes.length; i < ilen; ++i) {
+ layout = boxes[i];
+ box = layout.box;
+ if (layout.horizontal) {
+ box.left = box.fullWidth ? userPadding.left : chartArea.left;
+ box.right = box.fullWidth ? params.outerWidth - userPadding.right : chartArea.left + chartArea.w;
+ box.top = y;
+ box.bottom = y + box.height;
+ box.width = box.right - box.left;
+ y = box.bottom;
+ } else {
+ box.left = x;
+ box.right = x + box.width;
+ box.top = chartArea.top;
+ box.bottom = chartArea.top + chartArea.h;
+ box.height = box.bottom - box.top;
+ x = box.right;
+ }
+ }
+
+ chartArea.x = x;
+ chartArea.y = y;
+}
+
+core_defaults._set('global', {
+ layout: {
+ padding: {
+ top: 0,
+ right: 0,
+ bottom: 0,
+ left: 0
+ }
+ }
+});
+
+/**
+ * @interface ILayoutItem
+ * @prop {string} position - The position of the item in the chart layout. Possible values are
+ * 'left', 'top', 'right', 'bottom', and 'chartArea'
+ * @prop {number} weight - The weight used to sort the item. Higher weights are further away from the chart area
+ * @prop {boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down
+ * @prop {function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom)
+ * @prop {function} update - Takes two parameters: width and height. Returns size of item
+ * @prop {function} getPadding - Returns an object with padding on the edges
+ * @prop {number} width - Width of item. Must be valid after update()
+ * @prop {number} height - Height of item. Must be valid after update()
+ * @prop {number} left - Left edge of the item. Set by layout system and cannot be used in update
+ * @prop {number} top - Top edge of the item. Set by layout system and cannot be used in update
+ * @prop {number} right - Right edge of the item. Set by layout system and cannot be used in update
+ * @prop {number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update
+ */
+
+// The layout service is very self explanatory. It's responsible for the layout within a chart.
+// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need
+// It is this service's responsibility of carrying out that layout.
+var core_layouts = {
+ defaults: {},
+
+ /**
+ * Register a box to a chart.
+ * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.
+ * @param {Chart} chart - the chart to use
+ * @param {ILayoutItem} item - the item to add to be layed out
+ */
+ addBox: function(chart, item) {
+ if (!chart.boxes) {
+ chart.boxes = [];
+ }
+
+ // initialize item with default values
+ item.fullWidth = item.fullWidth || false;
+ item.position = item.position || 'top';
+ item.weight = item.weight || 0;
+ item._layers = item._layers || function() {
+ return [{
+ z: 0,
+ draw: function() {
+ item.draw.apply(item, arguments);
+ }
+ }];
+ };
+
+ chart.boxes.push(item);
+ },
+
+ /**
+ * Remove a layoutItem from a chart
+ * @param {Chart} chart - the chart to remove the box from
+ * @param {ILayoutItem} layoutItem - the item to remove from the layout
+ */
+ removeBox: function(chart, layoutItem) {
+ var index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1;
+ if (index !== -1) {
+ chart.boxes.splice(index, 1);
+ }
+ },
+
+ /**
+ * Sets (or updates) options on the given `item`.
+ * @param {Chart} chart - the chart in which the item lives (or will be added to)
+ * @param {ILayoutItem} item - the item to configure with the given options
+ * @param {object} options - the new item options.
+ */
+ configure: function(chart, item, options) {
+ var props = ['fullWidth', 'position', 'weight'];
+ var ilen = props.length;
+ var i = 0;
+ var prop;
+
+ for (; i < ilen; ++i) {
+ prop = props[i];
+ if (options.hasOwnProperty(prop)) {
+ item[prop] = options[prop];
+ }
+ }
+ },
+
+ /**
+ * Fits boxes of the given chart into the given size by having each box measure itself
+ * then running a fitting algorithm
+ * @param {Chart} chart - the chart
+ * @param {number} width - the width to fit into
+ * @param {number} height - the height to fit into
+ */
+ update: function(chart, width, height) {
+ if (!chart) {
+ return;
+ }
+
+ var layoutOptions = chart.options.layout || {};
+ var padding = helpers$1.options.toPadding(layoutOptions.padding);
+
+ var availableWidth = width - padding.width;
+ var availableHeight = height - padding.height;
+ var boxes = buildLayoutBoxes(chart.boxes);
+ var verticalBoxes = boxes.vertical;
+ var horizontalBoxes = boxes.horizontal;
+
+ // Essentially we now have any number of boxes on each of the 4 sides.
+ // Our canvas looks like the following.
+ // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and
+ // B1 is the bottom axis
+ // There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays
+ // These locations are single-box locations only, when trying to register a chartArea location that is already taken,
+ // an error will be thrown.
+ //
+ // |----------------------------------------------------|
+ // | T1 (Full Width) |
+ // |----------------------------------------------------|
+ // | | | T2 | |
+ // | |----|-------------------------------------|----|
+ // | | | C1 | | C2 | |
+ // | | |----| |----| |
+ // | | | | |
+ // | L1 | L2 | ChartArea (C0) | R1 |
+ // | | | | |
+ // | | |----| |----| |
+ // | | | C3 | | C4 | |
+ // | |----|-------------------------------------|----|
+ // | | | B1 | |
+ // |----------------------------------------------------|
+ // | B2 (Full Width) |
+ // |----------------------------------------------------|
+ //
+
+ var params = Object.freeze({
+ outerWidth: width,
+ outerHeight: height,
+ padding: padding,
+ availableWidth: availableWidth,
+ vBoxMaxWidth: availableWidth / 2 / verticalBoxes.length,
+ hBoxMaxHeight: availableHeight / 2
+ });
+ var chartArea = extend({
+ maxPadding: extend({}, padding),
+ w: availableWidth,
+ h: availableHeight,
+ x: padding.left,
+ y: padding.top
+ }, padding);
+
+ setLayoutDims(verticalBoxes.concat(horizontalBoxes), params);
+
+ // First fit vertical boxes
+ fitBoxes(verticalBoxes, chartArea, params);
+
+ // Then fit horizontal boxes
+ if (fitBoxes(horizontalBoxes, chartArea, params)) {
+ // if the area changed, re-fit vertical boxes
+ fitBoxes(verticalBoxes, chartArea, params);
+ }
+
+ handleMaxPadding(chartArea);
+
+ // Finally place the boxes to correct coordinates
+ placeBoxes(boxes.leftAndTop, chartArea, params);
+
+ // Move to opposite side of chart
+ chartArea.x += chartArea.w;
+ chartArea.y += chartArea.h;
+
+ placeBoxes(boxes.rightAndBottom, chartArea, params);
+
+ chart.chartArea = {
+ left: chartArea.left,
+ top: chartArea.top,
+ right: chartArea.left + chartArea.w,
+ bottom: chartArea.top + chartArea.h
+ };
+
+ // Finally update boxes in chartArea (radial scale for example)
+ helpers$1.each(boxes.chartArea, function(layout) {
+ var box = layout.box;
+ extend(box, chart.chartArea);
+ box.update(chartArea.w, chartArea.h);
+ });
+ }
+};
+
+/**
+ * Platform fallback implementation (minimal).
+ * @see https://github.com/chartjs/Chart.js/pull/4591#issuecomment-319575939
+ */
+
+var platform_basic = {
+ acquireContext: function(item) {
+ if (item && item.canvas) {
+ // Support for any object associated to a canvas (including a context2d)
+ item = item.canvas;
+ }
+
+ return item && item.getContext('2d') || null;
+ }
+};
+
+var platform_dom = "/*\n * DOM element rendering detection\n * https://davidwalsh.name/detect-node-insertion\n */\n@keyframes chartjs-render-animation {\n\tfrom { opacity: 0.99; }\n\tto { opacity: 1; }\n}\n\n.chartjs-render-monitor {\n\tanimation: chartjs-render-animation 0.001s;\n}\n\n/*\n * DOM element resizing detection\n * https://github.com/marcj/css-element-queries\n */\n.chartjs-size-monitor,\n.chartjs-size-monitor-expand,\n.chartjs-size-monitor-shrink {\n\tposition: absolute;\n\tdirection: ltr;\n\tleft: 0;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\toverflow: hidden;\n\tpointer-events: none;\n\tvisibility: hidden;\n\tz-index: -1;\n}\n\n.chartjs-size-monitor-expand > div {\n\tposition: absolute;\n\twidth: 1000000px;\n\theight: 1000000px;\n\tleft: 0;\n\ttop: 0;\n}\n\n.chartjs-size-monitor-shrink > div {\n\tposition: absolute;\n\twidth: 200%;\n\theight: 200%;\n\tleft: 0;\n\ttop: 0;\n}\n";
+
+var platform_dom$1 = /*#__PURE__*/Object.freeze({
+__proto__: null,
+'default': platform_dom
+});
+
+var stylesheet = getCjsExportFromNamespace(platform_dom$1);
+
+var EXPANDO_KEY = '$chartjs';
+var CSS_PREFIX = 'chartjs-';
+var CSS_SIZE_MONITOR = CSS_PREFIX + 'size-monitor';
+var CSS_RENDER_MONITOR = CSS_PREFIX + 'render-monitor';
+var CSS_RENDER_ANIMATION = CSS_PREFIX + 'render-animation';
+var ANIMATION_START_EVENTS = ['animationstart', 'webkitAnimationStart'];
+
+/**
+ * DOM event types -> Chart.js event types.
+ * Note: only events with different types are mapped.
+ * @see https://developer.mozilla.org/en-US/docs/Web/Events
+ */
+var EVENT_TYPES = {
+ touchstart: 'mousedown',
+ touchmove: 'mousemove',
+ touchend: 'mouseup',
+ pointerenter: 'mouseenter',
+ pointerdown: 'mousedown',
+ pointermove: 'mousemove',
+ pointerup: 'mouseup',
+ pointerleave: 'mouseout',
+ pointerout: 'mouseout'
+};
+
+/**
+ * The "used" size is the final value of a dimension property after all calculations have
+ * been performed. This method uses the computed style of `element` but returns undefined
+ * if the computed style is not expressed in pixels. That can happen in some cases where
+ * `element` has a size relative to its parent and this last one is not yet displayed,
+ * for example because of `display: none` on a parent node.
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
+ * @returns {number} Size in pixels or undefined if unknown.
+ */
+function readUsedSize(element, property) {
+ var value = helpers$1.getStyle(element, property);
+ var matches = value && value.match(/^(\d+)(\.\d+)?px$/);
+ return matches ? Number(matches[1]) : undefined;
+}
+
+/**
+ * Initializes the canvas style and render size without modifying the canvas display size,
+ * since responsiveness is handled by the controller.resize() method. The config is used
+ * to determine the aspect ratio to apply in case no explicit height has been specified.
+ */
+function initCanvas(canvas, config) {
+ var style = canvas.style;
+
+ // NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it
+ // returns null or '' if no explicit value has been set to the canvas attribute.
+ var renderHeight = canvas.getAttribute('height');
+ var renderWidth = canvas.getAttribute('width');
+
+ // Chart.js modifies some canvas values that we want to restore on destroy
+ canvas[EXPANDO_KEY] = {
+ initial: {
+ height: renderHeight,
+ width: renderWidth,
+ style: {
+ display: style.display,
+ height: style.height,
+ width: style.width
+ }
+ }
+ };
+
+ // Force canvas to display as block to avoid extra space caused by inline
+ // elements, which would interfere with the responsive resize process.
+ // https://github.com/chartjs/Chart.js/issues/2538
+ style.display = style.display || 'block';
+
+ if (renderWidth === null || renderWidth === '') {
+ var displayWidth = readUsedSize(canvas, 'width');
+ if (displayWidth !== undefined) {
+ canvas.width = displayWidth;
+ }
+ }
+
+ if (renderHeight === null || renderHeight === '') {
+ if (canvas.style.height === '') {
+ // If no explicit render height and style height, let's apply the aspect ratio,
+ // which one can be specified by the user but also by charts as default option
+ // (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2.
+ canvas.height = canvas.width / (config.options.aspectRatio || 2);
+ } else {
+ var displayHeight = readUsedSize(canvas, 'height');
+ if (displayWidth !== undefined) {
+ canvas.height = displayHeight;
+ }
+ }
+ }
+
+ return canvas;
+}
+
+/**
+ * Detects support for options object argument in addEventListener.
+ * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
+ * @private
+ */
+var supportsEventListenerOptions = (function() {
+ var supports = false;
+ try {
+ var options = Object.defineProperty({}, 'passive', {
+ // eslint-disable-next-line getter-return
+ get: function() {
+ supports = true;
+ }
+ });
+ window.addEventListener('e', null, options);
+ } catch (e) {
+ // continue regardless of error
+ }
+ return supports;
+}());
+
+// Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events.
+// https://github.com/chartjs/Chart.js/issues/4287
+var eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false;
+
+function addListener(node, type, listener) {
+ node.addEventListener(type, listener, eventListenerOptions);
+}
+
+function removeListener(node, type, listener) {
+ node.removeEventListener(type, listener, eventListenerOptions);
+}
+
+function createEvent(type, chart, x, y, nativeEvent) {
+ return {
+ type: type,
+ chart: chart,
+ native: nativeEvent || null,
+ x: x !== undefined ? x : null,
+ y: y !== undefined ? y : null,
+ };
+}
+
+function fromNativeEvent(event, chart) {
+ var type = EVENT_TYPES[event.type] || event.type;
+ var pos = helpers$1.getRelativePosition(event, chart);
+ return createEvent(type, chart, pos.x, pos.y, event);
+}
+
+function throttled(fn, thisArg) {
+ var ticking = false;
+ var args = [];
+
+ return function() {
+ args = Array.prototype.slice.call(arguments);
+ thisArg = thisArg || this;
+
+ if (!ticking) {
+ ticking = true;
+ helpers$1.requestAnimFrame.call(window, function() {
+ ticking = false;
+ fn.apply(thisArg, args);
+ });
+ }
+ };
+}
+
+function createDiv(cls) {
+ var el = document.createElement('div');
+ el.className = cls || '';
+ return el;
+}
+
+// Implementation based on https://github.com/marcj/css-element-queries
+function createResizer(handler) {
+ var maxSize = 1000000;
+
+ // NOTE(SB) Don't use innerHTML because it could be considered unsafe.
+ // https://github.com/chartjs/Chart.js/issues/5902
+ var resizer = createDiv(CSS_SIZE_MONITOR);
+ var expand = createDiv(CSS_SIZE_MONITOR + '-expand');
+ var shrink = createDiv(CSS_SIZE_MONITOR + '-shrink');
+
+ expand.appendChild(createDiv());
+ shrink.appendChild(createDiv());
+
+ resizer.appendChild(expand);
+ resizer.appendChild(shrink);
+ resizer._reset = function() {
+ expand.scrollLeft = maxSize;
+ expand.scrollTop = maxSize;
+ shrink.scrollLeft = maxSize;
+ shrink.scrollTop = maxSize;
+ };
+
+ var onScroll = function() {
+ resizer._reset();
+ handler();
+ };
+
+ addListener(expand, 'scroll', onScroll.bind(expand, 'expand'));
+ addListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink'));
+
+ return resizer;
+}
+
+// https://davidwalsh.name/detect-node-insertion
+function watchForRender(node, handler) {
+ var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});
+ var proxy = expando.renderProxy = function(e) {
+ if (e.animationName === CSS_RENDER_ANIMATION) {
+ handler();
+ }
+ };
+
+ helpers$1.each(ANIMATION_START_EVENTS, function(type) {
+ addListener(node, type, proxy);
+ });
+
+ // #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class
+ // is removed then added back immediately (same animation frame?). Accessing the
+ // `offsetParent` property will force a reflow and re-evaluate the CSS animation.
+ // https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics
+ // https://github.com/chartjs/Chart.js/issues/4737
+ expando.reflow = !!node.offsetParent;
+
+ node.classList.add(CSS_RENDER_MONITOR);
+}
+
+function unwatchForRender(node) {
+ var expando = node[EXPANDO_KEY] || {};
+ var proxy = expando.renderProxy;
+
+ if (proxy) {
+ helpers$1.each(ANIMATION_START_EVENTS, function(type) {
+ removeListener(node, type, proxy);
+ });
+
+ delete expando.renderProxy;
+ }
+
+ node.classList.remove(CSS_RENDER_MONITOR);
+}
+
+function addResizeListener(node, listener, chart) {
+ var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});
+
+ // Let's keep track of this added resizer and thus avoid DOM query when removing it.
+ var resizer = expando.resizer = createResizer(throttled(function() {
+ if (expando.resizer) {
+ var container = chart.options.maintainAspectRatio && node.parentNode;
+ var w = container ? container.clientWidth : 0;
+ listener(createEvent('resize', chart));
+ if (container && container.clientWidth < w && chart.canvas) {
+ // If the container size shrank during chart resize, let's assume
+ // scrollbar appeared. So we resize again with the scrollbar visible -
+ // effectively making chart smaller and the scrollbar hidden again.
+ // Because we are inside `throttled`, and currently `ticking`, scroll
+ // events are ignored during this whole 2 resize process.
+ // If we assumed wrong and something else happened, we are resizing
+ // twice in a frame (potential performance issue)
+ listener(createEvent('resize', chart));
+ }
+ }
+ }));
+
+ // The resizer needs to be attached to the node parent, so we first need to be
+ // sure that `node` is attached to the DOM before injecting the resizer element.
+ watchForRender(node, function() {
+ if (expando.resizer) {
+ var container = node.parentNode;
+ if (container && container !== resizer.parentNode) {
+ container.insertBefore(resizer, container.firstChild);
+ }
+
+ // The container size might have changed, let's reset the resizer state.
+ resizer._reset();
+ }
+ });
+}
+
+function removeResizeListener(node) {
+ var expando = node[EXPANDO_KEY] || {};
+ var resizer = expando.resizer;
+
+ delete expando.resizer;
+ unwatchForRender(node);
+
+ if (resizer && resizer.parentNode) {
+ resizer.parentNode.removeChild(resizer);
+ }
+}
+
+/**
+ * Injects CSS styles inline if the styles are not already present.
+ * @param {HTMLDocument|ShadowRoot} rootNode - the node to contain the