diff --git a/build/makepack-dolibarrmodule.pl b/build/makepack-dolibarrmodule.pl
index 4a9a217b570..8fbb28dc35f 100755
--- a/build/makepack-dolibarrmodule.pl
+++ b/build/makepack-dolibarrmodule.pl
@@ -293,6 +293,7 @@ foreach my $PROJECT (@PROJECTLIST) {
}
print "Clean $BUILDROOT\n";
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.cache`;
+ $ret=`rm -fr $BUILDROOT/$PROJECTLC/.git`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.project`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.settings`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/index.php`;
diff --git a/build/rpm/dolibarr_generic.spec b/build/rpm/dolibarr_generic.spec
index f6d81feaea4..a992c84f0f9 100755
--- a/build/rpm/dolibarr_generic.spec
+++ b/build/rpm/dolibarr_generic.spec
@@ -58,7 +58,7 @@ Requires: mysql, mysql-client
%if 0%{?suse_version}
# Voir http://en.opensuse.org/openSUSE:Packaging_Conventions_RPM_Macros
Group: Productivity/Office/Management
-Requires: apache2, apache2-mod_php5, php5 >= 5.3.0, php5-gd, php5-ldap, php5-imap, php5-mysql, php5-openssl, dejavu
+Requires: apache2, apache2-mod_php, php >= 5.3.0, php-gd, php-ldap, php-imap, php-mysql, php-openssl, dejavu
Requires: mysql-community-server, mysql-community-server-client
BuildRequires: update-desktop-files fdupes
%else
diff --git a/build/rpm/dolibarr_opensuse.spec b/build/rpm/dolibarr_opensuse.spec
index bd6834582ac..c7113828632 100755
--- a/build/rpm/dolibarr_opensuse.spec
+++ b/build/rpm/dolibarr_opensuse.spec
@@ -25,7 +25,7 @@ BuildArch: noarch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Group: Productivity/Office/Management
-Requires: apache2, apache2-mod_php5, php5 >= 5.3.0, php5-gd, php5-ldap, php5-imap, php5-mysql, php5-openssl, dejavu
+Requires: apache2, apache2-mod_php, php >= 5.3.0, php-gd, php-ldap, php-imap, php-mysql, php-openssl, dejavu
Requires: mysql-community-server, mysql-community-server-client
%if 0%{?suse_version}
BuildRequires: update-desktop-files fdupes
@@ -66,7 +66,6 @@ ed essere facile da usare.
Programmo web, progettato per poter fornire solo ciò di
cui hai bisogno ed essere facile da usare.
-%_datadir/dolibarr/htdocs/webhook
#---- prep
%prep
diff --git a/htdocs/accountancy/admin/card.php b/htdocs/accountancy/admin/card.php
index e70bc39bfd0..9eabd378e11 100644
--- a/htdocs/accountancy/admin/card.php
+++ b/htdocs/accountancy/admin/card.php
@@ -85,7 +85,7 @@ if ($action == 'add' && $user->hasRight('accounting', 'chartofaccount')) {
// Clean code
// To manage zero or not at the end of the accounting account
- if ($conf->global->ACCOUNTING_MANAGE_ZERO == 1) {
+ if (!empty($conf->global->ACCOUNTING_MANAGE_ZERO)) {
$account_number = $account_number;
} else {
$account_number = clean_account($account_number);
@@ -148,7 +148,7 @@ if ($action == 'add' && $user->hasRight('accounting', 'chartofaccount')) {
// Clean code
// To manage zero or not at the end of the accounting account
- if (isset($conf->global->ACCOUNTING_MANAGE_ZERO) && $conf->global->ACCOUNTING_MANAGE_ZERO == 1) {
+ if (!empty($conf->global->ACCOUNTING_MANAGE_ZERO)) {
$account_number = $account_number;
} else {
$account_number = clean_account($account_number);
diff --git a/htdocs/adherents/class/api_members.class.php b/htdocs/adherents/class/api_members.class.php
index 35ab65e9d82..8308c71fac0 100644
--- a/htdocs/adherents/class/api_members.class.php
+++ b/htdocs/adherents/class/api_members.class.php
@@ -480,11 +480,11 @@ class Members extends DolibarrApi
/**
* Add a subscription for a member
*
- * @param int $id ID of member
- * @param int $start_date Start date {@from body} {@type timestamp}
- * @param int $end_date End date {@from body} {@type timestamp}
- * @param float $amount Amount (may be 0) {@from body}
- * @param string $label Label {@from body}
+ * @param int $id ID of member
+ * @param string $start_date Start date {@from body} {@type timestamp}
+ * @param string $end_date End date {@from body} {@type timestamp}
+ * @param float $amount Amount (may be 0) {@from body}
+ * @param string $label Label {@from body}
* @return int ID of subscription
*
* @url POST {id}/subscriptions
diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php
index 213be0d2389..349ee1b0b6c 100644
--- a/htdocs/commande/list.php
+++ b/htdocs/commande/list.php
@@ -2446,7 +2446,7 @@ if ($resql) {
// Get local and virtual stock and store it into cache
if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product])) {
- $generic_product->load_stock('nobatch'); // ->load_virtual_stock() is already included into load_stock()
+ $generic_product->load_stock('nobatch,warehouseopen'); // ->load_virtual_stock() is already included into load_stock()
$productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_reel;
$productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique;
} else {
diff --git a/htdocs/compta/bank/class/api_bankaccounts.class.php b/htdocs/compta/bank/class/api_bankaccounts.class.php
index 8e38d1ffe78..c9886a176f0 100644
--- a/htdocs/compta/bank/class/api_bankaccounts.class.php
+++ b/htdocs/compta/bank/class/api_bankaccounts.class.php
@@ -471,7 +471,7 @@ class BankAccounts extends DolibarrApi
* Add a line to an account
*
* @param int $id ID of account
- * @param int $date Payment date (timestamp) {@from body} {@type timestamp}
+ * @param string $date Payment date (timestamp) {@from body} {@type timestamp}
* @param string $type Payment mode (TYP,VIR,PRE,LIQ,VAD,CB,CHQ...) {@from body}
* @param string $label Label {@from body}
* @param float $amount Amount (may be 0) {@from body}
@@ -480,7 +480,7 @@ class BankAccounts extends DolibarrApi
* @param string $cheque_writer Name of cheque writer {@from body}
* @param string $cheque_bank Bank of cheque writer {@from body}
* @param string $accountancycode Accountancy code {@from body}
- * @param int $datev Payment date value (timestamp) {@from body} {@type timestamp}
+ * @param string $datev Payment date value (timestamp) {@from body} {@type timestamp}
* @param string $num_releve Bank statement numero {@from body}
* @return int ID of line
*
diff --git a/htdocs/compta/bank/line.php b/htdocs/compta/bank/line.php
index 49edf3c3a1a..cb10a7310c6 100644
--- a/htdocs/compta/bank/line.php
+++ b/htdocs/compta/bank/line.php
@@ -657,13 +657,13 @@ if ($result) {
if ($user->rights->banque->consolidate) {
print '
';
if ($objp->rappro) {
- print ' rappro ? ' disabled' : '').'>';
- print ' ';
+ print ' rappro ? ' disabled' : '').'>';
+ print ' ';
} else {
- print ' rappro ? ' disabled' : '').'>';
+ print ' rappro ? ' disabled' : '').'>';
}
if ($objp->num_releve) {
- print ' ('.$langs->trans("AccountStatement").' '.$objp->num_releve.') ';
+ print ' ('.$langs->trans("AccountStatement").' '.$objp->num_releve.') ';
}
print ' ';
} else {
@@ -675,6 +675,28 @@ if ($result) {
if ($user->rights->banque->consolidate) {
print '';
print ' rappro ? ' checked="checked"' : '')).'">';
+
+ print '
+
+ ';
+
print ' ';
} else {
print ''.yn($objp->rappro).' ';
diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php
index 51c094d898e..4c1392e28eb 100644
--- a/htdocs/compta/facture/class/api_invoices.class.php
+++ b/htdocs/compta/facture/class/api_invoices.class.php
@@ -1452,7 +1452,6 @@ class Invoices extends DolibarrApi
$multicurrency_amounts[$id] = $newvalue;
}
-
// Creation of payment line
$paymentobj = new Paiement($this->db);
$paymentobj->datepaye = $datepaye;
diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php
index da72411528d..532140481ab 100644
--- a/htdocs/compta/facture/class/facture-rec.class.php
+++ b/htdocs/compta/facture/class/facture-rec.class.php
@@ -1272,6 +1272,8 @@ class FactureRec extends CommonInvoice
$tmparray = dol_getdate($now);
$today = dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); // Today is last second of current day
+ $this->output = null;
+
dol_syslog("createRecurringInvoices restrictioninvoiceid=".$restrictioninvoiceid." forcevalidation=".$forcevalidation);
$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'facture_rec';
diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php
index f6b31386215..8aaf8010dd2 100644
--- a/htdocs/compta/prelevement/class/bonprelevement.class.php
+++ b/htdocs/compta/prelevement/class/bonprelevement.class.php
@@ -353,7 +353,8 @@ class BonPrelevement extends CommonObject
if ($this->fetched == 1) {
if ($date < $this->date_trans) {
- $this->error = 'DateOfMovementLowerThanDateOfFileTransmission';
+ $langs->load("errors");
+ $this->error = $langs->trans('ErrorDateOfMovementLowerThanDateOfFileTransmission');
dol_syslog("bon-prelevment::set_infocredit 1027 ".$this->error);
return -1027;
}
diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php
index 8f4c59bb2f8..e8396a4299c 100644
--- a/htdocs/contact/list.php
+++ b/htdocs/contact/list.php
@@ -553,7 +553,15 @@ if (strlen($search_fax)) {
if (isModEnabled('socialnetworks')) {
foreach ($socialnetworks as $key => $value) {
if ($value['active'] && strlen($search_[$key])) {
- $sql .= " AND p.socialnetworks LIKE '%\"".$key."\":\"".$search_[$key]."%'";
+ $searchkeyinjsonformat = preg_replace('/"$/', '', preg_replace('/^"/', '', json_encode($search_[$key])));
+ if (in_array($db->type, array('mysql', 'mysqli'))) {
+ $sql .= " AND p.socialnetworks REGEXP '\"".$db->escapeforlike($db->escape($key))."\":\"[^\"]*".$db->escapeforlike($db->escape($searchkeyinjsonformat))."'";
+ } elseif ($db->type == 'pgsql') {
+ $sql .= " AND p.socialnetworks ~ '\"".$db->escapeforlike($db->escape($key))."\":\"[^\"]*".$db->escapeforlike($db->escape($searchkeyinjsonformat))."'";
+ } else {
+ // Works with all database but not reliable because search only for social network code starting with earched value
+ $sql .= " AND p.socialnetworks LIKE '%\"".$db->escapeforlike($db->escape($key))."\":\"".$db->escapeforlike($db->escape($searchkeyinjsonformat))."%'";
+ }
}
}
}
@@ -608,6 +616,7 @@ if ($view == "recent") {
} else {
$sql .= $db->order($sortfield, $sortorder);
}
+//print $sql;
// Count total nb of records
$nbtotalofrecords = '';
diff --git a/htdocs/core/ajax/selectsearchbox.php b/htdocs/core/ajax/selectsearchbox.php
index 19f7523fd21..5d47aeff430 100644
--- a/htdocs/core/ajax/selectsearchbox.php
+++ b/htdocs/core/ajax/selectsearchbox.php
@@ -90,7 +90,6 @@ if (((isModEnabled('product') && $user->hasRight('product', 'read')) || (isModEn
if (isModEnabled('mrp') && $user->hasRight('mrp', 'read') && empty($conf->global->MAIN_SEARCHFORM_MRP_DISABLED)) {
$arrayresult['searchintomo'] = array('position'=>35, 'shortcut'=>'', 'img'=>'object_mrp', 'label'=>$langs->trans("SearchIntoMO", $search_boxvalue), 'text'=>img_picto('', 'object_mrp', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoMO", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/mrp/mo_list.php'.($search_boxvalue ? '?search_all='.urlencode($search_boxvalue) : ''));
}
-
if (isModEnabled('project') && empty($conf->global->MAIN_SEARCHFORM_PROJECT_DISABLED) && $user->hasRight('projet', 'lire')) {
$arrayresult['searchintoprojects'] = array('position'=>40, 'shortcut'=>'Q', 'img'=>'object_project', 'label'=>$langs->trans("SearchIntoProjects", $search_boxvalue), 'text'=>img_picto('', 'object_project', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoProjects", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/projet/list.php'.($search_boxvalue ? '?search_all='.urlencode($search_boxvalue) : ''));
}
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index 1d94646d4f6..02f9dc5c712 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -8251,6 +8251,7 @@ class Form
if(! data.id) return null;';
if ($callurlonselect) {
+ // We forge the url with 'sall='
$outdelayed .= '
var urlBase = data.url;
diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php
index 594ab96d955..09f93a436ea 100644
--- a/htdocs/core/modules/import/import_csv.modules.php
+++ b/htdocs/core/modules/import/import_csv.modules.php
@@ -458,17 +458,27 @@ 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);
+ $result = call_user_func_array(array($classinstance, $method), $param_array);
+
+ // If duplicate record found
+ if (!($classinstance->id != '') && $result == -2) {
+ $this->errors[$error]['lib'] = $langs->trans('ErrorMultipleRecordFoundFromRef', $newval);
+ $this->errors[$error]['type'] = 'FOREIGNKEY';
+ $errorforthistable++;
+ $error++;
+ }
+
// If not found, try the fetch from label
if (!($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeorlabel') {
$param_array = array('', '', $newval);
call_user_func_array(array($classinstance, $method), $param_array);
}
$this->cacheconvert[$file.'_'.$class.'_'.$method.'_'][$newval] = $classinstance->id;
+
//print 'We have made a '.$class.'->'.$method.' to get id from code '.$newval.'. ';
if ($classinstance->id != '') { // id may be 0, it is a found value
$newval = $classinstance->id;
- } else {
+ } elseif (! $error) {
if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) {
$this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', num2Alpha($key - 1), $newval, 'code', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict']));
} elseif (!empty($objimport->array_import_convertvalue[0][$val]['element'])) {
@@ -729,9 +739,13 @@ class ImportCsv extends ModeleImports
if (isModEnabled("socialnetworks") && strpos($fieldname, "socialnetworks") !== false) {
if (!in_array("socialnetworks", $listfields)) {
$listfields[] = "socialnetworks";
+ $socialkey = array_search("socialnetworks", $listfields); // Return position of 'socialnetworks' key in array
+ $listvalues[$socialkey] = '';
}
+ //var_dump($newval); var_dump($arrayrecord[($key - 1)]['type']);
if (!empty($newval) && $arrayrecord[($key - 1)]['type'] > 0) {
- $socialkey = array_search("socialnetworks", $listfields);
+ $socialkey = array_search("socialnetworks", $listfields); // Return position of 'socialnetworks' key in array
+ //var_dump('sk='.$socialkey); // socialkey=19
$socialnetwork = explode("_", $fieldname)[1];
if (empty($listvalues[$socialkey]) || $listvalues[$socialkey] == "null") {
$json = new stdClass();
@@ -833,7 +847,6 @@ class ImportCsv extends ModeleImports
if (empty($lastinsertid)) { // No insert done yet for a parent table
$sqlSelect = "SELECT ".$fname." FROM ".$tablename;
-
$data = array_combine($listfields, $listvalues);
$where = array(); // filters to forge SQL request
$filters = array(); // filters to forge output error message
diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php
index 3637ce105c1..ecf7d8b4a77 100644
--- a/htdocs/core/modules/import/import_xlsx.modules.php
+++ b/htdocs/core/modules/import/import_xlsx.modules.php
@@ -502,17 +502,28 @@ class ImportXlsx 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);
+
+ $result = call_user_func_array(array($classinstance, $method), $param_array);
+
+ // If duplicate record found
+ if (!($classinstance->id != '') && $result == -2) {
+ $this->errors[$error]['lib'] = $langs->trans('ErrorMultipleRecordFoundFromRef', $newval);
+ $this->errors[$error]['type'] = 'FOREIGNKEY';
+ $errorforthistable++;
+ $error++;
+ }
+
// If not found, try the fetch from label
if (!($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeorlabel') {
$param_array = array('', '', $newval);
call_user_func_array(array($classinstance, $method), $param_array);
}
$this->cacheconvert[$file . '_' . $class . '_' . $method . '_'][$newval] = $classinstance->id;
+
//print 'We have made a '.$class.'->'.$method.' to get id from code '.$newval.'. ';
if ($classinstance->id != '') { // id may be 0, it is a found value
$newval = $classinstance->id;
- } else {
+ } elseif (! $error) {
if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) {
$this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'code', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict']));
} elseif (!empty($objimport->array_import_convertvalue[0][$val]['element'])) {
@@ -770,12 +781,14 @@ class ImportXlsx extends ModeleImports
}
// Define $listfields and $listvalues to build SQL request
- if ($conf->socialnetworks->enabled && strpos($fieldname, "socialnetworks") !== false) {
+ if (isModEnabled("socialnetworks") && strpos($fieldname, "socialnetworks") !== false) {
if (!in_array("socialnetworks", $listfields)) {
$listfields[] = "socialnetworks";
+ $socialkey = array_search("socialnetworks", $listfields); // Return position of 'socialnetworks' key in array. Example socialkey=19
+ $listvalues[$socialkey] = '';
}
if (!empty($newval) && $arrayrecord[($key)]['type'] > 0) {
- $socialkey = array_search("socialnetworks", $listfields);
+ $socialkey = array_search("socialnetworks", $listfields); // Return position of 'socialnetworks' key in array. Example socialkey=19
$socialnetwork = explode("_", $fieldname)[1];
if (empty($listvalues[$socialkey]) || $listvalues[$socialkey] == "null") {
$json = new stdClass();
@@ -797,7 +810,7 @@ class ImportXlsx extends ModeleImports
} elseif (empty($newval) && $arrayrecord[($key)]['type'] == 0) {
$listvalues[] = "''";
} else {
- $listvalues[] = "'" . $this->db->escape($newval) . "'";
+ $listvalues[] = "'".$this->db->escape($newval)."'";
}
}
}
@@ -810,7 +823,7 @@ class ImportXlsx extends ModeleImports
if (!empty($listfields) && is_array($objimport->array_import_fieldshidden[0])) {
// Loop on each hidden fields to add them into listfields/listvalues
foreach ($objimport->array_import_fieldshidden[0] as $key => $val) {
- if (!preg_match('/^' . preg_quote($alias, '/') . '\./', $key)) {
+ if (!preg_match('/^'.preg_quote($alias, '/').'\./', $key)) {
continue; // Not a field of current table
}
if ($val == 'user->id') {
@@ -876,17 +889,17 @@ class ImportXlsx extends ModeleImports
if (!empty($updatekeys)) {
// We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields)
- $where = array();
-
if (empty($lastinsertid)) { // No insert done yet for a parent table
$sqlSelect = "SELECT ".$fname." FROM " . $tablename;
$data = array_combine($listfields, $listvalues);
- $filters = array();
+
+ $where = array(); // filters to forge SQL request
+ $filters = array(); // filters to forge output error message
foreach ($updatekeys as $key) {
$col = $objimport->array_import_updatekeys[0][$key];
$key = preg_replace('/^.*\./i', '', $key);
- if ($conf->socialnetworks->enabled && strpos($key, "socialnetworks") !== false) {
+ if (isModEnabled("socialnetworks") && strpos($key, "socialnetworks") !== false) {
$tmp = explode("_", $key);
$key = $tmp[0];
$socialnetwork = $tmp[1];
diff --git a/htdocs/core/modules/modEventOrganization.class.php b/htdocs/core/modules/modEventOrganization.class.php
index 9ad2ede9b77..437fa691713 100644
--- a/htdocs/core/modules/modEventOrganization.class.php
+++ b/htdocs/core/modules/modEventOrganization.class.php
@@ -327,7 +327,7 @@ class modEventOrganization extends DolibarrModules
*/
public function init($options = '')
{
- global $conf, $langs;
+ global $conf, $langs, $user;
// Permissions
$this->remove($options);
diff --git a/htdocs/datapolicy/class/datapolicycron.class.php b/htdocs/datapolicy/class/datapolicycron.class.php
index 44152f0c68b..fb76767bf1e 100644
--- a/htdocs/datapolicy/class/datapolicycron.class.php
+++ b/htdocs/datapolicy/class/datapolicycron.class.php
@@ -451,8 +451,8 @@ class DataPolicyCron
$this->db->begin();
foreach ($arrayofparameters as $key => $params) {
- if ($conf->global->$key != '' && is_numeric($conf->global->$key) && (int) $conf->global->$key > 0) {
- $sql = sprintf($params['sql'], (int) $conf->entity, (int) $conf->global->$key, (int) $conf->global->$key);
+ if (getDolGlobalInt($key) > 0) {
+ $sql = sprintf($params['sql'], (int) $conf->entity, (int) getDolGlobalInt($key), (int) getDolGlobalInt($key));
$resql = $this->db->query($sql);
diff --git a/htdocs/install/mysql/data/llx_c_email_templates.sql b/htdocs/install/mysql/data/llx_c_email_templates.sql
index bce46a70e49..d2886631942 100644
--- a/htdocs/install/mysql/data/llx_c_email_templates.sql
+++ b/htdocs/install/mysql/data/llx_c_email_templates.sql
@@ -21,25 +21,26 @@
--
-- Bank Thirdparty
-INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'banque','thirdparty','',0,null,null,'(YourSEPAMandate)',1,'$conf->societe->enabled && $conf->banque->enabled && $conf->prelevement->enabled',0,'__(YourSEPAMandate)__','__(Hello)__, \n\n__(FindYourSEPAMandate)__ : \n__MYCOMPANY_NAME__ \n__MYCOMPANY_FULLADDRESS__ \n__(Sincerely)__ \n__USER_SIGNATURE__',null, 0);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'banque','thirdparty','',0,null,null,'(YourSEPAMandate)',1,'isModEnabled("societe") && isModEnabled("banque") && isModEnabled("prelevement")',0,'__(YourSEPAMandate)__','__(Hello)__, \n\n__(FindYourSEPAMandate)__ : \n__MYCOMPANY_NAME__ \n__MYCOMPANY_FULLADDRESS__ \n__(Sincerely)__ \n__USER_SIGNATURE__',null, 0);
-- Members
-INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnAutoSubscription)' ,10,'$conf->adherent->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourMembershipRequestWasReceived)__','__(Hello)__ __MEMBER_FULLNAME__, \n\n__(ThisIsContentOfYourMembershipRequestWasReceived)__ \n __ONLINE_PAYMENT_TEXT_AND_URL__ \n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
-INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnMemberValidation)' ,20,'$conf->adherent->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourMembershipWasValidated)__', '__(Hello)__ __MEMBER_FULLNAME__, \n\n__(ThisIsContentOfYourMembershipWasValidated)__ __(FirstName)__ : __MEMBER_FIRSTNAME__ __(LastName)__ : __MEMBER_LASTNAME__ __(ID)__ : __MEMBER_ID__ \n __ONLINE_PAYMENT_TEXT_AND_URL__ \n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
-INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnNewSubscription)' ,30,'$conf->adherent->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourSubscriptionWasRecorded)__', '__(Hello)__ __MEMBER_FULLNAME__, \n\n__(ThisIsContentOfYourSubscriptionWasRecorded)__ \n\n \n__(Sincerely)__ __USER_SIGNATURE__',null, 1);
-INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingReminderForExpiredSubscription)',40,'$conf->adherent->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(SubscriptionReminderEmail)__', '__(Hello)__ __MEMBER_FULLNAME__, \n\n__(ThisIsContentOfSubscriptionReminderEmail)__ \n __ONLINE_PAYMENT_TEXT_AND_URL__ \n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
-INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnCancelation)' ,50,'$conf->adherent->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourMembershipWasCanceled)__', '__(Hello)__ __MEMBER_FULLNAME__, \n\n__(YourMembershipWasCanceled)__ \n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
-INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingAnEMailToMember)' ,60,'$conf->adherent->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(CardContent)__', '__(Hello)__, \n\n__(ThisIsContentOfYourCard)__ \n__(ID)__ : __ID__ \n__(Civility)__ : __MEMBER_CIVILITY__ \n__(Firstname)__ : __MEMBER_FIRSTNAME__ \n__(Lastname)__ : __MEMBER_LASTNAME__ \n__(Fullname)__ : __MEMBER_FULLNAME__ \n__(Company)__ : __MEMBER_COMPANY__ \n__(Address)__ : __MEMBER_ADDRESS__ \n__(Zip)__ : __MEMBER_ZIP__ \n__(Town)__ : __MEMBER_TOWN__ \n__(Country)__ : __MEMBER_COUNTRY__ \n__(Email)__ : __MEMBER_EMAIL__ \n__(Birthday)__ : __MEMBER_BIRTH__ \n__(Photo)__ : __MEMBER_PHOTO__ \n__(Login)__ : __MEMBER_LOGIN__ \n__(Phone)__ : __MEMBER_PHONE__ \n__(PhonePerso)__ : __MEMBER_PHONEPRO__ \n__(PhoneMobile)__ : __MEMBER_PHONEMOBILE__ \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnAutoSubscription)' ,10, 'isModEnabled("adherent")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourMembershipRequestWasReceived)__','__(Hello)__ __MEMBER_FULLNAME__, \n\n__(ThisIsContentOfYourMembershipRequestWasReceived)__ \n __ONLINE_PAYMENT_TEXT_AND_URL__ \n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnMemberValidation)' ,20, 'isModEnabled("adherent")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourMembershipWasValidated)__', '__(Hello)__ __MEMBER_FULLNAME__, \n\n__(ThisIsContentOfYourMembershipWasValidated)__ __(FirstName)__ : __MEMBER_FIRSTNAME__ __(LastName)__ : __MEMBER_LASTNAME__ __(ID)__ : __MEMBER_ID__ \n __ONLINE_PAYMENT_TEXT_AND_URL__ \n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnNewSubscription)' ,30, 'isModEnabled("adherent")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourSubscriptionWasRecorded)__', '__(Hello)__ __MEMBER_FULLNAME__, \n\n__(ThisIsContentOfYourSubscriptionWasRecorded)__ \n\n \n__(Sincerely)__ __USER_SIGNATURE__',null, 1);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingReminderForExpiredSubscription)',40, 'isModEnabled("adherent")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(SubscriptionReminderEmail)__', '__(Hello)__ __MEMBER_FULLNAME__, \n\n__(ThisIsContentOfSubscriptionReminderEmail)__ \n __ONLINE_PAYMENT_TEXT_AND_URL__ \n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnCancelation)' ,50, 'isModEnabled("adherent")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourMembershipWasCanceled)__', '__(Hello)__ __MEMBER_FULLNAME__, \n\n__(YourMembershipWasCanceled)__ \n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingAnEMailToMember)' ,60, 'isModEnabled("adherent")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(CardContent)__', '__(Hello)__, \n\n__(ThisIsContentOfYourCard)__ \n__(ID)__ : __ID__ \n__(Civility)__ : __MEMBER_CIVILITY__ \n__(Firstname)__ : __MEMBER_FIRSTNAME__ \n__(Lastname)__ : __MEMBER_LASTNAME__ \n__(Fullname)__ : __MEMBER_FULLNAME__ \n__(Company)__ : __MEMBER_COMPANY__ \n__(Address)__ : __MEMBER_ADDRESS__ \n__(Zip)__ : __MEMBER_ZIP__ \n__(Town)__ : __MEMBER_TOWN__ \n__(Country)__ : __MEMBER_COUNTRY__ \n__(Email)__ : __MEMBER_EMAIL__ \n__(Birthday)__ : __MEMBER_BIRTH__ \n__(Photo)__ : __MEMBER_PHOTO__ \n__(Login)__ : __MEMBER_LOGIN__ \n__(Phone)__ : __MEMBER_PHONE__ \n__(PhonePerso)__ : __MEMBER_PHONEPRO__ \n__(PhoneMobile)__ : __MEMBER_PHONEMOBILE__ \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
-- Recruiting
-INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'recruitment','recruitmentcandidature_send','',0,null,null,'(AnswerCandidature)' ,100,'$conf->recruitment->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourCandidature)__', '__(Hello)__ __CANDIDATE_FULLNAME__, \n\n__(YourCandidatureAnswerMessage)__ __ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__\n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'recruitment','recruitmentcandidature_send','',0,null,null,'(AnswerCandidature)' ,100,'isModEnabled("recruitment")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourCandidature)__', '__(Hello)__ __CANDIDATE_FULLNAME__, \n\n__(YourCandidatureAnswerMessage)__ __ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__\n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
-- Event organization
INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskConf)', 10, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskConf)__', '__(Hello)__, __(OrganizationEventConfRequestWasReceived)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskBooth)', 20, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskBooth)__', '__(Hello)__, __(OrganizationEventBoothRequestWasReceived)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
-- TODO Add message for registration only to event __ONLINE_PAYMENT_TEXT_AND_URL__
-INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailSubsBooth)', 30, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailBoothPayment)__', '__(Hello)__, __(OrganizationEventPaymentOfBoothWasReceived)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
-INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailSubsEvent)', 40, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailRegistrationPayment)__', '__(Hello)__, __(OrganizationEventPaymentOfRegistrationWasReceived)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailBoothPayment)', 30, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailBoothPayment)__', '__(Hello)__, __(OrganizationEventPaymentOfBoothWasReceived)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailRegistrationPayment)', 40, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailRegistrationPayment)__', '__(Hello)__, __(OrganizationEventPaymentOfRegistrationWasReceived)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
+--
INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailAttendees)', 50, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailAttendees)__', '__(Hello)__, __(OrganizationEventBulkMailToAttendees)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailSpeakers)', 60, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailSpeakers)__', '__(Hello)__, __(OrganizationEventBulkMailToSpeakers)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql
index acbcbf7b0d3..60803396be3 100644
--- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql
+++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql
@@ -737,3 +737,34 @@ ALTER TABLE llx_loan_schedule ADD UNIQUE INDEX uk_loan_schedule_ref (fk_loan, da
-- We need when upgrade 15 to 16 with Dolibarr v17+ for upgrade2 function migrate_user_photospath2()
ALTER TABLE llx_user CHANGE COLUMN note note_private text;
+
+
+-- Bank Thirdparty
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'banque','thirdparty','',0,null,null,'(YourSEPAMandate)',1,'isModEnabled("societe") && isModEnabled("banque") && isModEnabled("prelevement")',0,'__(YourSEPAMandate)__','__(Hello)__, \n\n__(FindYourSEPAMandate)__ : \n__MYCOMPANY_NAME__ \n__MYCOMPANY_FULLADDRESS__ \n__(Sincerely)__ \n__USER_SIGNATURE__',null, 0);
+
+-- Members
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnAutoSubscription)' ,10, 'isModEnabled("adherent")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourMembershipRequestWasReceived)__','__(Hello)__ __MEMBER_FULLNAME__, \n\n__(ThisIsContentOfYourMembershipRequestWasReceived)__ \n __ONLINE_PAYMENT_TEXT_AND_URL__ \n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnMemberValidation)' ,20, 'isModEnabled("adherent")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourMembershipWasValidated)__', '__(Hello)__ __MEMBER_FULLNAME__, \n\n__(ThisIsContentOfYourMembershipWasValidated)__ __(FirstName)__ : __MEMBER_FIRSTNAME__ __(LastName)__ : __MEMBER_LASTNAME__ __(ID)__ : __MEMBER_ID__ \n __ONLINE_PAYMENT_TEXT_AND_URL__ \n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnNewSubscription)' ,30, 'isModEnabled("adherent")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourSubscriptionWasRecorded)__', '__(Hello)__ __MEMBER_FULLNAME__, \n\n__(ThisIsContentOfYourSubscriptionWasRecorded)__ \n\n \n__(Sincerely)__ __USER_SIGNATURE__',null, 1);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingReminderForExpiredSubscription)',40, 'isModEnabled("adherent")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(SubscriptionReminderEmail)__', '__(Hello)__ __MEMBER_FULLNAME__, \n\n__(ThisIsContentOfSubscriptionReminderEmail)__ \n __ONLINE_PAYMENT_TEXT_AND_URL__ \n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnCancelation)' ,50, 'isModEnabled("adherent")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourMembershipWasCanceled)__', '__(Hello)__ __MEMBER_FULLNAME__, \n\n__(YourMembershipWasCanceled)__ \n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingAnEMailToMember)' ,60, 'isModEnabled("adherent")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(CardContent)__', '__(Hello)__, \n\n__(ThisIsContentOfYourCard)__ \n__(ID)__ : __ID__ \n__(Civility)__ : __MEMBER_CIVILITY__ \n__(Firstname)__ : __MEMBER_FIRSTNAME__ \n__(Lastname)__ : __MEMBER_LASTNAME__ \n__(Fullname)__ : __MEMBER_FULLNAME__ \n__(Company)__ : __MEMBER_COMPANY__ \n__(Address)__ : __MEMBER_ADDRESS__ \n__(Zip)__ : __MEMBER_ZIP__ \n__(Town)__ : __MEMBER_TOWN__ \n__(Country)__ : __MEMBER_COUNTRY__ \n__(Email)__ : __MEMBER_EMAIL__ \n__(Birthday)__ : __MEMBER_BIRTH__ \n__(Photo)__ : __MEMBER_PHOTO__ \n__(Login)__ : __MEMBER_LOGIN__ \n__(Phone)__ : __MEMBER_PHONE__ \n__(PhonePerso)__ : __MEMBER_PHONEPRO__ \n__(PhoneMobile)__ : __MEMBER_PHONEMOBILE__ \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
+
+-- Recruiting
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'recruitment','recruitmentcandidature_send','',0,null,null,'(AnswerCandidature)' ,100,'isModEnabled("recruitment")',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourCandidature)__', '__(Hello)__ __CANDIDATE_FULLNAME__, \n\n__(YourCandidatureAnswerMessage)__ __ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__\n \n__(Sincerely)__ __USER_SIGNATURE__',null, 0);
+
+-- Event organization
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskConf)', 10, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskConf)__', '__(Hello)__, __(OrganizationEventConfRequestWasReceived)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskBooth)', 20, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskBooth)__', '__(Hello)__, __(OrganizationEventBoothRequestWasReceived)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
+-- TODO Add message for registration only to event __ONLINE_PAYMENT_TEXT_AND_URL__
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailBoothPayment)', 30, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailBoothPayment)__', '__(Hello)__, __(OrganizationEventPaymentOfBoothWasReceived)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailRegistrationPayment)', 40, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailRegistrationPayment)__', '__(Hello)__, __(OrganizationEventPaymentOfRegistrationWasReceived)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
+--
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailAttendees)', 50, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailAttendees)__', '__(Hello)__, __(OrganizationEventBulkMailToAttendees)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
+INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailSpeakers)', 60, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailSpeakers)__', '__(Hello)__, __(OrganizationEventBulkMailToSpeakers)__ __(Sincerely)__ __USER_SIGNATURE__', null, '1', null);
+
+-- Partnership
+INSERT INTO llx_c_email_templates (entity, module, type_template, label, lang, position, topic, joinfiles, content) VALUES (0, 'partnership', 'partnership_send', '(SendingEmailOnPartnershipWillSoonBeCanceled)', '', 100, '[__[MAIN_INFO_SOCIETE_NOM]__] - __(YourPartnershipWillSoonBeCanceledTopic)__', 0, '\n __(Hello)__, \n__(YourPartnershipWillSoonBeCanceledContent)__
\n \n\n \n\n __(Sincerely)__ \n __[MAIN_INFO_SOCIETE_NOM]__ \n \n');
+INSERT INTO llx_c_email_templates (entity, module, type_template, label, lang, position, topic, joinfiles, content) VALUES (0, 'partnership', 'partnership_send', '(SendingEmailOnPartnershipCanceled)', '', 100, '[__[MAIN_INFO_SOCIETE_NOM]__] - __(YourPartnershipCanceledTopic)__', 0, '\n __(Hello)__, \n__(YourPartnershipCanceledContent)__
\n \n\n \n\n __(Sincerely)__ \n __[MAIN_INFO_SOCIETE_NOM]__ \n \n');
+INSERT INTO llx_c_email_templates (entity, module, type_template, label, lang, position, topic, joinfiles, content) VALUES (0, 'partnership', 'partnership_send', '(SendingEmailOnPartnershipRefused)', '', 100, '[__[MAIN_INFO_SOCIETE_NOM]__] - __(YourPartnershipRefusedTopic)__', 0, '\n __(Hello)__, \n__(YourPartnershipRefusedContent)__
\n \n\n \n\n __(Sincerely)__ \n __[MAIN_INFO_SOCIETE_NOM]__ \n \n');
+INSERT INTO llx_c_email_templates (entity, module, type_template, label, lang, position, topic, joinfiles, content) VALUES (0, 'partnership', 'partnership_send', '(SendingEmailOnPartnershipAccepted)', '', 100, '[__[MAIN_INFO_SOCIETE_NOM]__] - __(YourPartnershipAcceptedTopic)__', 0, '\n __(Hello)__, \n__(YourPartnershipAcceptedContent)__
\n \n\n \n\n __(Sincerely)__ \n __[MAIN_INFO_SOCIETE_NOM]__ \n \n');
diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang
index 6ff5a63196a..860ae75e604 100644
--- a/htdocs/langs/en_US/errors.lang
+++ b/htdocs/langs/en_US/errors.lang
@@ -97,6 +97,7 @@ ErrorWrongValueForField=Field %s : '%s ' does not match regex rule <
ErrorHtmlInjectionForField=Field %s : The value '%s ' contains a malicious data not allowed
ErrorFieldValueNotIn=Field %s : '%s ' is not a value found in field %s of %s
ErrorFieldRefNotIn=Field %s : '%s ' is not a %s existing ref
+ErrorMultipleRecordFoundFromRef=Several record found when searching from ref %s . No way to know which ID to use.
ErrorsOnXLines=%s errors found
ErrorFileIsInfectedWithAVirus=The antivirus program was not able to validate the file (file might be infected by a virus)
ErrorNumRefModel=A reference exists into database (%s) and is not compatible with this numbering rule. Remove record or renamed reference to activate this module.
@@ -299,6 +300,7 @@ ErrorCharPlusNotSupportedByImapForSearch=IMAP search is not able to search into
ErrorTableNotFound=Table %s not found
ErrorValueForTooLow=Value for %s is too low
ErrorValueCantBeNull=Value for %s can't be null
+ErrorDateOfMovementLowerThanDateOfFileTransmission=The date of the bank transaction can't be lower than the date of the file transmission
# Warnings
WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup.
diff --git a/htdocs/langs/en_US/languages.lang b/htdocs/langs/en_US/languages.lang
index 78378c6c5d3..b6368a7d374 100644
--- a/htdocs/langs/en_US/languages.lang
+++ b/htdocs/langs/en_US/languages.lang
@@ -36,6 +36,7 @@ Language_en_SA=English (Saudi Arabia)
Language_en_SG=English (Singapore)
Language_en_US=English (United States)
Language_en_ZA=English (South Africa)
+Language_en_ZW=English (Zimbabwe)
Language_es_ES=Spanish
Language_es_AR=Spanish (Argentina)
Language_es_BO=Spanish (Bolivia)
diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang
index bf2dabf5a0a..fa2ed9669d9 100644
--- a/htdocs/langs/en_US/products.lang
+++ b/htdocs/langs/en_US/products.lang
@@ -399,7 +399,7 @@ ActionAvailableOnVariantProductOnly=Action only available on the variant of prod
ProductsPricePerCustomer=Product prices per customers
ProductSupplierExtraFields=Additional Attributes (Supplier Prices)
DeleteLinkedProduct=Delete the child product linked to the combination
-AmountUsedToUpdateWAP=Amount to use to update the Weighted Average Price
+AmountUsedToUpdateWAP=Unit amount to use to update the Weighted Average Price
PMPValue=Weighted average price
PMPValueShort=WAP
mandatoryperiod=Mandatory periods
diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php
index e247b5fabb5..705dc202932 100644
--- a/htdocs/modulebuilder/index.php
+++ b/htdocs/modulebuilder/index.php
@@ -1780,7 +1780,7 @@ if ($dirins && $action == 'generatepackage') {
dol_mkdir($dirofmodule);
}
// Note: We exclude /bin/ to not include the already generated zip
- $result = dol_compress_dir($dir, $outputfilezip, 'zip', '/\/bin\//', $modulelowercase);
+ $result = dol_compress_dir($dir, $outputfilezip, 'zip', '/\/bin\/|\.git/', $modulelowercase);
} else {
$result = -1;
}
diff --git a/htdocs/mrp/mo_list.php b/htdocs/mrp/mo_list.php
index 7f0cc15f873..f7a6ed88571 100644
--- a/htdocs/mrp/mo_list.php
+++ b/htdocs/mrp/mo_list.php
@@ -84,7 +84,7 @@ if (!$sortorder) {
}
// Initialize array of search criterias
-$search_all = GETPOST('search_all', 'alphanohtml');
+$search_all = GETPOST('search_all', 'alphanohtml') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml');
$search = array();
foreach ($object->fields as $key => $val) {
if (GETPOST('search_'.$key, 'alpha') !== '') {
@@ -230,8 +230,8 @@ $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
if (isset($extrafields->attributes[$object->table_element]['label']) && 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 (t.rowid = ef.fk_object)";
}
-$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."mrp_production lineparent ON t.fk_parent_line = lineparent.rowid";
-$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."mrp_mo moparent ON lineparent.fk_mo = moparent.rowid";
+$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."mrp_production as lineparent ON t.fk_parent_line = lineparent.rowid";
+$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."mrp_mo as moparent ON lineparent.fk_mo = moparent.rowid";
// Add table from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
@@ -266,17 +266,17 @@ foreach ($search as $key => $val) {
$mode_search = 2;
}
if ($search[$key] != '') {
- $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search));
+ $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
}
} else {
if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
$columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
if (preg_match('/_dtstart$/', $key)) {
- $sql .= " AND t.".$columnName." >= '".$db->idate($search[$key])."'";
+ $sql .= " AND t.".$db->escape($columnName)." >= '".$db->idate($search[$key])."'";
}
if (preg_match('/_dtend$/', $key)) {
- $sql .= " AND t." . $columnName . " <= '" . $db->idate($search[$key]) . "'";
+ $sql .= " AND t.".$db->escape($columnName)." <= '".$db->idate($search[$key])."'";
}
}
}
diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php
index 24b3516684e..64ae11909ef 100644
--- a/htdocs/mrp/mo_production.php
+++ b/htdocs/mrp/mo_production.php
@@ -814,6 +814,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
// Lines to consume
+ $bomcostupdated = 0; // We will recalculate the unitary cost to produce a product using the real "products to consume into MO"
+
if (!empty($object->lines)) {
$nblinetoconsume = 0;
foreach ($object->lines as $line) {
@@ -832,7 +834,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
$linecost = price2num($tmpproduct->pmp, 'MT');
if ($object->qty > 0) {
- // add free consume line cost to bomcost
+ // add free consume line cost to $bomcostupdated
$costprice = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp);
if (empty($costprice)) {
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
@@ -843,12 +845,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
$costprice = 0;
}
}
- $linecost = price2num(($line->qty * $costprice) / $object->qty, 'MT');
- $bomcost += $linecost;
+ $linecost = price2num(($line->qty * $costprice) / $object->qty, 'MT'); // price for line for all quantities
+ $bomcostupdated += price2num(($line->qty * $costprice) / $object->qty, 'MU'); // same but with full accuracy
}
- $bomcost = price2num($bomcost, 'MU');
-
+ $bomcostupdated = price2num($bomcostupdated, 'MU');
$arrayoflines = $object->fetchLinesLinked('consumed', $line->id);
$alreadyconsumed = 0;
foreach ($arrayoflines as $line2) {
@@ -1136,7 +1137,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
print ''.$langs->trans("Product").' ';
print ''.$langs->trans("Qty").' ';
if ($permissiontoupdatecost) {
- if (empty($bomcost)) {
+ if (empty($bomcostupdated)) {
print ''.$form->textwithpicto($langs->trans("UnitCost"), $langs->trans("AmountUsedToUpdateWAP")).' ';
} else {
print ''.$form->textwithpicto($langs->trans("ManufacturingPrice"), $langs->trans("AmountUsedToUpdateWAP")).' ';
@@ -1230,17 +1231,25 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
if ($permissiontoupdatecost) {
// Defined $manufacturingcost
$manufacturingcost = 0;
- if ($object->mrptype == 0) { // If MO is a "Manufacture" type (and not "Disassemble"
- $manufacturingcost = $bomcost;
+ $manufacturingcostsrc = '';
+ if ($object->mrptype == 0) { // If MO is a "Manufacture" type (and not "Disassemble")
+ $manufacturingcost = $bomcostupdated;
+ $manufacturingcostsrc = $langs->trans("CalculatedFromProductsToConsume");
+ if (empty($manufacturingcost)) {
+ $manufacturingcost = $bomcost;
+ $manufacturingcostsrc = $langs->trans("ValueFromBom");
+ }
if (empty($manufacturingcost)) {
$manufacturingcost = price2num($tmpproduct->cost_price, 'MU');
+ $manufacturingcostsrc = $langs->trans("CostPrice");
}
if (empty($manufacturingcost)) {
$manufacturingcost = price2num($tmpproduct->pmp, 'MU');
+ $manufacturingcostsrc = $langs->trans("PMPValue");
}
}
- print '';
+ print ' ';
if ($manufacturingcost) {
print price($manufacturingcost);
}
@@ -1344,19 +1353,27 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
if ($permissiontoupdatecost) {
// Defined $manufacturingcost
$manufacturingcost = 0;
- if ($object->mrptype == 0) { // If MO is a "Manufacture" type (and not "Disassemble"
- $manufacturingcost = $bomcost;
+ $manufacturingcostsrc = '';
+ if ($object->mrptype == 0) { // If MO is a "Manufacture" type (and not "Disassemble")
+ $manufacturingcost = $bomcostupdated;
+ $manufacturingcostsrc = $langs->trans("CalculatedFromProductsToConsume");
+ if (empty($manufacturingcost)) {
+ $manufacturingcost = $bomcost;
+ $manufacturingcostsrc = $langs->trans("ValueFromBom");
+ }
if (empty($manufacturingcost)) {
$manufacturingcost = price2num($tmpproduct->cost_price, 'MU');
+ $manufacturingcostsrc = $langs->trans("CostPrice");
}
if (empty($manufacturingcost)) {
$manufacturingcost = price2num($tmpproduct->pmp, 'MU');
+ $manufacturingcostsrc = $langs->trans("PMPValue");
}
}
if ($tmpproduct->type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
$preselected = (GETPOSTISSET('pricetoproduce-'.$line->id.'-'.$i) ? GETPOST('pricetoproduce-'.$line->id.'-'.$i) : ($manufacturingcost ? price($manufacturingcost) : ''));
- print ' ';
+ print ' ';
} else {
print ' ';
}
diff --git a/htdocs/product/stock/tpl/stockcorrection.tpl.php b/htdocs/product/stock/tpl/stockcorrection.tpl.php
index 40181167baa..69ae5eda5e0 100644
--- a/htdocs/product/stock/tpl/stockcorrection.tpl.php
+++ b/htdocs/product/stock/tpl/stockcorrection.tpl.php
@@ -109,7 +109,7 @@ if ($object->element == 'product') {
if (empty($ident) && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE)) {
$ident = $conf->global->MAIN_DEFAULT_WAREHOUSE;
}
- print img_picto('', 'stock').$formproduct->selectWarehouses($ident, 'id_entrepot', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'minwidth100');
+ print img_picto('', 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses($ident, 'id_entrepot', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'minwidth100 maxwidth300 widthcentpercentminusx');
print '';
}
if ($object->element == 'stock') {
@@ -155,10 +155,11 @@ if (ismodEnabled('productbatch') &&
print ' ';
print ' ';
} else {
- print ' ';
+ print img_picto('', 'barcode', 'class="pictofixedwidth"').' ';
}
print '';
print '';
+
print '';
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print ''.$langs->trans("SellByDate").' ';
diff --git a/htdocs/product/stock/tpl/stocktransfer.tpl.php b/htdocs/product/stock/tpl/stocktransfer.tpl.php
index 819fa404d52..7d08f2014a0 100644
--- a/htdocs/product/stock/tpl/stocktransfer.tpl.php
+++ b/htdocs/product/stock/tpl/stocktransfer.tpl.php
@@ -104,7 +104,7 @@ if (isModEnabled('productbatch') &&
print ' ';
print ' ';
} else {
- print ' ';
+ print img_picto('', 'barcode', 'class="pictofixedwidth"').' ';
}
print ' ';
print ' ';
diff --git a/htdocs/ticket/class/api_tickets.class.php b/htdocs/ticket/class/api_tickets.class.php
index 2fd77693984..35e01a74f0d 100644
--- a/htdocs/ticket/class/api_tickets.class.php
+++ b/htdocs/ticket/class/api_tickets.class.php
@@ -246,6 +246,7 @@ class Tickets extends DolibarrApi
$socid = DolibarrApiAccess::$user->socid;
}
+ $search_sale = null;
// If the internal user must only see his customers, force searching by him
$search_sale = 0;
if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) {
diff --git a/test/phpunit/CodingSqlTest.php b/test/phpunit/CodingSqlTest.php
index b04f6ed4737..bdcf381c8bb 100644
--- a/test/phpunit/CodingSqlTest.php
+++ b/test/phpunit/CodingSqlTest.php
@@ -193,7 +193,7 @@ class CodingSqlTest extends PHPUnit\Framework\TestCase
$result=strpos($filecontent, '"');
if ($result) {
- $result=(! strpos($filecontent, '["') && ! strpos($filecontent, '{"'));
+ $result=(! strpos($filecontent, '["') && ! strpos($filecontent, '{"') && ! strpos($filecontent, '("'));
}
//print __METHOD__." Result for checking we don't have double quote = ".$result."\n";
$this->assertTrue($result===false, 'Found double quote that is not [" neither {" (used for json content) into '.$file.'. Bad.');