';
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/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/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/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..ac4e5b030c1 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
@@ -1957,4 +1958,56 @@ 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)
+ {
+ 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 (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 bb876cb0533..d96fddca150 100644
--- a/htdocs/categories/index.php
+++ b/htdocs/categories/index.php
@@ -161,6 +161,15 @@ $cate_arbo = $categstatic->get_full_arbo($typetext);
// Define fulltree array
$fulltree = $cate_arbo;
+// Load possible missing includes
+if($conf->global->CATEGORY_SHOW_COUNTS)
+{
+ if ($type == Categorie::TYPE_MEMBER) require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
+ if ($type == Categorie::TYPE_ACCOUNT) require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
+ if ($type == Categorie::TYPE_PROJECT) require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
+ if ($type == Categorie::TYPE_USER) require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
+}
+
// Define data (format for treeview)
$data = array();
$data[] = array('rowid'=>0, 'fk_menu'=>-1, 'title'=>"racine", 'mainmenu'=>'', 'leftmenu'=>'', 'fk_mainmenu'=>'', 'fk_leftmenu'=>'');
@@ -173,10 +182,19 @@ 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
+ $elements = $categstatic->getObjectsInCateg($type, 1);
+ $counter = "".(is_countable($elements) ? count($elements) : '0')." ";
+ }
+
$data[] = array(
'rowid'=>$val['rowid'],
'fk_menu'=>$val['fk_parent'],
- 'entry'=>'color ? ' style="background: #'.$categstatic->color.';"' : ' style="background: #aaa"').'>'.$li.' '.
+ 'entry'=>'color ? ' style="background: #'.$categstatic->color.';"' : ' style="background: #aaa"').'>'.$li.' '.$counter.
//''.dolGetFirstLineOfText($desc).' '.
''.img_view().' '.
'
'
diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php
index 7f4156a6d15..5d81ccd7d63 100644
--- a/htdocs/categories/viewcat.php
+++ b/htdocs/categories/viewcat.php
@@ -144,6 +144,13 @@ if ($id > 0 && $removeelem > 0)
$result = $tmpobject->fetch($removeelem);
$elementtype = 'project';
}
+ elseif ($type == Categorie::TYPE_USER && $user->rights->user->user->creer)
+ {
+ require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
+ $tmpobject = new User($db);
+ $result = $tmpobject->fetch($removeelem);
+ $elementtype = 'user';
+ }
$result = $object->del_type($tmpobject, $elementtype);
if ($result < 0) dol_print_error('', $object->error);
@@ -207,7 +214,7 @@ elseif ($type == Categorie::TYPE_MEMBER) $title = $langs->trans("MembersCateg
elseif ($type == Categorie::TYPE_CONTACT) $title = $langs->trans("ContactCategoriesShort");
elseif ($type == Categorie::TYPE_ACCOUNT) $title = $langs->trans("AccountsCategoriesShort");
elseif ($type == Categorie::TYPE_PROJECT) $title = $langs->trans("ProjectsCategoriesShort");
-elseif ($type == Categorie::TYPE_USER) $title = $langs->trans("ProjectsCategoriesShort");
+elseif ($type == Categorie::TYPE_USER) $title = $langs->trans("UsersCategoriesShort");
else $title = $langs->trans("Category");
$head = categories_prepare_head($object, $type);
@@ -834,6 +841,53 @@ if ($type == Categorie::TYPE_PROJECT)
}
}
+// List of users
+if ($type == Categorie::TYPE_USER)
+{
+ require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
+
+ $users = $object->getObjectsInCateg("user");
+ if ($users < 0)
+ {
+ dol_print_error($db, $object->error, $object->errors);
+ }
+ else
+ {
+ print " ";
+ print "\n";
+ }
+}
+
// End of page
llxFooter();
$db->close();
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/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php
index f75244dcf7d..5a9c5277ccd 100644
--- a/htdocs/comm/action/class/actioncomm.class.php
+++ b/htdocs/comm/action/class/actioncomm.class.php
@@ -455,6 +455,7 @@ class ActionComm extends CommonObject
$sql .= "durationp,"; // deprecated
$sql .= "fk_action,";
$sql .= "code,";
+ $sql .= "ref_ext,";
$sql .= "fk_soc,";
$sql .= "fk_project,";
$sql .= "note,";
@@ -484,6 +485,7 @@ class ActionComm extends CommonObject
$sql .= ((isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '') ? "'".$this->db->escape($this->durationp)."'" : "null").", "; // deprecated
$sql .= (isset($this->type_id) ? $this->type_id : "null").",";
$sql .= ($code ? ("'".$code."'") : "null").", ";
+ $sql .= ($this->ref_ext ? ("'".$this->db->idate($this->ref_ext)."'") : "null").", ";
$sql .= ((isset($this->socid) && $this->socid > 0) ? $this->socid : "null").", ";
$sql .= ((isset($this->fk_project) && $this->fk_project > 0) ? $this->fk_project : "null").", ";
$sql .= " '".$this->db->escape($this->note_private ? $this->note_private : $this->note)."', ";
diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php
index 3ac82178810..895136f82f0 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);
@@ -100,12 +100,12 @@ $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/peruser.php b/htdocs/comm/action/peruser.php
index 947d0a9d2f8..f906c4cab45 100644
--- a/htdocs/comm/action/peruser.php
+++ b/htdocs/comm/action/peruser.php
@@ -49,10 +49,10 @@ $usergroup = GETPOST("search_usergroup", "int", 3) ?GETPOST("search_usergroup",
$showbirthday = 0;
// If not choice done on calendar owner, we filter on user.
-if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS))
+/*if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS))
{
$filtert = $user->id;
-}
+}*/
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php
index b5164d6078c..14929faf2ba 100644
--- a/htdocs/comm/card.php
+++ b/htdocs/comm/card.php
@@ -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)
{
@@ -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)
{
@@ -967,7 +967,7 @@ if ($object->id > 0)
}
/*
- * Last interventions
+ * Latest interventions
*/
if (!empty($conf->ficheinter->enabled) && $user->rights->ficheinter->lire)
{
@@ -1028,7 +1028,7 @@ if ($object->id > 0)
}
/*
- * Last invoices templates
+ * Latest invoices templates
*/
if (!empty($conf->facture->enabled) && $user->rights->facture->lire)
{
@@ -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/index.php b/htdocs/comm/index.php
index 111b411549e..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.mise_en_service as datemes, 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 94e885d53dc..b85826339e5 100644
--- a/htdocs/comm/mailing/advtargetemailing.php
+++ b/htdocs/comm/mailing/advtargetemailing.php
@@ -423,24 +423,24 @@ if ($object->fetch($id) >= 0) {
$linkback = ''.$langs->trans("BackToList").' ';
- print ' '.$langs->trans("Ref").' ';
+ print ''.$langs->trans("Ref").' ';
print '';
print $form->showrefnav($object, 'id', $linkback);
print ' ';
- print ''.$langs->trans("MailTitle").' '.$object->titre.' ';
+ print ''.$langs->trans("MailTitle").' '.$object->titre.' ';
- print ''.$langs->trans("MailFrom").' '.dol_print_email($object->email_from, 0, 0, 0, 0, 1).' ';
+ print ''.$langs->trans("MailFrom").' '.dol_print_email($object->email_from, 0, 0, 0, 0, 1).' ';
// Errors to
- print ''.$langs->trans("MailErrorsTo").' '.dol_print_email($object->email_errorsto, 0, 0, 0, 0, 1);
+ print ' '.$langs->trans("MailErrorsTo").' '.dol_print_email($object->email_errorsto, 0, 0, 0, 0, 1);
print ' ';
// Status
- print ''.$langs->trans("Status").' '.$object->getLibStatut(4).' ';
+ print ''.$langs->trans("Status").' '.$object->getLibStatut(4).' ';
// Nb of distinct emails
- print '';
+ print ' ';
print $langs->trans("TotalNbOfDistinctRecipients");
print ' ';
$nbemail = ($object->nbemail ? $object->nbemail : '0');
diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php
index 3dcfdf9e451..41e49ed09b3 100644
--- a/htdocs/comm/mailing/cibles.php
+++ b/htdocs/comm/mailing/cibles.php
@@ -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/advtargetemailing.class.php b/htdocs/comm/mailing/class/advtargetemailing.class.php
index 0b47d8c4aa5..da1775955b7 100644
--- a/htdocs/comm/mailing/class/advtargetemailing.class.php
+++ b/htdocs/comm/mailing/class/advtargetemailing.class.php
@@ -141,7 +141,7 @@ class AdvanceTargetingMailing extends CommonObject
$sql .= " ".(!isset($this->filtervalue) ? 'NULL' : "'".$this->db->escape($this->filtervalue)."'").",";
$sql .= " ".$user->id.",";
$sql .= " '".$this->db->idate(dol_now())."',";
- $sql .= " null";
+ $sql.= " ".$user->id;
$sql .= ")";
$this->db->begin();
diff --git a/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php b/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php
index 08736a3d268..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)
{
@@ -418,9 +416,10 @@ class FormAdvTargetEmailing extends Form
* @param integer $selected defaut selected
* @param integer $showempty empty lines
* @param string $type_element Type element. Example: 'mailing'
+ * @param string $morecss More CSS
* @return string HTML combo
*/
- public function selectAdvtargetemailingTemplate($htmlname = 'template_id', $selected = 0, $showempty = 0, $type_element = 'mailing')
+ public function selectAdvtargetemailingTemplate($htmlname = 'template_id', $selected = 0, $showempty = 0, $type_element = 'mailing', $morecss = '')
{
global $conf, $user, $langs;
@@ -431,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/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php
index 1337c62da94..9326082b193 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,11 +65,65 @@ class Proposals extends DolibarrApi
*/
public function get($id, $contact_list = 1)
{
+ 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);
+ $result = $this->propal->fetch($id, $ref, $ref_ext);
if( ! $result ) {
throw new RestException(404, 'Commercial Proposal not found');
}
@@ -377,8 +432,9 @@ 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)
{
@@ -417,8 +473,9 @@ 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)
{
@@ -458,9 +515,10 @@ 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)
{
@@ -629,10 +687,10 @@ 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
*/
diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php
index 32c3d67a18b..bea546eeae8 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
*/
@@ -1365,15 +1449,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 +1521,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 +1595,7 @@ class Propal extends CommonObject
$this->lines = array();
- /*
- * Lines
- */
+ // Lines
$result = $this->fetch_lines();
if ($result < 0)
{
@@ -1801,7 +1888,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)."',";
@@ -3549,10 +3636,10 @@ class Propal extends CommonObject
* @param string $get_params Parametres added to url
* @param int $notooltip 1=Disable tooltip
* @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
- * @param int $addlinktonotes Add linkt to notes
+ * @param int $addlinktonotes -1=Disable, 0=Just add label show notes, 1=Add private note (only internal user), 2=Add public note (internal or external user), 3=Add private (internal user) and public note (internal and external user)
* @return string String with URL
*/
- public function getNomUrl($withpicto = 0, $option = '', $get_params = '', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0)
+ public function getNomUrl($withpicto = 0, $option = '', $get_params = '', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1)
{
global $langs, $conf, $user;
@@ -3618,21 +3705,45 @@ class Propal extends CommonObject
if ($withpicto != 2) $result .= $this->ref;
$result .= $linkend;
- if ($addlinktonotes)
- {
- $txttoshow = ($user->socid > 0 ? $this->note_public : $this->note_private);
- if ($txttoshow)
- {
- $notetoshow = $langs->trans("ViewPrivateNote").': '.dol_string_nohtmltag($txttoshow, 1);
- $result .= ' ';
- $result .= '';
- $result .= img_picto('', 'note');
- $result .= ' ';
- //$result.=img_picto($langs->trans("ViewNote"),'object_generic');
- //$result.='';
- $result .= ' ';
- }
- }
+ if ($addlinktonotes >= 0) {
+ $txttoshow = '';
+
+ if ($addlinktonotes == 0) {
+ if (!empty($this->note_private) || !empty($this->note_public)) {
+ $txttoshow = $langs->trans('ViewPrivateNote');
+ }
+ } elseif ($addlinktonotes == 1) {
+ if (!empty($this->note_private)) {
+ $txttoshow .= ($user->socid > 0 ? '' : dol_string_nohtmltag($this->note_private, 1));
+ }
+ } elseif ($addlinktonotes == 2) {
+ if (!empty($this->note_public)) {
+ $txttoshow .= dol_string_nohtmltag($this->note_public, 1);
+ }
+ } elseif ($addlinktonotes == 3) {
+ if ($user->socid > 0) {
+ if (!empty($this->note_public)) {
+ $txttoshow .= dol_string_nohtmltag($this->note_public, 1);
+ }
+ } else {
+ if (!empty($this->note_public)) {
+ $txttoshow .= dol_string_nohtmltag($this->note_public, 1);
+ }
+ if (!empty($this->note_private)) {
+ if (!empty($txttoshow)) $txttoshow .= ' ';
+ $txttoshow .= dol_string_nohtmltag($this->note_private, 1);
+ }
+ }
+ }
+
+ if ($txttoshow) {
+ $result .= ' ';
+ $result .= '';
+ $result .= img_picto('', 'note');
+ $result .= ' ';
+ $result .= ' ';
+ }
+ }
return $result;
}
diff --git a/htdocs/comm/propal/class/propalestats.class.php b/htdocs/comm/propal/class/propalestats.class.php
index 0859bdb7974..ee42ca26471 100644
--- a/htdocs/comm/propal/class/propalestats.class.php
+++ b/htdocs/comm/propal/class/propalestats.class.php
@@ -210,10 +210,11 @@ 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;
@@ -227,6 +228,6 @@ class PropaleStats extends Stats
$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/index.php b/htdocs/comm/propal/index.php
index 11bb4292036..11a9fa8eff6 100644
--- a/htdocs/comm/propal/index.php
+++ b/htdocs/comm/propal/index.php
@@ -141,10 +141,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('idgraphthirdparties');
print $dolgraph->show($total ? 0 : 1);
diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php
index 13ab3a1ae17..365308a224b 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');
@@ -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,6 +858,7 @@ if ($resql)
$objectstatic->id = $obj->rowid;
$objectstatic->ref = $obj->ref;
+ $objectstatic->ref_client = $obj->ref_client;
$objectstatic->note_public = $obj->note_public;
$objectstatic->note_private = $obj->note_private;
@@ -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']))
@@ -798,7 +904,7 @@ if ($resql)
print '';
// Picto + Ref
print '';
- print $objectstatic->getNomUrl(1, '', '', 0, 1, 1);
+ print $objectstatic->getNomUrl(1, '', '', 0, 1, (isset($conf->global->PROPAL_LIST_SHOW_NOTES) ? $conf->global->PROPAL_LIST_SHOW_NOTES : 1));
print ' ';
// Warning
$warnornote = '';
@@ -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..37193726b01 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,8 +31,10 @@ 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'));
@@ -49,6 +52,11 @@ $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
@@ -138,9 +146,9 @@ 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();
@@ -151,14 +159,26 @@ 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;
+$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);
@@ -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();
diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php
index 9ae1d5d7d83..a16927bda0b 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');
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/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php
index 4c60434619a..8e83e6a33a4 100644
--- a/htdocs/compta/cashcontrol/cashcontrol_card.php
+++ b/htdocs/compta/cashcontrol/cashcontrol_card.php
@@ -345,7 +345,8 @@ if ($action == "create" || $action == "start")
print '';
$array = array();
- for($i = 1; $i <= max(1, $conf->global->TAKEPOS_NUM_TERMINALS); $i++) {
+ $numterminals = max(1, $conf->global->TAKEPOS_NUM_TERMINALS);
+ for($i = 1; $i <= $numterminals; $i++) {
$array[$i] = $i;
}
$selectedposnumber = 0; $showempty = 1;
diff --git a/htdocs/compta/deplacement/index.php b/htdocs/compta/deplacement/index.php
index fde600aff8f..ea180a6b0ee 100644
--- a/htdocs/compta/deplacement/index.php
+++ b/htdocs/compta/deplacement/index.php
@@ -115,10 +115,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($totalnb?0:1);
diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index 0d124c34f32..8510f1caa16 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') {
@@ -138,6 +141,7 @@ $result = restrictedArea($user, 'facture', $id, '', '', 'fk_soc', $fieldid, $isd
+
/*
* Actions
*/
@@ -293,31 +297,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();
- 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;
+ $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_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 +798,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();
@@ -1386,12 +1391,12 @@ if (empty($reshook))
dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines or deposit lines");
$result = $srcobject->fetch($object->origin_id);
- // If deposit invoice
- if ($_POST['type'] == Facture::TYPE_DEPOSIT)
- {
- $typeamount = GETPOST('typedeposit', 'alpha');
- $valuedeposit = GETPOST('valuedeposit', 'int');
+ $typeamount = GETPOST('typedeposit', 'aZ09');
+ $valuedeposit = GETPOST('valuedeposit', 'int');
+ // If deposit invoice
+ if ($_POST['type'] == Facture::TYPE_DEPOSIT && in_array($typeamount, array('amount', 'variable')))
+ {
$amountdeposit = array();
if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA))
{
@@ -1419,7 +1424,7 @@ if (empty($reshook))
{
$amountdeposit[0] = $valuedeposit;
}
- else
+ elseif ($typeamount == 'variable')
{
if ($result > 0)
{
@@ -1449,11 +1454,15 @@ if (empty($reshook))
$amount_ttc_diff = $amountdeposit[0];
}
+
foreach ($amountdeposit as $tva => $amount)
{
if (empty($amount)) continue;
- $arraylist = array('amount' => 'FixAmount', 'variable' => 'VarAmount');
+ $arraylist = array(
+ 'amount' => 'FixAmount',
+ 'variable' => 'VarAmount'
+ );
$descline = '(DEPOSIT)';
//$descline.= ' - '.$langs->trans($arraylist[$typeamount]);
if ($typeamount == 'amount') {
@@ -1500,7 +1509,8 @@ if (empty($reshook))
$object->updateline($object->lines[0]->id, $object->lines[0]->desc, $subprice_diff, $object->lines[0]->qty, $object->lines[0]->remise_percent, $object->lines[0]->date_start, $object->lines[0]->date_end, $object->lines[0]->tva_tx, 0, 0, 'HT', $object->lines[0]->info_bits, $object->lines[0]->product_type, 0, 0, 0, $object->lines[0]->pa_ht, $object->lines[0]->label, 0, array(), 100);
}
}
- else
+
+ if ($_POST['type'] != Facture::TYPE_DEPOSIT || ($_POST['type'] == Facture::TYPE_DEPOSIT && $typeamount == 'variablealllines'))
{
if ($result > 0)
{
@@ -1511,6 +1521,16 @@ if (empty($reshook))
$lines = $srcobject->lines;
}
+ // 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) {
+ // We keep ->subprice and ->pa_ht, but we change the qty
+ $line->qty = price2num($line->qty * $valuedeposit / 100, 'MS');
+ }
+ }
+ }
+
$fk_parent_line = 0;
$num = count($lines);
for ($i = 0; $i < $num; $i++)
@@ -2994,8 +3014,12 @@ if ($action == 'create')
if (($origin == 'propal') || ($origin == 'commande'))
{
print ' ';
- $arraylist = array('amount' => $langs->transnoentitiesnoconv('FixAmount', $langs->transnoentitiesnoconv('Deposit')), 'variable' => $langs->transnoentitiesnoconv('VarAmountOneLine', $langs->transnoentitiesnoconv('Deposit')));
- print $form->selectarray('typedeposit', $arraylist, GETPOST('typedeposit'), 0, 0, 0, '', 1);
+ $arraylist = array(
+ 'amount' => $langs->transnoentitiesnoconv('FixAmount', $langs->transnoentitiesnoconv('Deposit')),
+ 'variable' => $langs->transnoentitiesnoconv('VarAmountOneLine', $langs->transnoentitiesnoconv('Deposit')),
+ 'variablealllines' => $langs->transnoentitiesnoconv('VarAmountAllLines')
+ );
+ print $form->selectarray('typedeposit', $arraylist, GETPOST('typedeposit', 'aZ09'), 0, 0, 0, '', 1);
print ' ';
print ''.$langs->trans('Value').': ';
}
@@ -3332,8 +3356,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').' ';
@@ -3621,7 +3645,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)));
@@ -4498,7 +4522,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;
@@ -4509,7 +4533,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 ' ';
}
}
@@ -5074,9 +5098,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)
{
@@ -5089,13 +5113,13 @@ 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
- && (!empty($conf->global->INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED) || $object->getSommePaiement() == 0)
+ 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').' ';
}
@@ -5107,7 +5131,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))
)
{
@@ -5116,7 +5140,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-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php
index 8a25ee42745..fdffc320880 100644
--- a/htdocs/compta/facture/class/facture-rec.class.php
+++ b/htdocs/compta/facture/class/facture-rec.class.php
@@ -128,8 +128,8 @@ class FactureRec extends CommonInvoice
'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>30),
//'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35),
'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>40),
- 'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>45),
- 'remise_absolue' =>array('type'=>'double', 'label'=>'Remise absolue', 'enabled'=>1, 'visible'=>-1, 'position'=>50),
+ //'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>45),
+ //'remise_absolue' =>array('type'=>'double', 'label'=>'Remise absolue', 'enabled'=>1, 'visible'=>-1, 'position'=>50),
'tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>55, 'isameasure'=>1),
'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'isameasure'=>1),
'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>65, 'isameasure'=>1),
@@ -150,20 +150,19 @@ class FactureRec extends CommonInvoice
'nb_gen_done' =>array('type'=>'integer', 'label'=>'Nb gen done', 'enabled'=>1, 'visible'=>-1, 'position'=>140),
'nb_gen_max' =>array('type'=>'integer', 'label'=>'Nb gen max', 'enabled'=>1, 'visible'=>-1, 'position'=>145),
'frequency' =>array('type'=>'integer', 'label'=>'Frequency', 'enabled'=>1, 'visible'=>-1, 'position'=>150),
- 'usenewprice' =>array('type'=>'integer', 'label'=>'Usenewprice', 'enabled'=>1, 'visible'=>-1, 'position'=>155),
- 'revenuestamp' =>array('type'=>'double(24,8)', 'label'=>'Revenuestamp', 'enabled'=>1, 'visible'=>-1, 'position'=>160),
+ 'usenewprice' =>array('type'=>'integer', 'label'=>'UseNewPrice', 'enabled'=>1, 'visible'=>0, 'position'=>155),
+ 'revenuestamp' =>array('type'=>'double(24,8)', 'label'=>'RevenueStamp', 'enabled'=>1, 'visible'=>-1, 'position'=>160, 'isameasure'=>1),
'auto_validate' =>array('type'=>'integer', 'label'=>'Auto validate', 'enabled'=>1, 'visible'=>-1, 'position'=>165),
'generate_pdf' =>array('type'=>'integer', 'label'=>'Generate pdf', 'enabled'=>1, 'visible'=>-1, 'position'=>170),
'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>1, 'visible'=>-1, 'position'=>175),
'fk_multicurrency' =>array('type'=>'integer', 'label'=>'Fk multicurrency', 'enabled'=>1, 'visible'=>-1, 'position'=>180),
'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'Multicurrency code', 'enabled'=>1, 'visible'=>-1, 'position'=>185),
- 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency tx', 'enabled'=>1, 'visible'=>-1, 'position'=>190),
- 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ht', 'enabled'=>1, 'visible'=>-1, 'position'=>195),
- 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total tva', 'enabled'=>1, 'visible'=>-1, 'position'=>200),
- 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ttc', 'enabled'=>1, 'visible'=>-1, 'position'=>205),
+ 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency tx', 'enabled'=>1, 'visible'=>-1, 'position'=>190, 'isameasure'=>1),
+ 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ht', 'enabled'=>1, 'visible'=>-1, 'position'=>195, 'isameasure'=>1),
+ 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total tva', 'enabled'=>1, 'visible'=>-1, 'position'=>200, 'isameasure'=>1),
+ 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ttc', 'enabled'=>1, 'visible'=>-1, 'position'=>205, 'isameasure'=>1),
'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>210),
'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>215),
- 'vat_src_code' =>array('type'=>'varchar(10)', 'label'=>'Vat src code', 'enabled'=>1, 'visible'=>-1, 'position'=>220),
'suspended' =>array('type'=>'integer', 'label'=>'Suspended', 'enabled'=>1, 'visible'=>-1, 'position'=>225),
);
// END MODULEBUILDER PROPERTIES
@@ -1676,7 +1675,7 @@ class FactureRec extends CommonInvoice
$xnbp++;
}
- $this->usenewprice = 1;
+ $this->usenewprice = 0;
}
/**
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index a9a1e286d1e..b9e80ca1cf8 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),
'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),
@@ -293,7 +298,6 @@ class Facture extends CommonInvoice
'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>205),
'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>210),
'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>215),
- 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>220),
'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>225),
'situation_cycle_ref' =>array('type'=>'smallint(6)', 'label'=>'Situation cycle ref', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION', 'visible'=>-1, 'position'=>230),
'situation_counter' =>array('type'=>'smallint(6)', 'label'=>'Situation counter', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION', 'visible'=>-1, 'position'=>235),
@@ -301,19 +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),
+ '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;
@@ -1253,6 +1259,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 +1281,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 +1403,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 +1454,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 +1499,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 +1532,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 +1552,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 +1597,7 @@ class Facture extends CommonInvoice
// fetch optionals attributes and labels
$this->fetch_optionals();
- /*
- * Lines
- */
-
+ // Lines
$this->lines = array();
$result = $this->fetch_lines();
@@ -2408,12 +2428,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 +2536,7 @@ class Facture extends CommonInvoice
{
$num = $this->ref;
}
- $this->newref = $num;
+ $this->newref = dol_sanitizeFileName($num);
if ($num)
{
@@ -2555,11 +2586,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;
+ }
+ }
}
}
}
@@ -4102,7 +4216,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 +4692,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 +4769,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..730df6ee6e4 100644
--- a/htdocs/compta/facture/class/facturestats.class.php
+++ b/htdocs/compta/facture/class/facturestats.class.php
@@ -205,10 +205,11 @@ 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;
@@ -222,6 +223,6 @@ class FactureStats extends Stats
$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/invoicetemplate_list.php b/htdocs/compta/facture/invoicetemplate_list.php
index 370bfe9a8b9..b55f0c412b9 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');
@@ -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..82f92085abf 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');
@@ -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..3853847c363 100644
--- a/htdocs/compta/paiement.php
+++ b/htdocs/compta/paiement.php
@@ -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/card.php b/htdocs/compta/paiement/card.php
index edc76de0698..887fe2ec570 100644
--- a/htdocs/compta/paiement/card.php
+++ b/htdocs/compta/paiement/card.php
@@ -222,7 +222,7 @@ print ' ';
// Payment type (VIR, LIQ, ...)
$labeltype = $langs->trans("PaymentType".$object->type_code) != ("PaymentType".$object->type_code) ? $langs->trans("PaymentType".$object->type_code) : $object->type_label;
print ''.$langs->trans('PaymentMode').' '.$labeltype;
-print $object->num_paiement ? ' - '.$object->num_paiement : '';
+print $object->num_payment? ' - '.$object->num_payment : '';
print ' ';
// Amount
@@ -297,7 +297,7 @@ if (!empty($conf->banque->enabled))
print '';
print ''.$langs->trans('BankTransactionLine').' ';
print '';
- print $bankline->getNomUrl(1, 0, 'showconciliated');
+ print $bankline->getNomUrl(1, 0, 'showconciliatedandaccounted');
print ' ';
print ' ';
}
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/resultat/clientfourn.php b/htdocs/compta/resultat/clientfourn.php
index ee76a29d282..93afa054f71 100644
--- a/htdocs/compta/resultat/clientfourn.php
+++ b/htdocs/compta/resultat/clientfourn.php
@@ -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/list.php b/htdocs/compta/sociales/list.php
index d259fb362fd..54cfcfc37cd 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,6 +54,8 @@ $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');
@@ -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/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 174da6b5869..86fb598fb8b 100644
--- a/htdocs/compta/tva/card.php
+++ b/htdocs/compta/tva/card.php
@@ -38,6 +38,10 @@ $action=GETPOST("action", "alpha");
$refund=GETPOST("refund", "int");
if (empty($refund)) $refund=0;
+$datev=dol_mktime(12, 0, 0, GETPOST("datevmonth", 'int'), GETPOST("datevday", 'int'), GETPOST("datevyear", 'int'));
+$datep=dol_mktime(12, 0, 0, GETPOST("datepmonth", 'int'), GETPOST("datepday", 'int'), GETPOST("datepyear", 'int'));
+
+
// Security check
$socid = GETPOST('socid', 'int');
if ($user->socid) $socid=$user->socid;
@@ -70,7 +74,7 @@ if ($action == 'setlib' && $user->rights->tax->charges->creer)
if ($action == 'setdatev' && $user->rights->tax->charges->creer)
{
$object->fetch($id);
- $object->datev=dol_mktime(12, 0, 0, GETPOST('datevmonth', 'int'), GETPOST('datevday', 'int'), GETPOST('datevyear', 'int'));
+ $object->datev = $datev;
$result=$object->update($user);
if ($result < 0) dol_print_error($db, $object->error);
@@ -81,14 +85,12 @@ if ($action == 'add' && $_POST["cancel"] <> $langs->trans("Cancel"))
{
$error=0;
- $datev=dol_mktime(12, 0, 0, $_POST["datevmonth"], $_POST["datevday"], $_POST["datevyear"]);
- $datep=dol_mktime(12, 0, 0, $_POST["datepmonth"], $_POST["datepday"], $_POST["datepyear"]);
+ $object->accountid = GETPOST("accountid", 'int');
+ $object->type_payment = GETPOST("type_payment", 'alphanohtml');
+ $object->num_payment = GETPOST("num_payment", 'alphanohtml');
- $object->accountid=GETPOST("accountid");
- $object->type_payment=GETPOST("type_payment");
- $object->num_payment=GETPOST("num_payment");
- $object->datev=$datev;
- $object->datep=$datep;
+ $object->datev = $datev;
+ $object->datep = $datep;
$amount = price2num(GETPOST("amount", 'alpha'));
if ($refund == 1) {
@@ -277,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..2f15044f808 100644
--- a/htdocs/compta/tva/document.php
+++ b/htdocs/compta/tva/document.php
@@ -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/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 f56d03ceeb3..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),
@@ -86,9 +86,9 @@ class Contact extends CommonObject
'phone_mobile' =>array('type'=>'varchar(30)', 'label'=>'Phone mobile', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
'fax' =>array('type'=>'varchar(30)', 'label'=>'Fax', 'enabled'=>1, 'visible'=>-1, 'position'=>105),
'email' =>array('type'=>'varchar(255)', 'label'=>'Email', 'enabled'=>1, 'visible'=>-1, 'position'=>110),
- 'socialnetworks' =>array('type'=>'text', 'label'=>'Socialnetworks', 'enabled'=>1, 'visible'=>-1, 'position'=>115),
+ 'socialnetworks' =>array('type'=>'text', 'label'=>'SocialNetworks', 'enabled'=>1, 'visible'=>-1, 'position'=>115),
'photo' =>array('type'=>'varchar(255)', 'label'=>'Photo', 'enabled'=>1, 'visible'=>-1, 'position'=>170),
- 'priv' =>array('type'=>'smallint(6)', 'label'=>'Priv', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>175),
+ 'priv' =>array('type'=>'smallint(6)', 'label'=>'Private', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>175),
'no_email' =>array('type'=>'smallint(6)', 'label'=>'No email', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>180),
'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>185),
'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-1, 'position'=>190),
@@ -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;
@@ -992,19 +1002,25 @@ class Contact extends CommonObject
}
+
/**
- * Set property ->gender from property ->civility_id
+ * Set the property "gender" of this class, based on the property "civility_id"
+ * or use property "civility_code" as fallback, when "civility_id" is not available.
*
* @return void
*/
public function setGenderFromCivility()
{
- unset($this->gender);
- if (in_array($this->civility_id, array('MR'))) {
- $this->gender = 'man';
- } elseif (in_array($this->civility_id, array('MME', 'MLE'))) {
- $this->gender = 'woman';
- }
+ unset($this->gender);
+
+ if (in_array($this->civility_id, array('MR')) || in_array($this->civility_code, array('MR')))
+ {
+ $this->gender = 'man';
+ }
+ elseif (in_array($this->civility_id, array('MME', 'MLE')) || in_array($this->civility_code, array('MME', 'MLE')))
+ {
+ $this->gender = 'woman';
+ }
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
@@ -1270,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;
@@ -1574,7 +1597,7 @@ class Contact extends CommonObject
}
/**
- * Fetch Role for a contact
+ * Fetch Roles for a contact
*
* @return float|int
* @throws Exception
@@ -1586,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);
@@ -1630,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";
@@ -1638,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)
{
@@ -1678,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;
@@ -1698,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/list.php b/htdocs/contact/list.php
index 1d0c3839f4f..9903e37cd5e 100644
--- a/htdocs/contact/list.php
+++ b/htdocs/contact/list.php
@@ -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/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 ecf12e11484..0aee2ed876d 100644
--- a/htdocs/contrat/class/contrat.class.php
+++ b/htdocs/contrat/class/contrat.class.php
@@ -165,12 +165,6 @@ class Contrat extends CommonObject
*/
public $date_contrat;
- /**
- * @var integer|string Date of contract closure
- * @deprecated we close contract lines, not a contract
- */
- public $date_cloture;
-
public $commercial_signature_id;
public $commercial_suivi_id;
@@ -231,17 +225,11 @@ 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')),
- 'mise_en_service' =>array('type'=>'datetime', 'label'=>'Mise en service', 'enabled'=>1, 'visible'=>-1, 'position'=>55),
- 'fin_validite' =>array('type'=>'datetime', 'label'=>'Fin validite', 'enabled'=>1, 'visible'=>-1, 'position'=>60),
- 'date_cloture' =>array('type'=>'datetime', 'label'=>'Date cloture', 'enabled'=>1, 'visible'=>-1, 'position'=>65),
'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),
'fk_commercial_suivi' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk commercial suivi', 'enabled'=>1, 'visible'=>-1, 'position'=>85),
'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>90),
- 'fk_user_mise_en_service' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user mise en service', 'enabled'=>1, 'visible'=>-1, 'position'=>95),
- 'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user cloture', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>105),
'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>110),
'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>115),
@@ -250,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
@@ -528,7 +517,7 @@ class Contrat extends CommonObject
{
$num = $this->ref;
}
- $this->newref = $num;
+ $this->newref = dol_sanitizeFileName($num);
if ($num)
{
@@ -696,12 +685,12 @@ class Contrat extends CommonObject
*/
public function fetch($id, $ref = '', $ref_customer = '', $ref_supplier = '')
{
- $sql = "SELECT rowid, statut, ref, fk_soc, mise_en_service as datemise,";
+ $sql = "SELECT rowid, statut, ref, fk_soc,";
$sql .= " ref_supplier, ref_customer,";
$sql .= " ref_ext,";
$sql .= " entity,";
- $sql .= " fk_user_mise_en_service, date_contrat as datecontrat,";
- $sql .= " fk_user_author, fin_validite, date_cloture,";
+ $sql .= " date_contrat as datecontrat,";
+ $sql .= " fk_user_author,";
$sql .= " fk_projet as fk_project,";
$sql .= " fk_commercial_signature, fk_commercial_suivi,";
$sql .= " note_private, note_public, model_pdf, extraparams";
@@ -744,15 +733,10 @@ class Contrat extends CommonObject
$this->ref_ext = $obj->ref_ext;
$this->entity = $obj->entity;
$this->statut = $obj->statut;
- $this->mise_en_service = $this->db->jdate($obj->datemise);
$this->date_contrat = $this->db->jdate($obj->datecontrat);
$this->date_creation = $this->db->jdate($obj->datecontrat);
- $this->fin_validite = $this->db->jdate($obj->fin_validite);
- $this->date_cloture = $this->db->jdate($obj->date_cloture);
-
-
$this->user_author_id = $obj->fk_user_author;
$this->commercial_signature_id = $obj->fk_commercial_signature;
@@ -1367,8 +1351,6 @@ class Contrat extends CommonObject
if (isset($this->fk_soc)) $this->fk_soc = (int) $this->fk_soc;
if (isset($this->fk_commercial_signature)) $this->fk_commercial_signature = trim($this->fk_commercial_signature);
if (isset($this->fk_commercial_suivi)) $this->fk_commercial_suivi = trim($this->fk_commercial_suivi);
- if (isset($this->fk_user_mise_en_service)) $this->fk_user_mise_en_service = (int) $this->fk_user_mise_en_service;
- if (isset($this->fk_user_cloture)) $this->fk_user_cloture = (int) $this->fk_user_cloture;
if (isset($this->note_private)) $this->note_private = trim($this->note_private);
if (isset($this->note_public)) $this->note_public = trim($this->note_public);
if (isset($this->import_key)) $this->import_key = trim($this->import_key);
@@ -1386,15 +1368,10 @@ class Contrat extends CommonObject
$sql .= " entity=".$conf->entity.",";
$sql .= " date_contrat=".(dol_strlen($this->date_contrat) != 0 ? "'".$this->db->idate($this->date_contrat)."'" : 'null').",";
$sql .= " statut=".(isset($this->statut) ? $this->statut : "null").",";
- $sql .= " mise_en_service=".(dol_strlen($this->mise_en_service) != 0 ? "'".$this->db->idate($this->mise_en_service)."'" : 'null').",";
- $sql .= " fin_validite=".(dol_strlen($this->fin_validite) != 0 ? "'".$this->db->idate($this->fin_validite)."'" : 'null').",";
- $sql .= " date_cloture=".(dol_strlen($this->date_cloture) != 0 ? "'".$this->db->idate($this->date_cloture)."'" : 'null').",";
$sql .= " fk_soc=".($this->fk_soc > 0 ? $this->fk_soc : "null").",";
$sql .= " fk_projet=".($this->fk_project > 0 ? $this->fk_project : "null").",";
$sql .= " fk_commercial_signature=".(isset($this->fk_commercial_signature) ? $this->fk_commercial_signature : "null").",";
$sql .= " fk_commercial_suivi=".(isset($this->fk_commercial_suivi) ? $this->fk_commercial_suivi : "null").",";
- $sql .= " fk_user_mise_en_service=".(isset($this->fk_user_mise_en_service) ? $this->fk_user_mise_en_service : "null").",";
- $sql .= " fk_user_cloture=".(isset($this->fk_user_cloture) ? $this->fk_user_cloture : "null").",";
$sql .= " note_private=".(isset($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : "null").",";
$sql .= " note_public=".(isset($this->note_public) ? "'".$this->db->escape($this->note_public)."'" : "null").",";
$sql .= " import_key=".(isset($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : "null")."";
@@ -2096,9 +2073,9 @@ class Contrat extends CommonObject
*/
public function info($id)
{
- $sql = "SELECT c.rowid, c.ref, c.datec, c.date_cloture,";
+ $sql = "SELECT c.rowid, c.ref, c.datec,";
$sql .= " c.tms as date_modification,";
- $sql .= " fk_user_author, fk_user_cloture";
+ $sql .= " fk_user_author";
$sql .= " FROM ".MAIN_DB_PREFIX."contrat as c";
$sql .= " WHERE c.rowid = ".$id;
@@ -2117,15 +2094,9 @@ class Contrat extends CommonObject
$this->user_creation = $cuser;
}
- if ($obj->fk_user_cloture) {
- $cuser = new User($this->db);
- $cuser->fetch($obj->fk_user_cloture);
- $this->user_cloture = $cuser;
- }
$this->ref = (!$obj->ref) ? $obj->rowid : $obj->ref;
$this->date_creation = $this->db->jdate($obj->datec);
$this->date_modification = $this->db->jdate($obj->date_modification);
- $this->date_cloture = $this->db->jdate($obj->date_cloture);
}
$this->db->free($result);
@@ -2783,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)
{
@@ -2796,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/index.php b/htdocs/contrat/index.php
index 6dd6fc56e17..614743bbc46 100644
--- a/htdocs/contrat/index.php
+++ b/htdocs/contrat/index.php
@@ -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..c32e45c1b42 100644
--- a/htdocs/contrat/list.php
+++ b/htdocs/contrat/list.php
@@ -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/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..5c8fc84a843 100644
--- a/htdocs/core/actions_extrafields.inc.php
+++ b/htdocs/core/actions_extrafields.inc.php
@@ -183,7 +183,8 @@ if ($action == 'add')
(GETPOST('entitycurrentorall', 'alpha')?0:''),
GETPOST('langfile', 'alpha'),
1,
- (GETPOST('totalizable', 'alpha')?1:0)
+ (GETPOST('totalizable', 'alpha')?1:0),
+ GETPOST('printable', 'alpha')
);
if ($result > 0)
{
@@ -352,7 +353,8 @@ if ($action == 'update')
(GETPOST('entitycurrentorall', 'alpha')?0:''),
GETPOST('langfile'),
1,
- (GETPOST('totalizable', 'alpha')?1:0)
+ (GETPOST('totalizable', 'alpha')?1:0),
+ GETPOST('printable', 'alpha')
);
if ($result > 0)
{
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/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..3447b76a2b7 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 68095eaec31..9fffc92963f 100644
--- a/htdocs/core/boxes/box_project.php
+++ b/htdocs/core/boxes/box_project.php
@@ -3,6 +3,7 @@
* Copyright (C) 2014 Marcos García
* Copyright (C) 2015 Frederic France
* Copyright (C) 2016 Juan José Menent
+ * 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
@@ -95,9 +96,10 @@ 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.fk_statut = 1"; // Only open projects
+ $sql.= " WHERE p.entity IN (".getEntity('project').")"; // Only current entity or severals if permission ok
+ $sql.= " AND p.fk_statut = 1"; // Only open projects
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 p.datec DESC";
@@ -115,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"',
@@ -150,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++;
}
@@ -164,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_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 e0a1fd35092..bba38bddb30 100644
--- a/htdocs/core/class/CMailFile.class.php
+++ b/htdocs/core/class/CMailFile.class.php
@@ -82,15 +82,15 @@ class CMailFile
public $headers;
public $message;
/**
- * @var array fullfilenames list
+ * @var array fullfilenames list (full path of filename on file system)
*/
public $filename_list = array();
/**
- * @var array mimetypes of files list
+ * @var array mimetypes of files list (List of MIME type of attached files)
*/
public $mimetype_list = array();
/**
- * @var array filenames list
+ * @var array filenames list (List of attached file name in message)
*/
public $mimefilename_list = array();
@@ -137,6 +137,16 @@ class CMailFile
{
global $conf, $dolibarr_main_data_root;
+ // Clean values of $mimefilename_list
+ if (is_array($mimefilename_list)) {
+ foreach($mimefilename_list as $key => $val) {
+ $mimefilename_list[$key] = dol_string_unaccent($mimefilename_list[$key]);
+ }
+ }
+
+ // 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;
@@ -156,7 +166,6 @@ class CMailFile
$this->mimetype_list = $mimetype_list;
$this->mimefilename_list = $mimefilename_list;
-
// Define this->sendmode
$this->sendmode = '';
if ($this->sendcontext == 'emailing' && !empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default')
@@ -198,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)
@@ -220,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.
@@ -261,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')
@@ -323,7 +329,13 @@ class CMailFile
$smtps = new SMTPs();
$smtps->setCharSet($conf->file->character_set_client);
- $smtps->setSubject($this->encodetorfc2822($subject));
+ // Encode subject if required.
+ $subjecttouse = $subject;
+ if (! ascii_check($subjecttouse)) {
+ $subjecttouse = $this->encodetorfc2822($subjecttouse);
+ }
+
+ $smtps->setSubject($subjecttouse);
$smtps->setTO($this->getValidAddress($to, 0, 1));
$smtps->setFrom($this->getValidAddress($from, 0, 1));
$smtps->setTrackId($trackid);
@@ -342,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');
@@ -669,8 +684,14 @@ class CMailFile
if (!empty($conf->global->MAIN_MAIL_DEBUG)) $this->dump_mail();
- if (!empty($additionnalparam)) $res = mail($dest, $this->encodetorfc2822($this->subject), $this->message, $this->headers, $additionnalparam);
- else $res = mail($dest, $this->encodetorfc2822($this->subject), $this->message, $this->headers);
+ // Encode subject if required.
+ $subjecttouse = $this->subject;
+ if (! ascii_check($subjecttouse)) {
+ $subjecttouse = $this->encodetorfc2822($subjecttouse);
+ }
+
+ if (!empty($additionnalparam)) $res = mail($dest, $subjecttouse, $this->message, $this->headers, $additionnalparam);
+ else $res = mail($dest, $subjecttouse, $this->message, $this->headers);
if (!$res)
{
diff --git a/htdocs/core/class/canvas.class.php b/htdocs/core/class/canvas.class.php
index cfdb09c527e..68f2e9b1ba8 100644
--- a/htdocs/core/class/canvas.class.php
+++ b/htdocs/core/class/canvas.class.php
@@ -176,6 +176,7 @@ class Canvas
global $db, $conf, $langs, $user, $canvas;
global $form, $formfile;
+ //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 9d08480246b..b0001a695b8 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
@@ -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),
@@ -603,21 +609,32 @@ 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, ";
- 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}"
@@ -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;
@@ -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 = '')
{
@@ -1092,11 +1112,293 @@ abstract class CommonDocGenerator
if (empty($columnText)) return;
$pdf->SetXY($this->getColumnContentXStart($colKey), $curY); // Set curent position
$colDef = $this->cols[$colKey];
- $pdf->writeHTMLCell($this->getColumnContentWidth($colKey), 2, $this->getColumnContentXStart($colKey), $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 39bdc678fc4..da30b714db0 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)
{
@@ -1766,19 +1795,22 @@ abstract class CommonObject
if ($user->socid > 0) $socid = $user->socid;
// this->ismultientitymanaged contains
- // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
- $alias = 's';
- if ($this->element == 'societe') $alias = 'te';
+ // 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
$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) && $this->ismultientitymanaged == 2) $sql .= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity
+ 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
+ }
elseif ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to socid
elseif ($this->restrictiononfksoc == 2 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON te.fk_soc = s.rowid"; // If we need to link to societe to limit select to socid
- if ($this->restrictiononfksoc && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc";
+ if ($this->restrictiononfksoc && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$aliastablesociete.".rowid = sc.fk_soc";
$sql .= " WHERE te.".$fieldid." < '".$this->db->escape($this->ref)."'"; // ->ref must always be defined (set to id if field does not exists)
if ($this->restrictiononfksoc == 1 && !$user->rights->societe->client->voir && !$socid) $sql .= " AND sc.fk_user = ".$user->id;
if ($this->restrictiononfksoc == 2 && !$user->rights->societe->client->voir && !$socid) $sql .= " AND (sc.fk_user = ".$user->id.' OR te.fk_soc IS NULL)';
@@ -1787,7 +1819,10 @@ abstract class CommonObject
if (!preg_match('/^\s*AND/i', $filter)) $sql .= " AND "; // For backward compatibility
$sql .= $filter;
}
- if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2) $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity
+ 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
+ }
elseif ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to socid
if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
@@ -1801,6 +1836,10 @@ abstract class CommonObject
$sql .= ' AND te.entity IN ('.getEntity($this->element).')';
}
}
+ if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged) && $this->element != 'societe') {
+ $tmparray = explode('@', $this->ismultientitymanaged);
+ $sql .= ' AND parenttable.entity IN ('.getEntity($tmparray[1]).')';
+ }
if ($this->restrictiononfksoc == 1 && $socid && $this->element != 'societe') $sql .= ' AND te.fk_soc = '.$socid;
if ($this->restrictiononfksoc == 2 && $socid && $this->element != 'societe') $sql .= ' AND (te.fk_soc = '.$socid.' OR te.fk_soc IS NULL)';
if ($this->restrictiononfksoc && $socid && $this->element == 'societe') $sql .= ' AND te.rowid = '.$socid;
@@ -1821,10 +1860,10 @@ abstract class CommonObject
if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
$sql .= ",".MAIN_DB_PREFIX."usergroup_user as ug";
}
- if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2) $sql .= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity
+ if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 'fk_soc@societe') $sql .= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity
elseif ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to socid
elseif ($this->restrictiononfksoc == 2 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON te.fk_soc = s.rowid"; // If we need to link to societe to limit select to socid
- if ($this->restrictiononfksoc && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc";
+ if ($this->restrictiononfksoc && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$aliastablesociete.".rowid = sc.fk_soc";
$sql .= " WHERE te.".$fieldid." > '".$this->db->escape($this->ref)."'"; // ->ref must always be defined (set to id if field does not exists)
if ($this->restrictiononfksoc == 1 && !$user->rights->societe->client->voir && !$socid) $sql .= " AND sc.fk_user = ".$user->id;
if ($this->restrictiononfksoc == 2 && !$user->rights->societe->client->voir && !$socid) $sql .= " AND (sc.fk_user = ".$user->id.' OR te.fk_soc IS NULL)';
@@ -1833,7 +1872,7 @@ abstract class CommonObject
if (!preg_match('/^\s*AND/i', $filter)) $sql .= " AND "; // For backward compatibility
$sql .= $filter;
}
- if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2) $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity
+ if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 'fk_soc@societe') $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity
elseif ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to socid
if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
@@ -3330,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);
@@ -3352,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))
@@ -4734,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;
}
@@ -4934,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;
@@ -5374,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])."'";
}
@@ -5476,7 +5522,7 @@ abstract class CommonObject
$this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel);
return -1;
}
- elseif ($value == '')
+ elseif ($value === '')
{
$this->array_options["options_".$key] = null;
}
@@ -5489,7 +5535,7 @@ abstract class CommonObject
$this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel);
return -1;
}
- elseif ($value == '')
+ elseif ($value === '')
{
$this->array_options["options_".$key] = null;
}
@@ -5547,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;
}
@@ -5585,7 +5631,7 @@ abstract class CommonObject
$form = new Form($this->db);
}
- if (! empty($this->fields)) {
+ if (!empty($this->fields)) {
$val = $this->fields[$key];
}
@@ -6614,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]))
@@ -6747,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 4136cef1be5..c715f53194a 100644
--- a/htdocs/core/class/conf.class.php
+++ b/htdocs/core/class/conf.class.php
@@ -289,6 +289,8 @@ class Conf
{
$rootfordata .= '/'.$this->entity;
}
+ // Set standard temporary folder name or global override
+ $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)
@@ -296,10 +298,10 @@ class Conf
//var_dump($module);
// For multicompany sharings
$this->$module->multidir_output = array($this->entity => $rootfordata."/".$module);
- $this->$module->multidir_temp = array($this->entity => $rootfordata."/".$module."/temp");
+ $this->$module->multidir_temp = array($this->entity => $rootfortemp."/".$module."/temp");
// For backward compatibility
$this->$module->dir_output = $rootfordata."/".$module;
- $this->$module->dir_temp = $rootfordata."/".$module."/temp";
+ $this->$module->dir_temp = $rootfortemp."/".$module."/temp";
}
// External modules storage
@@ -311,56 +313,59 @@ class Conf
{
foreach ($dirs as $type => $name) // $type is 'output' or 'temp'
{
- $subdir = ($type == 'temp' ? '/temp' : '');
- // For multicompany sharings
- $varname = 'multidir_'.$type;
- $this->$module->$varname = array($this->entity => $rootfordata."/".$name.$subdir);
- // For backward compatibility
- $varname = 'dir_'.$type;
- $this->$module->$varname = $rootfordata."/".$name.$subdir;
+ $multidirname = 'multidir_'.$type;
+ $dirname = 'dir_'.$type;
+
+ if ($type != 'temp')
+ {
+ // For multicompany sharings
+ $this->$module->$multidirname = array($this->entity => $rootfordata."/".$name);
+
+ // For backward compatibility
+ $this->$module->$dirname = $rootfordata."/".$name;
+ }
+ else
+ {
+ // For multicompany sharings
+ $this->$module->$multidirname = array($this->entity => $rootfortemp."/".$name."/temp");
+
+ // For backward compatibility
+ $this->$module->$dirname = $rootfortemp."/".$name."/temp";
+ }
}
}
}
}
// For mycompany storage
- $this->mycompany->multidir_output = array($this->entity => $rootfordata."/mycompany");
- $this->mycompany->multidir_temp = array($this->entity => $rootfordata."/mycompany/temp");
- // For backward compatibility
$this->mycompany->dir_output = $rootfordata."/mycompany";
- $this->mycompany->dir_temp = $rootfordata."/mycompany/temp";
+ $this->mycompany->dir_temp = $rootfortemp."/mycompany/temp";
// For admin storage
$this->admin->dir_output = $rootfordata.'/admin';
- $this->admin->dir_temp = $rootfordata.'/admin/temp';
+ $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 => $rootfordata."/users/temp");
+ $this->user->multidir_temp = array($this->entity => $rootfortemp."/users/temp");
// For backward compatibility
$this->user->dir_output = $rootforuser."/users";
- $this->user->dir_temp = $rootforuser."/users/temp";
+ $this->user->dir_temp = $rootfortemp."/users/temp";
// For usergroup storage
$this->usergroup->dir_output = $rootforuser."/usergroups";
- $this->usergroup->dir_temp = $rootforuser."/usergroups/temp";
+ $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 => $rootfordata."/propale/temp");
+ $this->propal->multidir_temp = array($this->entity => $rootfortemp."/propale/temp");
// For backward compatibility
$this->propal->dir_output = $rootfordata."/propale";
- $this->propal->dir_temp = $rootfordata."/propale/temp";
-
- // For bank storage
- $this->bank->multidir_output = array($this->entity => $rootfordata."/bank");
- $this->bank->multidir_temp = array($this->entity => $rootfordata."/bank/temp");
- $this->bank->dir_output = $rootfordata."/bank";
- $this->bank->dir_temp = $rootfordata."/bank/temp";
+ $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 => $rootfordata."/medias/temp");
+ $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.
@@ -370,77 +375,85 @@ class Conf
$this->livraison_bon->enabled = (!empty($this->global->MAIN_SUBMODULE_LIVRAISON) ? $this->global->MAIN_SUBMODULE_LIVRAISON : 0);
// Module fournisseur
- // TODO To split into module supplier_invoice and supplier_order
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 => $rootfordata."/fournisseur/commande/temp");
+ $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 = $rootfordata."/fournisseur/commande/temp"; // 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 => $rootfordata."/fournisseur/facture/temp");
+ $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 = $rootfordata."/fournisseur/facture/temp"; // 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->fournisseur->payment = new stdClass();
$this->fournisseur->payment->multidir_output = array($this->entity => $rootfordata."/fournisseur/payment");
- $this->fournisseur->payment->multidir_temp = array($this->entity => $rootfordata."/fournisseur/payment/temp");
+ $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 = $rootfordata."/fournisseur/payment/temp"; // For backward compatibility
+ $this->fournisseur->payment->dir_temp = $rootfortemp."/fournisseur/payment/temp"; // For backward compatibility
- // To prepare split of module vendor(fournisseur) into vendor + supplier_order + supplier_invoice + supplierproposal
- if (!empty($this->fournisseur->enabled)) // By default, if module supplier is on, we set new properties
+ // 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->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 => $rootfordata."/fournisseur/commande/temp");
- $this->supplier_order->dir_output = $rootfordata."/fournisseur/commande"; // For backward compatibility
- $this->supplier_order->dir_temp = $rootfordata."/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 => $rootfordata."/fournisseur/facture/temp");
- $this->supplier_invoice->dir_output = $rootfordata."/fournisseur/facture"; // For backward compatibility
- $this->supplier_invoice->dir_temp = $rootfordata."/fournisseur/facture/temp"; // For backward compatibility
+ $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
}
}
}
// Module product/service
- $this->product->multidir_output = array($this->entity => $rootfordata."/produit");
- $this->product->multidir_temp = array($this->entity => $rootfordata."/produit/temp");
- $this->service->multidir_output = array($this->entity => $rootfordata."/produit");
- $this->service->multidir_temp = array($this->entity => $rootfordata."/produit/temp");
+ $this->product->multidir_output = array($this->entity => $rootfordata."/produit");
+ $this->product->multidir_temp = array($this->entity => $rootfortemp."/produit/temp");
+ $this->service->multidir_output = array($this->entity => $rootfordata."/produit");
+ $this->service->multidir_temp = array($this->entity => $rootfortemp."/produit/temp");
// For backward compatibility
- $this->product->dir_output = $rootfordata."/produit";
- $this->product->dir_temp = $rootfordata."/produit/temp";
- $this->service->dir_output = $rootfordata."/produit";
- $this->service->dir_temp = $rootfordata."/produit/temp";
+ $this->product->dir_output = $rootfordata."/produit";
+ $this->product->dir_temp = $rootfortemp."/produit/temp";
+ $this->service->dir_output = $rootfordata."/produit";
+ $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 => $rootfordata."/produitlot/temp");
+ $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 => $rootfordata."/contract/temp");
+ $this->contrat->multidir_temp = array($this->entity => $rootfortemp."/contract/temp");
// For backward compatibility
$this->contrat->dir_output = $rootfordata."/contract";
- $this->contrat->dir_temp = $rootfordata."/contract/temp";
+ $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 = $rootfordata."/bank/temp";
-
+ $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
@@ -514,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";
@@ -668,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..a38c25f7614 100644
--- a/htdocs/core/class/doleditor.class.php
+++ b/htdocs/core/class/doleditor.class.php
@@ -90,7 +90,7 @@ class DolEditor
{
$content = dol_htmlentitiesbr($content); // If content is not HTML, we convert to HTML.
}
- if ($this->tool == 'fckeditor')
+ /*if ($this->tool == 'fckeditor')
{
require_once DOL_DOCUMENT_ROOT.'/includes/fckeditor/fckeditor.php';
@@ -121,7 +121,7 @@ class DolEditor
$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')))
diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php
index 9aa54498edc..3f3f905166e 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,7 +738,7 @@ 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))
{
@@ -951,30 +746,38 @@ class DolGraph
$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
*
diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php
index 4425e43cda2..d241c2a8c5a 100644
--- a/htdocs/core/class/dolreceiptprinter.class.php
+++ b/htdocs/core/class/dolreceiptprinter.class.php
@@ -1,5 +1,6 @@
+ * Copyright (C) 2020 Andreu Bisquerra
*
* 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,26 +31,26 @@
* Use font A of printer
* Use font B of printer
* Use font C of printer
- * Text Bold
- * Text double height
- * Text double width
- * Underline text
- * Underline with double line
- * Emphasized text
- * Print in white on black
- * Ticket print width of 57mm
+ * Text Bold
+ * Disable Text Bold
+ * Text double height
+ * Text double width
+ * Text default height and width
+ * Underline text
+ * Disable underline text
* Cut ticket completely
* Cut ticket partially
* Open cash drawer
- * Activate buzzer
+ * Activate buzzer
* Print barcode
- * Print QR Code
* Print logo stored on printer. Example : 32|32
* Print logo stored on printer. Must be followed by logo code. For old printers.
* Print object lines
* 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
@@ -60,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
@@ -162,26 +161,17 @@ class dolReceiptPrinter extends Printer
'dol_use_font_b',
'dol_use_font_c',
'dol_bold',
- '/dol_bold',
+ 'dol_bold_disabled',
'dol_double_height',
- '/dol_double_height',
'dol_double_width',
- '/dol_double_width',
+ 'dol_default_height_width',
'dol_underline',
- '/dol_underline',
- 'dol_underline_2dots',
- '/dol_underline',
- 'dol_emphasized',
- '/dol_emphasized',
- 'dol_switch_colors',
- '/dol_switch_colors',
- 'dol_set_print_width_57',
+ 'dol_underline_disabled',
'dol_cut_paper_full',
'dol_cut_paper_partial',
'dol_open_drawer',
- //'dol_activate_buzzer',
+ 'dol_beep',
'dol_print_text',
- 'dol_print_qrcode',
'dol_print_barcode',
'dol_value_date',
'dol_value_date_time',
@@ -190,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',
@@ -202,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',
@@ -515,7 +505,7 @@ class dolReceiptPrinter extends Printer
{
global $conf;
$error = 0;
- $img = EscposImage::load(DOL_DOCUMENT_ROOT.'/theme/common/dolibarr_logo_bw.png');
+ $img = EscposImage::load(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo_bw.png');
//$this->profile = CapabilityProfile::load("TM-T88IV");
$ret = $this->initPrinter($printerid);
if ($ret > 0) {
@@ -589,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();
@@ -712,6 +700,52 @@ class dolReceiptPrinter extends Printer
case 'DOL_USE_FONT_C':
$this->printer->setFont(Printer::FONT_C);
break;
+ case 'DOL_BOLD':
+ $this->printer->setEmphasis(true);
+ break;
+ case 'DOL_BOLD_DISABLED':
+ $this->printer->setEmphasis(false);
+ break;
+ case 'DOL_DOUBLE_HEIGHT':
+ $this->printer->setTextSize(1, 2);
+ break;
+ case 'DOL_DOUBLE_WIDTH':
+ $this->printer->setTextSize(2, 1);
+ break;
+ case 'DOL_DEFAULT_HEIGHT_WIDTH':
+ $this->printer->setTextSize(1, 1);
+ break;
+ case 'DOL_UNDERLINE':
+ $this->printer->setUnderline(true);
+ break;
+ case 'DOL_UNDERLINE_DISABLED':
+ $this->printer->setUnderline(false);
+ break;
+ 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/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 e7cd695dc0b..0db01a84656 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,16 +6052,23 @@ class Form
// Search data
$sql = "SELECT t.rowid, ".$fieldstoshow." FROM ".MAIN_DB_PREFIX.$objecttmp->table_element." as t";
- if ($objecttmp->ismultientitymanaged == 2)
+ 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];
+ }
+ if ($objecttmp->ismultientitymanaged == 'fk_soc@societe')
if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql .= " WHERE 1=1";
- if (!empty($objecttmp->ismultientitymanaged)) $sql .= " AND t.entity IN (".getEntity($objecttmp->table_element).")";
+ if (isset($objecttmp->ismultientitymanaged) && $objecttmp->ismultientitymanaged == 1) $sql .= " AND t.entity IN (".getEntity($objecttmp->table_element).")";
+ if (isset($objecttmp->ismultientitymanaged) && !is_numeric($objecttmp->ismultientitymanaged)) {
+ $sql .= ' AND parenttable.entity = t.'.$tmparray[0];
+ }
if ($objecttmp->ismultientitymanaged == 1 && !empty($user->socid)) {
if ($objecttmp->element == 'societe') $sql .= " AND t.rowid = ".$user->socid;
else $sql .= " AND t.fk_soc = ".$user->socid;
}
if ($searchkey != '') $sql .= natural_search(explode(',', $fieldstoshow), $searchkey);
- if ($objecttmp->ismultientitymanaged == 2) {
+ if ($objecttmp->ismultientitymanaged == 'fk_soc@societe') {
if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND t.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
}
if ($objecttmp->filter) { // Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
@@ -6674,8 +6696,10 @@ class Form
@@ -7051,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();
});
});
@@ -7299,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 .= '';
@@ -8052,11 +8077,11 @@ class Form
$ret .= $langs->trans("Filters");
$ret .= '';
//$ret .= ' ';
- $ret .= '';
+ $ret .= '
';
$ret .= ' ';
$ret .= '
';
- foreach($arrayofcriterias as $criterias) {
- foreach($criterias as $criteriafamilykey => $criteriafamilyval) {
+ 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 a3d73b627b7..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)
@@ -859,7 +859,7 @@ class FormFile
if ($delallowed)
{
$tmpurlsource = preg_replace('/#[a-zA-Z0-9_]*$/', '', $urlsource);
- $out .= 'initHooks(array('formfile'));
$parameters = array(
diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php
index abad66c8a73..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
@@ -676,10 +669,12 @@ class FormMail extends Form
}
else
{
+ // The free input of email
if (!empty($this->withtofree))
{
- $out .= ' withto) : "").'" />';
+ $out .= ' withto) : "")).'" />';
}
+ // The select combo
if (!empty($this->withto) && is_array($this->withto))
{
if (!empty($this->withtofree)) $out .= " ".$langs->trans("and")."/".$langs->trans("or")." ";
@@ -1032,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..829a3f9c72f 100644
--- a/htdocs/core/class/html.formother.class.php
+++ b/htdocs/core/class/html.formother.class.php
@@ -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 .= '';
@@ -1338,4 +1338,122 @@ class FormOther
$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.formticket.class.php b/htdocs/core/class/html.formticket.class.php
index d99a6c091cc..ecf137adb04 100644
--- a/htdocs/core/class/html.formticket.class.php
+++ b/htdocs/core/class/html.formticket.class.php
@@ -919,7 +919,7 @@ class FormTicket
print ''.$langs->trans('Subject').' ';
$label_title = empty($conf->global->MAIN_APPLICATION_TITLE) ? $mysoc->name : $conf->global->MAIN_APPLICATION_TITLE;
- print ' ';
+ print ' ref.'] '.$langs->trans('TicketNewMessage').'" />';
print ' ';
// Destinataires
@@ -935,13 +935,13 @@ class FormTicket
if (is_array($contacts) && count($contacts) > 0) {
foreach ($contacts as $key => $info_sendto) {
if ($info_sendto['email'] != '') {
- $sendto[] = dol_escape_htmltag(trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">")." (".dol_escape_htmltag($info_sendto['libelle']).") ";
+ $sendto[] = dol_escape_htmltag(trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">").' ('.dol_escape_htmltag($info_sendto['libelle']).") ";
}
}
}
if ($ticketstat->origin_email && !in_array($this->dao->origin_email, $sendto)) {
- $sendto[] = dol_escape_htmltag($ticketstat->origin_email)." (".$langs->trans("TicketEmailOriginIssuer").") ";
+ $sendto[] = dol_escape_htmltag($ticketstat->origin_email).' ('.$langs->trans("TicketEmailOriginIssuer").") ";
}
if ($ticketstat->fk_soc > 0) {
@@ -949,12 +949,12 @@ class FormTicket
$ticketstat->fetch_thirdparty();
if (is_array($ticketstat->thirdparty->email) && !in_array($ticketstat->thirdparty->email, $sendto)) {
- $sendto[] = $ticketstat->thirdparty->email.' ('.$langs->trans('Customer').') ';
+ $sendto[] = $ticketstat->thirdparty->email.' ('.$langs->trans('Customer').') ';
}
}
if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS) {
- $sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO.' (generic email) ';
+ $sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO.' (generic email) ';
}
// Print recipient list
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..e0c19e300a3 100644
--- a/htdocs/core/class/stats.class.php
+++ b/htdocs/core/class/stats.class.php
@@ -269,13 +269,14 @@ 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;
- $datay=array();
+ $data=array();
// Search into cache
if (! empty($cachedelay))
@@ -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
}
@@ -604,7 +605,6 @@ abstract class Stats
global $langs;
$result=array();
- $res=array();
dol_syslog(get_class($this).'::'.__FUNCTION__."", LOG_DEBUG);
$resql=$this->db->query($sql);
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
new file mode 100644
index 00000000000..b5379ef911b
--- /dev/null
+++ b/htdocs/core/customreports.php
@@ -0,0 +1,740 @@
+
+ *
+ * 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 .
+ *
+ * This tool can be included into a list page with
+ * define('USE_CUSTOME_REPORT_AS_INCLUDE', 1);
+ * include DOL_DOCUMENT_ROOT.'/core/customreports.php';
+ */
+
+/**
+ * \file htdocs/core/customreports.php
+ * \ingroup core
+ * \brief Page to make custom reports
+ */
+
+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 = 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", "other", "exports", "sendings"));
+
+$extrafields = new ExtraFields($db);
+
+$hookmanager->initHooks(array('customreport')); // Note that conf->hooks_modules contains array
+
+$title = '';
+$picto = '';
+$head = array();
+$object = null;
+$ObjectClassName = '';
+// Objects available by default
+$arrayoftype = array(
+ '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->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' => "/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 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
+ $title = $hookmanager->resArray['title'];
+ }
+ if (!empty($hookmanager->resArray['picto'])) { // Add entries for tabs
+ $picto = $hookmanager->resArray['picto'];
+ }
+ 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) {
+ $arrayoftype[$key] = $val;
+ }
+ }
+}
+
+if ($objecttype) {
+ try {
+ if (! empty($arrayoftype[$objecttype]['ClassPath'])) {
+ dol_include_once($arrayoftype[$objecttype]['ClassPath']);
+ } else {
+ dol_include_once("/".$objecttype."/class/".$objecttype.".class.php");
+ }
+ $ObjectClassName = $arrayoftype[$objecttype]['ObjectClassName'];
+ $object = new $ObjectClassName($db);
+ }
+ catch (Exception $e) {
+ print 'Failed to load class for type '.$objecttype;
+ }
+}
+
+// Security check
+$socid = 0;
+if ($user->socid > 0) // Protection if external user
+{
+ //$socid = $user->socid;
+ accessforbidden();
+}
+
+$result = restrictedArea($user, $object->element, 0, '');
+
+// Fetch optionals attributes and labels
+$extrafields->fetch_name_optionals_label($object->table_element);
+//$extrafields->fetch_name_optionals_label($object->table_element_line);
+
+$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
+
+$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();
+
+
+
+/*
+ * Actions
+ */
+
+
+
+
+
+/*
+ * View
+ */
+
+$form = new Form($db);
+$formother = new FormOther($db);
+
+if (!defined('USE_CUSTOME_REPORT_AS_INCLUDE')) {
+ llxHeader('', $langs->transnoentitiesnoconv('CustomReports'), '');
+
+ dol_fiche_head($head, 'customreports', $title, -1, $picto);
+}
+
+// Check parameters
+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);
+
+ 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];
+ }
+
+ $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;
+
+$param = '';
+
+print '';
+print ' ';
+print ' ';
+print ' ';
+
+print '';
+
+// Select object
+print '
';
+print '
'.$langs->trans("StatisticsOn").'
';
+$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 '
';
+
+// Add measures into array
+print '
';
+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 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]) && (! 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").') ';
+ $arrayofmesures['te.'.$key.'-max'] = $langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).'
('.$langs->trans("Maximum").') ';
+ }
+ }
+}
+print '
'.$langs->trans("Measures").'
';
+print $form->multiselectarray('search_measures', $arrayofmesures, $search_measures, 0, 0, 'minwidth500', 1);
+print '
';
+
+
+// Group by
+print '
';
+print '
'.$langs->trans("GroupBy").'
';
+print $formother->selectGroupByField($object, $search_groupby, $arrayofgroupby);
+print '
';
+
+
+// XAxis
+print '
';
+print '
'.$langs->trans("XAxis").'
';
+print $formother->selectXAxisField($object, $search_xaxis, $arrayofxaxis);
+print '
';
+
+
+if ($mode == 'grid') {
+ // 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']).' ('.$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]) && (! 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) {
+ $arrayofyaxislabel[$key] = $val['label'];
+ }
+ print '
'.$langs->trans("YAxis").'
';
+ print $form->multiselectarray('search_yaxis', $arrayofyaxislabel, $search_yaxis, 0, 0, 'minwidth100', 1);
+ print '
';
+}
+
+if ($mode == 'graph') {
+ print '
';
+ $arrayofgraphs = array('bars' => 'Bars', 'lines' => 'Lines'); // also 'pies'
+ print '
'.$langs->trans("Graph").'
';
+ print $form->selectarray('search_graph', $arrayofgraphs, $search_graph, 0, 0, 0, 'minwidth100', 1);
+ print '
';
+}
+print '
';
+print ' ';
+print '
';
+print '
';
+print ' ';
+
+// Generate the SQL request
+$sql = '';
+if (!empty($search_measures) && !empty($search_xaxis))
+{
+ $fieldid = 'rowid';
+
+ $sql = 'SELECT ';
+ foreach ($search_xaxis as $key => $val) {
+ if (preg_match('/\-year$/', $val)) {
+ $tmpval = preg_replace('/\-year$/', '', $val);
+ $sql .= 'DATE_FORMAT('.$tmpval.", '%Y') as x_".$key.', ';
+ } elseif (preg_match('/\-month$/', $val)) {
+ $tmpval = preg_replace('/\-month$/', '', $val);
+ $sql .= 'DATE_FORMAT('.$tmpval.", '%Y-%m') as x_".$key.', ';
+ } elseif (preg_match('/\-day$/', $val)) {
+ $tmpval = preg_replace('/\-day$/', '', $val);
+ $sql .= 'DATE_FORMAT('.$tmpval.", '%Y-%m-%d') as x_".$key.', ';
+ }
+ else $sql .= $val.' as x_'.$key.', ';
+ }
+ 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);
+ $sql .= 'SUM('.$db->ifsql($tmpval.' IS NULL', '0', $tmpval).') as y_'.$key.', ';
+ }
+ elseif (preg_match('/\-average$/', $val)) {
+ $tmpval = preg_replace('/\-average$/', '', $val);
+ $sql .= 'AVG('.$db->ifsql($tmpval.' IS NULL', '0', $tmpval).') as y_'.$key.', ';
+ }
+ elseif (preg_match('/\-min$/', $val)) {
+ $tmpval = preg_replace('/\-min$/', '', $val);
+ $sql .= 'MIN('.$db->ifsql($tmpval.' IS NULL', '0', $tmpval).') as y_'.$key.', ';
+ }
+ elseif (preg_match('/\-max$/', $val)) {
+ $tmpval = preg_replace('/\-max$/', '', $val);
+ $sql .= 'MAX('.$db->ifsql($tmpval.' IS NULL', '0', $tmpval).') as y_'.$key.', ';
+ }
+ }
+ $sql = preg_replace('/,\s*$/', '', $sql);
+ $sql .= ' FROM '.MAIN_DB_PREFIX.$object->table_element.' as t';
+ // Add measure from extrafields
+ if ($object->isextrafieldmanaged) {
+ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.$object->table_element.'_extrafields as te ON te.fk_object = t.'.$fieldid;
+ }
+ if ($object->ismultientitymanaged) {
+ if ($object->ismultientitymanaged == 1) {
+ // Nothing here
+ } else {
+ $tmparray = explode('@', $object->ismultientitymanaged);
+ $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.$tmparray[1].' as parenttable ON t.'.$tmparray[0].' = parenttable.rowid';
+ $sql .= ' AND parenttable.entity IN ('.getEntity($tmparray[1]).')';
+ }
+ }
+ $sql .= ' WHERE 1 = 1';
+ if ($object->ismultientitymanaged == 1) {
+ $sql .= ' AND entity IN ('.getEntity($object->element).')';
+ }
+ foreach ($search_filters as $key => $val) {
+ // TODO Add the where here
+ }
+ $sql .= ' GROUP BY ';
+ foreach ($search_xaxis 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.', ';
+ }
+ 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) {
+ 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.', ';
+ }
+ 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[] = $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) {
+ dol_print_error($db);
+ }
+
+ $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 '';
+
+
+if ($mode == 'grid') {
+ // TODO
+}
+
+if ($mode == 'graph') {
+ $WIDTH = '80%';
+ $HEIGHT = 200;
+
+ // Show graph
+ $px1 = new DolGraph();
+ $mesg = $px1->isGraphKo();
+ if (!$mesg)
+ {
+ $px1->SetData($data);
+ unset($data);
+
+ $arrayoftypes = array();
+ foreach ($search_measures as $key => $val) {
+ $arrayoftypes[] = $search_graph;
+ }
+
+ $px1->SetLegend($legend);
+ $px1->SetMinValue($px1->GetFloorMinValue());
+ $px1->SetMaxValue($px1->GetCeilMaxValue());
+ $px1->SetWidth($WIDTH);
+ $px1->SetHeight($HEIGHT);
+ $px1->SetYLabel($langs->trans("Y"));
+ $px1->SetShading(3);
+ $px1->SetHorizTickIncrement(1);
+ $px1->SetCssPrefix("cssboxes");
+ $px1->SetType($arrayoftypes);
+ $px1->mode = 'depth';
+ $px1->SetTitle('');
+
+ $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';
+
+ $px1->draw($filenamenb, $fileurlnb);
+
+ print $px1->show($totalnbofrecord ? 0 : $langs->trans("SelectYourGraphOptionsFirst"));
+ }
+}
+
+if ($sql) {
+ // Show admin info
+ print '
'.info_admin($langs->trans("SQLUsedForExport").':
'.$sql, 0, 0, 1, '', 'TechnicalInformation');
+}
+
+print '
';
+
+if (!defined('USE_CUSTOME_REPORT_AS_INCLUDE')) {
+ dol_fiche_end();
+}
+
+// End of page
+llxFooter();
+
+$db->close();
diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php
index 29d77c089c0..8ca84e0dd10 100644
--- a/htdocs/core/db/DoliDB.class.php
+++ b/htdocs/core/db/DoliDB.class.php
@@ -29,7 +29,7 @@ require_once DOL_DOCUMENT_ROOT .'/core/db/Database.interface.php';
*/
abstract class DoliDB implements Database
{
- /** @var bool|resource Database handler */
+ /** @var bool|resource|SQLite3 Database handler */
public $db;
/** @var string Database type */
public $type;
diff --git a/htdocs/core/db/mssql.class.php b/htdocs/core/db/mssql.class.php
index 2c489b25181..79d26949394 100644
--- a/htdocs/core/db/mssql.class.php
+++ b/htdocs/core/db/mssql.class.php
@@ -41,7 +41,7 @@ class DoliDBMssql extends DoliDB
public $forcecollate='latin1_swedish_ci'; // Can't be static as it may be forced with a dynamic value
//! Version min database
const VERSIONMIN='2000';
- /** @var resource Resultset of last query */
+ /** @var boolean|resource Resultset of last query */
private $_results;
/**
@@ -336,6 +336,8 @@ class DoliDBMssql extends DoliDB
$query=preg_replace("/([. ,\t(])(percent|file|public)([. ,=\t)])/", "$1[$2]$3", $query);
+ $original_query='';
+
if ($type=="auto" || $type='dml')
{
$query=preg_replace('/AUTO_INCREMENT/i', 'IDENTITY', $query);
@@ -345,7 +347,6 @@ class DoliDBMssql extends DoliDB
$query=preg_replace('/([ \t])(MEDIUM|TINY|LONG){0,1}TEXT([ \t,])/i', "$1VARCHAR(MAX)$3", $query);
$matches=array();
- $original_query='';
if (preg_match('/ALTER TABLE\h+(\w+?)\h+ADD\h+(?:(UNIQUE)|INDEX)\h+(?:INDEX)?\h*(\w+?)\h*\((.+)\)/is', $query, $matches))
{
$original_query=$query;
@@ -356,10 +357,12 @@ class DoliDBMssql extends DoliDB
$fields_clear=array_map('trim', $fields);
$infos=$this->GetFieldInformation(trim($matches[1]), $fields_clear);
$query_comp=array();
- foreach($infos as $fld) {
- if ($fld->IS_NULLABLE == 'YES') {
- $query_comp[]=$fld->COLUMN_NAME." IS NOT NULL";
- }
+ if (is_array($infos)) {
+ foreach($infos as $fld) {
+ if ($fld->IS_NULLABLE == 'YES') {
+ $query_comp[]=$fld->COLUMN_NAME." IS NOT NULL";
+ }
+ }
}
if (! empty($query_comp))
$query.=" WHERE ".implode(" AND ", $query_comp);
@@ -784,7 +787,8 @@ class DoliDBMssql extends DoliDB
public function DDLListTables($database, $table = '')
{
// phpcs:enable
- $this->_results = mssql_list_tables($database, $this->db);
+ $v = mssql_query("Select name from sysobjects where type like 'u'", $this->db);
+ $this->_results = mssql_fetch_array($v);
return $this->_results;
}
@@ -825,6 +829,10 @@ class DoliDBMssql extends DoliDB
// phpcs:enable
// FIXME: $fulltext_keys parameter is unused
+ $sqlfields = array();
+ $sqluq = array();
+ $sqlk = array();
+
// cles recherchees dans le tableau des descriptions (fields) : type,value,attribute,null,default,extra
// ex. : $fields['rowid'] = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
$sql = "create table ".$table."(";
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/agenda.lib.php b/htdocs/core/lib/agenda.lib.php
index 1ea2dae72a6..dd1810fdf5f 100644
--- a/htdocs/core/lib/agenda.lib.php
+++ b/htdocs/core/lib/agenda.lib.php
@@ -545,7 +545,9 @@ function calendars_prepare_head($param)
$h++;
}
- $head[$h][0] = DOL_URL_ROOT.'/comm/action/peruser.php'.($param?'?'.$param:'');
+ $newparam = $param;
+ $newparam = preg_replace('/&?search_filtert=\d+/', '', $newparam);
+ $head[$h][0] = DOL_URL_ROOT.'/comm/action/peruser.php'.($newparam?'?'.$newparam:'');
$head[$h][1] = $langs->trans("ViewPerUser");
$head[$h][2] = 'cardperuser';
$h++;
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 3f7536368f1..a3771d53cff 100644
--- a/htdocs/core/lib/company.lib.php
+++ b/htdocs/core/lib/company.lib.php
@@ -207,8 +207,12 @@ function societe_prepare_head(Societe $object)
$sql = "SELECT COUNT(n.rowid) as nb";
$sql .= " FROM ".MAIN_DB_PREFIX."societe_rib as n";
- $sql .= " WHERE fk_soc = ".$object->id;
- $sql .= " AND status = ".$servicestatus;
+ $sql .= " WHERE n.fk_soc = ".$object->id;
+ if (empty($conf->stripe->enabled)) {
+ $sql .= " AND n.stripe_card_ref IS NULL";
+ } else {
+ $sql .= " AND (n.stripe_card_ref IS NULL OR (n.stripe_card_ref IS NOT NULL AND n.status = ".$servicestatus."))";
+ }
$resql = $db->query($sql);
if ($resql)
diff --git a/htdocs/core/lib/emailing.lib.php b/htdocs/core/lib/emailing.lib.php
index 59bb080d93e..cb4e5cf8b29 100644
--- a/htdocs/core/lib/emailing.lib.php
+++ b/htdocs/core/lib/emailing.lib.php
@@ -48,7 +48,7 @@ function emailing_prepare_head(Mailing $object)
$h++;
}
- if (! empty($conf->global->EMAILING_USE_ADVANCED_SELECTOR))
+ if ( empty($conf->global->EMAILING_USE_ADVANCED_SELECTOR))
{
$head[$h][0] = DOL_URL_ROOT."/comm/mailing/advtargetemailing.php?id=".$object->id;
$head[$h][1] = $langs->trans("MailAdvTargetRecipients");
diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php
index 4568ab2774d..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))
@@ -2912,6 +2913,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
if ($fuser->admin) $accessallowed = 1; // If user is admin
// Define $accessallowed
+ $reg = array();
if (preg_match('/^([a-z]+)_user_temp$/i', $modulepart, $reg))
{
if (empty($conf->{$reg[1]}->dir_temp)) // modulepart not supported
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 72f0d0f19e0..3ec6a434fc7 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
*/
@@ -1105,8 +1102,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 +1145,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 +1164,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 +1204,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 +1302,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 +1883,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 +2107,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 +2122,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 +3078,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 +3110,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 +3133,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 +3155,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 +3826,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 +4091,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 +4139,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));
@@ -4201,7 +4239,8 @@ function load_fiche_titre($titre, $morehtmlright = '', $picto = 'generic', $pict
if ($picto == 'setup') $picto = 'generic';
$return .= "\n";
- $return .= ' '; // maring bottom must be same than into print_barre_list
+ $return .= ''; // maring bottom must be same than into print_barre_list
+ $return .= '';
if ($picto) $return .= ''.img_picto('', $picto, 'class="valignmiddle widthpictotitle pictotitle"', $pictoisfullpath).' ';
$return .= '';
$return .= ''.$titre.'
';
@@ -4267,10 +4306,10 @@ function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '',
// Left
- if ($picto && $titre) print ' '.img_picto('', $picto, 'class="hideonsmartphone valignmiddle pictotitle widthpictotitle"', $pictoisfullpath).' ';
+ 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
@@ -5344,10 +5383,10 @@ function get_default_localtax($thirdparty_seller, $thirdparty_buyer, $local, $id
/**
* Return yes or no in current language
*
- * @param string $yesno Value to test (1, 'yes', 'true' or 0, 'no', 'false')
- * @param integer $case 1=Yes/No, 0=yes/no, 2=Disabled checkbox, 3=Disabled checkbox + Yes/No
- * @param int $color 0=texte only, 1=Text is formated with a color font style ('ok' or 'error'), 2=Text is formated with 'ok' color.
- * @return string HTML string
+ * @param string|int $yesno Value to test (1, 'yes', 'true' or 0, 'no', 'false')
+ * @param integer $case 1=Yes/No, 0=yes/no, 2=Disabled checkbox, 3=Disabled checkbox + Yes/No
+ * @param int $color 0=texte only, 1=Text is formated with a color font style ('ok' or 'error'), 2=Text is formated with 'ok' color.
+ * @return string HTML string
*/
function yn($yesno, $case = 1, $color = 0)
{
@@ -5559,22 +5598,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);
@@ -5583,14 +5627,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)
@@ -5598,6 +5644,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;
}
@@ -5970,7 +6021,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'),
@@ -6095,7 +6147,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');
@@ -6271,6 +6323,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;
}
}
}
@@ -6910,6 +6966,24 @@ function utf8_check($str)
return true;
}
+/**
+ * Check if a string is in ASCII
+ *
+ * @param string $str String to check
+ * @return boolean True if string is ASCII, False if not (byte value > 0x7F)
+ */
+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;
+ } else {
+ if (preg_match('/[^\x00-\x7f]/', $str)) return false; // Contains a byte > 7f
+ }
+
+ return true;
+}
+
/**
* Return a string encoded into OS filesystem encoding. This function is used to define
@@ -7571,15 +7645,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"))
{
@@ -7796,12 +7867,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 ' : '');
@@ -7992,7 +8062,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'; }
@@ -8549,6 +8619,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/functionsnumtoword.lib.php b/htdocs/core/lib/functionsnumtoword.lib.php
index 94479fe2c28..26db2bbec90 100644
--- a/htdocs/core/lib/functionsnumtoword.lib.php
+++ b/htdocs/core/lib/functionsnumtoword.lib.php
@@ -25,7 +25,7 @@
/**
* Function to return number in text.
- *
+ * May use module NUMBERWORDS if found.
*
* @param float $num Number to convert
* @param Translate $langs Language
@@ -38,15 +38,15 @@ function dol_convertToWord($num, $langs, $currency = false, $centimes = false)
global $conf;
$num = str_replace(array(',', ' '), '', trim($num));
- if (! $num) {
+ if (!$num) {
return false;
}
if ($centimes && strlen($num) == 1) {
- $num = $num*10;
+ $num = $num * 10;
}
- if (! empty($conf->global->MAIN_MODULE_NUMBERWORDS)) {
+ if (!empty($conf->global->MAIN_MODULE_NUMBERWORDS)) {
if ($currency) {
$type = 1;
} else {
@@ -106,24 +106,24 @@ function dol_convertToWord($num, $langs, $currency = false, $centimes = false)
$num_length = strlen($num);
$levels = (int) (($num_length + 2) / 3);
$max_length = $levels * 3;
- $num = substr('00' . $num, -$max_length);
+ $num = substr('00'.$num, -$max_length);
$num_levels = str_split($num, 3);
$nboflevels = count($num_levels);
for ($i = 0; $i < $nboflevels; $i++) {
$levels--;
$hundreds = (int) ($num_levels[$i] / 100);
- $hundreds = ($hundreds ? ' ' . $list1[$hundreds] . ' '.$langs->transnoentities('hundred') . ( $hundreds == 1 ? '' : 's' ) . ' ': '');
+ $hundreds = ($hundreds ? ' '.$list1[$hundreds].' '.$langs->transnoentities('hundred').($hundreds == 1 ? '' : 's').' ' : '');
$tens = (int) ($num_levels[$i] % 100);
$singles = '';
- if ( $tens < 20 ) {
- $tens = ($tens ? ' ' . $list1[$tens] . ' ' : '' );
+ if ($tens < 20) {
+ $tens = ($tens ? ' '.$list1[$tens].' ' : '');
} else {
$tens = (int) ($tens / 10);
- $tens = ' ' . $list2[$tens] . ' ';
+ $tens = ' '.$list2[$tens].' ';
$singles = (int) ($num_levels[$i] % 10);
- $singles = ' ' . $list1[$singles] . ' ';
+ $singles = ' '.$list1[$singles].' ';
}
- $words[] = $hundreds . $tens . $singles . ( ( $levels && ( int ) ( $num_levels[$i] ) ) ? ' ' . $list3[$levels] . ' ' : '' );
+ $words[] = $hundreds.$tens.$singles.(($levels && (int) ($num_levels[$i])) ? ' '.$list3[$levels].' ' : '');
} //end for loop
$commas = count($words);
if ($commas > 1) {
@@ -133,15 +133,15 @@ function dol_convertToWord($num, $langs, $currency = false, $centimes = false)
// Delete multi whitespaces
$concatWords = trim(preg_replace('/[ ]+/', ' ', $concatWords));
- if(!empty($currency)) {
+ if (!empty($currency)) {
$concatWords .= ' '.$currency;
}
// If we need to write cents call again this function for cents
- if(!empty($TNum[1])) {
- if(!empty($currency)) $concatWords .= ' '.$langs->transnoentities('and');
+ if (!empty($TNum[1])) {
+ if (!empty($currency)) $concatWords .= ' '.$langs->transnoentities('and');
$concatWords .= ' '.dol_convertToWord($TNum[1], $langs, $currency, true);
- if(!empty($currency)) $concatWords .= ' '.$langs->transnoentities('centimes');
+ if (!empty($currency)) $concatWords .= ' '.$langs->transnoentities('centimes');
}
return $concatWords;
}
@@ -165,35 +165,35 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number')
return -1;
// Get 2 decimals to cents, another functions round or truncate
$strnumber = number_format($numero, 10);
- $len=strlen($strnumber);
- for ($i=0; $i<$len; $i++)
+ $len = strlen($strnumber);
+ for ($i = 0; $i < $len; $i++)
{
- if ($strnumber[$i]=='.') {
- $parte_decimal = $strnumber[$i+1].$strnumber[$i+2];
+ if ($strnumber[$i] == '.') {
+ $parte_decimal = $strnumber[$i + 1].$strnumber[$i + 2];
break;
}
}
/*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and
in case exist why ask $lang like a parameter?*/
- if (((is_object($langs) && $langs->default == 'es_MX') || (! is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency')
+ if (((is_object($langs) && $langs->default == 'es_MX') || (!is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency')
{
- if ($numero>=1 && $numero<2) {
+ if ($numero >= 1 && $numero < 2) {
return ("UN PESO ".$parte_decimal." / 100 M.N.");
}
- elseif ($numero>=0 && $numero<1){
+ elseif ($numero >= 0 && $numero < 1) {
return ("CERO PESOS ".$parte_decimal." / 100 M.N.");
}
- elseif ($numero>=1000000 && $numero<1000001){
+ elseif ($numero >= 1000000 && $numero < 1000001) {
return ("UN MILLÓN DE PESOS ".$parte_decimal." / 100 M.N.");
}
- elseif ($numero>=1000000000000 && $numero<1000000000001){
+ elseif ($numero >= 1000000000000 && $numero < 1000000000001) {
return ("UN BILLÓN DE PESOS ".$parte_decimal." / 100 M.N.");
}
else {
- $entexto ="";
+ $entexto = "";
$number = $numero;
- if ($number >= 1000000000){
+ if ($number >= 1000000000) {
$CdMMillon = (int) ($numero / 100000000000);
$numero = $numero - $CdMMillon * 100000000000;
$DdMMillon = (int) ($numero / 10000000000);
@@ -203,7 +203,7 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number')
$entexto .= hundreds2text($CdMMillon, $DdMMillon, $UdMMillon);
$entexto .= " MIL ";
}
- if ($number >= 1000000){
+ if ($number >= 1000000) {
$CdMILLON = (int) ($numero / 100000000);
$numero = $numero - $CdMILLON * 100000000;
$DdMILLON = (int) ($numero / 10000000);
@@ -211,7 +211,7 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number')
$udMILLON = (int) ($numero / 1000000);
$numero = $numero - $udMILLON * 1000000;
$entexto .= hundreds2text($CdMILLON, $DdMILLON, $udMILLON);
- if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON==1)
+ if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON == 1)
$entexto .= " MILLÓN ";
else
$entexto .= " MILLONES ";
@@ -232,7 +232,7 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number')
$d = (int) ($numero / 10);
$u = (int) $numero - $d * 10;
$entexto .= hundreds2text($c, $d, $u);
- if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number>1000000)
+ if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number > 1000000)
$entexto .= " DE";
$entexto .= " PESOS ".$parte_decimal." / 100 M.N.";
}
@@ -250,40 +250,40 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number')
*/
function hundreds2text($hundreds, $tens, $units)
{
- if ($hundreds==1 && $tens==0 && $units==0){
+ if ($hundreds == 1 && $tens == 0 && $units == 0) {
return "CIEN";
}
- $centenas = array("CIENTO","DOSCIENTOS","TRESCIENTOS","CUATROCIENTOS","QUINIENTOS","SEISCIENTOS","SETECIENTOS","OCHOCIENTOS","NOVECIENTOS");
- $decenas = array("","","TREINTA ","CUARENTA ","CINCUENTA ","SESENTA ","SETENTA ","OCHENTA ","NOVENTA ");
- $veintis = array("VEINTE","VEINTIUN","VEINTIDÓS","VEINTITRÉS","VEINTICUATRO","VEINTICINCO","VEINTISÉIS","VEINTISIETE","VEINTIOCHO","VEINTINUEVE");
- $diecis = array("DIEZ","ONCE","DOCE","TRECE","CATORCE","QUINCE","DIECISÉIS","DIECISIETE","DIECIOCHO","DIECINUEVE");
- $unidades = array("UN","DOS","TRES","CUATRO","CINCO","SEIS","SIETE","OCHO","NUEVE");
+ $centenas = array("CIENTO", "DOSCIENTOS", "TRESCIENTOS", "CUATROCIENTOS", "QUINIENTOS", "SEISCIENTOS", "SETECIENTOS", "OCHOCIENTOS", "NOVECIENTOS");
+ $decenas = array("", "", "TREINTA ", "CUARENTA ", "CINCUENTA ", "SESENTA ", "SETENTA ", "OCHENTA ", "NOVENTA ");
+ $veintis = array("VEINTE", "VEINTIUN", "VEINTIDÓS", "VEINTITRÉS", "VEINTICUATRO", "VEINTICINCO", "VEINTISÉIS", "VEINTISIETE", "VEINTIOCHO", "VEINTINUEVE");
+ $diecis = array("DIEZ", "ONCE", "DOCE", "TRECE", "CATORCE", "QUINCE", "DIECISÉIS", "DIECISIETE", "DIECIOCHO", "DIECINUEVE");
+ $unidades = array("UN", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE", "OCHO", "NUEVE");
$entexto = "";
- if ($hundreds!=0){
- $entexto .= $centenas[$hundreds-1];
+ if ($hundreds != 0) {
+ $entexto .= $centenas[$hundreds - 1];
}
- if ($tens>2){
- if ($hundreds!=0) $entexto .= " ";
- $entexto .= $decenas[$tens-1];
- if ($units!=0){
+ if ($tens > 2) {
+ if ($hundreds != 0) $entexto .= " ";
+ $entexto .= $decenas[$tens - 1];
+ if ($units != 0) {
$entexto .= " Y ";
- $entexto .= $unidades[$units-1];
+ $entexto .= $unidades[$units - 1];
}
return $entexto;
}
- elseif ($tens==2){
- if ($hundreds!=0) $entexto .= " ";
+ elseif ($tens == 2) {
+ if ($hundreds != 0) $entexto .= " ";
$entexto .= " ".$veintis[$units];
return $entexto;
}
- elseif ($tens==1){
- if ($hundreds!=0) $entexto .= " ";
+ elseif ($tens == 1) {
+ if ($hundreds != 0) $entexto .= " ";
$entexto .= $diecis[$units];
return $entexto;
}
- if ($units!=0) {
- if ($hundreds!=0 || $tens!=0) $entexto .= " ";
- $entexto .= $unidades[$units-1];
+ if ($units != 0) {
+ if ($hundreds != 0 || $tens != 0) $entexto .= " ";
+ $entexto .= $unidades[$units - 1];
}
return $entexto;
}
diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
index e7538725bc2..b75cb1e4bd6 100644
--- a/htdocs/core/lib/pdf.lib.php
+++ b/htdocs/core/lib/pdf.lib.php
@@ -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..dbfeef03259 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,13 +2179,14 @@ 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);
@@ -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 93f17422c47..83cf576f0bb 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));
@@ -168,7 +168,7 @@ function dol_verifyHash($chain, $hash, $type = '0')
* If GETPOST('action','aZ09') defined, we also check write and delete permission.
*
* @param User $user User to check
- * @param string $features Features to check (it must be module name. Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...)
+ * @param string $features Features to check (it must be module $object->element. Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...)
* @param int $objectid Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional).
* @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany modume. Param not used if objectid is null (optional).
* @param string $feature2 Feature to check, second level of permission (optional). Can be a 'or' check with 'sublevela|sublevelb'.
@@ -188,11 +188,21 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
//print ", dbtablename=".$dbtablename.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select;
//print ", perm: ".$features."->".$feature2."=".($user->rights->$features->$feature2->lire)." ";
+ if ($features == 'facturerec') $features = 'facture';
+ if ($features == 'mo') $features = 'mrp';
+ if ($features == 'member') $features = 'adherent';
+ if ($features == 'subscription') { $features = 'adherent'; $feature2 = 'cotisation'; };
+
// 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."'";
@@ -311,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 10da4f60fc1..b9a606b98b4 100644
--- a/htdocs/core/lib/security2.lib.php
+++ b/htdocs/core/lib/security2.lib.php
@@ -221,7 +221,7 @@ if (!function_exists('dol_loginfunction'))
// Show logo (search in order: small company logo, large company logo, theme logo, common logo)
$width = 0;
- $urllogo = DOL_URL_ROOT.'/theme/login_logo.png';
+ $urllogo=DOL_URL_ROOT.'/theme/common/login_logo.png';
if (!empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small))
{
@@ -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/ticket.lib.php b/htdocs/core/lib/ticket.lib.php
index b7c741bd839..fe7fb4ba5a7 100644
--- a/htdocs/core/lib/ticket.lib.php
+++ b/htdocs/core/lib/ticket.lib.php
@@ -222,7 +222,7 @@ function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $
// Print logo
if (! empty($conf->global->TICKET_SHOW_COMPANY_LOGO))
{
- $urllogo = DOL_URL_ROOT . '/theme/login_logo.png';
+ $urllogo = DOL_URL_ROOT . '/theme/common/login_logo.png';
if (!empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output . '/logos/thumbs/' . $mysoc->logo_small)) {
$urllogo = DOL_URL_ROOT . '/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file=' . urlencode('logos/thumbs/'.$mysoc->logo_small);
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..2257203d25b 100644
--- a/htdocs/core/lib/website.lib.php
+++ b/htdocs/core/lib/website.lib.php
@@ -51,11 +51,14 @@ function dolStripPhpCode($str, $replacewith = '')
$partlings = 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 ?
//append to out string
- $newstr .= ''.$replacewith.' '.implode('', $partlings);
+ //$newstr .= ''.$replacewith.' '.implode('', $partlings);
+ //$newstr .= ''.$replacewith.' '.implode('', $partlings);
+ $newstr .= ''.$replacewith.' '.implode('', $partlings);
+ //$newstr .= $replacewith.implode('', $partlings);
}
}
}
@@ -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);
// 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 52e41ea2589..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++)
@@ -440,7 +450,12 @@ class pdf_espadon extends ModelePdfExpedition
$pdf->setPage($pageposbefore + 1);
$curY = $tab_top_newpage;
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
@@ -456,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();
@@ -482,7 +497,11 @@ class pdf_espadon extends ModelePdfExpedition
else
{
// We found a page break
- $showpricebeforepagebreak = 0;
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
@@ -516,12 +535,12 @@ class pdf_espadon extends ModelePdfExpedition
$weighttxt = '';
if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->weight)
{
- $weighttxt = round($object->lines[$i]->weight * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "weight", $object->lines[$i]->weight_units);
+ $weighttxt = round($object->lines[$i]->weight * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "weight", $object->lines[$i]->weight_units, 1);
}
$voltxt = '';
if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->volume)
{
- $voltxt = round($object->lines[$i]->volume * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "volume", $object->lines[$i]->volume_units ? $object->lines[$i]->volume_units : 0);
+ $voltxt = round($object->lines[$i]->volume * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "volume", $object->lines[$i]->volume_units ? $object->lines[$i]->volume_units : 0, 1);
}
@@ -549,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))
@@ -560,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));
}
@@ -1090,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
@@ -1127,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
),
);
@@ -1216,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/expedition/doc/pdf_rouget.modules.php b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php
index 0e9db902662..ad0272f46a1 100644
--- a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php
+++ b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php
@@ -452,7 +452,12 @@ class pdf_rouget extends ModelePdfExpedition
$pdf->setPage($pageposbefore + 1);
$curY = $tab_top_newpage;
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
if (isset($imglinesize['width']) && isset($imglinesize['height']))
@@ -494,7 +499,12 @@ class pdf_rouget extends ModelePdfExpedition
else
{
// We found a page break
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
@@ -526,12 +536,12 @@ class pdf_rouget extends ModelePdfExpedition
$weighttxt = '';
if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->weight)
{
- $weighttxt = round($object->lines[$i]->weight * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "weight", $object->lines[$i]->weight_units);
+ $weighttxt = round($object->lines[$i]->weight * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "weight", $object->lines[$i]->weight_units, 1);
}
$voltxt = '';
if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->volume)
{
- $voltxt = round($object->lines[$i]->volume * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "volume", $object->lines[$i]->volume_units ? $object->lines[$i]->volume_units : 0);
+ $voltxt = round($object->lines[$i]->volume * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "volume", $object->lines[$i]->volume_units ? $object->lines[$i]->volume_units : 0, 1);
}
if (empty($conf->global->SHIPPING_PDF_HIDE_WEIGHT_AND_VOLUME))
diff --git a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php
index 71295335460..0adf7cd2a6a 100644
--- a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php
+++ b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php
@@ -383,7 +383,11 @@ class pdf_standard extends ModeleExpenseReport
else
{
// We found a page break
- $showpricebeforepagebreak = 0;
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
@@ -572,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 c3fc7677f80..112a3fec279 100644
--- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
+++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
@@ -492,7 +492,12 @@ class pdf_crabe extends ModelePDFFactures
$pdf->setPage($pageposbefore + 1);
$curY = $tab_top_newpage;
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
if (isset($imglinesize['width']) && isset($imglinesize['height']))
@@ -532,7 +537,12 @@ class pdf_crabe extends ModelePDFFactures
else
{
// We found a page break
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
@@ -1041,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);
}
@@ -1105,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);
@@ -1697,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 b5e94e62aff..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'))
{
@@ -607,7 +614,12 @@ class pdf_sponge extends ModelePDFFactures
$pdf->setPage($pageposbefore + 1);
$curY = $tab_top_newpage;
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height']))
@@ -622,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;
@@ -646,17 +660,20 @@ class pdf_sponge extends ModelePDFFactures
else
{
// We found a page break
- $showpricebeforepagebreak = 0;
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
{
$pdf->commitTransaction();
}
- $posYAfterDescription = $pdf->GetY();
}
- $nexY = $pdf->GetY();
+ $nexY = $pdf->GetY();
$pageposafter = $pdf->getPage();
$pdf->setPage($pageposbefore);
$pdf->setTopMargin($this->marge_haute);
@@ -726,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,
@@ -794,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++;
@@ -819,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
@@ -837,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;
}
@@ -1043,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
@@ -1123,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)
{
@@ -1190,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);
@@ -1214,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
@@ -1780,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)
@@ -1788,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;
@@ -1808,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);
@@ -1835,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;
@@ -1911,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);
@@ -1937,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)
{
@@ -2147,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
@@ -2188,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
),
);
@@ -2295,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
@@ -2306,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 d6c43edd5c3..6c9dd9062a8 100644
--- a/htdocs/core/modules/import/import_csv.modules.php
+++ b/htdocs/core/modules/import/import_csv.modules.php
@@ -123,7 +123,7 @@ class ImportCsv extends ModeleImports
* Output header of an example file for this format
*
* @param Translate $outputlangs Output language
- * @return string
+ * @return string Empty string
*/
public function write_header_example($outputlangs)
{
@@ -137,7 +137,7 @@ class ImportCsv extends ModeleImports
*
* @param Translate $outputlangs Output language
* @param array $headerlinefields Array of fields name
- * @return string$limittoachartaccount
+ * @return string String output
*/
public function write_title_example($outputlangs, $headerlinefields)
{
@@ -152,7 +152,7 @@ class ImportCsv extends ModeleImports
*
* @param Translate $outputlangs Output language
* @param array $contentlinevalues Array of lines
- * @return string
+ * @return string String output
*/
public function write_record_example($outputlangs, $contentlinevalues)
{
@@ -166,7 +166,7 @@ class ImportCsv extends ModeleImports
* Output footer of an example file for this format
*
* @param Translate $outputlangs Output language
- * @return string
+ * @return string Empty string
*/
public function write_footer_example($outputlangs)
{
@@ -175,7 +175,6 @@ class ImportCsv extends ModeleImports
}
-
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Open input file
@@ -426,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";
@@ -449,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);
@@ -465,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/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php
index 03b3f941a1d..09628739494 100644
--- a/htdocs/core/modules/import/import_xlsx.modules.php
+++ b/htdocs/core/modules/import/import_xlsx.modules.php
@@ -130,7 +130,7 @@ class ImportXlsx extends ModeleImports
* Output header of an example file for this format
*
* @param Translate $outputlangs Output language
- * @return string
+ * @return string Empty string
*/
public function write_header_example($outputlangs)
{
@@ -164,7 +164,7 @@ class ImportXlsx extends ModeleImports
*
* @param Translate $outputlangs Output language
* @param array $headerlinefields Array of fields name
- * @return string
+ * @return string String output
*/
public function write_title_example($outputlangs, $headerlinefields)
{
@@ -190,7 +190,7 @@ class ImportXlsx extends ModeleImports
*
* @param Translate $outputlangs Output language
* @param array $contentlinevalues Array of lines
- * @return string
+ * @return string Empty string
*/
public function write_record_example($outputlangs, $contentlinevalues)
{
@@ -210,7 +210,7 @@ class ImportXlsx extends ModeleImports
* Output footer of an example file for this format
*
* @param Translate $outputlangs Output language
- * @return string
+ * @return string String output
*/
public function write_footer_example($outputlangs)
{
@@ -258,7 +258,7 @@ class ImportXlsx extends ModeleImports
* Return nb of records. File must be closed.
*
* @param string $file Path of filename
- * @return int <0 if KO, >=0 if OK
+ * @return int <0 if KO, >=0 if OK
*/
public function import_get_nb_of_lines($file)
{
diff --git a/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php b/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php
index 1b6ddf143e0..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;
@@ -407,7 +407,11 @@ class pdf_typhon extends ModelePDFDeliveryOrder
else
{
// We found a page break
- $showpricebeforepagebreak = 0;
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
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/modContrat.class.php b/htdocs/core/modules/modContrat.class.php
index fe846c1fd4c..3b8a7aa3f8b 100644
--- a/htdocs/core/modules/modContrat.class.php
+++ b/htdocs/core/modules/modContrat.class.php
@@ -165,7 +165,7 @@ class modContrat extends DolibarrModules
$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.code_compta'=>'CustomerAccountancyCode',
's.code_compta_fournisseur'=>'SupplierAccountancyCode','s.tva_intra'=>'VATIntra',
- 'co.rowid'=>"Id",'co.ref'=>"Ref",'co.datec'=>"DateCreation",'co.date_contrat'=>"DateContract",'co.mise_en_service'=>"ContractStartDate",
+ 'co.rowid'=>"Id",'co.ref'=>"Ref",'co.datec'=>"DateCreation",'co.date_contrat'=>"DateContract",
'co.fin_validite'=>"ContractEndDate",'co.date_cloture'=>"Closing",'co.note_private'=>"NotePrivate",'co.note_public'=>"NotePublic",
'cod.rowid'=>'LineId','cod.label'=>"LineLabel",'cod.description'=>"LineDescription",'cod.price_ht'=>"LineUnitPrice",'cod.tva_tx'=>"LineVATRate",
'cod.qty'=>"LineQty",'cod.total_ht'=>"LineTotalHT",'cod.total_tva'=>"LineTotalVAT",'cod.total_ttc'=>"LineTotalTTC",
@@ -175,7 +175,7 @@ class modContrat extends DolibarrModules
$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.code_compta'=>'company','s.code_compta_fournisseur'=>'company','s.tva_intra'=>'company',
- 'co.rowid'=>"contract",'co.ref'=>"contract",'co.datec'=>"contract",'co.date_contrat'=>"contract",'co.mise_en_service'=>"contract",
+ 'co.rowid'=>"contract",'co.ref'=>"contract",'co.datec'=>"contract",'co.date_contrat'=>"contract",
'co.fin_validite'=>"contract",'co.date_cloture'=>"contract",'co.note_private'=>"contract",'co.note_public'=>"contract",
'cod.rowid'=>'contract_line','cod.label'=>"contract_line",'cod.description'=>"contract_line",'cod.price_ht'=>"contract_line",'cod.tva_tx'=>"contract_line",
'cod.qty'=>"contract_line",'cod.total_ht'=>"contract_line",'cod.total_tva'=>"contract_line",'cod.total_ttc'=>"contract_line",
@@ -185,7 +185,7 @@ class modContrat extends DolibarrModules
$this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom",'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',
- 'co.ref'=>"Text",'co.datec'=>"Date",'co.date_contrat'=>"Date",'co.mise_en_service'=>"Date",
+ 'co.ref'=>"Text",'co.datec'=>"Date",'co.date_contrat'=>"Date",
'co.fin_validite'=>"Date",'co.date_cloture'=>"Date",'co.note_private'=>"Text",'co.note_public'=>"Text",
'cod.label'=>"Text",'cod.description'=>"Text",'cod.price_ht'=>"Numeric",'cod.tva_tx'=>"Numeric",
'cod.qty'=>"Numeric",'cod.total_ht'=>"Numeric",'cod.total_tva'=>"Numeric",'cod.total_ttc'=>"Numeric",
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..4f9558de8ae 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
@@ -181,6 +182,7 @@ class modProduct extends DolibarrModules
'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.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",
@@ -203,8 +205,9 @@ class modProduct extends DolibarrModules
$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.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',
@@ -315,6 +318,7 @@ class modProduct extends DolibarrModules
'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",
@@ -325,7 +329,8 @@ class modProduct extends DolibarrModules
$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_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",
@@ -337,7 +342,8 @@ class modProduct extends DolibarrModules
$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.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"
@@ -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' => "",
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..822c6bf699f 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
@@ -148,6 +149,7 @@ class modService extends DolibarrModules
'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.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",
@@ -171,6 +173,7 @@ class modService extends DolibarrModules
'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',
@@ -283,6 +286,7 @@ class modService extends DolibarrModules
'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",
@@ -293,7 +297,8 @@ class modService extends DolibarrModules
$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_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",
@@ -305,7 +310,8 @@ class modService extends DolibarrModules
$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.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"
@@ -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' => "",
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/modTicket.class.php b/htdocs/core/modules/modTicket.class.php
index 8d7f16fcaf7..fbf560565ee 100644
--- a/htdocs/core/modules/modTicket.class.php
+++ b/htdocs/core/modules/modTicket.class.php
@@ -120,16 +120,16 @@ class modTicket extends DolibarrModules
}
$this->dictionaries = array(
'langs' => 'ticket',
- 'tabname' => array(MAIN_DB_PREFIX . "c_ticket_type", MAIN_DB_PREFIX . "c_ticket_severity", MAIN_DB_PREFIX . "c_ticket_category"),
- 'tablib' => array("TicketDictType", "TicketDictSeverity", "TicketDictCategory"),
- 'tabsql' => array('SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticket_type as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticket_severity as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticket_category as f'),
- 'tabsqlsort' => array("pos ASC", "pos ASC", "pos ASC"),
- 'tabfield' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"),
- 'tabfieldvalue' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"),
- 'tabfieldinsert' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"),
- 'tabrowid' => array("rowid", "rowid", "rowid"),
- 'tabcond' => array($conf->ticket->enabled, $conf->ticket->enabled, $conf->ticket->enabled),
- 'tabhelp' => array(array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1"))),
+ 'tabname' => array(MAIN_DB_PREFIX."c_ticket_type", MAIN_DB_PREFIX."c_ticket_severity", MAIN_DB_PREFIX."c_ticket_category", MAIN_DB_PREFIX."c_ticket_resolution"),
+ 'tablib' => array("TicketDictType", "TicketDictSeverity", "TicketDictCategory", "TicketDictResolution"),
+ 'tabsql' => array('SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM '.MAIN_DB_PREFIX.'c_ticket_type as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM '.MAIN_DB_PREFIX.'c_ticket_severity as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM '.MAIN_DB_PREFIX.'c_ticket_category as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM '.MAIN_DB_PREFIX.'c_ticket_resolution as f'),
+ 'tabsqlsort' => array("pos ASC", "pos ASC", "pos ASC", "pos ASC"),
+ 'tabfield' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"),
+ 'tabfieldvalue' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"),
+ 'tabfieldinsert' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"),
+ 'tabrowid' => array("rowid", "rowid", "rowid", "rowid"),
+ 'tabcond' => array($conf->ticket->enabled, $conf->ticket->enabled, $conf->ticket->enabled, $conf->ticket->enabled),
+ 'tabhelp' => array(array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1"))),
);
// Boxes
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/doc/pdf_baleine.modules.php b/htdocs/core/modules/project/doc/pdf_baleine.modules.php
index 910ef3ec1cf..79941dba8d6 100644
--- a/htdocs/core/modules/project/doc/pdf_baleine.modules.php
+++ b/htdocs/core/modules/project/doc/pdf_baleine.modules.php
@@ -362,7 +362,13 @@ class pdf_baleine extends ModelePDFProjects
else
{
// We found a page break
- $showpricebeforepagebreak=0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
+
$forcedesconsamepage=1;
if ($forcedesconsamepage)
{
diff --git a/htdocs/core/modules/project/doc/pdf_beluga.modules.php b/htdocs/core/modules/project/doc/pdf_beluga.modules.php
index b26b46604ff..4072f22bf58 100644
--- a/htdocs/core/modules/project/doc/pdf_beluga.modules.php
+++ b/htdocs/core/modules/project/doc/pdf_beluga.modules.php
@@ -512,7 +512,13 @@ class pdf_beluga extends ModelePDFProjects
else
{
// We found a page break
- $showpricebeforepagebreak=0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
+
$forcedesconsamepage=1;
if ($forcedesconsamepage)
{
diff --git a/htdocs/core/modules/project/doc/pdf_timespent.modules.php b/htdocs/core/modules/project/doc/pdf_timespent.modules.php
index 27822545fa2..0c1eba3c9ac 100644
--- a/htdocs/core/modules/project/doc/pdf_timespent.modules.php
+++ b/htdocs/core/modules/project/doc/pdf_timespent.modules.php
@@ -293,7 +293,13 @@ class pdf_timespent extends ModelePDFProjects
else
{
// We found a page break
- $showpricebeforepagebreak=0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
+
$forcedesconsamepage=1;
if ($forcedesconsamepage)
{
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 fada0b8a142..0167d900b3f 100644
--- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php
+++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php
@@ -500,7 +500,12 @@ class pdf_azur extends ModelePDFPropales
$pdf->setPage($pageposbefore + 1);
$curY = $tab_top_newpage;
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
if (isset($imglinesize['width']) && isset($imglinesize['height']))
@@ -541,7 +546,12 @@ class pdf_azur extends ModelePDFPropales
else
{
// We found a page break
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
@@ -1091,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);
@@ -1123,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++;
@@ -1138,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);
@@ -1182,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
{
@@ -1195,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);
}
@@ -1214,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
@@ -1228,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);
@@ -1466,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;
@@ -1518,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 a14c087dbf7..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();
@@ -592,7 +598,12 @@ class pdf_cyan extends ModelePDFPropales
$pdf->setPage($pageposbefore + 1);
$curY = $tab_top_newpage;
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
@@ -608,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();
@@ -634,7 +647,11 @@ class pdf_cyan extends ModelePDFPropales
else
{
// We found a page break
- $showpricebeforepagebreak = 0;
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
@@ -708,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,
@@ -766,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)
@@ -1579,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);
@@ -1788,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
@@ -1825,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
),
);
@@ -1919,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
@@ -1930,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/reception/doc/pdf_squille.modules.php b/htdocs/core/modules/reception/doc/pdf_squille.modules.php
index 125c56960ca..f1c2eba89e4 100644
--- a/htdocs/core/modules/reception/doc/pdf_squille.modules.php
+++ b/htdocs/core/modules/reception/doc/pdf_squille.modules.php
@@ -374,7 +374,12 @@ class pdf_squille extends ModelePdfReception
$pdf->setPage($pageposbefore + 1);
$curY = $tab_top_newpage;
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
if (isset($imglinesize['width']) && isset($imglinesize['height']))
@@ -417,7 +422,12 @@ class pdf_squille extends ModelePdfReception
else
{
// We found a page break
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
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 97c0744c121..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
@@ -383,7 +383,12 @@ class pdf_standard extends ModelePDFStock
else
{
// We found a page break
- $showpricebeforepagebreak=0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
diff --git a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php
index 4f59c2510b4..362f17c7e9c 100644
--- a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php
+++ b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php
@@ -543,7 +543,12 @@ class pdf_stdmovement extends ModelePDFMovement
else
{
// We found a page break
- $showpricebeforepagebreak=0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
diff --git a/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php b/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php
index f318237a43e..a484343b1c0 100644
--- a/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php
+++ b/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php
@@ -428,7 +428,11 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
else
{
// We found a page break
- $showpricebeforepagebreak=0;
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
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 2a2916cf253..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);
@@ -526,7 +531,12 @@ class pdf_cornas extends ModelePDFSuppliersOrders
$pdf->setPage($pageposbefore + 1);
$curY = $tab_top_newpage;
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
if (!empty($imglinesize['width']) && !empty($imglinesize['height']))
@@ -543,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
@@ -567,7 +577,11 @@ class pdf_cornas extends ModelePDFSuppliersOrders
else
{
// We found a page break
- $showpricebeforepagebreak = 0;
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
@@ -640,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,
@@ -697,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)
{
@@ -1456,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
@@ -1493,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
),
);
@@ -1587,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
@@ -1598,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,
@@ -1621,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/doc/pdf_muscadet.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php
index 395e461e807..e4cb8f53e66 100644
--- a/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php
+++ b/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php
@@ -443,7 +443,12 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
$pdf->setPage($pageposbefore + 1);
$curY = $tab_top_newpage;
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
if (!empty($imglinesize['width']) && !empty($imglinesize['height']))
@@ -490,7 +495,11 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
else
{
// We found a page break
- $showpricebeforepagebreak = 0;
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
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/doc/pdf_standard.modules.php b/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php
index 2a6112db9e2..0ad8b391faf 100644
--- a/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php
+++ b/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php
@@ -363,7 +363,11 @@ class pdf_standard extends ModelePDFSuppliersPayments
else
{
// We found a page break
- $showpricebeforepagebreak = 0;
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
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/doc/pdf_aurore.modules.php b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php
index db5c5501d53..afaf4987e04 100644
--- a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php
+++ b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php
@@ -428,7 +428,12 @@ class pdf_aurore extends ModelePDFSupplierProposal
$pdf->setPage($pageposbefore + 1);
$curY = $tab_top_newpage;
- $showpricebeforepagebreak = 0;
+
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
if (!empty($imglinesize['width']) && !empty($imglinesize['height']))
@@ -478,7 +483,11 @@ class pdf_aurore extends ModelePDFSupplierProposal
else
{
// We found a page break
- $showpricebeforepagebreak = 0;
+ // 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))
+ $showpricebeforepagebreak = 1;
+ else
+ $showpricebeforepagebreak = 0;
}
}
else // No pagebreak
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/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..8859ce4ba9d 100644
--- a/htdocs/core/tpl/admin_extrafields_add.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php
@@ -148,7 +148,7 @@ $langs->load("modulebuilder");
trans("LabelOrTranslationKey"); ?>
-trans("AttributeCode"); ?> (trans("AlphaNumOnlyLowerCharsAndNoSpace"); ?>)
+trans("AttributeCode"); ?> (trans("AlphaNumOnlyLowerCharsAndNoSpace"); ?>)
trans("Type"); ?>
selectarray('type', $type2label, GETPOST('type', 'alpha')); ?>
@@ -196,6 +196,9 @@ $langs->load("modulebuilder");
+
+
diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php
index 4063111a6fb..4dc47bbf031 100644
--- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php
@@ -165,6 +165,7 @@ $list=$extrafields->attributes[$elementtype]['list'][$attrname];
$totalizable = $extrafields->attributes[$elementtype]['totalizable'][$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))
{
@@ -261,8 +262,12 @@ else
+
+
+
textwithpicto($langs->trans("HelpOnTooltip"), $langs->trans("HelpOnTooltipDesc")); ?>
@@ -270,7 +275,6 @@ else
trans("AllEntities"); ?> >
-
diff --git a/htdocs/core/tpl/admin_extrafields_view.tpl.php b/htdocs/core/tpl/admin_extrafields_view.tpl.php
index 0ddd3f5a8fa..a59350d8678 100644
--- a/htdocs/core/tpl/admin_extrafields_view.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_view.tpl.php
@@ -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 ' ';
@@ -92,6 +93,7 @@ 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)) {
print '';
diff --git a/htdocs/core/tpl/advtarget.tpl.php b/htdocs/core/tpl/advtarget.tpl.php
index 478c2dfa4b8..b3b6b5d1bf1 100644
--- a/htdocs/core/tpl/advtarget.tpl.php
+++ b/htdocs/core/tpl/advtarget.tpl.php
@@ -58,24 +58,27 @@ print ''."\n";
print ''."\n";
print ''."\n";
-print ' '."\n";
+print ' '."\n";
print ' '."\n";
print ' '."\n";
-print ''.$langs->trans('AdvTgtNameTemplate').' ';
+print ' '.$langs->trans('AdvTgtNameTemplate').' ';
if (!empty($template_id)) {
$default_template = $template_id;
} else {
$default_template = $advTarget->id;
}
-print $formadvtargetemaling->selectAdvtargetemailingTemplate('template_id', $default_template, 0, $advTarget->type_element);
-print ' ';
-print ' ';
-print ' ';
-print $langs->trans('AdvTgtOrCreateNewFilter');
+print $formadvtargetemaling->selectAdvtargetemailingTemplate('template_id', $default_template, 0, $advTarget->type_element, 'valignmiddle');
+print ' ';
+print ' ';
+print ' ';
+print ' ' . "\n";
+print ' ' . "\n";
+
+print '' . $langs->trans('AdvTgtOrCreateNewFilter') . ' ';
print ' ';
-print ' ';
+print ' ';
print ' '."\n";
print ' '."\n";
diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php
index 1a9a046bf81..795483b08ba 100644
--- a/htdocs/core/tpl/card_presend.tpl.php
+++ b/htdocs/core/tpl/card_presend.tpl.php
@@ -188,7 +188,8 @@ if ($action == 'presend')
}
}
- $formmail->withto = GETPOST('sendto') ? GETPOST('sendto') : $liste;
+ $formmail->withto = $liste;
+ $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..e6de4520ba4 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);
";
-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);
}
- ?>
-
-
-
-
-
- \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'));
@@ -248,3 +318,4 @@ if (is_object($hookmanager)) {
$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..2ef606afa0b 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..8a04aa32dea 100644
--- a/htdocs/core/tpl/extrafields_edit.tpl.php
+++ b/htdocs/core/tpl/extrafields_edit.tpl.php
@@ -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_list_search_param.tpl.php b/htdocs/core/tpl/extrafields_list_search_param.tpl.php
index ca72293365a..6e6d6305106 100644
--- a/htdocs/core/tpl/extrafields_list_search_param.tpl.php
+++ b/htdocs/core/tpl/extrafields_list_search_param.tpl.php
@@ -8,7 +8,7 @@ if (empty($conf) || !is_object($conf))
}
// Loop to complete $param for extrafields
-if (!empty($search_array_options)) // $extrafieldsobject is the $object->table_element like 'societe', 'socpeople', ...
+if (!empty($search_array_options) && is_array($search_array_options)) // $extrafieldsobject is the $object->table_element like 'societe', 'socpeople', ...
{
if (empty($search_options_pattern)) $search_options_pattern = 'search_options_';
diff --git a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php
index 29c67094975..3a0bcf6375c 100644
--- a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php
+++ b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php
@@ -40,7 +40,10 @@ if (! empty($extrafieldsobjectkey) && ! empty($search_array_options) && is_array
if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int
if (in_array($typ, array('chkbxlst','checkbox'))) $mode_search=4; // Search on a multiselect field with sql type = text
if (is_array($crit)) $crit = implode(' ', $crit); // natural_search() expects a string
-
+ elseif ($typ === 'select' and is_string($crit) and strpos($crit, ' ') === false) {
+ $sql .= ' AND (' . $extrafieldsobjectprefix.$tmpkey . ' = "' . $db->escape($crit) . '")';
+ continue;
+ }
$sql .= natural_search($extrafieldsobjectprefix.$tmpkey, $crit, $mode_search);
}
}
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..4e636f3d9cf 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)
);
@@ -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 = parseInt($('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..66e1b6fa4cd 100644
--- a/htdocs/core/triggers/interface_20_all_Logevents.class.php
+++ b/htdocs/core/triggers/interface_20_all_Logevents.class.php
@@ -206,9 +206,10 @@ class InterfaceLogevents extends DolibarrTriggers
else
{
$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..161ebe6cd73 100644
--- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
+++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
@@ -829,7 +829,7 @@ class InterfaceActionsAuto extends DolibarrTriggers
$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
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/dav/dav.class.php b/htdocs/dav/dav.class.php
index 7bb598135f3..145da542976 100644
--- a/htdocs/dav/dav.class.php
+++ b/htdocs/dav/dav.class.php
@@ -175,7 +175,7 @@ class CdavLib
$caldata.="LAST-MODIFIED:".gmdate('Ymd\THis', strtotime($obj->lastupd))."Z\n";
$caldata.="DTSTAMP:".gmdate('Ymd\THis', strtotime($obj->lastupd))."Z\n";
if($obj->sourceuid=='')
- $caldata.="UID:".$obj->id.'-ev-'.$calid.'-cal-'.CDAV_URI_KEY."\n";
+ $caldata.="UID:".$obj->id.'-ev-'.$calid.'-cal-'.constant('CDAV_URI_KEY')."\n";
else
$caldata.="UID:".$obj->sourceuid."\n";
$caldata.="SUMMARY:".$obj->label."\n";
@@ -277,7 +277,7 @@ class CdavLib
{
$calevents[] = array(
'calendardata' => $calendardata,
- 'uri' => $obj->id.'-ev-'.CDAV_URI_KEY,
+ 'uri' => $obj->id.'-ev-'.constant('CDAV_URI_KEY'),
'lastmodified' => strtotime($obj->lastupd),
'etag' => '"'.md5($calendardata).'"',
'calendarid' => $calendarId,
@@ -289,7 +289,7 @@ class CdavLib
{
$calevents[] = array(
// 'calendardata' => $calendardata, not necessary because etag+size are present
- 'uri' => $obj->id.'-ev-'.CDAV_URI_KEY,
+ 'uri' => $obj->id.'-ev-'.constant('CDAV_URI_KEY'),
'lastmodified' => strtotime($obj->lastupd),
'etag' => '"'.md5($calendardata).'"',
'calendarid' => $calendarId,
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/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..3cd49a20649 100644
--- a/htdocs/don/list.php
+++ b/htdocs/don/list.php
@@ -43,7 +43,7 @@ $pagenext = $page + 1;
if (! $sortorder) $sortorder="DESC";
if (! $sortfield) $sortfield="d.datedon";
-$search_status=(GETPOST("search_status", 'intcomma') != '') ? GETPOST("search_status", 'intcomma') : "-1";
+$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');
@@ -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
@@ -91,7 +92,7 @@ $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')
+if ($search_status != '' && $search_status != '-4')
{
$sql .= " AND d.fk_statut IN (".$db->escape($search_status).")";
}
@@ -196,7 +197,15 @@ 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);
print $searchpicto;
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/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php
index e6968109bf7..57311c2e437 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
{
@@ -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)
{
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 a3f5f21659d..4c6b7f46e47 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;
@@ -447,7 +448,7 @@ class Expedition extends CommonObject
* @param array $array_options extrafields array
* @return int <0 if KO, line_id if OK
*/
- public function create_line($entrepot_id, $origin_line_id, $qty, $rang, $array_options = 0)
+ public function create_line($entrepot_id, $origin_line_id, $qty, $rang = 0, $array_options = 0)
{
//phpcs:enable
global $user;
@@ -523,15 +524,15 @@ 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";
@@ -551,7 +552,7 @@ class Expedition extends CommonObject
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)."'";
+ if ($notused) $sql.= " AND e.ref_int='".$this->db->escape($notused)."'";
dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
$result = $this->db->query($sql);
@@ -697,7 +698,7 @@ class Expedition extends CommonObject
{
$numref = "EXP".$this->id;
}
- $this->newref = $numref;
+ $this->newref = dol_sanitizeFileName($numref);
$now = dol_now();
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/index.php b/htdocs/expensereport/index.php
index ec6f78d91f7..77cf3bb481e 100644
--- a/htdocs/expensereport/index.php
+++ b/htdocs/expensereport/index.php
@@ -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/payment/payment.php b/htdocs/expensereport/payment/payment.php
index 2f915b3f8e8..15073c50620 100644
--- a/htdocs/expensereport/payment/payment.php
+++ b/htdocs/expensereport/payment/payment.php
@@ -248,14 +248,14 @@ if ($action == 'create' || empty($action))
print ''."\n";
print ''.$langs->trans("Date").' ';
- $datepaid = dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]);
+ $datepaid = dol_mktime(12, 0, 0, GETPOST("remonth", 'int'), GETPOST("reday", 'int'), GETPOST("reyear", 'int'));
$datepayment=empty($conf->global->MAIN_AUTOFILL_DATE)?(empty($_POST["remonth"])?-1:$datepaid):0;
print $form->selectDate($datepayment, '', '', '', '', "add_payment", 1, 1);
print " ";
print ' ';
print ''.$langs->trans("PaymentMode").' ';
- $form->select_types_paiements(isset($_POST["fk_typepayment"])?$_POST["fk_typepayment"]:$expensereport->fk_typepayment, "fk_typepayment");
+ $form->select_types_paiements(GETPOSTISSET("fk_typepayment") ? GETPOST("fk_typepayment", 'alpha') : $expensereport->fk_c_paiement, "fk_typepayment");
print " \n";
print ' ';
@@ -264,7 +264,7 @@ if ($action == 'create' || empty($action))
print '';
print ''.$langs->trans('AccountToDebit').' ';
print '';
- $form->select_comptes(isset($_POST["accountid"])?$_POST["accountid"]:$expensereport->accountid, "accountid", 0, '', 1); // Show open bank account list
+ $form->select_comptes(GETPOSTISSET("accountid") ? GETPOST("accountid", "int") : $expensereport->accountid, "accountid", 0, '', 1); // Show open bank account list
print ' ';
}
diff --git a/htdocs/exports/class/export.class.php b/htdocs/exports/class/export.class.php
index 78d8ea09166..bf00027b58a 100644
--- a/htdocs/exports/class/export.class.php
+++ b/htdocs/exports/class/export.class.php
@@ -547,7 +547,7 @@ class Export
$indice = 0;
asort($array_selected);
- dol_syslog(get_class($this)."::".__FUNCTION__." ".$model.", ".$datatoexport.", ".implode(",", $array_selected));
+ dol_syslog(__METHOD__." ".$model.", ".$datatoexport.", ".implode(",", $array_selected));
// Check parameters or context properties
if (empty($this->array_export_fields) || !is_array($this->array_export_fields))
@@ -588,7 +588,7 @@ class Export
// Run the sql
$this->sqlusedforexport = $sql;
- dol_syslog(get_class($this)."::".__FUNCTION__."", LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql)
{
diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php
index f910001a5e0..6543747d1f7 100644
--- a/htdocs/exports/export.php
+++ b/htdocs/exports/export.php
@@ -33,7 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/export/modules_export.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
// Load translation files required by the page
-$langs->loadlangs(array('admin', 'exports', 'other', 'users', 'companies', 'projects', 'suppliers', 'products', 'bank'));
+$langs->loadlangs(array('admin', 'exports', 'other', 'users', 'companies', 'projects', 'suppliers', 'products', 'bank', 'bills'));
// Everybody should be able to go on this page
//if (! $user->admin)
@@ -147,6 +147,7 @@ $htmlother = new FormOther($db);
$formfile = new FormFile($db);
$sqlusedforexport = '';
+$head = array();
$upload_dir = $conf->export->dir_temp.'/'.$user->id;
//$usefilters=($conf->global->MAIN_FEATURES_LEVEL > 1);
@@ -410,12 +411,12 @@ if ($step == 4 && $action == 'submitFormField')
$newcode = (string) preg_replace('/\./', '_', $code);
//print 'xxx'.$code."=".$newcode."=".$type."=".$_POST[$newcode]."\n ";
$filterqualified = 1;
- if (!isset($_POST[$newcode]) || $_POST[$newcode] == '') $filterqualified = 0;
- elseif (preg_match('/^List/', $type) && (is_numeric($_POST[$newcode]) && $_POST[$newcode] <= 0)) $filterqualified = 0;
+ if (!GETPOSTISSET($newcode) || GETPOST($newcode, 'restricthtml') == '') $filterqualified = 0;
+ elseif (preg_match('/^List/', $type) && (is_numeric(GETPOST($newcode, 'restricthtml')) && GETPOST($newcode, 'restricthtml') <= 0)) $filterqualified = 0;
if ($filterqualified)
{
//print 'Filter on '.$newcode.' type='.$type.' value='.$_POST[$newcode]."\n";
- $objexport->array_export_FilterValue[0][$code] = $_POST[$newcode];
+ $objexport->array_export_FilterValue[0][$code] = GETPOST($newcode, 'restricthtml');
}
}
$array_filtervalue = (!empty($objexport->array_export_FilterValue[0]) ? $objexport->array_export_FilterValue[0] : '');
@@ -938,7 +939,7 @@ if ($step == 4 && $datatoexport)
// List of filtered fiels
if (isset($objexport->array_export_TypeFields[0]) && is_array($objexport->array_export_TypeFields[0]))
{
- print ''.$langs->trans("FilteredFields").' ';
+ print ''.$langs->trans("FilteredFields").' ';
$list = '';
if (!empty($array_filtervalue))
{
@@ -952,7 +953,7 @@ if ($step == 4 && $datatoexport)
}
}
}
- print ''.(!empty($list) ? $list : $langs->trans("None")).' ';
+ print ''.(!empty($list) ? $list : ''.$langs->trans("None").' ').' ';
print ' ';
}
@@ -1266,22 +1267,17 @@ if ($step == 5 && $datatoexport)
print '';
- print '';
-
if ($sqlusedforexport && $user->admin)
{
- print '';
- print info_admin($langs->trans("SQLUsedForExport").': '.$sqlusedforexport);
- print ' ';
+ print info_admin($langs->trans("SQLUsedForExport").': '.$sqlusedforexport, 0, 0, 1, '', 'TechnicalInformation');
}
- print '
';
if (!is_dir($conf->export->dir_temp)) dol_mkdir($conf->export->dir_temp);
// Show existing generated documents
// NB: La fonction show_documents rescanne les modules qd genallowed=1, sinon prend $liste
- print $formfile->showdocuments('export', '', $upload_dir, $_SERVER["PHP_SELF"].'?step=5&datatoexport='.$datatoexport, $liste, 1, (!empty($_POST['model']) ? $_POST['model'] : 'csv'), 1, 1, 0, 0, 0, '', ' ', '', '', '');
+ print $formfile->showdocuments('export', '', $upload_dir, $_SERVER["PHP_SELF"].'?step=5&datatoexport='.$datatoexport, $liste, 1, (!empty($_POST['model']) ? $_POST['model'] : 'csv'), 1, 1, 0, 0, 0, '', 'none', '', '', '');
}
llxFooter();
diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php
index c096a889ab4..ad96829d7b9 100644
--- a/htdocs/fichinter/card.php
+++ b/htdocs/fichinter/card.php
@@ -96,6 +96,8 @@ if ($id > 0 || !empty($ref))
$permissionnote = $user->rights->ficheinter->creer; // Used by the include of actions_setnotes.inc.php
$permissiondellink = $user->rights->ficheinter->creer; // Used by the include of actions_dellink.inc.php
+$error = 0;
+
/*
* Actions
@@ -284,99 +286,100 @@ if (empty($reshook))
$lines = $srcobject->lines;
}
- $fk_parent_line = 0;
- $num = count($lines);
+ if (is_array($lines)) {
+ $num = count($lines);
- for ($i = 0; $i < $num; $i++)
- {
- $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : Product::TYPE_PRODUCT);
+ for ($i = 0; $i < $num; $i++)
+ {
+ $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : Product::TYPE_PRODUCT);
- if ($product_type == Product::TYPE_SERVICE || !empty($conf->global->FICHINTER_PRINT_PRODUCTS)) { //only services except if config includes products
- $duration = 3600; // Default to one hour
+ if ($product_type == Product::TYPE_SERVICE || !empty($conf->global->FICHINTER_PRINT_PRODUCTS)) { //only services except if config includes products
+ $duration = 3600; // Default to one hour
- // Predefined products & services
- if ($lines[$i]->fk_product > 0)
- {
- $prod = new Product($db);
- $prod->id = $lines[$i]->fk_product;
+ // Predefined products & services
+ if ($lines[$i]->fk_product > 0)
+ {
+ $prod = new Product($db);
+ $prod->id = $lines[$i]->fk_product;
- // Define output language
- if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) {
- $prod->getMultiLangs();
- // We show if duration is present on service (so we get it)
- $prod->fetch($lines[$i]->fk_product);
- $outputlangs = $langs;
- $newlang = '';
- if (empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09');
- if (empty($newlang)) $newlang = $srcobject->thirdparty->default_lang;
- if (!empty($newlang)) {
- $outputlangs = new Translate("", $conf);
- $outputlangs->setDefaultLang($newlang);
+ // Define output language
+ if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) {
+ $prod->getMultiLangs();
+ // We show if duration is present on service (so we get it)
+ $prod->fetch($lines[$i]->fk_product);
+ $outputlangs = $langs;
+ $newlang = '';
+ if (empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09');
+ if (empty($newlang)) $newlang = $srcobject->thirdparty->default_lang;
+ if (!empty($newlang)) {
+ $outputlangs = new Translate("", $conf);
+ $outputlangs->setDefaultLang($newlang);
+ }
+ $label = (!empty($prod->multilangs[$outputlangs->defaultlang]["libelle"])) ? $prod->multilangs[$outputlangs->defaultlang]["libelle"] : $lines[$i]->product_label;
+ } else {
+ $prod->fetch($lines[$i]->fk_product);
+ $label = $lines[$i]->product_label;
}
- $label = (!empty($prod->multilangs[$outputlangs->defaultlang]["libelle"])) ? $prod->multilangs[$outputlangs->defaultlang]["libelle"] : $lines[$i]->product_label;
- } else {
- $prod->fetch($lines[$i]->fk_product);
- $label = $lines[$i]->product_label;
- }
- if ($prod->duration_value && $conf->global->FICHINTER_USE_SERVICE_DURATION) {
- switch ($prod->duration_unit) {
- default:
- case 'h':
- $mult = 3600;
- break;
- case 'd':
- $mult = 3600 * 24;
- break;
- case 'w':
- $mult = 3600 * 24 * 7;
- break;
- case 'm':
- $mult = (int) 3600 * 24 * (365 / 12); // Average month duration
- break;
- case 'y':
- $mult = 3600 * 24 * 365;
- break;
+ if ($prod->duration_value && $conf->global->FICHINTER_USE_SERVICE_DURATION) {
+ switch ($prod->duration_unit) {
+ default:
+ case 'h':
+ $mult = 3600;
+ break;
+ case 'd':
+ $mult = 3600 * 24;
+ break;
+ case 'w':
+ $mult = 3600 * 24 * 7;
+ break;
+ case 'm':
+ $mult = (int) 3600 * 24 * (365 / 12); // Average month duration
+ break;
+ case 'y':
+ $mult = 3600 * 24 * 365;
+ break;
+ }
+ $duration = $prod->duration_value * $mult * $lines[$i]->qty;
}
- $duration = $prod->duration_value * $mult * $lines[$i]->qty;
- }
- $desc = $lines[$i]->product_ref;
- $desc .= ' - ';
- $desc .= $label;
+ $desc = $lines[$i]->product_ref;
+ $desc .= ' - ';
+ $desc .= $label;
+ $desc .= ' ';
+ }
+ // Common part (predefined or free line)
+ $desc .= dol_htmlentitiesbr($lines[$i]->desc);
$desc .= ' ';
- }
- // Common part (predefined or free line)
- $desc .= dol_htmlentitiesbr($lines[$i]->desc);
- $desc .= ' ';
- $desc .= ' ('.$langs->trans('Quantity').': '.$lines[$i]->qty.')';
+ $desc .= ' ('.$langs->trans('Quantity').': '.$lines[$i]->qty.')';
- $timearray = dol_getdate(mktime());
- $date_intervention = dol_mktime(0, 0, 0, $timearray['mon'], $timearray['mday'], $timearray['year']);
+ $timearray = dol_getdate(dol_now());
+ $date_intervention = dol_mktime(0, 0, 0, $timearray['mon'], $timearray['mday'], $timearray['year']);
- if ($product_type == Product::TYPE_PRODUCT) {
- $duration = 0;
- }
+ if ($product_type == Product::TYPE_PRODUCT) {
+ $duration = 0;
+ }
- $predef = '';
+ $predef = '';
- // Extrafields
- $extrafields->fetch_name_optionals_label($object->table_element_line);
- $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
+ // Extrafields
+ $extrafields->fetch_name_optionals_label($object->table_element_line);
+ $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
- $result = $object->addline(
- $user,
- $id,
- $desc,
- $date_intervention,
- $duration,
- $array_options
- );
+ $result = $object->addline(
+ $user,
+ $id,
+ $desc,
+ $date_intervention,
+ $duration,
+ $array_options
+ );
- if ($result < 0)
- {
- $error++;
- break;
+ if ($result < 0)
+ {
+ $error++;
+ break;
+ }
}
}
}
@@ -818,10 +821,7 @@ llxHeader('', $langs->trans("Intervention"));
if ($action == 'create')
{
- /*
- * Mode creation
- * Creation d'une nouvelle fiche d'intervention
- */
+ // Create new intervention
$soc = new Societe($db);
@@ -831,11 +831,12 @@ if ($action == 'create')
if ($socid) $res = $soc->fetch($socid);
- if (GETPOST('origin') && GETPOST('originid'))
+ if (GETPOST('origin', 'alphanohtml') && GETPOST('originid', 'int'))
{
// Parse element/subelement (ex: project_task)
- $element = $subelement = GETPOST('origin');
- if (preg_match('/^([^_]+)_([^_]+)/i', GETPOST('origin'), $regs))
+ $regs = array();
+ $element = $subelement = GETPOST('origin', 'alphanohtml');
+ if (preg_match('/^([^_]+)_([^_]+)/i', GETPOST('origin', 'alphanohtml'), $regs))
{
$element = $regs[1];
$subelement = $regs[2];
@@ -843,7 +844,7 @@ if ($action == 'create')
if ($element == 'project')
{
- $projectid = GETPOST('originid');
+ $projectid = GETPOST('originid', 'int');
}
else
{
@@ -941,7 +942,7 @@ if ($action == 'create')
$numprojet = $formproject->select_projects($soc->id, $projectid, 'projectid');
if ($numprojet == 0)
{
- print ' '.$langs->trans("AddProject").' ';
+ print ' ';
}
print '';
}
@@ -954,7 +955,7 @@ if ($action == 'create')
$numcontrat = $formcontract->select_contract($soc->id, GETPOST('contratid', 'int'), 'contratid', 0, 1);
if ($numcontrat == 0)
{
- print ' '.$langs->trans("AddContract").' ';
+ print ' ';
}
print '';
}
@@ -1063,9 +1064,11 @@ if ($action == 'create')
}
else
{
+ print '';
+ print ' ';
+
dol_fiche_head('');
- print ' ';
if (is_object($objectsrc))
{
print ' ';
@@ -1076,6 +1079,7 @@ if ($action == 'create')
print '';
print ''.$langs->trans("ThirdParty").' ';
print $form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300');
+ print ' ';
print ' ';
print '
';
diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php
index 9f180fc24b0..1ae4364a77d 100644
--- a/htdocs/fichinter/class/fichinter.class.php
+++ b/htdocs/fichinter/class/fichinter.class.php
@@ -36,6 +36,35 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
*/
class Fichinter extends CommonObject
{
+
+ public $fields=array(
+ 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
+ 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>15),
+ 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>20),
+ 'fk_contrat' =>array('type'=>'integer', 'label'=>'Fk contrat', 'enabled'=>1, 'visible'=>-1, 'position'=>25),
+ 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>30),
+ 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>35),
+ 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>40, 'index'=>1),
+ 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>45),
+ 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>50),
+ 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>55),
+ 'datei' =>array('type'=>'date', 'label'=>'Datei', 'enabled'=>1, 'visible'=>-1, 'position'=>60),
+ 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>65),
+ 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>70),
+ 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>75),
+ 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Fk statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500),
+ 'dateo' =>array('type'=>'date', 'label'=>'Dateo', 'enabled'=>1, 'visible'=>-1, 'position'=>85),
+ 'datee' =>array('type'=>'date', 'label'=>'Datee', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
+ 'datet' =>array('type'=>'date', 'label'=>'Datet', 'enabled'=>1, 'visible'=>-1, 'position'=>95),
+ 'duree' =>array('type'=>'double', 'label'=>'Duree', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
+ 'description' =>array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>105,'showoncombobox'=>1),
+ 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>110),
+ 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>115),
+ 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>120),
+ 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
+ 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>130),
+ 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>135),
+ );
/**
* @var string ID to identify managed object
*/
@@ -544,7 +573,7 @@ class Fichinter extends CommonObject
{
$num = $this->ref;
}
- $this->newref = $num;
+ $this->newref = dol_sanitizeFileName($num);
$sql = "UPDATE ".MAIN_DB_PREFIX."fichinter";
$sql .= " SET fk_statut = 1";
@@ -753,8 +782,10 @@ class Fichinter extends CommonObject
$result = '';
$label = ''.$langs->trans("ShowIntervention").' ';
- if (!empty($this->ref))
- $label .= ''.$langs->trans('Ref').': '.$this->ref;
+ $label .= ''.$langs->trans('Ref').': '.$this->ref;
+ if (isset($this->statut)) {
+ $label .= ''.$langs->trans("Status").": ".$this->getLibStatut(5);
+ }
$url = DOL_URL_ROOT.'/fichinter/card.php?id='.$this->id;
diff --git a/htdocs/fichinter/class/fichinterrec.class.php b/htdocs/fichinter/class/fichinterrec.class.php
index 92a42d1ffdf..4a6dab2dd8c 100644
--- a/htdocs/fichinter/class/fichinterrec.class.php
+++ b/htdocs/fichinter/class/fichinterrec.class.php
@@ -243,10 +243,9 @@ class FichinterRec extends Fichinter
* @param int $rowid Id of object to load
* @param string $ref Reference of fichinter
* @param string $ref_ext External reference of fichinter
- * @param int $ref_int Internal reference of other object
* @return int >0 if OK, <0 if KO, 0 if not found
*/
- public function fetch($rowid = 0, $ref = '', $ref_ext = '', $ref_int = '')
+ public function fetch($rowid = 0, $ref = '', $ref_ext = '')
{
$sql = 'SELECT f.titre, f.fk_soc';
$sql .= ', f.datec, f.duree, f.fk_projet, f.fk_contrat, f.description';
@@ -258,11 +257,6 @@ class FichinterRec extends Fichinter
if ($rowid > 0) $sql .= ' WHERE f.rowid='.$rowid;
elseif ($ref) $sql .= " WHERE f.titre='".$this->db->escape($ref)."'";
- /* This field are not used for template fichinter
- 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)."'";
- */
-
dol_syslog(get_class($this)."::fetch rowid=".$rowid, LOG_DEBUG);
$result = $this->db->query($sql);
diff --git a/htdocs/fichinter/class/fichinterstats.class.php b/htdocs/fichinter/class/fichinterstats.class.php
index 98eb218e9ef..0a4daa03955 100644
--- a/htdocs/fichinter/class/fichinterstats.class.php
+++ b/htdocs/fichinter/class/fichinterstats.class.php
@@ -191,10 +191,11 @@ class FichinterStats 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 = 0)
{
global $user;
@@ -208,6 +209,6 @@ class FichinterStats extends Stats
$sql.= $this->db->order('nb', 'DESC');
//$sql.= $this->db->plimit(20);
- return $this->_getAllByProduct($sql);
+ return $this->_getAllByProduct($sql, $limit);
}
}
diff --git a/htdocs/fichinter/index.php b/htdocs/fichinter/index.php
index cd18699ccdb..6bde087fa61 100644
--- a/htdocs/fichinter/index.php
+++ b/htdocs/fichinter/index.php
@@ -140,10 +140,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);
$data = array('series'=>$dataseries);
diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php
index 03000bdb44d..71e251fd9e7 100644
--- a/htdocs/fichinter/list.php
+++ b/htdocs/fichinter/list.php
@@ -204,7 +204,7 @@ foreach ($arrayfields as $tmpkey => $tmpval)
$sql = "SELECT";
$sql .= " f.ref, f.rowid, f.fk_statut, f.description, f.datec as date_creation, f.tms as date_update, f.note_private,";
if (empty($conf->global->FICHINTER_DISABLE_DETAILS) && $atleastonefieldinlines) $sql .= "fd.rowid as lineid, fd.description as descriptiondetail, fd.date as dp, fd.duree,";
-$sql .= " s.nom as name, s.rowid as socid, s.client";
+$sql .= " s.nom as name, s.rowid as socid, s.client, s.fournisseur, s.email, s.status as thirdpartystatus";
if (!empty($conf->projet->enabled)) {
$sql .= ", pr.rowid as projet_id, pr.ref as projet_ref, pr.title as projet_title";
}
@@ -479,6 +479,13 @@ if ($resql)
$objectstatic->ref = $obj->ref;
$objectstatic->statut = $obj->fk_statut;
+ $companystatic->name=$obj->name;
+ $companystatic->id=$obj->socid;
+ $companystatic->client=$obj->client;
+ $companystatic->fournisseur=$obj->fournisseur;
+ $companystatic->email=$obj->email;
+ $companystatic->status=$obj->thirdpartystatus;
+
print '';
if (!empty($arrayfields['f.ref']['checked']))
@@ -521,9 +528,6 @@ if ($resql)
if (! empty($arrayfields['s.nom']['checked']))
{
print '';
- $companystatic->name=$obj->name;
- $companystatic->id=$obj->socid;
- $companystatic->client=$obj->client;
print $companystatic->getNomUrl(1, '', 44);
print ' ';
if (! $i) $totalarray['nbfield']++;
diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php
index 18e2992930c..d8f7dad8ac0 100644
--- a/htdocs/filefunc.inc.php
+++ b/htdocs/filefunc.inc.php
@@ -165,7 +165,8 @@ if (! defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck))
if ($csrfattack)
{
//print 'NOCSRFCHECK='.defined('NOCSRFCHECK').' REQUEST_METHOD='.$_SERVER['REQUEST_METHOD'].' HTTP_HOST='.$_SERVER['HTTP_HOST'].' HTTP_REFERER='.$_SERVER['HTTP_REFERER'];
- print "Access refused by CSRF protection in main.inc.php. Referer of form (".$_SERVER['HTTP_REFERER'].") is outside the server that serve this page (with method = ".$_SERVER['REQUEST_METHOD'].").\n";
+ // Note: We can't use dol_escape_htmltag here to escape output because lib functions.lib.ph is not yet loaded.
+ print "Access refused by CSRF protection in main.inc.php. Referer of form (".htmlentities($_SERVER['HTTP_REFERER'], ENT_COMPAT, 'UTF-8').") is outside the server that serve this page (with method = ".htmlentities($_SERVER['REQUEST_METHOD'], ENT_COMPAT, 'UTF-8').").\n";
print "If you access your server behind a proxy using url rewriting, you might check that all HTTP headers are propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file to remove this security check).\n";
die;
}
diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php
index 23031d09d90..8051b9684f9 100644
--- a/htdocs/fourn/card.php
+++ b/htdocs/fourn/card.php
@@ -809,16 +809,6 @@ if ($object->id > 0)
}
}
- if ($user->rights->fournisseur->facture->creer)
- {
- $langs->load("bills");
- if ($object->status == 1) {
- print ''.$langs->trans("AddBill").' ';
- } else {
- print ''.$langs->trans("AddBill").' ';
- }
- }
-
if ($user->rights->fournisseur->facture->creer)
{
if (!empty($orders2invoice) && $orders2invoice > 0)
@@ -836,6 +826,16 @@ if ($object->id > 0)
else print '';
}
+ if ($user->rights->fournisseur->facture->creer)
+ {
+ $langs->load("bills");
+ if ($object->status == 1) {
+ print ''.$langs->trans("AddBill").' ';
+ } else {
+ print ''.$langs->trans("AddBill").' ';
+ }
+ }
+
// Add action
if (!empty($conf->agenda->enabled) && !empty($conf->global->MAIN_REPEATTASKONEACHTAB) && $object->status == 1)
{
diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php
index 21e5e82c13b..204471bc9e7 100644
--- a/htdocs/fourn/class/api_supplier_invoices.class.php
+++ b/htdocs/fourn/class/api_supplier_invoices.class.php
@@ -194,8 +194,8 @@ class SupplierInvoices extends DolibarrApi
*
* @return int ID of supplier invoice
*
- * @throws 401
- * @throws 500
+ * @throws RestException 401
+ * @throws RestException 500
*/
public function post($request_data = null)
{
@@ -226,8 +226,8 @@ class SupplierInvoices extends DolibarrApi
*
* @return int
*
- * @throws 401
- * @throws 404
+ * @throws RestException 401
+ * @throws RestException 404
*/
public function put($id, $request_data = null)
{
@@ -262,9 +262,9 @@ class SupplierInvoices extends DolibarrApi
*
* @return array
*
- * @throws 401
- * @throws 404
- * @throws 500
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 500
*/
public function delete($id)
{
@@ -304,11 +304,11 @@ class SupplierInvoices extends DolibarrApi
*
* @return array
*
- * @throws 304
- * @throws 401
- * @throws 404
- * @throws 405
- * @throws 500
+ * @throws RestException 304
+ * @throws RestException 401
+ * @throws RestException 404
+ * @throws RestException 405
+ * @throws RestException 500
*/
public function validate($id, $idwarehouse = 0, $notrigger = 0)
{
@@ -348,10 +348,10 @@ class SupplierInvoices 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)
{
@@ -396,9 +396,9 @@ class SupplierInvoices 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 = '')
{
diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php
index 37ac4c55e9d..cb2e27b1a97 100644
--- a/htdocs/fourn/class/api_supplier_orders.class.php
+++ b/htdocs/fourn/class/api_supplier_orders.class.php
@@ -252,8 +252,8 @@ class SupplierOrders extends DolibarrApi
/**
* Delete supplier order
*
- * @param int $id Supplier order ID
- * @return type
+ * @param int $id Supplier order ID
+ * @return array Array of result
*/
public function delete($id)
{
diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php
index bd74d52a4d5..9197c14be5c 100644
--- a/htdocs/fourn/class/fournisseur.commande.class.php
+++ b/htdocs/fourn/class/fournisseur.commande.class.php
@@ -183,6 +183,60 @@ class CommandeFournisseur extends CommonOrder
public $multicurrency_total_tva;
public $multicurrency_total_ttc;
+
+
+ public $fields = array(
+ 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
+ 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>15),
+ 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20),
+ 'ref' =>array('type'=>'varchar(255)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'showoncombobox'=>1, 'position'=>25),
+ 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>30, 'index'=>1),
+ 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>35),
+ 'ref_supplier' =>array('type'=>'varchar(255)', 'label'=>'RefSupplier', 'enabled'=>1, 'visible'=>-1, 'position'=>40),
+ 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>45),
+ 'date_creation' =>array('type'=>'datetime', 'label'=>'Date creation', 'enabled'=>1, 'visible'=>-1, 'position'=>50),
+ 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>55),
+ 'date_approve' =>array('type'=>'datetime', 'label'=>'Date approve', 'enabled'=>1, 'visible'=>-1, 'position'=>60),
+ 'date_approve2' =>array('type'=>'datetime', 'label'=>'Date approve2', 'enabled'=>1, 'visible'=>-1, 'position'=>65),
+ 'date_commande' =>array('type'=>'date', 'label'=>'Date commande', 'enabled'=>1, 'visible'=>-1, 'position'=>70),
+ 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>75),
+ 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>80),
+ 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>85),
+ 'fk_user_approve' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserApproval', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
+ 'fk_user_approve2' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserSecondApproval', 'enabled'=>1, 'visible'=>-1, 'position'=>95),
+ 'source' =>array('type'=>'smallint(6)', 'label'=>'Source', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>100),
+ 'billed' =>array('type'=>'smallint(6)', 'label'=>'Billed', 'enabled'=>1, 'visible'=>-1, 'position'=>110),
+ 'amount_ht' =>array('type'=>'double(24,8)', 'label'=>'Amount ht', 'enabled'=>1, 'visible'=>-1, 'position'=>115),
+ 'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>120),
+ 'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
+ 'tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', '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_ht' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>145, 'isameasure'=>1),
+ 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>150, 'isameasure'=>1),
+ 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>155),
+ 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>160),
+ 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'ModelPDF', 'enabled'=>1, 'visible'=>0, 'position'=>165),
+ 'fk_input_method' =>array('type'=>'integer', 'label'=>'InputMethod', 'enabled'=>1, 'visible'=>-1, 'position'=>170),
+ 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'position'=>175),
+ 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>180),
+ 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>190),
+ 'date_livraison' =>array('type'=>'datetime', 'label'=>'DeliveryDate', 'enabled'=>1, 'visible'=>-1, 'position'=>195),
+ 'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>1, 'visible'=>-1, 'position'=>200),
+ 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>1, 'visible'=>-1, 'position'=>205),
+ 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLocation', 'enabled'=>1, 'visible'=>-1, 'position'=>210),
+ 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'Fk multicurrency', 'enabled'=>1, 'visible'=>-1, 'position'=>215),
+ 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCode', 'enabled'=>1, 'visible'=>-1, 'position'=>220),
+ 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>1, 'visible'=>-1, 'position'=>225),
+ 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>230),
+ 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>235),
+ 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>240),
+ 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>-1, 'position'=>245),
+ 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'position'=>500),
+ 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900),
+ );
+
+
/**
* Draft status
*/
@@ -387,6 +441,7 @@ class CommandeFournisseur extends CommonOrder
*/
public function fetch_lines($only_product = 0)
{
+ global $conf;
// phpcs:enable
//$result=$this->fetch_lines();
$this->lines = array();
@@ -399,8 +454,12 @@ class CommandeFournisseur extends CommonOrder
$sql .= " l.fk_unit,";
$sql .= " l.date_start, l.date_end,";
$sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc';
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING))
+ $sql .= ", pfp.rowid as fk_pfp, pfp.packaging";
$sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as l";
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING))
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON l.fk_product = pfp.fk_product and l.ref = pfp.ref_fourn";
$sql .= " WHERE l.fk_commande = ".$this->id;
if ($only_product) $sql .= ' AND p.fk_product_type = 0';
$sql .= " ORDER BY l.rang, l.rowid";
@@ -451,7 +510,13 @@ class CommandeFournisseur extends CommonOrder
$line->ref_fourn = $objp->ref_supplier; // The supplier ref of price when product was added. May have change since
$line->ref_supplier = $objp->ref_supplier; // The supplier ref of price when product was added. May have change since
- $line->date_start = $this->db->jdate($objp->date_start);
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING))
+ {
+ $line->fk_fournprice = $objp->fk_pfp;
+ $line->packaging = $objp->packaging;
+ }
+
+ $line->date_start = $this->db->jdate($objp->date_start);
$line->date_end = $this->db->jdate($objp->date_end);
$line->fk_unit = $objp->fk_unit;
@@ -522,7 +587,7 @@ class CommandeFournisseur extends CommonOrder
{
$num = $this->ref;
}
- $this->newref = $num;
+ $this->newref = dol_sanitizeFileName($num);
$sql = 'UPDATE '.MAIN_DB_PREFIX."commande_fournisseur";
$sql .= " SET ref='".$this->db->escape($num)."',";
@@ -906,7 +971,7 @@ class CommandeFournisseur extends CommonOrder
{
$num = $this->ref;
}
- $this->newref = $num;
+ $this->newref = dol_sanitizeFileName($num);
// Do we have to change status now ? (If double approval is required and first approval, we keep status to 1 = validated)
$movetoapprovestatus = true;
@@ -1310,7 +1375,7 @@ class CommandeFournisseur extends CommonOrder
false,
$this->lines[$i]->date_start,
$this->lines[$i]->date_end,
- 0,
+ $this->lines[$i]->array_options,
$this->lines[$i]->fk_unit
);
if ($result < 0)
@@ -1420,9 +1485,9 @@ class CommandeFournisseur extends CommonOrder
$this->db->begin();
- // get lines so they will be clone
- foreach ($this->lines as $line)
- $line->fetch_optionals();
+ // get extrafields so they will be clone
+ foreach($this->lines as $line)
+ $line->fetch_optionals();
// Load source object
$objFrom = clone $this;
@@ -1631,6 +1696,26 @@ class CommandeFournisseur extends CommonOrder
return -1;
}
}
+
+ // redefine quantity according to packaging
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING))
+ {
+ $prod = new Product($this->db, $fk_product);
+ $prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', ($this->fk_soc ? $this->fk_soc : $this->socid));
+ if ($qty < $prod->packaging)
+ {
+ $qty = $prod->packaging;
+ }
+ else
+ {
+ if (($qty % $prod->packaging) > 0)
+ {
+ $coeff = intval($qty / $prod->packaging) + 1;
+ $qty = $prod->packaging * $coeff;
+ setEventMessage($langs->trans('QtyRecalculatedWithPackaging'), 'mesgs');
+ }
+ }
+ }
}
else
{
@@ -2582,6 +2667,25 @@ class CommandeFournisseur extends CommonOrder
$this->line->fk_commande = $this->id;
//$this->line->label=$label;
$this->line->desc = $desc;
+
+ // redefine quantity according to packaging
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING))
+ {
+ if ($qty < $this->line->packaging)
+ {
+ $qty = $this->line->packaging;
+ }
+ else
+ {
+ if (($qty % $this->line->packaging) > 0)
+ {
+ $coeff = intval($qty / $this->line->packaging) + 1;
+ $qty = $this->line->packaging * $coeff;
+ setEventMessage($langs->trans('QtyRecalculatedWithPackaging'), 'mesgs');
+ }
+ }
+ }
+
$this->line->qty = $qty;
$this->line->ref_supplier = $ref_supplier;
@@ -3336,6 +3440,8 @@ class CommandeFournisseurLigne extends CommonOrderLine
*/
public function fetch($rowid)
{
+ global $conf;
+
$sql = 'SELECT cd.rowid, cd.fk_commande, cd.fk_product, cd.product_type, cd.description, cd.qty, cd.tva_tx, cd.special_code,';
$sql .= ' cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.ref,';
$sql .= ' cd.remise, cd.remise_percent, cd.subprice,';
@@ -3344,8 +3450,12 @@ class CommandeFournisseurLigne extends CommonOrderLine
$sql .= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc,';
$sql .= ' cd.date_start, cd.date_end, cd.fk_unit,';
$sql .= ' cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc';
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING))
+ $sql .= ", pfp.rowid as fk_pfp, pfp.packaging";
$sql .= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseurdet as cd';
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid';
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING))
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON cd.fk_product = pfp.fk_product and cd.ref = pfp.ref_fourn";
$sql .= ' WHERE cd.rowid = '.$rowid;
$result = $this->db->query($sql);
if ($result)
@@ -3383,6 +3493,11 @@ class CommandeFournisseurLigne extends CommonOrderLine
$this->product_ref = $objp->product_ref;
$this->product_libelle = $objp->product_libelle;
$this->product_desc = $objp->product_desc;
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING))
+ {
+ $this->packaging = $objp->packaging;
+ $this->fk_fournprice = $objp->fk_pfp;
+ }
$this->date_start = $this->db->jdate($objp->date_start);
$this->date_end = $this->db->jdate($objp->date_end);
diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php
index 231a5e9e910..d54e2da4eb1 100644
--- a/htdocs/fourn/class/fournisseur.facture.class.php
+++ b/htdocs/fourn/class/fournisseur.facture.class.php
@@ -217,6 +217,59 @@ class FactureFournisseur extends CommonInvoice
*/
public $fk_facture_source;
+
+ public $fields = array(
+ 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
+ 'ref' =>array('type'=>'varchar(255)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>15),
+ 'ref_supplier' =>array('type'=>'varchar(255)', 'label'=>'RefSupplier', 'enabled'=>1, 'visible'=>-1, 'position'=>20),
+ 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>25, 'index'=>1),
+ 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'RefExt', 'enabled'=>1, 'visible'=>0, 'position'=>30),
+ 'type' =>array('type'=>'smallint(6)', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35),
+ 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>40),
+ 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>45),
+ 'datef' =>array('type'=>'date', 'label'=>'Date', 'enabled'=>1, 'visible'=>-1, 'position'=>50),
+ 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>55),
+ 'libelle' =>array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>-1, 'position'=>60),
+ 'paye' =>array('type'=>'smallint(6)', 'label'=>'Paye', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>65),
+ 'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>70),
+ 'remise' =>array('type'=>'double(24,8)', 'label'=>'Discount', 'enabled'=>1, 'visible'=>-1, 'position'=>75),
+ 'close_code' =>array('type'=>'varchar(16)', 'label'=>'CloseCode', 'enabled'=>1, 'visible'=>-1, 'position'=>80),
+ 'close_note' =>array('type'=>'varchar(128)', 'label'=>'CloseNote', 'enabled'=>1, 'visible'=>-1, 'position'=>85),
+ 'tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
+ 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>95),
+ 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
+ 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>105),
+ 'total_tva' =>array('type'=>'double(24,8)', 'label'=>'TotalVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>110),
+ 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>115),
+ 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
+ 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>130),
+ 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>135),
+ 'fk_facture_source' =>array('type'=>'integer', 'label'=>'Fk facture source', 'enabled'=>1, 'visible'=>-1, 'position'=>140),
+ 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>1, 'visible'=>-1, 'position'=>145),
+ 'fk_account' =>array('type'=>'integer', 'label'=>'Account', 'enabled'=>1, 'visible'=>-1, 'position'=>150),
+ 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'position'=>155),
+ 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>160),
+ 'date_lim_reglement' =>array('type'=>'date', 'label'=>'DateLimReglement', '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'=>'ModelPdf', 'enabled'=>1, 'visible'=>0, 'position'=>180),
+ 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>190),
+ 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>1, 'visible'=>-1, 'position'=>195),
+ 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLocation', 'enabled'=>1, 'visible'=>-1, 'position'=>200),
+ 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'MulticurrencyId', 'enabled'=>1, 'visible'=>-1, 'position'=>205),
+ 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCode', 'enabled'=>1, 'visible'=>-1, 'position'=>210),
+ 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>1, 'visible'=>-1, 'position'=>215),
+ 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>220),
+ 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>225),
+ 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>230),
+ 'date_pointoftax' =>array('type'=>'date', 'label'=>'Date pointoftax', 'enabled'=>1, 'visible'=>-1, 'position'=>235),
+ 'date_valid' =>array('type'=>'date', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>240),
+ 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>245),
+ '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),
+ );
+
+
/**
* Standard invoice
*/
@@ -1360,7 +1413,7 @@ class FactureFournisseur extends CommonInvoice
{
$num = $this->ref;
}
- $this->newref = $num;
+ $this->newref = dol_sanitizeFileName($num);
$sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn";
$sql .= " SET ref='".$num."', fk_statut = 1, fk_user_valid = ".$user->id.", date_valid = '".$this->db->idate($now)."'";
@@ -1953,7 +2006,7 @@ class FactureFournisseur extends CommonInvoice
if (is_array($array_options) && count($array_options) > 0) {
// We replace values in this->line->array_options only for entries defined into $array_options
foreach ($array_options as $key => $value) {
- $this->line->array_options[$key] = $array_options[$key];
+ $line->array_options[$key] = $array_options[$key];
}
}
@@ -2234,7 +2287,7 @@ class FactureFournisseur extends CommonInvoice
if ($facturestatic->hasDelay()) {
$response->nbtodolate++;
- $response->url_late=DOL_URL_ROOT.'/fourn/facture/list.php?option=late&mainmenu=billing&leftmenu=suppliers_bills';
+ $response->url_late = DOL_URL_ROOT.'/fourn/facture/list.php?option=late&mainmenu=billing&leftmenu=suppliers_bills';
}
}
$this->db->free($resql);
@@ -2305,6 +2358,9 @@ class FactureFournisseur extends CommonInvoice
elseif ($this->type == self::TYPE_CREDIT_NOTE) $label = $langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref;
elseif ($this->type == self::TYPE_DEPOSIT) $label = $langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref;
if ($moretitle) $label .= ' - '.$moretitle;
+ if (isset($this->statut) && isset($this->alreadypaid)) {
+ $label .= ''.$langs->trans("Status").": ".$this->getLibStatut(5, $this->alreadypaid);
+ }
$ref = $this->ref;
if (empty($ref)) $ref = $this->id;
diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php
index 717a617b0ca..332e33ece59 100644
--- a/htdocs/fourn/class/fournisseur.product.class.php
+++ b/htdocs/fourn/class/fournisseur.product.class.php
@@ -273,6 +273,7 @@ class ProductFournisseur extends Product
$charges = price2num($charges, 'MU');
$qty = price2num($qty, 'MS');
$unitBuyPrice = price2num($buyprice / $qty, 'MU');
+ $packaging = ($this->packaging < $qty) ? $qty : $this->packaging;
$error = 0;
$now = dol_now();
@@ -359,6 +360,7 @@ class ProductFournisseur extends Product
$sql .= " supplier_reputation = ".(empty($supplier_reputation) ? 'NULL' : "'".$this->db->escape($supplier_reputation)."'").",";
$sql .= " barcode = ".(empty($barcode) ? 'NULL' : "'".$this->db->escape($barcode)."'").",";
$sql .= " fk_barcode_type = ".(empty($fk_barcode_type) ? 'NULL' : "'".$this->db->escape($fk_barcode_type)."'");
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", packaging = ".(empty($packaging) ? 1 : $packaging);
$sql .= " WHERE rowid = ".$this->product_fourn_price_id;
// TODO Add price_base_type and price_ttc
@@ -408,6 +410,7 @@ class ProductFournisseur extends Product
$sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price(";
$sql .= " multicurrency_price, multicurrency_unitprice, multicurrency_tx, fk_multicurrency, multicurrency_code,";
$sql .= "datec, fk_product, fk_soc, ref_fourn, desc_fourn, fk_user, price, quantity, remise_percent, remise, unitprice, tva_tx, charges, fk_availability, default_vat_code, info_bits, entity, delivery_time_days, supplier_reputation, barcode, fk_barcode_type)";
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", packaging";
$sql .= " values(";
$sql .= (isset($multicurrency_buyprice) ? "'".$this->db->escape(price2num($multicurrency_buyprice))."'" : 'null').",";
$sql .= (isset($multicurrency_unitBuyPrice) ? "'".$this->db->escape(price2num($multicurrency_unitBuyPrice))."'" : 'null').",";
@@ -435,13 +438,14 @@ class ProductFournisseur extends Product
$sql .= (empty($supplier_reputation) ? 'NULL' : "'".$this->db->escape($supplier_reputation)."'").",";
$sql .= (empty($barcode) ? 'NULL' : "'".$this->db->escape($barcode)."'").",";
$sql .= (empty($fk_barcode_type) ? 'NULL' : "'".$this->db->escape($fk_barcode_type)."'");
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", ".(empty($this->packaging) ? 1 : $this->db->escape($this->packaging));
$sql .= ")";
$this->product_fourn_price_id = 0;
$resql = $this->db->query($sql);
if ($resql) {
- $this->product_fourn_price_id = $this->db->last_insert_id(MAIN_DB_PREFIX . "product_fournisseur_price");
+ $this->product_fourn_price_id = $this->db->last_insert_id(MAIN_DB_PREFIX."product_fournisseur_price");
}
else {
$error++;
@@ -501,6 +505,7 @@ class ProductFournisseur extends Product
$sql .= " pfp.supplier_reputation, pfp.fk_user, pfp.datec,";
$sql .= " pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code,";
$sql .= " pfp.barcode, pfp.fk_barcode_type";
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", pfp.packaging";
$sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp";
$sql .= " WHERE pfp.rowid = ".(int) $rowid;
@@ -544,6 +549,12 @@ class ProductFournisseur extends Product
$this->fourn_barcode = $obj->barcode;
$this->fourn_fk_barcode_type = $obj->fk_barcode_type;
}
+
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) {
+ $this->packaging = $obj->packaging;
+ if ($this->packaging < $this->fourn_qty) $this->packaging = $this->fourn_qty;
+ }
+
if (empty($ignore_expression) && !empty($this->fk_supplier_price_expression))
{
$priceparser = new PriceParser($this->db);
@@ -598,7 +609,8 @@ class ProductFournisseur extends Product
$sql .= " pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.fk_availability, pfp.charges, pfp.info_bits, pfp.delivery_time_days, pfp.supplier_reputation,";
$sql .= " pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code, pfp.datec, pfp.tms,";
$sql .= " pfp.barcode, pfp.fk_barcode_type";
- $sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp, ".MAIN_DB_PREFIX."societe as s";
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", pfp.packaging";
+ $sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp, ".MAIN_DB_PREFIX."societe as s";
$sql .= " WHERE pfp.entity IN (".getEntity('productsupplierprice').")";
$sql .= " AND pfp.fk_soc = s.rowid";
$sql .= " AND s.status=1"; // only enabled company selected
@@ -647,6 +659,11 @@ class ProductFournisseur extends Product
$prodfourn->fourn_multicurrency_id = $record["fk_multicurrency"];
$prodfourn->fourn_multicurrency_code = $record["multicurrency_code"];
+ if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) {
+ $prodfourn->packaging = $record["packaging"];
+ if ($prodfourn->packaging < $prodfourn->fourn_qty) $prodfourn->packaging = $prodfourn->fourn_qty;
+ }
+
if ($conf->barcode->enabled) {
$prodfourn->barcode = $record["barcode"];
$prodfourn->fk_barcode_type = $record["fk_barcode_type"];
diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php
index 9adad176ab2..17d81c40c72 100644
--- a/htdocs/fourn/commande/card.php
+++ b/htdocs/fourn/commande/card.php
@@ -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/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..78cb4ecf7c7 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');
@@ -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 = '';
@@ -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
@@ -1086,6 +1152,40 @@ if ($resql)
$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
diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php
index ffdfb07baa0..f901500cc6f 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);
diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php
index 9b865cae3e6..48d56d8e502 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');
@@ -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),
@@ -218,6 +230,11 @@ if (empty($reshook))
$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='';
@@ -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']++;
@@ -1054,6 +1147,54 @@ 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';
@@ -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..1b6f8257977 100644
--- a/htdocs/fourn/facture/paiement.php
+++ b/htdocs/fourn/facture/paiement.php
@@ -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);
diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php
index 4c4a5212abd..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";
@@ -1654,21 +1654,24 @@ class Holiday extends CommonObject
{
if ($type)
{
- // Si utilisateur de Dolibarr
-
- $sql = "SELECT u.rowid";
- $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
+ // If user of Dolibarr
+ $sql = "SELECT";
+ if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
+ $sql .= " DISTINCT";
+ }
+ $sql.= " u.rowid";
+ $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 = ".$conf->entity.")";
- $sql .= " OR u.admin = 1";
+ $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 (0,".$conf->entity.")";
+ $sql .= " WHERE u.entity IN (".getEntity('user').")";
}
$sql .= " AND u.statut > 0";
if ($filters) $sql .= $filters;
@@ -1709,7 +1712,7 @@ class Holiday extends CommonObject
// We want only list of vacation balance for user ids
$sql = "SELECT DISTINCT cpu.fk_user";
$sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
- $sql .= " WHERE cpu.fk_user = u.user";
+ $sql .= " WHERE cpu.fk_user = u.rowid";
if ($filters) $sql .= $filters;
$resql = $this->db->query($sql);
@@ -1750,17 +1753,24 @@ class Holiday extends CommonObject
// List for Dolibarr users
if ($type)
{
- $sql = "SELECT u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user";
+ // If user of Dolibarr
+ $sql = "SELECT";
+ if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
+ $sql .= " DISTINCT";
+ }
+ $sql.= " u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user";
$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 = ".$conf->entity.")";
- $sql.= " OR u.admin = 1";
- } else {
- $sql.= " WHERE u.entity IN (0,".$conf->entity.")";
+ $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.statut > 0";
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/chart/.codeclimate.yml b/htdocs/includes/chart/.codeclimate.yml
new file mode 100644
index 00000000000..0b8340feb58
--- /dev/null
+++ b/htdocs/includes/chart/.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/chart/.editorconfig b/htdocs/includes/chart/.editorconfig
new file mode 100644
index 00000000000..922810ad734
--- /dev/null
+++ b/htdocs/includes/chart/.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/chart/.eslintignore b/htdocs/includes/chart/.eslintignore
new file mode 100644
index 00000000000..96212a3593b
--- /dev/null
+++ b/htdocs/includes/chart/.eslintignore
@@ -0,0 +1 @@
+**/*{.,-}min.js
diff --git a/htdocs/includes/chart/.eslintrc.yml b/htdocs/includes/chart/.eslintrc.yml
new file mode 100644
index 00000000000..b0d9d5695a9
--- /dev/null
+++ b/htdocs/includes/chart/.eslintrc.yml
@@ -0,0 +1,7 @@
+extends: chartjs
+
+env:
+ browser: true
+ node: true
+
+plugins: ['html']
diff --git a/htdocs/includes/chart/.gitignore b/htdocs/includes/chart/.gitignore
new file mode 100644
index 00000000000..c4998047b01
--- /dev/null
+++ b/htdocs/includes/chart/.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/chart/.htmllintrc b/htdocs/includes/chart/.htmllintrc
new file mode 100644
index 00000000000..1ab933490de
--- /dev/null
+++ b/htdocs/includes/chart/.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/chart/.travis.yml b/htdocs/includes/chart/.travis.yml
new file mode 100644
index 00000000000..beb8789b46b
--- /dev/null
+++ b/htdocs/includes/chart/.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/chart/LICENSE.md b/htdocs/includes/chart/LICENSE.md
new file mode 100644
index 00000000000..29c941dcccf
--- /dev/null
+++ b/htdocs/includes/chart/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/chart/MAINTAINING.md b/htdocs/includes/chart/MAINTAINING.md
new file mode 100644
index 00000000000..288b03945ff
--- /dev/null
+++ b/htdocs/includes/chart/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/chart/README.md b/htdocs/includes/chart/README.md
new file mode 100644
index 00000000000..5a522a5e915
--- /dev/null
+++ b/htdocs/includes/chart/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/chart/book.json b/htdocs/includes/chart/book.json
new file mode 100644
index 00000000000..22acbde968c
--- /dev/null
+++ b/htdocs/includes/chart/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/chart/composer.json b/htdocs/includes/chart/composer.json
new file mode 100644
index 00000000000..b332bb0f595
--- /dev/null
+++ b/htdocs/includes/chart/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/chart/dist/Chart.bundle.js b/htdocs/includes/chart/dist/Chart.bundle.js
new file mode 100644
index 00000000000..204156a8fc7
--- /dev/null
+++ b/htdocs/includes/chart/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