diff --git a/ChangeLog b/ChangeLog
index e55cfad84d1..b67cbabafb4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,103 @@ English Dolibarr ChangeLog
--------------------------------------------------------------
+***** ChangeLog for 15.0.2 compared to 15.0.1 *****
+
+FIX: #19777 #20281
+FIX: #20140 #20301
+FIX: #20279 Accountancy - PostGreSQL - Error on mass update lines already binded
+FIX: #20476 migration postgresql 14.0.x to 15.0.x packaging type
+FIX: #20733 Inventory: Do not use batch qty even if present if batch module is disabled.
+FIX: action comm list: holiday last day not included + handle duration with halfdays
+FIX: Add missing entity on salary's payment
+FIX: Add 'recruitment' into check array
+FIX: add tools to fix bad bank amount in accounting with multicurrency
+FIX: assign member cateogry to a member
+FIX: backport
+FIX: bad bank amount in accounting with multicurrency
+FIX: Bad condition on remx
+FIX: Bad filter on date on salary list
+FIX: bad link to add a customer price (token duplicated)
+FIX: bad status of member on widget by type and status
+FIX: better error management at product selling price update
+FIX: Can't edit bank record
+FIX: check mandatory thirdparty fields for mass action
+FIX: check thirdparty object loaded and properties exist
+FIX: comment
+FIX: compatibility for ticket number sharing
+FIX: compatibility with multicompany sharings
+FIX: contact card: single extrafield update failed
+FIX: country not visible into list of states
+FIX: Delete an extrafield where type is double
+FIX: deprecated module are not more viewed as external modules
+FIX: Disable customer type by default if type prospect/customer is disabled
+FIX: each time we create a supplier order, we need to give it a ref_supplier
+FIX: Error management
+FIX: fatal error for $db usage in tpl
+FIX: filter into the list of product lots
+FIX: Filter on Object Referent page give CRSF page
+FIX: Fix default options ($hidedetails, $hidedesc, $hideref) with globales when generate PDF in mass actions
+FIX: Fix search by filters
+FIX: Fix the adding of lines in the create invoice functions
+FIX: forgotten form confirm before various payment delete
+FIX: holiday/leave requests: write status change emails in HTML
+FIX: include discount price for PMP after a reception (Issue #20029)
+FIX: incrementation
+FIX: in salary stats and payment list, we must check right perms as well as salary list
+FIX: intervention entity missing
+FIX: label tax cat trad
+FIX: Mass action ship orders
+FIX: missing advanced perms
+FIX: missing call to executeHooks()
+FIX: Missing entity on adding new VAT
+FIX: missing hook for row ordering
+FIX: missing hook parameter ($possiblelinks)
+FIX: missing parenthesis
+FIX: missing picto in combo of mass actions of thirdparties.
+FIX: missing signature library when ODT model is used
+FIX: Missing unset fields after updateline expensereport
+FIX: ModuileBuilder - Fix getLinesArray() error reporting
+FIX: Move delete task time trigger position
+FIX: Navigation between invoices
+FIX: No empty line inserted into accounting_bookkeeping
+FIX: Numbering of sepa files
+FIX: object cloning: set unique extrafield values to null to prevent duplicates
+FIX: on update with action reminder in future there is user key error
+FIX: originproductline array td identification data-id
+FIX: out of memory when more than 100 000 invoices.
+FIX: permit access to medias when logged in a different entity
+FIX: phpcs
+FIX: project creation prevented if PROJECTLEADER contact role renamed, de-activated or deleted
+FIX: project timesheet by week: cleanup unused code
+FIX: project timesheet: public holidays offset by 1 day
+FIX: project timesheets: assume Saturday and Sunday as default weekend days when working days conf is empty or badly formed
+FIX: propal list: bad error management when setting "not signed" mass action
+FIX: propal list mass action translations and error management (v14 edition)
+FIX: propal list: missing not signed massaction translation keys for transifex
+FIX: PR returns
+FIX: ref_client doesn't exists on supplier invoice, then ref_fourn needs to have a default value when we want to bill several supplier orders
+FIX: replenish and manage product stock by warhouse
+FIX: sending email on payment of registration of event
+FIX: SEPA ICS is not mandatory for bank transfer
+FIX: Set datec when add time spent on a project task
+FIX: status filter on supplierOrder stats doesn't work
+FIX: stickler-ci
+FIX: still prevent project creation if PROJECTLEADER role unavailable, but with a specific error message
+FIX: Supplier order stats
+FIX: Tabulation must be allowed for HTML content
+FIX: tool to fix bank account not in main currency for vendor invoice
+FIX: translations
+FIX: Travis + Update dev
+FIX: truncate Customer Reference too long on PDF header (PR #20718)
+FIX: uniformize code
+FIX: Update of sale price (log not correctly updated)
+FIX: user actions rights when mulit-company transverse mode is enabled
+FIX: user employee tab: offset in open days messes up holiday length calculation
+FIX: We need to have a different default_ref_supplier for each new fourn invoice
+FIX: "WHERE" clause missing on resource export
+FIX: #yogosha9754
+
+
***** ChangeLog for 15.0.1 compared to 15.0.0 *****
FIX: #19777 #20281
FIX: bad position of extrafields for interventions
diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php
index d43d35f84c7..0fd0b719cd7 100644
--- a/htdocs/accountancy/bookkeeping/card.php
+++ b/htdocs/accountancy/bookkeeping/card.php
@@ -431,12 +431,12 @@ if ($action == 'create') {
// Account movement
print '
';
- if (!$objp->rappro && !$bankline->getVentilExportCompta()) {
- print img_picto('', 'bank_account', 'class="paddingright"');
- print $form->select_comptes($acct->id, 'accountid', 0, '', 0, '', 0, '', 1);
- } else {
+ // $objp->fk_account may be not > 0 if data was lost by an old bug. In such a case, we let a chance to user to fix it.
+ if (($objp->rappro || $bankline->getVentilExportCompta()) && $objp->fk_account > 0) {
print $acct->getNomUrl(1, 'transactions', 'reflabel');
+ } else {
+ print img_picto('', 'bank_account', 'class="paddingright"');
+ print $form->select_comptes($acct->id, 'accountid', 0, '', ($acct->id > 0 ? $acct->id : 1), '', 0, '', 1);
}
print '
';
print '
';
diff --git a/htdocs/compta/facture/stats/index.php b/htdocs/compta/facture/stats/index.php
index 6ee1a057664..cb0e38b7a34 100644
--- a/htdocs/compta/facture/stats/index.php
+++ b/htdocs/compta/facture/stats/index.php
@@ -102,7 +102,7 @@ if ($mode == 'customer') {
$stats->where .= ' AND f.fk_statut IN ('.$db->sanitize($object_status).')';
}
if (is_array($custcats) && !empty($custcats)) {
- $stats->from .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_societe as cat OmdN (f.fk_soc = cat.fk_soc)';
+ $stats->from .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_societe as cat ON (f.fk_soc = cat.fk_soc)';
$stats->where .= ' AND cat.fk_categorie IN ('.$db->sanitize(implode(',', $custcats)).')';
}
}
diff --git a/htdocs/core/ajax/row.php b/htdocs/core/ajax/row.php
index 8b16cd4699c..8158b935ad5 100644
--- a/htdocs/core/ajax/row.php
+++ b/htdocs/core/ajax/row.php
@@ -48,7 +48,7 @@ if (!defined('NOREQUIRETRAN')) {
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/genericobject.class.php';
-
+$hookmanager->initHooks(array('rowinterface'));
// Security check
// This is done later into view.
@@ -116,7 +116,15 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3)
$perm = 1;
}
}
-
+ $parameters = array('roworder'=> &$roworder, 'table_element_line' => &$table_element_line, 'fk_element' => &$fk_element, 'element_id' => &$element_id, 'perm' => &$perm);
+ $row = new GenericObject($db);
+ $row->table_element_line = $table_element_line;
+ $row->fk_element = $fk_element;
+ $row->id = $element_id;
+ $reshook = $hookmanager->executeHooks('checkRowPerms', $parameters, $row, $action);
+ if ($reshook > 0) {
+ $perm = $hookmanager->resArray['perm'];
+ }
if (! $perm) {
// We should not be here. If we are not allowed to reorder rows, feature should not be visible on script.
// If we are here, it is a hack attempt, so we report a warning.
@@ -133,10 +141,7 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3)
}
}
- $row = new GenericObject($db);
- $row->table_element_line = $table_element_line;
- $row->fk_element = $fk_element;
- $row->id = $element_id;
+
$row->line_ajaxorder($newrowordertab); // This update field rank or position in table row->table_element_line
diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
index c01ff5af541..a9f79095242 100644
--- a/htdocs/core/class/html.formfile.class.php
+++ b/htdocs/core/class/html.formfile.class.php
@@ -892,7 +892,7 @@ class FormFile
}
$out .= '>';
$out .= img_mime($file["name"], $langs->trans("File").': '.$file["name"]);
- $out .= dol_trunc($file["name"], 150);
+ $out .= dol_trunc($file["name"], 40);
$out .= ''."\n";
$out .= $this->showPreview($file, $modulepart, $relativepath, 0, $param);
$out .= '';
diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php
index 4bf8a0e7219..e98a25ddbee 100644
--- a/htdocs/core/lib/company.lib.php
+++ b/htdocs/core/lib/company.lib.php
@@ -271,7 +271,7 @@ function societe_prepare_head(Societe $object)
$h++;
}
- if (getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR') == 'thirdparty') {
+ if (getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR', 'thirdparty') == 'thirdparty') {
if (!empty($user->rights->partnership->read)) {
$langs->load("partnership");
$nbPartnership = is_array($object->partnerships) ? count($object->partnerships) : 0;
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 22ff541f7d5..43a549655b9 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -8200,7 +8200,7 @@ function verifCond($strToEvaluate)
* @param string $s String to evaluate
* @param int $returnvalue 0=No return (used to execute eval($a=something)). 1=Value of eval is returned (used to eval($something)).
* @param int $hideerrors 1=Hide errors
- * @param string $onlysimplestring 0=Accept all chars, 1=Accept only simple string with char 'a-z0-9\s$_->&|=';, 2=Accept also '!?():"\';,/'
+ * @param string $onlysimplestring 0=Accept all chars, 1=Accept only simple string with char 'a-z0-9\s^$_+-.*\/>&|=!?():"\',/';, 2=Accept also ';[]'
* @return mixed Nothing or return result of eval
*/
function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1')
@@ -8218,7 +8218,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1'
// Test dangerous char (used for RCE), we allow only PHP variable testing.
if ($onlysimplestring == '1') {
//print preg_quote('$_->&|', '/');
- if (preg_match('/[^a-z0-9\s'.preg_quote('$_+-*/>&|=!?():"', '/').']/i', $s)) {
+ if (preg_match('/[^a-z0-9\s'.preg_quote('^$_+-.*/>&|=!?():"\',/', '/').']/i', $s)) {
if ($returnvalue) {
return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s;
} else {
@@ -8228,7 +8228,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1'
}
} elseif ($onlysimplestring == '2') {
//print preg_quote('$_->&|', '/');
- if (preg_match('/[^a-z0-9\s'.preg_quote('^$_+-*/>&|=!?():"\';,/', '/').']/i', $s)) {
+ if (preg_match('/[^a-z0-9\s'.preg_quote('^$_+-.*/>&|=!?():"\',/;[]', '/').']/i', $s)) {
if ($returnvalue) {
return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s;
} else {
@@ -8245,7 +8245,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1'
return '';
}
}
- if (strpos($s, '.') !== false) {
+ if (preg_match('/[^0-9]+\.[^0-9]+/', $s)) { // We refuse . if not between 2 numbers
if ($returnvalue) {
return 'Bad string syntax to evaluate (dot char is forbidden): '.$s;
} else {
diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php
index fb11846a4fb..2a436677cad 100644
--- a/htdocs/core/lib/website2.lib.php
+++ b/htdocs/core/lib/website2.lib.php
@@ -49,7 +49,7 @@ function dolSaveMasterFile($filemaster)
@chmod($filemaster, octdec($conf->global->MAIN_UMASK));
}
- return $result;
+ return $result;
}
/**
@@ -291,11 +291,12 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage,
* @param string $fileindex Full path of file index.php
* @param string $filetpl File tpl the index.php page redirect to (used only if $fileindex is provided)
* @param string $filewrapper Full path of file wrapper.php
+ * @param Website $object Object website
* @return boolean True if OK
*/
-function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper)
+function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper, $object = null)
{
- global $conf;
+ global $conf, $db;
$result1 = false;
$result2 = false;
@@ -320,6 +321,44 @@ function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper)
if (!empty($conf->global->MAIN_UMASK)) {
@chmod($fileindex, octdec($conf->global->MAIN_UMASK));
}
+
+ if (is_object($object) && $object->fk_default_home > 0) {
+ $objectpage = new WebsitePage($db);
+ $objectpage->fetch($object->fk_default_home);
+
+ // Create a version for sublanguages
+ if (empty($objectpage->lang) || !in_array($objectpage->lang, explode(',', $object->otherlang))) {
+ if (empty($conf->global->WEBSITE_DISABLE_MAIN_LANGUAGE_INTO_LANGSUBDIR) && is_object($object) && !empty($object->otherlang)) {
+ $dirname = dirname($fileindex);
+ foreach (explode(',', $object->otherlang) as $sublang) {
+ // Avoid to erase main alias file if $sublang is empty string
+ if (empty(trim($sublang))) continue;
+ $fileindexsub = $dirname.'/'.$sublang.'/index.php';
+
+ // Same indexcontent than previously but with ../ instead of ./ for master and tpl file include/require_once.
+ $relpath = '..';
+ $indexcontent = ''."\n";
+ $result = file_put_contents($fileindexsub, $indexcontent);
+ if ($result === false) {
+ dol_syslog("Failed to write file ".$fileindexsub, LOG_WARNING);
+ }
+ if (!empty($conf->global->MAIN_UMASK)) {
+ @chmod($fileindexsub, octdec($conf->global->MAIN_UMASK));
+ }
+ }
+ }
+ }
+ }
} else {
$result1 = true;
}
@@ -491,7 +530,7 @@ function dolSaveReadme($file, $content)
@chmod($file, octdec($conf->global->MAIN_UMASK));
}
- return $result;
+ return $result;
}
@@ -545,9 +584,9 @@ function showWebsiteTemplates(Website $website)
while (($subdir = readdir($handle)) !== false) {
if (is_file($dirtheme."/".$subdir) && substr($subdir, 0, 1) <> '.'
&& substr($subdir, 0, 3) <> 'CVS' && preg_match('/\.zip$/i', $subdir)) {
- $subdirwithoutzip = preg_replace('/\.zip$/i', '', $subdir);
+ $subdirwithoutzip = preg_replace('/\.zip$/i', '', $subdir);
- // Disable not stable themes (dir ends with _exp or _dev)
+ // Disable not stable themes (dir ends with _exp or _dev)
if ($conf->global->MAIN_FEATURES_LEVEL < 2 && preg_match('/_dev$/i', $subdir)) {
continue;
}
@@ -555,38 +594,38 @@ function showWebsiteTemplates(Website $website)
continue;
}
- print '